Example #1
0
const char *GetNameOfHostsByDns(const NsswitchConf *conf, const DistroInfo *distro)
{
    int line = FindEntry(conf, 0, "hosts");

    if (FindModuleOnLine(conf, line, "dns") != -1)
        return "dns";

    if (FindModuleOnLine(conf, line, "bind") != -1)
        return "bind";

    if(distro->os == OS_AIX)
        return "bind";
    else
        return "dns";
}
Example #2
0
const char *GetNameOfHostsByFile(const NsswitchConf *conf, const DistroInfo *distro)
{
    int line = FindEntry(conf, 0, "hosts");

    if (FindModuleOnLine(conf, line, "local") != -1)
        return "local";

    if (FindModuleOnLine(conf, line, "files") != -1)
        return "files";

    if(distro->os == OS_AIX)
        return "local";
    else
        return "files";
}
Example #3
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 #4
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 #5
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 #6
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;
}