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); }
void setosjobid(pid_t sid, gid_t *add_grp_id_ptr, struct passwd *pw) { FILE *fp=NULL; shepherd_trace("setosjobid: uid = "pid_t_fmt", euid = "pid_t_fmt, getuid(), geteuid()); # if defined(SOLARIS) || defined(ALPHA) || defined(LINUX) || defined(FREEBSD) || defined(DARWIN) /* Read SgeId from config-File and create Addgrpid-File */ { char *cp; if ((cp = search_conf_val("add_grp_id"))) *add_grp_id_ptr = atol(cp); else *add_grp_id_ptr = 0; } if ((fp = fopen("addgrpid", "w")) == NULL) { shepherd_error(1, "can't open \"addgrpid\" file"); } fprintf(fp, gid_t_fmt"\n", *add_grp_id_ptr); FCLOSE(fp); # elif defined(HP1164) || defined(AIX) { if ((fp = fopen("addgrpid", "w")) == NULL) { shepherd_error(1, "can't open \"addgrpid\" file"); } fprintf(fp, pid_t_fmt"\n", getpgrp()); FCLOSE(fp); } # else { char osjobid[100]; if ((fp = fopen("osjobid", "w")) == NULL) { shepherd_error(1, "can't open \"osjobid\" file"); } if(sge_switch2start_user() == 0) { # if defined(IRIX) { /* The following block contains the operations necessary for * IRIX6.2 (and later) to set array session handles (ASHs) and * service provider info (SPI) records */ struct acct_spi spi; int ret; char *cp; shepherd_trace("in irix code"); /* get _local_ array session id */ if ((ret=newarraysess())) { shepherd_error(1, "error: can't create ASH; errno=%d", ret); } /* retrieve array session id we just assigned to the process and * write it to the os-jobid file */ sprintf(osjobid, "%lld", getash()); shepherd_trace(osjobid); /* set service provider information (spi) record */ strncpy(spi.spi_company, "SGE", 8); strncpy(spi.spi_initiator, get_conf_val("spi_initiator"), 8); strncpy(spi.spi_origin, get_conf_val("queue"),16); strcpy(spi.spi_spi, "Job "); strncat(spi.spi_spi, get_conf_val("job_id"),11); if ((ret=setspinfo(&spi))) { shepherd_error(1, "error: can't set SPI; errno=%d", ret); } if ((cp = search_conf_val("acct_project"))) { prid_t proj; if (strcasecmp(cp, "none") && ((proj = projid(cp)) >= 0)) { shepherd_trace("setting project \"%s\" to id %lld", cp, proj); if (setprid(proj) == -1) shepherd_trace("failed setting project id"); } else { shepherd_trace("can't get id for project \"%s\"", cp); } } else { shepherd_trace("can't get configuration entry for projects"); } } # elif defined(CRAY) { char *cp; { int jobid; if ((jobid=setjob(pw->pw_uid, 0)) < 0) { shepherd_error(1, "error: can't set job ID; errno = %d", errno); } if (sesscntl(jobid, S_ADDFL, S_BATCH) == -1) { shepherd_error(1, "error: sesscntl(%d, S_ADDFL, S_BATCH) failed," " errno = %d", sid, errno); } sprintf(osjobid, "%d", jobid); } if ((cp = search_conf_val("acct_project"))) { int proj; if (strcasecmp(cp, "none") && ((proj = nam2acid(cp)) >= 0)) { shephed_trace("setting project \"%s\" to acid %d", cp, proj); if (acctid(0, proj) == -1) { shepherd_trace("failed setting project id (acctid)"); } } else { shepherd_trace("can't get id for project \"%s\"", cp); } } else { shepherd_trace("can't get configuration entry for projects"); } } # elif defined(NECSX4) || defined(NECSX5) { id_t jobid = 0; dispset2_t attr; int value; /* * Create new Super-UX job */ if (setjid() == -1) { shepherd_trace("ERROR: can't set jobid: %s[%d]", strerror(errno), errno); } else { jobid = getjid(0); shepherd_trace("Created job with id: "sge_u32, (u_long32) jobid); } sprintf(osjobid, sge_u32, (u_long32) jobid); /* * We will use limits for the whole job */ set_rlimits_os_job_id(jobid); /* * The job will use the resources of the configured * Resource Sharing Group (rsg) */ { char *rsg_id_string; int rsg_id; char fsg_dev_string[256]; rsg_id_string = get_conf_val("processors"); rsg_id = atoi(rsg_id_string); if (rsg_id) { int fd; sprintf(fsg_dev_string, "/dev/rsg/%d", rsg_id); fd = open(fsg_dev_string, O_RDONLY); if (fd <= 0) { shepherd_trace("ERROR: can't switch to rsg%d because can't open" "device: %s[%d]", rsg_id, strerror(errno), errno); } else { if (ioctl(fd, RSG_JUMP, NULL) == -1) { close(fd); shepherd_trace("ERROR: can't switch to rsg%d: %s[%d]", rsg_id, strerror(errno), errno); return; } else { close(fd); shepherd_trace("switched to rsg%d", rsg_id); } } } else { shepherd_trace("using default rsg", rsg_id); } } /* * Set scheduling parameter for job */ if (((attr.basepri = atoi(get_conf_val("nec_basepriority"))) != NEC_UNDEF_VALUE) && ((attr.modcpu = atoi(get_conf_val("nec_modcpu"))) != NEC_UNDEF_VALUE) && ((attr.tickcnt = atoi(get_conf_val("nec_tickcnt"))) != NEC_UNDEF_VALUE) && ((attr.dcyfctr = atoi(get_conf_val("nec_dcyfctr"))) != NEC_UNDEF_VALUE) && ((attr.dcyintvl = atoi(get_conf_val("nec_dcyintvl"))) != NEC_UNDEF_VALUE) && ((attr.tmslice = atoi(get_conf_val("nec_timeslice"))) != NEC_UNDEF_VALUE) && ((attr.mempri = atoi(get_conf_val("nec_memorypriority"))) != NEC_UNDEF_VALUE) && ((attr.szefctmrt = atoi(get_conf_val("nec_mrt_size_effct"))) != NEC_UNDEF_VALUE) && ((attr.priefctmrt = atoi(get_conf_val("nec_mrt_pri_effct"))) != NEC_UNDEF_VALUE) && ((attr.minmrt = atoi(get_conf_val("nec_mrt_minimum"))) != NEC_UNDEF_VALUE) && ((attr.agrange = atoi(get_conf_val("nec_aging_range"))) != NEC_UNDEF_VALUE) && ((attr.spinherit = atoi(get_conf_val("nec_slavepriority"))) != NEC_UNDEF_VALUE) && ((attr.concpu = atoi(get_conf_val("nec_cpu_count"))) != NEC_UNDEF_VALUE)) { if (dispcntl(SG_JID, getjid(0), DCNTL_SET2, &attr) == -1) { shepherd_trace("ERROR: can't set scheduling parameter: %s[%d]", strerror(errno), errno); } else { shepherd_trace("control parameters for active process scheduling modified"); print_scheduling_parameters(attr); } } else { shepherd_trace("we do not control active process scheduling"); } } # else /* write a default os-jobid to file */ sprintf(osjobid, pid_t_fmt, sid); # endif sge_switch2admin_user(); } else /* not running as super user --> we want a default os-jobid */ sprintf(osjobid, "0"); if(fprintf(fp, "%s\n", osjobid) < 0) shepherd_trace("error writing osjobid file"); FCLOSE(fp); /* Close os-jobid file */ } # endif return; FCLOSE_ERROR: shepherd_error(1, "can't close file"); }