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