]>
Commit | Line | Data |
---|---|---|
68187931 | 1 | /* |
2 | * XXX: license? | |
3 | */ | |
4 | ||
ca5c7d6a | 5 | /* |
6 | * 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> | |
1a23ac2c | 19 | #include <sys/priv.h> |
20 | #include <sys/secparm.h> | |
21 | #include <sys/usrv.h> | |
22 | #include <sys/sysv.h> | |
23 | #include <sys/sectab.h> | |
ca5c7d6a | 24 | #include <sys/stat.h> |
25 | #include <stdlib.h> | |
26 | #include <pwd.h> | |
27 | #include <fcntl.h> | |
28 | #include <errno.h> | |
29 | ||
1a23ac2c | 30 | #include "bsd-cray.h" |
31 | ||
68187931 | 32 | char cray_tmpdir[TPATHSIZ+1]; /* job TMPDIR path */ |
ca5c7d6a | 33 | |
34 | /* | |
35 | * Functions. | |
36 | */ | |
ca5c7d6a | 37 | void cray_retain_utmp(struct utmp *, int); |
8280a5ae | 38 | void cray_delete_tmpdir(char *, int, uid_t); |
ca5c7d6a | 39 | void cray_init_job(struct passwd *); |
40 | void cray_set_tmpdir(struct utmp *); | |
41 | ||
1a23ac2c | 42 | |
68187931 | 43 | /* |
ca5c7d6a | 44 | * Orignal written by: |
45 | * Wayne Schroeder | |
46 | * San Diego Supercomputer Center | |
47 | * schroeder@sdsc.edu | |
48 | */ | |
1a23ac2c | 49 | void |
ca5c7d6a | 50 | cray_setup(uid_t uid, char *username) |
51 | { | |
68187931 | 52 | struct udb *p; |
ca5c7d6a | 53 | extern char *setlimits(); |
68187931 | 54 | 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; | |
62 | ||
63 | if ((jid = getjtab(&jbuf)) < 0) | |
64 | fatal("getjtab: no jid"); | |
65 | ||
66 | err = setudb(); /* open and rewind the Cray User DataBase */ | |
67 | if (err != 0) | |
68 | fatal("UDB open failure"); | |
69 | naccts = 0; | |
1a23ac2c | 70 | p = getudbnam(username); |
68187931 | 71 | if (p == NULL) |
72 | fatal("No UDB entry for %.100s", username); | |
73 | if (uid != p->ue_uid) | |
8280a5ae | 74 | fatal("UDB entry %.100s uid(%d) does not match uid %d", |
75 | username, (int) p->ue_uid, (int) uid); | |
68187931 | 76 | for (j = 0; p->ue_acids[j] != -1 && j < MAXVIDS; j++) { |
77 | accts[naccts] = p->ue_acids[j]; | |
78 | naccts++; | |
79 | } | |
80 | endudb(); /* close the udb */ | |
81 | ||
82 | 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]); | |
1a23ac2c | 88 | } |
ca5c7d6a | 89 | |
68187931 | 90 | /* 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. */ | |
1a23ac2c | 93 | |
68187931 | 94 | pid = getpid(); |
95 | sr = setlimits(username, C_PROC, pid, UDBRC_INTER); | |
96 | if (sr != NULL) | |
97 | fatal("%.200s", sr); | |
1a23ac2c | 98 | |
68187931 | 99 | sr = setlimits(username, C_JOB, jid, UDBRC_INTER); |
100 | if (sr != NULL) | |
101 | fatal("%.200s", sr); | |
1a23ac2c | 102 | |
68187931 | 103 | } |
1a23ac2c | 104 | |
68187931 | 105 | /* |
1a23ac2c | 106 | * 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 | */ | |
111 | void | |
112 | drop_cray_privs() | |
113 | { | |
114 | #if defined(_SC_CRAY_PRIV_SU) | |
68187931 | 115 | 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; | |
1a23ac2c | 120 | |
121 | /* | |
122 | * If ether of theses two flags are not set | |
68187931 | 123 | * 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."); | |
1a23ac2c | 129 | |
68187931 | 130 | debug("Dropping privileges."); |
1a23ac2c | 131 | |
132 | memset(&usrv, 0, sizeof(usrv)); | |
68187931 | 133 | if (setusrv(&usrv) < 0) |
8280a5ae | 134 | fatal("%s(%d): setusrv(): %s", __FILE__, __LINE__, |
68187931 | 135 | strerror(errno)); |
ca5c7d6a | 136 | |
1a23ac2c | 137 | if ((privstate = priv_init_proc()) != NULL) { |
68187931 | 138 | result = priv_set_proc(privstate); |
139 | if (result != 0 ) | |
8280a5ae | 140 | fatal("%s(%d): priv_set_proc(): %s", |
68187931 | 141 | __FILE__, __LINE__, strerror(errno)); |
142 | priv_free_proc(privstate); | |
143 | } | |
144 | debug ("Privileges should be cleared..."); | |
1a23ac2c | 145 | #else |
68187931 | 146 | /* XXX: do this differently */ |
147 | # error Cray systems must be run with _SC_CRAY_PRIV_SU on! | |
1a23ac2c | 148 | #endif |
ca5c7d6a | 149 | } |
150 | ||
151 | ||
152 | /* | |
153 | * Retain utmp/wtmp information - used by cray accounting. | |
154 | */ | |
155 | void | |
156 | cray_retain_utmp(struct utmp *ut, int pid) | |
157 | { | |
158 | int fd; | |
68187931 | 159 | struct utmp utmp; |
160 | ||
161 | 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; | |
4809bc4c | 165 | /* 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)); | |
68187931 | 169 | break; |
ca5c7d6a | 170 | } |
171 | } | |
172 | close(fd); | |
68187931 | 173 | } |
174 | /* XXX: error message? */ | |
ca5c7d6a | 175 | } |
176 | ||
177 | /* | |
178 | * tmpdir support. | |
179 | */ | |
180 | ||
181 | /* | |
182 | * find and delete jobs tmpdir. | |
183 | */ | |
184 | void | |
185 | cray_delete_tmpdir(char *login, int jid, uid_t uid) | |
186 | { | |
187 | int child; | |
68187931 | 188 | static char jtmp[TPATHSIZ]; |
189 | struct stat statbuf; | |
190 | int c; | |
191 | int wstat; | |
192 | ||
193 | 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 | } | |
ca5c7d6a | 198 | |
68187931 | 199 | if (c > 'z') |
200 | return; | |
ca5c7d6a | 201 | |
68187931 | 202 | if ((child = fork()) == 0) { |
8280a5ae | 203 | execl(CLEANTMPCMD, CLEANTMPCMD, login, jtmp, (char *)NULL); |
68187931 | 204 | fatal("cray_delete_tmpdir: execl of CLEANTMPCMD failed"); |
205 | } | |
ca5c7d6a | 206 | |
68187931 | 207 | while (waitpid(child, &wstat, 0) == -1 && errno == EINTR) |
208 | ; | |
ca5c7d6a | 209 | } |
210 | ||
211 | /* | |
212 | * Remove tmpdir on job termination. | |
213 | */ | |
214 | void | |
68187931 | 215 | cray_job_termination_handler(int sig) |
ca5c7d6a | 216 | { |
217 | int jid; | |
218 | char *login = NULL; | |
219 | struct jtab jtab; | |
220 | ||
221 | debug("Received SIG JOB."); | |
222 | ||
223 | if ((jid = waitjob(&jtab)) == -1 || | |
68187931 | 224 | (login = uid2nam(jtab.j_uid)) == NULL) |
225 | return; | |
ca5c7d6a | 226 | |
227 | cray_delete_tmpdir(login, jid, jtab.j_uid); | |
228 | } | |
229 | ||
ca5c7d6a | 230 | /* |
231 | * Set job id and create tmpdir directory. | |
232 | */ | |
68187931 | 233 | void |
ca5c7d6a | 234 | cray_init_job(struct passwd *pw) |
68187931 | 235 | { |
236 | int jid; | |
237 | int c; | |
238 | ||
239 | jid = setjob(pw->pw_uid, WJSIGNAL); | |
240 | if (jid < 0) | |
241 | fatal("System call setjob failure"); | |
242 | ||
243 | 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 | } | |
253 | ||
254 | if (c > 'z') | |
255 | cray_tmpdir[0] = '\0'; | |
256 | } | |
ca5c7d6a | 257 | |
258 | void | |
259 | cray_set_tmpdir(struct utmp *ut) | |
68187931 | 260 | { |
261 | int jid; | |
262 | struct jtab jbuf; | |
ca5c7d6a | 263 | |
68187931 | 264 | if ((jid = getjtab(&jbuf)) < 0) |
265 | return; | |
ca5c7d6a | 266 | |
267 | /* | |
268 | * Set jid and tmpdir in utmp record. | |
68187931 | 269 | */ |
ca5c7d6a | 270 | ut->ut_jid = jid; |
271 | strncpy(ut->ut_tpath, cray_tmpdir, TPATHSIZ); | |
68187931 | 272 | } |
ca5c7d6a | 273 | #endif |