/** * @brief * vn_encode_DIS_V4 - encode version 4 vnode information, used by Mom. * * @par Functionality: * Used to encode vnode information. See vn_encode_DIS() above for a * description of the information. Supports version 4 only. * * @param[in] fd - socket descriptor to which to write the encode info. * @param[in] vnlp - structure to encode and send. * * @return int * @retval DIS_SUCCESS (0) on success * @retval DIS_* on error. * * @par Side Effects: None * * @par MT-safe: No, the structure pointed to by vnlp needs to be locked * */ static int vn_encode_DIS_V4(int fd, vnl_t *vnlp) { int rc; unsigned int i, j; if (((rc = diswui(fd, PS_DIS_V4)) != 0) || ((rc = diswsl(fd, (long) vnlp->vnl_modtime)) != 0) || ((rc = diswui(fd, vnlp->vnl_used)) != 0)) return (rc); for (i = 0; i < vnlp->vnl_used; i++) { vnal_t *curreslist = VNL_NODENUM(vnlp, i); if ((rc = diswst(fd, curreslist->vnal_id)) != 0) return (rc); if ((rc = diswui(fd, curreslist->vnal_used)) != 0) return (rc); for (j = 0; j < curreslist->vnal_used; j++) { vna_t *curres = VNAL_NODENUM(curreslist, j); if ((rc = diswst(fd, curres->vna_name)) != 0) return (rc); if ((rc = diswst(fd, curres->vna_val)) != 0) return (rc); if ((rc = diswsi(fd, curres->vna_type)) != 0) return (rc); if ((rc = diswsi(fd, curres->vna_flag)) != 0) return (rc); } } return (DIS_SUCCESS); }
int encode_DIS_Run(int sock, char *id, char *where, unsigned long arg) { int rc; if ((rc = diswst(sock, id) != 0) || (rc = diswst(sock, where) != 0) || (rc = diswul(sock, arg) != 0)) return rc; return 0; }
int encode_DIS_TrackJob(int sock, struct batch_request *preq) { int rc; if ((rc = diswst(sock, preq->rq_ind.rq_track.rq_jid) != 0) || (rc = diswui(sock, preq->rq_ind.rq_track.rq_hopcount) != 0) || (rc = diswst(sock, preq->rq_ind.rq_track.rq_location) != 0) || (rc = diswuc(sock, preq->rq_ind.rq_track.rq_state[0]) != 0)) return rc; return 0; }
int encode_DIS_Register(int sock, struct batch_request *preq) { int rc; if ((rc = diswst(sock, preq->rq_ind.rq_register.rq_owner) != 0) || (rc = diswst(sock, preq->rq_ind.rq_register.rq_parent) != 0) || (rc = diswst(sock, preq->rq_ind.rq_register.rq_child) != 0) || (rc = diswui(sock, preq->rq_ind.rq_register.rq_dependtype) != 0) || (rc = diswui(sock, preq->rq_ind.rq_register.rq_op) != 0) || (rc = diswsl(sock, preq->rq_ind.rq_register.rq_cost) != 0)) return rc; return 0; }
static int encode_DIS_Resc( struct tcp_chan *chan, char **rlist, int ct, resource_t rh) { int i; int rc; if ((rc = diswsi(chan,rh)) == 0) /* resource reservation handle */ { /* next send the number of resource strings */ if ((rc = diswui(chan, ct)) == 0) { /* now send each string (if any) */ for (i = 0; i < ct; ++i) { if ((rc = diswst(chan, *(rlist + i))) != 0) break; } } } return rc; }
int send_command_str( struct tcp_chan *chan, int cmd, char *query) /* I */ { int rc; rc = diswsi(chan, cmd); if ((rc != DIS_SUCCESS) || (cmd == RM_CMD_CLOSE)) return(rc); if (cmd == RM_CMD_CONFIG) { if((rc = diswst(chan, ConfigBuf)) != DIS_SUCCESS) return (rc); } rc = diswcs(chan, query, strlen(query)); DIS_tcp_wflush(chan); return(rc); } /* END send_command_str() */
int encode_DIS_SubmitResv(int sock, char *resv_id, struct attropl *aoplp) { int rc; if (resv_id == NULL) resv_id = ""; /* send the reservation ID and then an empty destination * This is done so the server can use the queuejob structure */ if ((rc = diswst(sock, resv_id) != 0) || (rc = diswst(sock, "") != 0)) return rc; return (encode_DIS_attropl(sock, aoplp)); }
int encode_DIS_attrl(int sock, struct attrl *pattrl) { unsigned int ct = 0; unsigned int name_len; struct attrl *ps; int rc; /* count how many */ for (ps = pattrl; ps; ps = ps->next) { ++ct; } if ((rc = diswui(sock, ct)) != 0) return rc; for (ps = pattrl; ps; ps = ps->next) { /* length of three strings */ name_len = (int)strlen(ps->name) + (int)strlen(ps->value) + 2; if (ps->resource) name_len += strlen(ps->resource) + 1; if ((rc = diswui(sock, name_len)) != 0) break; if ((rc = diswst(sock, ps->name)) != 0) break; if (ps->resource) { /* has a resource name */ if ((rc = diswui(sock, 1)) != 0) break; if ((rc = diswst(sock, ps->resource)) != 0) break; } else { if ((rc = diswui(sock, 0)) != 0) /* no resource name */ break; } if ((rc = diswst(sock, ps->value)) || (rc = diswui(sock, (unsigned int)SET))) break; } return rc; }
int encode_DIS_DelHookFile(int sock, char *filename) { int rc; if ((rc = diswst(sock, filename) != 0)) return rc; return 0; }
int encode_DIS_MoveJob( int sock, char *jobid, char *destin) { int rc; if ((rc = diswst(sock, jobid) != 0) || (rc = diswst(sock, destin) != 0)) { /* FAILURE */ return(rc); } /* SUCCESS */ return(0); }
int encode_DIS_CopyHookFile(int sock, int seq, char *buf, int len, char *filename) { int rc; if ((rc = diswui(sock, seq) != 0) || (rc = diswui(sock, len) != 0) || (rc = diswst(sock, filename) != 0) || (rc = diswcs(sock, buf, len) != 0)) return rc; return 0; }
int encode_DIS_ReqExtend(int sock, char *extend) { int rc; if ((extend == NULL) || (*extend == '\0')) { rc = diswui(sock, 0); } else { if ((rc = diswui(sock, 1)) == 0) { rc = diswst(sock, extend); } } return rc; }
/** * @brief encode the Modify Reservation request for sending to the server. * * @param[in] sock - socket descriptor for the connection. * @param[in] resv_id - Reservation identifier of the reservation that would be modified. * @param[in] aoplp - list of attributes that will be modified. * * @return - error code while writing data to the socket. */ int encode_DIS_ModifyResv(int sock, char *resv_id, struct attropl *aoplp) { int rc = 0; if (resv_id == NULL) resv_id = ""; if (((rc = diswui(sock, MGR_OBJ_RESV)) != 0) || ((rc = diswst(sock, resv_id)) != 0)) return rc; return (encode_DIS_attropl(sock, aoplp)); }
int encode_DIS_QueueJob( struct tcp_chan *chan, const char *jobid, const char *destin, struct attropl *aoplp) { int rc; if (jobid == (char *)0) jobid = (char *)""; if (destin == (char *)0) destin = (char *)""; if ((rc = diswst(chan, jobid) != 0) || (rc = diswst(chan, destin) != 0)) { return rc; } return(encode_DIS_attropl(chan, aoplp)); } /* END encode_DIS_QueueJob() */
int encode_DIS_replyRPP(int sock, char *rppcmd_msgid, struct batch_reply *reply) { int rc; /* first encode "header" consisting of protocol type and version */ /* since it RPP, write a header */ if ((rc = is_compose(sock, IS_CMD_REPLY)) != DIS_SUCCESS) return rc; /* for IS_CMD_REPLY, also send across the rppcmd_msgid, so that * server can match the reply with the request it had sent earlier */ if ((rc = diswst(sock, rppcmd_msgid)) != DIS_SUCCESS) return rc; return (encode_DIS_reply_inner(sock, reply)); }
int send_command( struct tcp_chan *chan, int cmd) { int rc; rc = diswsi(chan,cmd); if (cmd == RM_CMD_CONFIG) { diswst(chan,ConfigBuf); } DIS_tcp_wflush(chan); if (cmd == RM_CMD_CLOSE) DIS_tcp_close(chan); return(rc); } /* END send_command() */
int encode_DIS_ReqExtend( struct tcp_chan *chan, char *extend) { int rc; if ((extend == (char *)0) || (*extend == '\0')) { rc = diswui(chan, 0); } else { if ((rc = diswui(chan, 1)) == 0) { rc = diswst(chan, extend); } } return rc; }
/** * @brief * -encode_DIS_CopyFiles_Cred() - encode a Copy Files with Credential Dependency * Batch Request * * @par Note: * This request is used by the server ONLY; its input is a server * batch request structure. * * @param[in] sock - socket descriptor * @param[in] preq - pointer to batch request * * @par Data items are:\n * string job id\n * string job owner(may be null)\n * string execution user name\n * string execution group name(may be null)\n * unsigned int direction & job_dir_enable flag\n * unsigned int count of file pairs in set\n * set of file pairs:\n * unsigned int flag\n * string local path name\n * string remote path name (may be null)\n * unsigned int credential type\n * unsigned int credential length (bytes)\n * byte string credential\n * * @return int * @retval 0 success * @retval !0 error * */ int encode_DIS_CopyFiles_Cred(int sock, struct batch_request *preq) { int pair_ct = 0; char *nullstr = ""; struct rqfpair *ppair; int rc; size_t clen; struct rq_cpyfile *rcpyf; clen = (size_t)preq->rq_ind.rq_cpyfile_cred.rq_credlen; rcpyf = &preq->rq_ind.rq_cpyfile_cred.rq_copyfile; ppair = (struct rqfpair *)GET_NEXT(rcpyf->rq_pair); while (ppair) { ++pair_ct; ppair = (struct rqfpair *)GET_NEXT(ppair->fp_link); } if ((rc = diswst(sock, rcpyf->rq_jobid) != 0) || (rc = diswst(sock, rcpyf->rq_owner) != 0) || (rc = diswst(sock, rcpyf->rq_user) != 0) || (rc = diswst(sock, rcpyf->rq_group) != 0) || (rc = diswui(sock, rcpyf->rq_dir) != 0)) return rc; if ((rc = diswui(sock, pair_ct) != 0)) return rc; ppair = (struct rqfpair *)GET_NEXT(rcpyf->rq_pair); while (ppair) { if (ppair->fp_rmt == NULL) ppair->fp_rmt = nullstr; if ((rc = diswui(sock, ppair->fp_flag) != 0) || (rc = diswst(sock, ppair->fp_local) != 0) || (rc = diswst(sock, ppair->fp_rmt) != 0)) return rc; ppair = (struct rqfpair *)GET_NEXT(ppair->fp_link); } rc = diswui(sock, preq->rq_ind.rq_cpyfile_cred.rq_credtype); if (rc != 0) return rc; rc = diswcs(sock, preq->rq_ind.rq_cpyfile_cred.rq_pcred, clen); if (rc != 0) return rc; return 0; }
int encode_DIS_JobObit( int sock, /* I */ struct batch_request *preq) /* I */ { int rc; struct svrattrl *psvrl; psvrl = (struct svrattrl *)GET_NEXT(preq->rq_ind.rq_jobobit.rq_attr); if ((rc = diswst(sock, preq->rq_ind.rq_jobobit.rq_jid) != 0) || (rc = diswsi(sock, preq->rq_ind.rq_jobobit.rq_status) != 0) || (rc = encode_DIS_svrattrl(sock, psvrl) != 0)) { /* FAILURE */ return(rc); } return(0); } /* END encode_DIS_JobObit() */
int encode_DIS_JobFile( struct tcp_chan *chan, int seq, char *buf, int len, const char *jobid, int which) { int rc; if (jobid == (char *)0) jobid = (char *)""; if ((rc = diswui(chan, seq) != 0) || (rc = diswui(chan, which) != 0) || (rc = diswui(chan, len) != 0) || (rc = diswst(chan, jobid) != 0) || (rc = diswcs(chan, buf, len) != 0)) return rc; return 0; }
/** * @brief * -encode a Copy Files Dependency Batch Request * * @param[in] sock - socket descriptor * @param[in] preq - pointer to batch_request * * @return int * @retval 0 success * @retval !0 error * */ int encode_DIS_CopyFiles(int sock, struct batch_request *preq) { int pair_ct = 0; char *nullstr = ""; struct rqfpair *ppair; int rc; ppair = (struct rqfpair *)GET_NEXT(preq->rq_ind.rq_cpyfile.rq_pair); while (ppair) { ++pair_ct; ppair = (struct rqfpair *)GET_NEXT(ppair->fp_link); } if ((rc = diswst(sock, preq->rq_ind.rq_cpyfile.rq_jobid) != 0) || (rc = diswst(sock, preq->rq_ind.rq_cpyfile.rq_owner) != 0) || (rc = diswst(sock, preq->rq_ind.rq_cpyfile.rq_user) != 0) || (rc = diswst(sock, preq->rq_ind.rq_cpyfile.rq_group) != 0) || (rc = diswui(sock, preq->rq_ind.rq_cpyfile.rq_dir) != 0)) return rc; if ((rc = diswui(sock, pair_ct) != 0)) return rc; ppair = (struct rqfpair *)GET_NEXT(preq->rq_ind.rq_cpyfile.rq_pair); while (ppair) { if (ppair->fp_rmt == NULL) ppair->fp_rmt = nullstr; if ((rc = diswui(sock, ppair->fp_flag) != 0) || (rc = diswst(sock, ppair->fp_local) != 0) || (rc = diswst(sock, ppair->fp_rmt) != 0)) return rc; ppair = (struct rqfpair *)GET_NEXT(ppair->fp_link); } return 0; }
int PBSD_munge_authenticate( int psock, /* I */ int handle) /* I */ { int rc; munge_ctx_t mctx = NULL; munge_err_t mret = EMUNGE_SNAFU; char *mcred = NULL; /* user id and name stuff */ struct passwd *pwent; uid_t myrealuid; struct batch_reply *reply; unsigned short user_port = 0; struct sockaddr_in sockname; socklen_t socknamelen = sizeof(sockname); struct tcp_chan *chan; if ((mctx = munge_ctx_create()) == NULL) { return(-1); } if ((mret = munge_encode (&mcred, mctx, NULL, 0)) != EMUNGE_SUCCESS) { const char *merrmsg = NULL; if (!(merrmsg = munge_ctx_strerror(mctx))) { merrmsg = munge_strerror(mret); } fprintf(stderr, "munge_encode failed: %s (%d)\n", merrmsg, mret); munge_ctx_destroy(mctx); return(PBSE_MUNGE_NOT_FOUND); /*TODO more fine-grained error codes? */ } munge_ctx_destroy(mctx); /* We got the certificate. Now make the PBS_BATCH_AltAuthenUser request */ myrealuid = getuid(); pwent = getpwuid(myrealuid); rc = getsockname(psock, (struct sockaddr *)&sockname, &socknamelen); if (rc == -1) { fprintf(stderr, "getsockname failed: %d\n", errno); return(-1); } user_port = ntohs(sockname.sin_port); if ((chan = DIS_tcp_setup(psock)) == NULL) { } else if ((rc = encode_DIS_ReqHdr(chan, PBS_BATCH_AltAuthenUser, pwent->pw_name)) || (rc = diswui(chan, user_port)) || (rc = diswst(chan, mcred)) || (rc = encode_DIS_ReqExtend(chan, NULL)) || (rc = DIS_tcp_wflush(chan))) { PBSD_munge_cred_destroy(&mcred); /* ERROR */ return(rc); } else { int local_err = PBSE_NONE; PBSD_munge_cred_destroy(&mcred); /* read the reply */ if ((reply = PBSD_rdrpy(&local_err, handle)) != NULL) free(reply); return(PBSE_NONE); } return(-1); }
int PBSD_munge_authenticate( int psock, /* I */ int handle) /* I */ { int rc = PBSE_NONE; int fd; FILE *munge_pipe; char munge_buf[MUNGE_SIZE]; char munge_command[MUNGE_SIZE]; char *ptr; /* pointer to the current place to copy data into munge_buf */ int bytes_read; int total_bytes_read = 0; int local_errno = 0; /* user id and name stuff */ struct passwd *pwent; uid_t myrealuid; struct batch_reply *reply; unsigned short user_port = 0; struct sockaddr_in sockname; socklen_t socknamelen = sizeof(sockname); struct tcp_chan *chan = NULL; snprintf(munge_command,sizeof(munge_command), "munge -n 2>/dev/null"); memset(munge_buf, 0, MUNGE_SIZE); ptr = munge_buf; if ((munge_pipe = popen(munge_command,"r")) == NULL) { /* FAILURE */ return(-1); } fd = fileno(munge_pipe); while ((bytes_read = read_ac_socket(fd, ptr, MUNGE_SIZE - total_bytes_read)) > 0) { total_bytes_read += bytes_read; ptr += bytes_read; } pclose(munge_pipe); if (bytes_read == -1) { /* read failed */ local_errno = errno; log_err(local_errno, __func__, "error reading pipe in PBSD_munge_authenticate"); return -1; } /* if we got no bytes back then Munge may not be installed etc. */ if (total_bytes_read == 0) { return(PBSE_MUNGE_NOT_FOUND); } /* We got the certificate. Now make the PBS_BATCH_AltAuthenUser request */ myrealuid = getuid(); pwent = getpwuid(myrealuid); rc = getsockname(psock, (struct sockaddr *)&sockname, &socknamelen); if (rc == -1) { fprintf(stderr, "getsockname failed: %d\n", errno); return rc; } user_port = ntohs(sockname.sin_port); if ((chan = DIS_tcp_setup(psock)) == NULL) { rc = PBSE_MEM_MALLOC; } else if ((rc = encode_DIS_ReqHdr(chan,PBS_BATCH_AltAuthenUser,pwent->pw_name)) || (rc = diswui(chan, user_port)) || (rc = diswst(chan, munge_buf)) || (rc = encode_DIS_ReqExtend(chan, NULL)) || (rc = DIS_tcp_wflush(chan))) { /* ERROR */ } else { /* read the reply */ if ((reply = PBSD_rdrpy(&local_errno, handle)) != NULL) free(reply); rc = PBSE_NONE; } if (chan != NULL) DIS_tcp_cleanup(chan); return rc; } /* END PBSD_munge_authenticate() */
int encode_DIS_reply( struct tcp_chan *chan, struct batch_reply *reply) { int ct; int i; struct brp_select *psel; struct brp_status *pstat; svrattrl *psvrl; int rc; /* first encode "header" consisting of protocol type and version */ if ((rc = diswui(chan, PBS_BATCH_PROT_TYPE)) || (rc = diswui(chan, PBS_BATCH_PROT_VER))) return rc; /* next encode code, auxcode and choice (union type identifier) */ if ((rc = diswsi(chan, reply->brp_code)) || (rc = diswsi(chan, reply->brp_auxcode)) || (rc = diswui(chan, reply->brp_choice))) return rc; switch (reply->brp_choice) { case BATCH_REPLY_CHOICE_NULL: break; /* no more to do */ case BATCH_REPLY_CHOICE_Queue: case BATCH_REPLY_CHOICE_RdytoCom: case BATCH_REPLY_CHOICE_Commit: if ((rc = diswst(chan, reply->brp_un.brp_jid))) return (rc); break; case BATCH_REPLY_CHOICE_Select: /* have to send count of number of strings first */ ct = 0; psel = reply->brp_un.brp_select; while (psel) { ++ct; psel = psel->brp_next; } if ((rc = diswui(chan, ct))) return rc; psel = reply->brp_un.brp_select; while (psel) { /* now encode each string */ if ((rc = diswst(chan, psel->brp_jobid))) return rc; psel = psel->brp_next; } break; case BATCH_REPLY_CHOICE_Status: /* encode "server version" of status structure. * * Server always uses svrattrl form. * Commands decode into their form. * * First need to encode number of status objects and then * the object itself. */ ct = 0; pstat = (struct brp_status *)GET_NEXT(reply->brp_un.brp_status); while (pstat) { ++ct; pstat = (struct brp_status *)GET_NEXT(pstat->brp_stlink); } if ((rc = diswui(chan, ct))) return rc; pstat = (struct brp_status *)GET_NEXT(reply->brp_un.brp_status); while (pstat) { if ((rc = diswui(chan, pstat->brp_objtype)) || (rc = diswst(chan, pstat->brp_objname))) return rc; psvrl = (svrattrl *)GET_NEXT(pstat->brp_attr); if ((rc = encode_DIS_svrattrl(chan, psvrl))) return rc; pstat = (struct brp_status *)GET_NEXT(pstat->brp_stlink); } break; case BATCH_REPLY_CHOICE_Text: /* text reply */ if ((rc = diswcs(chan, reply->brp_un.brp_txt.brp_str, reply->brp_un.brp_txt.brp_txtlen))) return rc; break; case BATCH_REPLY_CHOICE_Locate: /* Locate Job Reply */ if ((rc = diswst(chan, reply->brp_un.brp_locate))) return rc; break; case BATCH_REPLY_CHOICE_RescQuery: /* Query Resources Reply */ ct = reply->brp_un.brp_rescq.brq_number; if ((rc = diswui(chan, ct))) return rc; for (i = 0; (i < ct) && (rc == 0); ++i) { rc = diswui(chan, *(reply->brp_un.brp_rescq.brq_avail + i)); } if (rc) return rc; for (i = 0; (i < ct) && (rc == 0); ++i) { rc = diswui(chan, *(reply->brp_un.brp_rescq.brq_alloc + i)); } if (rc) return rc; for (i = 0; (i < ct) && (rc == 0); ++i) { rc = diswui(chan, *(reply->brp_un.brp_rescq.brq_resvd + i)); } if (rc) return rc; for (i = 0; (i < ct) && (rc == 0); ++i) { rc = diswui(chan, *(reply->brp_un.brp_rescq.brq_down + i)); } if (rc) return rc; break; default: return -1; } return 0; }
int encode_DIS_attrl( struct tcp_chan *chan, struct attrl *pattrl) { unsigned int ct = 0; unsigned int name_len; struct attrl *ps; int rc; /* count how many */ for (ps = pattrl;ps != NULL;ps = ps->next) { ++ct; } if ((rc = diswui(chan, ct))) { return(rc); } for (ps = pattrl;ps != NULL;ps = ps->next) { /* length of three strings */ name_len = 0; if (ps->name != NULL) { name_len += (int)strlen(ps->name) + 1; } if (ps->value != NULL) { name_len += (int)strlen(ps->value) + 1; } if (ps->resource != NULL) name_len += strlen(ps->resource) + 1; rc = diswui(chan, name_len); if (rc != 0) break; if (ps->name != NULL) rc = diswst(chan, ps->name); else rc = diswst(chan, ""); if (rc != 0) break; if (ps->resource != NULL) { /* has a resource name */ if ((rc = diswui(chan, 1)) != 0) break; if ((rc = diswst(chan, ps->resource)) != 0) break; } else { if ((rc = diswui(chan, 0)) != 0) /* no resource name */ break; } if ((rc = diswst( chan, (ps->value != NULL) ? ps->value : "")) || (rc = diswui(chan, (unsigned int)SET))) break; } /* END for (ps) */ return(rc); } /* END encode_DIS_attrl() */
int encode_DIS_attropl( int sock, struct attropl *pattropl) { unsigned int ct = 0; unsigned int name_len; struct attropl *ps; int rc; /* count how many */ for (ps = pattropl;ps;ps = ps->next) { ++ct; } if ((rc = diswui(sock, ct))) { return(rc); } for (ps = pattropl;ps;ps = ps->next) { /* length of three strings */ if (ps->name == NULL) { /* Continue if attribute has no name (CRI 2005-04-22). */ continue; } name_len = strlen(ps->name) + 1; if (ps->value != NULL) name_len += strlen(ps->value) + 1; if (ps->resource != NULL) name_len += strlen(ps->resource) + 1; if ((rc = diswui(sock, name_len))) break; if ((rc = diswst(sock, ps->name))) break; if (ps->resource != NULL) { /* has a resource name */ if ((rc = diswui(sock, 1))) break; if ((rc = diswst(sock, ps->resource))) break; } else { if ((rc = diswui(sock, 0))) /* no resource name */ break; } if (ps->value != NULL) { if ((rc = diswst(sock, ps->value)) || (rc = diswui(sock, (unsigned int)ps->op))) break; } else { if ((rc = diswst(sock, "")) || (rc = diswui(sock, (unsigned int)ps->op))) break; } } /* END for (ps) */ return(rc); } /* END encode_DIS_attropl() */