int set_jobexid( job *pjob, /* I */ pbs_attribute *attrry, /* I */ char *EMsg) /* O (optional,minsize=1024) */ { int addflags = 0; pbs_attribute *pattr; char **pmem; struct group *gpent; int free_puser = FALSE; char *puser = NULL; char *at; char *usr_at_host = NULL; int len; struct passwd *pwent = NULL; char *pgrpn; int free_pgrpn = TRUE; char gname[PBS_MAXGRPN + 1]; #ifdef _CRAY struct udb *pudb; #endif char tmpLine[1024 + 1]; char log_buf[LOCAL_LOG_BUF_SIZE]; long disable_id_check = 0; int CheckID; /* boolean */ if (EMsg != NULL) EMsg[0] = '\0'; /* use the passed User_List if set, may be a newly modified one */ /* if not set, fall back to the job's actual User_List, may be same */ if (get_svr_attr_l(SRV_ATR_DisableServerIdCheck, &disable_id_check) != PBSE_NONE) CheckID = 1; else CheckID = !disable_id_check; if (CheckID == 0) { /* NOTE: use owner, not userlist - should this be changed? */ /* Yes, changed 10/17/2007 */ if (pjob->ji_wattr[JOB_ATR_job_owner].at_val.at_str != NULL) { /* start of change to use userlist instead of owner 10/17/2007 */ if ((attrry + JOB_ATR_userlst)->at_flags & ATR_VFLAG_SET) pattr = attrry + JOB_ATR_userlst; else pattr = &pjob->ji_wattr[JOB_ATR_userlst]; if (pjob->ji_wattr[JOB_ATR_proxy_user].at_flags & ATR_VFLAG_SET) { puser = pjob->ji_wattr[JOB_ATR_proxy_user].at_val.at_str; /* set the job's owner as the new user, appending @host if * the job's owner has that */ at = strchr(pjob->ji_wattr[JOB_ATR_job_owner].at_val.at_str,'@'); len = strlen(puser) + 1; if (at != NULL) { len += strlen(at); usr_at_host = (char *)calloc(len, sizeof(char)); snprintf(usr_at_host,len,"%s%s", puser, at); } else { usr_at_host = (char *)calloc(len, sizeof(char)); snprintf(usr_at_host,len,"%s", puser); } free(pjob->ji_wattr[JOB_ATR_job_owner].at_val.at_str); pjob->ji_wattr[JOB_ATR_job_owner].at_val.at_str = usr_at_host; } else if ((puser = geteusernam(pjob, pattr)) == NULL) { if (EMsg != NULL) snprintf(EMsg, 1024, "cannot locate user name in job"); return(PBSE_BADUSER); } free_puser = TRUE; sprintf(tmpLine, "%s", puser); /* end of change to use userlist instead of owner 10/17/2007 */ } else { strcpy(tmpLine, "???"); } } /* END if (CheckID == 0) */ else { int perm; if ((attrry + JOB_ATR_userlst)->at_flags & ATR_VFLAG_SET) pattr = attrry + JOB_ATR_userlst; else pattr = &pjob->ji_wattr[JOB_ATR_userlst]; free_puser = TRUE; if ((puser = geteusernam(pjob, pattr)) == NULL) { if (EMsg != NULL) snprintf(EMsg, 1024, "cannot locate user name in job"); return(PBSE_BADUSER); } pwent = getpwnam_ext(puser); perm = svr_get_privilege(puser,get_variable(pjob,(char *)"PBS_O_HOST")); if (pwent == NULL) { snprintf(log_buf,sizeof(log_buf), "User %s does not exist in server password file\n", puser); log_err(errno, __func__, log_buf); if (EMsg != NULL) snprintf(EMsg,1024,"%s",log_buf); free(puser); return(PBSE_BADUSER); } if ((pwent->pw_uid == 0) || (perm & ATR_DFLAG_MGWR)) { struct array_strings *pas = NULL; get_svr_attr_arst(SRV_ATR_AclRoot, &pas); /* add check here for virtual user */ if (pjob->ji_wattr[JOB_ATR_proxy_user].at_flags & ATR_VFLAG_SET) { free(puser); free_puser = FALSE; puser = pjob->ji_wattr[JOB_ATR_proxy_user].at_val.at_str; pwent = getpwnam_ext(puser); if (pwent == NULL) { snprintf(log_buf,sizeof(log_buf), "User %s does not exist in server password file\n", puser); log_err(errno, __func__, log_buf); if (EMsg != NULL) snprintf(EMsg,1024,"%s",log_buf); return(PBSE_BADUSER); } /* set the job's owner as the new user */ at = strchr(pjob->ji_wattr[JOB_ATR_job_owner].at_val.at_str,'@'); len = strlen(puser) + 1; if (at != NULL) { len += strlen(at); usr_at_host = (char *)calloc(len, sizeof(char)); snprintf(usr_at_host,len,"%s%s", puser, at); } else { usr_at_host = (char *)calloc(len, sizeof(char)); snprintf(usr_at_host,len,"%s", puser); } free(pjob->ji_wattr[JOB_ATR_job_owner].at_val.at_str); pjob->ji_wattr[JOB_ATR_job_owner].at_val.at_str = usr_at_host; } else if (get_svr_attr_arst(SRV_ATR_AclRoot, &pas) == PBSE_NONE) { if (acl_check_my_array_string(pas, pjob->ji_wattr[JOB_ATR_job_owner].at_val.at_str, ACL_User) == 0) { if (EMsg != NULL) snprintf(EMsg, 1024, "root user %s fails ACL check", puser); if (free_puser == TRUE) free(puser); return(PBSE_BADUSER); /* root not allowed */ } } else if (pwent->pw_uid == 0) { if (EMsg != NULL) snprintf(EMsg, 1024, "root user %s not allowed", puser); if (free_puser == TRUE) free(puser); return(PBSE_BADUSER); /* root not allowed */ } } /* END if (pwent->pw_uid == 0) */ else if (pjob->ji_wattr[JOB_ATR_proxy_user].at_flags & ATR_VFLAG_SET) { /* cannot submit a proxy job if not root or a manager */ if (EMsg != NULL) { snprintf(EMsg, 1024, "User '%s' is attempting to submit a proxy job for user '%s' but is not a manager", puser, pjob->ji_wattr[JOB_ATR_proxy_user].at_val.at_str); } snprintf(log_buf, 1024, "User '%s' is attempting to submit a proxy job for user '%s' but is not a manager", puser, pjob->ji_wattr[JOB_ATR_proxy_user].at_val.at_str); log_err(PBSE_BADUSER, __func__, log_buf); if (free_puser == TRUE) free(puser); return(PBSE_BADUSER); } if (site_check_user_map(pjob, puser, EMsg, LOGLEVEL) == -1) { if (free_puser == TRUE) free(puser); return(PBSE_BADUSER); } snprintf(tmpLine, sizeof(tmpLine), "%s", puser); } /* END else (CheckID == 0) */ pattr = attrry + JOB_ATR_euser; job_attr_def[JOB_ATR_euser].at_free(pattr); job_attr_def[JOB_ATR_euser].at_decode(pattr, NULL, NULL, tmpLine, 0); #ifdef _CRAY /* on cray check UDB (user data base) for permission to batch it */ if ((pwent != NULL) && (puser != NULL)) { pudb = getudbuid(pwent->pw_uid); endudb(); if (pudb == UDB_NULL) { if (EMsg != NULL) snprintf(EMsg, 1024, "user %s not located in user data base", puser); if (free_puser == TRUE) free(puser); return(PBSE_BADUSER); } if (pudb->ue_permbits & (PERMBITS_NOBATCH | PERMBITS_RESTRICTED)) { if (free_puser == TRUE) free(puser); return(PBSE_QACESS); } /* if account (qsub -A) not specified, set default from UDB */ pattr = attrry + JOB_ATR_account; if ((pattr->at_flags & ATR_VFLAG_SET) == 0) { job_attr_def[JOB_ATR_account].at_decode( pattr, NULL, NULL, (char *)acid2nam(pudb->ue_acids[0])); } } /* END if ((pwent != NULL) && (puser != NULL)) */ #endif /* _CRAY */ /* * now figure out the group name under which the job should execute * PBS requires that each group have an entry in the group file, * see the admin guide for the reason why... * * use the passed group_list if set, may be a newly modified one * if not set, fall back to the job's actual group_list, may be same */ if ((attrry + JOB_ATR_grouplst)->at_flags & ATR_VFLAG_SET) pattr = attrry + JOB_ATR_grouplst; else pattr = &pjob->ji_wattr[JOB_ATR_grouplst]; /* extract user-specified egroup if it exists */ pgrpn = getegroup(pjob, pattr); if (pgrpn == NULL) { free_pgrpn = FALSE; if ((pwent != NULL) || ((pwent = getpwnam_ext(puser)) != NULL)) { /* egroup not specified - use user login group */ gpent = getgrgid(pwent->pw_gid); if (gpent != NULL) { pgrpn = gpent->gr_name; /* use group name */ } else { sprintf(gname, "%ld", (long)pwent->pw_gid); pgrpn = gname; /* turn gid into string */ } } else if (CheckID == 0) { strcpy(gname, "???"); pgrpn = gname; } else { log_err(errno, __func__, (char *)"getpwnam failed"); if (EMsg != NULL) snprintf(EMsg, 1024, "user does not exist in server password file"); if (free_puser == TRUE) free(puser); return(PBSE_BADUSER); } /* * setting the DEFAULT flag is a "kludgy" way to keep MOM from * having to do an unneeded look up of the group file. * We needed to have JOB_ATR_egroup set for the server but * MOM only wants it if it is not the login group, so there! */ addflags = ATR_VFLAG_DEFLT; } /* END if ((pgrpn = getegroup(pjob,pattr))) */ else if (CheckID == 0) { /* egroup specified - do not validate group within server */ /* NO-OP */ } else { /* user specified a group, group must exist and either */ /* must be user's primary group or the user must be in it */ gpent = getgrnam_ext(pgrpn); if (gpent == NULL) { if (CheckID == 0) { strcpy(gname, "???"); pgrpn = gname; } else if (EMsg != NULL) snprintf(EMsg, 1024, "cannot locate group %s in server group file", pgrpn); if (free_puser == TRUE) free(puser); free(pgrpn); return(PBSE_BADGRP); /* no such group */ } if (gpent->gr_gid != pwent->pw_gid) { /* not primary group */ pmem = gpent->gr_mem; while (*pmem != NULL) { if (!strcmp(puser, *pmem)) break; ++pmem; } if (*pmem == NULL) { /* requested group not allowed */ snprintf(log_buf,sizeof(log_buf), "user %s is not a member of group %s in server password file", puser, pgrpn); log_err(-1, __func__, log_buf); if (EMsg != NULL) snprintf(EMsg, 1024, "%s",log_buf); if (free_puser == TRUE) free(puser); free(pgrpn); return(PBSE_BADGRP); /* user not in group */ } } } /* END if ((pgrpn = getegroup(pjob,pattr))) */ /* set new group */ pattr = attrry + JOB_ATR_egroup; job_attr_def[JOB_ATR_egroup].at_free(pattr); job_attr_def[JOB_ATR_egroup].at_decode(pattr, NULL, NULL, pgrpn, 0); pattr->at_flags |= addflags; /* SUCCESS */ if (free_puser == TRUE) free(puser); if (free_pgrpn == TRUE) free(pgrpn); return(0); } /* END set_jobexid() */
int set_objexid(void *pobj, int objtype, attribute *attrry) { int addflags = 0; int isowner; attribute *pattr; char *puser; char *pgrpn; char *owner; int idx_ul, idx_gl; int idx_owner, idx_euser, idx_egroup; int idx_acct; int bad_euser, bad_egrp; attribute *objattrs; attribute_def *obj_attr_def; attribute *paclRoot; /*future: aclRoot resv != aclRoot job*/ #ifdef WIN32 char user_s[PBS_MAXHOSTNAME+ MAXNAMLEN+3]; char *p = NULL; char *p0 = NULL; int ch = '\\'; SID *sid; char *defgrp = NULL; #else char **pmem; struct group *gpent; struct passwd *pwent; char gname[PBS_MAXGRPN+1]; #endif /* determine index values and pointers based on object type */ if (objtype == JOB_OBJECT) { idx_ul = (int)JOB_ATR_userlst; idx_gl = (int)JOB_ATR_grouplst; idx_owner = (int)JOB_ATR_job_owner; idx_euser = (int)JOB_ATR_euser; idx_egroup = (int)JOB_ATR_egroup; idx_acct = (int)JOB_ATR_account; obj_attr_def = job_attr_def; objattrs = ((job *)pobj)->ji_wattr; owner = ((job *)pobj)->ji_wattr[idx_owner].at_val.at_str; paclRoot = &server.sv_attr[(int)SRV_ATR_AclRoot]; bad_euser = PBSE_BADUSER; bad_egrp = PBSE_BADGRP; } else { idx_ul = (int)RESV_ATR_userlst; idx_gl = (int)RESV_ATR_grouplst; idx_owner = (int)RESV_ATR_resv_owner; idx_euser = (int)RESV_ATR_euser; idx_egroup = (int)RESV_ATR_egroup; idx_acct = (int)RESV_ATR_account; obj_attr_def = resv_attr_def; objattrs = ((resc_resv *)pobj)->ri_wattr; owner = ((resc_resv *)pobj)->ri_wattr[idx_owner].at_val.at_str; paclRoot = &server.sv_attr[(int)SRV_ATR_AclRoot]; bad_euser = PBSE_R_UID; bad_egrp = PBSE_R_GID; } /* if passed in "User_List" attribute is set use it - this may * be a newly modified one. * if not set, fall back to the object's User_List, which may * actually be the same as what is passed into this function */ if ((attrry + idx_ul)->at_flags & ATR_VFLAG_SET) pattr = attrry + idx_ul; else pattr = &objattrs[idx_ul]; if ((puser = determine_euser(pobj, objtype, pattr, &isowner)) == NULL) return (bad_euser); #ifdef WIN32 if (isAdminPrivilege(puser)) { /* equivalent of root */ if ((paclRoot->at_flags & ATR_VFLAG_SET) == 0) return (bad_euser); /* root not allowed */ if (acl_check(paclRoot, owner, ACL_User) == 0) return (bad_euser); /* root not allowed */ } #else pwent = getpwnam(puser); if (pwent == NULL) { if (!server.sv_attr[(int)SRV_ATR_FlatUID].at_val.at_long) return (bad_euser); } else if (pwent->pw_uid == 0) { if ((paclRoot->at_flags & ATR_VFLAG_SET) == 0) return (bad_euser); /* root not allowed */ if (acl_check(paclRoot, owner, ACL_User) == 0) return (bad_euser); /* root not allowed */ } #endif if (!isowner || !server.sv_attr[(int)SRV_ATR_FlatUID].at_val.at_long) { #ifdef WIN32 if ( (server.sv_attr[SRV_ATR_ssignon_enable].at_flags & \ ATR_VFLAG_SET) && \ (server.sv_attr[SRV_ATR_ssignon_enable].at_val.at_long \ == 1) ) { /* read/cache user password */ cache_usertoken_and_homedir(puser, NULL, 0, user_read_password, (char *)puser, pbs_decrypt_pwd, 0); } else { /* read/cache job password */ cache_usertoken_and_homedir(puser, NULL, 0, read_cred, (job *)pobj, pbs_decrypt_pwd, 0); } #endif if (site_check_user_map(pobj, objtype, puser) == -1) return (bad_euser); } pattr = &objattrs[idx_euser]; obj_attr_def[idx_euser].at_free(pattr); obj_attr_def[idx_euser].at_decode(pattr, NULL, NULL, puser); #ifndef WIN32 if (pwent != NULL) { #endif /* if account (qsub -A) is not specified, set to empty string */ pattr = &objattrs[idx_acct]; if ((pattr->at_flags & ATR_VFLAG_SET) == 0) { (void)obj_attr_def[idx_acct].at_decode(pattr, NULL, NULL, "\0"); } /* * now figure out (for this host) the effective/execute "group name" * for the object. * PBS requires that each group have an entry in the group file, * see the admin guide for the reason why... * * use the passed group_list if set, may be a newly modified one. * if it isn't set, use the object's group_list, which may in fact * be same as what was passed */ if ((attrry + idx_gl)->at_flags & ATR_VFLAG_SET) pattr = attrry + idx_gl; else pattr = &objattrs[idx_gl]; if ((pgrpn = determine_egroup(pobj, objtype, pattr)) != NULL) { /* user specified a group, group must exists and either */ /* must be user's primary group or the user must be in it */ #ifdef WIN32 if ((sid=getgrpsid(pgrpn)) == NULL) return (bad_egrp); /* no such group */ (void)LocalFree(sid); #else gpent = getgrnam(pgrpn); if (gpent == NULL) { if (pwent != NULL) /* no such group is allowed */ return (bad_egrp); /* only when no user (flatuid)*/ } else if (gpent->gr_gid != pwent->pw_gid) { /* not primary */ pmem = gpent->gr_mem; while (*pmem) { if (!strcmp(puser, *pmem)) break; ++pmem; } if (*pmem == 0) return (bad_egrp); /* user not in group */ } #endif addflags = ATR_VFLAG_SET; } else { /* Use user login group */ #ifdef WIN32 if ((defgrp=getdefgrpname(puser)) == NULL) return (bad_egrp); /* set to a group that ALL users belong to as default */ pgrpn = defgrp; #else gpent = getgrgid(pwent->pw_gid); if (gpent != NULL) { pgrpn = gpent->gr_name; /* use group name */ } else { (void)sprintf(gname, "%d", pwent->pw_gid); pgrpn = gname; /* turn gid into string */ } #endif /* * setting the DEFAULT flag is a "kludy" way to keep MOM from * having to do an unneeded look up of the group file. * We needed to have JOB_ATR_egroup set for the server but * MOM only wants it if it is not the login group, so there! */ addflags = ATR_VFLAG_SET | ATR_VFLAG_DEFLT; } #ifndef WIN32 } else { /* * null password entry, * set group to "default" and set default for Mom to use login group */ pgrpn = "-default-"; addflags = ATR_VFLAG_SET | ATR_VFLAG_DEFLT; } #endif pattr = attrry + idx_egroup; obj_attr_def[idx_egroup].at_free(pattr); if (addflags != 0) { obj_attr_def[idx_egroup].at_decode(pattr, NULL, NULL, pgrpn); pattr->at_flags |= addflags; } #ifdef WIN32 if (defgrp) (void)free(defgrp); #endif return (0); }