Example #1
0
DWORD CTGetDistroString(CtDistroType type, char **result)
{
    int i;
    for(i = 0; i < sizeof(distroList)/sizeof(distroList[0]); i++)
    {
        if(type == distroList[i].value)
            return CTStrdup(distroList[i].name, result);
    }
    return CTStrdup("unknown", result);
}
Example #2
0
DWORD CTGetArchString(CtArchType type, char **result)
{
    int i;
    for(i = 0; i < sizeof(archList)/sizeof(archList[0]); i++)
    {
        if(type == archList[i].value)
            return CTStrdup(archList[i].name, result);
    }
    return CTStrdup("unknown", result);
}
Example #3
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;
}
Example #4
0
DWORD CTDupOrNullStr(const char *src, char **dest)
{
    if(src == NULL)
    {
        *dest = NULL;
        return ERROR_SUCCESS;
    }
    return CTStrdup(src, dest);
}
Example #5
0
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;
}
Example #6
0
static DWORD AddEntry(NsswitchConf *conf, const DistroInfo *distro,
        int *addedIndex, const char *name)
{
    DWORD ceError = ERROR_SUCCESS;
    int line = -1;
    NsswitchEntry lineObj;
    const NsswitchEntry *copy;

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

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

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

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

cleanup:
    FreeNsswitchEntryContents(&lineObj);
    return ceError;
}
Example #7
0
static
DWORD
GetAuthType(const DynamicArray *lines, PSTR *result)
{
    DWORD ceError = DJGetOptionValue(lines, "usw", "auth_type", result);
    if(ceError == ERROR_NOT_FOUND)
    {
        //return the default
        ceError = CTStrdup("STD_AUTH", result);
    }
    return ceError;
}
Example #8
0
void DoGetDistroInfo(int argc, char **argv, LWException **exc)
{
    PSTR str = NULL;
    PCSTR requestType = argv[0];
    PCSTR testPrefix = NULL;
    LwDistroInfo distro = {0};

    argc--;
    argv++;

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

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

cleanup:
    DJFreeDistroInfo(&distro);
    CT_SAFE_FREE_STRING(str);
}
Example #9
0
static DWORD ReadNsswitchFile(NsswitchConf *conf, const char *rootPrefix, const char *filename)
{
    DWORD ceError = ERROR_SUCCESS;
    FILE *file = NULL;
    PSTR buffer = NULL;
    char *fullPath = NULL;
    BOOLEAN endOfFile = FALSE;
    BOOLEAN exists;

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

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

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

    conf->modified = FALSE;

cleanup:
    CT_SAFE_FREE_STRING(buffer);
    if(file != NULL)
        CTCloseFile(file);
    CT_SAFE_FREE_STRING(fullPath);
    if(ceError)
        FreeNsswitchConfContents(conf);
    return ceError;
}
Example #10
0
static DWORD ReadSshFile(struct SshConf *conf, const char *rootPrefix, const char *filename)
{
    DWORD ceError = ERROR_SUCCESS;
    FILE *file = NULL;
    PSTR buffer = NULL;
    char *fullPath = NULL;
    BOOLEAN endOfFile = FALSE;
    BOOLEAN exists;

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

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

    return ceError;

error:
    if(file != NULL)
        CTCloseFile(file);
    CT_SAFE_FREE_STRING(fullPath);
    FreeSshConfContents(conf);
    CT_SAFE_FREE_STRING(buffer);
    return ceError;
}
Example #11
0
DWORD DJGetOptionValue(const DynamicArray *lines, PCSTR stanza, PCSTR name, PSTR *value)
{
    DWORD ceError = ERROR_SUCCESS;
    ssize_t i = DJFindLine(lines, stanza, name);
    PCSTR line;
    PSTR _value = NULL;

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

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

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

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

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

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

    *value = _value;
    _value = NULL;

cleanup:
    CT_SAFE_FREE_STRING(_value);
    return ceError;
}
Example #12
0
static
DWORD
FillMissingPassword(
    PCSTR username,
    PSTR* ppszPassword
    )
{
    DWORD ceError = ERROR_SUCCESS;
    PSTR pszPassword = NULL;
    PCSTR pszEnvPassword = NULL;

    pszEnvPassword = getenv("PASSWORD");
    if (pszEnvPassword == NULL)
    {
        fprintf(stdout, "%s's password: "******"\n");
    }
    else
    {
        DJ_LOG_WARNING("Retrieved password from envionmental variable");
        ceError = CTStrdup(pszEnvPassword, &pszPassword);
        BAIL_ON_CENTERIS_ERROR(ceError);
    }

    if (!IsNullOrEmptyString(pszPassword)) {
        *ppszPassword = pszPassword;
        pszPassword = NULL;
    }

error:

    if (pszPassword)
        CTFreeString(pszPassword);

    return ceError;
}
Example #13
0
DWORD CTGetDistroInfo(const char *testPrefix, CtDistroInfo *info)
{
    BOOLEAN exists;
    DWORD ceError = ERROR_SUCCESS;
    struct utsname unameStruct;
    char *path = NULL;
    PSTR fileContents = NULL;
    PSTR distroString = NULL;
    BOOLEAN rxAlloced = FALSE;
    regex_t rx;
    memset(info, 0, sizeof(*info));
#if defined(HAVE_SYSINFO) && defined(SI_ARCHITECTURE)
    char archBuffer[100];
#endif

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

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

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

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

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

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

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

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

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

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

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

cleanup:
    CT_SAFE_FREE_STRING(path);
    CT_SAFE_FREE_STRING(fileContents);
    CT_SAFE_FREE_STRING(distroString);
    if(rxAlloced)
        regfree(&rx);
    if(ceError)
    {
        CTFreeDistroInfo(info);
    }
    return ceError;
}
Example #14
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.");
            }
        }
Example #15
0
/* Copy a ssh configuration line and add it below the old line. */
static DWORD SetOption(struct SshConf *conf, const char *name, const char *value)
{
    DWORD ceError = ERROR_SUCCESS;
    int line = -1;
    DynamicArray printedLine;
    struct SshLine lineObj;
    int found = 0;

    memset(&lineObj, 0, sizeof(struct SshLine));
    memset(&printedLine, 0, sizeof(printedLine));

    for(line = 0; line < conf->lineCount; line++)
    {
        line = FindOption(conf, line, name);
        if(line == -1)
            break;
        found++;
        if(!strcmp(conf->lines[line].value.value, value))
            continue;

        //Insert a commented out version of the line
        BAIL_ON_CENTERIS_ERROR(ceError = GetPrintedLine(&printedLine, conf, line));
        BAIL_ON_CENTERIS_ERROR(ceError = CTStrdup("",
            &lineObj.leadingWhiteSpace));
        BAIL_ON_CENTERIS_ERROR(ceError = CTStrdup("",
            &lineObj.name.value));
        BAIL_ON_CENTERIS_ERROR(ceError = CTStrdup("",
            &lineObj.name.trailingSeparator));
        BAIL_ON_CENTERIS_ERROR(ceError = CTStrdup("",
            &lineObj.value.value));
        BAIL_ON_CENTERIS_ERROR(ceError = CTAllocateStringPrintf(
            &lineObj.value.trailingSeparator,
            "#Overwritten by lwidentity: %s",
            printedLine.data));
        BAIL_ON_CENTERIS_ERROR(ceError = CTArrayInsert(&conf->private_data,
                    line, sizeof(struct SshLine), &lineObj, 1));
        memset(&lineObj, 0, sizeof(lineObj));
        UpdatePublicLines(conf);
        conf->modified = 1;
        line++;

        //Change the option value of the line
        CT_SAFE_FREE_STRING(conf->lines[line].value.value);
        BAIL_ON_CENTERIS_ERROR(ceError = CTStrdup(value,
            &conf->lines[line].value.value));
    }

    /*If the option wasn't already in the file, search for comments that
      mention the option, and insert the line after the comment*/
    for(line = 0; !found && line < conf->lineCount; line++)
    {
        if(strstr(conf->lines[line].value.trailingSeparator, name) == NULL)
            continue;

        BAIL_ON_CENTERIS_ERROR(ceError = CTStrdup("",
            &lineObj.leadingWhiteSpace));
        BAIL_ON_CENTERIS_ERROR(ceError = CTStrdup(name,
            &lineObj.name.value));
        BAIL_ON_CENTERIS_ERROR(ceError = CTStrdup(" ",
            &lineObj.name.trailingSeparator));
        BAIL_ON_CENTERIS_ERROR(ceError = CTStrdup(value,
            &lineObj.value.value));
        BAIL_ON_CENTERIS_ERROR(ceError = CTStrdup("",
            &lineObj.value.trailingSeparator));
        BAIL_ON_CENTERIS_ERROR(ceError = CTArrayInsert(&conf->private_data,
                    line + 1, sizeof(struct SshLine), &lineObj, 1));
        memset(&lineObj, 0, sizeof(lineObj));
        conf->modified = 1;
        found++;
    }

    /*If the option wasn't even in a comment, just add the option at the
      end of the file
      */
    if(!found)
    {
        BAIL_ON_CENTERIS_ERROR(ceError = CTStrdup("",
            &lineObj.leadingWhiteSpace));
        BAIL_ON_CENTERIS_ERROR(ceError = CTStrdup(name,
            &lineObj.name.value));
        BAIL_ON_CENTERIS_ERROR(ceError = CTStrdup(" ",
            &lineObj.name.trailingSeparator));
        BAIL_ON_CENTERIS_ERROR(ceError = CTStrdup(value,
            &lineObj.value.value));
        BAIL_ON_CENTERIS_ERROR(ceError = CTStrdup("",
            &lineObj.value.trailingSeparator));
        BAIL_ON_CENTERIS_ERROR(ceError = CTArrayAppend(&conf->private_data,
                    sizeof(struct SshLine), &lineObj, 1));
        memset(&lineObj, 0, sizeof(lineObj));
        conf->modified = 1;
    }

error:
    UpdatePublicLines(conf);
    FreeSshLineContents(&lineObj);
    CTArrayFree(&printedLine);
    return ceError;
}
Example #16
0
DWORD
CTGetLikewiseVersion(
    PSTR *product,
    PSTR *version,
    PSTR *build,
    PSTR *revision
    )
{
    FILE *versionFile = NULL;
    PSTR line = NULL; 
    BOOLEAN isEndOfFile = FALSE;
    DWORD ceError = ERROR_SUCCESS;
    BOOLEAN bIsEnterprise = FALSE;

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

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

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

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

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

    GCE(ceError = CTSafeCloseFile(&versionFile));

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

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

    return ceError;
}
Example #17
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;
}
Example #18
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 #19
0
DWORD
ReadNsswitchConf(NsswitchConf *conf, const char *testPrefix,
        BOOLEAN allowFileCreate)
{
    PSTR copyDestPath = NULL;
    PSTR defaultFilePath = NULL;
    DWORD ceError = ERROR_SUCCESS;
    BOOLEAN bFileExists = FALSE;
    memset(conf, 0, sizeof(*conf));
    
    //Keep trying to read different filenames until one of them is found
    if(!bFileExists)
    {
        bFileExists = TRUE;
        ceError = ReadNsswitchFile(conf, testPrefix, "/etc/nsswitch.conf");
        if(ceError == ERROR_FILE_NOT_FOUND)
        {
            bFileExists = FALSE;
            ceError = ERROR_SUCCESS;
        }
        GCE(ceError);
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

cleanup:
    CTFreeParseTokenContents(&addModule);
    return ceError;
}
Example #21
0
void DoJoin(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;
    int passwordIndex = -1;
    PSTR moduleDetails = NULL;
    PSTR wrapped = NULL;

    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(!strcmp(argv[0], "--ignore-firewall-ntp"))
        {
            printf("Warning: --ignore-firewall-ntp is deprecated. This behavior is now default.\n");
        }
        else if(!strcmp(argv[0], "--ignore-pam"))
            options.ignorePam = TRUE;
        else if(!strcmp(argv[0], "--notimesync"))
            options.disableTimeSync = TRUE;
        else if(!strcmp(argv[0], "--multiple"))
            options.enableMultipleJoins = TRUE;
        else if(!strcmp(argv[0], "--nohosts"))
        {
            PCSTR module = "hostname";
            LW_CLEANUP_CTERR(exc, CTArrayAppend(&disableModules, sizeof(PCSTR), &module, 1));
        }
        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], "--ou"))
        {
            DJ_LOG_INFO("Domainjoin invoked with option --ou %s", argv[1]);
            CT_SAFE_FREE_STRING(options.ouName);
            LW_CLEANUP_CTERR(exc, CTStrdup(argv[1], &options.ouName));
            argv++;
            argc--;
        }
        else if(!strcmp(argv[0], "--uac-flags"))
        {
            DJ_LOG_INFO("Domainjoin invoked with option --uac-flags %s", argv[1]);
            CT_SAFE_FREE_STRING(options.ouName);
            options.uacFlags = strtoul(argv[1], NULL, 0);
            argv++;
            argc--;
        }
        else if(!strcmp(argv[0], "--assumeDefaultDomain"))
        {
            DJ_LOG_INFO("Domainjoin invoked with option --assumeDefaultDomain");
            options.setAssumeDefaultDomain = TRUE;

            if (!strcasecmp(argv[1], "yes") || !strcasecmp(argv[1], "true") ||
                !strcasecmp(argv[1], "on"))
            {
                options.assumeDefaultDomain = TRUE;
            }
            else if (!strcasecmp(argv[1], "no") ||
                !strcasecmp(argv[1], "false") ||
                !strcasecmp(argv[1], "off"))
            {
                options.assumeDefaultDomain = FALSE;
            }
            else
            {
                LW_RAISE(exc, LW_ERROR_SHOW_USAGE);
                goto cleanup;
            }
            argv++;
            argc--;
        }
        else if(!strcmp(argv[0], "--userDomainPrefix"))
        {
            DJ_LOG_INFO("Domainjoin invoked with option --userDomainPrefix %s", argv[1]);
            options.setAssumeDefaultDomain = TRUE;
            options.assumeDefaultDomain = TRUE;
            CT_SAFE_FREE_STRING(options.userDomainPrefix);
            LW_CLEANUP_CTERR(exc, CTStrdup(argv[1], &options.userDomainPrefix));
            CTStrToUpper(options.userDomainPrefix);
            argv++;
            argc--;
        }
        else
        {
            LW_RAISE(exc, LW_ERROR_SHOW_USAGE);
            goto cleanup;
        }
        argv++;
        argc--;
    }

    if(argc == 3)
    {
        LW_CLEANUP_CTERR(exc, CTStrdup(argv[2], &options.password));
        passwordIndex = 2;
    }
    // The join username is not required in preview or details mode.
    else if(argc == 1 && (preview || detailModules.size != 0) )
        ;
    else if(argc != 2)
    {
        LW_RAISE(exc, LW_ERROR_SHOW_USAGE);
        goto cleanup;
    }
    options.joiningDomain = TRUE;

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

    LW_CLEANUP_CTERR(exc, CTStrdup(
        argv[0], &options.domainName));
    if(argc > 1)
    {
        LW_CLEANUP_CTERR(exc, CTStrdup(argv[1], &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 ignored and enabled", 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 enabled and ignored", 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 disabled and ignored", 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 (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);
}
Example #22
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);
}
Example #23
0
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;
}