/* * Cray access denied */ int cray_access_denied(char *username) { struct udb *ueptr; /* UDB pointer for username */ int errcode; /* IA errorcode */ errcode = 0; getsysudb(); if ((ueptr = getudbnam(username)) == UDB_NULL) { debug("cray_login_failure(): getudbname() returned NULL"); } endudb(); if (ueptr && ueptr->ue_disabled) errcode = IA_DISABLED; if (errcode) cray_login_failure(username, errcode); return (errcode); }
void cray_login_failure(char *username, int errcode) { struct udb *ueptr; /* UDB pointer for username */ ia_failure_t fsent; /* ia_failure structure */ ia_failure_ret_t fret; /* ia_failure return stuff */ struct jtab jtab; /* job table structure */ int jid = 0; /* job id */ if ((jid = getjtab(&jtab)) < 0) debug("cray_login_failure(): getjtab error"); getsysudb(); if ((ueptr = getudbnam(username)) == UDB_NULL) debug("cray_login_failure(): getudbname() returned NULL"); endudb(); memset(&fsent, '\0', sizeof(fsent)); fsent.revision = 0; fsent.uname = username; fsent.host = (char *)get_canonical_hostname(options.use_dns); fsent.ttyn = "sshd"; fsent.caller = IA_SSHD; fsent.flags = IA_INTERACTIVE; fsent.ueptr = ueptr; fsent.jid = jid; fsent.errcode = errcode; fsent.pwdp = NULL; fsent.exitcode = 0; /* dont exit in ia_failure() */ fret.revision = 0; fret.normal = 0; /* * Call ia_failure because of an login failure. */ ia_failure(&fsent, &fret); }
int cray_setup (uid_t uid, char *username, const char *command) { extern struct udb *getudb(); extern char *setlimits(); int err; /* error return */ time_t system_time; /* current system clock */ time_t expiration_time; /* password expiration time */ int maxattempts; /* maximum no. of failed login attempts */ int SecureSys; /* unicos security flag */ int minslevel = 0; /* system minimum security level */ int i, j; int valid_acct = -1; /* flag for reading valid acct */ char acct_name[MAXACID] = { "" }; /* used to read acct name */ struct jtab jtab; /* Job table struct */ struct udb ue; /* udb entry for logging-in user */ struct udb *up; /* pointer to UDB entry */ struct secstat secinfo; /* file security attributes */ struct servprov init_info; /* used for sesscntl() call */ int jid; /* job ID */ int pid; /* process ID */ char *sr; /* status return from setlimits() */ char *ttyn = NULL; /* ttyname or command name*/ char hostname[MAXHOSTNAMELEN]; passwd_t pwdacm, pwddialup, pwdudb, pwdwal, pwddce; /* passwd stuff for ia_user */ ia_user_ret_t uret; /* stuff returned from ia_user */ ia_user_t usent; /* ia_user main structure */ int ia_rcode; /* ia_user return code */ ia_failure_t fsent; /* ia_failure structure */ ia_failure_ret_t fret; /* ia_failure return stuff */ ia_success_t ssent; /* ia_success structure */ ia_success_ret_t sret; /* ia_success return stuff */ int ia_mlsrcode; /* ia_mlsuser return code */ int secstatrc; /* [f]secstat return code */ if (SecureSys = (int)sysconf(_SC_CRAY_SECURE_SYS)) { getsysv(&sysv, sizeof(struct sysv)); minslevel = sysv.sy_minlvl; if (getusrv(&usrv) < 0) { debug("getusrv() failed, errno = %d",errno); exit(1); } } hostname[0] = '\0'; strncpy(hostname, (char *)get_canonical_hostname(options.verify_reverse_mapping), MAXHOSTNAMELEN); /* * Fetch user's UDB entry. */ getsysudb(); if ((up = getudbnam(username)) == UDB_NULL) { debug("cannot fetch user's UDB entry"); exit(1); } /* * Prevent any possible fudging so perform a data * safety check and compare the supplied uid against * the udb's uid. */ if (up->ue_uid != uid) { debug("IA uid missmatch"); exit(1); } endudb(); if ((jid = getjtab (&jtab)) < 0) { debug("getjtab"); return -1; } pid = getpid(); ttyn = ttyname(0); if (SecureSys) { if (ttyn) { secstatrc = secstat(ttyn, &secinfo); } else { secstatrc = fsecstat(1, &secinfo); } if (secstatrc == 0) { debug("[f]secstat() successful"); } else { debug("[f]secstat() error, rc = %d", secstatrc); exit(1); } } if ((ttyn == NULL) && ((char *)command != NULL)) ttyn = (char *)command; /* * Initialize all structures to call ia_user */ usent.revision = 0; usent.uname = username; usent.host = hostname; usent.ttyn = ttyn; usent.caller = IA_SSHD; usent.pswdlist = &pwdacm; usent.ueptr = &ue; usent.flags = IA_INTERACTIVE | IA_FFLAG; pwdacm.atype = IA_SECURID; pwdacm.pwdp = NULL; pwdacm.next = &pwdudb; pwdudb.atype = IA_UDB; pwdudb.pwdp = NULL; pwdudb.next = &pwddce; pwddce.atype = IA_DCE; pwddce.pwdp = NULL; pwddce.next = &pwddialup; pwddialup.atype = IA_DIALUP; pwddialup.pwdp = NULL; /* pwddialup.next = &pwdwal; */ pwddialup.next = NULL; pwdwal.atype = IA_WAL; pwdwal.pwdp = NULL; pwdwal.next = NULL; uret.revision = 0; uret.pswd = NULL; uret.normal = 0; ia_rcode = ia_user(&usent, &uret); switch (ia_rcode) { /* * These are acceptable return codes from ia_user() */ case IA_UDBWEEK: /* Password Expires in 1 week */ expiration_time = ue.ue_pwage.time + ue.ue_pwage.maxage; printf ("WARNING - your current password will expire %s\n", ctime((const time_t *)&expiration_time)); break; case IA_UDBEXPIRED: if (ttyname(0) != NULL) { /* Force a password change */ printf("Your password has expired; Choose a new one.\n"); execl("/bin/passwd", "passwd", username, 0); exit(9); } break; case IA_NORMAL: /* Normal Return Code */ break; case IA_BACKDOOR: strcpy(ue.ue_name, "root"); strcpy(ue.ue_passwd, ""); strcpy(ue.ue_dir, "/"); strcpy(ue.ue_shell, "/bin/sh"); strcpy(ue.ue_age, ""); strcpy(ue.ue_comment, ""); strcpy(ue.ue_loghost, ""); strcpy(ue.ue_logline, ""); ue.ue_uid=-1; ue.ue_nice[UDBRC_INTER]=0; for (i=0;i<MAXVIDS;i++) ue.ue_gids[i]=0; ue.ue_logfails=0; ue.ue_minlvl=minslevel; ue.ue_maxlvl=minslevel; ue.ue_deflvl=minslevel; ue.ue_defcomps=0; ue.ue_comparts=0; ue.ue_permits=0; ue.ue_trap=0; ue.ue_disabled=0; ue.ue_logtime=0; break; case IA_CONSOLE: /* Superuser not from Console */ case IA_TRUSTED: /* Trusted user */ if (options.permit_root_login > PERMIT_NO) break; /* Accept root login */ default: /* * These are failed return codes from ia_user() */ switch (ia_rcode) { case IA_BADAUTH: printf ("Bad authorization, access denied.\n"); break; case IA_DIALUPERR: break; case IA_DISABLED: printf ("Your login has been disabled. Contact the system "); printf ("administrator for assistance.\n"); break; case IA_GETSYSV: printf ("getsysv() failed - errno = %d\n", errno); break; case IA_LOCALHOST: break; case IA_MAXLOGS: printf ("Maximum number of failed login attempts exceeded.\n"); printf ("Access denied.\n"); break; case IA_NOPASS: break; case IA_PUBLIC: break; case IA_SECURIDERR: break; case IA_CONSOLE: break; case IA_TRUSTED: break; case IA_UDBERR: break; case IA_UDBPWDNULL: /* * NULL password not allowed on MLS systems */ if (SecureSys) { printf("NULL Password not allowed on MLS systems.\n"); } break; case IA_UNKNOWN: break; case IA_UNKNOWNYP: break; case IA_WALERR: break; default: /* nothing special */ ; } /* 2. switch (ia_rcode) */ /* * Authentication failed. */ printf("sshd: Login incorrect, (0%o)\n", ia_rcode-IA_ERRORCODE); /* * Initialize structure for ia_failure * which will exit. */ fsent.revision = 0; fsent.uname = username; fsent.host = hostname; fsent.ttyn = ttyn; fsent.caller = IA_SSHD; fsent.flags = IA_INTERACTIVE; fsent.ueptr = &ue; fsent.jid = jid; fsent.errcode = ia_rcode; fsent.pwdp = uret.pswd; fsent.exitcode = 1; fret.revision = 0; fret.normal = 0; /* * Call ia_failure because of an IA failure. * There is no return because ia_failure exits. */ ia_failure(&fsent,&fret); exit(1); } /* 1. switch (ia_rcode) */ ia_mlsrcode = IA_NORMAL; if (SecureSys) { debug("calling ia_mlsuser()"); ia_mlsrcode = ia_mlsuser (&ue, &secinfo, &usrv, NULL, 0); } if (ia_mlsrcode != IA_NORMAL) { printf("sshd: Login incorrect, (0%o)\n", ia_mlsrcode-IA_ERRORCODE); /* * Initialize structure for ia_failure * which will exit. */ fsent.revision = 0; fsent.uname = username; fsent.host = hostname; fsent.ttyn = ttyn; fsent.caller = IA_SSHD; fsent.flags = IA_INTERACTIVE; fsent.ueptr = &ue; fsent.jid = jid; fsent.errcode = ia_mlsrcode; fsent.pwdp = uret.pswd; fsent.exitcode = 1; fret.revision = 0; fret.normal = 0; /* * Call ia_failure because of an IA failure. * There is no return because ia_failure exits. */ ia_failure(&fsent,&fret); exit(1); } /* Provide login status information */ if (options.print_lastlog && ue.ue_logtime != 0) { printf("Last successful login was : %.*s ", 19, (char *)ctime(&ue.ue_logtime)); if (*ue.ue_loghost != '\0') printf("from %.*s\n", sizeof(ue.ue_loghost), ue.ue_loghost); else printf("on %.*s\n", sizeof(ue.ue_logline), ue.ue_logline); if ( SecureSys && (ue.ue_logfails != 0)) printf(" followed by %d failed attempts\n", ue.ue_logfails); } /* * Call ia_success to process successful I/A. */ ssent.revision = 0; ssent.uname = username; ssent.host = hostname; ssent.ttyn = ttyn; ssent.caller = IA_SSHD; ssent.flags = IA_INTERACTIVE; ssent.ueptr = &ue; ssent.jid = jid; ssent.errcode = ia_rcode; ssent.us = NULL; ssent.time = 1; /* Set ue_logtime */ sret.revision = 0; sret.normal = 0; ia_success(&ssent,&sret); /* * Query for account, iff > 1 valid acid & askacid permbit */ if (((ue.ue_permbits & PERMBITS_ACCTID) || (ue.ue_acids[0] >= 0) && (ue.ue_acids[1] >= 0)) && ue.ue_permbits & PERMBITS_ASKACID) { if (ttyname(0) != NULL) { debug("cray_setup: ttyname true case, %.100s", ttyname); while (valid_acct == -1) { printf("Account (? for available accounts)" " [%s]: ", acid2nam(ue.ue_acids[0])); gets(acct_name); switch (acct_name[0]) { case EOF: exit(0); break; case '\0': valid_acct = ue.ue_acids[0]; strcpy(acct_name, acid2nam(valid_acct)); break; case '?': /* Print the list 3 wide */ for (i = 0, j = 0; i < MAXVIDS; i++) { if (ue.ue_acids[i] == -1) { printf("\n"); break; } if (++j == 4) { j = 1; printf("\n"); } printf(" %s", acid2nam(ue.ue_acids[i])); } if (ue.ue_permbits & PERMBITS_ACCTID) printf("\"acctid\" permbit also allows" " you to select any valid " "account name.\n"); printf("\n"); break; default: if ((valid_acct = nam2acid(acct_name)) == -1) printf("Account id not found for" " account name \"%s\"\n\n", acct_name); break; } /* * If an account was given, search the user's * acids array to verify they can use this account. */ if ((valid_acct != -1) && !(ue.ue_permbits & PERMBITS_ACCTID)) { for (i = 0; i < MAXVIDS; i++) { if (ue.ue_acids[i] == -1) break; if (valid_acct == ue.ue_acids[i]) break; } if (i == MAXVIDS || ue.ue_acids[i] == -1) { fprintf(stderr, "Cannot set" " account name to " "\"%s\", permission " "denied\n\n", acct_name); valid_acct = -1; } } } } else { /* * The client isn't connected to a terminal and can't * respond to an acid prompt. Use default acid. */ debug("cray_setup: ttyname false case, %.100s", ttyname); valid_acct = ue.ue_acids[0]; } } else { /* * The user doesn't have the askacid permbit set or * only has one valid account to use. */ valid_acct = ue.ue_acids[0]; } if (acctid(0, valid_acct) < 0) { printf ("Bad account id: %d\n", valid_acct); exit(1); } /* set up shares and quotas */ /* Now set shares, quotas, limits, including CPU time for the (interactive) * job and process, and set up permissions (for chown etc), etc. */ if (setshares(ue.ue_uid, valid_acct, printf, 0, 0)) { printf("Unable to give %d shares to <%s>(%d/%d)\n", ue.ue_shares, ue.ue_name, ue.ue_uid, valid_acct); exit(1); } sr = setlimits(username, C_PROC, pid, UDBRC_INTER); if (sr != NULL) { debug("%.200s", sr); exit(1); } sr = setlimits(username, C_JOB, jid, UDBRC_INTER); if (sr != NULL) { debug("%.200s", sr); exit(1); } /* * Place the service provider information into * the session table (Unicos) or job table (Unicos/mk). * There exist double defines for the job/session table in * unicos/mk (jtab.h) so no need for a compile time switch. */ bzero((char *)&init_info, sizeof(struct servprov)); init_info.s_sessinit.si_id = URM_SPT_LOGIN; init_info.s_sessinit.si_pid = getpid(); init_info.s_sessinit.si_sid = jid; init_info.s_routing.seqno = 0; init_info.s_routing.iadrs = 0; sesscntl(0, S_SETSERVPO, (int)&init_info); /* * Set user and controlling tty security attributes. */ if (SecureSys) { if (setusrv(&usrv) == -1) { debug("setusrv() failed, errno = %d",errno); exit(1); } } return(0); }
static void do_login(const struct passwd *pwd, char *tty, char *ttyn) { #ifdef HAVE_GETSPNAM struct spwd *sp; #endif int rootlogin = (pwd->pw_uid == 0); gid_t tty_gid; struct group *gr; const char *home_dir; int i; if(!rootlogin) checknologin(); #ifdef HAVE_GETSPNAM sp = getspnam(pwd->pw_name); #endif update_utmp(pwd->pw_name, remote_host ? remote_host : "", tty, ttyn); gr = getgrnam ("tty"); if (gr != NULL) tty_gid = gr->gr_gid; else tty_gid = pwd->pw_gid; if (chown (ttyn, pwd->pw_uid, tty_gid) < 0) { warn("chown %s", ttyn); if (rootlogin == 0) exit (1); } if (chmod (ttyn, S_IRUSR | S_IWUSR | S_IWGRP) < 0) { warn("chmod %s", ttyn); if (rootlogin == 0) exit (1); } #ifdef HAVE_SETLOGIN if(setlogin(pwd->pw_name)){ warn("setlogin(%s)", pwd->pw_name); if(rootlogin == 0) exit(1); } #endif if(rootlogin == 0) { const char *file = login_conf_get_string("limits"); if(file == NULL) file = _PATH_LIMITS_CONF; read_limits_conf(file, pwd); } #ifdef HAVE_SETPCRED if (setpcred (pwd->pw_name, NULL) == -1) warn("setpcred(%s)", pwd->pw_name); #endif /* HAVE_SETPCRED */ #ifdef HAVE_INITGROUPS if(initgroups(pwd->pw_name, pwd->pw_gid)){ warn("initgroups(%s, %u)", pwd->pw_name, (unsigned)pwd->pw_gid); if(rootlogin == 0) exit(1); } #endif if(do_osfc2_magic(pwd->pw_uid)) exit(1); if(setgid(pwd->pw_gid)){ warn("setgid(%u)", (unsigned)pwd->pw_gid); if(rootlogin == 0) exit(1); } if(setuid(pwd->pw_uid) || (pwd->pw_uid != 0 && setuid(0) == 0)) { warn("setuid(%u)", (unsigned)pwd->pw_uid); if(rootlogin == 0) exit(1); } /* make sure signals are set to default actions, apparently some OS:es like to ignore SIGINT, which is not very convenient */ for (i = 1; i < NSIG; ++i) signal(i, SIG_DFL); /* all kinds of different magic */ #ifdef HAVE_GETSPNAM check_shadow(pwd, sp); #endif #if defined(HAVE_GETUDBNAM) && defined(HAVE_SETLIM) { struct udb *udb; long t; const long maxcpu = 46116860184; /* some random constant */ udb = getudbnam(pwd->pw_name); if(udb == UDB_NULL) errx(1, "Failed to get UDB entry."); t = udb->ue_pcpulim[UDBRC_INTER]; if(t == 0 || t > maxcpu) t = CPUUNLIM; else t *= 100 * CLOCKS_PER_SEC; if(limit(C_PROC, 0, L_CPU, t) < 0) warn("limit C_PROC"); t = udb->ue_jcpulim[UDBRC_INTER]; if(t == 0 || t > maxcpu) t = CPUUNLIM; else t *= 100 * CLOCKS_PER_SEC; if(limit(C_JOBPROCS, 0, L_CPU, t) < 0) warn("limit C_JOBPROCS"); nice(udb->ue_nice[UDBRC_INTER]); } #endif #if defined(HAVE_SGI_GETCAPABILITYBYNAME) && defined(HAVE_CAP_SET_PROC) /* XXX SGI capability hack IRIX 6.x (x >= 0?) has something called capabilities, that allow you to give away permissions (such as chown) to specific processes. From 6.5 this is default on, and the default capability set seems to not always be the empty set. The problem is that the runtime linker refuses to do just about anything if the process has *any* capabilities set, so we have to remove them here (unless otherwise instructed by /etc/capability). In IRIX < 6.5, these functions was called sgi_cap_setproc, etc, but we ignore this fact (it works anyway). */ { struct user_cap *ucap = sgi_getcapabilitybyname(pwd->pw_name); cap_t cap; if(ucap == NULL) cap = cap_from_text("all="); else cap = cap_from_text(ucap->ca_default); if(cap == NULL) err(1, "cap_from_text"); if(cap_set_proc(cap) < 0) err(1, "cap_set_proc"); cap_free(cap); free(ucap); } #endif home_dir = pwd->pw_dir; if (chdir(home_dir) < 0) { fprintf(stderr, "No home directory \"%s\"!\n", pwd->pw_dir); if (chdir("/")) exit(0); home_dir = "/"; fprintf(stderr, "Logging in with home = \"/\".\n"); } #ifdef KRB5 if (auth == AUTH_KRB5) { krb5_start_session (pwd); } krb5_get_afs_tokens (pwd); krb5_finish (); #endif /* KRB5 */ add_env("PATH", _PATH_DEFPATH); { const char *str = login_conf_get_string("environment"); char buf[MAXPATHLEN]; if(str == NULL) { login_read_env(_PATH_ETC_ENVIRONMENT); } else { while(strsep_copy(&str, ",", buf, sizeof(buf)) != -1) { if(buf[0] == '\0') continue; login_read_env(buf); } } } { const char *str = login_conf_get_string("motd"); char buf[MAXPATHLEN]; if(str != NULL) { while(strsep_copy(&str, ",", buf, sizeof(buf)) != -1) { if(buf[0] == '\0') continue; show_file(buf); } } else { str = login_conf_get_string("welcome"); if(str != NULL) show_file(str); } } add_env("HOME", home_dir); add_env("USER", pwd->pw_name); add_env("LOGNAME", pwd->pw_name); add_env("SHELL", pwd->pw_shell); exec_shell(pwd->pw_shell, rootlogin); }