blob: fa76641c8c6a6807a1a0cce4519978b633eeb9c9 [file] [log] [blame]
Ben Lindstromd9e08242001-07-22 19:32:00 +00001/*
Kevin Stevesf744b512001-08-14 20:31:49 +00002 * XXX: license?
3 */
4
5/*
Ben Lindstromd9e08242001-07-22 19:32:00 +00006 * The modules contains code to support cray t3e and sv1 computers.
7 * It is here to minimize the modifcations to the openssh base code.
8 */
9
10#ifdef _CRAY
11
12#include <udb.h>
13#include <tmpdir.h>
14#include <unistd.h>
15#include <sys/category.h>
16#include <utmp.h>
17#include <sys/jtab.h>
18#include <signal.h>
Ben Lindstrom6db66ff2001-08-06 23:29:16 +000019#include <sys/priv.h>
20#include <sys/secparm.h>
21#include <sys/usrv.h>
22#include <sys/sysv.h>
23#include <sys/sectab.h>
Ben Lindstromd9e08242001-07-22 19:32:00 +000024#include <sys/stat.h>
25#include <stdlib.h>
26#include <pwd.h>
27#include <fcntl.h>
28#include <errno.h>
29
Ben Lindstrom6db66ff2001-08-06 23:29:16 +000030#include "bsd-cray.h"
31
Kevin Stevesf744b512001-08-14 20:31:49 +000032char cray_tmpdir[TPATHSIZ+1]; /* job TMPDIR path */
Ben Lindstromd9e08242001-07-22 19:32:00 +000033
34/*
35 * Functions.
36 */
Ben Lindstromd9e08242001-07-22 19:32:00 +000037void cray_retain_utmp(struct utmp *, int);
Kevin Steves4da21ab2001-08-14 21:02:15 +000038void cray_delete_tmpdir(char *, int, uid_t);
Ben Lindstromd9e08242001-07-22 19:32:00 +000039void cray_init_job(struct passwd *);
40void cray_set_tmpdir(struct utmp *);
41
Ben Lindstrom6db66ff2001-08-06 23:29:16 +000042
Kevin Stevesf744b512001-08-14 20:31:49 +000043/*
Ben Lindstromd9e08242001-07-22 19:32:00 +000044 * Orignal written by:
45 * Wayne Schroeder
46 * San Diego Supercomputer Center
47 * schroeder@sdsc.edu
48*/
Ben Lindstrom6db66ff2001-08-06 23:29:16 +000049void
Ben Lindstromd9e08242001-07-22 19:32:00 +000050cray_setup(uid_t uid, char *username)
51{
Kevin Stevesf744b512001-08-14 20:31:49 +000052 struct udb *p;
Ben Lindstromd9e08242001-07-22 19:32:00 +000053 extern char *setlimits();
Kevin Stevesf744b512001-08-14 20:31:49 +000054 int i, j;
55 int accts[MAXVIDS];
56 int naccts;
57 int err;
58 char *sr;
59 int pid;
60 struct jtab jbuf;
61 int jid;
Ben Lindstromd9e08242001-07-22 19:32:00 +000062
Kevin Stevesf744b512001-08-14 20:31:49 +000063 if ((jid = getjtab(&jbuf)) < 0)
64 fatal("getjtab: no jid");
Ben Lindstromd9e08242001-07-22 19:32:00 +000065
Kevin Stevesf744b512001-08-14 20:31:49 +000066 err = setudb(); /* open and rewind the Cray User DataBase */
67 if (err != 0)
68 fatal("UDB open failure");
69 naccts = 0;
Ben Lindstrom6db66ff2001-08-06 23:29:16 +000070 p = getudbnam(username);
Kevin Stevesf744b512001-08-14 20:31:49 +000071 if (p == NULL)
72 fatal("No UDB entry for %.100s", username);
73 if (uid != p->ue_uid)
Kevin Steves4da21ab2001-08-14 21:02:15 +000074 fatal("UDB entry %.100s uid(%d) does not match uid %d",
75 username, (int) p->ue_uid, (int) uid);
Kevin Stevesf744b512001-08-14 20:31:49 +000076 for (j = 0; p->ue_acids[j] != -1 && j < MAXVIDS; j++) {
77 accts[naccts] = p->ue_acids[j];
78 naccts++;
Ben Lindstrom6db66ff2001-08-06 23:29:16 +000079 }
Kevin Stevesf744b512001-08-14 20:31:49 +000080 endudb(); /* close the udb */
Ben Lindstromd9e08242001-07-22 19:32:00 +000081
Kevin Stevesf744b512001-08-14 20:31:49 +000082 if (naccts != 0) {
83 /* Perhaps someday we'll prompt users who have multiple accounts
84 to let them pick one (like CRI's login does), but for now just set
85 the account to the first entry. */
86 if (acctid(0, accts[0]) < 0)
87 fatal("System call acctid failed, accts[0]=%d", accts[0]);
88 }
Ben Lindstromd9e08242001-07-22 19:32:00 +000089
Kevin Stevesf744b512001-08-14 20:31:49 +000090 /* Now set limits, including CPU time for the (interactive) job and process,
91 and set up permissions (for chown etc), etc. This is via an internal CRI
92 routine, setlimits, used by CRI's login. */
93
94 pid = getpid();
95 sr = setlimits(username, C_PROC, pid, UDBRC_INTER);
96 if (sr != NULL)
97 fatal("%.200s", sr);
98
99 sr = setlimits(username, C_JOB, jid, UDBRC_INTER);
100 if (sr != NULL)
101 fatal("%.200s", sr);
Ben Lindstrom6db66ff2001-08-06 23:29:16 +0000102
103}
104
Kevin Stevesf744b512001-08-14 20:31:49 +0000105/*
Ben Lindstrom6db66ff2001-08-06 23:29:16 +0000106 * The rc.* and /etc/sdaemon methods of starting a program on unicos/unicosmk
107 * can have pal privileges that sshd can inherit which
108 * could allow a user to su to root with out a password.
109 * This subroutine clears all privileges.
110 */
111void
112drop_cray_privs()
113{
114#if defined(_SC_CRAY_PRIV_SU)
Kevin Stevesf744b512001-08-14 20:31:49 +0000115 priv_proc_t* privstate;
116 int result;
117 extern int priv_set_proc();
118 extern priv_proc_t* priv_init_proc();
119 struct usrv usrv;
Ben Lindstrom6db66ff2001-08-06 23:29:16 +0000120
121 /*
122 * If ether of theses two flags are not set
Kevin Stevesf744b512001-08-14 20:31:49 +0000123 * then don't allow this version of ssh to run.
124 */
125 if (!sysconf(_SC_CRAY_PRIV_SU))
126 fatal("Not PRIV_SU system.");
127 if (!sysconf(_SC_CRAY_POSIX_PRIV))
128 fatal("Not POSIX_PRIV.");
Ben Lindstrom6db66ff2001-08-06 23:29:16 +0000129
Kevin Stevesf744b512001-08-14 20:31:49 +0000130 debug("Dropping privileges.");
Ben Lindstrom6db66ff2001-08-06 23:29:16 +0000131
132 memset(&usrv, 0, sizeof(usrv));
Kevin Stevesf744b512001-08-14 20:31:49 +0000133 if (setusrv(&usrv) < 0)
Kevin Steves4da21ab2001-08-14 21:02:15 +0000134 fatal("%s(%d): setusrv(): %s", __FILE__, __LINE__,
Kevin Stevesf744b512001-08-14 20:31:49 +0000135 strerror(errno));
Ben Lindstrom6db66ff2001-08-06 23:29:16 +0000136
137 if ((privstate = priv_init_proc()) != NULL) {
Kevin Stevesf744b512001-08-14 20:31:49 +0000138 result = priv_set_proc(privstate);
139 if (result != 0 )
Kevin Steves4da21ab2001-08-14 21:02:15 +0000140 fatal("%s(%d): priv_set_proc(): %s",
Kevin Stevesf744b512001-08-14 20:31:49 +0000141 __FILE__, __LINE__, strerror(errno));
142 priv_free_proc(privstate);
143 }
144 debug ("Privileges should be cleared...");
Ben Lindstrom6db66ff2001-08-06 23:29:16 +0000145#else
Kevin Stevesf744b512001-08-14 20:31:49 +0000146 /* XXX: do this differently */
147# error Cray systems must be run with _SC_CRAY_PRIV_SU on!
Ben Lindstrom6db66ff2001-08-06 23:29:16 +0000148#endif
Ben Lindstromd9e08242001-07-22 19:32:00 +0000149}
150
151
152/*
153 * Retain utmp/wtmp information - used by cray accounting.
154 */
155void
156cray_retain_utmp(struct utmp *ut, int pid)
157{
158 int fd;
Kevin Stevesf744b512001-08-14 20:31:49 +0000159 struct utmp utmp;
Ben Lindstromd9e08242001-07-22 19:32:00 +0000160
Kevin Stevesf744b512001-08-14 20:31:49 +0000161 if ((fd = open(UTMP_FILE, O_RDONLY)) != -1) {
162 while (read(fd, (char *)&utmp, sizeof(utmp)) == sizeof(utmp)) {
163 if (pid == utmp.ut_pid) {
164 ut->ut_jid = utmp.ut_jid;
Kevin Steves72992af2001-08-14 20:54:52 +0000165 /* XXX: MIN_SIZEOF here? can this go in loginrec? */
166 strncpy(ut->ut_tpath, utmp.ut_tpath, sizeof(utmp.ut_tpath));
167 strncpy(ut->ut_host, utmp.ut_host, sizeof(utmp.ut_host));
168 strncpy(ut->ut_name, utmp.ut_name, sizeof(utmp.ut_name));
Kevin Stevesf744b512001-08-14 20:31:49 +0000169 break;
Ben Lindstromd9e08242001-07-22 19:32:00 +0000170 }
171 }
172 close(fd);
Kevin Stevesf744b512001-08-14 20:31:49 +0000173 }
174 /* XXX: error message? */
Ben Lindstromd9e08242001-07-22 19:32:00 +0000175}
176
177/*
178 * tmpdir support.
179 */
180
181/*
182 * find and delete jobs tmpdir.
183 */
184void
185cray_delete_tmpdir(char *login, int jid, uid_t uid)
186{
187 int child;
Kevin Stevesf744b512001-08-14 20:31:49 +0000188 static char jtmp[TPATHSIZ];
189 struct stat statbuf;
190 int c;
191 int wstat;
Ben Lindstromd9e08242001-07-22 19:32:00 +0000192
Kevin Stevesf744b512001-08-14 20:31:49 +0000193 for (c = 'a'; c <= 'z'; c++) {
194 snprintf(jtmp, TPATHSIZ, "%s/jtmp.%06d%c", JTMPDIR, jid, c);
195 if (stat(jtmp, &statbuf) == 0 && statbuf.st_uid == uid)
196 break;
197 }
Ben Lindstromd9e08242001-07-22 19:32:00 +0000198
Kevin Stevesf744b512001-08-14 20:31:49 +0000199 if (c > 'z')
200 return;
Ben Lindstromd9e08242001-07-22 19:32:00 +0000201
Kevin Stevesf744b512001-08-14 20:31:49 +0000202 if ((child = fork()) == 0) {
Kevin Steves4da21ab2001-08-14 21:02:15 +0000203 execl(CLEANTMPCMD, CLEANTMPCMD, login, jtmp, (char *)NULL);
Kevin Stevesf744b512001-08-14 20:31:49 +0000204 fatal("cray_delete_tmpdir: execl of CLEANTMPCMD failed");
205 }
Ben Lindstromd9e08242001-07-22 19:32:00 +0000206
Kevin Stevesf744b512001-08-14 20:31:49 +0000207 while (waitpid(child, &wstat, 0) == -1 && errno == EINTR)
208 ;
Ben Lindstromd9e08242001-07-22 19:32:00 +0000209}
210
211/*
212 * Remove tmpdir on job termination.
213 */
214void
Kevin Stevesf744b512001-08-14 20:31:49 +0000215cray_job_termination_handler(int sig)
Ben Lindstromd9e08242001-07-22 19:32:00 +0000216{
217 int jid;
218 char *login = NULL;
219 struct jtab jtab;
220
221 debug("Received SIG JOB.");
222
223 if ((jid = waitjob(&jtab)) == -1 ||
Kevin Stevesf744b512001-08-14 20:31:49 +0000224 (login = uid2nam(jtab.j_uid)) == NULL)
225 return;
Ben Lindstromd9e08242001-07-22 19:32:00 +0000226
227 cray_delete_tmpdir(login, jid, jtab.j_uid);
228}
229
Ben Lindstromd9e08242001-07-22 19:32:00 +0000230/*
231 * Set job id and create tmpdir directory.
232 */
Kevin Stevesf744b512001-08-14 20:31:49 +0000233void
Ben Lindstromd9e08242001-07-22 19:32:00 +0000234cray_init_job(struct passwd *pw)
Kevin Stevesf744b512001-08-14 20:31:49 +0000235{
236 int jid;
237 int c;
Ben Lindstromd9e08242001-07-22 19:32:00 +0000238
Kevin Stevesf744b512001-08-14 20:31:49 +0000239 jid = setjob(pw->pw_uid, WJSIGNAL);
240 if (jid < 0)
241 fatal("System call setjob failure");
Ben Lindstromd9e08242001-07-22 19:32:00 +0000242
Kevin Stevesf744b512001-08-14 20:31:49 +0000243 for (c = 'a'; c <= 'z'; c++) {
244 snprintf(cray_tmpdir, TPATHSIZ, "%s/jtmp.%06d%c", JTMPDIR, jid, c);
245 if (mkdir(cray_tmpdir, JTMPMODE) != 0)
246 continue;
247 if (chown(cray_tmpdir, pw->pw_uid, pw->pw_gid) != 0) {
248 rmdir(cray_tmpdir);
249 continue;
250 }
251 break;
252 }
Ben Lindstromd9e08242001-07-22 19:32:00 +0000253
Kevin Stevesf744b512001-08-14 20:31:49 +0000254 if (c > 'z')
255 cray_tmpdir[0] = '\0';
256}
Ben Lindstromd9e08242001-07-22 19:32:00 +0000257
258void
259cray_set_tmpdir(struct utmp *ut)
Kevin Stevesf744b512001-08-14 20:31:49 +0000260{
261 int jid;
262 struct jtab jbuf;
Ben Lindstromd9e08242001-07-22 19:32:00 +0000263
Kevin Stevesf744b512001-08-14 20:31:49 +0000264 if ((jid = getjtab(&jbuf)) < 0)
265 return;
Ben Lindstromd9e08242001-07-22 19:32:00 +0000266
267 /*
268 * Set jid and tmpdir in utmp record.
Kevin Stevesf744b512001-08-14 20:31:49 +0000269 */
Ben Lindstromd9e08242001-07-22 19:32:00 +0000270 ut->ut_jid = jid;
271 strncpy(ut->ut_tpath, cray_tmpdir, TPATHSIZ);
Kevin Stevesf744b512001-08-14 20:31:49 +0000272}
Ben Lindstromd9e08242001-07-22 19:32:00 +0000273#endif