Example #1
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;
}
Example #2
0
void DoGetDistroInfo(int argc, char **argv, LWException **exc)
{
    PSTR str = NULL;
    PCSTR requestType = argv[0];
    PCSTR testPrefix = NULL;
    LwDistroInfo distro = {0};

    argc--;
    argv++;

    if(argc > 0 && !strcmp(argv[0], "--testprefix"))
    {
        testPrefix = argv[1];
        argv += 2;
        argc -= 2;
    }
    if(argc > 0)
    {
        LW_RAISE(exc, LW_ERROR_SHOW_USAGE);
        goto cleanup;
    }

    LW_CLEANUP_CTERR(exc, DJGetDistroInfo(testPrefix, &distro));
    if(!strcmp(requestType, "get_os_type"))
    {
        LW_CLEANUP_CTERR(exc, DJGetOSString(distro.os, &str));
    }
    else if(!strcmp(requestType, "get_arch"))
    {
        LW_CLEANUP_CTERR(exc, DJGetArchString(distro.arch, &str));
    }
    else if(!strcmp(requestType, "get_distro"))
    {
        LW_CLEANUP_CTERR(exc, DJGetDistroString(distro.distro, &str));
    }
    else if(!strcmp(requestType, "get_distro_version"))
    {
        LW_CLEANUP_CTERR(exc, CTStrdup(distro.version, &str));
    }
    else
    {
        LW_RAISE(exc, LW_ERROR_SHOW_USAGE);
        goto cleanup;
    }
    fprintf(stdout, "%s\n", str);

cleanup:
    DJFreeDistroInfo(&distro);
    CT_SAFE_FREE_STRING(str);
}
Example #3
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;
}
Example #4
0
DWORD
DJGetBaseDaemonPriorities(
    int *startPriority,
    int *stopPriority,
    int *stopLaterOffset
    )
{
    LwDistroInfo distro;
    DWORD ceError = ERROR_SUCCESS;

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

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

    if (distro.os == OS_HPUX)
    {
        // Start after S590Rpcd
        *startPriority = 591;
        // Stop before K410Rpcd
        *stopPriority = 401;

        // On HP-UX, the kill scripts are run in numerical order. So adding 1
        // the priority causes it to stop later in the shutdown.
        *stopLaterOffset = 1;
    }
    else
    {
        *startPriority = 19;
        *stopPriority = 9;

        // On Linux, the stop scrips are run in descending order
        *stopLaterOffset = -1;
    }

cleanup:
    DJFreeDistroInfo(&distro);
    return ceError;
}
Example #5
0
void
DJSetComputerName(
    PCSTR pszComputerName,
    PCSTR pszDnsDomainName,
    LWException **exc
    )
{
    DWORD ceError = ERROR_SUCCESS;
    BOOLEAN bValidComputerName = FALSE;
    PSTR oldShortHostname = NULL;
    PSTR oldFqdnHostname = NULL;
    PSTR pszComputerName_lower = NULL;
    PSTR pNewFqdnHostname = NULL;
    PSTR ppszHostfilePaths[] = { "/etc/hostname", "/etc/HOSTNAME", NULL };
    LwDistroInfo distro;

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

    LW_CLEANUP_CTERR(exc, DJGetDistroInfo(NULL, &distro));

    LW_CLEANUP_CTERR(exc, DJIsValidComputerName(pszComputerName, &bValidComputerName));

    if (!bValidComputerName) {
        LW_CLEANUP_CTERR(exc, ERROR_INVALID_COMPUTERNAME);
    }

    LW_CLEANUP_CTERR(exc, CTAllocateString(pszComputerName, &pszComputerName_lower));

    CTStrToLower(pszComputerName_lower);

    /* Start spelunking for various hostname holding things. Rather
       than trying to worry about what flavor of linux we are
       running, we look for various files and fix them up if they
       exist. That way we dont end up with a huge wad of repeated
       code for each linux flavor.

       change the repositories of the 'HOSTNAME' variable.
       it's a string in /etc/HOSTNAME for some dists, it's a variable in
       /etc/sysconfig/network for others

       fixup HOSTNAME file if it exists
       Ubuntu/Debian have /etc/hostname, so add that...
    */

    LW_CLEANUP_CTERR(exc, WriteHostnameToFiles(pszComputerName_lower,
                                   ppszHostfilePaths));

    // insert/correct the new hostname in /etc/hosts - note that this
    // has to be done *before* we update the running hostname because
    // we call hostname to get the current hostname so that we can
    // find it and replace it.
    LW_CLEANUP_CTERR(exc, DJGetFQDN(&oldShortHostname, &oldFqdnHostname));

    //Don't replace localhost in /etc/hosts, always add our new hostname instead
    if(oldFqdnHostname != NULL && !strcmp(oldFqdnHostname, "localhost"))
    {
        CTFreeString(oldFqdnHostname);
        oldFqdnHostname = NULL;
    }
    if(oldShortHostname != NULL && !strcmp(oldShortHostname, "localhost"))
    {
        CTFreeString(oldShortHostname);
        oldShortHostname = NULL;
    }

    if (pszDnsDomainName[0])
    {
        ceError = LwAllocateStringPrintf(
                    &pNewFqdnHostname,
                    "%s.%s",
                    pszComputerName,
                    pszDnsDomainName);
        LW_CLEANUP_CTERR(exc, ceError);
    }
    else
    {
        ceError = LwAllocateStringPrintf(
                    &pNewFqdnHostname,
                    "%s",
                    pszComputerName);
        LW_CLEANUP_CTERR(exc, ceError);
    }

    ceError = DJCopyMissingHostsEntry("/etc/inet/ipnodes", "/etc/hosts",
            pszComputerName_lower, oldShortHostname);
    if(ceError == ERROR_FILE_NOT_FOUND)
        ceError = ERROR_SUCCESS;
    LW_CLEANUP_CTERR(exc, ceError);

    LW_CLEANUP_CTERR(exc, DJReplaceNameInHostsFile("/etc/hosts",
            oldShortHostname, oldFqdnHostname,
            pszComputerName_lower, pszDnsDomainName));

    ceError = DJReplaceNameInHostsFile("/etc/inet/ipnodes",
            oldShortHostname, oldFqdnHostname,
            pszComputerName_lower, pszDnsDomainName);
    if(ceError == ERROR_FILE_NOT_FOUND)
        ceError = ERROR_SUCCESS;
    LW_CLEANUP_CTERR(exc, ceError);

    switch (distro.os)
    {
        case OS_SUNOS:
            LW_CLEANUP_CTERR(exc, WriteHostnameToSunFiles(
                        oldShortHostname,
                        pszComputerName_lower,
                        pszDnsDomainName,
                        oldFqdnHostname,
                        pNewFqdnHostname
                        ));
            break;
        case OS_AIX:
            LW_CLEANUP_CTERR(exc, SetAIXHostname(pszComputerName_lower));
            break;
        case OS_HPUX:
            LW_CLEANUP_CTERR(exc, SetHPUXHostname(pszComputerName_lower));
            break;
        case OS_DARWIN:
            LW_CLEANUP_CTERR(exc, SetMacOsXHostName(pszComputerName_lower));
            break;
        default:
            break;
    }

    LW_TRY(exc, FixNetworkInterfaces(pszComputerName_lower, &LW_EXC));

cleanup:
    CT_SAFE_FREE_STRING(oldShortHostname);
    CT_SAFE_FREE_STRING(oldFqdnHostname);
    CT_SAFE_FREE_STRING(pszComputerName_lower);
    CT_SAFE_FREE_STRING(pNewFqdnHostname);
    DJFreeDistroInfo(&distro);
}
Example #6
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;
}
Example #7
0
static QueryResult RemoveCompat(NsswitchConf *conf, PSTR *description, LWException **exc)
{
    DistroInfo distro;
    int compatLine;
    int noncompatLine;
    int compatModIndex;
    BOOLEAN passwdNeedUpdate = FALSE;
    BOOLEAN groupNeedUpdate = FALSE;
    QueryResult result = FullyConfigured;

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

    /* The default configuration on FreeBSD is:
     * passwd: compat
     * passwd_compat: nis
     * group: compat
     * group_compat: nis
     *
     * The nsswitch man page says that compat must be the only module on the
     * line if it is used. Unfortunately, if a module is listed on the compat
     * line, it goes through a different interface which LSASS does not
     * understand. So this configuration must first be transformed into:
     *
     * passwd: files nis
     * group: files nis
     *
     * If the user is using compat mode with a non-default configuration, show
     * an error message instead.
     */

    LW_CLEANUP_CTERR(exc, DJGetDistroInfo(NULL, &distro));

    compatLine = FindEntry(conf, 0, "passwd_compat");
    if(compatLine != -1)
    {
        const NsswitchEntry *lineEntry = GetEntry(conf, compatLine);

        passwdNeedUpdate = TRUE;

        if(lineEntry->modules.size != 1)
        {
            result = CannotConfigure;
            goto done_configuring;
        }
        if(FindModuleOnLine(conf, compatLine, "nis") == -1)
        {
            result = CannotConfigure;
            goto done_configuring;
        }
        noncompatLine = FindEntry(conf, 0, "passwd");
        if(noncompatLine == -1)
        {
            result = CannotConfigure;
            goto done_configuring;
        }
        lineEntry = GetEntry(conf, noncompatLine);
        if(lineEntry->modules.size != 1)
        {
            result = CannotConfigure;
            goto done_configuring;
        }
        compatModIndex = FindModuleOnLine(conf, noncompatLine, "compat");
        if(compatModIndex == -1)
        {
            result = CannotConfigure;
            goto done_configuring;
        }

        result = NotConfigured;

        LW_CLEANUP_CTERR(exc, InsertModule(conf, &distro, noncompatLine, -1, "files"));
        LW_CLEANUP_CTERR(exc, InsertModule(conf, &distro, noncompatLine, -1, "nis"));
        LW_CLEANUP_CTERR(exc, RemoveModule(conf, noncompatLine, compatModIndex));
        LW_CLEANUP_CTERR(exc, RemoveLine(conf, compatLine));
    }

    compatLine = FindEntry(conf, 0, "group_compat");
    if(compatLine != -1)
    {
        const NsswitchEntry *lineEntry = GetEntry(conf, compatLine);

        groupNeedUpdate = TRUE;

        if(lineEntry->modules.size != 1)
        {
            result = CannotConfigure;
            goto done_configuring;
        }
        if(FindModuleOnLine(conf, compatLine, "nis") == -1)
        {
            result = CannotConfigure;
            goto done_configuring;
        }
        noncompatLine = FindEntry(conf, 0, "group");
        if(noncompatLine == -1)
        {
            result = CannotConfigure;
            goto done_configuring;
        }
        lineEntry = GetEntry(conf, noncompatLine);
        if(lineEntry->modules.size != 1)
        {
            result = CannotConfigure;
            goto done_configuring;
        }
        compatModIndex = FindModuleOnLine(conf, noncompatLine, "compat");
        if(compatModIndex == -1)
        {
            result = CannotConfigure;
            goto done_configuring;
        }

        result = NotConfigured;

        LW_CLEANUP_CTERR(exc, InsertModule(conf, &distro, noncompatLine, -1, "files"));
        LW_CLEANUP_CTERR(exc, InsertModule(conf, &distro, noncompatLine, -1, "nis"));
        LW_CLEANUP_CTERR(exc, RemoveModule(conf, noncompatLine, compatModIndex));
        LW_CLEANUP_CTERR(exc, RemoveLine(conf, compatLine));
    }

done_configuring:
    if(result == CannotConfigure && description != NULL)
    {
        LW_CLEANUP_CTERR(exc, CTStrdup("Remove the passwd_compat and/or group_compat lines and use passwd and group instead. This cannot be done automatically because your system has a non-default nsswitch configuration.\n", description));
    }
    else if((passwdNeedUpdate || groupNeedUpdate) && description != NULL)
    {
        LW_CLEANUP_CTERR(exc, CTStrdup("Remove the passwd_compat and/or group_compat lines and use passwd and group instead.\n", description));
        result = NotConfigured;
    }
    else if(description != NULL)
    {
        LW_CLEANUP_CTERR(exc, CTStrdup("Fully Configured.", description));
    }

cleanup:
    DJFreeDistroInfo(&distro);

    return result;
}
Example #8
0
static void RestartDtloginIfRunning(JoinProcessOptions *options, LWException **exc)
{
    BOOLEAN doRestart;
    BOOLEAN inX;
    LWException *inner = NULL;
    DistroInfo distro;

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

    DJGetDaemonStatus("dtlogin", &doRestart, &inner);
    if(!LW_IS_OK(inner) && inner->code == ERROR_SERVICE_NOT_FOUND)
    {
        LW_HANDLE(&inner);
        goto cleanup;
    }
    LW_CLEANUP(exc, inner);

    if(doRestart)
    {
        /* Dtlogin will only be restarted if no one is logged in. */
        LW_CLEANUP_CTERR(exc, CTIsUserInX(&inX));

        if(inX)
        {
            doRestart = FALSE;
            /* If we're disabling domain logins, it isn't critical that
             * dtlogin is restarted. Without lwiauthd running, domain
             * users won't be able to log in anyway. */
            if(options->joiningDomain)
            {
                LW_CLEANUP_CTERR(exc, DJGetDistroInfo(NULL, &distro));
                if(distro.os == OS_SUNOS)
                {
                    if (options->warningCallback != NULL)
                    {
                        options->warningCallback(options, "Unable to restart dtlogin",
                            "The dtlogin process needs to be restarted for domain users to interactively login graphically, but it cannot be restarted at this time because a user is currently logged in. After the user exits, please run these commands as root, outside of an Xwindows session:\n\n"
                            "/etc/init.d/dtlogin stop\n"
                            "/etc/init.d/dtlogin start");
                    }
                }
                else if(distro.os == OS_HPUX)
                {
                    if (options->warningCallback != NULL)
                    {
                        options->warningCallback(options, "Unable to restart dtlogin",
                            "The dtlogin process needs to be restarted for domain users to interactively login graphically, but it cannot be restarted at this time because a user is currently logged in. After the user exits, please run these commands as root, outside of an Xwindows session:\n\n"
                            "/sbin/init.d/dtlogin.rc stop\n"
                            "/sbin/init.d/dtlogin.rc start");
                    }
                }
                else if(distro.os == OS_AIX)
                {
                    if (options->warningCallback != NULL)
                    {
                        options->warningCallback(options, "Unable to restart dtlogin",
                            "The dtlogin process needs to be restarted for domain users to interactively login graphically, but it cannot be restarted at this time because a user is currently logged in. After the user exits, please run these commands as root, outside of an Xwindows session:\n\n"
                            "kill `cat /var/dt/Xpid`\n"
                            "/etc/rc.dt");
                    }
                }
                else
                {
                    if (options->warningCallback != NULL)
                    {
                        options->warningCallback(options, "Unable to restart dtlogin",
                            "The dtlogin process needs to be restarted for domain users to interactively login graphically, but it cannot be restarted at this time because a user is currently logged in. After the user exits, please restart dtlogin.");
                    }
                }
            }
        }
    }
    if(doRestart)
    {
        LW_TRY(exc, DJStartStopDaemon("dtlogin", FALSE, &LW_EXC));
        LW_TRY(exc, DJStartStopDaemon("dtlogin", TRUE, &LW_EXC));
    }
cleanup:
    LW_HANDLE(&inner);
    DJFreeDistroInfo(&distro);
}
Example #9
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;
}
Example #10
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;
}
Example #11
0
DWORD
ReadNsswitchConf(NsswitchConf *conf, const char *testPrefix,
        BOOLEAN allowFileCreate)
{
    PSTR copyDestPath = NULL;
    PSTR defaultFilePath = NULL;
    DWORD ceError = ERROR_SUCCESS;
    BOOLEAN bFileExists = FALSE;
    LwDistroInfo distro = {0};

    memset(conf, 0, sizeof(*conf));

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

    //Keep trying to read different filenames until one of them is found
    if(!bFileExists)
    {
	    if(distro.os == OS_SUNOS)
		{
			if(strcmp("5.11", distro.version) == 0)
			{
				// Solaris 11 and above use SMF for nsswitch configuration.
				// When in Automatic mode, by default Solaris 11.x uses the /etc/nsswitch.dns
				// as a template.
				bFileExists = TRUE;
				ceError = ReadNsswitchFile(conf, testPrefix, "/etc/nsswitch.dns");
				if(ceError == ERROR_FILE_NOT_FOUND)
				{
					bFileExists = FALSE;
					ceError = ERROR_SUCCESS;
				}
				GCE(ceError);
			}
		}
	}
	
    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);
    DJFreeDistroInfo(&distro);

    return ceError;
}