char *getegroup( job *pjob, /* I */ pbs_attribute *pattr) /* I group_list pbs_attribute */ { char *hit = 0; int i; struct array_strings *parst; char *pn; char *ptr; char groupname[PBS_MAXUSER + 1]; char *ret_group; /* search the group-list pbs_attribute */ if ((pattr->at_flags & ATR_VFLAG_SET) && (parst = pattr->at_val.at_arst)) { for (i = 0;i < parst->as_usedptr;i++) { pn = parst->as_string[i]; ptr = strchr(pn, '@'); if (ptr != NULL) { /* has host specification */ if (!strncmp(server_host, ptr + 1, strlen(ptr + 1))) { hit = pn; /* option 1. */ break; } } else { /* wildcard host (null) */ hit = pn; /* option 2. */ } } } if (!hit) /* nothing specified, return null */ { return(NULL); } /* copy group name into return buffer, strip off host name */ /* get_jobowner() works for group as well, same size */ get_jobowner(hit, groupname); ret_group = (char *)calloc(1, strlen(groupname) + 1); strcpy(ret_group,groupname); return(ret_group); } /* END getegroup() */
END_TEST START_TEST(get_jobowner_test) { char* from = (char *)"owner@host"; char to[PBS_MAXUSER+1]; memset(to, 0, sizeof(to)); get_jobowner(NULL, to); get_jobowner(from, NULL); get_jobowner(from, to); fail_unless(strcmp(to,"owner") == 0, "get_jobowner fail"); }
int svr_authorize_jobreq( struct batch_request *preq, /* I */ job *pjob) /* I */ { char owner[PBS_MAXUSER + 1]; get_jobowner(pjob->ji_wattr[JOB_ATR_job_owner].at_val.at_str, owner); return svr_authorize_req(preq, owner, get_variable(pjob, pbs_o_host)); } /* END svr_authorize_jobreq() */
int svr_chk_ownerResv(struct batch_request *preq, resc_resv *presv) { char owner[PBS_MAXUSER + 1]; char *host; char *pu; char rmtuser[PBS_MAXUSER + 1]; /* map user@host to "local" name */ pu = site_map_user(preq->rq_user, preq->rq_host); if (pu == NULL) return (-1); (void)strncpy(rmtuser, pu, PBS_MAXUSER); get_jobowner(presv->ri_wattr[(int)RESV_ATR_resv_owner].at_val.at_str, owner); host = get_hostPart(presv->ri_wattr[(int)RESV_ATR_resv_owner].at_val.at_str); pu = site_map_user(owner, host); return (strcmp(rmtuser, pu)); }
void req_deletearray(struct batch_request *preq) { job_array *pa; char *range; struct work_task *ptask; int num_skipped; char owner[PBS_MAXUSER + 1]; pa = get_array(preq->rq_ind.rq_delete.rq_objname); if (pa == NULL) { reply_ack(preq); return; } /* check authorization */ get_jobowner(pa->ai_qs.owner, owner); if (svr_authorize_req(preq, owner, pa->ai_qs.submit_host) == -1) { sprintf(log_buffer, msg_permlog, preq->rq_type, "Array", preq->rq_ind.rq_delete.rq_objname, preq->rq_user, preq->rq_host); log_event( PBSEVENT_SECURITY, PBS_EVENTCLASS_JOB, preq->rq_ind.rq_delete.rq_objname, log_buffer); req_reject(PBSE_PERM, 0, preq, NULL, "operation not permitted"); return; } /* get the range of jobs to iterate over */ range = preq->rq_extend; if ((range != NULL) && (strstr(range,ARRAY_RANGE) != NULL)) { /* parse the array range */ num_skipped = delete_array_range(pa,range); if (num_skipped < 0) { /* ERROR */ req_reject(PBSE_IVALREQ,0,preq,NULL,"Error in specified array range"); return; } } else { num_skipped = delete_whole_array(pa); } /* check if the array is gone */ if ((pa = get_array(preq->rq_ind.rq_delete.rq_objname)) != NULL) { /* some jobs were not deleted. They must have been running or had JOB_SUBSTATE_TRANSIT */ if (num_skipped != 0) { ptask = set_task(WORK_Timed, time_now + 2, array_delete_wt, preq); if(ptask) { return; } } } /* now that the whole array is deleted, we should mail the user if necessary */ reply_ack(preq); return; }
int req_deletearray( struct batch_request *preq) { job_array *pa; char *range; struct work_task *ptask; char log_buf[LOCAL_LOG_BUF_SIZE]; int num_skipped = 0; char owner[PBS_MAXUSER + 1]; time_t time_now = time(NULL); pa = get_array(preq->rq_ind.rq_delete.rq_objname); if (pa == NULL) { reply_ack(preq); return(PBSE_NONE); } /* check authorization */ get_jobowner(pa->ai_qs.owner, owner); if (svr_authorize_req(preq, owner, pa->ai_qs.submit_host) == -1) { sprintf(log_buf, msg_permlog, preq->rq_type, "Array", preq->rq_ind.rq_delete.rq_objname, preq->rq_user, preq->rq_host); log_event(PBSEVENT_SECURITY,PBS_EVENTCLASS_JOB,preq->rq_ind.rq_delete.rq_objname,log_buf); pthread_mutex_unlock(pa->ai_mutex); if (LOGLEVEL >= 7) { sprintf(log_buf, "%s: unlocked ai_mutex", __func__); log_event(PBSEVENT_JOB, PBS_EVENTCLASS_JOB, __func__, log_buf); } req_reject(PBSE_PERM, 0, preq, NULL, "operation not permitted"); return(PBSE_NONE); } /* get the range of jobs to iterate over */ range = preq->rq_extend; if ((range != NULL) && (strstr(range,ARRAY_RANGE) != NULL)) { if (LOGLEVEL >= 5) { sprintf(log_buf, "delete array requested by %s@%s for %s (%s)", preq->rq_user, preq->rq_host, preq->rq_ind.rq_delete.rq_objname, range); log_record(PBSEVENT_JOB, PBS_EVENTCLASS_JOB, __func__, log_buf); } /* parse the array range */ num_skipped = delete_array_range(pa,range); if (num_skipped < 0) { /* ERROR */ pthread_mutex_unlock(pa->ai_mutex); if (LOGLEVEL >= 7) { sprintf(log_buf, "%s: unlocked ai_mutex", __func__); log_event(PBSEVENT_JOB, PBS_EVENTCLASS_JOB, __func__, log_buf); } req_reject(PBSE_IVALREQ,0,preq,NULL,"Error in specified array range"); return(PBSE_NONE); } } else { if (LOGLEVEL >= 5) { sprintf(log_buf, "delete array requested by %s@%s for %s", preq->rq_user, preq->rq_host, preq->rq_ind.rq_delete.rq_objname); log_record(PBSEVENT_JOB, PBS_EVENTCLASS_JOB, __func__, log_buf); } if ((num_skipped = delete_whole_array(pa)) == NO_JOBS_IN_ARRAY) array_delete(pa); } if (num_skipped != NO_JOBS_IN_ARRAY) { pthread_mutex_unlock(pa->ai_mutex); if (LOGLEVEL >= 7) { sprintf(log_buf, "%s: unlocked ai_mutex", __func__); log_event(PBSEVENT_JOB, PBS_EVENTCLASS_JOB, __func__, log_buf); } /* check if the array is gone */ if ((pa = get_array(preq->rq_ind.rq_delete.rq_objname)) != NULL) { pthread_mutex_unlock(pa->ai_mutex); if (LOGLEVEL >= 7) { sprintf(log_buf, "%s: unlocked ai_mutex", __func__); log_event(PBSEVENT_JOB, PBS_EVENTCLASS_JOB, __func__, log_buf); } /* some jobs were not deleted. They must have been running or had JOB_SUBSTATE_TRANSIT */ if (num_skipped != 0) { ptask = set_task(WORK_Timed, time_now + 10, array_delete_wt, preq, FALSE); if (ptask) { return(PBSE_NONE); } } } } /* now that the whole array is deleted, we should mail the user if necessary */ reply_ack(preq); return(PBSE_NONE); } /* END req_deletearray() */
static char *geteusernam( job *pjob, pbs_attribute *pattr) /* pointer to User_List pbs_attribute */ { int rule3 = 0; char *hit = 0; int i; struct array_strings *parst; char *pn; char *ptr; char username[PBS_MAXUSER + 1]; char *ret_user; /* search the user-list pbs_attribute */ if ((pattr->at_flags & ATR_VFLAG_SET) && (parst = pattr->at_val.at_arst)) { for (i = 0;i < parst->as_usedptr;i++) { pn = parst->as_string[i]; ptr = strchr(pn, '@'); if (ptr != NULL) { /* has host specification */ if (!strncmp(server_host, ptr + 1, strlen(ptr + 1))) { hit = pn; /* option 1. */ break; } } else { /* wildcard host (null) */ hit = pn; /* option 2. */ } } } if (!hit) { /* default to the job owner ( 3.) */ hit = pjob->ji_wattr[JOB_ATR_job_owner].at_val.at_str; rule3 = 1; } /* copy user name into return buffer, strip off host name */ get_jobowner(hit, username); if (rule3) { ptr = site_map_user(username, get_variable(pjob, (char *)"PBS_O_HOST")); if (ptr != username) snprintf(username, sizeof(username), "%s", ptr); } ret_user = (char *)calloc(1, strlen(username) + 1); strcpy(ret_user,username); return(ret_user); } /* END geteusernam() */
void req_holdarray(struct batch_request *preq) { int i; char *pset; char *range_str; int rc; attribute temphold; char owner[PBS_MAXUSER + 1]; job_array *pa; /* batch_request *preq_tmp; */ pa = get_array(preq->rq_ind.rq_hold.rq_orig.rq_objname); if (pa == NULL) { /* this shouldn't happen since we verify that this is a valid array just prior to calling this function */ req_reject(PBSE_UNKARRAYID, 0, preq, NULL, "unable to find array"); } get_jobowner(pa->ai_qs.owner, owner); if (svr_authorize_req(preq, owner, pa->ai_qs.submit_host) == -1) { sprintf(log_buffer, msg_permlog, preq->rq_type, "Array", preq->rq_ind.rq_delete.rq_objname, preq->rq_user, preq->rq_host); log_event( PBSEVENT_SECURITY, PBS_EVENTCLASS_JOB, preq->rq_ind.rq_delete.rq_objname, log_buffer); req_reject(PBSE_PERM, 0, preq, NULL, "operation not permitted"); return; } if ((rc = get_hold(&preq->rq_ind.rq_hold.rq_orig.rq_attr, &pset, &temphold)) != 0) { req_reject(rc, 0, preq, NULL, NULL); return; } /* if other than HOLD_u is being set, must have privil */ if ((rc = chk_hold_priv(temphold.at_val.at_long, preq->rq_perm)) != 0) { req_reject(rc, 0, preq, NULL, NULL); return; } /* get the range of jobs to iterate over */ range_str = preq->rq_extend; if ((range_str != NULL) && (strstr(range_str,ARRAY_RANGE) != NULL)) { if ((rc = hold_array_range(pa,range_str,&temphold)) != 0) { req_reject(rc,0,preq,NULL, "Error in specified array range"); } } else { /* do the entire array */ for (i = 0;i < pa->ai_qs.array_size;i++) { if (pa->jobs[i] == NULL) continue; hold_job(&temphold,pa->jobs[i]); } } reply_ack(preq); }
int req_holdarray( void *vp) /* I */ { int i; struct batch_request *preq = (struct batch_request *)vp; char *pset; char *range_str; int rc; pbs_attribute temphold; char owner[PBS_MAXUSER + 1]; job_array *pa; job *pjob; char log_buf[LOCAL_LOG_BUF_SIZE]; pa = get_array(preq->rq_ind.rq_hold.rq_orig.rq_objname); if (pa == NULL) { /* this shouldn't happen since we verify that this is a valid array just prior to calling this function */ req_reject(PBSE_UNKARRAYID, 0, preq, NULL, "unable to find array"); return(PBSE_NONE); } get_jobowner(pa->ai_qs.owner, owner); if (svr_authorize_req(preq, owner, pa->ai_qs.submit_host) == -1) { sprintf(log_buf, msg_permlog, preq->rq_type, "Array", preq->rq_ind.rq_delete.rq_objname, preq->rq_user, preq->rq_host); log_event(PBSEVENT_SECURITY, PBS_EVENTCLASS_JOB, preq->rq_ind.rq_delete.rq_objname, log_buf); if (LOGLEVEL >= 7) { sprintf(log_buf, "%s: unlocking ai_mutex", __func__); log_event(PBSEVENT_JOB, PBS_EVENTCLASS_JOB, pa->ai_qs.parent_id, log_buf); } pthread_mutex_unlock(pa->ai_mutex); req_reject(PBSE_PERM, 0, preq, NULL, "operation not permitted"); return(PBSE_NONE); } if ((rc = get_hold(&preq->rq_ind.rq_hold.rq_orig.rq_attr, &pset, &temphold)) != 0) { if (LOGLEVEL >= 7) { sprintf(log_buf, "%s: unlocking ai_mutex", __func__); log_event(PBSEVENT_JOB, PBS_EVENTCLASS_JOB, pa->ai_qs.parent_id, log_buf); } pthread_mutex_unlock(pa->ai_mutex); req_reject(rc, 0, preq, NULL, NULL); return(PBSE_NONE); } /* if other than HOLD_u is being set, must have privil */ if ((rc = chk_hold_priv(temphold.at_val.at_long, preq->rq_perm)) != 0) { if (LOGLEVEL >= 7) { sprintf(log_buf, "%s: unlocking ai_mutex", __func__); log_event(PBSEVENT_JOB, PBS_EVENTCLASS_JOB, pa->ai_qs.parent_id, log_buf); } pthread_mutex_unlock(pa->ai_mutex); req_reject(rc, 0, preq, NULL, NULL); return(PBSE_NONE); } /* get the range of jobs to iterate over */ range_str = preq->rq_extend; if ((range_str != NULL) && (strstr(range_str,ARRAY_RANGE) != NULL)) { if ((rc = hold_array_range(pa,range_str,&temphold)) != 0) { pthread_mutex_unlock(pa->ai_mutex); req_reject(rc,0,preq,NULL, "Error in specified array range"); return(PBSE_NONE); } } else { /* do the entire array */ for (i = 0;i < pa->ai_qs.array_size;i++) { if (pa->job_ids[i] == NULL) continue; if ((pjob = svr_find_job(pa->job_ids[i], FALSE)) == NULL) { free(pa->job_ids[i]); pa->job_ids[i] = NULL; } else { hold_job(&temphold,pjob); if (LOGLEVEL >= 7) { sprintf(log_buf, "%s: unlocking ai_mutex", __func__); log_event(PBSEVENT_JOB, PBS_EVENTCLASS_JOB, pa->ai_qs.parent_id, log_buf); } unlock_ji_mutex(pjob, __func__, "1", LOGLEVEL); } } } if (LOGLEVEL >= 7) { sprintf(log_buf, "%s: unlocking ai_mutex", __func__); log_event(PBSEVENT_JOB, PBS_EVENTCLASS_JOB, pa->ai_qs.parent_id, log_buf); } pthread_mutex_unlock(pa->ai_mutex); reply_ack(preq); return(PBSE_NONE); } /* END req_holdarray() */
int svr_chk_owner(struct batch_request *preq, job *pjob) { char owner[PBS_MAXUSER+1]; char *pu; char *ph; char rmtuser[PBS_MAXUSER+PBS_MAXHOSTNAME+2]; extern int ruserok(const char *rhost, int suser, const char *ruser, const char *luser); #ifdef WIN32 extern int user_read_password(char *user, char **cred, size_t *len); extern int read_cred(job *pjob, char **cred, size_t *len); extern int decrypt_pwd(char *crypted, size_t len, char **passwd); #endif /* Are the owner and requestor the same? */ snprintf(rmtuser, sizeof(rmtuser), "%s", pjob->ji_wattr[(int)JOB_ATR_job_owner].at_val.at_str); pu = rmtuser; ph = strchr(rmtuser, '@'); if (!ph) return -1; *ph++ = '\0'; if (strcmp(preq->rq_user, pu) == 0) { /* Avoid the lookup if they match. */ if (strcmp(preq->rq_host, ph) == 0) return 0; /* Perform the lookup. */ if (is_same_host(preq->rq_host, ph)) return 0; } /* map requestor user@host to "local" name */ pu = site_map_user(preq->rq_user, preq->rq_host); if (pu == NULL) return (-1); (void)strncpy(rmtuser, pu, PBS_MAXUSER); /* * Get job owner name without "@host" and then map to "local" name. */ get_jobowner(pjob->ji_wattr[(int)JOB_ATR_job_owner].at_val.at_str, owner); pu = site_map_user(owner, get_hostPart(pjob->ji_wattr[(int)JOB_ATR_job_owner].at_val.at_str)); if (server.sv_attr[(int)SRV_ATR_FlatUID].at_val.at_long) { /* with flatuid, all that must match is user names */ return (strcmp(rmtuser, pu)); } else { /* non-flatuid space, must validate rmtuser vs owner */ #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(pu, NULL, 0, user_read_password, (char *)pu, pbs_decrypt_pwd, 0); } else { /* read/cache job password */ cache_usertoken_and_homedir(pu, NULL, 0, read_cred, (job *)pjob, pbs_decrypt_pwd, 0); } #endif return (ruserok(preq->rq_host, 0, rmtuser, pu)); } }