int secure_file2(char *path, char *user, ACCESS_MASK mask, char *user2, ACCESS_MASK mask2) { SECURITY_DESCRIPTOR sd; SID *usid = NULL; SID *gsid; ACL *pdacl; struct stat sbuf; SECURITY_INFORMATION si = 0; char logb[LOG_BUF_SIZE] = {'\0' } ; char *gname = NULL; if (path == NULL) return (0); if (lstat(path, &sbuf) == -1) return (0); /* ignore non-existent files! */ if (!has_privilege(SE_RESTORE_NAME)) ena_privilege(SE_RESTORE_NAME); if (!has_privilege(SE_TAKE_OWNERSHIP_NAME)) ena_privilege(SE_TAKE_OWNERSHIP_NAME); InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION); /* make PBS service account as the owner */ usid = create_administrators_sid(); if (usid == NULL) usid = getusersid(getlogin()); if (usid) { if (SetSecurityDescriptorOwner(&sd, usid, FALSE) == 0) { sprintf(logb, "error setting owner for file %s", path); log_err(-1, "secure_file2", logb); LocalFree(usid); return (0); } si |= OWNER_SECURITY_INFORMATION; /* trick with setting perms, set ownership first! */ if (SetFileSecurity(path, si, &sd) == 0) { sprintf(logb, "error setting actual owner for file %s", path); log_err(-1, "secure_file2", logb); LocalFree(usid); return (0); } InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION); si = 0; } /* can't use gsid=getgid() since gsid here must be LocalFree()d */ if ((gname=getdefgrpname(getlogin()))) { gsid = getgrpsid(gname); (void)free(gname); } else { gsid = NULL; } if (gsid) { if (SetSecurityDescriptorGroup(&sd, gsid, FALSE) == 0) { sprintf(logb, "error setting group for file %s", path); log_err(-1, "secure_file2", logb); if (usid) LocalFree(usid); LocalFree(gsid); return (0); } si |= GROUP_SECURITY_INFORMATION; } pdacl = create_secure_dacl2(user, mask, user2, mask2, usid); if (pdacl == NULL) { sprintf(logb, "failed to create secure dacl for file %s", path); log_err(-1, "secure_file2", logb); if (usid) LocalFree(usid); if (gsid) LocalFree(gsid); return (0); } if (SetSecurityDescriptorDacl(&sd, TRUE, pdacl, TRUE) == 0) { sprintf(logb, "error setting dacl for file %s", path); log_err(-1, "secure_file2", logb); if (usid) LocalFree(usid); if (gsid) LocalFree(gsid); (void)free(pdacl); return (0); } si |= DACL_SECURITY_INFORMATION; if (SetFileSecurity(path, si, &sd) == 0) { sprintf(logb, "error setting security for file %s", path); log_err(-1, "secure_file2", logb); if (usid) LocalFree(usid); if (gsid) LocalFree(gsid); (void)free(pdacl); return (0); } if (usid) LocalFree(usid); if (gsid) LocalFree(gsid); (void)free(pdacl); /* Even though permissions have been set on the file, it can be */ /* overriden if a file attribute was given say a */ /* FILE_ATTRIBUTE_READONLY flag previously outside of PBS. Any */ /* writes to the file would still fail even if Administrators */ /* have been given write permission. */ /* The following call is to clear any special attributes that */ /* may have gotten set outside of PBS, negating PBS' permission */ /* change. */ (void)SetFileAttributes(path, FILE_ATTRIBUTE_NORMAL); return (1); }
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); }