int UIProcessCommand( msocket_t *S) /* I */ { char SBuffer[MAX_SBUFFER]; char Message[MAX_MLINE]; int HeadSize; int index; int sindex; int FLAGS; int hostcheck; char ServiceType[MAX_MLINE]; char Auth[MAX_MNAME]; char Passwd[MAX_MNAME]; int scode; int Align; char *ptr; char *ptr2; char *args; char *TokPtr; int rc; long tmpL; char tmpLine[MMAX_LINE]; const char *FName = "UIProcessCommand"; DBG(3,fUI) DPrint("%s(S)\n", FName); if (S == NULL) { return(FAILURE); } if (MSURecvData(S,MAX_SOCKETWAIT,TRUE,NULL,NULL) == FAILURE) { DBG(3,fSOCK) DPrint("ALERT: cannot read client packet\n"); return(FAILURE); } switch(S->WireProtocol) { case mwpXML: rc = MUISProcessRequest(S,Message); return(rc); /*NOTREACHED*/ break; default: break; } /* END switch(S->WireProtocol) */ memset(SBuffer,0,sizeof(SBuffer)); S->SBuffer = SBuffer; strcpy(CurrentHostName,S->Host); /* NOTE: not very threadsafe :) */ if ((X.XUIHandler != (int (*)())0) && ((*X.XUIHandler)(X.xd,S,MSched.DefaultCSKey,0) == SUCCESS)) { /* service handled externally */ return(SUCCESS); } if (MUISProcessRequest(S,Message) == SUCCESS) { /* new style client request received and processed */ return(SUCCESS); } /* locate/process args */ if ((args = strstr(S->RBuffer,MCKeyword[mckArgs])) == NULL) { DBG(3,fSOCK) DPrint("ALERT: cannot locate command arg\n"); sprintf(S->SBuffer,"%s%d %s%s\n", MCKeyword[mckStatusCode], scFAILURE, MCKeyword[mckArgs], "ERROR: cannot locate command args"); S->SBufSize = strlen(S->SBuffer); MSUSendData(S,MAX_SOCKETWAIT,TRUE,TRUE); return(FAILURE); } *args = '\0'; args += strlen(MCKeyword[mckArgs]); /* get service */ ServiceType[0] = '\0'; if ((ptr = strstr(S->RBuffer,MCKeyword[mckCommand])) == NULL) { DBG(3,fSOCK) DPrint("ALERT: cannot locate command\n"); sprintf(S->SBuffer,"%s%d %s%s\n", MCKeyword[mckStatusCode], scFAILURE, MCKeyword[mckArgs], "ERROR: cannot locate command"); S->SBufSize = strlen(S->SBuffer); MSUSendData(S,MAX_SOCKETWAIT,TRUE,TRUE); return(FAILURE); } ptr += strlen(MCKeyword[mckCommand]); MUStrCpy(ServiceType,ptr,sizeof(ServiceType)); for (ptr2 = &ServiceType[0];*ptr2 != '\0';ptr2++) { if (isspace(*ptr2)) { *ptr2 = '\0'; break; } } /* END for (ptr2) */ /* get authentication */ if ((ptr = strstr(S->RBuffer,MCKeyword[mckAuth])) == NULL) { DBG(3,fSOCK) DPrint("ALERT: cannot locate authentication\n"); sprintf(S->SBuffer,"%s%d %s%s\n", MCKeyword[mckStatusCode], scFAILURE, MCKeyword[mckArgs], "ERROR: cannot locate authentication"); S->SBufSize = (long)strlen(S->SBuffer); MSUSendData(S,MAX_SOCKETWAIT,TRUE,TRUE); return(FAILURE); } ptr += strlen(MCKeyword[mckAuth]); MUStrCpy(Auth,ptr,sizeof(Auth)); /* FORMAT: <USERNAME>[:<PASSWORD>] */ for (ptr2 = &Auth[0];*ptr2 != '\0';ptr2++) { if (isspace(*ptr2)) { *ptr2 = '\0'; break; } } if ((ptr2 = MUStrTok(Auth,":",&TokPtr)) != NULL) { MUStrCpy(Passwd,ptr2,sizeof(Passwd)); } else { Passwd[0] = '\0'; } /* determine service */ if ((sindex = MUGetIndex(ServiceType,MService,0,0)) == 0) { DBG(3,fUI) DPrint("INFO: service '%s' not handled in %s\n", ServiceType, FName); sprintf(Message,"ERROR: cannot support service '%s'", ServiceType); sprintf(S->SBuffer,"%s%d %s%s\n", MCKeyword[mckStatusCode], scFAILURE, MCKeyword[mckArgs], Message); S->SBufSize = (long)strlen(S->SBuffer); MSUSendData(S,MAX_SOCKETWAIT,TRUE,TRUE); return(FAILURE); } DBG(3,fUI) DPrint("INFO: client '%s' read (%ld bytes) initiating service call for '%s' (Auth: %s)\n", S->Name, S->SBufSize, MService[sindex], Auth); /* fail if name is not recognized */ if (Auth[0] == '\0') { DBG(2,fUI) DPrint("WARNING: client id '%s' is unknown\n", Auth); sprintf(S->SBuffer,"%s%d %s%s\n", MCKeyword[mckStatusCode], scFAILURE, MCKeyword[mckArgs], "ERROR: cannot authenticate client"); S->SBufSize = (long)strlen(S->SBuffer); MSUSendData(S,MAX_SOCKETWAIT,TRUE,TRUE); return(FAILURE); } ServerGetAuth(Auth,&tmpL); FLAGS = (int)tmpL; switch(sindex) { /* admin1 functions */ case svcResetStats: case svcSched: case svcSetJobDeadline: case svcReleaseJobDeadline: case svcChangeParameter: case svcMigrateJob: case svcBNFQuery: case svcMGridCtl: case svcMJobCtl: case svcMNodeCtl: if (!(FLAGS & (1 << fAdmin1))) { sprintf(Message,"ERROR: user '%s' is not authorized to run command '%s'\n", Auth, MService[sindex]); sprintf(S->SBuffer,"%s%d %s%s\n", MCKeyword[mckStatusCode], scFAILURE, MCKeyword[mckArgs], Message); S->SBufSize = (long)strlen(SBuffer); MSUSendData(S,MAX_SOCKETWAIT,TRUE,TRUE); return(FAILURE); /*NOTREACHED*/ break; } hostcheck = FALSE; for (index = 0;index < MAX_MADMINHOSTS;index++) { if (MSched.AdminHost[index][0] == '\0') break; if (!strcasecmp(MSched.AdminHost[index],S->Host)) { hostcheck = TRUE; break; } if (!strcasecmp(MSched.AdminHost[index],"ALL")) { hostcheck = TRUE; break; } } /* END for (index) */ if (hostcheck == FALSE) { sprintf(Message,"ERROR: command '%s' cannot be executed from host '%s'\n", MService[sindex], S->Host); sprintf(S->SBuffer,"%s%d %s%s\n", MCKeyword[mckStatusCode], scFAILURE, MCKeyword[mckArgs], Message); S->SBufSize = (long)strlen(SBuffer); MSUSendData(S,MAX_SOCKETWAIT,TRUE,TRUE); return(FAILURE); /*NOTREACHED*/ break; } /* admin1 or admin2 function */ case svcSetJobSystemPrio: case svcRunJob: if (!(FLAGS & ((1 << fAdmin1) | (1 << fAdmin2)))) { sprintf(Message,"ERROR: user '%s' is not authorized to execute command '%s'\n", Auth, MService[sindex]); sprintf(S->SBuffer,"%s%d %s%s\n", MCKeyword[mckStatusCode], scFAILURE, MCKeyword[mckArgs], Message); S->SBufSize = (long)strlen(SBuffer); MSUSendData(S,MAX_SOCKETWAIT,TRUE,TRUE); return(FAILURE); /*NOTREACHED*/ break; } /* admin1, admin2, or admin3 functions */ case svcShowStats: case svcDiagnose: case svcShowJobDeadline: case svcShowConfig: case svcNodeShow: case svcShowEstimatedStartTime: case svcShowGrid: case svcClusterShow: if (!(FLAGS & ((1 << fAdmin1) | (1 << fAdmin2) | (1 << fAdmin3)))) { sprintf(Message,"ERROR: user '%s' is not authorized to execute command '%s'\n", Auth, MService[sindex]); sprintf(S->SBuffer,"%s%d %s%s\n", MCKeyword[mckStatusCode], scFAILURE, MCKeyword[mckArgs], Message); S->SBufSize = (long)strlen(SBuffer); MSUSendData(S,MAX_SOCKETWAIT,TRUE,TRUE); return(FAILURE); /*NOTREACHED*/ break; } /* global functions or case specific functions */ case svcResCreate: case svcResShow: case svcSetJobQOS: case svcCancelJob: case svcSetJobUserPrio: case svcJobShow: case svcShowQ: case svcSetJobHold: case svcReleaseJobHold: case svcResDestroy: case svcShowJobHold: case svcShowEarliestDeadline: case svcShowBackfillWindow: case svcMBal: if (sindex == svcMGridCtl) strcpy(Auth,S->Name); S->SBufSize = (long)sizeof(SBuffer); sprintf(tmpLine,"%s%d ", MCKeyword[mckStatusCode], scFAILURE); Align = (int)strlen(tmpLine) + (int)strlen(MCKeyword[mckArgs]); sprintf(S->SBuffer,"%s%*s%s", tmpLine, 16 - (Align % 16), " ", MCKeyword[mckArgs]); HeadSize = (int)strlen(SBuffer); S->SBufSize -= HeadSize + 1; if (Function[sindex] != NULL) scode = (*Function[sindex])(args,S->SBuffer + HeadSize,FLAGS,Auth,&S->SBufSize); else scode = FAILURE; ptr = S->SBuffer + strlen(MCKeyword[mckStatusCode]); *ptr = scode + '0'; S->SBufSize = (long)strlen(S->SBuffer); MSUSendData(S,MAX_SOCKETWAIT,TRUE,TRUE); break; default: DBG(2,fUI) DPrint("WARNING: unexpected service (%d) requested (ignoring request)\n", sindex); sprintf(Message,"ERROR: service '%s' (%d) not implemented\n", ServiceType, sindex); sprintf(S->SBuffer,"%s%d %s%s\n", MCKeyword[mckStatusCode], scFAILURE, MCKeyword[mckArgs], Message); S->SBufSize = (long)strlen(S->SBuffer); MSUSendData(S,MAX_SOCKETWAIT,TRUE,TRUE); break; } /* END switch(sindex) */ fflush(mlog.logfp); return(SUCCESS); } /* END UIProcessCommand() */
int MSysProcessRequest( msocket_t *S, /* I */ mbool_t RequestIsPreLoaded) /* I */ { char Message[MMAX_LINE]; int HeadSize; int sindex; /* enum MSvcEnum */ mbitmap_t AuthBM; char SName[MMAX_LINE]; char Auth[MMAX_NAME]; char Passwd[MMAX_NAME]; char tmpLine[MMAX_LINE]; int SC; int Align; char *ptr; char *ptr2; char *args; char *TokPtr; int rc; const char *FName = "MSysProcessRequest"; MDB(3,fUI) MLog("%s(S,%s)\n", FName, MBool[RequestIsPreLoaded]); if (S == NULL) { return(FAILURE); } if ((MGlobalReqBuf == NULL) && (MSUAllocSBuf( &MGlobalReqBuf, MSched.M[mxoJob], MPar[0].ConfigNodes, &MGlobalReqBufSize, FALSE) == FAILURE)) { MDB(1,fUI) MLog("ERROR: cannot allocate request buffer\n"); return(FAILURE); } else if (MIncrGlobalReqBuf == TRUE) { if (MSUAllocSBuf( &MGlobalReqBuf, 0, 0, &MGlobalReqBufSize, TRUE) == FAILURE) { MDB(1,fUI) MLog("ERROR: cannot allocate increase request buffer\n"); return(FAILURE); } MIncrGlobalReqBuf = FALSE; } if (RequestIsPreLoaded == FALSE) { char EMsg[MMAX_LINE]; enum MStatusCodeEnum SC; if (MSURecvData(S,MSched.SocketWaitTime,TRUE,&SC,EMsg) == FAILURE) { MDB(3,fSOCK) MLog("ALERT: cannot read client packet\n"); MUStrDup(&MSched.UIBadRequestMsg,EMsg); if (S->RemoteHost != NULL) MUStrDup(&MSched.UIBadRequestor,S->RemoteHost); else MUStrDup(&MSched.UIBadRequestor,"???"); if (MSched.DefaultDropBadRequest == FALSE) { MUStrDup(&S->SMsg,EMsg); if (SC == mscNoAuth) S->StatusCode = (long)msfESecServerAuth; else S->StatusCode = (long)msfEGServer; MSUSendData(S,MSched.SocketWaitTime,TRUE,TRUE,NULL,NULL); } MSUDisconnect(S); return(FAILURE); } /* END if (MSURecvData(S,MMAX_SOCKETWAIT,TRUE,&SC,EMsg) == FAILURE) */ } /* END if (RequestIsPreLoaded == FALSE) */ S->SBuffer = MGlobalReqBuf; S->SBufSize = MGlobalReqBufSize; if (S->ProcessTime == 0) MUGetMS(NULL,(long *)&S->ProcessTime); switch (S->WireProtocol) { case mwpXML: case mwpS32: { int SC; /* new style request - process and return */ rc = MUISProcessRequest(S,Message,&SC); if (rc == FAILURE) { if (SC != mscNoEnt) MUISAddData(S,"ERROR: command not supported"); MSUSendData(S,MSched.SocketWaitTime,TRUE,TRUE,NULL,NULL); } return(rc); } /* END BLOCK */ /*NOTREACHED*/ break; default: /* NO-OP */ break; } /* END switch (S->WireProtocol) */ /* old style request - process below */ MGlobalReqBuf[0] = '\0'; S->SBuffer = MGlobalReqBuf; S->SBufSize = MGlobalReqBufSize; MUStrCpy(CurrentHostName,S->Host,MMAX_NAME); /* NOTE: not threadsafe */ /* locate/process args */ if ((args = strstr(S->RBuffer,MCKeyword[mckArgs])) == NULL) { MDB(3,fSOCK) MLog("ALERT: cannot locate command arg\n"); sprintf(S->SBuffer,"%s%d %s%s\n", MCKeyword[mckStatusCode], scFAILURE, MCKeyword[mckArgs], "ERROR: cannot locate command args"); S->SBufSize = strlen(S->SBuffer); MSUSendData(S,MSched.SocketWaitTime,TRUE,TRUE,NULL,NULL); return(FAILURE); } *args = '\0'; args += strlen(MCKeyword[mckArgs]); /* get service */ SName[0] = '\0'; if ((ptr = strstr(S->RBuffer,MCKeyword[mckCommand])) == NULL) { MDB(3,fSOCK) MLog("ALERT: cannot locate command\n"); sprintf(S->SBuffer,"%s%d %s%s\n", MCKeyword[mckStatusCode], scFAILURE, MCKeyword[mckArgs], "ERROR: cannot locate command"); S->SBufSize = strlen(S->SBuffer); MSUSendData(S,MSched.SocketWaitTime,TRUE,TRUE,NULL,NULL); return(FAILURE); } ptr += strlen(MCKeyword[mckCommand]); MUStrCpy(SName,ptr,sizeof(SName)); for (ptr2 = &SName[0];*ptr2 != '\0';ptr2++) { if (isspace(*ptr2)) { *ptr2 = '\0'; break; } } /* END for (ptr2) */ /* get authentication */ if ((ptr = strstr(S->RBuffer,MCKeyword[mckAuth])) == NULL) { MDB(3,fSOCK) MLog("ALERT: cannot locate authentication\n"); sprintf(S->SBuffer,"%s%d %s%s\n", MCKeyword[mckStatusCode], scFAILURE, MCKeyword[mckArgs], "ERROR: cannot locate authentication"); S->SBufSize = (long)strlen(S->SBuffer); MSUSendData(S,MSched.SocketWaitTime,TRUE,TRUE,NULL,NULL); return(FAILURE); } ptr += strlen(MCKeyword[mckAuth]); MUStrCpy(Auth,ptr,sizeof(Auth)); /* FORMAT: <USERNAME>[:<PASSWORD>] */ for (ptr2 = &Auth[0];*ptr2 != '\0';ptr2++) { if (isspace(*ptr2)) { *ptr2 = '\0'; break; } } /* END for (ptr2) */ if ((ptr2 = MUStrTok(Auth,":",&TokPtr)) != NULL) { MUStrCpy(Passwd,ptr2,sizeof(Passwd)); } else { Passwd[0] = '\0'; } /* determine service */ for (sindex = 1;MUI[sindex].SName != NULL;sindex++) { if (!strcmp(SName,MUI[sindex].SName)) break; } /* END for (sindex) */ if ((MUI[sindex].SName == NULL) || (MUI[sindex].Func == NULL)) { MDB(3,fUI) MLog("ALERT: cannot support service '%s'\n", SName); sprintf(Message,"ERROR: cannot support service '%s' (%s)", SName, (MUI[sindex].SName == NULL) ? "service" : "func"); sprintf(S->SBuffer,"%s%d %s%s\n", MCKeyword[mckStatusCode], scFAILURE, MCKeyword[mckArgs], Message); S->SBufSize = (long)strlen(S->SBuffer); MSUSendData(S,MSched.SocketWaitTime,TRUE,TRUE,NULL,NULL); return(FAILURE); } /* END if (MUI[sindex].SName == NULL) */ if (S->SIndex == mcsNONE) S->SIndex = (enum MSvcEnum)sindex; MDB(3,fUI) MLog("INFO: client '%s' read (%ld bytes) initiating service call for '%s' (Auth: %s)\n", S->Name, S->SBufSize, MUI[sindex].SName, Auth); /* fail if name is not recognized */ if (Auth[0] == '\0') { MDB(2,fUI) MLog("WARNING: client id '%s' is unknown\n", Auth); sprintf(S->SBuffer,"%s%d %s%s\n", MCKeyword[mckStatusCode], scFAILURE, MCKeyword[mckArgs], "ERROR: cannot authenticate client"); S->SBufSize = (long)strlen(S->SBuffer); MSUSendData(S,MSched.SocketWaitTime,TRUE,TRUE,NULL,NULL); return(FAILURE); } MSysGetAuth(Auth,(enum MSvcEnum)sindex,0,&AuthBM); if (!bmisset(&AuthBM,mcalOwner) && !bmisset(&AuthBM,mcalGranted)) { sprintf(Message,"ERROR: user '%s' is not authorized to run command '%s'\n", Auth, MUI[sindex].SName); sprintf(S->SBuffer,"%s%d %s%s\n", MCKeyword[mckStatusCode], scFAILURE, MCKeyword[mckArgs], Message); S->SBufSize = (long)strlen(S->SBuffer); MSUSendData(S,MSched.SocketWaitTime,TRUE,TRUE,NULL,NULL); return(FAILURE); } S->SBufSize = (long)MGlobalReqBufSize; sprintf(tmpLine,"%s%d ", MCKeyword[mckStatusCode], scFAILURE); Align = (int)strlen(tmpLine) + (int)strlen(MCKeyword[mckArgs]); sprintf(S->SBuffer,"%s%*s%s", tmpLine, 16 - (Align % 16), " ", MCKeyword[mckArgs]); HeadSize = (int)strlen(S->SBuffer); S->SBufSize -= HeadSize; SC = (*MUI[sindex].Func)( args, S->SBuffer + HeadSize, &AuthBM, Auth, &S->SBufSize); ptr = S->SBuffer + strlen(MCKeyword[mckStatusCode]); *ptr = SC + '0'; if (S->SBufSize != MGlobalReqBufSize) S->SBufSize += (long)HeadSize; else S->SBufSize = (long)strlen(S->SBuffer); MSUSendData(S,MSched.SocketWaitTime,TRUE,TRUE,NULL,NULL); fflush(mlog.logfp); /* mrelAllSchedCommand --- Record all commands. * mrelSchedCommand --- Record only commands that perform an action. */ if (bmisset(&MSched.RecordEventList,mrelAllSchedCommand)) { MSysRecordCommandEvent(S,(enum MSvcEnum)sindex,SC,Auth); } else if (bmisset(&MSched.RecordEventList,mrelSchedCommand)) { switch (sindex) { /* info only commands, do not record event under only mrelSchedCommand */ case mcsShowQueue: case mcsShowState: case mcsStatShow: case mcsCheckJob: case mcsRsvShow: case mcsCheckNode: case mcsShowResAvail: case mcsShowEstimatedStartTime: case mcsShowConfig: case mcsMShow: case mcsMDiagnose: break; /* info/action commands, do not ALWAYS record event here. * Instrument these functions intenally to determine whether to record * command events */ case mcsMJobCtl: case mcsMRsvCtl: case mcsMSchedCtl: case mcsMVCCtl: case mcsMVMCtl: if (bmisset(&S->Flags,msftReadOnlyCommand)) { break; } /* else fall though... */ default: MSysRecordCommandEvent(S,(enum MSvcEnum)sindex,SC,Auth); break; } /* END switch (sindex) */ } /* END if (bmisset(&MSched.RecordEventList,mrelSchedCommand)) */ return(SUCCESS); } /* END MSysProcessRequest() */