]>
Commit | Line | Data |
---|---|---|
ca5c7d6a | 1 | /* |
2 | * The modules contains code to support cray t3e and sv1 computers. | |
3 | * It is here to minimize the modifcations to the openssh base code. | |
4 | */ | |
5 | ||
6 | #ifdef _CRAY | |
7 | ||
8 | #include <udb.h> | |
9 | #include <tmpdir.h> | |
10 | #include <unistd.h> | |
11 | #include <sys/category.h> | |
12 | #include <utmp.h> | |
13 | #include <sys/jtab.h> | |
14 | #include <signal.h> | |
1a23ac2c | 15 | #include <sys/priv.h> |
16 | #include <sys/secparm.h> | |
17 | #include <sys/usrv.h> | |
18 | #include <sys/sysv.h> | |
19 | #include <sys/sectab.h> | |
ca5c7d6a | 20 | #include <sys/stat.h> |
21 | #include <stdlib.h> | |
22 | #include <pwd.h> | |
23 | #include <fcntl.h> | |
24 | #include <errno.h> | |
25 | ||
1a23ac2c | 26 | #include "bsd-cray.h" |
27 | ||
ca5c7d6a | 28 | char cray_tmpdir[TPATHSIZ+1]; /* job TMPDIR path */ |
29 | ||
30 | /* | |
31 | * Functions. | |
32 | */ | |
ca5c7d6a | 33 | void cray_retain_utmp(struct utmp *, int); |
34 | void cray_create_tmpdir(int, uid_t, gid_t); | |
35 | void cray_delete_tmpdir(char *, int , uid_t); | |
36 | void cray_job_termination_handler (int); | |
37 | void cray_init_job(struct passwd *); | |
38 | void cray_set_tmpdir(struct utmp *); | |
39 | ||
1a23ac2c | 40 | |
ca5c7d6a | 41 | /* |
42 | * Orignal written by: | |
43 | * Wayne Schroeder | |
44 | * San Diego Supercomputer Center | |
45 | * schroeder@sdsc.edu | |
46 | */ | |
1a23ac2c | 47 | void |
ca5c7d6a | 48 | cray_setup(uid_t uid, char *username) |
49 | { | |
50 | struct udb *p; | |
ca5c7d6a | 51 | extern char *setlimits(); |
52 | int i, j; | |
53 | int accts[MAXVIDS]; | |
54 | int naccts; | |
55 | int err; | |
56 | char *sr; | |
57 | int pid; | |
58 | struct jtab jbuf; | |
59 | int jid; | |
60 | ||
1a23ac2c | 61 | if ((jid = getjtab (&jbuf)) < 0) fatal("getjtab: no jid"); |
ca5c7d6a | 62 | |
1a23ac2c | 63 | err = setudb(); /* open and rewind the Cray User DataBase */ |
64 | if(err != 0) fatal("UDB open failure"); | |
ca5c7d6a | 65 | naccts = 0; |
1a23ac2c | 66 | p = getudbnam(username); |
67 | if (p == NULL) fatal("No UDB entry for %s", username); | |
68 | if(uid != p->ue_uid) | |
69 | fatal("UDB etnry %s uid(%d) does not match uid %d\n", | |
70 | username, p->ue_uid, uid); | |
71 | for(j = 0; p->ue_acids[j] != -1 && j < MAXVIDS; j++) { | |
72 | accts[naccts] = p->ue_acids[j]; | |
73 | naccts++; | |
ca5c7d6a | 74 | } |
1a23ac2c | 75 | endudb(); /* close the udb */ |
76 | ||
77 | if (naccts != 0) { | |
78 | /* Perhaps someday we'll prompt users who have multiple accounts | |
79 | to let them pick one (like CRI's login does), but for now just set | |
80 | the account to the first entry. */ | |
81 | if (acctid(0, accts[0]) < 0) | |
82 | fatal("System call acctid failed, accts[0]=%d",accts[0]); | |
83 | } | |
ca5c7d6a | 84 | |
1a23ac2c | 85 | /* Now set limits, including CPU time for the (interactive) job and process, |
86 | and set up permissions (for chown etc), etc. This is via an internal CRI | |
87 | routine, setlimits, used by CRI's login. */ | |
ca5c7d6a | 88 | |
89 | pid = getpid(); | |
90 | sr = setlimits(username, C_PROC, pid, UDBRC_INTER); | |
1a23ac2c | 91 | if (sr != NULL) fatal("%.200s", sr); |
92 | ||
ca5c7d6a | 93 | sr = setlimits(username, C_JOB, jid, UDBRC_INTER); |
1a23ac2c | 94 | if (sr != NULL) fatal("%.200s", sr); |
95 | ||
96 | } | |
97 | ||
98 | ||
99 | /* | |
100 | * The rc.* and /etc/sdaemon methods of starting a program on unicos/unicosmk | |
101 | * can have pal privileges that sshd can inherit which | |
102 | * could allow a user to su to root with out a password. | |
103 | * This subroutine clears all privileges. | |
104 | */ | |
105 | void | |
106 | drop_cray_privs() | |
107 | { | |
108 | #if defined(_SC_CRAY_PRIV_SU) | |
109 | priv_proc_t* privstate; | |
110 | int result; | |
111 | extern int priv_set_proc(); | |
112 | extern priv_proc_t* priv_init_proc(); | |
113 | struct usrv usrv; | |
114 | ||
115 | /* | |
116 | * If ether of theses two flags are not set | |
117 | * then don't allow this version of ssh to run. | |
118 | */ | |
119 | if (!sysconf(_SC_CRAY_PRIV_SU)) fatal("Not PRIV_SU system."); | |
120 | if (!sysconf(_SC_CRAY_POSIX_PRIV)) fatal("Not POSIX_PRIV."); | |
121 | ||
122 | debug ("Dropping privileges."); | |
123 | ||
124 | memset(&usrv, 0, sizeof(usrv)); | |
125 | if (setusrv(&usrv) < 0) | |
126 | fatal ("%s(%d): setusrv(): %s\n", __FILE__, __LINE__, strerror(errno)); | |
ca5c7d6a | 127 | |
1a23ac2c | 128 | if ((privstate = priv_init_proc()) != NULL) { |
129 | result = priv_set_proc(privstate); | |
130 | if ( result != 0 ) fatal ("%s(%d): priv_set_proc(): %s\n", | |
131 | __FILE__, __LINE__, strerror(errno)); | |
132 | priv_free_proc(privstate); | |
133 | } | |
134 | debug ("Privileges should be cleared..."); | |
135 | #else | |
136 | Cray systems must be run with _SC_CRAY_PRIV_SU on! | |
137 | #endif | |
ca5c7d6a | 138 | } |
139 | ||
140 | ||
141 | /* | |
142 | * Retain utmp/wtmp information - used by cray accounting. | |
143 | */ | |
144 | void | |
145 | cray_retain_utmp(struct utmp *ut, int pid) | |
146 | { | |
147 | int fd; | |
148 | struct utmp utmp; | |
149 | ||
150 | if ((fd = open(UTMP_FILE, O_RDONLY)) >= 0) { | |
151 | while (read(fd, (char *)&utmp, sizeof(utmp)) == sizeof(utmp)) { | |
152 | if (pid == utmp.ut_pid) { | |
153 | ut->ut_jid = utmp.ut_jid; | |
154 | strncpy(ut->ut_tpath, utmp.ut_tpath, TPATHSIZ); | |
155 | strncpy(ut->ut_host, utmp.ut_host, strlen(utmp.ut_host)); | |
156 | strncpy(ut->ut_name, utmp.ut_name, strlen(utmp.ut_name)); | |
157 | break; | |
158 | } | |
159 | } | |
160 | close(fd); | |
161 | } | |
162 | } | |
163 | ||
164 | /* | |
165 | * tmpdir support. | |
166 | */ | |
167 | ||
168 | /* | |
169 | * find and delete jobs tmpdir. | |
170 | */ | |
171 | void | |
172 | cray_delete_tmpdir(char *login, int jid, uid_t uid) | |
173 | { | |
174 | int child; | |
175 | static char jtmp[TPATHSIZ]; | |
176 | struct stat statbuf; | |
177 | int c; | |
178 | int wstat; | |
179 | ||
180 | for (c = 'a'; c <= 'z'; c++) { | |
181 | snprintf(jtmp, TPATHSIZ, "%s/jtmp.%06d%c", JTMPDIR, jid, c); | |
182 | if (stat(jtmp, &statbuf) == 0 && statbuf.st_uid == uid) break; | |
183 | } | |
184 | ||
185 | if (c > 'z') return; | |
186 | ||
187 | if ((child = fork()) == 0) { | |
188 | execl(CLEANTMPCMD, CLEANTMPCMD, login, jtmp, 0); | |
189 | fatal("ssh_cray_rmtmpdir: execl of CLEANTMPCMD failed"); | |
190 | } | |
191 | ||
192 | while (waitpid (child, &wstat, 0) == -1 && errno == EINTR); | |
193 | } | |
194 | ||
195 | /* | |
196 | * Remove tmpdir on job termination. | |
197 | */ | |
198 | void | |
199 | cray_job_termination_handler (int sig) | |
200 | { | |
201 | int jid; | |
202 | char *login = NULL; | |
203 | struct jtab jtab; | |
204 | ||
205 | debug("Received SIG JOB."); | |
206 | ||
207 | if ((jid = waitjob(&jtab)) == -1 || | |
208 | (login = uid2nam(jtab.j_uid)) == NULL) return; | |
209 | ||
210 | cray_delete_tmpdir(login, jid, jtab.j_uid); | |
211 | } | |
212 | ||
213 | ||
214 | /* | |
215 | * Set job id and create tmpdir directory. | |
216 | */ | |
217 | void | |
218 | cray_init_job(struct passwd *pw) | |
219 | { | |
220 | int jid; | |
221 | int c; | |
222 | ||
223 | jid = setjob(pw->pw_uid, WJSIGNAL); | |
224 | if (jid < 0) fatal("System call setjob failure"); | |
225 | ||
226 | for (c = 'a'; c <= 'z'; c++) { | |
227 | snprintf(cray_tmpdir, TPATHSIZ, "%s/jtmp.%06d%c", JTMPDIR, jid, c); | |
228 | if (mkdir(cray_tmpdir, JTMPMODE) != 0) continue; | |
229 | if (chown(cray_tmpdir, pw->pw_uid, pw->pw_gid) != 0) { | |
230 | rmdir(cray_tmpdir); | |
231 | continue; | |
232 | } | |
233 | break; | |
234 | } | |
235 | ||
236 | if (c > 'z') cray_tmpdir[0] = '\0'; | |
237 | } | |
238 | ||
239 | void | |
240 | cray_set_tmpdir(struct utmp *ut) | |
241 | { | |
242 | int jid; | |
243 | struct jtab jbuf; | |
244 | ||
245 | if ((jid = getjtab (&jbuf)) < 0) return; | |
246 | ||
247 | /* | |
248 | * Set jid and tmpdir in utmp record. | |
249 | */ | |
250 | ut->ut_jid = jid; | |
251 | strncpy(ut->ut_tpath, cray_tmpdir, TPATHSIZ); | |
252 | } | |
253 | ||
254 | #endif |