void Id_SetSuperUser(Bool yes) // IN: TRUE to acquire super user, FALSE to release { if (!IsSuperUser() == !yes) { // settid(2) fails on spurious transitions. return; } if (yes) { syscall(SYS_settid, KAUTH_UID_NONE, KAUTH_GID_NONE /* Ignored. */); } else { if (syscall(SYS_settid, getuid(), getgid()) == -1) { Log("Failed to release super user privileges.\n"); } } }
/*********************************************************************** * Function Name : tokenParser * Description : parse the token and process it * comparing possibly non-NULL strings. * Input : @pCli, cli control structure * @pTbl, token table * Output : * Return value : CLI_PARSE_OK, parse token success * CLI_PARSE_ERROR, parse token failure * CLI_PARSE_NO_TBL, no token table valid * CLI_PARSE_NO_VALUE,no parameter in token * CLI_PARSE_TOO_FEW, not enough items in token * CLI_PARSE_TOO_MANY, items of token is more than it have to * CLI_PARSE_UNKNOWN, do not match any token in the token table * CLI_PARSE_INPUT_ERROR, withdraw charactor error form input * CLI_PARSE_INVALID_PARAMETER, parameter from item is invalide * CLI_PARSE_MULTI_MATCHES, inputed token matchs more than one token in the token table * CLI_PARSE_QUIT, parse terminate unexpected * CLI_PARSE_NOMESSAGE, no message parse from token ***********************************************************************/ LOCAL int tokenParser(CLI * pCli, struct parse_token_s *pTbl) { char *p; char *pFilter; int rc = 0; CLIDEBUG(("tokenParser\n")); pCli->tokenLvl++; pCli->ParseTbl[pCli->parseTblIdx++] = pTbl; p = tokenPopWoCase(pCli); if (p) { struct parse_token_s *pTblx; int len = strlen(p); int k, match; for (pTblx = pTbl; pTblx->fHandler; pTblx++) { pTblx->abbrevMatchCnt = 0; } CLIDEBUG(("p: %s, len: %d\n", p, strlen(p))); pFilter = p; match = 0; for (pTblx = pTbl; pTblx->fHandler; pTblx++) { if (len == strlen(pTblx->pCmd) && tokenIsValidOpMode(pCli, pTblx) == TRUE && tokencmp(p, pTblx->pCmd, len) == 0) { CLIDEBUG(("Exact match found\n")); match = 1; /* exact match */ pTblx->abbrevMatchCnt = len; break; } } if (match == 0) { for (k = 0; k < len; k++) { for (pTblx = pTbl; pTblx->fHandler; pTblx++) { /* Don't let priv and hidden tokens out of the bag */ if (pCli->securityCheck && tokenIsProtected(pTblx) == TRUE && IsSuperUser() == FALSE) { continue; } if (tokenIsHidden(pTblx) || tokenIsValidOpMode(pCli, pTblx) == FALSE) { continue; } if (*(p + k) && *(pTblx->pCmd + k)) { if (*(p + k) == *(pTblx->pCmd + k)) { if (k == 0) { match++; } if (k == pTblx->abbrevMatchCnt) { pTblx->abbrevMatchCnt++; CLIDEBUG(("%s -- abbrevMatch: %d\n", pTblx->pCmd, pTblx->abbrevMatchCnt)); } } } } } } CLIDEBUG(("%d match found, filter: %s\n", match, pFilter)); if (match == 1) { match = 0; pFilter = p; len = strlen(p); for (pTblx = pTbl; pTblx->fHandler; pTblx++) { if (pTblx->abbrevMatchCnt) { if (len <= strlen(pTblx->pCmd)) { if (tokencmp(p, pTblx->pCmd, len) == 0) { if (!pCli->securityCheck || IsSuperUser() == TRUE || tokenIsProtected(pTblx) == FALSE) { //Deleted by Mario Huang, it seems useless //tokenCurTblSet(pTblx); rc = (*pTblx->fHandler) (pCli, p, pTblx->pNxtParseTbl); if (rc == CLI_PARSE_NO_VALUE || rc == CLI_PARSE_UNKNOWN || rc == CLI_PARSE_INVALID_PARAMETER) { if (rc == CLI_PARSE_INVALID_PARAMETER) { helpCmdScan(pCli, pCli->ParseTbl[pCli-> parseTblIdx - 1], "", NULL, 1); } else { if (rc == CLI_PARSE_UNKNOWN) { helpCmdScan(pCli, pCli->ParseTbl[pCli-> parseTblIdx - 1], pTblx->pCmd, pFilter, 1); } else { helpCmdScan(pCli, pTblx->pNxtParseTbl, pTblx->pCmd, NULL, 1); } } rc = (rc == CLI_PARSE_NO_VALUE) ? CLI_PARSE_TOO_FEW : CLI_PARSE_ERROR; } /* Count the related setting functions have been done successfully, * so as to do associated applying action while excute apply cmd. * add by Tony 2007.9.30 */ else if (rc == CLI_PARSE_OK) { if (pTblx->pApplyActionTbl) pTblx->pApplyActionTbl->settingCnt++; } return rc; } match = 1; } CLIDEBUG(("tokenParser -- %s can't match with table item %s, pTbl: %p\n", p, pTblx->pCmd, (void *) pTblx)); } } } } else if (match != 0) { /* * Multiple matches found. Find the one with the highest match */ int cnt; cnt = pTbl->abbrevMatchCnt; for (pTblx = pTbl; pTblx->fHandler; pTblx++) { if (pTblx->abbrevMatchCnt) { if (pTblx->abbrevMatchCnt > cnt) { cnt = pTblx->abbrevMatchCnt; } } } CLIDEBUG(("highest abmatch cnt: %d\n", cnt)); match = 0; for (pTblx = pTbl; pTblx->fHandler; pTblx++) { if (pTblx->abbrevMatchCnt == cnt) { if (cnt == strlen(p) && cnt == strlen(pTblx->pCmd)) { /* any possibility??? these equals exact matching */ match = 1; break; } match++; } } CLIDEBUG(("match -- %d\n", match)); if (match) { len = strlen(p); for (pTblx = pTbl; pTblx->fHandler; pTblx++) { if (pTblx->abbrevMatchCnt == cnt) { if (len <= strlen(pTblx->pCmd)) { if (tokencmp(p, pTblx->pCmd, len) == 0) { /* Handler the highest matched command */ //if(match == 1) { if (!pCli->securityCheck || IsSuperUser() == TRUE || tokenIsProtected(pTblx) == FALSE) { //Deleted by Mario Huang, it seems useless //tokenCurTblSet(pTblx); rc = (*pTblx->fHandler) (pCli, p, pTblx-> pNxtParseTbl); if (rc == CLI_PARSE_NO_VALUE) { helpCmdScan(pCli, pTblx->pNxtParseTbl, pTblx->pCmd, NULL, 1); rc = CLI_PARSE_TOO_FEW; } /* Count the related setting functions have been done successfully, * so as to do associated applying action while excute apply cmd. * add by Tony 2007.9.30 */ else if (rc == CLI_PARSE_OK) { if (pTblx->pApplyActionTbl) pTblx->pApplyActionTbl-> settingCnt++; } return rc; } //} //else { //helpCmdScan(pCli, pTblx, pTblx->pCmd, pTblx->pCmd, 1); //rc = CLI_PARSE_MULTI_MATCHES; //} } } break; } } if (rc == CLI_PARSE_MULTI_MATCHES) return rc; CLIDEBUG(("%s won't match with table item %s, pTbl: %p\n", p, pTblx->pCmd, (void *) pTblx)); } } if (pCli->tokenLvl > 1) { uiPrintf("Invalid parameter: %s", p); } else { uiPrintf("Unknown command: %s", p); } while ((p = tokenPop(pCli)) != NULL) { uiPrintf(" %s", p); } uiPrintf("\n"); CLIDEBUG(("parseTblIdx: %d\n", pCli->parseTblIdx)); if (!(pCli->parseTblIdx - 1 == 0 && *(pCli->ParseTbl[pCli->parseTblIdx - 1]->pCmd) == '#')) { if (pCli->tokenLvl <= 2) { uiPrintf("Type \"help\" for a list of valid commands.\n"); } else { uiPrintf("List of valid parameter(s):\n"); } } return pCli->tokenLvl <= 2 ? CLI_PARSE_UNKNOWN : CLI_PARSE_INVALID_PARAMETER; } return CLI_PARSE_OK; }
/*********************************************************************** * Function Name : helpCmdScan * Description : search for the help command * Input : @pCli, cli control structure * @pTbl, token table * @pTxt, next token * @pFilter, token filter * @verbose, version * Output : * Return value : CLI_PARSE_OK, help scan success ***********************************************************************/ int helpCmdScan(CLI * pCli, struct parse_token_s *pTbl, char *pTxt, char *pFilter, int verbose) { struct parse_token_s *pTblx; char buf[132]; int bmatch; if (pTbl == NULL || pTxt == NULL) { return CLI_PARSE_OK; } for (pTblx = pTbl; pTblx->fHandler; pTblx++) { if (pCli->securityCheck) { if (tokenIsProtected(pTblx) == TRUE && IsSuperUser() == FALSE) continue; if (tokenIsHidden(pTblx) == TRUE || tokenIsValidOpMode(pCli, pTblx) == FALSE) continue; } /* murphy van 2004-06-11 add */ if (tokenIsValidOpMode(pCli, pTblx) == FALSE) continue; if (verbose && pTblx->pNxtParseTbl) { sprintf(buf, "%s %s", pTxt, pTblx->pCmd); if (verbose == 1) { if (pFilter) { bmatch = bcmp(pTblx->pCmd, pFilter, strlen(pFilter)); if (bmatch == 0) { helpCmdScan(pCli, pTblx->pNxtParseTbl, buf, NULL, 0); } } else { helpCmdScan(pCli, pTblx->pNxtParseTbl, buf, pFilter, 0); } } if (verbose >= 10) { helpCmdScan(pCli, pTblx->pNxtParseTbl, buf, NULL, verbose); } } else { sprintf(buf, "%s %s", pTxt, pTblx->pCmd); if (pTblx->pHelpText) { if (pFilter) { bmatch = bcmp(pTblx->pCmd, pFilter, strlen(pFilter)); if (bmatch == 0) { uiPrintf("%-35s -- %s\n", buf, pTblx->pHelpText ? pTblx->pHelpText : ""); } } else { uiPrintf("%-35s -- %s\n", buf, pTblx->pHelpText ? pTblx->pHelpText : ""); } } } } return CLI_PARSE_OK; }