Exemple #1
0
DWORD
DJSetComputerNameEx(
    PCSTR pszComputerName
    )
{
    DWORD dwError = 0;
    LWException *exc = NULL;
    HANDLE hLsaConnection = NULL;

    LW_TRY(&exc, DJSetComputerName(pszComputerName, NULL, &LW_EXC));

    LW_CLEANUP_CTERR(&exc, LsaOpenServer(&hLsaConnection));

    LW_CLEANUP_CTERR(&exc, LsaSetMachineName(hLsaConnection, pszComputerName));

cleanup:

    if (hLsaConnection)
    {
        LsaCloseServer(hLsaConnection);
    }

    if (!LW_IS_OK(exc))
    {
        dwError = exc->code;
        LWHandle(&exc);
    }

    return dwError;
}
void
DJManageDaemonsDescription(
    BOOLEAN bStart,
    PSTR *description,
    LWException **exc
    )
{
    BOOLEAN bFileExists = TRUE;
    LWException *innerExc = NULL;
    StringBuffer buffer;
    PSTR daemonDescription = NULL;

    LW_CLEANUP_CTERR(exc, CTStringBufferConstruct(&buffer));

    LW_CLEANUP_CTERR(exc, CTCheckFileExists(PWGRD, &bFileExists));
    if(bFileExists && bStart)
    {
        LW_CLEANUP_CTERR(exc, CTStringBufferAppend(&buffer, "Shutdown pwgrd because it only handles usernames up to 8 characters long. This is done by running '/sbin/init.d/pwgr stop' and setting PWGR=0 in "PWGRD"."));
    }

    *description = CTStringBufferFreeze(&buffer);

cleanup:
    CT_SAFE_FREE_STRING(daemonDescription);
    LW_HANDLE(&innerExc);
    CTStringBufferDestroy(&buffer);
}
static void DoDSPlugin(JoinProcessOptions *options, LWException **exc)
{
    if(options->joiningDomain)
        LW_CLEANUP_CTERR(exc, DJConfigureDSPlugin());
    else
        LW_CLEANUP_CTERR(exc, DJUnconfigureDSPlugin());
cleanup:
    ;
}
static void DoPamMode(JoinProcessOptions *options, LWException **exc)
{
    if(options->joiningDomain)
    {
        LW_CLEANUP_CTERR(exc, DJAddMissingAIXServices(NULL));
        LW_CLEANUP_CTERR(exc, DJFixLoginConfigFile(NULL));
    }
cleanup:
    ;
}
Exemple #5
0
DWORD
DJJoinDomain(
    PCSTR pszDomain,
    PCSTR pszOU,
    PCSTR pszUsername,
    PCSTR pszPassword
    )
{
    DWORD dwError = 0;
    LWException *exc = NULL; 
    JoinProcessOptions options;

    DJZeroJoinProcessOptions(&options);
    options.joiningDomain = TRUE;

    if (IsNullOrEmptyString(pszDomain))
    {
        LW_RAISE(&exc, ERROR_INVALID_PARAMETER);
    }

    LW_CLEANUP_CTERR(&exc, CTStrdup(pszDomain, &options.domainName));

    if (!IsNullOrEmptyString(pszOU))
    {
        LW_CLEANUP_CTERR(&exc, CTStrdup(pszOU, &options.ouName));
    }

    if (!IsNullOrEmptyString(pszUsername))
    {
        LW_CLEANUP_CTERR(&exc, CTStrdup(pszUsername, &options.username));
    }

    if (!IsNullOrEmptyString(pszPassword))
    {
        LW_CLEANUP_CTERR(&exc, CTStrdup(pszPassword, &options.password));
    }

    LW_CLEANUP_CTERR(&exc, DJGetComputerName(&options.computerName));

    LW_TRY(&exc, DJInitModuleStates(&options, &LW_EXC));

    LW_TRY(&exc, DJRunJoinProcess(&options, &LW_EXC));

cleanup:

    DJFreeJoinProcessOptions(&options);

    if (!LW_IS_OK(exc))
    {
        dwError = exc->code;
        LWHandle(&exc);
    }

    return dwError;
}
Exemple #6
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);
}
Exemple #7
0
static void DoSetHostname(JoinProcessOptions *options, LWException **exc)
{
    LWException *inner = NULL;
    DWORD ceError;

    LW_TRY(exc,
        DJSetComputerName(options->computerName,
            options->domainName, &LW_EXC));

#ifndef ENABLE_MINIMAL
    ceError = DJConfigureHostsEntry(NULL);
    if(ceError == ERROR_FILE_NOT_FOUND)
    {
        ceError = ERROR_SUCCESS;
#if !defined(__LWI_DARWIN__)
        DJ_LOG_WARNING("Warning: Could not find nsswitch file");
#endif
    }
    LW_CLEANUP_CTERR(exc, ceError);
#endif

#ifndef ENABLE_MINIMAL
    DJRestartIfRunning("nscd", &inner);
    if(!LW_IS_OK(inner) && inner->code == ERROR_FILE_NOT_FOUND)
        LW_HANDLE(&inner);
    LW_CLEANUP(exc, inner);
#endif

cleanup:
    LW_HANDLE(&inner);
}
Exemple #8
0
void PrintJoinHeader(const JoinProcessOptions *options, LWException **exc)
{
    PSTR fqdn = NULL;
    PDOMAINJOININFO pDomainJoinInfo = NULL;
    PCSTR domain;

    if(options->joiningDomain)
    {
        LW_CLEANUP_CTERR(exc, DJGetFinalFqdn(options, &fqdn));
        fprintf(stdout,
                "Joining to AD Domain:   %s\n"
                "With Computer DNS Name: %s\n\n",
                options->domainName,
                fqdn);
    }
    else
    {
        if (options->domainName)
        {
            domain = options->domainName;
        }
        else
        {
            LW_TRY(exc, QueryInformation(&pDomainJoinInfo, &LW_EXC));
            domain = pDomainJoinInfo->pszDomainName;
        }
        if(domain == NULL)
            domain = "(unknown)";
        fprintf(stdout, "Leaving AD Domain:   %s\n", domain);
    }

cleanup:
    CT_SAFE_FREE_STRING(fqdn);
}
static PSTR GetDSPluginDescription(const JoinProcessOptions *options, LWException **exc)
{
    PSTR ret = NULL;
    if(options->joiningDomain)
    {
        LW_CLEANUP_CTERR(exc, CTStrdup(
                    "The Likewise Directory Services plugin will be enabled by adding it to the custom search path and switching the search policy to custom.",
                    &ret));
    }
    else
    {
        LW_CLEANUP_CTERR(exc, CTStrdup(
                    "The Likewise Directory Services plugin will removed from the custom search path and and the search policy will be switched back to standard.",
                    &ret));
    }

cleanup:
    return ret;
}
Exemple #10
0
void
DJQuery(
    char **computer, 
    char **domain,
    DJOptions* options,
    LWException** exc
    )
{
    PDOMAINJOININFO info = NULL;

    LW_TRY(exc, QueryInformation(&info, &LW_EXC));
    
    if (info->pszName)
    {
	LW_CLEANUP_CTERR(exc,
			 CTAllocateString(info->pszName, computer));
    }
    else
    {
	*computer = NULL;
    }

    if (info->pszDomainName)
    {
	LW_CLEANUP_CTERR(exc,
			 CTAllocateString(info->pszDomainName, domain));
    }
    else
    {
	*domain = NULL;
    }
    
cleanup:
    
    if (info)
    {
	FreeDomainJoinInfo(info);
    }
}
static PSTR GetPamModeDescription(const JoinProcessOptions *options, LWException **exc)
{
    PSTR ret = NULL;
    LW_CLEANUP_CTERR(exc, CTAllocateStringPrintf( &ret,
"By default AIX will use LAM to perform authentication requests, but AIX 5.3 may instead use PAM for authentication. PAM allows for richer text in prompts and error messages, so it is recommended that the system be switched into PAM mode. This will be done by setting 'auth_type = PAM_AUTH' in the 'usw' stanza in /etc/security/login.cfg.\n"
"\n"
"A few of the programs that ship with AIX are not enabled in the default pam.conf. Before switching the system into PAM mode, entries are made in pam.conf for these services:"
"\tsshd\n"
"\tsudo\n"
"\tdtsession"));

cleanup:
    return ret;
}
Exemple #12
0
DWORD
DJInit(
    VOID
    )
{
    DWORD dwError = 0;
    LWException *exc = NULL; 

    setlocale(LC_ALL, "");

    LW_CLEANUP_CTERR(&exc, dj_disable_logging());

cleanup:

    if (!LW_IS_OK(exc))
    {
        dwError = exc->code;
        LWHandle(&exc);
    }

    return dwError;
}
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;
}
static QueryResult QueryNsswitch(const JoinProcessOptions *options, LWException **exc)
{
    QueryResult result = FullyConfigured;
    BOOLEAN configured;
    BOOLEAN exists;
    BOOLEAN hasBadSeLinux;
    NsswitchConf conf;
    DWORD ceError = ERROR_SUCCESS;
    uid_t uid = 0;
    gid_t gid = 0;
    mode_t mode = 0;

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

    if (options->enableMultipleJoins)
    {
        result = NotApplicable;
        goto cleanup;
    }

    if (options->joiningDomain)
    {
        ceError = ReadNsswitchConf(&conf, NULL, FALSE);
        if(ceError == ERROR_FILE_NOT_FOUND)
        {
            ceError = ERROR_SUCCESS;
            DJ_LOG_WARNING("Warning: Could not find nsswitch file");
            goto cleanup;
        }
        LW_CLEANUP_CTERR(exc, ceError);

        LW_TRY(exc, result = RemoveCompat(&conf, NULL, &LW_EXC));
        if(result == CannotConfigure || result == NotConfigured)
        {
            goto cleanup;
        }

        LW_CLEANUP_CTERR(exc, CTGetOwnerAndPermissions(
            conf.filename, &uid, &gid, &mode));

        if ((mode & 0444) != 0444)
        {
            // The user has to fix the permissions
            result = CannotConfigure;
            goto cleanup;
        }

        LW_CLEANUP_CTERR(exc, UpdateNsswitchConf(&conf, TRUE));
        if(conf.modified)
        {
            LW_CLEANUP_CTERR(exc, UnsupportedSeLinuxEnabled(&hasBadSeLinux));
            if(hasBadSeLinux)
                result = CannotConfigure;
            else
                result = NotConfigured;
            goto cleanup;
        }

        LW_CLEANUP_CTERR(exc, DJHasMethodsCfg(&exists));

        if(exists)
        {
            LW_CLEANUP_CTERR(exc, DJIsMethodsCfgConfigured(&configured));

            if(!configured)
            {
                result = NotConfigured;
                goto cleanup;
            }
        }

        LW_CLEANUP_CTERR(exc, IsApparmorConfigured(&configured));

        if(!configured)
        {
            result = NotConfigured;
            goto cleanup;
        }
    }
    else
    {
        LW_CLEANUP_CTERR(exc, DJHasMethodsCfg(&exists));

        if(exists)
        {
            LW_CLEANUP_CTERR(exc, DJIsMethodsCfgConfigured(&configured));

            if(configured)
            {
                result = NotConfigured;
                goto cleanup;
            }
        }
    }

cleanup:

    FreeNsswitchConfContents(&conf);

    return result;
}
Exemple #15
0
void DoLeaveNew(int argc, char **argv, int columns, LWException **exc)
{
    JoinProcessOptions options;
    BOOLEAN advanced = FALSE;
    BOOLEAN preview = FALSE;
    DynamicArray enableModules, disableModules, ignoreModules;
    DynamicArray detailModules;
    size_t i;
    PSTR moduleDetails = NULL;
    PSTR wrapped = NULL;
    int passwordIndex = -1;

    DJZeroJoinProcessOptions(&options);
    memset(&enableModules, 0, sizeof(enableModules));
    memset(&disableModules, 0, sizeof(disableModules));
    memset(&ignoreModules, 0, sizeof(ignoreModules));
    memset(&detailModules, 0, sizeof(detailModules));

    while(argc > 0 && CTStrStartsWith(argv[0], "--"))
    {
        if(!strcmp(argv[0], "--advanced"))
            advanced = TRUE;
        else if(!strcmp(argv[0], "--preview"))
            preview = TRUE;
        else if(argc < 2)
        {
            LW_RAISE(exc, LW_ERROR_SHOW_USAGE);
            goto cleanup;
        }
        else if(!strcmp(argv[0], "--enable"))
        {
            LW_CLEANUP_CTERR(exc, CTArrayAppend(&enableModules, sizeof(PCSTR *), &argv[1], 1));
            argv++;
            argc--;
        }
        else if(!strcmp(argv[0], "--disable"))
        {
            if(!strcmp(argv[1], "ssh")){
                options.ignoreSsh = TRUE;
            }
            else {
                options.ignoreSsh = FALSE;
                LW_CLEANUP_CTERR(exc, CTArrayAppend(&disableModules, sizeof(PCSTR *), &argv[1], 1));
            }
            argv++;
            argc--;
        }
        else if(!strcmp(argv[0], "--ignore"))
        {
            LW_CLEANUP_CTERR(exc, CTArrayAppend(&ignoreModules, sizeof(PCSTR *), &argv[1], 1));
            argv++;
            argc--;
        }
        else if(!strcmp(argv[0], "--details"))
        {
            LW_CLEANUP_CTERR(exc, CTArrayAppend(&detailModules, sizeof(PCSTR *), &argv[1], 1));
            argv++;
            argc--;
        }
        else if(!strcmp(argv[0], "--multiple"))
        {
            options.enableMultipleJoins = TRUE;
            LW_CLEANUP_CTERR(exc, CTStrdup(argv[1], &options.domainName));
            argv++;
            argc--;
        }
        else
        {
            LW_RAISE(exc, LW_ERROR_SHOW_USAGE);
            goto cleanup;
        }
        argv++;
        argc--;
    }

    if(argc == 2)
    {
        LW_CLEANUP_CTERR(exc, CTStrdup(argv[1], &options.password));
        passwordIndex = 1;
    }
    else if(argc > 2)
    {
        LW_RAISE(exc, LW_ERROR_SHOW_USAGE);
        goto cleanup;
    }
    options.joiningDomain = FALSE;

    DJ_LOG_INFO("Domainjoin invoked with %d arg(s) to the leave command:", argc);
    for(i = 0; i < argc; i++)
    {
        DJ_LOG_INFO("    [%s]", i == passwordIndex ? "<password>" : argv[i]);
    }

    if(argc > 0)
    {
        LW_CLEANUP_CTERR(exc, CTStrdup(argv[0], &options.username));
    }

    options.warningCallback = PrintWarning;
    options.showTraces = advanced;
    LW_CLEANUP_CTERR(exc, DJGetComputerName(&options.computerName));

    LW_TRY(exc, DJInitModuleStates(&options, &LW_EXC));

    for(i = 0; i < enableModules.size; i++)
    {
        PCSTR module = *(PCSTR *)CTArrayGetItem(
                    &enableModules, i, sizeof(PCSTR));
        if(CTArrayFindString(&disableModules, module) != -1)
        {
            LW_RAISE_EX(exc, ERROR_INVALID_PARAMETER, "Module already specified", "The module '%s' is listed as being disabled and enabled", module);
            goto cleanup;
        }
        if(CTArrayFindString(&ignoreModules, module) != -1)
        {
            LW_RAISE_EX(exc, ERROR_INVALID_PARAMETER, "Module already specified", "The module '%s' is listed as being ignored and enabled", module);
            goto cleanup;
        }
        LW_TRY(exc, DJSetModuleDisposition(&options, module, EnableModule, &LW_EXC));
    }

    for(i = 0; i < disableModules.size; i++)
    {
        PCSTR module = *(PCSTR *)CTArrayGetItem(
                    &disableModules, i, sizeof(PCSTR));
        if(CTArrayFindString(&enableModules, module) != -1)
        {
            LW_RAISE_EX(exc, ERROR_INVALID_PARAMETER, "Module already specified", "The module '%s' is listed as being disabled and enabled", module);
            goto cleanup;
        }
        if(CTArrayFindString(&ignoreModules, module) != -1)
        {
            LW_RAISE_EX(exc, ERROR_INVALID_PARAMETER, "Module already specified", "The module '%s' is listed as being disabled and ignored", module);
            goto cleanup;
        }
        LW_TRY(exc, DJSetModuleDisposition(&options, module, DisableModule, &LW_EXC));
    }

    for(i = 0; i < ignoreModules.size; i++)
    {
        PCSTR module = *(PCSTR *)CTArrayGetItem(
                    &ignoreModules, i, sizeof(PCSTR));
        if(CTArrayFindString(&enableModules, module) != -1)
        {
            LW_RAISE_EX(exc, ERROR_INVALID_PARAMETER, "Module already specified", "The module '%s' is listed as being ignored and enabled", module);
            goto cleanup;
        }
        if(CTArrayFindString(&disableModules, module) != -1)
        {
            LW_RAISE_EX(exc, ERROR_INVALID_PARAMETER, "Module already specified", "The module '%s' is listed as being ignored and disabled", module);
            goto cleanup;
        }
        LW_TRY(exc, DJSetModuleDisposition(&options, module, IgnoreModule, &LW_EXC));
    }

    for(i = 0; i < detailModules.size; i++)
    {
        PCSTR module = *(PCSTR *)CTArrayGetItem(
                    &detailModules, i, sizeof(PCSTR));
        ModuleState *state = DJGetModuleStateByName(&options, module);
        if(state == NULL)
        {
            LW_RAISE_EX(exc, ERROR_INVALID_PARAMETER, "Unable to find module.", "Please check the spelling of '%s'. This module cannot be found", module);
            goto cleanup;
        }
        PrintModuleState(state);
    }
    if(detailModules.size > 0)
    {
        PrintStateKey();
    }
    for(i = 0; i < detailModules.size; i++)
    {
        PCSTR module = *(PCSTR *)CTArrayGetItem(
                    &detailModules, i, sizeof(PCSTR));
        ModuleState *state = DJGetModuleStateByName(&options, module);
        CT_SAFE_FREE_STRING(moduleDetails);
        CT_SAFE_FREE_STRING(wrapped);
        LW_TRY(exc, moduleDetails = state->module->GetChangeDescription(&options, &LW_EXC));
        LW_CLEANUP_CTERR(exc, CTWordWrap(moduleDetails, &wrapped, 4, columns));
        fprintf(stdout, "\nDetails for '%s':\n%s\n", state->module->longName, wrapped);
    }
    if(detailModules.size > 0)
        goto cleanup;

    LW_TRY(exc, PrintJoinHeader(&options, &LW_EXC));

    if(preview)
    {
        PrintModuleStates(advanced, &options);
        if(!advanced)
            LW_TRY(exc, DJCheckRequiredEnabled(&options, &LW_EXC));
        goto cleanup;
    }

    LW_TRY(exc, DJCheckRequiredEnabled(&options, &LW_EXC));

    if (options.username != NULL && IsNullOrEmptyString(options.password))
    {
        CT_SAFE_FREE_STRING(options.password);

        LW_CLEANUP_CTERR(exc, FillMissingPassword(options.username,
                    &options.password));
    }

    LW_TRY(exc, DJRunJoinProcess(&options, &LW_EXC));
    fprintf(stdout, "SUCCESS\n");

cleanup:
    DJFreeJoinProcessOptions(&options);
    CTArrayFree(&enableModules);
    CTArrayFree(&disableModules);
    CTArrayFree(&ignoreModules);
    CTArrayFree(&detailModules);
    CT_SAFE_FREE_STRING(moduleDetails);
    CT_SAFE_FREE_STRING(wrapped);
}
Exemple #16
0
static
void
FixNetworkInterfaces(
    PSTR pszComputerName,
    LWException **exc
    )
{
    DWORD ceError = ERROR_SUCCESS;
    int EE = 0;
    BOOLEAN bFileExists = FALSE;
    BOOLEAN bDirExists = FALSE;
    PSTR* ppszPaths = NULL;
    DWORD nPaths = 0;
    DWORD iPath = 0;
    CHAR szBuf[1024];
    PSTR pszPathifcfg = NULL;
    BOOLEAN bDHCPHost = FALSE;
    PSTR pszMachineSID = NULL;
    PCSTR networkConfigPath = "/etc/sysconfig/network";

    LW_CLEANUP_CTERR(exc, DJGetMachineSID(&pszMachineSID));

    /*
     * fixup HOSTNAME variable in /etc/sysconfig/network file if it exists
     * note that 'network' is a *directory* on some dists (ie SUSE),
     * is a *file* on others (ie Redhat). weird.
     */
    LW_CLEANUP_CTERR(exc, CTCheckFileExists(networkConfigPath, &bFileExists));

    if (bFileExists) {
        sprintf(szBuf, "s/^.*\\(HOSTNAME\\).*=.*$/\\1=%s/", pszComputerName);
        LW_CLEANUP_CTERR(exc, CTRunSedOnFile(networkConfigPath, networkConfigPath,
                FALSE, szBuf));
    }

    LW_CLEANUP_CTERR(exc, CTCheckDirectoryExists("/etc/sysconfig/network", &bDirExists));
    if (!bDirExists)
    {
        LW_CLEANUP_CTERR(exc, CTCheckDirectoryExists("/etc/sysconfig/network-scripts", &bDirExists));
    }

    if (bDirExists) {

        struct
        {
            PCSTR dir;
            PCSTR glob;
        } const searchPaths[] = {
            {"/etc/sysconfig/network", "ifcfg-eth-id-[^.]*$"},
            {"/etc/sysconfig/network", "ifcfg-eth0[^.]*$"},
            {"/etc/sysconfig/network", "ifcfg-eth[^.]*$"},
            {"/etc/sysconfig/network", "ifcfg-eth-bus[^.]*$"},
            //SLES 10.1 on zSeries uses one of:
            //  /etc/sysconfig/network/ifcfg-qeth-bus-ccw-0.0.0500
            //  /etc/sysconfig/network/ifcfg-ctc-bus-ccw-0.0.0004
            {"/etc/sysconfig/network", "ifcfg-qeth-bus.*\\.[0-9]\\+$"},
            {"/etc/sysconfig/network", "ifcfg-ctc-bus.*\\.[0-9]\\+$"},
            // Redhat uses /etc/sysconfig/network-scripts/ifcfg-eth<number>
            {"/etc/sysconfig/network-scripts", "ifcfg-eth[^.]*$"},
            // RHEL 6 uses this
            {"/etc/sysconfig/network-scripts", "ifcfg-Auto_eth[^.]*$"},
            // ESX 3.5 and 4.0 use
            // /etc/sysconfig/network-scripts/ifcfg-vswif<number>
            {"/etc/sysconfig/network-scripts", "ifcfg-vswif[^.]*$"},
            // RHEL 7: network interface naming seems to be ensXX or enoXXXX, etc.
            {"/etc/sysconfig/network-scripts", "ifcfg-en[^.]*$"},
            {NULL, NULL}
        };

        // Find the ifcfg file
        pszPathifcfg = NULL;

        for(iPath = 0; searchPaths[iPath].dir != NULL && pszPathifcfg == NULL; iPath++)
        {
            if (ppszPaths)
            {
                CTFreeStringArray(ppszPaths, nPaths);
                ppszPaths = NULL;
            }

            ceError = CTGetMatchingFilePathsInFolder(searchPaths[iPath].dir,
                                                         searchPaths[iPath].glob,
                                                         &ppszPaths,
                                                         &nPaths);
            if(ceError == ERROR_DIRECTORY)
            {
                ceError = ERROR_SUCCESS;
                continue;
            }
            LW_CLEANUP_CTERR(exc, ceError);

            if(nPaths > 0)
            {
                LW_CLEANUP_CTERR(exc, CTAllocateString(ppszPaths[0], &pszPathifcfg));
            }
        }

        if (IsNullOrEmptyString(pszPathifcfg)) {
            LW_CLEANUP_CTERR(exc, ERROR_FILE_NOT_FOUND);
        }

        DJ_LOG_INFO("Found ifcfg file at %s", pszPathifcfg);

        LW_CLEANUP_CTERR(exc, DJCheckIfDHCPHost(pszPathifcfg, &bDHCPHost));

        if (bDHCPHost) {
            LW_CLEANUP_CTERR(exc, DJFixDHCPHost(pszPathifcfg, pszComputerName));
        }
    }

    ceError = CTShell("/bin/hostname %hostname >/dev/null",
            CTSHELL_STRING(hostname, pszComputerName));

    LW_CLEANUP_CTERR(exc, ceError);

    // Only DHCP boxes need to restart their networks
    if (bDHCPHost) {
        LW_CLEANUP_CTERR(exc, DJConfigureDHCPService(pszComputerName));
    }

cleanup:

    // This ensures that we do not change the SID after a machine name
    // change.  The issue here is that Samba implements its SAM such that
    // a machine name change changes the seeding used for the machine SID.
    // Therefore, we must re-store the old SID with the new machine name
    // seed.
    if (pszMachineSID) {
        if (*pszMachineSID != '\0')
            DJSetMachineSID(pszMachineSID);
        CTFreeString(pszMachineSID);
    }

    if (ppszPaths)
        CTFreeStringArray(ppszPaths, nPaths);

    if (pszPathifcfg)
        CTFreeString(pszPathifcfg);

    DJ_LOG_VERBOSE("FixNetworkInterfaces LEAVE -> 0x%08x (EE = %d)", ceError, EE);
}
Exemple #17
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);
}
Exemple #18
0
void DoConfigure(int argc, char **argv, LWException **exc)
{
    EnableType dwEnable = ENABLE_TYPE_AUTO;
    PCSTR testPrefix = NULL;
    PCSTR longDomain = NULL;
    PCSTR shortDomain = NULL;
    JoinProcessOptions options = { 0 };

    while(argc > 0 && CTStrStartsWith(argv[0], "--"))
    {
        if(!strcmp(argv[0], "--autoenable"))
            dwEnable = ENABLE_TYPE_AUTO;
        else if(!strcmp(argv[0], "--enable"))
            dwEnable = ENABLE_TYPE_ENABLE;
        else if(!strcmp(argv[0], "--disable"))
            dwEnable = ENABLE_TYPE_DISABLE;
        else if(argc < 2)
        {
            LW_RAISE(exc, LW_ERROR_SHOW_USAGE);
            goto cleanup;
        }
        else if(!strcmp(argv[0], "--testprefix"))
        {
            testPrefix = argv[1];
            argv++;
            argc--;
        }
        else if(!strcmp(argv[0], "--long"))
        {
            longDomain = argv[1];
            argv++;
            argc--;
        }
        else if(!strcmp(argv[0], "--short"))
        {
            shortDomain = argv[1];
            argv++;
            argc--;
        }
        else
        {
            LW_RAISE(exc, LW_ERROR_SHOW_USAGE);
            goto cleanup;
        }
        argv++;
        argc--;
    }

    if(argc < 1)
    {
        LW_RAISE(exc, LW_ERROR_SHOW_USAGE);
        goto cleanup;
    }

    options.joiningDomain = GetEnableBoolean(dwEnable);
    options.warningCallback = PrintWarning;

    if(!strcmp(argv[0], "pam"))
        LW_TRY(exc, DJNewConfigurePamForADLogin(testPrefix, NULL, PrintWarning, GetEnableBoolean(dwEnable), &LW_EXC));
    else if(!strcmp(argv[0], "nsswitch"))
    {
        LW_TRY(exc, DoNsswitch(&options, &LW_EXC));
    }
    else if(!strcmp(argv[0], "ssh"))
        LW_TRY(exc, DJConfigureSshForADLogin(GetEnableBoolean(dwEnable), NULL, &LW_EXC));
    else if(!strcmp(argv[0], "krb5"))
        LW_CLEANUP_CTERR(exc, DJModifyKrb5Conf(testPrefix,
            GetEnableBoolean(dwEnable), longDomain, shortDomain, NULL, NULL));
    else if(!strcmp(argv[0], "eventfwdd"))
        LW_CLEANUP_CTERR(exc, DJConfigureEventFwd(testPrefix, GetEnableBoolean(dwEnable)));
    else if(!strcmp(argv[0], "reapsysld"))
        LW_CLEANUP_CTERR(exc, DJConfigureReapSyslog(testPrefix, GetEnableBoolean(dwEnable)));
    else
    {
        LW_RAISE(exc, LW_ERROR_SHOW_USAGE);
        goto cleanup;
    }
    fprintf(stdout, "SUCCESS\n");
cleanup:
    ;
}
Exemple #19
0
static QueryResult QueryDescriptionSetHostname(const JoinProcessOptions *options, PSTR *changeDescription, LWException **exc)
{
    PSTR required = NULL;
    PSTR optional = NULL;
    PSTR both = NULL;
    PSTR newFqdn = NULL;
    PSTR oldShortHostname = NULL;
    PSTR oldFqdnHostname = NULL;
    PSTR newValue;
    PHOSTSFILELINE pHostsFileLineList = NULL;
    BOOLEAN describedFqdn = FALSE;
    QueryResult result = CannotConfigure;
    BOOLEAN modified = FALSE;
    DWORD ceError = ERROR_SUCCESS;

    if(!options->joiningDomain || options->enableMultipleJoins)
    {
        if(changeDescription != NULL)
        {
            LW_CLEANUP_CTERR(exc, CTAllocateStringPrintf(changeDescription,
                "The hostname is fully set"));
        }
        result = NotApplicable;
        goto cleanup;
    }

    //Throws an exception if the hostname is not valid
    LW_TRY(exc, DJCheckValidComputerName(options->computerName, &LW_EXC));

    LW_CLEANUP_CTERR(exc, CTStrdup("", &required));
    LW_CLEANUP_CTERR(exc, CTStrdup("", &optional));
//    LW_CLEANUP_CTERR(exc, CTStrdup("", &both));

    LW_CLEANUP_CTERR(exc, DJGetFQDN(&oldShortHostname, &oldFqdnHostname));
    CTStrToLower(oldShortHostname);
    CTStrToLower(oldFqdnHostname);
    if(strcasecmp(oldShortHostname, options->computerName))
    {
        LW_CLEANUP_CTERR(exc, CTAllocateStringPrintf(&newValue,
"%s\n"
"\tSet the computer short hostname (currently %s) to the requested hostname (%s) by setting:\n"
"\t\t* The kernel hostname\n"
"\t\t* The hostname in files for statically configured computers\n"
"\t\t* The hostname in files for DHCP configured computers",
            required, oldShortHostname, options->computerName));
        CT_SAFE_FREE_STRING(required);
        required = newValue;
    }

    LW_CLEANUP_CTERR(exc, CTAllocateStringPrintf(&newFqdn,
                "%s.%s", options->computerName,
            options->domainName));
    CTStrToLower(newFqdn);
    if(oldFqdnHostname == NULL)
    {
        LW_CLEANUP_CTERR(exc, CTAllocateStringPrintf(&newValue,
"%s\n"
"\tGive the machine a fully-qualified domain name. If performed automatically, the fqdn will be set through /etc/hosts to '%s', but it is possible to use a different fqdn and/or set it through dns instead of /etc/hosts. However in all cases, the fqdn must follow standard DNS naming conventions, and have a period in the name. The following steps will be used if the fqdn is set automatically:\n"
"\t\t* Make sure local comes before bind in nsswitch\n"
"\t\t* Add a loopback entry in /etc/hosts and put the fqdn as the primary name\n",
            required, newFqdn));
        CT_SAFE_FREE_STRING(required);
        required = newValue;
        describedFqdn = TRUE;
    }
    else if(strcmp(newFqdn, oldFqdnHostname))
    {
        //The current fqdn does not match our ideal fqdn
#if defined(__LWI_DARWIN__)
        LW_CLEANUP_CTERR(exc, CTAllocateStringPrintf(&newValue,
"%s\n"
"\tChange the fqdn from '%s' to '%s'. This could be done via DNS, but this program will do it with the following steps:\n"
"\t\t* Making sure local comes before bind in nsswitch\n"
"\t\t* Adding the fqdn before all entries in /etc/hosts that contain the short hostname and removing the old fqdn if it appears on the line\n"
"\t\t* Sending hang-up command to mDNSResponder to flush the DNS cache",
            optional, oldFqdnHostname, newFqdn));
#else
        LW_CLEANUP_CTERR(exc, CTAllocateStringPrintf(&newValue,
"%s\n"
"\tChange the fqdn from '%s' to '%s'. This could be done via DNS, but this program will do it with the following steps:\n"
"\t\t* Making sure local comes before bind in nsswitch\n"
"\t\t* Adding the fqdn before all entries in /etc/hosts that contain the short hostname and removing the old fqdn if it appears on the line\n"
"\t\t* Restart nscd (if running) to flush the DNS cache",
            optional, oldFqdnHostname, newFqdn));
#endif
        CT_SAFE_FREE_STRING(optional);
        optional = newValue;
        describedFqdn = TRUE;
    }

    //Find out if the fqdn is stored in /etc/hosts
    if(oldFqdnHostname != NULL && !strcmp(oldFqdnHostname, "localhost"))
    {
        CT_SAFE_FREE_STRING(oldFqdnHostname);
    }
    if(oldShortHostname != NULL && !strcmp(oldShortHostname, "localhost"))
    {
        CT_SAFE_FREE_STRING(oldShortHostname);
    }

    LW_CLEANUP_CTERR(exc, DJParseHostsFile("/etc/hosts", &pHostsFileLineList));
    LW_CLEANUP_CTERR(exc, DJReplaceHostnameInMemory(
                pHostsFileLineList,
                oldShortHostname, oldFqdnHostname,
                options->computerName, options->domainName));
    modified |= DJHostsFileWasModified(pHostsFileLineList);
    if (pHostsFileLineList)
    {
        DJFreeHostsFileLineList(pHostsFileLineList);
        pHostsFileLineList = NULL;
    }
    ceError = DJParseHostsFile("/etc/inet/ipnodes", &pHostsFileLineList);
    if(ceError == ERROR_FILE_NOT_FOUND)
    {
        ceError = ERROR_SUCCESS;
    }
    else if(!ceError)
    {
        LW_CLEANUP_CTERR(exc, DJReplaceHostnameInMemory(
                    pHostsFileLineList,
                    oldShortHostname, oldFqdnHostname,
                    options->computerName, options->domainName));
        modified |= DJHostsFileWasModified(pHostsFileLineList);
    }
    LW_CLEANUP_CTERR(exc, ceError);

    if (modified && !describedFqdn) {
        LW_CLEANUP_CTERR(exc, CTAllocateStringPrintf(&newValue,
"%s\n"
"\tSet the fqdn in /etc/hosts and /etc/inet/ipnodes. This will preserve the fqdn even when the DNS server is unreachable. This will be performed with these steps:\n"
"\t\t* Making sure local comes before bind in nsswitch\n"
"\t\t* Adding the fqdn before all entries in /etc/hosts and /etc/inet/ipnodes that contain the short hostname and removing the old fqdn if it appears on the line\n"
"\t\t* Restart nscd (if running) to flush the DNS cache"
        , optional, oldFqdnHostname, newFqdn));
        CT_SAFE_FREE_STRING(optional);
        optional = newValue;
        describedFqdn = TRUE;
    }

    if(strlen(required) > 1)
    {
        if(strlen(optional) > 1)
        {
            LW_CLEANUP_CTERR(exc, CTAllocateStringPrintf(&both,
"The following step(s) are required:%s\n\nThe following step(s) are optional (but will performed automatically when this step is run):%s", required, optional));
        }
        else
        {
            LW_CLEANUP_CTERR(exc, CTAllocateStringPrintf(&both,
"The following step(s) are required:%s", required));
        }
        result = NotConfigured;
    }
    else if(strlen(optional) > 1)
    {
        LW_CLEANUP_CTERR(exc, CTAllocateStringPrintf(&both,
"The following step(s) are optional:%s", optional));
        result = SufficientlyConfigured;
    }
    else
    {
        LW_CLEANUP_CTERR(exc, CTAllocateStringPrintf(&both,
"The hostname is fully set"));
        result = FullyConfigured;
    }

    if(changeDescription != NULL)
    {
        *changeDescription = both;
        both = NULL;
    }

cleanup:
    CT_SAFE_FREE_STRING(required);
    CT_SAFE_FREE_STRING(optional);
    CT_SAFE_FREE_STRING(both);
    CT_SAFE_FREE_STRING(oldShortHostname);
    CT_SAFE_FREE_STRING(oldFqdnHostname);
    CT_SAFE_FREE_STRING(newFqdn);
    if (pHostsFileLineList)
        DJFreeHostsFileLineList(pHostsFileLineList);

    return result;
}
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);
}
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;
}
static PSTR GetNsswitchDescription(const JoinProcessOptions *options, LWException **exc)
{
    PSTR ret = NULL;
    PCSTR configureSteps;
    BOOLEAN hasBadSeLinux;
    QueryResult compatResult = FullyConfigured;
    PSTR compatDescription = NULL;
    NsswitchConf conf;
    DWORD ceError = ERROR_SUCCESS;

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

    LW_CLEANUP_CTERR(exc, UnsupportedSeLinuxEnabled(&hasBadSeLinux));
    if(hasBadSeLinux)
    {
        LW_CLEANUP_CTERR(exc, CTAllocateStringPrintf(&ret,
"Your machine is using an unsupported SeLinux policy. This must be disabled before nsswitch can be modified to allow active directory users. Please run '/usr/sbin/setenforce Permissive' and then re-run this program."));
        goto cleanup;
    }

    ceError = ReadNsswitchConf(&conf, "", TRUE);
    if(ceError == ERROR_FILE_NOT_FOUND)
    {
        ceError = ERROR_SUCCESS;
        if (options->warningCallback != NULL)
        {
            options->warningCallback(options, "Could not find file", "Could not find nsswitch file");
        }
        goto cleanup;
    }
    LW_CLEANUP_CTERR(exc, ceError);

    if(options->joiningDomain)
    {
        LW_TRY(exc, compatResult = RemoveCompat(&conf, &compatDescription, &LW_EXC));
    }
    if(compatResult == FullyConfigured)
    {
        CT_SAFE_FREE_STRING(compatDescription);
        LW_CLEANUP_CTERR(exc, CTStrdup("", &compatDescription));
    }

    if (options->joiningDomain)
    {
        uid_t uid = 0;
        gid_t gid = 0;
        mode_t mode = 0;
        LW_CLEANUP_CTERR(exc, CTGetOwnerAndPermissions(
            conf.filename, &uid, &gid, &mode));

        if ((mode & 0444) != 0444)
        {
            LW_CLEANUP_CTERR(exc, CTAllocateStringPrintf(&ret,
"The permissions of 0%03o on %s are invalid. All users must have at least read permission for the file. You can fix this by running 'chmod a+r %s'.", (int)(mode&0777), conf.filename, conf.filename));
            goto cleanup;
        }
    }

    conf.modified = FALSE;
    LW_CLEANUP_CTERR(exc, UpdateNsswitchConf(&conf, options->joiningDomain));

    if(options->joiningDomain && conf.modified)
        configureSteps = 
"The following steps are required and can be performed automatically:\n"
"\t* Edit nsswitch apparmor profile to allow libraries in the " PREFIXDIR "/lib  and " PREFIXDIR "/lib64 directories\n"
"\t* List lwidentity module in /usr/lib/security/methods.cfg (AIX only)\n"
"\t* Add lwidentity to passwd and group/groups line /etc/nsswitch.conf or /etc/netsvc.conf\n";
    else if(conf.modified)
        configureSteps = 
"The following steps are required and can be performed automatically:\n"
"\t* Remove lwidentity module from /usr/lib/security/methods.cfg (AIX only)\n"
"\t* Remove lwidentity from passwd and group/groups line /etc/nsswitch.conf or /etc/netsvc.conf\n"
"The following step is optional:\n"
"\t* Remove apparmor exception for likewise nsswitch libraries\n";
    else
        configureSteps = "";

    if(strlen(compatDescription) || strlen(configureSteps))
    {
        LW_CLEANUP_CTERR(exc, CTAllocateStringPrintf(&ret,
"%s%sIf any changes are performed, then the following services must be restarted:\n"
"\t* GDM\n"
"\t* XDM\n"
"\t* Cron\n"
"\t* Dbus\n"
"\t* Nscd", compatDescription, configureSteps));
    }
    else
        LW_CLEANUP_CTERR(exc, CTStrdup("Fully Configured", &ret));

cleanup:
    CT_SAFE_FREE_STRING(compatDescription);
    FreeNsswitchConfContents(&conf);
    return ret;
}
Exemple #23
0
int main(
    int argc,
    char* argv[]
    )
{
    LWException *exc = NULL;
    int columns;
    PSTR pszLogFilePath = NULL;
    BOOLEAN bNoLog = FALSE;
    PSTR logLevel = "warning";
    DWORD dwLogLevel;
    BOOLEAN showHelp = FALSE;
    BOOLEAN showInternalHelp = FALSE;
    int remainingArgs = argc;
    char **argPos = argv;
    int i;
    BOOLEAN directoryExists = FALSE;

    if(CTGetTerminalWidth(fileno(stdout), &columns))
        columns = -1;

    /* Skip the program name */
    argPos++;
    remainingArgs--;

    setlocale(LC_ALL, "");

    while(remainingArgs > 0 && CTStrStartsWith(argPos[0], "--"))
    {
        if(!strcmp(argPos[0], "--help"))
            showHelp = TRUE;
        else if(!strcmp(argPos[0], "--help-internal"))
            showInternalHelp = TRUE;
        else if(!strcmp(argPos[0], "--nolog"))
            bNoLog = TRUE;
        //All options after this point take an argument
        else if(remainingArgs < 2)
            showHelp = TRUE;
        else if(!strcmp(argPos[0], "--logfile"))
        {
            pszLogFilePath = (++argPos)[0];
            remainingArgs--;
        }
        else if(!strcmp(argPos[0], "--loglevel"))
        {
            logLevel = (++argPos)[0];
            remainingArgs--;
        }
        else
            break;
        remainingArgs--;
        argPos++;
    }

    if(remainingArgs < 1)
        showHelp = TRUE;

    if (showInternalHelp) {
        ShowUsageInternal();
        goto cleanup;
    }

    if (showHelp) {
        ShowUsage();
        goto cleanup;
    }

    if (!strcasecmp(logLevel, "error"))
    {
        dwLogLevel = LOG_LEVEL_ERROR;
        LwRtlLogSetLevel(LW_RTL_LOG_LEVEL_ERROR);
    }
    else if (!strcasecmp(logLevel, "warning"))
    {
        dwLogLevel = LOG_LEVEL_WARNING;
        LwRtlLogSetLevel(LW_RTL_LOG_LEVEL_WARNING);
    }
    else if (!strcasecmp(logLevel, "info"))
    {
        dwLogLevel = LOG_LEVEL_INFO;
        LwRtlLogSetLevel(LW_RTL_LOG_LEVEL_INFO);
    }
    else if (!strcasecmp(logLevel, "verbose"))
    {
        dwLogLevel = LOG_LEVEL_VERBOSE;
        LwRtlLogSetLevel(LW_RTL_LOG_LEVEL_VERBOSE);
    }
    else if (!strcasecmp(logLevel, "debug"))
    {
        dwLogLevel = LOG_LEVEL_VERBOSE;
        LwRtlLogSetLevel(LW_RTL_LOG_LEVEL_DEBUG);
    }
    else {
        LW_CLEANUP_CTERR(&exc, LW_ERROR_INVALID_LOG_LEVEL);
    }

    if (pszLogFilePath == NULL)
    {
        // Determine the default log path
        LW_CLEANUP_CTERR(&exc,
                CTCheckDirectoryExists("/var/log", &directoryExists));
        if (directoryExists)
        {
            pszLogFilePath = "/var/log/domainjoin-cli.log";
        }
        else
        {
            pszLogFilePath = "/var/adm/domainjoin-cli.log";
        }
    }

    if (bNoLog) {
        LW_CLEANUP_CTERR(&exc, dj_disable_logging());
    } else if (!strcmp(pszLogFilePath, ".")) {
        LW_CLEANUP_CTERR(&exc, dj_init_logging_to_console(dwLogLevel));
    } else {
        DWORD ceError = dj_init_logging_to_file(dwLogLevel, pszLogFilePath);
        if(ceError == ERROR_ACCESS_DENIED)
        {
            fprintf(stderr, "Warning: insufficient permissions to log to %s. To enable logging, please specify a different filename with --logfile <file>.\n",
                    pszLogFilePath);
            ceError = ERROR_SUCCESS;
            LW_CLEANUP_CTERR(&exc, dj_disable_logging());
        }
        else if (ceError == ERROR_FILE_NOT_FOUND)
        {
            fprintf(stderr, "Warning: parent directory of log file %s does not exist. To enable logging, please specify a different filename with --logfile <file>.\n",
                    pszLogFilePath);
            ceError = ERROR_SUCCESS;
            LW_CLEANUP_CTERR(&exc, dj_disable_logging());
        }
        LW_CLEANUP_CTERR(&exc, ceError);
    }
    LwRtlLogSetCallback(RtlLogCallback, NULL);

    if (!strcmp(argPos[0], "join") || !strcmp(argPos[0], "leave"))
    {
        DJ_LOG_INFO("Domainjoin invoked with the %s command (remaining arguments will be printed later):", argPos[0]);
        // Only print up to the 'join' part
        for (i = 0; i <= argPos - argv; i++)
        {
            DJ_LOG_INFO("    [%s]", argv[i]);
        }
    }
    else
    {
        DJ_LOG_INFO("Domainjoin invoked with %d arg(s):", argc);
        for (i = 0; i < argc; i++)
        {
            DJ_LOG_INFO("    [%s]", argv[i]);
        }
    }

    if(!strcmp(argPos[0], "setname"))
    {
        PSTR pDomainSuffix = 0;
        argPos++;
        if(--remainingArgs != 1)
        {
            ShowUsage();
            goto cleanup;
        }

        pDomainSuffix = strchr(argPos[0], '.');
        if (pDomainSuffix)
        {
            *pDomainSuffix = 0;
            pDomainSuffix++;
        }
        else
        {
            pDomainSuffix = "";
        }
        LW_TRY(&exc, DJSetComputerName(argPos[0], pDomainSuffix, &LW_EXC));
    }
    else if(!strcmp(argPos[0], "join"))
    {
        argPos++;
        remainingArgs--;
        LW_TRY(&exc, DoJoin(remainingArgs, argPos, columns, &LW_EXC));
    }
    else if(!strcmp(argPos[0], "leave"))
    {
        argPos++;
        remainingArgs--;
        LW_TRY(&exc, DoLeaveNew(remainingArgs, argPos, columns, &LW_EXC));
    }
    else if(!strcmp(argPos[0], "query"))
    {
        LW_TRY(&exc, DoQuery(&LW_EXC));
    }
    else if(!strcmp(argPos[0], "fixfqdn"))
        LW_TRY(&exc, DoFixFqdn(&LW_EXC));
#ifndef ENABLE_MINIMAL
    else if(!strcmp(argPos[0], "configure"))
    {
        argPos++;
        remainingArgs--;
        LW_TRY(&exc, DoConfigure(remainingArgs, argPos, &LW_EXC));
    }
#endif
    else if(!strcmp(argPos[0], "get_os_type") ||
        !strcmp(argPos[0], "get_arch") ||
        !strcmp(argPos[0], "get_distro") ||
        !strcmp(argPos[0], "get_distro_version"))
    {
        LW_TRY(&exc, DoGetDistroInfo(remainingArgs, argPos, &LW_EXC));
    }
    else
    {
        LW_RAISE(&exc, LW_ERROR_SHOW_USAGE);
        goto cleanup;
    }

cleanup:

    if (!LW_IS_OK(exc) && exc->code == LW_ERROR_SHOW_USAGE)
    {
        ShowUsage();
        LWHandle(&exc);
    }
    else if (!LW_IS_OK(exc))
    {
        //Ignoring the return value from this because we can't do anything
        //if there is an error
        fprintf(stdout, "\n");
        LWPrintException(stdout, exc, FALSE);
        DJLogException(LOG_LEVEL_ERROR, exc);
        LWHandle(&exc);
        dj_close_log();
        return 1;
    }

    dj_close_log();

    return 0;
}
Exemple #24
0
static void GetSshVersion(PCSTR rootPrefix, SshdVersion *version, PCSTR binaryPath, LWException **exc)
{
    DWORD ceError = ERROR_SUCCESS;
    PSTR command = NULL;
    PSTR commandOutput = NULL;
    PCSTR versionStart;
    PSTR intEnd;

    version->isOpenSsh = FALSE;
    version->major = -1;
    version->minor = -1;
    version->secondMinor = -1;
    version->patch = -1;

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

    LW_CLEANUP_CTERR(exc, CTAllocateStringPrintf(
        &command, "%s%s -v 2>&1",
        rootPrefix, binaryPath));

    ceError = CTCaptureOutput(command, &commandOutput);
    if(ceError == ERROR_BAD_COMMAND)
        ceError = ERROR_SUCCESS;
    LW_CLEANUP_CTERR(exc, ceError);

    // The version string is in the form OpenSSH_4.6p1
    // or OpenSSH_3.6.1p1
    versionStart = strstr(commandOutput, "OpenSSH_");
    if(versionStart == NULL)
    {
        goto cleanup;
    }
    version->isOpenSsh = TRUE;

    versionStart += strlen("OpenSSH_");
    version->major = strtoul(versionStart, &intEnd, 10);
    if(intEnd == versionStart)
        version->major = -1;
    if(intEnd == NULL || *intEnd != '.')
        goto cleanup;
    versionStart = intEnd + 1;

    version->minor = strtoul(versionStart, &intEnd, 10);
    if(intEnd == versionStart)
        version->minor = -1;
    if(intEnd == NULL || (*intEnd != '.' && *intEnd != 'p'))
        goto cleanup;
    versionStart = intEnd + 1;

    if(*intEnd == '.')
    {
        version->secondMinor = strtoul(versionStart, &intEnd, 10);
        if(intEnd == versionStart)
            version->secondMinor = -1;
        if(intEnd == NULL || *intEnd != 'p')
            goto cleanup;
        versionStart = intEnd + 1;
    }

    version->patch = strtoul(versionStart, &intEnd, 10);
    if(intEnd == versionStart)
        version->patch = -1;

cleanup:

    if(version->isOpenSsh)
    {
        DJ_LOG_INFO("Found open sshd version %d.%d.%dp%d", version->major,
                version->minor, version->secondMinor, version->patch);
    }
    else
    {
        DJ_LOG_INFO("Found non-openssh version of ssh");
    }

    CT_SAFE_FREE_STRING(command);
    CT_SAFE_FREE_STRING(commandOutput);
}
Exemple #25
0
BOOLEAN FindSshAndConfig(
        PCSTR pSshOrSshd,
        PSTR *ppSshBinary,
        PSTR *ppSshConfig,
        LWException **ppExc)
{
    DWORD ceError = ERROR_SUCCESS;
    /* Mac OS X stores the configuration in /etc */
    /* CSW ssh on Solaris uses /opt/csw/etc/ssh */
    const PCSTR ppSshConfigPaths[] = {
        "/etc/ssh",
        "/opt/ssh/etc",
        "/usr/local/etc",
        "/etc",
        "/etc/openssh",
        "/usr/openssh/etc",
        "/opt/csw/etc/ssh",
        NULL
    };
    DWORD foundConfigCount = 0;
    PSTR* ppFoundConfigs = NULL;

    /* Solaris Sparc 10 stores sshd in /usr/lib/ssh */
    /* Experian says their sshd is at /usr/openssh/sbin/sshd */
    /* CSW ssh on Solaris uses /opt/csw/sbin/sshd */
    const PCSTR ppSshBinaryPaths[] = {
        "/usr/sbin",
        "/opt/ssh/sbin",
        "/usr/local/sbin",
        "/usr/bin",
        "/opt/ssh/bin",
        "/usr/local/bin",
        "/usr/lib/ssh",
        "/usr/openssh/sbin",
        "/usr/openssh/bin",
        "/opt/csw/sbin",
        "/opt/csw/bin",
        "/opt/ssh/hpux64/sbin",
        NULL
    };
    DWORD foundBinaryCount = 0;
    PSTR* ppFoundBinaries = NULL;
    PSTR pConfigFilename = NULL;
    PSTR pBinaryFilename = NULL;
    PSTR pFoundConfigList = NULL;
    PSTR pFoundBinaryList = NULL;
    DWORD index = 0;

    *ppSshBinary = NULL;
    *ppSshConfig = NULL;

    LW_CLEANUP_CTERR(ppExc, CTAllocateStringPrintf(
        &pConfigFilename, "%s_config", pSshOrSshd));
    LW_CLEANUP_CTERR(ppExc, CTAllocateStringPrintf(
        &pBinaryFilename, "%s", pSshOrSshd));

    ceError = LwFindFilesInPaths(
                    pConfigFilename,
                    LWFILE_REGULAR,
                    ppSshConfigPaths,
                    &foundConfigCount,
                    &ppFoundConfigs);
    LW_CLEANUP_CTERR(ppExc, ceError);

    ceError = LwRemoveDuplicateInodes(
                    &foundConfigCount,
                    ppFoundConfigs);
    LW_CLEANUP_CTERR(ppExc, ceError);

    ceError = LwFindFilesInPaths(
                    pBinaryFilename,
                    LWFILE_REGULAR,
                    ppSshBinaryPaths,
                    &foundBinaryCount,
                    &ppFoundBinaries);
    LW_CLEANUP_CTERR(ppExc, ceError);

    ceError = LwRemoveDuplicateInodes(
                    &foundBinaryCount,
                    ppFoundBinaries);
    LW_CLEANUP_CTERR(ppExc, ceError);

    // Ssh version A.04.40.005 on HP-UX Itanimum has these paths:
    //  /opt/ssh/hpux64/sbin/sshd (ELF-64 IA64)
    //  /opt/ssh/sbin/sshd (ELF-32 IA64)
    //  /usr/sbin/sshd (symlink to /opt/ssh/hpux64/sbin/sshd)
    //
    // Ssh version A.04.30.007 on HP-UX Itanimum has these paths:
    //  /opt/ssh/hpux64/sbin/sshd (ELF-64 IA64)
    //  /opt/ssh/sbin/sshd (ELF-32 IA64)
    //  /usr/sbin/sshd (symlink to /opt/ssh/sbin/sshd)
    //
    // Both files point to the same config path. An exception must exist for
    // this case since the inodes are different for the two architectures.
    //
    // The symlink at /usr/sbin/sshd wins the duplication removal process. So
    // if it is found, the other path must be removed.
    
    for (index = 0; index < foundBinaryCount; index++)
    {
        if (!strcmp(ppFoundBinaries[index], "/usr/sbin/sshd"))
        {
            // Remove /opt/ssh/sbin/sshd or /opt/ssh/hpux64/sbin/sshd if they
            // are in the list
            for (index = 0; index < foundBinaryCount; index++)
            {
                if (!strcmp(ppFoundBinaries[index], "/opt/ssh/sbin/sshd") ||
                    !strcmp(ppFoundBinaries[index],
                        "/opt/ssh/hpux64/sbin/sshd"))
                {
                    LW_SAFE_FREE_STRING(ppFoundBinaries[index]);
                    memmove(&ppFoundBinaries[index],
                            &ppFoundBinaries[index+1],
                            (foundBinaryCount - index - 1) *
                                sizeof(ppFoundBinaries[index]));
                    foundBinaryCount--;
                    break;
                }
            }
            break;
        }
    }

    if ((foundConfigCount | foundBinaryCount) > 0 && foundConfigCount != foundBinaryCount)
    {
        ceError = CombinePaths(
                        foundConfigCount,
                        ppFoundConfigs,
                        &pFoundConfigList);
        LW_CLEANUP_CTERR(ppExc, ceError);

        ceError = CombinePaths(
                        foundBinaryCount,
                        ppFoundBinaries,
                        &pFoundBinaryList);
        LW_CLEANUP_CTERR(ppExc, ceError);

        if ((foundConfigCount | foundBinaryCount) == 1)
        {
            ceError = ERROR_FILE_NOT_FOUND;
        }
        else
        {
            ceError = ERROR_DUPLICATE_SERVICE_NAME;
        }

        LW_RAISE_EX(ppExc, ceError,
                "Unable to find ssh binary",
"A %s config file was at %s, and a %s binary file was found at %s. Exactly one config file and one binary must exist on the system in a standard location. Uninstall any unused copies of ssh.",
                pSshOrSshd,
                pFoundConfigList,
                pSshOrSshd,
                pFoundBinaryList);
    }

    if (foundConfigCount == 1)
    {
        DJ_LOG_INFO("Found config file %s", ppFoundConfigs[0]);
        *ppSshConfig = ppFoundConfigs[0];
        ppFoundConfigs[0] = NULL;
    }
    if (foundBinaryCount == 1)
    {
        DJ_LOG_INFO("Found binary %s", ppFoundBinaries[0]);
        *ppSshBinary = ppFoundBinaries[0];
        ppFoundBinaries[0] = NULL;
    }

cleanup:
    if (ppFoundConfigs)
    {
        LwFreeStringArray(
                ppFoundConfigs,
                foundConfigCount);
    }
    if (ppFoundBinaries)
    {
        LwFreeStringArray(
                ppFoundBinaries,
                foundBinaryCount);
    }
    LW_SAFE_FREE_STRING(pConfigFilename);
    LW_SAFE_FREE_STRING(pBinaryFilename);
    LW_SAFE_FREE_STRING(pFoundConfigList);
    LW_SAFE_FREE_STRING(pFoundBinaryList);
    return (foundConfigCount == 1);
}
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);
}
Exemple #27
0
static BOOLEAN TestOption(PCSTR rootPrefix, struct SshConf *conf, PCSTR binary, PCSTR testFlag, PCSTR optionName, LWException **exc)
{
    DWORD ceError = ERROR_SUCCESS;
    BOOLEAN result = FALSE;
    PSTR command = NULL;
    PSTR commandOutput = NULL;
    int existingLine;

    if(rootPrefix == NULL)
        rootPrefix = "";
    DJ_LOG_INFO("Testing option %s", optionName);

    existingLine = FindOption(conf, 0, optionName);
    if(existingLine != -1)
    {
        if(!strcmp(conf->lines[existingLine].value.value, "yes"))
        {
            //The option is already enabled, so it must be supported
            result = TRUE;
            goto cleanup;
        }
    }

    /* Most versions of sshd support the -t option which runs it in test
       mode. Test mode is used to verify that a config file is correct, or
       in our case that the passed options are valid.

       The only version of sshd known to not support -t is the version that
       comes with Solaris 9. However, this version does not support the -o
       option, and it will error out if the -o option is used. The Solaris
       9 version of sshd does not support any of the options we'd like to
       enable, so it will correctly fail all of the option tests.

       Sshd will either complain about the first invalid option that is
       passed with -o, or it will complain about all invalid options. -o
       BadOption=yes is passed to verify that sshd understands -o, and to
       make doubly sure that it will not start listening on a port.

       The -v option can be used to test whether ssh (the client) supports
       given options.  Passing -v to ssh will cause it to print out its
       version number and not attempt to connect to a machine. All versions of
       ssh seem to parse the options passed with -o even when -v is passed.

       Ssh will either complain about the first invalid option that is
       passed with -o, or it will complain about all invalid options. -o
       BadOption=yes is passed to verify that ssh understands -o.
     */
    LW_CLEANUP_CTERR(exc, CTAllocateStringPrintf(
        &command, "%s%s %s -o %s=yes -o BadOption=yes 2>&1",
        rootPrefix, binary, testFlag, optionName));

    ceError = CTCaptureOutput(command, &commandOutput);
    /* Some versions of sshd will return an error code because an invalid
       option was passed, but not all will. */
    if(ceError == ERROR_BAD_COMMAND)
        ceError = ERROR_SUCCESS;
    LW_CLEANUP_CTERR(exc, ceError);

    if(strstr(commandOutput, optionName) != NULL)
    {
        DJ_LOG_INFO("Option %s not supported", optionName);
        goto cleanup;
    }

    if(strstr(commandOutput, "BadOption") == NULL)
    {
        DJ_LOG_INFO("Sshd does not support -o");
        goto cleanup;
    }

    DJ_LOG_INFO("Option %s supported", optionName);
    result = TRUE;

cleanup:
    CT_SAFE_FREE_STRING(command);
    CT_SAFE_FREE_STRING(commandOutput);
    return result;
}
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);
}
Exemple #29
0
static QueryResult UpdateSshdConf(struct SshConf *conf, PCSTR testPrefix,
        PCSTR binaryPath, BOOLEAN enable, PSTR *changeDescription,
        const JoinProcessOptions *options, LWException **exc)
{
    size_t i;
    BOOLEAN modified = conf->modified;
    PSTR requiredOptions = NULL;
    PSTR optionalOptions = NULL;
    BOOLEAN supported;
    PSTR temp = NULL;
    QueryResult result = NotConfigured;
    const char *requiredSshdOptions[] = {
        "ChallengeResponseAuthentication",
        "UsePAM", "PAMAuthenticationViaKBDInt",
        "KbdInteractiveAuthentication", NULL};
    const char *optionalSshdOptions[] = {"GSSAPIAuthentication",
        "GSSAPICleanupCredentials", NULL};
    SshdVersion version;
    BOOLEAN compromisedOptions = FALSE;

    if(changeDescription != NULL)
        *changeDescription = NULL;

    LW_TRY(exc, GetSshVersion("", &version, binaryPath, &LW_EXC));

    if(enable)
    {
        LW_CLEANUP_CTERR(exc, CTStrdup("", &requiredOptions));
        LW_CLEANUP_CTERR(exc, CTStrdup("", &optionalOptions));
        for(i = 0; requiredSshdOptions[i] != NULL; i++)
        {
            PCSTR option = requiredSshdOptions[i];
            LW_TRY(exc, supported = TestOption(testPrefix, conf, binaryPath, "-t", option, &LW_EXC));
            if(supported)
            {
                PCSTR value = "yes";

                if(IsNewerThanOrEq(&version, 2, 3, 1, -1) &&
                        IsOlderThanOrEq(&version, 3, 3, -1, -1) &&
                        (!strcmp(option, "ChallengeResponseAuthentication") ||
                         !strcmp(option, "PAMAuthenticationViaKBDInt")))
                {
                    value = "no";
                    compromisedOptions = TRUE;
                }
                conf->modified = FALSE;
                LW_CLEANUP_CTERR(exc, SetOption(conf, option, value));
                if(conf->modified)
                {
                    modified = TRUE;
                    temp = requiredOptions;
                    requiredOptions = NULL;
                    CTAllocateStringPrintf(&requiredOptions, "%s\t%s\n", temp, option);
                    CT_SAFE_FREE_STRING(temp);
                }
            }
        }
        for(i = 0; optionalSshdOptions[i] != NULL; i++)
        {
            PCSTR option = optionalSshdOptions[i];
            LW_TRY(exc, supported = TestOption(testPrefix, conf, binaryPath, "-t", option, &LW_EXC));
            if(supported)
            {
                conf->modified = FALSE;
                LW_CLEANUP_CTERR(exc, SetOption(conf, option, "yes"));
                if(conf->modified)
                {
                    modified = TRUE;
                    temp = optionalOptions;
                    optionalOptions = NULL;
                    LW_CLEANUP_CTERR(exc, CTAllocateStringPrintf(&optionalOptions, "%s\t%s\n", temp, option));
                    CT_SAFE_FREE_STRING(temp);
                }
            }
        }
        result = FullyConfigured;
        if(strlen(optionalOptions) > 0)
        {
            temp = optionalOptions;
            optionalOptions = NULL;
            LW_CLEANUP_CTERR(exc, CTAllocateStringPrintf(
                        &optionalOptions,
                        "The following options will be enabled in %s to provide a better user experience:\n%s",
                        conf->filename, temp));
            CT_SAFE_FREE_STRING(temp);
            result = SufficientlyConfigured;
        }
        if(strlen(requiredOptions) > 0)
        {
            temp = requiredOptions;
            requiredOptions = NULL;
            LW_CLEANUP_CTERR(exc, CTAllocateStringPrintf(
                        &requiredOptions,
                        "The following options must be enabled in %s:\n%s",
                        conf->filename, temp));
            CT_SAFE_FREE_STRING(temp);
            result = NotConfigured;
        }
        if(changeDescription != NULL)
        {
            LW_CLEANUP_CTERR(exc, CTAllocateStringPrintf(
                        changeDescription,
                        "%s%s",
                        requiredOptions, optionalOptions));
        }
    }
    else
    {
        conf->modified = FALSE;
        LW_CLEANUP_CTERR(exc, RemoveOption(conf, "GSSAPIAuthentication"));
        if(conf->modified)
        {
            if(changeDescription != NULL)
            {
                LW_CLEANUP_CTERR(exc, CTAllocateStringPrintf(
                            changeDescription,
                            "In %s, GSSAPIAuthentication may optionally be removed.\n",
                            conf->filename));
            }
            result = SufficientlyConfigured;
        }
        else
            result = FullyConfigured;
    }
    if(changeDescription != NULL && *changeDescription == NULL)
        LW_CLEANUP_CTERR(exc, CTStrdup("", changeDescription));

    if(options != NULL)
    {
        ModuleState *state = DJGetModuleStateByName(options, "ssh");
        if(state->moduleData == (void *)-1)
        {
            //We already showed a warning
        }
        else if(compromisedOptions)
        {
            state->moduleData = (void *)-1;
            if (options->warningCallback != NULL)
            {
                options->warningCallback(options, "Unpatched version of SSH",
                        "The version of your sshd daemon indicates that it is susceptible to the remote exploit described at http://www.openssh.com/txt/preauth.adv . To avoid exposing your system to this exploit, the 'ChallengeResponseAuthentication' and 'PAMAuthenticationViaKBDInt' options will be set to 'no' instead of 'yes'. As a side effect, all login error messages will appear as 'permission denied' instead of more detailed messages like 'account disabled'. Additionally, password changes on login may not work.\n\
\n\
Even when those options are disabled, your system is still vulnerable to http://www.cert.org/advisories/CA-2003-24.html . We recommend upgrading your version of SSH.");
            }
        }
void
DoNsswitch(
    JoinProcessOptions *options,
    LWException **exc
    )
{
    LWException *restartException = NULL;
    NsswitchConf conf;
    DWORD ceError = ERROR_SUCCESS;

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

    LW_TRY(exc, ConfigureApparmor(options->joiningDomain, &LW_EXC));

    if(options->joiningDomain)
        LW_CLEANUP_CTERR(exc, DJFixMethodsConfigFile());
    else
        LW_CLEANUP_CTERR(exc, DJUnconfigMethodsConfigFile());

    ceError = ReadNsswitchConf(&conf, "", TRUE);
    if(ceError == ERROR_FILE_NOT_FOUND)
    {
        ceError = ERROR_SUCCESS;
        if (options->warningCallback != NULL)
        {
            options->warningCallback(options, "Could not find file", "Could not find nsswitch file");
        }
        goto cleanup;
    }
    LW_CLEANUP_CTERR(exc, ceError);

    if(options->joiningDomain)
    {
        LW_TRY(exc, RemoveCompat(&conf, NULL, &LW_EXC));
    }

    LW_CLEANUP_CTERR(exc, UpdateNsswitchConf(&conf, options->joiningDomain));

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

    CTCaptureOutputToExc( SCRIPTDIR "/ConfigureLogin nsswitch_restart",
            &restartException);
    if(restartException != NULL && restartException->code == ERROR_BAD_COMMAND)
    {
        if (options->warningCallback)
        {
            options->warningCallback(options, "Some services require manual restart", restartException->longMsg);
        }
        LW_HANDLE(&restartException);
    }
    LW_CLEANUP(exc, restartException);

    LW_TRY(exc, RestartDtloginIfRunning(options, &LW_EXC));

    if (options->joiningDomain && options->warningCallback != NULL)
    {
        options->warningCallback(options,
                                 "System restart required",
                                 "Your system has been configured to authenticate to "
                                 "Active Directory for the first time.  It is recommended "
                                 "that you restart your system to ensure that all applications "
                                 "recognize the new settings.");
    }

cleanup:

    FreeNsswitchConfContents(&conf);
}