shadow-4.5-passwd在fedora22-powerpc上passwd的配置文件引起的口令策略校验失效问题

前言

同事在fedora22-PC版上,配置出了可用的password策略. 输入不合规的口令,会有警告或报错提示.
将同样的配置文件挪到fedora22-powerpc版上,passwd执行后,输入不合规的口令,可以完成口令修改。
我没有找到fedora22原版的passwd工程下载,用的是gnu-shadow-4.5中的passwd工程。
现在怀疑是配置文件条目不同引起的问题(gnu的代码写的刚刚的,也不敢怀疑:))

排错

gdb -tui –args ./passwd user_test
break new_password
run

new_password 中对PASS_ALWAYS_WARN配置项进行了检查

if (amroot && !warned && getdef_bool ("PASS_ALWAYS_WARN")
            && (!obscure (orig, pass, pw) || reuse (pass, pw))) {
            (void) puts (_("\nWarning: weak password (enter it again to use it anyway)."));
            warned = true;
            continue;
        }

检查代码有与的关系, 如果PASS_ALWAYS_WARN 项的bool值不是yes, 后面的检查(obscure(), reuse())不会被执行了,导致口令检查策略失效.
obscure_msg 处判断了login.defs OBSCURE_CHECKS_ENAB yes
到了obscure_msg中, 就可以看到口令检查的全过程。
发现了login.defs 缺OBSCURE_CHECKS_ENAB配置项后,补全了先试了一下,口令检查策略文件已经生效了,就没有再继续观赏剩下的口令检查实现.

bool obscure (const char *old, const char *new, const struct passwd *pwdp)
{
    const char *msg = obscure_msg (old, new, pwdp);

    if (NULL != msg) {
        printf (_("Bad password: %s. "), msg);
        return false;
    }
    return true;
}

static /*@observer@*//*@null@*/const char *obscure_msg (
    /*@notnull@*/const char *old,
    /*@notnull@*/const char *new,
    /*@notnull@*/const struct passwd *pwdp)
{
    size_t maxlen, oldlen, newlen;
    char *new1, *old1;
    const char *msg;
    const char *result;

    oldlen = strlen (old);
    newlen = strlen (new);

    if (newlen < (size_t) getdef_num ("PASS_MIN_LEN", 0)) {
        return _("too short");
    }

    /* * Remaining checks are optional. */
    if (!getdef_bool ("OBSCURE_CHECKS_ENAB")) {
        return NULL;
    }

    msg = password_check (old, new, pwdp);
    if (NULL != msg) {
        return msg;
    }

    result = getdef_str ("ENCRYPT_METHOD");
    if (NULL == result) {
    /* The traditional crypt() truncates passwords to 8 chars. It is possible to circumvent the above checks by choosing an easy 8-char password and adding some random characters to it... Example: "password$%^&*123". So check it again, this time truncated to the maximum length. Idea from npasswd. --marekm */

        if (getdef_bool ("MD5_CRYPT_ENAB")) {
            return NULL;
        }

    } else {

        if (   (strcmp (result, "MD5")    == 0)
#ifdef USE_SHA_CRYPT
            || (strcmp (result, "SHA256") == 0)
            || (strcmp (result, "SHA512") == 0)
#endif
            ) {
            return NULL;
        }

    }
    maxlen = (size_t) getdef_num ("PASS_MAX_LEN", 8);
    if (   (oldlen <= maxlen)
        && (newlen <= maxlen)) {
        return NULL;
    }

    new1 = xstrdup (new);
    old1 = xstrdup (old);
    if (newlen > maxlen) {
        new1[maxlen] = '\0';
    }
    if (oldlen > maxlen) {
        old1[maxlen] = '\0';
    }

    msg = password_check (old1, new1, pwdp);

    memzero (new1, newlen);
    memzero (old1, oldlen);
    free (new1);
    free (old1);

    return msg;
}

最后修正的配置文件

etc/login.defs

必须有的2项配置

PASS_ALWAYS_WARN yes
OBSCURE_CHECKS_ENAB yes
如果没有这2项,不继续向后检查口令是否符合策略要求了.

完整配置文件

#
# Please note that the parameters in this configuration file control the
# behavior of the tools from the shadow-utils component. None of these
# tools uses the PAM mechanism, and the utilities that use PAM (such as the
# passwd command) should therefore be configured elsewhere. Refer to
# /etc/pam.d/system-auth for more information.
#

# *REQUIRED*
# Directory where mailboxes reside, _or_ name of file, relative to the
# home directory. If you _do_ define both, MAIL_DIR takes precedence.
# QMAIL_DIR is for Qmail
#
#QMAIL_DIR Maildir
MAIL_DIR    /var/spool/mail
#MAIL_FILE .mail

# Password aging controls:
#
# PASS_MAX_DAYS Maximum number of days a password may be used.
# PASS_MIN_DAYS Minimum number of days allowed between password changes.
# PASS_MIN_LEN Minimum acceptable password length.
# PASS_WARN_AGE Number of days warning given before a password expires.
#
PASS_MAX_DAYS   99999
PASS_MIN_DAYS   0
PASS_MIN_LEN    5
PASS_WARN_AGE   7
PASS_ALWAYS_WARN yes
OBSCURE_CHECKS_ENAB yes

#
# Min/max values for automatic uid selection in useradd
#
UID_MIN                  1000
UID_MAX                 60000
# System accounts
SYS_UID_MIN               201
SYS_UID_MAX               999

#
# Min/max values for automatic gid selection in groupadd
#
GID_MIN                  1000
GID_MAX                 60000
# System accounts
SYS_GID_MIN               201
SYS_GID_MAX               999

#
# If defined, this command is run when removing a user.
# It should remove any at/cron/print jobs etc. owned by
# the user to be removed (passed as the first argument).
#
#USERDEL_CMD /usr/sbin/userdel_local

#
# If useradd should create home directories for users by default
# On RH systems, we do. This option is overridden with the -m flag on
# useradd command line.
#
CREATE_HOME yes

# The permission mask is initialized to this value. If not specified, 
# the permission mask will be initialized to 022.
UMASK           077

# This enables userdel to remove user groups if no members exist.
#
USERGROUPS_ENAB yes

# Use SHA512 to encrypt password.
ENCRYPT_METHOD MD5

MD5_CRYPT_ENAB yes

/etc/pam.d/system-auth

这个配置文件可能是 /etc/pam.d/system-auth-ac 的软连接
这配置文件没动,本身就是正确的. 加了口令校验配置项.

#%PAM-1.0
# This file is auto-generated.
# User changes will be destroyed the next time authconfig is run.
auth        required      pam_env.so
auth        sufficient    pam_unix.so nullok try_first_pass
auth        requisite     pam_succeed_if.so uid >= 1000 quiet_success
auth        required      pam_deny.so

account     required      pam_unix.so
account     sufficient    pam_localuser.so
account     sufficient    pam_succeed_if.so uid < 1000 quiet
account     required      pam_permit.so

password requisite pam_cracklib.so retry=2 difok=10 minlen=6 ucredit=-1 lcredit=-1 dcredit=-1 ocredit=-1 enforce_for_root
#password requisite pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type=
password    sufficient    pam_unix.so md5 shadow nullok try_first_pass use_authtok
password    required      pam_deny.so

session     optional      pam_keyinit.so revoke
session     required      pam_limits.so
-session     optional      pam_systemd.so
session     [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
session     required      pam_unix.so

总结

开源软件是好,只要解决了编译问题,编译用-g选项不带-O2, 有个gdb, 有啥问题都可以单步明白。

相关文章
相关标签/搜索