]> andersk Git - gssapi-openssh.git/blob - openssh/openbsd-compat/bsd-cray.c
Import of OpenSSH 3.7.1p2
[gssapi-openssh.git] / openssh / openbsd-compat / bsd-cray.c
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  *
36  */
37 #ifdef _UNICOS
38
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/tfm.h>
49 #include <sys/usrv.h>
50 #include <sys/sysv.h>
51 #include <sys/sectab.h>
52 #include <sys/secstat.h>
53 #include <sys/stat.h>
54 #include <sys/session.h>
55 #include <stdlib.h>
56 #include <pwd.h>
57 #include <fcntl.h>
58 #include <errno.h>
59 #include <ia.h>
60 #include <urm.h>
61 #include "ssh.h"
62 #include "log.h"
63 #include "servconf.h"
64 #include "bsd-cray.h"
65
66 #define MAXACID 80
67
68 extern ServerOptions options;
69
70 char cray_tmpdir[TPATHSIZ + 1];             /* job TMPDIR path */
71
72 struct sysv sysv;       /* system security structure */
73 struct usrv usrv;       /* user security structure */
74
75 /*
76  * Functions.
77  */
78 void cray_retain_utmp(struct utmp *, int);
79 void cray_delete_tmpdir(char *, int, uid_t);
80 void cray_init_job(struct passwd *);
81 void cray_set_tmpdir(struct utmp *);
82 void cray_login_failure(char *, int);
83 int cray_setup(uid_t, char *, const char *);
84 int cray_access_denied(char *);
85
86 void
87 cray_login_failure(char *username, int errcode)
88 {
89         struct udb *ueptr;              /* UDB pointer for username */
90         ia_failure_t fsent;             /* ia_failure structure */
91         ia_failure_ret_t fret;          /* ia_failure return stuff */
92         struct jtab jtab;               /* job table structure */
93         int jid = 0;                    /* job id */
94
95         if ((jid = getjtab(&jtab)) < 0)
96                 debug("cray_login_failure(): getjtab error");
97
98         getsysudb();
99         if ((ueptr = getudbnam(username)) == UDB_NULL)
100                 debug("cray_login_failure(): getudbname() returned NULL");
101         endudb();
102
103         memset(&fsent, '\0', sizeof(fsent));
104         fsent.revision = 0;
105         fsent.uname = username;
106         fsent.host = (char *)get_canonical_hostname(options.use_dns);
107         fsent.ttyn = "sshd";
108         fsent.caller = IA_SSHD;
109         fsent.flags = IA_INTERACTIVE;
110         fsent.ueptr = ueptr;
111         fsent.jid = jid;
112         fsent.errcode = errcode;
113         fsent.pwdp = NULL;
114         fsent.exitcode = 0;     /* dont exit in ia_failure() */
115
116         fret.revision = 0;
117         fret.normal = 0;
118
119         /*
120          * Call ia_failure because of an login failure.
121          */
122         ia_failure(&fsent, &fret);
123 }
124
125 /*
126  *  Cray access denied
127  */
128 int
129 cray_access_denied(char *username)
130 {
131         struct udb *ueptr;              /* UDB pointer for username */
132         int errcode;                    /* IA errorcode */
133
134         errcode = 0;
135         getsysudb();
136         if ((ueptr = getudbnam(username)) == UDB_NULL)
137                 debug("cray_login_failure(): getudbname() returned NULL");
138         endudb();
139
140         if (ueptr != NULL && ueptr->ue_disabled)
141                 errcode = IA_DISABLED;
142         if (errcode)
143                 cray_login_failure(username, errcode);
144
145         return (errcode);
146 }
147
148 /*
149  * record_failed_login: generic "login failed" interface function
150  */
151 void
152 record_failed_login(const char *user, const char *ttyname)
153 {
154         cray_login_failure((char *)user, IA_UDBERR);
155 }
156
157 int
158 cray_setup (uid_t uid, char *username, const char *command)
159 {
160         extern struct udb *getudb();
161         extern char *setlimits();
162
163         int err;                        /* error return */
164         time_t system_time;             /* current system clock */
165         time_t expiration_time;         /* password expiration time */
166         int maxattempts;                /* maximum no. of failed login attempts */
167         int SecureSys;                  /* unicos security flag */
168         int minslevel = 0;              /* system minimum security level */
169         int i, j;
170         int valid_acct = -1;            /* flag for reading valid acct */
171         char acct_name[MAXACID] = { "" }; /* used to read acct name */
172         struct jtab jtab;               /* Job table struct */
173         struct udb ue;                  /* udb entry for logging-in user */
174         struct udb *up;                 /* pointer to UDB entry */
175         struct secstat secinfo;         /* file  security attributes */
176         struct servprov init_info;      /* used for sesscntl() call */
177         int jid;                        /* job ID */
178         int pid;                        /* process ID */
179         char *sr;                       /* status return from setlimits() */
180         char *ttyn = NULL;              /* ttyname or command name*/
181         char hostname[MAXHOSTNAMELEN];
182         /* passwd stuff for ia_user */
183         passwd_t pwdacm, pwddialup, pwdudb, pwdwal, pwddce;
184         ia_user_ret_t uret;             /* stuff returned from ia_user */
185         ia_user_t usent                 /* ia_user main structure */
186         int ia_rcode;                   /* ia_user return code */
187         ia_failure_t fsent;             /* ia_failure structure */
188         ia_failure_ret_t fret;          /* ia_failure return stuff */
189         ia_success_t ssent;             /* ia_success structure */
190         ia_success_ret_t sret;          /* ia_success return stuff */
191         int ia_mlsrcode;                /* ia_mlsuser return code */
192         int secstatrc;                  /* [f]secstat return code */
193
194         if (SecureSys = (int)sysconf(_SC_CRAY_SECURE_SYS)) {
195                 getsysv(&sysv, sizeof(struct sysv));
196                 minslevel = sysv.sy_minlvl;
197                 if (getusrv(&usrv) < 0)
198                         fatal("getusrv() failed, errno = %d", errno);
199         }
200         hostname[0] = '\0';
201         strlcpy(hostname,
202            (char *)get_canonical_hostname(options.use_dns),
203            MAXHOSTNAMELEN);
204         /*
205          *  Fetch user's UDB entry.
206          */
207         getsysudb();
208         if ((up = getudbnam(username)) == UDB_NULL)
209                 fatal("cannot fetch user's UDB entry");
210
211         /*
212          *  Prevent any possible fudging so perform a data
213          *  safety check and compare the supplied uid against
214          *  the udb's uid.
215          */
216         if (up->ue_uid != uid)
217                 fatal("IA uid missmatch");
218         endudb();
219
220         if ((jid = getjtab(&jtab)) < 0) {
221                 debug("getjtab");
222                 return(-1);
223         }
224         pid = getpid();
225         ttyn = ttyname(0);
226         if (SecureSys) {
227                 if (ttyn != NULL)
228                         secstatrc = secstat(ttyn, &secinfo);
229                 else
230                         secstatrc = fsecstat(1, &secinfo);
231
232                 if (secstatrc == 0)
233                         debug("[f]secstat() successful");
234                 else
235                         fatal("[f]secstat() error, rc = %d", secstatrc);
236         }
237         if ((ttyn == NULL) && ((char *)command != NULL))
238                 ttyn = (char *)command;
239         /*
240          *  Initialize all structures to call ia_user
241          */
242         usent.revision = 0;
243         usent.uname = username;
244         usent.host = hostname;
245         usent.ttyn = ttyn;
246         usent.caller = IA_SSHD; 
247         usent.pswdlist = &pwdacm;
248         usent.ueptr = &ue;
249         usent.flags = IA_INTERACTIVE | IA_FFLAG;
250         pwdacm.atype = IA_SECURID;
251         pwdacm.pwdp = NULL;
252         pwdacm.next = &pwdudb;
253
254         pwdudb.atype = IA_UDB;
255         pwdudb.pwdp = NULL;
256         pwdudb.next = &pwddce;
257
258         pwddce.atype = IA_DCE;
259         pwddce.pwdp = NULL;
260         pwddce.next = &pwddialup;
261
262         pwddialup.atype = IA_DIALUP;
263         pwddialup.pwdp = NULL;
264         /* pwddialup.next = &pwdwal; */
265         pwddialup.next = NULL;
266
267         pwdwal.atype = IA_WAL;
268         pwdwal.pwdp = NULL;
269         pwdwal.next = NULL;
270
271         uret.revision = 0;
272         uret.pswd = NULL;
273         uret.normal = 0;
274
275         ia_rcode = ia_user(&usent, &uret);
276         switch (ia_rcode) {
277         /*
278          *  These are acceptable return codes from ia_user()
279          */
280         case IA_UDBWEEK:        /* Password Expires in 1 week */
281                 expiration_time = ue.ue_pwage.time + ue.ue_pwage.maxage;
282                 printf ("WARNING - your current password will expire %s\n",
283                 ctime((const time_t *)&expiration_time));
284                 break;
285         case IA_UDBEXPIRED:
286                 if (ttyname(0) != NULL) {
287                         /* Force a password change */
288                         printf("Your password has expired; Choose a new one.\n");
289                         execl("/bin/passwd", "passwd", username, 0);
290                         exit(9);
291                         }
292                 break;
293         case IA_NORMAL:         /* Normal Return Code */
294                 break;
295         case IA_BACKDOOR:
296                 /* XXX: can we memset it to zero here so save some of this */
297                 strlcpy(ue.ue_name, "root", sizeof(ue.ue_name));
298                 strlcpy(ue.ue_dir, "/", sizeof(ue.ue_dir));
299                 strlcpy(ue.ue_shell, "/bin/sh", sizeof(ue.ue_shell));
300
301                 ue.ue_passwd[0] = '\0';
302                 ue.ue_age[0] = '\0';
303                 ue.ue_comment[0] = '\0';
304                 ue.ue_loghost[0] = '\0';
305                 ue.ue_logline[0] = '\0';
306
307                 ue.ue_uid = -1;
308                 ue.ue_nice[UDBRC_INTER] = 0;
309
310                 for (i = 0; i < MAXVIDS; i++)
311                         ue.ue_gids[i] = 0;
312
313                 ue.ue_logfails = 0;
314                 ue.ue_minlvl = ue.ue_maxlvl = ue.ue_deflvl = minslevel;
315                 ue.ue_defcomps = 0;
316                 ue.ue_comparts = 0;
317                 ue.ue_permits = 0;
318                 ue.ue_trap = 0;
319                 ue.ue_disabled = 0;
320                 ue.ue_logtime = 0;
321                 break;
322         case IA_CONSOLE:        /* Superuser not from Console */
323         case IA_TRUSTED:        /* Trusted user */
324                 if (options.permit_root_login > PERMIT_NO)
325                         break;  /* Accept root login */
326         default:
327         /*
328          *  These are failed return codes from ia_user()
329          */
330                 switch (ia_rcode) 
331                 {
332                 case IA_BADAUTH:
333                         printf("Bad authorization, access denied.\n");
334                         break;
335                 case IA_DISABLED:
336                         printf("Your login has been disabled. Contact the system ");
337                         printf("administrator for assistance.\n");
338                         break;
339                 case IA_GETSYSV:
340                         printf("getsysv() failed - errno = %d\n", errno);
341                         break;
342                 case IA_MAXLOGS:
343                         printf("Maximum number of failed login attempts exceeded.\n");
344                         printf("Access denied.\n");
345                         break;
346                 case IA_UDBPWDNULL:
347                         if (SecureSys)
348                                 printf("NULL Password not allowed on MLS systems.\n");
349                         break;
350                 default:
351                         break;
352                 }
353
354                 /*
355                  *  Authentication failed.
356                  */
357                 printf("sshd: Login incorrect, (0%o)\n",
358                     ia_rcode-IA_ERRORCODE);
359
360                 /*
361                  *  Initialize structure for ia_failure
362                  *  which will exit.
363                  */
364                 fsent.revision = 0;
365                 fsent.uname = username;
366                 fsent.host = hostname;
367                 fsent.ttyn = ttyn;
368                 fsent.caller = IA_SSHD;
369                 fsent.flags = IA_INTERACTIVE;
370                 fsent.ueptr = &ue;
371                 fsent.jid = jid;
372                 fsent.errcode = ia_rcode;
373                 fsent.pwdp = uret.pswd;
374                 fsent.exitcode = 1;
375
376                 fret.revision = 0;
377                 fret.normal = 0;
378
379                 /*
380                 *  Call ia_failure because of an IA failure.
381                 *  There is no return because ia_failure exits.
382                 */
383                 ia_failure(&fsent, &fret);
384
385                 exit(1); 
386         }
387
388         ia_mlsrcode = IA_NORMAL;
389         if (SecureSys) {
390                 debug("calling ia_mlsuser()");
391                 ia_mlsrcode = ia_mlsuser(&ue, &secinfo, &usrv, NULL, 0);
392         }
393         if (ia_mlsrcode != IA_NORMAL) {
394                 printf("sshd: Login incorrect, (0%o)\n",
395                     ia_mlsrcode-IA_ERRORCODE);
396                 /*
397                  *  Initialize structure for ia_failure
398                  *  which will exit.
399                  */
400                 fsent.revision = 0;
401                 fsent.uname = username;
402                 fsent.host = hostname;
403                 fsent.ttyn = ttyn;
404                 fsent.caller = IA_SSHD;
405                 fsent.flags = IA_INTERACTIVE;
406                 fsent.ueptr = &ue;
407                 fsent.jid  = jid;
408                 fsent.errcode = ia_mlsrcode;
409                 fsent.pwdp = uret.pswd;
410                 fsent.exitcode = 1;
411                 fret.revision = 0;
412                 fret.normal = 0;
413
414                 /*
415                  *  Call ia_failure because of an IA failure.
416                  *  There is no return because ia_failure exits.
417                  */
418                 ia_failure(&fsent,&fret);
419                 exit(1); 
420         }
421
422         /* Provide login status information */
423         if (options.print_lastlog && ue.ue_logtime != 0) {
424                 printf("Last successful login was : %.*s ", 19,
425                     (char *)ctime(&ue.ue_logtime));
426
427                 if (*ue.ue_loghost != '\0') {
428                         printf("from %.*s\n", sizeof(ue.ue_loghost),
429                             ue.ue_loghost);
430                 } else {
431                         printf("on %.*s\n", sizeof(ue.ue_logline),
432                             ue.ue_logline);
433                 }
434
435                 if (SecureSys && (ue.ue_logfails != 0)) {
436                         printf("  followed by %d failed attempts\n",
437                             ue.ue_logfails);
438                 }
439         }
440
441         /*
442          * Call ia_success to process successful I/A.
443          */
444         ssent.revision = 0;
445         ssent.uname = username;
446         ssent.host = hostname;
447         ssent.ttyn = ttyn;
448         ssent.caller = IA_SSHD;
449         ssent.flags = IA_INTERACTIVE;
450         ssent.ueptr = &ue;
451         ssent.jid = jid;
452         ssent.errcode = ia_rcode;
453         ssent.us = NULL;
454         ssent.time = 1; /* Set ue_logtime */
455
456         sret.revision = 0;
457         sret.normal = 0;
458
459         ia_success(&ssent, &sret);
460
461         /*
462          * Query for account, iff > 1 valid acid & askacid permbit
463          */
464         if (((ue.ue_permbits & PERMBITS_ACCTID) ||
465             (ue.ue_acids[0] >= 0) && (ue.ue_acids[1] >= 0)) &&
466             ue.ue_permbits & PERMBITS_ASKACID) {
467                 if (ttyname(0) != NULL) {
468                         debug("cray_setup: ttyname true case, %.100s", ttyname);
469                         while (valid_acct == -1) {
470                                 printf("Account (? for available accounts)"
471                                     " [%s]: ", acid2nam(ue.ue_acids[0]));
472                                 fgets(acct_name, MAXACID, stdin);
473                                 switch (acct_name[0]) {
474                                 case EOF:
475                                         exit(0);
476                                         break;
477                                 case '\0':
478                                         valid_acct = ue.ue_acids[0];
479                                         strlcpy(acct_name, acid2nam(valid_acct), MAXACID);
480                                         break;
481                                 case '?':
482                                         /* Print the list 3 wide */
483                                         for (i = 0, j = 0; i < MAXVIDS; i++) {
484                                                 if (ue.ue_acids[i] == -1) {
485                                                         printf("\n");
486                                                         break;
487                                                 }
488                                                 if (++j == 4) {
489                                                         j = 1;
490                                                         printf("\n");
491                                                 }
492                                                 printf(" %s",
493                                                     acid2nam(ue.ue_acids[i]));
494                                         }
495                                         if (ue.ue_permbits & PERMBITS_ACCTID) {
496                                                 printf("\"acctid\" permbit also allows"
497                                                     " you to select any valid "
498                                                     "account name.\n");
499                                         }
500                                         printf("\n");
501                                         break;
502                                 default:
503                                         valid_acct = nam2acid(acct_name);
504                                         if (valid_acct == -1) {
505                                                 printf(
506                                                     "Account id not found for"
507                                                     " account name \"%s\"\n\n",
508                                                     acct_name);
509                                         break;
510                                         }
511                                         /*
512                                          * If an account was given, search the user's
513                                          * acids array to verify they can use this account.
514                                          */
515                                         if ((valid_acct != -1) &&
516                                             !(ue.ue_permbits & PERMBITS_ACCTID)) {
517                                                 for (i = 0; i < MAXVIDS; i++) {
518                                                         if (ue.ue_acids[i] == -1)
519                                                                 break;
520                                                         if (valid_acct == ue.ue_acids[i])
521                                                                 break;
522                                                 }
523                                                 if (i == MAXVIDS ||
524                                                     ue.ue_acids[i] == -1) {
525                                                         fprintf(stderr, "Cannot set"
526                                                             " account name to "
527                                                             "\"%s\", permission "
528                                                             "denied\n\n", acct_name);
529                                                         valid_acct = -1;
530                                                 }
531                                         }
532                                 }
533                         } else {
534                                 /*
535                                  * The client isn't connected to a terminal and can't
536                                  * respond to an acid prompt.  Use default acid.
537                                  */
538                                 debug("cray_setup: ttyname false case, %.100s",
539                                     ttyname);
540                                 valid_acct = ue.ue_acids[0];
541                         }
542                 } else {
543                         /*
544                          * The user doesn't have the askacid permbit set or
545                          * only has one valid account to use.
546                          */
547                         valid_acct = ue.ue_acids[0];
548                 }
549                 if (acctid(0, valid_acct) < 0) {
550                         printf ("Bad account id: %d\n", valid_acct);
551                         exit(1);
552         }
553
554         /* 
555          * Now set shares, quotas, limits, including CPU time for the 
556          * (interactive) job and process, and set up permissions 
557          * (for chown etc), etc.
558          */
559         if (setshares(ue.ue_uid, valid_acct, printf, 0, 0)) {
560                 printf("Unable to give %d shares to <%s>(%d/%d)\n",
561                     ue.ue_shares, ue.ue_name, ue.ue_uid, valid_acct);
562                 exit(1);
563         }
564
565         sr = setlimits(username, C_PROC, pid, UDBRC_INTER);
566         if (sr != NULL) {
567                 debug("%.200s", sr);
568                 exit(1);
569         }
570         sr = setlimits(username, C_JOB, jid, UDBRC_INTER);
571         if (sr != NULL) {
572                 debug("%.200s", sr);
573                 exit(1);
574         }
575         /*
576          * Place the service provider information into
577          * the session table (Unicos) or job table (Unicos/mk).
578          * There exist double defines for the job/session table in
579          * unicos/mk (jtab.h) so no need for a compile time switch.
580          */
581         memset(&init_info, '\0', sizeof(init_info));
582         init_info.s_sessinit.si_id = URM_SPT_LOGIN;
583         init_info.s_sessinit.si_pid = getpid();
584         init_info.s_sessinit.si_sid = jid;
585         sesscntl(0, S_SETSERVPO, (int)&init_info);
586
587         /*
588          * Set user and controlling tty security attributes.
589          */
590         if (SecureSys) {
591                 if (setusrv(&usrv) == -1) {
592                         debug("setusrv() failed, errno = %d",errno);
593                         exit(1);
594                 }
595         }
596
597         return (0);
598 }
599
600 /*
601  * The rc.* and /etc/sdaemon methods of starting a program on unicos/unicosmk
602  * can have pal privileges that sshd can inherit which
603  * could allow a user to su to root with out a password.
604  * This subroutine clears all privileges.
605  */
606 void
607 drop_cray_privs()
608 {
609 #if defined(_SC_CRAY_PRIV_SU)
610         priv_proc_t *privstate;
611         int result;
612         extern int priv_set_proc();
613         extern priv_proc_t *priv_init_proc();
614
615         /*
616          * If ether of theses two flags are not set
617          * then don't allow this version of ssh to run.
618          */
619         if (!sysconf(_SC_CRAY_PRIV_SU))
620                 fatal("Not PRIV_SU system.");
621         if (!sysconf(_SC_CRAY_POSIX_PRIV))
622                 fatal("Not POSIX_PRIV.");
623
624         debug("Setting MLS labels.");;
625
626         if (sysconf(_SC_CRAY_SECURE_MAC)) {
627                 usrv.sv_minlvl = SYSLOW;
628                 usrv.sv_actlvl = SYSHIGH;
629                 usrv.sv_maxlvl = SYSHIGH;
630         } else {
631                 usrv.sv_minlvl = sysv.sy_minlvl;
632                 usrv.sv_actlvl = sysv.sy_minlvl;
633                 usrv.sv_maxlvl = sysv.sy_maxlvl;
634         }       
635         usrv.sv_actcmp = 0;
636         usrv.sv_valcmp = sysv.sy_valcmp;
637
638         usrv.sv_intcat = TFM_SYSTEM;
639         usrv.sv_valcat |= (TFM_SYSTEM | TFM_SYSFILE);
640
641         if (setusrv(&usrv) < 0) {
642                 fatal("%s(%d): setusrv(): %s", __FILE__, __LINE__,
643                     strerror(errno));
644         }
645
646         if ((privstate = priv_init_proc()) != NULL) {
647                 result = priv_set_proc(privstate);
648                 if (result != 0 ) {
649                         fatal("%s(%d): priv_set_proc(): %s",
650                             __FILE__, __LINE__, strerror(errno));
651                 }
652                 priv_free_proc(privstate);
653         }
654         debug ("Privileges should be cleared...");
655 #else
656         /* XXX: do this differently */
657 #       error Cray systems must be run with _SC_CRAY_PRIV_SU on!
658 #endif
659 }
660
661
662 /*
663  *  Retain utmp/wtmp information - used by cray accounting.
664  */
665 void
666 cray_retain_utmp(struct utmp *ut, int pid)
667 {
668         int fd;
669         struct utmp utmp;
670
671         if ((fd = open(UTMP_FILE, O_RDONLY)) != -1) {
672                 /* XXX use atomicio */
673                 while (read(fd, (char *)&utmp, sizeof(utmp)) == sizeof(utmp)) {
674                         if (pid == utmp.ut_pid) {
675                                 ut->ut_jid = utmp.ut_jid;
676                                 strncpy(ut->ut_tpath, utmp.ut_tpath, sizeof(utmp.ut_tpath));
677                                 strncpy(ut->ut_host, utmp.ut_host, sizeof(utmp.ut_host));
678                                 strncpy(ut->ut_name, utmp.ut_name, sizeof(utmp.ut_name));
679                                 break;
680                         }
681                 }
682                 close(fd);
683         } else
684                 fatal("Unable to open utmp file");
685 }
686
687 /*
688  * tmpdir support.
689  */
690
691 /*
692  * find and delete jobs tmpdir.
693  */
694 void
695 cray_delete_tmpdir(char *login, int jid, uid_t uid)
696 {
697         static char jtmp[TPATHSIZ];
698         struct stat statbuf;
699         int child, c, wstat;
700
701         for (c = 'a'; c <= 'z'; c++) {
702                 snprintf(jtmp, TPATHSIZ, "%s/jtmp.%06d%c", JTMPDIR, jid, c);
703                 if (stat(jtmp, &statbuf) == 0 && statbuf.st_uid == uid)
704                         break;
705         }
706
707         if (c > 'z')
708                 return;
709
710         if ((child = fork()) == 0) {
711                 execl(CLEANTMPCMD, CLEANTMPCMD, login, jtmp, (char *)NULL);
712                 fatal("cray_delete_tmpdir: execl of CLEANTMPCMD failed");
713         }
714
715         while (waitpid(child, &wstat, 0) == -1 && errno == EINTR)
716                 ;
717 }
718
719 /*
720  * Remove tmpdir on job termination.
721  */
722 void
723 cray_job_termination_handler(int sig)
724 {
725         int jid;
726         char *login = NULL;
727         struct jtab jtab;
728
729         debug("received signal %d",sig);
730
731         if ((jid = waitjob(&jtab)) == -1 ||
732             (login = uid2nam(jtab.j_uid)) == NULL)
733                 return;
734
735         cray_delete_tmpdir(login, jid, jtab.j_uid);
736 }
737
738 /*
739  * Set job id and create tmpdir directory.
740  */
741 void
742 cray_init_job(struct passwd *pw)
743 {
744         int jid;
745         int c;
746
747         jid = setjob(pw->pw_uid, WJSIGNAL);
748         if (jid < 0)
749                 fatal("System call setjob failure");
750
751         for (c = 'a'; c <= 'z'; c++) {
752                 snprintf(cray_tmpdir, TPATHSIZ, "%s/jtmp.%06d%c", JTMPDIR, jid, c);
753                 if (mkdir(cray_tmpdir, JTMPMODE) != 0)
754                         continue;
755                 if (chown(cray_tmpdir,  pw->pw_uid, pw->pw_gid) != 0) {
756                         rmdir(cray_tmpdir);
757                         continue;
758                 }
759                 break;
760         }
761
762         if (c > 'z')
763                 cray_tmpdir[0] = '\0';
764 }
765
766 void
767 cray_set_tmpdir(struct utmp *ut)
768 {
769         int jid;
770         struct jtab jbuf;
771
772         if ((jid = getjtab(&jbuf)) < 0)
773                 return;
774
775         /*
776          * Set jid and tmpdir in utmp record.
777          */
778         ut->ut_jid = jid;
779         strncpy(ut->ut_tpath, cray_tmpdir, TPATHSIZ);
780 }
781 #endif
This page took 0.10454 seconds and 5 git commands to generate.