]>
Commit | Line | Data |
---|---|---|
0c83d9ea | 1 | /* |
2 | * $Id$ | |
3 | * | |
4 | * bsd-cray.c | |
5 | * | |
6 | * Copyright (c) 2002, Cray Inc. (Wendy Palm <wendyp@cray.com>) | |
7 | * Significant portions provided by | |
8 | * Wayne Schroeder, SDSC <schroeder@sdsc.edu> | |
9 | * William Jones, UTexas <jones@tacc.utexas.edu> | |
10 | * | |
11 | * Redistribution and use in source and binary forms, with or without | |
12 | * modification, are permitted provided that the following conditions | |
13 | * are met: | |
14 | * 1. Redistributions of source code must retain the above copyright | |
15 | * notice, this list of conditions and the following disclaimer. | |
16 | * 2. Redistributions in binary form must reproduce the above copyright | |
17 | * notice, this list of conditions and the following disclaimer in the | |
18 | * documentation and/or other materials provided with the distribution. | |
19 | * | |
20 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | |
21 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |
22 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |
23 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
24 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
25 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
26 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
27 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
28 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
29 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
30 | * | |
31 | * Created: Apr 22 16.34:00 2002 wp | |
32 | * | |
33 | * This file contains functions required for proper execution | |
34 | * on UNICOS systems. | |
35 | * | |
ca5c7d6a | 36 | */ |
37 | ||
38 | #ifdef _CRAY | |
ca5c7d6a | 39 | #include <udb.h> |
40 | #include <tmpdir.h> | |
41 | #include <unistd.h> | |
42 | #include <sys/category.h> | |
43 | #include <utmp.h> | |
44 | #include <sys/jtab.h> | |
45 | #include <signal.h> | |
1a23ac2c | 46 | #include <sys/priv.h> |
47 | #include <sys/secparm.h> | |
48 | #include <sys/usrv.h> | |
49 | #include <sys/sysv.h> | |
50 | #include <sys/sectab.h> | |
ca5c7d6a | 51 | #include <sys/stat.h> |
52 | #include <stdlib.h> | |
53 | #include <pwd.h> | |
54 | #include <fcntl.h> | |
55 | #include <errno.h> | |
56 | ||
1a23ac2c | 57 | #include "bsd-cray.h" |
58 | ||
68187931 | 59 | char cray_tmpdir[TPATHSIZ+1]; /* job TMPDIR path */ |
ca5c7d6a | 60 | |
61 | /* | |
62 | * Functions. | |
63 | */ | |
ca5c7d6a | 64 | void cray_retain_utmp(struct utmp *, int); |
8280a5ae | 65 | void cray_delete_tmpdir(char *, int, uid_t); |
ca5c7d6a | 66 | void cray_init_job(struct passwd *); |
67 | void cray_set_tmpdir(struct utmp *); | |
68 | ||
1a23ac2c | 69 | |
68187931 | 70 | /* |
ca5c7d6a | 71 | * Orignal written by: |
72 | * Wayne Schroeder | |
73 | * San Diego Supercomputer Center | |
74 | * schroeder@sdsc.edu | |
75 | */ | |
1a23ac2c | 76 | void |
ca5c7d6a | 77 | cray_setup(uid_t uid, char *username) |
78 | { | |
68187931 | 79 | struct udb *p; |
ca5c7d6a | 80 | extern char *setlimits(); |
68187931 | 81 | int i, j; |
82 | int accts[MAXVIDS]; | |
83 | int naccts; | |
84 | int err; | |
85 | char *sr; | |
86 | int pid; | |
87 | struct jtab jbuf; | |
88 | int jid; | |
89 | ||
90 | if ((jid = getjtab(&jbuf)) < 0) | |
91 | fatal("getjtab: no jid"); | |
92 | ||
93 | err = setudb(); /* open and rewind the Cray User DataBase */ | |
94 | if (err != 0) | |
95 | fatal("UDB open failure"); | |
96 | naccts = 0; | |
1a23ac2c | 97 | p = getudbnam(username); |
68187931 | 98 | if (p == NULL) |
99 | fatal("No UDB entry for %.100s", username); | |
100 | if (uid != p->ue_uid) | |
8280a5ae | 101 | fatal("UDB entry %.100s uid(%d) does not match uid %d", |
102 | username, (int) p->ue_uid, (int) uid); | |
68187931 | 103 | for (j = 0; p->ue_acids[j] != -1 && j < MAXVIDS; j++) { |
104 | accts[naccts] = p->ue_acids[j]; | |
105 | naccts++; | |
106 | } | |
107 | endudb(); /* close the udb */ | |
108 | ||
109 | if (naccts != 0) { | |
110 | /* Perhaps someday we'll prompt users who have multiple accounts | |
111 | to let them pick one (like CRI's login does), but for now just set | |
112 | the account to the first entry. */ | |
113 | if (acctid(0, accts[0]) < 0) | |
114 | fatal("System call acctid failed, accts[0]=%d", accts[0]); | |
1a23ac2c | 115 | } |
ca5c7d6a | 116 | |
68187931 | 117 | /* Now set limits, including CPU time for the (interactive) job and process, |
118 | and set up permissions (for chown etc), etc. This is via an internal CRI | |
119 | routine, setlimits, used by CRI's login. */ | |
1a23ac2c | 120 | |
68187931 | 121 | pid = getpid(); |
122 | sr = setlimits(username, C_PROC, pid, UDBRC_INTER); | |
123 | if (sr != NULL) | |
124 | fatal("%.200s", sr); | |
1a23ac2c | 125 | |
68187931 | 126 | sr = setlimits(username, C_JOB, jid, UDBRC_INTER); |
127 | if (sr != NULL) | |
128 | fatal("%.200s", sr); | |
1a23ac2c | 129 | |
68187931 | 130 | } |
1a23ac2c | 131 | |
68187931 | 132 | /* |
1a23ac2c | 133 | * The rc.* and /etc/sdaemon methods of starting a program on unicos/unicosmk |
134 | * can have pal privileges that sshd can inherit which | |
135 | * could allow a user to su to root with out a password. | |
136 | * This subroutine clears all privileges. | |
137 | */ | |
138 | void | |
139 | drop_cray_privs() | |
140 | { | |
141 | #if defined(_SC_CRAY_PRIV_SU) | |
68187931 | 142 | priv_proc_t* privstate; |
143 | int result; | |
144 | extern int priv_set_proc(); | |
145 | extern priv_proc_t* priv_init_proc(); | |
146 | struct usrv usrv; | |
1a23ac2c | 147 | |
148 | /* | |
149 | * If ether of theses two flags are not set | |
68187931 | 150 | * then don't allow this version of ssh to run. |
151 | */ | |
152 | if (!sysconf(_SC_CRAY_PRIV_SU)) | |
153 | fatal("Not PRIV_SU system."); | |
154 | if (!sysconf(_SC_CRAY_POSIX_PRIV)) | |
155 | fatal("Not POSIX_PRIV."); | |
1a23ac2c | 156 | |
68187931 | 157 | debug("Dropping privileges."); |
1a23ac2c | 158 | |
159 | memset(&usrv, 0, sizeof(usrv)); | |
68187931 | 160 | if (setusrv(&usrv) < 0) |
8280a5ae | 161 | fatal("%s(%d): setusrv(): %s", __FILE__, __LINE__, |
68187931 | 162 | strerror(errno)); |
ca5c7d6a | 163 | |
1a23ac2c | 164 | if ((privstate = priv_init_proc()) != NULL) { |
68187931 | 165 | result = priv_set_proc(privstate); |
166 | if (result != 0 ) | |
8280a5ae | 167 | fatal("%s(%d): priv_set_proc(): %s", |
68187931 | 168 | __FILE__, __LINE__, strerror(errno)); |
169 | priv_free_proc(privstate); | |
170 | } | |
171 | debug ("Privileges should be cleared..."); | |
1a23ac2c | 172 | #else |
68187931 | 173 | /* XXX: do this differently */ |
174 | # error Cray systems must be run with _SC_CRAY_PRIV_SU on! | |
1a23ac2c | 175 | #endif |
ca5c7d6a | 176 | } |
177 | ||
178 | ||
179 | /* | |
180 | * Retain utmp/wtmp information - used by cray accounting. | |
181 | */ | |
182 | void | |
183 | cray_retain_utmp(struct utmp *ut, int pid) | |
184 | { | |
185 | int fd; | |
68187931 | 186 | struct utmp utmp; |
187 | ||
188 | if ((fd = open(UTMP_FILE, O_RDONLY)) != -1) { | |
189 | while (read(fd, (char *)&utmp, sizeof(utmp)) == sizeof(utmp)) { | |
190 | if (pid == utmp.ut_pid) { | |
191 | ut->ut_jid = utmp.ut_jid; | |
4809bc4c | 192 | /* XXX: MIN_SIZEOF here? can this go in loginrec? */ |
193 | strncpy(ut->ut_tpath, utmp.ut_tpath, sizeof(utmp.ut_tpath)); | |
194 | strncpy(ut->ut_host, utmp.ut_host, sizeof(utmp.ut_host)); | |
195 | strncpy(ut->ut_name, utmp.ut_name, sizeof(utmp.ut_name)); | |
68187931 | 196 | break; |
ca5c7d6a | 197 | } |
198 | } | |
199 | close(fd); | |
68187931 | 200 | } |
201 | /* XXX: error message? */ | |
ca5c7d6a | 202 | } |
203 | ||
204 | /* | |
205 | * tmpdir support. | |
206 | */ | |
207 | ||
208 | /* | |
209 | * find and delete jobs tmpdir. | |
210 | */ | |
211 | void | |
212 | cray_delete_tmpdir(char *login, int jid, uid_t uid) | |
213 | { | |
214 | int child; | |
68187931 | 215 | static char jtmp[TPATHSIZ]; |
216 | struct stat statbuf; | |
217 | int c; | |
218 | int wstat; | |
219 | ||
220 | for (c = 'a'; c <= 'z'; c++) { | |
221 | snprintf(jtmp, TPATHSIZ, "%s/jtmp.%06d%c", JTMPDIR, jid, c); | |
222 | if (stat(jtmp, &statbuf) == 0 && statbuf.st_uid == uid) | |
223 | break; | |
224 | } | |
ca5c7d6a | 225 | |
68187931 | 226 | if (c > 'z') |
227 | return; | |
ca5c7d6a | 228 | |
68187931 | 229 | if ((child = fork()) == 0) { |
8280a5ae | 230 | execl(CLEANTMPCMD, CLEANTMPCMD, login, jtmp, (char *)NULL); |
68187931 | 231 | fatal("cray_delete_tmpdir: execl of CLEANTMPCMD failed"); |
232 | } | |
ca5c7d6a | 233 | |
68187931 | 234 | while (waitpid(child, &wstat, 0) == -1 && errno == EINTR) |
235 | ; | |
ca5c7d6a | 236 | } |
237 | ||
238 | /* | |
239 | * Remove tmpdir on job termination. | |
240 | */ | |
241 | void | |
68187931 | 242 | cray_job_termination_handler(int sig) |
ca5c7d6a | 243 | { |
244 | int jid; | |
245 | char *login = NULL; | |
246 | struct jtab jtab; | |
247 | ||
248 | debug("Received SIG JOB."); | |
249 | ||
250 | if ((jid = waitjob(&jtab)) == -1 || | |
68187931 | 251 | (login = uid2nam(jtab.j_uid)) == NULL) |
252 | return; | |
ca5c7d6a | 253 | |
254 | cray_delete_tmpdir(login, jid, jtab.j_uid); | |
255 | } | |
256 | ||
ca5c7d6a | 257 | /* |
258 | * Set job id and create tmpdir directory. | |
259 | */ | |
68187931 | 260 | void |
ca5c7d6a | 261 | cray_init_job(struct passwd *pw) |
68187931 | 262 | { |
263 | int jid; | |
264 | int c; | |
265 | ||
266 | jid = setjob(pw->pw_uid, WJSIGNAL); | |
267 | if (jid < 0) | |
268 | fatal("System call setjob failure"); | |
269 | ||
270 | for (c = 'a'; c <= 'z'; c++) { | |
271 | snprintf(cray_tmpdir, TPATHSIZ, "%s/jtmp.%06d%c", JTMPDIR, jid, c); | |
272 | if (mkdir(cray_tmpdir, JTMPMODE) != 0) | |
273 | continue; | |
274 | if (chown(cray_tmpdir, pw->pw_uid, pw->pw_gid) != 0) { | |
275 | rmdir(cray_tmpdir); | |
276 | continue; | |
277 | } | |
278 | break; | |
279 | } | |
280 | ||
281 | if (c > 'z') | |
282 | cray_tmpdir[0] = '\0'; | |
283 | } | |
ca5c7d6a | 284 | |
285 | void | |
286 | cray_set_tmpdir(struct utmp *ut) | |
68187931 | 287 | { |
288 | int jid; | |
289 | struct jtab jbuf; | |
ca5c7d6a | 290 | |
68187931 | 291 | if ((jid = getjtab(&jbuf)) < 0) |
292 | return; | |
ca5c7d6a | 293 | |
294 | /* | |
295 | * Set jid and tmpdir in utmp record. | |
68187931 | 296 | */ |
ca5c7d6a | 297 | ut->ut_jid = jid; |
298 | strncpy(ut->ut_tpath, cray_tmpdir, TPATHSIZ); | |
68187931 | 299 | } |
ca5c7d6a | 300 | #endif |