int SetPasswordCreationRequirements()

in src/common/commonutils/PassUtils.c [726:836]


int SetPasswordCreationRequirements(int retry, int minlen, int minclass, int dcredit, int ucredit, int ocredit, int lcredit, OsConfigLogHandle log)
{
    // These lines are used for password creation requirements configuration.
    //
    // A single line for /etc/pam.d/common-password when pam_pwquality.so is present:
    //
    // 'password requisite pam_pwquality.so retry=3 minlen=14 lcredit=-1 ucredit=-1 ocredit=-1 dcredit=-1'
    //
    //  Otherwise a single line for /etc/pam.d/common-password when pam_cracklib.so is present:
    //
    // 'password required pam_cracklib.so retry=3 minlen=14 dcredit=-1 ucredit=-1 ocredit=-1 lcredit=-1'
    //
    // Separate lines for /etc/security/pwquality.conf:
    //
    // 'retry = 3'
    // 'minlen = 14'
    // 'minclass = 4'
    // 'dcredit = -1'
    // 'ucredit = -1'
    // 'ocredit = -1'
    // 'lcredit = -1'
    //
    // Where:
    //
    // - password requisite pam_pwquality.so: the pam_pwquality module is required during password authentication
    // - retry: the user will be prompted at most this times to enter a valid password before an error is returned
    // - minlen: the minlen parameter sets the minimum acceptable length for a password to 14 characters
    // - minclass: the minimum number of character types that must be used (e.g., uppercase, lowercase, digits, other)
    // - lcredit: the minimum number of lowercase letters required in the password (negative means no requirement)
    // - ucredit: the minimum number of uppercase letters required in the password (negative means no requirement)
    // - ocredit: the minimum number of other (non-alphanumeric) characters required in the password (negative means none)
    // - dcredit: the minimum number of digits required in the password  (negative means no requirement)

    const char* etcPamdCommonPasswordLineTemplate = "password requisite %s retry=%d minlen=%d lcredit=%d ucredit=%d ocredit=%d dcredit=%d\n";
    const char* etcSecurityPwQualityConfLineTemplate = "%s = %d\n";
    const char* pamPwQualitySo = "pam_pwquality.so";
    const char* pamCrackLibSo = "pam_cracklib.so";
    PasswordCreationRequirements entries[] = {{"retry", 0}, {"minlen", 0}, {"minclass", 0}, {"dcredit", 0}, {"ucredit", 0}, {"ocredit", 0}, {"lcredit", 0}};
    int numEntries = ARRAY_SIZE(entries);
    bool pamPwQualitySoExists = false;
    bool pamCrackLibSoExists = false;
    bool pamUnixSoExists = false;
    char* pamModulePath = NULL;
    char* pamModulePath2 = NULL;
    char* pamModulePath3 = NULL;
    int i = 0, status = 0, _status = 0;
    char* line = NULL;

    if (0 == CheckFileExists(g_etcPamdCommonPassword, NULL, log))
    {
        EnsurePamModulePackagesAreInstalled(log);

        pamPwQualitySoExists = (NULL != (pamModulePath = FindPamModule(pamPwQualitySo, log))) ? true : false;
        pamCrackLibSoExists = (NULL != (pamModulePath2 = FindPamModule(pamCrackLibSo, log))) ? true : false;
        pamUnixSoExists = (NULL != (pamModulePath3 = FindPamModule(g_pamUnixSo, log))) ? true : false;

        if (pamPwQualitySoExists || pamCrackLibSoExists || pamUnixSoExists)
        {
            if (NULL != (line = FormatAllocateString(etcPamdCommonPasswordLineTemplate,
                pamPwQualitySoExists ? pamModulePath : (pamCrackLibSoExists ? pamModulePath2 : pamModulePath3),
                retry, minlen, lcredit, ucredit, ocredit, dcredit)))
            {
                status = ReplaceMarkedLinesInFile(g_etcPamdCommonPassword, pamPwQualitySoExists ? pamPwQualitySo : (pamCrackLibSoExists ? pamCrackLibSo : g_pamUnixSo), line, '#', true, log);
                FREE_MEMORY(line);
            }
            else
            {
                OsConfigLogError(log, "SetPasswordCreationRequirements: out of memory when allocating new line for '%s'", g_etcPamdCommonPassword);
            }
        }
        else
        {
            status = ENOENT;
        }

        FREE_MEMORY(pamModulePath);
        FREE_MEMORY(pamModulePath2);
        FREE_MEMORY(pamModulePath3);
    }

    if (0 == CheckFileExists(g_etcSecurityPwQualityConf, NULL, log))
    {
        entries[0].value = retry;
        entries[1].value = minlen;
        entries[2].value = minclass;
        entries[3].value = dcredit;
        entries[4].value = ucredit;
        entries[5].value = ocredit;
        entries[6].value = lcredit;

        for (i = 0; i < numEntries; i++)
        {
            if (NULL != (line = FormatAllocateString(etcSecurityPwQualityConfLineTemplate, entries[i].name, entries[i].value)))
            {
                _status = ReplaceMarkedLinesInFile(g_etcSecurityPwQualityConf, entries[i].name, line, '#', true, log);
                FREE_MEMORY(line);
            }
            else
            {
                OsConfigLogError(log, "SetPasswordCreationRequirements: out of memory when allocating new line for '%s'", g_etcSecurityPwQualityConf);
            }
        }
    }

    if ((0 == _status) || (_status && (0 == status)))
    {
        status = _status;
    }

    return status;
}