📄 stafprocess.cpp
字号:
// allocate memory for the environment table envp = new char* [envc + 1]; envstr = startData->environment; // initialize environment table while (*envstr) { envp[i++] = envstr; envstr += strlen(envstr) + 1; } envp[i] = 0; } // now argv and envp are ready, so lock the static variables and let // the processMonitorThread know that we are ready to start a process STAFMutexSemLock lock(sCreateProcessSem); STAFRC_t rc = kSTAFOk; STAFProcessEndCallbackLevel1 dummyCallback = { 0 }; sProcessCreateInfo = ProcessCreateInfo( startData->commandType, command.toCurrentCodePage(), argv, envp, usrID, grpID, STAFString(startData->username).toCurrentCodePage(), STAFString(startData->workdir).toCurrentCodePage(), startData->stdinMode, child_stdin, startData->stdoutMode, child_stdout, startData->stderrMode, child_stderr, (startData->callback != 0) ? *startData->callback : dummyCallback); // we have a process we want to start so let process thread know sProcessThread.post(); // wait until process has been created so that we can pick pid sProcessCreated.wait(); sProcessCreated.reset(); if (pid) *pid = sProcessCreateInfo.pid; if (procHandle) *procHandle = sProcessCreateInfo.pid; if (sProcessCreateInfo.pid == -1) { rc = kSTAFBaseOSError; if (errorBuffer) { STAFString errMsg = STAFString("Error starting the process."); *errorBuffer = errMsg.adoptImpl(); } } // recurse over arg vector and clean up for (unsigned int j = 0; j < argc; j++) delete[] argv[j]; delete[] argv; delete[] envp; return rc;}STAFRC_t STAFProcessStop(STAFProcessID_t pid, STAFProcessStopMethod_t stopMethod, unsigned int *osRC){ STAFMutexSemLock lock(sMonitorDataSem); ProcessMonitorInfo processMonitorInfo; ProcessMonitorMap::iterator iter = sMonitorMap.find(pid); if (iter != sMonitorMap.end()) { // if found, then send a signal int theSignal = 0; if (stopMethod == kSTAFProcessStopWithSigKillAll) theSignal = SIGKILL; else if (stopMethod == kSTAFProcessStopWithSigKill) theSignal = SIGKILL; else if (stopMethod == kSTAFProcessStopWithSigTerm) theSignal = SIGTERM; else if (stopMethod == kSTAFProcessStopWithSigInt) theSignal = SIGINT; else return kSTAFUnknownError; if (kill((stopMethod == kSTAFProcessStopWithSigKillAll) ? -pid : pid, theSignal) == -1) { // error sending the signal to the process(es) if (osRC) *osRC = errno; return kSTAFBaseOSError; } } else { // process did not exist return kSTAFHandleDoesNotExist; } return kSTAFOk;}STAFRC_t STAFProcessIsValidAuthMode(STAFProcessAuthenticationMode_t authMode){ if ((authMode != kSTAFProcessAuthDisabled) && (authMode != kSTAFProcessAuthNone)) return kSTAFInvalidValue; else return kSTAFOk;}STAFRC_t STAFProcessIsValidStopMethod(STAFProcessStopMethod_t stopMethod){ if (stopMethod == kSTAFProcessStopWithWM_CLOSE) return kSTAFInvalidValue; else return kSTAFOk;}STAFRC_t STAFProcessRegisterEndCallback(STAFProcessID_t pid, STAFProcessHandle_t procHandle, void *genericCallback, unsigned int callbackLevel){ // NOTE: Registered processes will always return a fake rc of 0 if (genericCallback == 0) return kSTAFInvalidValue; if (callbackLevel != 1) return kSTAFInvalidValue; STAFMutexSemLock lock(sMonitorDataSem); STAFProcessEndCallbackLevel1 *callback = reinterpret_cast<STAFProcessEndCallbackLevel1 *>(genericCallback); sMonitorMap[pid].push_back(ProcessMonitorInfo(procHandle, pid, *callback)); // Needed here too in case "outsider" processes are run before any // "insider" processes are run InitProcessManager(); return kSTAFOk;}STAFRC_t STAFProcessGetHandleFromID(STAFProcessID_t processID, STAFProcessHandle_t *procHandle, unsigned int *osRC){ if (procHandle == 0) return kSTAFInvalidValue; *procHandle = processID; return kSTAFOk;}STAFRC_t STAFProcessIsRunning(STAFProcessHandle_t processHandle, unsigned int *isRunning, unsigned int *osRC){ if (isRunning == 0) return kSTAFInvalidValue; if (kill(processHandle, 0) != -1) *isRunning = 1; else *isRunning = 0; return kSTAFOk;}int ParseCommandParms(STAFString &command, char ***argv){ static STAFString dquote = STAFString(kUTF8_DQUOTE); static STAFString bslash = STAFString(kUTF8_BSLASH); static STAFString space = STAFString(kUTF8_SPACE); STAFString currChar, nextArg; // we actually allocate words (which may not match the number // of real args, but should guarantee enough slots in the array) int words = command.numWords(); *argv = new char *[words + 1]; memset(*argv, 0, sizeof(char *) * (words + 1)); int i = 0, j = 0; int inQuotes = 0; int inEscape = 0; int argReady = 0; for (i = 0; i < command.length(STAFString::kChar); ++i) { currChar = command.subString(i, 1, STAFString::kChar); if ((currChar == space) && !inEscape && !inQuotes) { if (argReady) { argReady = 0; STAFStringBufferPtr nextArgInCurrCP = nextArg.toCurrentCodePage(); unsigned int nextArgInCurrCPLen = nextArgInCurrCP->length(); (*argv)[j] = new char[nextArgInCurrCPLen + 1]; strcpy((*argv)[j++], nextArgInCurrCP->buffer()); nextArg = ""; } continue; } else if ((currChar == dquote) && !inEscape) { inQuotes = !inQuotes; continue; } else if ((currChar == bslash) && !inEscape) { inEscape = 1; continue; } else { inEscape = 0; argReady = 1; nextArg += currChar; } } if (argReady) { STAFStringBufferPtr nextArgInCurrCP = nextArg.toCurrentCodePage(); unsigned int nextArgInCurrCPLen = nextArgInCurrCP->length(); (*argv)[j] = new char[nextArgInCurrCPLen + 1]; strcpy((*argv)[j++], nextArgInCurrCP->buffer()); } // return the number of allocated slots in argv return j;}unsigned int UserAuthenticate(STAFUserID_t &uid, STAFGroupID_t &gid, const STAFString &username, const STAFString &password, bool mustValidate, unsigned int *osRC){ // Note: if username has not been specified (neither in the request // nor as a default) then we simply take no action at all if (username.length() == 0 || mustValidate == false) return 1; char realUsername[256] = { 0 }; char realPassword[256] = { 0 }; STAFStringBufferPtr realUsernameInCurrCP = username.toCurrentCodePage(); STAFStringBufferPtr realPasswordInCurrCP = password.toCurrentCodePage(); strcpy(realUsername, realUsernameInCurrCP->buffer()); strcpy(realPassword, realPasswordInCurrCP->buffer()); // Note: we already handled the case where username is empty (above) struct passwd *n = 0; if (username.isDigits()) { // if username is uid, resolve & convert ... n = getpwuid(uid = username.asUInt()); // XXX: This was the old way // if (n) username = n->pw_name; // but, I think this is actually correct if (n) strcpy(realUsername, n->pw_name); } else { // ... otherwise, get username and set uid n = getpwnam(realUsername); if (n) uid = n->pw_uid; } if (n == NULL) { return 0; } gid = n->pw_gid; return (*sAuthenticateFuncPtr)(realUsername, realPassword);}unsigned int sAuthNone(const char *user, const char *pswd){ return 1;}////////////////////////////////////////////////////////////////////////////////#ifdef STAF_PAM_AVAILABLE#include <security/pam_appl.h>#include <security/pam_misc.h>static struct pam_conv conv = { misc_conv, NULL };#endif // STAF_PAM_AVAILABLEunsigned int sAuthPam(const char *user, const char *pswd){#ifdef STAF_PAM_AVAILABLE // DOCUMENTATION FOUND AT: // http://www.us.kernel.org/pub/linux/libs/pam/Linux-PAM-html/ // pam_appl.html // Add the following lines to /etc/pam.conf // STAFProc auth required /lib/security/pam_unix_auth.so // STAFProc account required /lib/security/pam_unix_acct.so int rc = PAM_SUCCESS; pam_handle_t *pamh = NULL; const char *serviceName = "STAFProc"; rc = pam_start(serviceName, user, &conv, &pamh); if (rc == PAM_SUCCESS) { // is user really user? rc = pam_authenticate(pamh, 0); } if (rc == PAM_SUCCESS) { // permitted access? rc = pam_acct_mgmt(pamh, 0); } // This is where we have been authorized or not. if (rc == PAM_SUCCESS) { if (pam_end(pamh, rc) != PAM_SUCCESS) { STAFTrace::trace( kSTAFTraceError, serviceName + ": Failed to release authenticator"); } return 1; }#endif // STAF_PAM_AVAILABLE return 0;}////////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -