198937Sdes/* 2181111Sdes * $Id: bsd-cray.c,v 1.17 2007/08/15 09:17:43 dtucker Exp $ 398937Sdes * 498937Sdes * bsd-cray.c 598937Sdes * 698937Sdes * Copyright (c) 2002, Cray Inc. (Wendy Palm <wendyp@cray.com>) 798937Sdes * Significant portions provided by 898937Sdes * Wayne Schroeder, SDSC <schroeder@sdsc.edu> 998937Sdes * William Jones, UTexas <jones@tacc.utexas.edu> 1098937Sdes * 1198937Sdes * Redistribution and use in source and binary forms, with or without 1298937Sdes * modification, are permitted provided that the following conditions 1398937Sdes * are met: 1498937Sdes * 1. Redistributions of source code must retain the above copyright 1598937Sdes * notice, this list of conditions and the following disclaimer. 1698937Sdes * 2. Redistributions in binary form must reproduce the above copyright 1798937Sdes * notice, this list of conditions and the following disclaimer in the 1898937Sdes * documentation and/or other materials provided with the distribution. 1998937Sdes * 2098937Sdes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 2198937Sdes * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2298937Sdes * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2398937Sdes * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2498937Sdes * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2598937Sdes * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2698937Sdes * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2798937Sdes * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2898937Sdes * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2998937Sdes * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3098937Sdes * 3198937Sdes * Created: Apr 22 16.34:00 2002 wp 3298937Sdes * 3398937Sdes * This file contains functions required for proper execution 3498937Sdes * on UNICOS systems. 3598937Sdes * 3698937Sdes */ 37106121Sdes#ifdef _UNICOS 3898937Sdes 3998937Sdes#include <udb.h> 4098937Sdes#include <tmpdir.h> 4198937Sdes#include <unistd.h> 4298937Sdes#include <sys/category.h> 4398937Sdes#include <utmp.h> 4498937Sdes#include <sys/jtab.h> 4598937Sdes#include <signal.h> 4698937Sdes#include <sys/priv.h> 4798937Sdes#include <sys/secparm.h> 48106121Sdes#include <sys/tfm.h> 4998937Sdes#include <sys/usrv.h> 5098937Sdes#include <sys/sysv.h> 5198937Sdes#include <sys/sectab.h> 52106121Sdes#include <sys/secstat.h> 5398937Sdes#include <sys/stat.h> 54106121Sdes#include <sys/session.h> 55162852Sdes#include <stdarg.h> 5698937Sdes#include <stdlib.h> 57162852Sdes#include <string.h> 58162852Sdes#include <unistd.h> 5998937Sdes#include <pwd.h> 6098937Sdes#include <fcntl.h> 6198937Sdes#include <errno.h> 62106121Sdes#include <ia.h> 63106121Sdes#include <urm.h> 64106121Sdes#include "ssh.h" 65126274Sdes 66126274Sdes#include "includes.h" 67126274Sdes#include "sys/types.h" 68126274Sdes 69126274Sdes#ifndef HAVE_STRUCT_SOCKADDR_STORAGE 70126274Sdes# define _SS_MAXSIZE 128 /* Implementation specific max size */ 71126274Sdes# define _SS_PADSIZE (_SS_MAXSIZE - sizeof (struct sockaddr)) 72126274Sdes 73126274Sdes# define ss_family ss_sa.sa_family 74126274Sdes#endif /* !HAVE_STRUCT_SOCKADDR_STORAGE */ 75126274Sdes 76126274Sdes#ifndef IN6_IS_ADDR_LOOPBACK 77126274Sdes# define IN6_IS_ADDR_LOOPBACK(a) \ 78126274Sdes (((u_int32_t *) (a))[0] == 0 && ((u_int32_t *) (a))[1] == 0 && \ 79126274Sdes ((u_int32_t *) (a))[2] == 0 && ((u_int32_t *) (a))[3] == htonl (1)) 80126274Sdes#endif /* !IN6_IS_ADDR_LOOPBACK */ 81126274Sdes 82126274Sdes#ifndef AF_INET6 83126274Sdes/* Define it to something that should never appear */ 84126274Sdes#define AF_INET6 AF_MAX 85126274Sdes#endif 86126274Sdes 87106121Sdes#include "log.h" 88106121Sdes#include "servconf.h" 8998937Sdes#include "bsd-cray.h" 9098937Sdes 91106121Sdes#define MAXACID 80 92106121Sdes 93106121Sdesextern ServerOptions options; 94106121Sdes 95124208Sdeschar cray_tmpdir[TPATHSIZ + 1]; /* job TMPDIR path */ 9698937Sdes 97124208Sdesstruct sysv sysv; /* system security structure */ 98124208Sdesstruct usrv usrv; /* user security structure */ 99106121Sdes 10098937Sdes/* 10198937Sdes * Functions. 10298937Sdes */ 10398937Sdesvoid cray_retain_utmp(struct utmp *, int); 10498937Sdesvoid cray_delete_tmpdir(char *, int, uid_t); 10598937Sdesvoid cray_init_job(struct passwd *); 10698937Sdesvoid cray_set_tmpdir(struct utmp *); 107106121Sdesvoid cray_login_failure(char *, int); 108106121Sdesint cray_setup(uid_t, char *, const char *); 109106121Sdesint cray_access_denied(char *); 11098937Sdes 111106121Sdesvoid 112106121Sdescray_login_failure(char *username, int errcode) 113106121Sdes{ 114124208Sdes struct udb *ueptr; /* UDB pointer for username */ 115124208Sdes ia_failure_t fsent; /* ia_failure structure */ 116106121Sdes ia_failure_ret_t fret; /* ia_failure return stuff */ 117124208Sdes struct jtab jtab; /* job table structure */ 118124208Sdes int jid = 0; /* job id */ 11998937Sdes 120124208Sdes if ((jid = getjtab(&jtab)) < 0) 121106121Sdes debug("cray_login_failure(): getjtab error"); 122124208Sdes 123106121Sdes getsysudb(); 124124208Sdes if ((ueptr = getudbnam(username)) == UDB_NULL) 125106121Sdes debug("cray_login_failure(): getudbname() returned NULL"); 126106121Sdes endudb(); 127106121Sdes 128124208Sdes memset(&fsent, '\0', sizeof(fsent)); 129124208Sdes fsent.revision = 0; 130124208Sdes fsent.uname = username; 131124208Sdes fsent.host = (char *)get_canonical_hostname(options.use_dns); 132124208Sdes fsent.ttyn = "sshd"; 133124208Sdes fsent.caller = IA_SSHD; 134124208Sdes fsent.flags = IA_INTERACTIVE; 135124208Sdes fsent.ueptr = ueptr; 136124208Sdes fsent.jid = jid; 137124208Sdes fsent.errcode = errcode; 138124208Sdes fsent.pwdp = NULL; 139124208Sdes fsent.exitcode = 0; /* dont exit in ia_failure() */ 140106121Sdes 141124208Sdes fret.revision = 0; 142124208Sdes fret.normal = 0; 143124208Sdes 144106121Sdes /* 145106121Sdes * Call ia_failure because of an login failure. 146106121Sdes */ 147124208Sdes ia_failure(&fsent, &fret); 148106121Sdes} 149106121Sdes 15098937Sdes/* 151106121Sdes * Cray access denied 152106121Sdes */ 153106121Sdesint 154106121Sdescray_access_denied(char *username) 15598937Sdes{ 156124208Sdes struct udb *ueptr; /* UDB pointer for username */ 157124208Sdes int errcode; /* IA errorcode */ 158106121Sdes 159106121Sdes errcode = 0; 160106121Sdes getsysudb(); 161124208Sdes if ((ueptr = getudbnam(username)) == UDB_NULL) 162106121Sdes debug("cray_login_failure(): getudbname() returned NULL"); 163106121Sdes endudb(); 164124208Sdes 165124208Sdes if (ueptr != NULL && ueptr->ue_disabled) 166106121Sdes errcode = IA_DISABLED; 167106121Sdes if (errcode) 168106121Sdes cray_login_failure(username, errcode); 169124208Sdes 170106121Sdes return (errcode); 171106121Sdes} 172106121Sdes 173124208Sdes/* 174124208Sdes * record_failed_login: generic "login failed" interface function 175124208Sdes */ 176124208Sdesvoid 177146998Sdesrecord_failed_login(const char *user, const char *hostname, const char *ttyname) 178124208Sdes{ 179124208Sdes cray_login_failure((char *)user, IA_UDBERR); 180124208Sdes} 181124208Sdes 182106121Sdesint 183106121Sdescray_setup (uid_t uid, char *username, const char *command) 184106121Sdes{ 185106121Sdes extern struct udb *getudb(); 18698937Sdes extern char *setlimits(); 18798937Sdes 188124208Sdes int err; /* error return */ 189124208Sdes time_t system_time; /* current system clock */ 190124208Sdes time_t expiration_time; /* password expiration time */ 191124208Sdes int maxattempts; /* maximum no. of failed login attempts */ 192124208Sdes int SecureSys; /* unicos security flag */ 193124208Sdes int minslevel = 0; /* system minimum security level */ 194124208Sdes int i, j; 195124208Sdes int valid_acct = -1; /* flag for reading valid acct */ 196124208Sdes char acct_name[MAXACID] = { "" }; /* used to read acct name */ 197124208Sdes struct jtab jtab; /* Job table struct */ 198124208Sdes struct udb ue; /* udb entry for logging-in user */ 199124208Sdes struct udb *up; /* pointer to UDB entry */ 200124208Sdes struct secstat secinfo; /* file security attributes */ 201124208Sdes struct servprov init_info; /* used for sesscntl() call */ 202124208Sdes int jid; /* job ID */ 203124208Sdes int pid; /* process ID */ 204124208Sdes char *sr; /* status return from setlimits() */ 205124208Sdes char *ttyn = NULL; /* ttyname or command name*/ 206124208Sdes char hostname[MAXHOSTNAMELEN]; 207124208Sdes /* passwd stuff for ia_user */ 208124208Sdes passwd_t pwdacm, pwddialup, pwdudb, pwdwal, pwddce; 209124208Sdes ia_user_ret_t uret; /* stuff returned from ia_user */ 210126274Sdes ia_user_t usent; /* ia_user main structure */ 211124208Sdes int ia_rcode; /* ia_user return code */ 212124208Sdes ia_failure_t fsent; /* ia_failure structure */ 213106121Sdes ia_failure_ret_t fret; /* ia_failure return stuff */ 214124208Sdes ia_success_t ssent; /* ia_success structure */ 215106121Sdes ia_success_ret_t sret; /* ia_success return stuff */ 216124208Sdes int ia_mlsrcode; /* ia_mlsuser return code */ 217124208Sdes int secstatrc; /* [f]secstat return code */ 21898937Sdes 219106121Sdes if (SecureSys = (int)sysconf(_SC_CRAY_SECURE_SYS)) { 220106121Sdes getsysv(&sysv, sizeof(struct sysv)); 221106121Sdes minslevel = sysv.sy_minlvl; 222124208Sdes if (getusrv(&usrv) < 0) 223124208Sdes fatal("getusrv() failed, errno = %d", errno); 22498937Sdes } 225106121Sdes hostname[0] = '\0'; 226124208Sdes strlcpy(hostname, 227124208Sdes (char *)get_canonical_hostname(options.use_dns), 228106121Sdes MAXHOSTNAMELEN); 229124208Sdes /* 230124208Sdes * Fetch user's UDB entry. 231124208Sdes */ 232124208Sdes getsysudb(); 233124208Sdes if ((up = getudbnam(username)) == UDB_NULL) 234124208Sdes fatal("cannot fetch user's UDB entry"); 23598937Sdes 236124208Sdes /* 237124208Sdes * Prevent any possible fudging so perform a data 238124208Sdes * safety check and compare the supplied uid against 239124208Sdes * the udb's uid. 240124208Sdes */ 241124208Sdes if (up->ue_uid != uid) 242124208Sdes fatal("IA uid missmatch"); 243106121Sdes endudb(); 244106121Sdes 245124208Sdes if ((jid = getjtab(&jtab)) < 0) { 246106121Sdes debug("getjtab"); 247124208Sdes return(-1); 24898937Sdes } 249106121Sdes pid = getpid(); 250106121Sdes ttyn = ttyname(0); 251106121Sdes if (SecureSys) { 252124208Sdes if (ttyn != NULL) 253106121Sdes secstatrc = secstat(ttyn, &secinfo); 254124208Sdes else 255106121Sdes secstatrc = fsecstat(1, &secinfo); 256124208Sdes 257124208Sdes if (secstatrc == 0) 258106121Sdes debug("[f]secstat() successful"); 259124208Sdes else 260124208Sdes fatal("[f]secstat() error, rc = %d", secstatrc); 261106121Sdes } 262106121Sdes if ((ttyn == NULL) && ((char *)command != NULL)) 263106121Sdes ttyn = (char *)command; 264124208Sdes /* 265124208Sdes * Initialize all structures to call ia_user 266124208Sdes */ 267124208Sdes usent.revision = 0; 268124208Sdes usent.uname = username; 269124208Sdes usent.host = hostname; 270124208Sdes usent.ttyn = ttyn; 271124208Sdes usent.caller = IA_SSHD; 272124208Sdes usent.pswdlist = &pwdacm; 273124208Sdes usent.ueptr = &ue; 274124208Sdes usent.flags = IA_INTERACTIVE | IA_FFLAG; 275124208Sdes pwdacm.atype = IA_SECURID; 276124208Sdes pwdacm.pwdp = NULL; 277124208Sdes pwdacm.next = &pwdudb; 27898937Sdes 279124208Sdes pwdudb.atype = IA_UDB; 280124208Sdes pwdudb.pwdp = NULL; 281124208Sdes pwdudb.next = &pwddce; 28298937Sdes 283124208Sdes pwddce.atype = IA_DCE; 284124208Sdes pwddce.pwdp = NULL; 285124208Sdes pwddce.next = &pwddialup; 286106121Sdes 287124208Sdes pwddialup.atype = IA_DIALUP; 288124208Sdes pwddialup.pwdp = NULL; 289124208Sdes /* pwddialup.next = &pwdwal; */ 290124208Sdes pwddialup.next = NULL; 291106121Sdes 292124208Sdes pwdwal.atype = IA_WAL; 293124208Sdes pwdwal.pwdp = NULL; 294124208Sdes pwdwal.next = NULL; 295106121Sdes 296124208Sdes uret.revision = 0; 297124208Sdes uret.pswd = NULL; 298124208Sdes uret.normal = 0; 299106121Sdes 300124208Sdes ia_rcode = ia_user(&usent, &uret); 301124208Sdes switch (ia_rcode) { 302124208Sdes /* 303124208Sdes * These are acceptable return codes from ia_user() 304124208Sdes */ 305124208Sdes case IA_UDBWEEK: /* Password Expires in 1 week */ 306124208Sdes expiration_time = ue.ue_pwage.time + ue.ue_pwage.maxage; 307124208Sdes printf ("WARNING - your current password will expire %s\n", 308124208Sdes ctime((const time_t *)&expiration_time)); 309124208Sdes break; 310124208Sdes case IA_UDBEXPIRED: 311124208Sdes if (ttyname(0) != NULL) { 312124208Sdes /* Force a password change */ 313124208Sdes printf("Your password has expired; Choose a new one.\n"); 314124208Sdes execl("/bin/passwd", "passwd", username, 0); 315124208Sdes exit(9); 316124208Sdes } 317124208Sdes break; 318124208Sdes case IA_NORMAL: /* Normal Return Code */ 319124208Sdes break; 320124208Sdes case IA_BACKDOOR: 321124208Sdes /* XXX: can we memset it to zero here so save some of this */ 322124208Sdes strlcpy(ue.ue_name, "root", sizeof(ue.ue_name)); 323124208Sdes strlcpy(ue.ue_dir, "/", sizeof(ue.ue_dir)); 324124208Sdes strlcpy(ue.ue_shell, "/bin/sh", sizeof(ue.ue_shell)); 325106121Sdes 326124208Sdes ue.ue_passwd[0] = '\0'; 327124208Sdes ue.ue_age[0] = '\0'; 328124208Sdes ue.ue_comment[0] = '\0'; 329124208Sdes ue.ue_loghost[0] = '\0'; 330124208Sdes ue.ue_logline[0] = '\0'; 331106121Sdes 332124208Sdes ue.ue_uid = -1; 333124208Sdes ue.ue_nice[UDBRC_INTER] = 0; 334106121Sdes 335124208Sdes for (i = 0; i < MAXVIDS; i++) 336124208Sdes ue.ue_gids[i] = 0; 337124208Sdes 338124208Sdes ue.ue_logfails = 0; 339124208Sdes ue.ue_minlvl = ue.ue_maxlvl = ue.ue_deflvl = minslevel; 340124208Sdes ue.ue_defcomps = 0; 341124208Sdes ue.ue_comparts = 0; 342124208Sdes ue.ue_permits = 0; 343124208Sdes ue.ue_trap = 0; 344124208Sdes ue.ue_disabled = 0; 345124208Sdes ue.ue_logtime = 0; 346124208Sdes break; 347124208Sdes case IA_CONSOLE: /* Superuser not from Console */ 348124208Sdes case IA_TRUSTED: /* Trusted user */ 349124208Sdes if (options.permit_root_login > PERMIT_NO) 350124208Sdes break; /* Accept root login */ 351124208Sdes default: 352124208Sdes /* 353124208Sdes * These are failed return codes from ia_user() 354124208Sdes */ 355124208Sdes switch (ia_rcode) 356124208Sdes { 357124208Sdes case IA_BADAUTH: 358124208Sdes printf("Bad authorization, access denied.\n"); 359124208Sdes break; 360124208Sdes case IA_DISABLED: 361124208Sdes printf("Your login has been disabled. Contact the system "); 362124208Sdes printf("administrator for assistance.\n"); 363124208Sdes break; 364124208Sdes case IA_GETSYSV: 365124208Sdes printf("getsysv() failed - errno = %d\n", errno); 366124208Sdes break; 367124208Sdes case IA_MAXLOGS: 368124208Sdes printf("Maximum number of failed login attempts exceeded.\n"); 369124208Sdes printf("Access denied.\n"); 370124208Sdes break; 371124208Sdes case IA_UDBPWDNULL: 372124208Sdes if (SecureSys) 373124208Sdes printf("NULL Password not allowed on MLS systems.\n"); 374124208Sdes break; 375124208Sdes default: 376124208Sdes break; 377124208Sdes } 378124208Sdes 379124208Sdes /* 380124208Sdes * Authentication failed. 381124208Sdes */ 382124208Sdes printf("sshd: Login incorrect, (0%o)\n", 383124208Sdes ia_rcode-IA_ERRORCODE); 384124208Sdes 385124208Sdes /* 386124208Sdes * Initialize structure for ia_failure 387124208Sdes * which will exit. 388124208Sdes */ 389124208Sdes fsent.revision = 0; 390124208Sdes fsent.uname = username; 391124208Sdes fsent.host = hostname; 392124208Sdes fsent.ttyn = ttyn; 393124208Sdes fsent.caller = IA_SSHD; 394124208Sdes fsent.flags = IA_INTERACTIVE; 395124208Sdes fsent.ueptr = &ue; 396124208Sdes fsent.jid = jid; 397124208Sdes fsent.errcode = ia_rcode; 398124208Sdes fsent.pwdp = uret.pswd; 399124208Sdes fsent.exitcode = 1; 400124208Sdes 401124208Sdes fret.revision = 0; 402124208Sdes fret.normal = 0; 403124208Sdes 404124208Sdes /* 405124208Sdes * Call ia_failure because of an IA failure. 406124208Sdes * There is no return because ia_failure exits. 407124208Sdes */ 408124208Sdes ia_failure(&fsent, &fret); 409124208Sdes 410124208Sdes exit(1); 411124208Sdes } 412124208Sdes 413106121Sdes ia_mlsrcode = IA_NORMAL; 414106121Sdes if (SecureSys) { 415106121Sdes debug("calling ia_mlsuser()"); 416124208Sdes ia_mlsrcode = ia_mlsuser(&ue, &secinfo, &usrv, NULL, 0); 417106121Sdes } 418106121Sdes if (ia_mlsrcode != IA_NORMAL) { 419106121Sdes printf("sshd: Login incorrect, (0%o)\n", 420124208Sdes ia_mlsrcode-IA_ERRORCODE); 421106121Sdes /* 422124208Sdes * Initialize structure for ia_failure 423124208Sdes * which will exit. 424124208Sdes */ 425106121Sdes fsent.revision = 0; 426124208Sdes fsent.uname = username; 427124208Sdes fsent.host = hostname; 428124208Sdes fsent.ttyn = ttyn; 429124208Sdes fsent.caller = IA_SSHD; 430124208Sdes fsent.flags = IA_INTERACTIVE; 431124208Sdes fsent.ueptr = &ue; 432124208Sdes fsent.jid = jid; 433124208Sdes fsent.errcode = ia_mlsrcode; 434124208Sdes fsent.pwdp = uret.pswd; 435106121Sdes fsent.exitcode = 1; 436124208Sdes fret.revision = 0; 437124208Sdes fret.normal = 0; 438106121Sdes 439106121Sdes /* 440124208Sdes * Call ia_failure because of an IA failure. 441124208Sdes * There is no return because ia_failure exits. 442124208Sdes */ 443106121Sdes ia_failure(&fsent,&fret); 444106121Sdes exit(1); 445106121Sdes } 446106121Sdes 447124208Sdes /* Provide login status information */ 448124208Sdes if (options.print_lastlog && ue.ue_logtime != 0) { 449124208Sdes printf("Last successful login was : %.*s ", 19, 450124208Sdes (char *)ctime(&ue.ue_logtime)); 451106121Sdes 452124208Sdes if (*ue.ue_loghost != '\0') { 453124208Sdes printf("from %.*s\n", sizeof(ue.ue_loghost), 454124208Sdes ue.ue_loghost); 455124208Sdes } else { 456124208Sdes printf("on %.*s\n", sizeof(ue.ue_logline), 457124208Sdes ue.ue_logline); 458124208Sdes } 459124208Sdes 460124208Sdes if (SecureSys && (ue.ue_logfails != 0)) { 461124208Sdes printf(" followed by %d failed attempts\n", 462124208Sdes ue.ue_logfails); 463124208Sdes } 464124208Sdes } 465124208Sdes 466106121Sdes /* 467106121Sdes * Call ia_success to process successful I/A. 468106121Sdes */ 469106121Sdes ssent.revision = 0; 470106121Sdes ssent.uname = username; 471106121Sdes ssent.host = hostname; 472106121Sdes ssent.ttyn = ttyn; 473106121Sdes ssent.caller = IA_SSHD; 474106121Sdes ssent.flags = IA_INTERACTIVE; 475106121Sdes ssent.ueptr = &ue; 476106121Sdes ssent.jid = jid; 477106121Sdes ssent.errcode = ia_rcode; 478106121Sdes ssent.us = NULL; 479124208Sdes ssent.time = 1; /* Set ue_logtime */ 480106121Sdes 481106121Sdes sret.revision = 0; 482106121Sdes sret.normal = 0; 483106121Sdes 484124208Sdes ia_success(&ssent, &sret); 485106121Sdes 486124208Sdes /* 487124208Sdes * Query for account, iff > 1 valid acid & askacid permbit 488124208Sdes */ 489124208Sdes if (((ue.ue_permbits & PERMBITS_ACCTID) || 490124208Sdes (ue.ue_acids[0] >= 0) && (ue.ue_acids[1] >= 0)) && 491124208Sdes ue.ue_permbits & PERMBITS_ASKACID) { 492106121Sdes if (ttyname(0) != NULL) { 493124208Sdes debug("cray_setup: ttyname true case, %.100s", ttyname); 494124208Sdes while (valid_acct == -1) { 495124208Sdes printf("Account (? for available accounts)" 496124208Sdes " [%s]: ", acid2nam(ue.ue_acids[0])); 497124208Sdes fgets(acct_name, MAXACID, stdin); 498124208Sdes switch (acct_name[0]) { 499124208Sdes case EOF: 500124208Sdes exit(0); 501124208Sdes break; 502124208Sdes case '\0': 503124208Sdes valid_acct = ue.ue_acids[0]; 504124208Sdes strlcpy(acct_name, acid2nam(valid_acct), MAXACID); 505124208Sdes break; 506124208Sdes case '?': 507124208Sdes /* Print the list 3 wide */ 508124208Sdes for (i = 0, j = 0; i < MAXVIDS; i++) { 509124208Sdes if (ue.ue_acids[i] == -1) { 510124208Sdes printf("\n"); 511124208Sdes break; 512124208Sdes } 513124208Sdes if (++j == 4) { 514124208Sdes j = 1; 515124208Sdes printf("\n"); 516124208Sdes } 517124208Sdes printf(" %s", 518124208Sdes acid2nam(ue.ue_acids[i])); 519124208Sdes } 520124208Sdes if (ue.ue_permbits & PERMBITS_ACCTID) { 521124208Sdes printf("\"acctid\" permbit also allows" 522124208Sdes " you to select any valid " 523124208Sdes "account name.\n"); 524124208Sdes } 525124208Sdes printf("\n"); 526124208Sdes break; 527124208Sdes default: 528124208Sdes valid_acct = nam2acid(acct_name); 529126274Sdes if (valid_acct == -1) 530124208Sdes printf( 531124208Sdes "Account id not found for" 532124208Sdes " account name \"%s\"\n\n", 533124208Sdes acct_name); 534124208Sdes break; 535126274Sdes } 536126274Sdes /* 537126274Sdes * If an account was given, search the user's 538126274Sdes * acids array to verify they can use this account. 539126274Sdes */ 540126274Sdes if ((valid_acct != -1) && 541126274Sdes !(ue.ue_permbits & PERMBITS_ACCTID)) { 542126274Sdes for (i = 0; i < MAXVIDS; i++) { 543126274Sdes if (ue.ue_acids[i] == -1) 544126274Sdes break; 545126274Sdes if (valid_acct == ue.ue_acids[i]) 546126274Sdes break; 547124208Sdes } 548126274Sdes if (i == MAXVIDS || 549126274Sdes ue.ue_acids[i] == -1) { 550126274Sdes fprintf(stderr, "Cannot set" 551126274Sdes " account name to " 552126274Sdes "\"%s\", permission " 553126274Sdes "denied\n\n", acct_name); 554126274Sdes valid_acct = -1; 555124208Sdes } 556124208Sdes } 557124208Sdes } 558106121Sdes } else { 559106121Sdes /* 560126274Sdes * The client isn't connected to a terminal and can't 561126274Sdes * respond to an acid prompt. Use default acid. 562106121Sdes */ 563126274Sdes debug("cray_setup: ttyname false case, %.100s", 564126274Sdes ttyname); 565106121Sdes valid_acct = ue.ue_acids[0]; 566106121Sdes } 567126274Sdes } else { 568126274Sdes /* 569126274Sdes * The user doesn't have the askacid permbit set or 570126274Sdes * only has one valid account to use. 571126274Sdes */ 572126274Sdes valid_acct = ue.ue_acids[0]; 573124208Sdes } 574126274Sdes if (acctid(0, valid_acct) < 0) { 575126274Sdes printf ("Bad account id: %d\n", valid_acct); 576126274Sdes exit(1); 577126274Sdes } 578106121Sdes 579124208Sdes /* 580124208Sdes * Now set shares, quotas, limits, including CPU time for the 581124208Sdes * (interactive) job and process, and set up permissions 582124208Sdes * (for chown etc), etc. 583124208Sdes */ 584106121Sdes if (setshares(ue.ue_uid, valid_acct, printf, 0, 0)) { 585124208Sdes printf("Unable to give %d shares to <%s>(%d/%d)\n", 586124208Sdes ue.ue_shares, ue.ue_name, ue.ue_uid, valid_acct); 587106121Sdes exit(1); 588124208Sdes } 589106121Sdes 59098937Sdes sr = setlimits(username, C_PROC, pid, UDBRC_INTER); 591106121Sdes if (sr != NULL) { 592106121Sdes debug("%.200s", sr); 593106121Sdes exit(1); 594106121Sdes } 59598937Sdes sr = setlimits(username, C_JOB, jid, UDBRC_INTER); 596106121Sdes if (sr != NULL) { 597106121Sdes debug("%.200s", sr); 598106121Sdes exit(1); 599106121Sdes } 600106121Sdes /* 601124208Sdes * Place the service provider information into 602106121Sdes * the session table (Unicos) or job table (Unicos/mk). 603106121Sdes * There exist double defines for the job/session table in 604106121Sdes * unicos/mk (jtab.h) so no need for a compile time switch. 605106121Sdes */ 606124208Sdes memset(&init_info, '\0', sizeof(init_info)); 607124208Sdes init_info.s_sessinit.si_id = URM_SPT_LOGIN; 608106121Sdes init_info.s_sessinit.si_pid = getpid(); 609106121Sdes init_info.s_sessinit.si_sid = jid; 610106121Sdes sesscntl(0, S_SETSERVPO, (int)&init_info); 61198937Sdes 612106121Sdes /* 613106121Sdes * Set user and controlling tty security attributes. 614106121Sdes */ 615106121Sdes if (SecureSys) { 616106121Sdes if (setusrv(&usrv) == -1) { 617106121Sdes debug("setusrv() failed, errno = %d",errno); 618106121Sdes exit(1); 619106121Sdes } 620106121Sdes } 621106121Sdes 622124208Sdes return (0); 62398937Sdes} 62498937Sdes 62598937Sdes/* 62698937Sdes * The rc.* and /etc/sdaemon methods of starting a program on unicos/unicosmk 62798937Sdes * can have pal privileges that sshd can inherit which 62898937Sdes * could allow a user to su to root with out a password. 62998937Sdes * This subroutine clears all privileges. 63098937Sdes */ 63198937Sdesvoid 63298937Sdesdrop_cray_privs() 63398937Sdes{ 63498937Sdes#if defined(_SC_CRAY_PRIV_SU) 635124208Sdes priv_proc_t *privstate; 636124208Sdes int result; 637124208Sdes extern int priv_set_proc(); 638124208Sdes extern priv_proc_t *priv_init_proc(); 63998937Sdes 64098937Sdes /* 64198937Sdes * If ether of theses two flags are not set 64298937Sdes * then don't allow this version of ssh to run. 64398937Sdes */ 64498937Sdes if (!sysconf(_SC_CRAY_PRIV_SU)) 64598937Sdes fatal("Not PRIV_SU system."); 64698937Sdes if (!sysconf(_SC_CRAY_POSIX_PRIV)) 64798937Sdes fatal("Not POSIX_PRIV."); 64898937Sdes 649106121Sdes debug("Setting MLS labels.");; 65098937Sdes 651106121Sdes if (sysconf(_SC_CRAY_SECURE_MAC)) { 652106121Sdes usrv.sv_minlvl = SYSLOW; 653106121Sdes usrv.sv_actlvl = SYSHIGH; 654106121Sdes usrv.sv_maxlvl = SYSHIGH; 655106121Sdes } else { 656106121Sdes usrv.sv_minlvl = sysv.sy_minlvl; 657106121Sdes usrv.sv_actlvl = sysv.sy_minlvl; 658106121Sdes usrv.sv_maxlvl = sysv.sy_maxlvl; 659106121Sdes } 660106121Sdes usrv.sv_actcmp = 0; 661106121Sdes usrv.sv_valcmp = sysv.sy_valcmp; 662106121Sdes 663106121Sdes usrv.sv_intcat = TFM_SYSTEM; 664106121Sdes usrv.sv_valcat |= (TFM_SYSTEM | TFM_SYSFILE); 665106121Sdes 666124208Sdes if (setusrv(&usrv) < 0) { 66798937Sdes fatal("%s(%d): setusrv(): %s", __FILE__, __LINE__, 66898937Sdes strerror(errno)); 669124208Sdes } 67098937Sdes 67198937Sdes if ((privstate = priv_init_proc()) != NULL) { 67298937Sdes result = priv_set_proc(privstate); 673124208Sdes if (result != 0 ) { 67498937Sdes fatal("%s(%d): priv_set_proc(): %s", 67598937Sdes __FILE__, __LINE__, strerror(errno)); 676124208Sdes } 67798937Sdes priv_free_proc(privstate); 67898937Sdes } 67998937Sdes debug ("Privileges should be cleared..."); 68098937Sdes#else 68198937Sdes /* XXX: do this differently */ 68298937Sdes# error Cray systems must be run with _SC_CRAY_PRIV_SU on! 68398937Sdes#endif 68498937Sdes} 68598937Sdes 68698937Sdes 68798937Sdes/* 68898937Sdes * Retain utmp/wtmp information - used by cray accounting. 68998937Sdes */ 69098937Sdesvoid 69198937Sdescray_retain_utmp(struct utmp *ut, int pid) 69298937Sdes{ 69398937Sdes int fd; 69498937Sdes struct utmp utmp; 69598937Sdes 69698937Sdes if ((fd = open(UTMP_FILE, O_RDONLY)) != -1) { 697124208Sdes /* XXX use atomicio */ 69898937Sdes while (read(fd, (char *)&utmp, sizeof(utmp)) == sizeof(utmp)) { 69998937Sdes if (pid == utmp.ut_pid) { 70098937Sdes ut->ut_jid = utmp.ut_jid; 70198937Sdes strncpy(ut->ut_tpath, utmp.ut_tpath, sizeof(utmp.ut_tpath)); 70298937Sdes strncpy(ut->ut_host, utmp.ut_host, sizeof(utmp.ut_host)); 70398937Sdes strncpy(ut->ut_name, utmp.ut_name, sizeof(utmp.ut_name)); 70498937Sdes break; 70598937Sdes } 70698937Sdes } 70798937Sdes close(fd); 708124208Sdes } else 709124208Sdes fatal("Unable to open utmp file"); 71098937Sdes} 71198937Sdes 71298937Sdes/* 71398937Sdes * tmpdir support. 71498937Sdes */ 71598937Sdes 71698937Sdes/* 71798937Sdes * find and delete jobs tmpdir. 71898937Sdes */ 71998937Sdesvoid 72098937Sdescray_delete_tmpdir(char *login, int jid, uid_t uid) 72198937Sdes{ 72298937Sdes static char jtmp[TPATHSIZ]; 72398937Sdes struct stat statbuf; 724124208Sdes int child, c, wstat; 72598937Sdes 72698937Sdes for (c = 'a'; c <= 'z'; c++) { 72798937Sdes snprintf(jtmp, TPATHSIZ, "%s/jtmp.%06d%c", JTMPDIR, jid, c); 72898937Sdes if (stat(jtmp, &statbuf) == 0 && statbuf.st_uid == uid) 72998937Sdes break; 73098937Sdes } 73198937Sdes 73298937Sdes if (c > 'z') 73398937Sdes return; 73498937Sdes 73598937Sdes if ((child = fork()) == 0) { 73698937Sdes execl(CLEANTMPCMD, CLEANTMPCMD, login, jtmp, (char *)NULL); 73798937Sdes fatal("cray_delete_tmpdir: execl of CLEANTMPCMD failed"); 73898937Sdes } 73998937Sdes 74098937Sdes while (waitpid(child, &wstat, 0) == -1 && errno == EINTR) 74198937Sdes ; 74298937Sdes} 74398937Sdes 74498937Sdes/* 74598937Sdes * Remove tmpdir on job termination. 74698937Sdes */ 74798937Sdesvoid 74898937Sdescray_job_termination_handler(int sig) 74998937Sdes{ 75098937Sdes int jid; 75198937Sdes char *login = NULL; 75298937Sdes struct jtab jtab; 75398937Sdes 75498937Sdes if ((jid = waitjob(&jtab)) == -1 || 75598937Sdes (login = uid2nam(jtab.j_uid)) == NULL) 75698937Sdes return; 75798937Sdes 75898937Sdes cray_delete_tmpdir(login, jid, jtab.j_uid); 75998937Sdes} 76098937Sdes 76198937Sdes/* 76298937Sdes * Set job id and create tmpdir directory. 76398937Sdes */ 76498937Sdesvoid 76598937Sdescray_init_job(struct passwd *pw) 76698937Sdes{ 76798937Sdes int jid; 76898937Sdes int c; 76998937Sdes 77098937Sdes jid = setjob(pw->pw_uid, WJSIGNAL); 77198937Sdes if (jid < 0) 77298937Sdes fatal("System call setjob failure"); 77398937Sdes 77498937Sdes for (c = 'a'; c <= 'z'; c++) { 77598937Sdes snprintf(cray_tmpdir, TPATHSIZ, "%s/jtmp.%06d%c", JTMPDIR, jid, c); 77698937Sdes if (mkdir(cray_tmpdir, JTMPMODE) != 0) 77798937Sdes continue; 77898937Sdes if (chown(cray_tmpdir, pw->pw_uid, pw->pw_gid) != 0) { 77998937Sdes rmdir(cray_tmpdir); 78098937Sdes continue; 78198937Sdes } 78298937Sdes break; 78398937Sdes } 78498937Sdes 78598937Sdes if (c > 'z') 78698937Sdes cray_tmpdir[0] = '\0'; 78798937Sdes} 78898937Sdes 78998937Sdesvoid 79098937Sdescray_set_tmpdir(struct utmp *ut) 79198937Sdes{ 79298937Sdes int jid; 79398937Sdes struct jtab jbuf; 79498937Sdes 79598937Sdes if ((jid = getjtab(&jbuf)) < 0) 79698937Sdes return; 79798937Sdes 79898937Sdes /* 79998937Sdes * Set jid and tmpdir in utmp record. 80098937Sdes */ 80198937Sdes ut->ut_jid = jid; 80298937Sdes strncpy(ut->ut_tpath, cray_tmpdir, TPATHSIZ); 80398937Sdes} 804126274Sdes#endif /* UNICOS */ 805126274Sdes 806126274Sdes#ifdef _UNICOSMP 807126274Sdes#include <pwd.h> 808126274Sdes/* 809126274Sdes * Set job id and create tmpdir directory. 810126274Sdes */ 811126274Sdesvoid 812126274Sdescray_init_job(struct passwd *pw) 813126274Sdes{ 814126274Sdes initrm_silent(pw->pw_uid); 815126274Sdes return; 816126274Sdes} 817126274Sdes#endif /* _UNICOSMP */ 818