diff options
Diffstat (limited to 'openbsd-compat/bsd-cray.c')
-rw-r--r-- | openbsd-compat/bsd-cray.c | 223 |
1 files changed, 223 insertions, 0 deletions
diff --git a/openbsd-compat/bsd-cray.c b/openbsd-compat/bsd-cray.c new file mode 100644 index 000000000..c887322cb --- /dev/null +++ b/openbsd-compat/bsd-cray.c | |||
@@ -0,0 +1,223 @@ | |||
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> | ||
15 | #include <sys/stat.h> | ||
16 | #include <stdlib.h> | ||
17 | #include <pwd.h> | ||
18 | #include <fcntl.h> | ||
19 | #include <errno.h> | ||
20 | |||
21 | char cray_tmpdir[TPATHSIZ+1]; /* job TMPDIR path */ | ||
22 | |||
23 | /* | ||
24 | * Functions. | ||
25 | */ | ||
26 | int cray_setup(uid_t, char *); | ||
27 | void cray_retain_utmp(struct utmp *, int); | ||
28 | void cray_create_tmpdir(int, uid_t, gid_t); | ||
29 | void cray_delete_tmpdir(char *, int , uid_t); | ||
30 | void cray_job_termination_handler (int); | ||
31 | void cray_init_job(struct passwd *); | ||
32 | void cray_set_tmpdir(struct utmp *); | ||
33 | |||
34 | /* | ||
35 | * Orignal written by: | ||
36 | * Wayne Schroeder | ||
37 | * San Diego Supercomputer Center | ||
38 | * schroeder@sdsc.edu | ||
39 | */ | ||
40 | int | ||
41 | cray_setup(uid_t uid, char *username) | ||
42 | { | ||
43 | struct udb *p; | ||
44 | extern struct udb *getudb(); | ||
45 | extern char *setlimits(); | ||
46 | int i, j; | ||
47 | int accts[MAXVIDS]; | ||
48 | int naccts; | ||
49 | int err; | ||
50 | char *sr; | ||
51 | int pid; | ||
52 | struct jtab jbuf; | ||
53 | int jid; | ||
54 | |||
55 | if ((jid = getjtab (&jbuf)) < 0) { | ||
56 | debug("getjtab"); | ||
57 | return -1; | ||
58 | } | ||
59 | |||
60 | /* Find all of the accounts for a particular user */ | ||
61 | err = setudb(); /* open and rewind the Cray User DataBase */ | ||
62 | if(err != 0) { | ||
63 | debug("UDB open failure"); | ||
64 | return -1; | ||
65 | } | ||
66 | naccts = 0; | ||
67 | while ((p = getudb()) != UDB_NULL) { | ||
68 | if (p->ue_uid == -1) break; | ||
69 | if(uid == p->ue_uid) { | ||
70 | for(j = 0; p->ue_acids[j] != -1 && j < MAXVIDS; j++) { | ||
71 | accts[naccts] = p->ue_acids[j]; | ||
72 | naccts++; | ||
73 | } | ||
74 | } | ||
75 | } | ||
76 | endudb(); /* close the udb */ | ||
77 | if (naccts == 0 || accts[0] == 0) { | ||
78 | debug("No Cray accounts found"); | ||
79 | return -1; | ||
80 | } | ||
81 | |||
82 | /* Perhaps someday we'll prompt users who have multiple accounts | ||
83 | to let them pick one (like CRI's login does), but for now just set | ||
84 | the account to the first entry. */ | ||
85 | if (acctid(0, accts[0]) < 0) { | ||
86 | debug("System call acctid failed, accts[0]=%d",accts[0]); | ||
87 | return -1; | ||
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 | debug("%.200s", sr); | ||
98 | return -1; | ||
99 | } | ||
100 | sr = setlimits(username, C_JOB, jid, UDBRC_INTER); | ||
101 | if (sr != NULL) { | ||
102 | debug("%.200s", sr); | ||
103 | return -1; | ||
104 | } | ||
105 | |||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | |||
110 | /* | ||
111 | * Retain utmp/wtmp information - used by cray accounting. | ||
112 | */ | ||
113 | void | ||
114 | cray_retain_utmp(struct utmp *ut, int pid) | ||
115 | { | ||
116 | int fd; | ||
117 | struct utmp utmp; | ||
118 | |||
119 | if ((fd = open(UTMP_FILE, O_RDONLY)) >= 0) { | ||
120 | while (read(fd, (char *)&utmp, sizeof(utmp)) == sizeof(utmp)) { | ||
121 | if (pid == utmp.ut_pid) { | ||
122 | ut->ut_jid = utmp.ut_jid; | ||
123 | strncpy(ut->ut_tpath, utmp.ut_tpath, TPATHSIZ); | ||
124 | strncpy(ut->ut_host, utmp.ut_host, strlen(utmp.ut_host)); | ||
125 | strncpy(ut->ut_name, utmp.ut_name, strlen(utmp.ut_name)); | ||
126 | break; | ||
127 | } | ||
128 | } | ||
129 | close(fd); | ||
130 | } | ||
131 | } | ||
132 | |||
133 | /* | ||
134 | * tmpdir support. | ||
135 | */ | ||
136 | |||
137 | /* | ||
138 | * find and delete jobs tmpdir. | ||
139 | */ | ||
140 | void | ||
141 | cray_delete_tmpdir(char *login, int jid, uid_t uid) | ||
142 | { | ||
143 | int child; | ||
144 | static char jtmp[TPATHSIZ]; | ||
145 | struct stat statbuf; | ||
146 | int c; | ||
147 | int wstat; | ||
148 | |||
149 | for (c = 'a'; c <= 'z'; c++) { | ||
150 | snprintf(jtmp, TPATHSIZ, "%s/jtmp.%06d%c", JTMPDIR, jid, c); | ||
151 | if (stat(jtmp, &statbuf) == 0 && statbuf.st_uid == uid) break; | ||
152 | } | ||
153 | |||
154 | if (c > 'z') return; | ||
155 | |||
156 | if ((child = fork()) == 0) { | ||
157 | execl(CLEANTMPCMD, CLEANTMPCMD, login, jtmp, 0); | ||
158 | fatal("ssh_cray_rmtmpdir: execl of CLEANTMPCMD failed"); | ||
159 | } | ||
160 | |||
161 | while (waitpid (child, &wstat, 0) == -1 && errno == EINTR); | ||
162 | } | ||
163 | |||
164 | /* | ||
165 | * Remove tmpdir on job termination. | ||
166 | */ | ||
167 | void | ||
168 | cray_job_termination_handler (int sig) | ||
169 | { | ||
170 | int jid; | ||
171 | char *login = NULL; | ||
172 | struct jtab jtab; | ||
173 | |||
174 | debug("Received SIG JOB."); | ||
175 | |||
176 | if ((jid = waitjob(&jtab)) == -1 || | ||
177 | (login = uid2nam(jtab.j_uid)) == NULL) return; | ||
178 | |||
179 | cray_delete_tmpdir(login, jid, jtab.j_uid); | ||
180 | } | ||
181 | |||
182 | |||
183 | /* | ||
184 | * Set job id and create tmpdir directory. | ||
185 | */ | ||
186 | void | ||
187 | cray_init_job(struct passwd *pw) | ||
188 | { | ||
189 | int jid; | ||
190 | int c; | ||
191 | |||
192 | jid = setjob(pw->pw_uid, WJSIGNAL); | ||
193 | if (jid < 0) fatal("System call setjob failure"); | ||
194 | |||
195 | for (c = 'a'; c <= 'z'; c++) { | ||
196 | snprintf(cray_tmpdir, TPATHSIZ, "%s/jtmp.%06d%c", JTMPDIR, jid, c); | ||
197 | if (mkdir(cray_tmpdir, JTMPMODE) != 0) continue; | ||
198 | if (chown(cray_tmpdir, pw->pw_uid, pw->pw_gid) != 0) { | ||
199 | rmdir(cray_tmpdir); | ||
200 | continue; | ||
201 | } | ||
202 | break; | ||
203 | } | ||
204 | |||
205 | if (c > 'z') cray_tmpdir[0] = '\0'; | ||
206 | } | ||
207 | |||
208 | void | ||
209 | cray_set_tmpdir(struct utmp *ut) | ||
210 | { | ||
211 | int jid; | ||
212 | struct jtab jbuf; | ||
213 | |||
214 | if ((jid = getjtab (&jbuf)) < 0) return; | ||
215 | |||
216 | /* | ||
217 | * Set jid and tmpdir in utmp record. | ||
218 | */ | ||
219 | ut->ut_jid = jid; | ||
220 | strncpy(ut->ut_tpath, cray_tmpdir, TPATHSIZ); | ||
221 | } | ||
222 | |||
223 | #endif | ||