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