]>
Commit | Line | Data |
---|---|---|
3c0ef626 | 1 | /* |
2 | * XXX: license? | |
3 | */ | |
4 | ||
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> | |
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> | |
24 | #include <sys/stat.h> | |
25 | #include <stdlib.h> | |
26 | #include <pwd.h> | |
27 | #include <fcntl.h> | |
28 | #include <errno.h> | |
29 | ||
30 | #include "bsd-cray.h" | |
31 | ||
32 | char cray_tmpdir[TPATHSIZ+1]; /* job TMPDIR path */ | |
33 | ||
34 | /* | |
35 | * Functions. | |
36 | */ | |
37 | void cray_retain_utmp(struct utmp *, int); | |
38 | void cray_delete_tmpdir(char *, int, uid_t); | |
39 | void cray_init_job(struct passwd *); | |
40 | void cray_set_tmpdir(struct utmp *); | |
41 | ||
42 | ||
43 | /* | |
44 | * Orignal written by: | |
45 | * Wayne Schroeder | |
46 | * San Diego Supercomputer Center | |
47 | * schroeder@sdsc.edu | |
48 | */ | |
49 | void | |
50 | cray_setup(uid_t uid, char *username) | |
51 | { | |
52 | struct udb *p; | |
53 | extern char *setlimits(); | |
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; | |
70 | p = getudbnam(username); | |
71 | if (p == NULL) | |
72 | fatal("No UDB entry for %.100s", username); | |
73 | if (uid != p->ue_uid) | |
74 | fatal("UDB entry %.100s uid(%d) does not match uid %d", | |
75 | username, (int) p->ue_uid, (int) uid); | |
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]); | |
88 | } | |
89 | ||
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. */ | |
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); | |
102 | ||
103 | } | |
104 | ||
105 | /* | |
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) | |
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; | |
120 | ||
121 | /* | |
122 | * If ether of theses two flags are not set | |
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."); | |
129 | ||
130 | debug("Dropping privileges."); | |
131 | ||
132 | memset(&usrv, 0, sizeof(usrv)); | |
133 | if (setusrv(&usrv) < 0) | |
134 | fatal("%s(%d): setusrv(): %s", __FILE__, __LINE__, | |
135 | strerror(errno)); | |
136 | ||
137 | if ((privstate = priv_init_proc()) != NULL) { | |
138 | result = priv_set_proc(privstate); | |
139 | if (result != 0 ) | |
140 | fatal("%s(%d): priv_set_proc(): %s", | |
141 | __FILE__, __LINE__, strerror(errno)); | |
142 | priv_free_proc(privstate); | |
143 | } | |
144 | debug ("Privileges should be cleared..."); | |
145 | #else | |
146 | /* XXX: do this differently */ | |
147 | # error Cray systems must be run with _SC_CRAY_PRIV_SU on! | |
148 | #endif | |
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; | |
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; | |
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)); | |
169 | break; | |
170 | } | |
171 | } | |
172 | close(fd); | |
173 | } | |
174 | /* XXX: error message? */ | |
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; | |
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 | } | |
198 | ||
199 | if (c > 'z') | |
200 | return; | |
201 | ||
202 | if ((child = fork()) == 0) { | |
203 | execl(CLEANTMPCMD, CLEANTMPCMD, login, jtmp, (char *)NULL); | |
204 | fatal("cray_delete_tmpdir: execl of CLEANTMPCMD failed"); | |
205 | } | |
206 | ||
207 | while (waitpid(child, &wstat, 0) == -1 && errno == EINTR) | |
208 | ; | |
209 | } | |
210 | ||
211 | /* | |
212 | * Remove tmpdir on job termination. | |
213 | */ | |
214 | void | |
215 | cray_job_termination_handler(int sig) | |
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 || | |
224 | (login = uid2nam(jtab.j_uid)) == NULL) | |
225 | return; | |
226 | ||
227 | cray_delete_tmpdir(login, jid, jtab.j_uid); | |
228 | } | |
229 | ||
230 | /* | |
231 | * Set job id and create tmpdir directory. | |
232 | */ | |
233 | void | |
234 | cray_init_job(struct passwd *pw) | |
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 | } | |
257 | ||
258 | void | |
259 | cray_set_tmpdir(struct utmp *ut) | |
260 | { | |
261 | int jid; | |
262 | struct jtab jbuf; | |
263 | ||
264 | if ((jid = getjtab(&jbuf)) < 0) | |
265 | return; | |
266 | ||
267 | /* | |
268 | * Set jid and tmpdir in utmp record. | |
269 | */ | |
270 | ut->ut_jid = jid; | |
271 | strncpy(ut->ut_tpath, cray_tmpdir, TPATHSIZ); | |
272 | } | |
273 | #endif |