Esempio n. 1
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;
}
Esempio n. 2
0
static QueryResult QueryPamMode(const JoinProcessOptions *options, LWException **exc)
{
    BOOLEAN bFileExists = FALSE;
    DistroInfo distro;
    QueryResult result = NotApplicable;
    FILE* fp = NULL;
    DynamicArray lines;
    PCSTR pszFilePath = LOGIN_CONFIG_PATH;
    PSTR currentSystem = NULL;

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

    if(!options->joiningDomain || options->enableMultipleJoins)
        goto cleanup;

    LW_CLEANUP_CTERR(exc, DJGetDistroInfo(NULL, &distro));
    if(distro.os != OS_AIX || strcmp(distro.version, "5.3"))
        goto cleanup;

    LW_CLEANUP_CTERR(exc, CTCheckFileExists(pszFilePath, &bFileExists));

    if (!bFileExists)
        goto cleanup;

    result = SufficientlyConfigured;

    LW_CLEANUP_CTERR(exc, CTOpenFile(pszFilePath, "r", &fp));
    LW_CLEANUP_CTERR(exc, CTReadLines(fp, &lines));
    LW_CLEANUP_CTERR(exc, CTSafeCloseFile(&fp));

    LW_CLEANUP_CTERR(exc, GetAuthType(&lines, &currentSystem));
    if(strcmp(currentSystem, "PAM_AUTH"))
        goto cleanup;

    result = FullyConfigured;

cleanup:
    CT_SAFE_FREE_STRING(currentSystem);
    DJFreeDistroInfo(&distro);
    CTSafeCloseFile(&fp);
    CTFreeLines(&lines);
    return result;
}
Esempio n. 3
0
static
DWORD
WriteHostnameToSunFiles(
    PCSTR pOldShortHostname,
    PCSTR pNewShortHostname,
    PCSTR pDnsDomainName,
    PCSTR pOldFqdnHostname,
    PCSTR pNewFqdnHostname
    )
{
    DWORD ceError = ERROR_SUCCESS;
    FILE* fp = NULL;
    PSTR* ppszHostfilePaths = NULL;
    DWORD nPaths = 0;
    DWORD iPath = 0;
    PSTR pRealPath = NULL;
    PSTR pTempPath = NULL;
    PSTR pOldEscapedShortHostname = NULL;
    PSTR pOldEscapedFqdnHostname = NULL;
    PSTR pOldSedExpression = NULL;
    PSTR pSedExpression = NULL;
    BOOLEAN isSame = FALSE;

    DJ_LOG_INFO("Setting hostname to [%s]", pNewShortHostname);

    ceError = CTGetFileTempPath(
                        "/etc/nodename",
                        &pRealPath,
                        &pTempPath);
    BAIL_ON_CENTERIS_ERROR(ceError);

    ceError = CTOpenFile(
            pTempPath,
            "w",
            &fp);
    BAIL_ON_CENTERIS_ERROR(ceError);

    if (fprintf(fp, "%s\n", pNewShortHostname) < 0)
    {
        ceError = LwMapErrnoToLwError(errno);
        BAIL_ON_CENTERIS_ERROR(ceError);
    }

    ceError = CTSafeCloseFile(&fp);
    BAIL_ON_CENTERIS_ERROR(ceError);

    ceError = CTFileContentsSame(
                    pTempPath,
                    pRealPath,
                    &isSame);
    BAIL_ON_CENTERIS_ERROR(ceError);
    if (isSame)
    {
        BAIL_ON_CENTERIS_ERROR(ceError = CTRemoveFile(pTempPath));
    }
    else
    {
        ceError = CTSafeReplaceFile(pRealPath, pTempPath);
        BAIL_ON_CENTERIS_ERROR(ceError);
    }

    CT_SAFE_FREE_STRING(pRealPath);
    CT_SAFE_FREE_STRING(pTempPath);

    ceError = CTGetFileTempPath(
                        "/etc/defaultdomain",
                        &pRealPath,
                        &pTempPath);
    BAIL_ON_CENTERIS_ERROR(ceError);

    ceError = CTOpenFile(
            pTempPath,
            "w",
            &fp);
    BAIL_ON_CENTERIS_ERROR(ceError);

    fprintf(fp, "%s\n", pDnsDomainName);

    ceError = CTSafeCloseFile(&fp);
    BAIL_ON_CENTERIS_ERROR(ceError);

    ceError = CTFileContentsSame(
                    pTempPath,
                    pRealPath,
                    &isSame);
    BAIL_ON_CENTERIS_ERROR(ceError);
    if (isSame)
    {
        BAIL_ON_CENTERIS_ERROR(ceError = CTRemoveFile(pTempPath));
    }
    else
    {
        ceError = CTSafeReplaceFile(pRealPath, pTempPath);
        BAIL_ON_CENTERIS_ERROR(ceError);
    }

    /* The first column of the /etc/hostname.<interface> files is the IP
     * address of the interface. It may either be specified directly in the
     * file, or the file may refer to an entry in /etc/hosts. This program is
     * editing /etc/hosts, any old entries in the hostname files need to be
     * fixed. */
    ceError = CTGetMatchingFilePathsInFolder("/etc",
                                             "hostname.*",
                                             &ppszHostfilePaths,
                                             &nPaths);
    BAIL_ON_CENTERIS_ERROR(ceError);

    ceError = SedEscapeLiteral(
                pOldShortHostname,
                &pOldEscapedShortHostname);
    BAIL_ON_CENTERIS_ERROR(ceError);

    ceError = LwAllocateStringPrintf(
                &pSedExpression,
                "s/^%s\\([ ].*\\)\\{0,1\\}$/%s\\1/",
                pOldEscapedShortHostname,
                pNewShortHostname);
    BAIL_ON_CENTERIS_ERROR(ceError);

    if (pOldFqdnHostname != NULL)
    {
        ceError = SedEscapeLiteral(
                    pOldFqdnHostname,
                    &pOldEscapedFqdnHostname);
        BAIL_ON_CENTERIS_ERROR(ceError);

        pOldSedExpression = pSedExpression;
        pSedExpression = NULL;

        ceError = LwAllocateStringPrintf(
                    &pSedExpression,
                    "%s;s/^%s\\([ ].*\\)\\{0,1\\}$/%s\\1/",
                    pOldSedExpression,
                    pOldEscapedFqdnHostname,
                    pNewFqdnHostname);
        BAIL_ON_CENTERIS_ERROR(ceError);
    }

    for (iPath = 0; iPath < nPaths; iPath++)
    {
        if (!CTStrEndsWith(ppszHostfilePaths[iPath], ".lwidentity.bak") &&
            !CTStrEndsWith(ppszHostfilePaths[iPath], ".lwidentity.orig"))
        {
            ceError = CTRunSedOnFile(
                            ppszHostfilePaths[iPath],
                            ppszHostfilePaths[iPath],
                            FALSE,
                            pSedExpression);
            BAIL_ON_CENTERIS_ERROR(ceError);
        }
    }

error:

    if (ppszHostfilePaths)
        CTFreeStringArray(ppszHostfilePaths, nPaths);

    if (fp) {
        fclose(fp);
    }

    CT_SAFE_FREE_STRING(pRealPath);
    CT_SAFE_FREE_STRING(pTempPath);
    CT_SAFE_FREE_STRING(pOldEscapedShortHostname);
    CT_SAFE_FREE_STRING(pOldEscapedFqdnHostname);
    CT_SAFE_FREE_STRING(pOldSedExpression);
    CT_SAFE_FREE_STRING(pSedExpression);

    return ceError;
}
Esempio n. 4
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);
}
Esempio n. 5
0
void
DJManageDaemons(
    BOOLEAN bStart,
    LWException **exc
    )
{
    BOOLEAN bFileExists = TRUE;
    FILE* fp = NULL;
    LWException *innerExc = NULL;
    int i;
    PLSA_LOG_INFO pLogInfo = NULL;
    BOOLEAN bLsassContacted = FALSE;
    DWORD dwError = 0;
    LW_HANDLE hLsa = NULL;

    LW_CLEANUP_CTERR(exc, CTCheckFileExists(PWGRD, &bFileExists));
    if(bFileExists)
    {
        //Shutdown pwgr (a nscd-like daemon) on HP-UX because it only handles
        //usernames up to 8 characters in length.
        LW_TRY(exc, DJStartStopDaemon("pwgr", FALSE, &LW_EXC));
        LW_CLEANUP_CTERR(exc, CTRunSedOnFile(PWGRD, PWGRD, FALSE, "s/=1/=0/"));
    }

    if(bStart)
    {
        // Set registry value for gpagentd to autostart.
        dwError = SetBooleanRegistryValue("Services\\gpagent", "Autostart", TRUE);
        // Trigger gpagentd start
        dwError = DJStartService("gpagent");

        // Make sure lsass is responding
        bLsassContacted = FALSE;
        for (i = 0; !bLsassContacted && i < 30; i++)
        {
            DJ_LOG_INFO("Trying to contact lsassd");
            if (hLsa)
            {
                LsaCloseServer(hLsa);
                hLsa = NULL;
            }
            dwError = LsaOpenServer(&hLsa);
            if (dwError == ERROR_FILE_NOT_FOUND ||
                    dwError == LW_ERROR_ERRNO_ECONNREFUSED)
            {
                DJ_LOG_INFO("Failed with %d", dwError);
                dwError = 0;
                sleep(1);
                continue;
            }
            LW_CLEANUP_CTERR(exc, dwError);
            LW_CLEANUP_CTERR(exc, LsaGetLogInfo(hLsa, &pLogInfo));
            bLsassContacted = TRUE;
        }
        if (!bLsassContacted)
        {
            LW_RAISE_EX(exc, ERROR_SERVICE_NOT_ACTIVE, "Unable to reach lsassd", "The lsass daemon could not be reached for 30 seconds after trying to start it. Please verify it is running.");
            goto cleanup;
        }
    }
    else
    {
        dwError = SetBooleanRegistryValue("Services\\gpagent", "Autostart", FALSE);

        dwError = DJStopService("gpagent");
    }

cleanup:
    CTSafeCloseFile(&fp);
    if (pLogInfo)
    {
        LsaFreeLogInfo(pLogInfo);
    }
    if (hLsa)
    {
        LsaCloseServer(hLsa);
    }

    LW_HANDLE(&innerExc);
}
Esempio n. 6
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;
}
Esempio n. 7
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;
}
Esempio n. 8
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;
}