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