示例#1
0
static DWORD
IsApparmorConfigured(BOOLEAN *configured)
{
    DWORD ceError = ERROR_SUCCESS;
    BOOLEAN hasApparmor;

    *configured = FALSE;

    GCE(ceError = HasApparmor(&hasApparmor));
    if(hasApparmor)
    {
        GCE(ceError = CTCheckFileHoldsPattern(APPARMOR_NSSWITCH,
                    "centeris", configured));
        if(!*configured)
        {
            GCE(ceError = CTCheckFileHoldsPattern(APPARMOR_NSSWITCH,
                        "likewise", configured));
        }
    }
    else
    {
        *configured = TRUE;
    }

cleanup:

    return ceError;
}
示例#2
0
DWORD
DJGetFinalFqdn(
    const JoinProcessOptions *options,
    PSTR *fqdn
    )
{
    DWORD ceError = ERROR_SUCCESS;
    const ModuleState *state = DJGetModuleStateByName((JoinProcessOptions *)options, "hostname");

    *fqdn = NULL;

    if(state != NULL && state->disposition == EnableModule)
    {
        //The fqdn will be set
        ceError = CTAllocateStringPrintf(fqdn, "%s.%s", options->computerName, options->domainName);
        GCE(ceError);
    }
    else
    {
        //The fqdn will not be set
        GCE(ceError = DJGetFQDN(NULL, fqdn));
    }
cleanup:
    return ceError;
}
示例#3
0
DWORD LWPrintException(FILE *dest, const LWException *print, BOOLEAN showTrace)
{
    DWORD ceError = ERROR_SUCCESS;
    PSTR string = NULL;
    PSTR wrapped = NULL;
    int columns;

    ceError = LWExceptionToString(print, "Error: ", FALSE, showTrace, &string);
    GCE(ceError);
    //Don't word wrap if the terminal width can't be determined
    if (CTGetTerminalWidth(fileno(dest), &columns))
        columns = -1;
    ceError = CTWordWrap(string, &wrapped, 4, columns);
    GCE(ceError);
    fprintf(dest, "%s\n", wrapped);

cleanup:
    if(ceError)
    {
        fprintf(dest, "Error %x occurred while trying to print exception\n", ceError);
    }
    CT_SAFE_FREE_STRING(string);
    CT_SAFE_FREE_STRING(wrapped);
    return ceError;
}
示例#4
0
DWORD LWExceptionToString(const LWException *conv, PCSTR titlePrefix, BOOLEAN showSymbolicCode, BOOLEAN showTrace, PSTR *result)
{
    DWORD ceError;
    PSTR ret = NULL;
    PSTR temp = NULL;
    PCSTR codeName = NULL;

    if(titlePrefix == NULL)
        titlePrefix = "";
    
    if(showSymbolicCode)
        codeName = LwWin32ExtErrorToName(conv->code);

    if(codeName != NULL)
    {
        GCE(ceError = CTAllocateStringPrintf(
            &ret, "%s%s [%s]\n\n%s", titlePrefix, conv->shortMsg, codeName, conv->longMsg));
    }
    else
    {
        GCE(ceError = CTAllocateStringPrintf(
            &ret, "%s%s [code 0x%.8x]\n\n%s", titlePrefix, conv->shortMsg, conv->code, conv->longMsg));
    }
    if(showTrace)
    {
        const LWStackFrame *frame = &conv->stack;

        temp = ret;
        GCE(ceError = CTAllocateStringPrintf(
                &ret, "%s\n\nStack Trace:", temp));
        CT_SAFE_FREE_STRING(temp);
        while(frame != NULL)
        {
            temp = ret;
            GCE(ceError = CTAllocateStringPrintf(
                    &ret, "%s\n%s:%d", temp, frame->file, frame->line));
            CT_SAFE_FREE_STRING(temp);
            frame = frame->down;
        }
    }
    *result = ret;
    ret = NULL;

cleanup:
    CT_SAFE_FREE_STRING(temp);
    CT_SAFE_FREE_STRING(ret);
    return ceError;
}
示例#5
0
static DWORD RemoveModule(NsswitchConf *conf,
        int line, int moduleIndex)
{
    DWORD ceError = ERROR_SUCCESS;
    NsswitchEntry *lineObj = (NsswitchEntry *)GetEntry(conf, line);
    CTParseToken *beforeModule = NULL, *afterModule = NULL;
    CTParseToken *removeModule;

    removeModule = (CTParseToken *)lineObj->modules.data + moduleIndex;

    if(moduleIndex - 1 >= 0)
        beforeModule = (CTParseToken *)lineObj->modules.data + moduleIndex - 1;
    if(moduleIndex + 1 < lineObj->modules.size)
        afterModule = (CTParseToken *)lineObj->modules.data + moduleIndex + 1;

    if(afterModule == NULL && beforeModule != NULL)
    {
        /* Since the last module is being removed, move the trailingSeparator
         * to the previous module */
        CT_SAFE_FREE_STRING(beforeModule->trailingSeparator);
        beforeModule->trailingSeparator = removeModule->trailingSeparator;
        removeModule->trailingSeparator = NULL;
    }
    CTFreeParseTokenContents(removeModule);

    GCE(ceError = CTArrayRemove(&lineObj->modules, moduleIndex, sizeof(CTParseToken), 1));
    conf->modified = 1;

cleanup:
    return ceError;
}
示例#6
0
DWORD
DJConfigureNameServiceSwitch(const char *testPrefix, BOOLEAN enable)
{
    DWORD ceError = ERROR_SUCCESS;
    NsswitchConf conf;

    if(testPrefix == NULL)
        testPrefix = "";

    ceError = ReadNsswitchConf(&conf, testPrefix, TRUE);
    if(ceError == ERROR_FILE_NOT_FOUND)
    {
        ceError = ERROR_SUCCESS;
        DJ_LOG_WARNING("Warning: Could not find nsswitch file");
        goto cleanup;
    }
    GCE(ceError);

    ceError = UpdateNsswitchConf(&conf, enable);

    if(conf.modified)
        WriteNsswitchConfiguration(testPrefix, &conf);
    else
        DJ_LOG_INFO("nsswitch not modified");

cleanup:
    FreeNsswitchConfContents(&conf);

    return ceError;
}
示例#7
0
DWORD DJGetOptionValue(const DynamicArray *lines, PCSTR stanza, PCSTR name, PSTR *value)
{
    DWORD ceError = ERROR_SUCCESS;
    ssize_t i = DJFindLine(lines, stanza, name);
    PCSTR line;
    PSTR _value = NULL;

    *value = NULL;
    
    if(i == -1)
        GCE(ceError = ERROR_NOT_FOUND);

    line = *(PCSTR *)CTArrayGetItem((DynamicArray*)lines, i,
            sizeof(PCSTR));

    while (*line != '\0' && isspace((int)*line))
        line++;

    line += strlen(name);
   
    while (*line != '\0' && isspace((int)*line))
        line++;

    if(*line != '=')
    {
        GCE(ceError = ERROR_BAD_FORMAT);
    }
    line++;

    GCE(ceError = CTStrdup(line, &_value));
    CTStripWhitespace(_value);
    /* Remove the quotes around the value, if they exist */
    if(CTStrStartsWith(_value, "\"") && CTStrEndsWith(_value, "\""))
    {
        size_t len = strlen(_value);
        memmove(_value, _value + 1, len - 2 );
        _value[len - 2 ] = '\0';
    }

    *value = _value;
    _value = NULL;

cleanup:
    CT_SAFE_FREE_STRING(_value);
    return ceError;
}
示例#8
0
static DWORD RemoveLine(NsswitchConf *conf, int line)
{
    DWORD ceError = ERROR_SUCCESS;
    NsswitchEntry *lineObj = (NsswitchEntry *)GetEntry(conf, line);

    if(lineObj == NULL)
    {
        GCE(ceError = ERROR_INVALID_PARAMETER);
    }

    FreeNsswitchEntryContents(lineObj);
    GCE(ceError = CTArrayRemove(&conf->lines, line, sizeof(NsswitchEntry), 1));

    conf->modified = 1;

cleanup:
    return ceError;
}
示例#9
0
static DWORD AddEntry(NsswitchConf *conf, const DistroInfo *distro,
        int *addedIndex, const char *name)
{
    DWORD ceError = ERROR_SUCCESS;
    int line = -1;
    NsswitchEntry lineObj;
    const NsswitchEntry *copy;

    memset(&lineObj, 0, sizeof(lineObj));
    GCE(ceError = CTStrdup(name, &lineObj.name.value));

    for(line = 0; line < conf->lines.size; line++)
    {
        copy = GetEntry(conf, line);
        if(copy->name.value != NULL)
        {
            GCE(ceError = CTStrdup(copy->name.trailingSeparator, &lineObj.name.trailingSeparator));
            break;
        }
    }

    if(lineObj.name.trailingSeparator == NULL)
    {
        //Couldn't find an existing line to copy the separator from. We'll
        //have to guess based on the OS
        if(distro->os == OS_AIX)
            GCE(ceError = CTStrdup(" = ", &lineObj.name.trailingSeparator));
        else
            GCE(ceError = CTStrdup(": ", &lineObj.name.trailingSeparator));
    }

    GCE(ceError = CTArrayAppend(&conf->lines,
                sizeof(NsswitchEntry), &lineObj, 1));
    memset(&lineObj, 0, sizeof(lineObj));
    conf->modified = 1;
    if(addedIndex != NULL)
        *addedIndex = conf->lines.size - 1;

cleanup:
    FreeNsswitchEntryContents(&lineObj);
    return ceError;
}
示例#10
0
//Does the platform-specific equivalent of this in nsswitch.conf:
// hosts: files dns
DWORD
DJConfigureHostsEntry(const char *testPrefix)
{
    DWORD ceError = ERROR_SUCCESS;
    NsswitchConf conf;
    DistroInfo distro;
    int line;
    const char *hostsByFile;
    const char *hostsByDns;
    int moduleIndex;

    if(testPrefix == NULL)
        testPrefix = "";

    memset(&distro, 0, sizeof(distro));
    memset(&conf, 0, sizeof(conf));

    GCE(ceError = DJGetDistroInfo(testPrefix, &distro));

    ceError = ReadNsswitchConf(&conf, testPrefix, TRUE);
    GCE(ceError);

    hostsByFile = GetNameOfHostsByFile(&conf, &distro);
    hostsByDns = GetNameOfHostsByDns(&conf, &distro);

    line = FindEntry(&conf, 0, "hosts");
    if(line == -1)
    {
        DJ_LOG_INFO("Adding hosts line");
        GCE(ceError = AddEntry(&conf, &distro, &line, "hosts"));
        GCE(ceError = InsertModule(&conf, &distro, line, 0, hostsByDns));
        GCE(ceError = InsertModule(&conf, &distro, line, 0, hostsByFile));
    }
    moduleIndex = FindModuleOnLine(&conf, line, hostsByFile);
    if(moduleIndex > 0)
    {
        /* The local module exists on the line, but it is not the first
         * entry. */
        GCE(ceError = RemoveModule(&conf, line, moduleIndex));
    }
    if(moduleIndex != 0)
    {
        GCE(ceError = InsertModule(&conf, &distro, line, 0, hostsByFile));
    }

    if(conf.modified)
        WriteNsswitchConfiguration(testPrefix, &conf);
    else
        DJ_LOG_INFO("nsswitch not modified");

cleanup:
    FreeNsswitchConfContents(&conf);
    DJFreeDistroInfo(&distro);

    return ceError;
}
示例#11
0
static
DWORD
GetPstrFromStringRef(
    CFStringRef pIn,
    PSTR *ppOut
    )
{
    size_t len = 0;
    PSTR pOut = NULL;
    DWORD error = 0;

    len = CFStringGetMaximumSizeForEncoding(
                CFStringGetLength(pIn),
                CFStringGetSystemEncoding());

    error = LwAllocateMemory(
                len + 1,
                (PVOID*)&pOut);
    GCE(error);

    if (!CFStringGetCString(
                pIn,
                pOut,
                len + 1,
                CFStringGetSystemEncoding()))
    {
        error = ERROR_ILLEGAL_CHARACTER;
        GCE(error);
    }

    *ppOut = pOut;

cleanup:
    if (error)
    {
        LW_SAFE_FREE_STRING(pOut);
    }
    return error;
}
示例#12
0
DWORD
DJSetOptionValue(DynamicArray *lines, PCSTR stanza, PCSTR name, PCSTR value)
{
    ssize_t index;
    PSTR newLine = NULL;
    DWORD ceError = ERROR_SUCCESS;

    if(strchr(value, ' '))
    {
        /* Fixes bug 5564 */
        GCE(ceError = CTAllocateStringPrintf(&newLine, "\t%s = \"%s\"\n", name, value));
    }
    else
        GCE(ceError = CTAllocateStringPrintf(&newLine, "\t%s = %s\n", name, value));

    index = DJFindLine(lines, stanza, name);

    if(index == -1)
    {
        index = DJFindStanza(lines, stanza);
        if(index == -1)
            GCE(ceError = ERROR_INVALID_OPERATION);
        index++;
    }
    else
    {
        CT_SAFE_FREE_STRING(*(PSTR *)CTArrayGetItem((DynamicArray*)lines,
                    index, sizeof(PSTR)));
        GCE(ceError = CTArrayRemove((DynamicArray *)lines, index,
                    sizeof(PSTR), 1));
    }

    GCE(ceError = CTArrayInsert((DynamicArray *)lines, index,
                sizeof(PSTR), &newLine, 1));

cleanup:
    return ceError;
}
示例#13
0
static DWORD WriteNsswitchConfiguration(const char *rootPrefix, NsswitchConf *conf)
{
    DWORD ceError = ERROR_SUCCESS;
    DynamicArray printedLine;
    int i;
    char *tempName = NULL;
    char *finalName = NULL;
    char *prefixedPath = NULL;
    FILE *file = NULL;
    memset(&printedLine, 0, sizeof(printedLine));

    GCE(ceError = CTAllocateStringPrintf(&prefixedPath, "%s%s", rootPrefix, conf->filename));

    GCE(ceError = CTGetFileTempPath(
                        prefixedPath,
                        &finalName,
                        &tempName));

    DJ_LOG_INFO("Writing nsswitch configuration for %s", finalName);

    ceError = CTOpenFile(tempName, "w", &file);
    if(ceError)
    {
        DJ_LOG_ERROR("Unable to open '%s' for writing", tempName);
        GCE(ceError);
    }

    for(i = 0; i < conf->lines.size; i++)
    {
        GCE(ceError = GetPrintedLine(&printedLine, conf, i));
        GCE(ceError = CTFilePrintf(file, "%s\n", printedLine.data));
    }

    GCE(ceError = CTCloseFile(file));
    file = NULL;

    GCE(ceError = CTSafeReplaceFile(
            finalName,
            tempName));
    DJ_LOG_INFO("File moved into place");

cleanup:
    if(file != NULL)
        CTCloseFile(file);
    CTArrayFree(&printedLine);
    CT_SAFE_FREE_STRING(tempName);
    CT_SAFE_FREE_STRING(finalName);
    CT_SAFE_FREE_STRING(prefixedPath);
    return ceError;
}
示例#14
0
static DWORD ReadNsswitchFile(NsswitchConf *conf, const char *rootPrefix, const char *filename)
{
    DWORD ceError = ERROR_SUCCESS;
    FILE *file = NULL;
    PSTR buffer = NULL;
    char *fullPath = NULL;
    BOOLEAN endOfFile = FALSE;
    BOOLEAN exists;

    if(rootPrefix == NULL)
        rootPrefix = "";

    GCE(ceError = CTAllocateStringPrintf(
            &fullPath, "%s%s", rootPrefix, filename));
    DJ_LOG_INFO("Reading nsswitch file %s", fullPath);
    GCE(ceError = CTCheckFileOrLinkExists(fullPath, &exists));
    if(!exists)
    {
        DJ_LOG_INFO("File %s does not exist", fullPath);
        ceError = ERROR_FILE_NOT_FOUND;
        goto cleanup;
    }

    GCE(ceError = CTStrdup(filename,
        &conf->filename));
    GCE(ceError = CTOpenFile(fullPath, "r", &file));
    CT_SAFE_FREE_STRING(fullPath);
    while(TRUE)
    {
        CT_SAFE_FREE_STRING(buffer);
        GCE(ceError = CTReadNextLine(file, &buffer, &endOfFile));
        if(endOfFile)
            break;
        GCE(ceError = AddFormattedLine(conf, filename, buffer, NULL));
    }

    conf->modified = FALSE;

cleanup:
    CT_SAFE_FREE_STRING(buffer);
    if(file != NULL)
        CTCloseFile(file);
    CT_SAFE_FREE_STRING(fullPath);
    if(ceError)
        FreeNsswitchConfContents(conf);
    return ceError;
}
示例#15
0
static DWORD AddFormattedLine(NsswitchConf *conf, const char *filename, const char *linestr, const char **endptr)
{
    DWORD ceError = ERROR_SUCCESS;
    NsswitchEntry lineObj;
    const char *pos = linestr;
    const char *token_start = NULL;
    CTParseToken token;

    memset(&lineObj, 0, sizeof(lineObj));
    memset(&token, 0, sizeof(token));

    /* Find the leading whitespace in the line */
    token_start = pos;
    while(isblank(*pos)) pos++;
    GCE(ceError = CTStrndup(token_start, pos - token_start, &lineObj.leadingWhiteSpace));

    /* Read the name of the entry and attach its trailing : or = */
    GCE(ceError = CTReadToken(&pos, &lineObj.name, "=: \t", ";#\r\n", ""));

    /* Create an array of the modules for this entry */
    while(strchr("\r\n;#", *pos) == NULL)
    {
        GCE(ceError = CTReadToken(&pos, &token, ", \t", ";#\r\n", ""));
        GCE(ceError = CTArrayAppend(&lineObj.modules, sizeof(CTParseToken), &token, 1));
        memset(&token, 0, sizeof(token));
    }

    /*Read the comment, if there is one*/
    token_start = pos;
    while(strchr("\r\n", *pos) == NULL) pos++;

    if(pos != token_start)
        GCE(ceError = CTStrndup(token_start, pos - token_start, &lineObj.comment));

    GCE(ceError = CTArrayAppend(&conf->lines, sizeof(lineObj), &lineObj, 1));
    memset(&lineObj, 0, sizeof(lineObj));

    if(endptr != NULL)
        *endptr = pos;

cleanup:
    FreeNsswitchEntryContents(&lineObj);
    CTFreeParseTokenContents(&token);

    return ceError;
}
示例#16
0
/* Get the printed form of a line from the parsed form by concatenating all of the strings together */
static DWORD GetPrintedLine(DynamicArray *dest, NsswitchConf *conf, int line)
{
    DWORD ceError = ERROR_SUCCESS;
    size_t len = 0;
    char *pos;
    int i;
    const NsswitchEntry *lineObj = GetEntry(conf, line);

    len += CTGetTokenLen(&lineObj->name);
    for(i = 0; i < lineObj->modules.size; i++)
    {
        len += CTGetTokenLen(&((CTParseToken *)lineObj->modules.data)[i]);
    }
    if(lineObj->comment != NULL)
        len += strlen(lineObj->comment);

    //For the terminating NULL
    len++;

    if(len > dest->capacity)
        GCE(ceError = CTSetCapacity(dest, 1, len));
    pos = dest->data;
    CTAppendTokenString(&pos, &lineObj->name);
    for(i = 0; i < lineObj->modules.size; i++)
    {
        CTAppendTokenString(&pos, &((CTParseToken *)lineObj->modules.data)[i]);
    }
    if(lineObj->comment != NULL)
    {
        memcpy(pos, lineObj->comment, strlen(lineObj->comment));
        pos += strlen(lineObj->comment);
    }
    *pos = '\0';
    dest->size = len;

cleanup:
    return ceError;
}
示例#17
0
DWORD
DJFixLoginConfigFile(
    PCSTR pszPath
    )
{
    DWORD ceError = ERROR_SUCCESS;
    PCSTR pszFilePath = NULL;
    PSTR pszTmpPath = NULL;
    PSTR pszFinalPath = NULL;
    BOOLEAN bFileExists = FALSE;
    FILE* fp = NULL;
    FILE* fp_new = NULL;
    DynamicArray lines;
    PSTR currentSystem = NULL;

    memset(&lines, 0, sizeof(lines));
    if (IsNullOrEmptyString(pszPath))
        pszFilePath = LOGIN_CONFIG_PATH;
    else
        pszFilePath = pszPath;

    GCE(ceError = CTGetFileTempPath(
                        pszFilePath,
                        &pszFinalPath,
                        &pszTmpPath));

    GCE(ceError = CTCheckFileExists(pszFinalPath, &bFileExists));

    if (!bFileExists)
        goto cleanup;

    GCE(ceError = CTOpenFile(pszFinalPath, "r", &fp));
    GCE(ceError = CTReadLines(fp, &lines));
    GCE(ceError = CTSafeCloseFile(&fp));

    GCE(ceError = GetAuthType(&lines, &currentSystem));
    if(!strcmp(currentSystem, "PAM_AUTH"))
        goto cleanup;

    GCE(ceError = SetAuthType(&lines, "PAM_AUTH"));

    GCE(ceError = CTOpenFile(pszTmpPath, "w", &fp_new));
    GCE(ceError = CTWriteLines(fp_new, &lines));
    GCE(ceError = CTSafeCloseFile(&fp_new));

    GCE(ceError = CTSafeReplaceFile(pszFilePath, pszTmpPath));

cleanup:
    CTSafeCloseFile(&fp);
    CTSafeCloseFile(&fp_new);

    CT_SAFE_FREE_STRING(currentSystem);
    CT_SAFE_FREE_STRING(pszTmpPath);
    CT_SAFE_FREE_STRING(pszFinalPath);
    CTFreeLines(&lines);

    return ceError;
}
示例#18
0
DWORD
CTGetPidOfCmdLine(
    PCSTR programName,
    PCSTR programFilename,
    PCSTR cmdLine,
    uid_t owner,
    pid_t *pid,
    size_t *count
    )
{
    DWORD ceError = ERROR_NOT_SUPPORTED;
    size_t fillCount = 0;
    size_t foundCount = 0;
    struct stat findStat;
#if HAVE_DECL_PSTAT_GETPROC
    //HPUX should have this
    struct pst_status mystatus;
    struct pst_status status[10];
    int inBuffer;
    int i;
#endif
#ifdef HAVE_STRUCT_PSINFO
    //Solaris and AIX should have this
    DIR *dir = NULL;
    struct dirent *dirEntry = NULL;
    PSTR filePath = NULL;
    struct psinfo infoStruct;
    FILE *infoFile = NULL;
    struct stat compareStat;
    BOOLEAN bFileExists;
#endif
#if defined(HAVE_KVM_GETPROCS) && HAVE_DECL_KERN_PROC_PATHNAME
    //FreeBSD has this
    char pathBuffer[MAXPATHLEN];
    size_t len;
    int unfilteredCount;
    kvm_t *kd = NULL;
    struct kinfo_proc *procs;
    int i;
    struct kinfo_proc *pos;
    int sysctlName[4] = {
        CTL_KERN,
        KERN_PROC,
        KERN_PROC_PATHNAME,
        0 };
#endif

    if(count)
    {
        fillCount = *count;
        *count = 0;
    }
    else if(pid != NULL)
        fillCount = 1;

    if(programFilename != NULL)
    {
        while(stat(programFilename, &findStat) < 0)
        {
            if(errno == EINTR)
                continue;
            GCE(ceError = LwMapErrnoToLwError(errno));
        }
    }
    
#if HAVE_DECL_PSTAT_GETPROC
    //First get the process info for this process
    inBuffer = pstat_getproc(&mystatus, sizeof(mystatus), 0,
            getpid());
    if(inBuffer != 1)
        GCE(ceError = LwMapErrnoToLwError(errno));

    //Now look at all processes
    inBuffer = pstat_getproc(status, sizeof(status[0]),
            sizeof(status)/sizeof(status[0]), 0);
    if(inBuffer < 0)
        GCE(ceError = LwMapErrnoToLwError(errno));
    while(inBuffer > 0)
    {
        for(i = 0; i < inBuffer; i++)
        {
            if(memcmp(&mystatus.pst_rdir, &status[i].pst_rdir,
                        sizeof(mystatus.pst_rdir)))
            {
                /* This process has a different root directory (it is being run
                   via a chroot). Let's not count this process as a match. */
                continue;
            }
            if (owner != (uid_t)-1 && owner != status[i].pst_euid)
            {
                continue;
            }
            if (programName != NULL && strcmp(status[i].pst_ucomm, programName))
            {
                continue;
            }
            if (cmdLine != NULL && strcmp(status[i].pst_cmd, cmdLine))
            {
                continue;
            }
            if(programFilename != NULL && (
                    status[i].pst_text.psf_fileid != findStat.st_ino ||
                    status[i].pst_text.psf_fsid.psfs_id != findStat.st_dev ||
                    status[i].pst_text.psf_fsid.psfs_type != findStat.st_fstype
                    ))
            {
                continue;
            }
 
            //This is a match
            if(foundCount < fillCount)
                pid[foundCount] = status[i].pst_pid;
            foundCount++;
        }
        //Continue looking at the process list where we left off
        inBuffer = pstat_getproc(status, sizeof(status[0]),
                sizeof(status)/sizeof(status[0]),
                status[inBuffer - 1].pst_idx + 1);
        if(inBuffer < 0)
            GCE(ceError = LwMapErrnoToLwError(errno));
    }
    ceError = ERROR_SUCCESS;
#endif

#ifdef HAVE_STRUCT_PSINFO
    if ((dir = opendir("/proc")) == NULL) {
        GCE(ceError = LwMapErrnoToLwError(errno));
    }

    while(1)
    {
        errno = 0;
        dirEntry = readdir(dir);
        if(dirEntry == NULL)
        {
            if(errno != 0)
                GCE(ceError = LwMapErrnoToLwError(errno));
            else
            {
                //No error here. We simply read the last entry
                break;
            }
        }
        if(dirEntry->d_name[0] == '.')
            continue;
        // On AIX, there is a /proc/sys which does not contain a psinfo
        if(!isdigit((int)dirEntry->d_name[0]))
            continue;
        CT_SAFE_FREE_STRING(filePath);
        GCE(ceError = CTAllocateStringPrintf(&filePath, "/proc/%s/psinfo",
                    dirEntry->d_name));
        GCE(ceError = CTCheckFileOrLinkExists(filePath, &bFileExists));
        if(!bFileExists)
        {
            // On AIX 6.1, a defunct process can lack a psinfo file.
            continue;
        }
        GCE(ceError = CTSafeCloseFile(&infoFile));
        GCE(ceError = CTOpenFile(filePath, "r", &infoFile));
        if(fread(&infoStruct, sizeof(infoStruct), 1, infoFile) != 1)
        {
            GCE(ceError = LwMapErrnoToLwError(errno));
        }

        if (owner != (uid_t)-1 && owner != infoStruct.pr_euid)
        {
            continue;
        }
        if (programName != NULL && strcmp(infoStruct.pr_fname, programName))
        {
            continue;
        }
        if (cmdLine != NULL && strcmp(infoStruct.pr_psargs, cmdLine))
        {
            continue;
        }
        if(programFilename != NULL)
        {
            CT_SAFE_FREE_STRING(filePath);
            GCE(ceError = CTAllocateStringPrintf(&filePath,
                        "/proc/%s/object/a.out",
                        dirEntry->d_name));

            while(stat(filePath, &compareStat) < 0)
            {
                if(errno == EINTR)
                    continue;
                if(errno == ENOENT || errno == ENOTDIR)
                {
                    //This process wasn't executed from a file?
                    goto not_match;
                }
                GCE(ceError = LwMapErrnoToLwError(errno));
            }
            if(findStat.st_ino != compareStat.st_ino)
                continue;
            if(findStat.st_dev != compareStat.st_dev)
                continue;
            if(findStat.st_rdev != compareStat.st_rdev)
                continue;
        }
 
        //This is a match
        if(foundCount < fillCount)
            pid[foundCount] = infoStruct.pr_pid;
        foundCount++;
not_match:
        ;
    }
#endif

#if defined(HAVE_KVM_GETPROCS) && HAVE_DECL_KERN_PROC_PATHNAME
    kd = kvm_open(NULL, "/dev/null", NULL, O_RDONLY, NULL);
    if (kd == NULL)
        GCE(ceError = DWORD_ACCESS_DENIED);

    procs = kvm_getprocs(kd, KERN_PROC_PROC, 0, &unfilteredCount);
    if (procs == NULL)
        GCE(ceError = DWORD_ACCESS_DENIED);

    pos = procs;
    for(i = 0; i < unfilteredCount; i++,
        pos = (struct kinfo_proc *)((char *)pos + pos->ki_structsize))
    {
        if (owner != (uid_t)-1 && owner != pos->ki_uid)
        {
            continue;
        }
        if (programName != NULL && strcmp(pos->ki_comm, programName))
        {
            continue;
        }
        if (cmdLine != NULL)
        {
            char **args = kvm_getargv(kd, pos, 0);
            char **argPos = args;
            PCSTR cmdLinePos = cmdLine;

            while (*cmdLinePos != '\0')
            {
                if (argPos == NULL || *argPos == NULL)
                    break;

                if (strncmp(cmdLinePos, *argPos, strlen(*argPos)))
                    break;

                cmdLinePos += strlen(*argPos);
                argPos++;

                if(cmdLinePos[0] == ' ')
                    cmdLinePos++;
            }

            if(*cmdLinePos != '\0' || (argPos != NULL && *argPos != NULL))
            {
                //not a match
                continue;
            }
        }
        if (programFilename != NULL)
        {
            pathBuffer[0] = '\0';
            if (pos->ki_textvp != NULL)
            {
                sysctlName[3] = pos->ki_pid;
                len = sizeof(pathBuffer);
                if( sysctl(sysctlName, 4, pathBuffer, &len, NULL, 0) < 0)
                {
		    /* If the executable path does not exist
		       (e.g. because the file was deleted after
		       the program started), move on */
		    if (errno == ENOENT)
			continue;
                    GCE(ceError = LwMapErrnoToLwError(errno));
                }
            }
            if(strcmp(programFilename, pathBuffer))
                continue;
        }

        //This is a match
        if(foundCount < fillCount)
            pid[foundCount] = pos->ki_pid;
        foundCount++;
    }
    ceError = ERROR_SUCCESS;
#endif

    if(count)
        *count = foundCount;
    else if(!ceError && foundCount == 0)
        ceError = ERROR_PROC_NOT_FOUND;

cleanup:
#ifdef HAVE_STRUCT_PSINFO
    if(dir != NULL)
        closedir(dir);
    CT_SAFE_FREE_STRING(filePath);
    CTSafeCloseFile(&infoFile);
#endif
#if defined(HAVE_KVM_GETPROCS) && HAVE_DECL_KERN_PROC_PATHNAME
    if(kd != NULL)
    {
        kvm_close(kd);
    }
#endif

    return ceError;
}
示例#19
0
static void ConfigureApparmor(BOOLEAN enable, LWException **exc)
{
    DWORD ceError = ERROR_SUCCESS;
    BOOLEAN hasApparmor;
    BOOLEAN configured;
    BOOLEAN usingMr;
    FILE *file = NULL;
    PCSTR addString;
    PSTR restartPath = NULL;
    PSTR restartCommand = NULL;
    char *tempName = NULL;
    char *finalName = NULL;

    LW_CLEANUP_CTERR(exc, IsApparmorConfigured(&configured));
    if(configured == enable)
        goto cleanup;

    LW_CLEANUP_CTERR(exc, CTCheckFileOrLinkExists(APPARMOR_NSSWITCH,
                &hasApparmor));
    if(!hasApparmor)
        goto cleanup;

    GCE(ceError = CTGetFileTempPath(
                        APPARMOR_NSSWITCH,
                        &finalName,
                        &tempName));

    LW_CLEANUP_CTERR(exc, CTCheckFileHoldsPattern(finalName,
                "mr,", &usingMr));

    if(usingMr)
        addString = 
PREFIXDIR "/lib/*.so*            mr,\n"
PREFIXDIR "/lib64/*.so*          mr,\n"
"/tmp/.lwidentity/pipe              rw,\n"
LOCALSTATEDIR "/lib/likewise/.lsassd  rw,\n"
LOCALSTATEDIR "/tmp/.lsaclient_*              rw,\n";
    else
        addString =
PREFIXDIR "/lib/*.so*            r,\n"
PREFIXDIR "/lib64/*.so*          r,\n"
"/tmp/.lwidentity/pipe              rw,\n"
LOCALSTATEDIR "/lib/likewise/.lsassd  rw,\n"
LOCALSTATEDIR "/tmp/.lsaclient_*              rw,\n";


    if(enable)
    {
        LW_CLEANUP_CTERR(exc, CTCopyFileWithOriginalPerms(finalName, tempName));
        LW_CLEANUP_CTERR(exc, CTOpenFile(tempName, "a", &file));
        LW_CLEANUP_CTERR(exc, CTFilePrintf(file, "# likewise\n%s# end likewise\n",
                    addString));

        CTSafeCloseFile(&file);

        LW_CLEANUP_CTERR(exc, CTSafeReplaceFile(finalName, tempName));
    }
    else
    {
        LW_CLEANUP_CTERR(exc, CTRunSedOnFile(finalName, finalName, FALSE, "/^[ \t]*#[ \t]*likewise[ \t]*$/,/^[ \t]*#[ \t]*end likewise[ \t]*$/d"));
        LW_CLEANUP_CTERR(exc, CTRunSedOnFile(finalName, finalName, FALSE, "/^[ \t]*#[ \t]*centeris[ \t]*$/,/^[ \t]*#[ \t]*end centeris[ \t]*$/d"));
    }


    ceError = CTFindFileInPath("rcapparmor", "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", &restartPath);
    if(ceError == ERROR_FILE_NOT_FOUND)
    {
        ceError = CTFindFileInPath("apparmor", "/etc/init.d/apparmor", &restartPath);
    }
    
    if(ceError == ERROR_FILE_NOT_FOUND)
    {
        ceError = ERROR_SUCCESS;
    }
    else if(!ceError)
    {
        LW_CLEANUP_CTERR(exc, CTAllocateStringPrintf(&restartCommand,
                    "%s restart", restartPath));
        LW_TRY(exc, CTCaptureOutputToExc(restartCommand, &LW_EXC));
    }
    LW_CLEANUP_CTERR(exc, ceError);

cleanup:
    if(file != NULL)
    {
        CTCloseFile(file);
        CTRemoveFile(tempName);
    }
    CT_SAFE_FREE_STRING(restartPath);
    CT_SAFE_FREE_STRING(restartCommand);
    CT_SAFE_FREE_STRING(tempName);
    CT_SAFE_FREE_STRING(finalName);
}
示例#20
0
static
DWORD
CTGetPListVersion(
    PSTR* ppVersion
    )
{
    DWORD error = 0;
    CFURLRef pURL = NULL;
    CFDataRef pContents = NULL;
//    SInt32 urlError = 0;
    // Do not free. This is returned by a mac function following the "get"
    // rule.
    CFStringRef pVers = NULL;
    CFErrorRef pError = NULL;
    PSTR pVersionString = NULL;
    CFPropertyListRef pPList = NULL;
    PSTR pErrorString = NULL;

    pURL = CFURLCreateWithFileSystemPath(
                    kCFAllocatorDefault,
                    CFSTR("/System/Library/CoreServices/SystemVersion.plist"),
                    kCFURLPOSIXPathStyle,
                    false);
    
    if (!pURL)
    {
        error = ERROR_NOT_ENOUGH_MEMORY;
        GCE(error);
    }
    ////
    
    CFMutableDataRef fileContent = CFDataCreateMutable(kCFAllocatorDefault, 0);
    CFReadStreamRef stream = CFReadStreamCreateWithFile(kCFAllocatorDefault, pURL);
    if(stream)
    {
        if(CFReadStreamOpen(stream)) 
        {
            UInt8 buffer[BUFFERSIZE];
            CFIndex bytesRead;
            do
            {
                bytesRead = CFReadStreamRead(stream, buffer, sizeof(buffer));
                if(bytesRead > 0)
                {
                    CFDataAppendBytes(fileContent, buffer, bytesRead);
                }
            } while (bytesRead > 0);

            CFReadStreamClose(stream);                
            
        }
        
        CFRelease(stream);        
    }
    
    
    
    
    
    
////
 /*   if (!CFURLCreateDataAndPropertiesFromResource(
            kCFAllocatorDefault,
            pURL,
            &pContents,
            NULL,
            NULL,
            &urlError))
    {
        error = UrlErrorToLwError(urlError);
        GCE(error);
    }
*/
    pPList = CFPropertyListCreateWithData(
                    kCFAllocatorDefault,
                    pContents,
                    kCFPropertyListImmutable,
                    NULL,
                    &pError);
    if (!pPList)
    {
        CFStringRef pErrorDesc = CFErrorCopyDescription(pError);
        GetPstrFromStringRef(pErrorDesc, &pErrorString);
        // CT_LOG_ERROR("Error '%s' parsing OS X version file",
        //         LW_SAFE_LOG_STRING(pErrorString));
        error = ERROR_PRODUCT_VERSION;
        CFRelease(pErrorDesc);
        GCE(error);
    }

    pVers = (CFStringRef)CFDictionaryGetValue(
                (CFDictionaryRef)pPList,
                CFSTR("ProductVersion"));
    if (!pVers)
    {
        error = ERROR_PRODUCT_VERSION;
        GCE(error);
    }

    error = GetPstrFromStringRef(
                pVers,
                &pVersionString);
    GCE(error);

    *ppVersion = pVersionString;

cleanup:
    if (error)
    {
        LW_SAFE_FREE_STRING(pVersionString);
    }
    if (pError)
    {
        CFRelease(pError);
    }
    LW_SAFE_FREE_STRING(pErrorString);
    if (pURL)
    {
        CFRelease(pURL);
    }
    if (pContents)
    {
        CFRelease(pContents);
    }
    if (pPList)
    {
        CFRelease(pPList);
    }
    return error;
}
示例#21
0
DWORD CTGetDistroInfo(const char *testPrefix, CtDistroInfo *info)
{
    BOOLEAN exists;
    DWORD ceError = ERROR_SUCCESS;
    struct utsname unameStruct;
    char *path = NULL;
    PSTR fileContents = NULL;
    PSTR distroString = NULL;
    BOOLEAN rxAlloced = FALSE;
    regex_t rx;
    memset(info, 0, sizeof(*info));
#if defined(HAVE_SYSINFO) && defined(SI_ARCHITECTURE)
    char archBuffer[100];
#endif

    //According to the Solaris man page, any non-negative return value
    //indicates success. In fact, Solaris 8 returns 1, while Linux returns
    //0.
    if(uname(&unameStruct) < 0)
        return LwMapErrnoToLwError(errno);

    //Check for os override file
    if(testPrefix == NULL)
        testPrefix = "";
    GCE(ceError = CTAllocateStringPrintf(
            &path, "%s/ostype", testPrefix));
    GCE(ceError = CTCheckFileOrLinkExists(
            path, &exists));
    if(exists)
    {
        GCE(ceError = CTReadFile(
                path, SIZE_MAX, &fileContents, NULL));
    }
    if(fileContents != NULL)
    {
        CTStripWhitespace(fileContents);
        info->os = CTGetOSFromString(fileContents);
    }
    else
        info->os = CTGetOSFromString(unameStruct.sysname);
    CT_SAFE_FREE_STRING(fileContents);
    CT_SAFE_FREE_STRING(path);

    //Check for distro override file
    GCE(ceError = CTAllocateStringPrintf(
            &path, "%s/osdistro", testPrefix));
    GCE(ceError = CTCheckFileOrLinkExists(
            path, &exists));
    if(exists)
    {
        GCE(ceError = CTReadFile(
                path, SIZE_MAX, &distroString, NULL));
    }
    CT_SAFE_FREE_STRING(path);

    if(distroString != NULL)
    {
        CTStripWhitespace(distroString);
        info->distro = CTGetDistroFromString(distroString);
        CT_SAFE_FREE_STRING(distroString);
        GCE(ceError = CTStrdup("unknown", &info->version));
    }
    else if(info->os == OS_LINUX)
    {
        struct
        {
            CtDistroType matchDistro;
            const char *searchFile;
            const char *matchRegex;
            int versionMatchNum;
            int updateMatchNum;
            BOOLEAN compareCase;
        } const distroSearch[] = {
            {
                DISTRO_ESX,
                "/etc/vmware-release",
                /*
                # The format of the line is something like:
                #   VMware ESX 4.0 (Kandinsky)
                */
                "^[[:space:]]*VMware ESX ([[:digit:]]+(\\.[[:digit:]]+)?)"
                "( \\(\\S+\\))?",
                1,
                -1,
                1
            },
            {
                DISTRO_RHEL,
                "/etc/redhat-release",
                /*
                # The format of the line is something like:
                #   Red Hat Enterprise Linux ES release 4 (Nahant Update 1)
                #   Red Hat Linux Advanced Server release 2.1AS (Pensacola)
                #   Red Hat Enterprise Linux Client release 5 (Tikanga)
                #   Red Hat Enterprise Linux Server release 5.3 (Tikanga)
                #   Red Hat Enterprise Linux ES release 4 (Nahant Update 8)
                #   Red Hat Enterprise Linux Workstation release 6.0 (Santiago)
                # In addition, Oracle Linux reports itself as:
                #   Enterprise Linux Enterprise Linux AS release 4 (October Update 5)
                */
                //Find a matching distro name
                "^[[:space:]]*((Red Hat)|(Enterprise Linux)) ((Enterprise Linux)|(Linux (Advanced|Enterprise) Server))[[:space:]]+(AS |ES |Client |Server |Workstation )?"
                "release ([[:digit:]]+(\\.[[:digit:]]+)?(AS|ES)?) (\\(\\S+ Update ([[:digit:]]+)\\))?",
                9,
                13,
                1
            },
            {
                DISTRO_REDHAT,
                "/etc/redhat-release",
                /*
                # The format of the line is something like:
                #   Red Hat Linux release 7.3 (Valhala)
                */
                "^[[:space:]]*Red Hat Linux release ([[:digit:]]+(\\.[[:digit:]]+)?)",
                1,
                -1,
                1
            },
            {
                DISTRO_FEDORA,
                "/etc/redhat-release",
                /*
                # The format of the line is something like:
                #   Fedora Core release 4 (Stentz)
                */
                "^[[:space:]]*Fedora (Core )?release (\\S+)",
                2,
                -1,
                1
            },
            {
                DISTRO_CENTOS,
                "/etc/redhat-release",
                /*
                # The format of the line is something like:
                #   CentOS release 4.x (Final)
                */
                "^[[:space:]]*(CentOS|CentOS Linux) release ([[:digit:]]+(\\.[[:digit:]]+)?)",
                2,
                -1,
                1
            },
            {
                DISTRO_SCIENTIFIC,
                "/etc/redhat-release",
                /*
                # The format of the line is something like:
                #   Scientific Linux release 6.1 (Carbon)
                */
                "^[[:space:]]*(Scientific|Scientific Linux) release ([[:digit:]]+(\\.[[:digit:]]+)?)",
                2,
                -1,
                1
            },
            {
                DISTRO_SUSE,
                "/etc/SuSE-release",
                "^[[:space:]]*SUSE LINUX ([[:digit:]]+\\.[[:digit:]]+)[[:space:]]+",
                1,
                -1,
                0
            },
            {
                DISTRO_OPENSUSE,
                "/etc/SuSE-release",
                "^[[:space:]]*openSUSE ([[:digit:]]+\\.[[:digit:]]+)[[:space:]]+",
                1,
                -1,
                0
            },
            {
                DISTRO_SLES,
                "/etc/SuSE-release",
                "^[[:space:]]*SUSE LINUX Enterprise Server ([[:digit:]]+( SP[[:digit:]]+)?)",
                1,
                -1,
                0
            },
            {
                DISTRO_SLED,
                "/etc/SuSE-release",
                "^[[:space:]]*SUSE LINUX Enterprise Desktop ([[:digit:]]+( SP[[:digit:]]+)?)",
                1,
                -1,
                0
            },
            {
                DISTRO_UBUNTU,
                "/etc/lsb-release",
                /*
                # The file will have lines that include:
                #   DISTRIB_ID=Ubuntu
                #   DISTRIB_RELEASE=6.06
                */
                "^[[:space:]]*DISTRIB_ID[[:space:]]*=[[:space:]]*Ubuntu[[:space:]]*\n"
                "(.*\n)?DISTRIB_RELEASE[[:space:]]*=[[:space:]]*(\\S+)[[:space:]]*(\n.*)?$",
                2,
                -1,
                1
            },
            {
                DISTRO_DEBIAN,
                "/etc/debian_version",
                /*
                # The format of the entire file is a single line like:
                # 3.1
                # and nothing else, so that is the version
                */
                "^[[:space:]]*(\\S+)[[:space:]]*$",
                1,
                -1,
                1
            },
        };
        int i;
        regmatch_t matches[20];
        info->distro = DISTRO_UNKNOWN;
        for(i = 0; info->distro == DISTRO_UNKNOWN; i++)
        {
            if(i == sizeof(distroSearch)/sizeof(distroSearch[0]))
            {
                //We past the last item in DistroSearch
                break;
            }
            GCE(ceError = CTAllocateStringPrintf(
                    &path, "%s%s", testPrefix, distroSearch[i].searchFile));
            GCE(ceError = CTCheckFileOrLinkExists(path, &exists));
            if(exists)
            {
                int flags = REG_EXTENDED;
                if(!distroSearch[i].compareCase)
                    flags |= REG_ICASE;

                GCE(ceError = CTReadFile(path, SIZE_MAX, &fileContents, NULL));
                if(regcomp(&rx, distroSearch[i].matchRegex, flags) != 0)
                {
                    GCE(ceError = LW_ERROR_REGEX_COMPILE_FAILED);
                }
                rxAlloced = TRUE;
                if(regexec(&rx, fileContents,
                        sizeof(matches)/sizeof(matches[0]), matches, 0) == 0 &&
                        matches[distroSearch[i].versionMatchNum].rm_so != -1)
                {
                    //This is the correct distro
                    regmatch_t *ver = &matches[distroSearch[i].versionMatchNum];
                    regmatch_t *update = &matches[distroSearch[i].updateMatchNum];
                    info->distro = distroSearch[i].matchDistro;
                    if (distroSearch[i].updateMatchNum == -1 ||
                            update->rm_so == -1)
                    {
                        GCE(ceError = CTStrndup(fileContents + ver->rm_so,
                                    ver->rm_eo - ver->rm_so,
                                    &info->version));
                    }
                    else
                    {
                        GCE(ceError = CTAllocateStringPrintf(
                                &info->version,
                                "%.*s.%.*s",
                                ver->rm_eo - ver->rm_so,
                                fileContents + ver->rm_so,
                                update->rm_eo - update->rm_so,
                                fileContents + update->rm_so));
                    }
                }
                regfree(&rx);
                rxAlloced = FALSE;
                CT_SAFE_FREE_STRING(fileContents);
            }
            CT_SAFE_FREE_STRING(path);
        }
        if(info->distro == DISTRO_DEBIAN)
        {
            /*
            #
            # Debian and Ubuntu both have /etc/debian_version,
            # but only Ubuntu has an /etc/lsb-release
            #
            */
            GCE(ceError = CTAllocateStringPrintf(
                    &path, "%s/etc/lsb-release", testPrefix));
            GCE(ceError = CTCheckFileOrLinkExists(path, &exists));
            if(exists)
            {
                // CT_LOG_ERROR("Unexpected file: %s", path);
                info->distro = DISTRO_UNKNOWN;
            }
            CT_SAFE_FREE_STRING(path);
        }
    }
    else
    {
        //It's a UNIX system
        switch(info->os)
        {
        case OS_AIX:
            info->distro = DISTRO_AIX;
            /*Uname output from AIX 5.3:
            $ uname -v
            5
            $ uname -r
            3
            */
            GCE(ceError = CTAllocateStringPrintf(&info->version,
                        "%s.%s", unameStruct.version, unameStruct.release));
            break;
        case OS_SUNOS:
            info->distro = DISTRO_SUNOS;
            /*Uname output from Solaris 8:
            $ uname -r
            5.8
            */
            GCE(ceError = CTAllocateStringPrintf(&info->version,
                        "%s", unameStruct.release));
            break;
        case OS_DARWIN:
            info->distro = DISTRO_DARWIN;
            ceError = CTGetPListVersion(&info->version);
            GCE(ceError);
            CTStripWhitespace(info->version);
            break;
        case OS_HPUX:
            info->distro = DISTRO_HPUX;
            {
                const char *temp = unameStruct.release;
                while(!isdigit((int)*temp)) temp++;
                GCE(ceError = CTStrdup(temp, &info->version));
            }
            break;
        case OS_FREEBSD:
            info->distro = DISTRO_FREEBSD;
            GCE(ceError = CTAllocateStringPrintf(&info->version,
                        "%s", unameStruct.release));
            break;
        default:
            info->distro = DISTRO_UNKNOWN;
        }
    }

    if(info->distro == DISTRO_UNKNOWN)
    {
        CT_SAFE_FREE_STRING(info->version);
        GCE(ceError = CTStrdup("unknown", &info->version));
    }

    //Check for version override file
    GCE(ceError = CTAllocateStringPrintf(
            &path, "%s/osver", testPrefix));
    GCE(ceError = CTCheckFileOrLinkExists(
            path, &exists));
    if(exists)
    {
        GCE(ceError = CTReadFile(
                path, SIZE_MAX, &fileContents, NULL));
    }
    if(fileContents != NULL)
    {
        CTStripWhitespace(fileContents);
        CT_SAFE_FREE_STRING(info->version);
        info->version = fileContents;
        fileContents = NULL;
    }
    CT_SAFE_FREE_STRING(path);

    /*
    uname -m output:
    Linux: x86_64
    Linux: i386
    Linux: i686
    AIX: 00CBE1DD4C00
    Solaris: sun4u
    Solaris: i86pc
    Darwin: i386
    Darwin: Power Macintosh
    HPUX: 9000/785

    uname -i output:
    Linux: x86_64
    Linux: i386
    RHEL21: not recogn
    AIX: not recogn
    Darwin: not recogn
    Solaris: SUNW,Ultra-4
    Solaris: i86pc
    HPUX: 2000365584

    uname -p output:
    Linux reads /proc/cpuinfo
    Linux: x86_64
    Linux: i686
    Linux: athlon
    Darwin: i386
    Darwin: powerpc
    AIX has the value hard coded in uname
    AIX: powerpc
    Solaris uses sysinfo(SI_ARCHITECTURE, buff, sizeof(buff)
    Solaris: sparc
    Solaris: i386
    HPUX: not recogn
    */
    info->arch = ARCH_UNKNOWN;
#if defined(HAVE_SYSINFO) && defined(SI_ARCHITECTURE)
    //Solaris has this
    if(info->arch == ARCH_UNKNOWN &&
            sysinfo(SI_ARCHITECTURE, archBuffer, sizeof(archBuffer)) != -1)
    {
        info->arch = CTGetArchFromString(archBuffer);
    }
#endif
#if defined(HAVE_SYSCONF) && defined(_SC_CPU_VERSION)
    //HPUX uses this
    if(info->arch == ARCH_UNKNOWN)
    {
        switch(sysconf(_SC_CPU_VERSION))
        {
            case CPU_PA_RISC1_0:
            case CPU_PA_RISC1_1:
            case CPU_PA_RISC1_2:
            case CPU_PA_RISC2_0:
            case CPU_PA_RISC_MAX:
                info->arch = ARCH_HPPA;
                break;
#ifdef CPU_HP_INTEL_EM_1_0
            case CPU_HP_INTEL_EM_1_0:
#endif
#ifdef CPU_IA64_ARCHREV_0
            case CPU_IA64_ARCHREV_0:
#endif
                info->arch = ARCH_IA64;
                break;
            //If it's not any of the previous values, let another test figure
            //it out.
        }
    }
#endif
    if(info->arch == ARCH_UNKNOWN)
    {
        //Linux uses this, and sometimes Darwin does too. If 'uname -m' doesn't
        //return something meaningful on this platform, then the arch will stay
        //as unknown.
        info->arch = CTGetArchFromString(unameStruct.machine);
    }
    if(info->arch == ARCH_UNKNOWN)
    {
        //AIX and sometimes Darwin use this
        GCE(ceError = CTCaptureOutput("uname -p", &distroString));
        CTStripWhitespace(distroString);
        info->arch = CTGetArchFromString(distroString);
        CT_SAFE_FREE_STRING(distroString);
    }

    //Check for arch override file
    GCE(ceError = CTAllocateStringPrintf(
            &path, "%s/osarch", testPrefix));
    GCE(ceError = CTCheckFileOrLinkExists(
            path, &exists));
    if(exists)
    {
        GCE(ceError = CTReadFile(
                path, SIZE_MAX, &fileContents, NULL));
        info->arch = CTGetArchFromString(fileContents);
        CT_SAFE_FREE_STRING(fileContents);
    }
    CT_SAFE_FREE_STRING(path);

cleanup:
    CT_SAFE_FREE_STRING(path);
    CT_SAFE_FREE_STRING(fileContents);
    CT_SAFE_FREE_STRING(distroString);
    if(rxAlloced)
        regfree(&rx);
    if(ceError)
    {
        CTFreeDistroInfo(info);
    }
    return ceError;
}
示例#22
0
DWORD
CTGetLikewiseVersion(
    PSTR *product,
    PSTR *version,
    PSTR *build,
    PSTR *revision
    )
{
    FILE *versionFile = NULL;
    PSTR line = NULL; 
    BOOLEAN isEndOfFile = FALSE;
    DWORD ceError = ERROR_SUCCESS;
    BOOLEAN bIsEnterprise = FALSE;

    PSTR _product = NULL;
    PSTR _version = NULL;
    PSTR _build = NULL;
    PSTR _revision = NULL;

    *version = NULL;
    *build = NULL;
    *revision = NULL;

#ifdef MINIMAL_JOIN
    GCE(ceError = CTOpenFile(LOCALSTATEDIR "/VERSION", "r", &versionFile));
#else
    ceError = CTOpenFile(PREFIXDIR "/data/ENTERPRISE_VERSION", "r", &versionFile);
    if (ceError == 0)
    {
        bIsEnterprise = TRUE;
    }
    else
    {
        GCE(ceError = CTOpenFile(PREFIXDIR "/data/VERSION", "r", &versionFile));
    }
#endif

    while (TRUE)
    {
		CT_SAFE_FREE_STRING(line);
        GCE(ceError = CTReadNextLine(versionFile, &line, &isEndOfFile));
        if (isEndOfFile)
            break;
        CTStripWhitespace(line);
        if (!strncmp(line, "VERSION=", sizeof("VERSION=") - 1))
        {
            GCE(ceError = CTStrdup(line + sizeof("VERSION=") - 1,
                        &_version));
        }
        else if (!strncmp(line, "BUILD=", sizeof("BUILD=") - 1))
        {
            GCE(ceError = CTStrdup(line + sizeof("BUILD=") - 1,
                    &_build));
        }
        else if (!strncmp(line, "REVISION=", sizeof("REVISION=") - 1))
        {
            GCE(ceError = CTStrdup(line + sizeof("REVISION=") - 1,
                    &_revision));
        }
    }

    if (bIsEnterprise)
    {
        GCE(ceError = CTStrdup("Enterprise", &_product));
    }
    else
    {
        GCE(ceError = CTStrdup("Open", &_product));
    }
    if (_version == NULL)
    {
        GCE(ceError = CTStrdup("unknown", &_version));
    }
    if (_build == NULL)
    {
        GCE(ceError = CTStrdup("unknown", &_build));
    }
    if (_revision == NULL)
    {
        GCE(ceError = CTStrdup("unknown", &_revision));
    }

    GCE(ceError = CTSafeCloseFile(&versionFile));

    *product = _product;
    *version = _version;
    *build = _build;
    *revision = _revision;
    _product = NULL;
    _version = NULL;
    _build = NULL;
    _revision = NULL;
    
cleanup:

    CTSafeCloseFile(&versionFile);
    CT_SAFE_FREE_STRING(line);
    CT_SAFE_FREE_STRING(_version);
    CT_SAFE_FREE_STRING(_build);
    CT_SAFE_FREE_STRING(_revision);

    return ceError;
}
示例#23
0
DWORD
UpdateNsswitchConf(NsswitchConf *conf, BOOLEAN enable)
{
    DWORD ceError = ERROR_SUCCESS;
    DistroInfo distro;
    int line;
    int lwiIndex;
    static const char* moduleName = "lsass";
    static const char* oldModule = "lwidentity";

    GCE(ceError = DJGetDistroInfo(NULL, &distro));

    line = FindEntry(conf, 0, "passwd");
    if(enable && line == -1)
    {
        DJ_LOG_INFO("Adding passwd line");
        GCE(ceError = AddEntry(conf, &distro, &line, "passwd"));
        GCE(ceError = InsertModule(conf, &distro, line, -1, "files"));
    }
    lwiIndex = FindModuleOnLine(conf, line, moduleName);
    if(enable && lwiIndex == -1)
    {
        GCE(ceError = InsertModule(conf, &distro, line, -1, moduleName));
    }
    if(!enable && lwiIndex != -1)
    {
        GCE(ceError = RemoveModule(conf, line, lwiIndex));
    }
    lwiIndex = FindModuleOnLine(conf, line, oldModule);
    if(lwiIndex != -1)
    {
        GCE(ceError = RemoveModule(conf, line, lwiIndex));
    }

    // If lwidentity was the only entry
    // and we removed that now, don't write
    // an empty entry into the file
    if(!enable && line != -1 && GetEntry(conf, line)->modules.size == 0)
    {
        GCE(ceError = InsertModule(conf, &distro, line, -1, "files"));
    }

    line = FindEntry(conf, 0, "group");
    if(line == -1)
    {
        line = FindEntry(conf, 0, "groups");
    }
    if(enable && line == -1)
    {
        /* The nsswitch file doesn't have an existing groups line. We have to
         * guess based on platform whether it uses 'group' or 'groups'.
         */
        const char *groupName = "group";
        if(distro.os == OS_AIX || distro.os == OS_DARWIN)
        {
            groupName = "groups";
        }
        DJ_LOG_INFO("Adding %s line", groupName);
        GCE(ceError = AddEntry(conf, &distro, &line, groupName));
        GCE(ceError = InsertModule(conf, &distro, line, -1, "files"));
    }
    lwiIndex = FindModuleOnLine(conf, line, moduleName);
    if(enable && lwiIndex == -1)
    {
        GCE(ceError = InsertModule(conf, &distro, line, -1, moduleName));
    }
    if(!enable && lwiIndex != -1)
    {
        GCE(ceError = RemoveModule(conf, line, lwiIndex));
    }
    lwiIndex = FindModuleOnLine(conf, line, oldModule);
    if(lwiIndex != -1)
    {
        GCE(ceError = RemoveModule(conf, line, lwiIndex));
    }

    // If lwidentity was the only entry
    // and we removed that now, don't write
    // an empty entry into the file
    if(!enable && line != -1 && GetEntry(conf, line)->modules.size == 0)
    {
        GCE(ceError = InsertModule(conf, &distro, line, -1, "files"));
    }

cleanup:
    DJFreeDistroInfo(&distro);

    return ceError;
}
示例#24
0
DWORD
ReadNsswitchConf(NsswitchConf *conf, const char *testPrefix,
        BOOLEAN allowFileCreate)
{
    PSTR copyDestPath = NULL;
    PSTR defaultFilePath = NULL;
    DWORD ceError = ERROR_SUCCESS;
    BOOLEAN bFileExists = FALSE;
    memset(conf, 0, sizeof(*conf));
    
    //Keep trying to read different filenames until one of them is found
    if(!bFileExists)
    {
        bFileExists = TRUE;
        ceError = ReadNsswitchFile(conf, testPrefix, "/etc/nsswitch.conf");
        if(ceError == ERROR_FILE_NOT_FOUND)
        {
            bFileExists = FALSE;
            ceError = ERROR_SUCCESS;
        }
        GCE(ceError);
    }

    if(!bFileExists)
    {
        bFileExists = TRUE;
        ceError = ReadNsswitchFile(conf, testPrefix, "/etc/netsvc.conf");
        if(ceError == ERROR_FILE_NOT_FOUND)
        {
            bFileExists = FALSE;
            ceError = ERROR_SUCCESS;
        }
        GCE(ceError);
    }

    /* HP-UX 11.xx does not appear to have an nsswitch file in
       place by default. If we don't find on already installed,
       use our own */

    if(!bFileExists)
    {
        GCE(ceError = CTAllocateStringPrintf(
          &defaultFilePath, "%s%s", testPrefix, NSSWITCH_LWIDEFAULTS));
        GCE(ceError = CTCheckFileExists(defaultFilePath, &bFileExists));
      
        if (bFileExists) {
            ceError = ReadNsswitchFile(conf, testPrefix, NSSWITCH_LWIDEFAULTS);
            GCE(ceError);
            CT_SAFE_FREE_STRING(conf->filename);
            conf->modified = TRUE;

            if(allowFileCreate)
            {
                GCE(ceError = CTStrdup(NSSWITCH_CONF_PATH, &conf->filename));

                /* Copy over the original file. This way the user can more
                 * clearly see what we changed by comparing nsswitch.conf with
                 * nsswitch.conf.lwidentity.orig. Also, the permissions will be
                 * correct this way when the file is written out.
                 */
                DJ_LOG_INFO("Copying default nsswitch file");
                GCE(ceError = CTAllocateStringPrintf(
                    &copyDestPath, "%s%s", testPrefix, NSSWITCH_CONF_PATH));
                ceError = CTCopyFileWithOriginalPerms(defaultFilePath, copyDestPath);
                GCE(ceError);
            }
            else
            {
                GCE(ceError = CTStrdup(NSSWITCH_LWIDEFAULTS, &conf->filename));
            }
        }
    }

    if(!bFileExists)
    {
        GCE(ceError = ERROR_FILE_NOT_FOUND);
    }

cleanup:
    CT_SAFE_FREE_STRING(copyDestPath);
    CT_SAFE_FREE_STRING(defaultFilePath);

    return ceError;
}
示例#25
0
// HPUX should have this
DWORD
CTGetPidOfCmdLine(
    PCSTR programName,
    PCSTR programFilename,
    PCSTR cmdLine,
    uid_t owner,
    pid_t *pid,
    size_t *count
    )
{
    DWORD ceError = ERROR_NOT_SUPPORTED;
    size_t fillCount = 0;
    size_t foundCount = 0;
    struct stat findStat;
    struct pst_status mystatus;
    struct pst_status status[10];
    int inBuffer;
    int i;

    if(count)
    {
        fillCount = *count;
        *count = 0;
    }
    else if(pid != NULL)
        fillCount = 1;

    if(programFilename != NULL)
    {
        while(stat(programFilename, &findStat) < 0)
        {
            if(errno == EINTR)
                continue;
            GCE(ceError = LwMapErrnoToLwError(errno));
        }
    }

    //First get the process info for this process
    inBuffer = pstat_getproc(&mystatus, sizeof(mystatus), 0,
            getpid());
    if(inBuffer != 1)
        GCE(ceError = LwMapErrnoToLwError(errno));

    //Now look at all processes
    inBuffer = pstat_getproc(status, sizeof(status[0]),
            sizeof(status)/sizeof(status[0]), 0);
    if(inBuffer < 0)
        GCE(ceError = LwMapErrnoToLwError(errno));
    while(inBuffer > 0)
    {
        for(i = 0; i < inBuffer; i++)
        {
            if(memcmp(&mystatus.pst_rdir, &status[i].pst_rdir,
                        sizeof(mystatus.pst_rdir)))
            {
                /* This process has a different root directory (it is being run
                   via a chroot). Let's not count this process as a match. */
                continue;
            }
            if (owner != (uid_t)-1 && owner != status[i].pst_euid)
            {
                continue;
            }
            if (programName != NULL && strcmp(status[i].pst_ucomm, programName))
            {
                continue;
            }
            if (cmdLine != NULL && strcmp(status[i].pst_cmd, cmdLine))
            {
                continue;
            }
            if(programFilename != NULL && (
                    status[i].pst_text.psf_fileid != findStat.st_ino ||
                    status[i].pst_text.psf_fsid.psfs_id != findStat.st_dev ||
                    status[i].pst_text.psf_fsid.psfs_type != findStat.st_fstype
                    ))
            {
                continue;
            }
 
            //This is a match
            if(foundCount < fillCount)
                pid[foundCount] = status[i].pst_pid;
            foundCount++;
        }
        //Continue looking at the process list where we left off
        inBuffer = pstat_getproc(status, sizeof(status[0]),
                sizeof(status)/sizeof(status[0]),
                status[inBuffer - 1].pst_idx + 1);
        if(inBuffer < 0)
            GCE(ceError = LwMapErrnoToLwError(errno));
    }
    ceError = ERROR_SUCCESS;

    if(count)
        *count = foundCount;
    else if(!ceError && foundCount == 0)
        ceError = ERROR_PROC_NOT_FOUND;

cleanup:

    return ceError;
}
示例#26
0
//Solaris and AIX should have this
DWORD
CTGetPidOfCmdLine(
    PCSTR programName,
    PCSTR programFilename,
    PCSTR cmdLine,
    uid_t owner,
    pid_t *pid,
    size_t *count
    )
{
    DWORD ceError = ERROR_NOT_SUPPORTED;
    size_t fillCount = 0;
    size_t foundCount = 0;
    struct stat findStat;
    DIR *dir = NULL;
    struct dirent *dirEntry = NULL;
    PSTR filePath = NULL;
    struct psinfo infoStruct;
    FILE *infoFile = NULL;
    struct stat compareStat;
    BOOLEAN bFileExists;
#if defined(__LWI_SOLARIS__)
    int (*getzoneid)() = NULL;
    int zoneid = -1;
#endif

    if(count)
    {
        fillCount = *count;
        *count = 0;
    }
    else if(pid != NULL)
        fillCount = 1;

    if(programFilename != NULL)
    {
        while(stat(programFilename, &findStat) < 0)
        {
            if(errno == EINTR)
                continue;
            GCE(ceError = LwMapErrnoToLwError(errno));
        }
    }

    if ((dir = opendir("/proc")) == NULL) {
        GCE(ceError = LwMapErrnoToLwError(errno));
    }

#if defined(__LWI_SOLARIS__)
    getzoneid = dlsym(RTLD_DEFAULT, "getzoneid");
    if (getzoneid)
    {
        zoneid = getzoneid();
    }
#endif

    while(1)
    {
        errno = 0;
        dirEntry = readdir(dir);
        if(dirEntry == NULL)
        {
            if(errno != 0)
                GCE(ceError = LwMapErrnoToLwError(errno));
            else
            {
                //No error here. We simply read the last entry
                break;
            }
        }
        if(dirEntry->d_name[0] == '.')
            continue;
        // On AIX, there is a /proc/sys which does not contain a psinfo
        if(!isdigit((int)dirEntry->d_name[0]))
            continue;
        CT_SAFE_FREE_STRING(filePath);
        GCE(ceError = CTAllocateStringPrintf(&filePath, "/proc/%s/psinfo",
                    dirEntry->d_name));
        GCE(ceError = CTCheckFileOrLinkExists(filePath, &bFileExists));
        if(!bFileExists)
        {
            // On AIX 6.1, a defunct process can lack a psinfo file.
            continue;
        }
        GCE(ceError = CTSafeCloseFile(&infoFile));
        GCE(ceError = CTOpenFile(filePath, "r", &infoFile));
        if(fread(&infoStruct, sizeof(infoStruct), 1, infoFile) != 1)
        {
            GCE(ceError = LwMapErrnoToLwError(errno));
        }

#if defined(__LWI_SOLARIS__)
        if (zoneid != -1)
        {
            int processzoneid = -1;

#ifdef HAVE_STRUCT_PSINFO_PR_ZONEID
            processzoneid = (int) infoStruct.pr_zoneid;
#else
            processzoneid = (int)
                *(infoStruct.pr_filler +
                sizeof(infoStruct.pr_filler)/sizeof(infoStruct.pr_filler[0]) -
                3);
#endif
            if (zoneid != processzoneid)
            {
                continue;
            }
        }
#endif

        if (owner != (uid_t)-1 && owner != infoStruct.pr_euid)
        {
            continue;
        }
        if (programName != NULL && strcmp(infoStruct.pr_fname, programName))
        {
            continue;
        }
        if (cmdLine != NULL && strcmp(infoStruct.pr_psargs, cmdLine))
        {
            continue;
        }
        if(programFilename != NULL)
        {
            CT_SAFE_FREE_STRING(filePath);
            GCE(ceError = CTAllocateStringPrintf(&filePath,
                        "/proc/%s/object/a.out",
                        dirEntry->d_name));

            while(stat(filePath, &compareStat) < 0)
            {
                if(errno == EINTR)
                    continue;
                if(errno == ENOENT || errno == ENOTDIR)
                {
                    //This process wasn't executed from a file?
                    goto not_match;
                }
                GCE(ceError = LwMapErrnoToLwError(errno));
            }
            if(findStat.st_ino != compareStat.st_ino)
                continue;
            if(findStat.st_dev != compareStat.st_dev)
                continue;
            if(findStat.st_rdev != compareStat.st_rdev)
                continue;
        }
 
        //This is a match
        if(foundCount < fillCount)
            pid[foundCount] = infoStruct.pr_pid;
        foundCount++;
not_match:
        ;
    }

    if(count)
        *count = foundCount;
    else if(!ceError && foundCount == 0)
        ceError = ERROR_PROC_NOT_FOUND;

cleanup:
    if(dir != NULL)
        closedir(dir);
    CT_SAFE_FREE_STRING(filePath);
    CTSafeCloseFile(&infoFile);

    return ceError;
}
示例#27
0
static DWORD InsertModule(NsswitchConf *conf, const DistroInfo *distro,
        int line, int insertIndex, const char *name)
{
    DWORD ceError = ERROR_SUCCESS;
    NsswitchEntry *lineObj = (NsswitchEntry *)GetEntry(conf, line);
    CTParseToken *beforeModule = NULL, *afterModule = NULL;
    CTParseToken addModule;

    memset(&addModule, 0, sizeof(addModule));
    if(insertIndex == -1)
        insertIndex = lineObj->modules.size;

    GCE(ceError = CTStrdup(name, &addModule.value));

    if(insertIndex - 1 >= 0)
        beforeModule = (CTParseToken *)lineObj->modules.data + insertIndex - 1;
    if(insertIndex < lineObj->modules.size)
        afterModule = (CTParseToken *)lineObj->modules.data + insertIndex;

    if(beforeModule != NULL)
    {
        /* Copy the separator from the previous module */
        GCE(ceError = CTDupOrNullStr(beforeModule->trailingSeparator,
                &addModule.trailingSeparator));
        if(afterModule == NULL)
        {
            /*This is the last module.  Put in the correct separator after the
             * previous module */
            CT_SAFE_FREE_STRING(beforeModule->trailingSeparator);
            GCE(ceError = CTStrdup(GetModuleSeparator(conf, distro),
                    &beforeModule->trailingSeparator));
        }
    }
    else
    {
        if(afterModule == NULL)
        {
            //This is the last module
            if(lineObj->comment == NULL)
            {
                //Leave the trailingSeparator as NULL
            }
            else
            {
                GCE(ceError = CTStrdup(" ", &addModule.trailingSeparator));
            }
        }
        else
        {
            //This is the first module. Add the appropriate separator to
            //distinguish it from the next module.
            GCE(ceError = CTStrdup(GetModuleSeparator(conf, distro),
                    &addModule.trailingSeparator));
        }
    }

    GCE(ceError = CTArrayInsert(&lineObj->modules, insertIndex,
                sizeof(addModule), &addModule, 1));
    memset(&addModule, 0, sizeof(addModule));
    conf->modified = 1;

cleanup:
    CTFreeParseTokenContents(&addModule);
    return ceError;
}
示例#28
0
//FreeBSD has this
DWORD
CTGetPidOfCmdLine(
    PCSTR programName,
    PCSTR programFilename,
    PCSTR cmdLine,
    uid_t owner,
    pid_t *pid,
    size_t *count
    )
{
    DWORD ceError = ERROR_NOT_SUPPORTED;
    size_t fillCount = 0;
    size_t foundCount = 0;
    struct stat findStat;
    //FreeBSD has this
    char pathBuffer[MAXPATHLEN];
    size_t len;
    int unfilteredCount;
    kvm_t *kd = NULL;
    struct kinfo_proc *procs;
    int i;
    struct kinfo_proc *pos;
    int sysctlName[4] = {
        CTL_KERN,
        KERN_PROC,
        KERN_PROC_PATHNAME,
        0 };

    if(count)
    {
        fillCount = *count;
        *count = 0;
    }
    else if(pid != NULL)
        fillCount = 1;

    if(programFilename != NULL)
    {
        while(stat(programFilename, &findStat) < 0)
        {
            if(errno == EINTR)
                continue;
            GCE(ceError = LwMapErrnoToLwError(errno));
        }
    }

    kd = kvm_open(NULL, "/dev/null", NULL, O_RDONLY, NULL);
    if (kd == NULL)
        GCE(ceError = DWORD_ACCESS_DENIED);

    procs = kvm_getprocs(kd, KERN_PROC_PROC, 0, &unfilteredCount);
    if (procs == NULL)
        GCE(ceError = DWORD_ACCESS_DENIED);

    pos = procs;
    for(i = 0; i < unfilteredCount; i++,
        pos = (struct kinfo_proc *)((char *)pos + pos->ki_structsize))
    {
        if (owner != (uid_t)-1 && owner != pos->ki_uid)
        {
            continue;
        }
        if (programName != NULL && strcmp(pos->ki_comm, programName))
        {
            continue;
        }
        if (cmdLine != NULL)
        {
            char **args = kvm_getargv(kd, pos, 0);
            char **argPos = args;
            PCSTR cmdLinePos = cmdLine;

            while (*cmdLinePos != '\0')
            {
                if (argPos == NULL || *argPos == NULL)
                    break;

                if (strncmp(cmdLinePos, *argPos, strlen(*argPos)))
                    break;

                cmdLinePos += strlen(*argPos);
                argPos++;

                if(cmdLinePos[0] == ' ')
                    cmdLinePos++;
            }

            if(*cmdLinePos != '\0' || (argPos != NULL && *argPos != NULL))
            {
                //not a match
                continue;
            }
        }
        if (programFilename != NULL)
        {
            pathBuffer[0] = '\0';
            if (pos->ki_textvp != NULL)
            {
                sysctlName[3] = pos->ki_pid;
                len = sizeof(pathBuffer);
                if( sysctl(sysctlName, 4, pathBuffer, &len, NULL, 0) < 0)
                {
		    /* If the executable path does not exist
		       (e.g. because the file was deleted after
		       the program started), move on */
		    if (errno == ENOENT)
			continue;
                    GCE(ceError = LwMapErrnoToLwError(errno));
                }
            }
            if(strcmp(programFilename, pathBuffer))
                continue;
        }

        //This is a match
        if(foundCount < fillCount)
            pid[foundCount] = pos->ki_pid;
        foundCount++;
    }
    ceError = ERROR_SUCCESS;

    if(count)
        *count = foundCount;
    else if(!ceError && foundCount == 0)
        ceError = ERROR_PROC_NOT_FOUND;

cleanup:
    if(kd != NULL)
    {
        kvm_close(kd);
    }

    return ceError;
}
示例#29
0
DWORD
UpdateNsswitchConf(NsswitchConf *conf, BOOLEAN enable)
{
    DWORD ceError = ERROR_SUCCESS;
    LwDistroInfo distro;
    int line;
    int lwiIndex;
    static const char* moduleName = "lsass";
    static const char* oldModule = "lwidentity";
    const char* pszModule = NULL;
    CHAR  szCommand[2 * PATH_MAX + 1] = {};

    GCE(ceError = DJGetDistroInfo(NULL, &distro));

    line = FindEntry(conf, 0, "passwd");
    if(enable && line == -1)
    {
        DJ_LOG_INFO("Adding passwd line");
        GCE(ceError = AddEntry(conf, &distro, &line, "passwd"));
        GCE(ceError = InsertModule(conf, &distro, line, -1, "files"));
    }
    lwiIndex = FindModuleOnLine(conf, line, moduleName);
    if(enable && lwiIndex == -1)
    {
        GCE(ceError = InsertModule(conf, &distro, line, -1, moduleName));
    }
    if(!enable && lwiIndex != -1)
    {
        GCE(ceError = RemoveModule(conf, line, lwiIndex));
    }
    lwiIndex = FindModuleOnLine(conf, line, oldModule);
    if(lwiIndex != -1)
    {
        GCE(ceError = RemoveModule(conf, line, lwiIndex));
    }

    // If lwidentity was the only entry
    // and we removed that now, don't write
    // an empty entry into the file
    if(!enable && line != -1 && GetEntry(conf, line)->modules.size == 0)
    {
        GCE(ceError = InsertModule(conf, &distro, line, -1, "files"));
    }

    line = FindEntry(conf, 0, "group");
    if(line == -1)
    {
        line = FindEntry(conf, 0, "groups");
    }
    if(enable && line == -1)
    {
        /* The nsswitch file doesn't have an existing groups line. We have to
         * guess based on platform whether it uses 'group' or 'groups'.
         */
        const char *groupName = "group";
        if(distro.os == OS_AIX || distro.os == OS_DARWIN)
        {
            groupName = "groups";
        }
        DJ_LOG_INFO("Adding %s line", groupName);
        GCE(ceError = AddEntry(conf, &distro, &line, groupName));
        GCE(ceError = InsertModule(conf, &distro, line, -1, "files"));
    }
    lwiIndex = FindModuleOnLine(conf, line, moduleName);
    if(enable && lwiIndex == -1)
    {
        GCE(ceError = InsertModule(conf, &distro, line, -1, moduleName));
    }
    if(!enable && lwiIndex != -1)
    {
        GCE(ceError = RemoveModule(conf, line, lwiIndex));
    }
    lwiIndex = FindModuleOnLine(conf, line, oldModule);
    if(lwiIndex != -1)
    {
        GCE(ceError = RemoveModule(conf, line, lwiIndex));
    }

    // If lwidentity was the only entry
    // and we removed that now, don't write
    // an empty entry into the file
    if(!enable && line != -1 && GetEntry(conf, line)->modules.size == 0)
    {
        GCE(ceError = InsertModule(conf, &distro, line, -1, "files"));
    }

    // If initgroups is present, it overrides the groups line 
    // and has different semantics.
    // As soon as a module reports success, processing stops. We don't want
    // that so we need to add '[SUCCESS=continue]'
    // We are not adding initgroups if it is not present.
    line = FindEntry(conf, 0, "initgroups");
    lwiIndex = FindModuleOnLine(conf, line, moduleName);
    if(enable && line != -1 && lwiIndex == -1)
    {
        GCE(ceError = InsertModule(conf, &distro, line, -1, moduleName));
        lwiIndex = FindModuleOnLine(conf, line, moduleName);
        if (lwiIndex > 0)
        {
            ceError = InsertModule(conf, &distro, line, lwiIndex, "[SUCCESS=continue]");
            if (ceError)
            {
                RemoveModule(conf, line, lwiIndex - 1);
                GCE(ceError);
            }
        }
    }
    if (!enable && line != -1 && lwiIndex != -1)
    {
        if (lwiIndex > 0)
        {
            pszModule = GetModule(conf, line, lwiIndex - 1);
            if (pszModule && *pszModule == '[')
            {
                GCE(ceError = RemoveModule(conf, line, lwiIndex - 1));
                lwiIndex = lwiIndex - 1;
            }
        }
        GCE(ceError = RemoveModule(conf, line, lwiIndex));
    }

    if(!enable && line != -1 && GetEntry(conf, line)->modules.size == 0)
    {
        GCE(ceError = InsertModule(conf, &distro, line, -1, "files"));
    }

    if(distro.os == OS_SUNOS)
    {
        if(strcmp("5.11", distro.version) == 0)
        {
            if(enable)
            {
                sprintf(szCommand,
                   "svccfg -s name-service/switch setprop config/password=\\\"files %s\\\"",
                   moduleName);
                if(system(szCommand) < 0)
                {
                   goto cleanup;
                }
                memset(szCommand, 0, sizeof(szCommand));
                sprintf(szCommand,
                   "svccfg -s name-service/switch setprop config/group=\\\"files %s\\\"",
                   moduleName);
                if(system(szCommand) < 0)
                {
                   goto cleanup;
                }
                memset(szCommand, 0, sizeof(szCommand));
                sprintf(szCommand, "svcadm refresh name-service/switch");
                if(system(szCommand) < 0)
                {
                    goto cleanup;
                }
            }
            else
            {
                memset(szCommand, 0, sizeof(szCommand));
                sprintf(szCommand,
                   "svccfg -s name-service/switch setprop config/password=files");
                if(system(szCommand) < 0)
                {
                    goto cleanup;
                }
                memset(szCommand, 0, sizeof(szCommand));
                sprintf(szCommand,
                   "svccfg -s name-service/switch setprop config/group=files");
                if(system(szCommand) < 0)
                {
                    goto cleanup;
                }
                memset(szCommand, 0, sizeof(szCommand));
                sprintf(szCommand, "svcadm refresh name-service/switch");
                if(system(szCommand) < 0)
                {
                    goto cleanup;
                }
            }
        }
        else
        {
            goto cleanup;
        }
    }

cleanup:
    DJFreeDistroInfo(&distro);

    return ceError;
}
示例#30
0
static DWORD UnsupportedSeLinuxEnabled(BOOLEAN *hasBadSeLinux)
{
    BOOLEAN hasSeLinux;
    DWORD ceError = ERROR_SUCCESS;
    PSTR output = NULL;
    DistroInfo distro;

    *hasBadSeLinux = FALSE;
    memset(&distro, 0, sizeof(distro));

    GCE(ceError = CTCheckFileOrLinkExists("/usr/sbin/selinuxenabled", &hasSeLinux));
    if(!hasSeLinux)
        goto cleanup;

    GCE(ceError = CTCheckFileOrLinkExists("/usr/sbin/getenforce", &hasSeLinux));
    if(!hasSeLinux)
        goto cleanup;

    ceError = CTRunCommand("/usr/sbin/selinuxenabled >/dev/null 2>&1");
    if(ceError == ERROR_BAD_COMMAND)
    {
        //selinux is not enabled
        ceError = ERROR_SUCCESS;
        goto cleanup;
    }
    GCE(ceError);

    GCE(ceError = CTCaptureOutput("/usr/sbin/getenforce", &output));
    CTStripWhitespace(output);
    if(!strcmp(output, "Permissive"))
    {
        goto cleanup;
    }

    DJ_LOG_INFO("Selinux found to be present, enabled, and enforcing.");

    GCE(ceError = DJGetDistroInfo("", &distro));

    switch(distro.distro)
    {
        case DISTRO_CENTOS:
        case DISTRO_RHEL:
            if(distro.version[0] < '5')
            {
                DJ_LOG_INFO("Safe version of RHEL");
                goto cleanup;
            }
            break;
        case DISTRO_FEDORA:
            if(atol(distro.version) < 6)
            {
                DJ_LOG_INFO("Safe version of Fedora");
                goto cleanup;
            }
            break;
        default:
            goto cleanup;
    }
    *hasBadSeLinux = TRUE;

cleanup:
    if(ceError)
        *hasBadSeLinux = TRUE;

    CT_SAFE_FREE_STRING(output);
    DJFreeDistroInfo(&distro);

    return ceError;
}