]>
Commit | Line | Data |
---|---|---|
700318f3 | 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 | * | |
3c0ef626 | 36 | */ |
37 | ||
38 | #ifdef _CRAY | |
3c0ef626 | 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> | |
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> | |
51 | #include <sys/stat.h> | |
52 | #include <stdlib.h> | |
53 | #include <pwd.h> | |
54 | #include <fcntl.h> | |
55 | #include <errno.h> | |
56 | ||
57 | #include "bsd-cray.h" | |
58 | ||
59 | char cray_tmpdir[TPATHSIZ+1]; /* job TMPDIR path */ | |
60 | ||
61 | /* | |
62 | * Functions. | |
63 | */ | |
64 | void cray_retain_utmp(struct utmp *, int); | |
65 | void cray_delete_tmpdir(char *, int, uid_t); | |
66 | void cray_init_job(struct passwd *); | |
67 | void cray_set_tmpdir(struct utmp *); | |
68 | ||
69 | ||
70 | /* | |
71 | * Orignal written by: | |
72 | * Wayne Schroeder | |
73 | * San Diego Supercomputer Center | |
74 | * schroeder@sdsc.edu | |
75 | */ | |
76 | void | |
77 | cray_setup(uid_t uid, char *username) | |
78 | { | |
79 | struct udb *p; | |
80 | extern char *setlimits(); | |
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; | |
97 | p = getudbnam(username); | |
98 | if (p == NULL) | |
99 | fatal("No UDB entry for %.100s", username); | |
100 | if (uid != p->ue_uid) | |
101 | fatal("UDB entry %.100s uid(%d) does not match uid %d", | |
102 | username, (int) p->ue_uid, (int) uid); | |
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]); | |
115 | } | |
116 | ||
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. */ | |
120 | ||
121 | pid = getpid(); | |
122 | sr = setlimits(username, C_PROC, pid, UDBRC_INTER); | |
123 | if (sr != NULL) | |
124 | fatal("%.200s", sr); | |
125 | ||
126 | sr = setlimits(username, C_JOB, jid, UDBRC_INTER); | |
127 | if (sr != NULL) | |
128 | fatal("%.200s", sr); | |
129 | ||
130 | } | |
131 | ||
132 | /* | |
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) | |
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; | |
147 | ||
148 | /* | |
149 | * If ether of theses two flags are not set | |
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."); | |
156 | ||
157 | debug("Dropping privileges."); | |
158 | ||
159 | memset(&usrv, 0, sizeof(usrv)); | |
160 | if (setusrv(&usrv) < 0) | |
161 | fatal("%s(%d): setusrv(): %s", __FILE__, __LINE__, | |
162 | strerror(errno)); | |
163 | ||
164 | if ((privstate = priv_init_proc()) != NULL) { | |
165 | result = priv_set_proc(privstate); | |
166 | if (result != 0 ) | |
167 | fatal("%s(%d): priv_set_proc(): %s", | |
168 | __FILE__, __LINE__, strerror(errno)); | |
169 | priv_free_proc(privstate); | |
170 | } | |
171 | debug ("Privileges should be cleared..."); | |
172 | #else | |
173 | /* XXX: do this differently */ | |
174 | # error Cray systems must be run with _SC_CRAY_PRIV_SU on! | |
175 | #endif | |
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; | |
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; | |
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)); | |
196 | break; | |
197 | } | |
198 | } | |
199 | close(fd); | |
200 | } | |
201 | /* XXX: error message? */ | |
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; | |
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 | } | |
225 | ||
226 | if (c > 'z') | |
227 | return; | |
228 | ||
229 | if ((child = fork()) == 0) { | |
230 | execl(CLEANTMPCMD, CLEANTMPCMD, login, jtmp, (char *)NULL); | |
231 | fatal("cray_delete_tmpdir: execl of CLEANTMPCMD failed"); | |
232 | } | |
233 | ||
234 | while (waitpid(child, &wstat, 0) == -1 && errno == EINTR) | |
235 | ; | |
236 | } | |
237 | ||
238 | /* | |
239 | * Remove tmpdir on job termination. | |
240 | */ | |
241 | void | |
242 | cray_job_termination_handler(int sig) | |
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 || | |
251 | (login = uid2nam(jtab.j_uid)) == NULL) | |
252 | return; | |
253 | ||
254 | cray_delete_tmpdir(login, jid, jtab.j_uid); | |
255 | } | |
256 | ||
257 | /* | |
258 | * Set job id and create tmpdir directory. | |
259 | */ | |
260 | void | |
261 | cray_init_job(struct passwd *pw) | |
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 | } | |
284 | ||
285 | void | |
286 | cray_set_tmpdir(struct utmp *ut) | |
287 | { | |
288 | int jid; | |
289 | struct jtab jbuf; | |
290 | ||
291 | if ((jid = getjtab(&jbuf)) < 0) | |
292 | return; | |
293 | ||
294 | /* | |
295 | * Set jid and tmpdir in utmp record. | |
296 | */ | |
297 | ut->ut_jid = jid; | |
298 | strncpy(ut->ut_tpath, cray_tmpdir, TPATHSIZ); | |
299 | } | |
300 | #endif |