CentOS 6 和 RHEL 6 上 linux 用户名的真正规则是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6949667/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 05:29:28  来源:igfitidea点击:

What are the real rules for linux usernames on CentOS 6 and RHEL 6?

linuxcentosusernameshadowcentos6

提问by Alan Carwile

I'm writing some web UI pages that can be used to create Linux user accounts. This web UI will be used on CentOS 6 (which is derived from RHEL 6). I'm finding inconsistent and incomplete information about what constitutes a valid Linux user name. I went to the source, examining a Linux shadow-utils source package but I did not ensure that the version I was looking at is in fact the same as that which is part of CentOS 6.

我正在编写一些可用于创建 Linux 用户帐户的 Web UI 页面。此 Web UI 将用于 CentOS 6(源自 RHEL 6)。我发现有关什么构成有效的 Linux 用户名的信息不一致且不完整。我查看了源代码,检查了一个 Linux shadow-utils 源代码包,但我并不确定我正在查看的版本实际上与 CentOS 6 中的版本相同。

Below is the code fragment I currently use, which includes copy/paste of the comments from the shadow-utils package version 4.1.4.3, plus some of my own notes, and a Java regular expression search to follow my understanding from looking at shadow-utils source.

下面是我目前使用的代码片段,其中包括从 shadow-utils 包版本 4.1.4.3 中复制/粘贴的注释,加上我自己的一些笔记,以及一个 Java 正则表达式搜索,以遵循我对 shadow- 的理解 -实用程序源。

The referenced "is_valid_name()" check in chkname.c is apparently not what is used from the useradd command on Linux, since the comments (and the C-code source) do not allow names beginning with a number. However, useradd does allow one to create an account like "1234".

chkname.c 中引用的“is_valid_name()”检查显然不是 Linux 上 useradd 命令使用的,因为注释(和 C 代码源)不允许名称以数字开头。但是,useradd 确实允许创建一个像“1234”这样的帐户。

I'd appreciate assistance adjusting from what I have now to what would be more correct, as well as info about how useradd.c is implemented with some slightly different is_valid_name function.

我很感激帮助从我现在拥有的调整到更正确的内容,以及有关如何使用一些略有不同的 is_valid_name 函数实现 useradd.c 的信息。

Thanks! Alan

谢谢!艾伦

/**
 * Define constants for use in isNameLinuxCompatible(...) method.
 *
 * The source for the Linux compatible user name rule is is_valid_name(...) a function in the "shadow" package
 * for Linux.  The source file for that function has a comment as follows:
 *      User/group names must match [a-z_][a-z0-9_-]*[$]
 * That expression is a little loose/sloppy since
 * (1) the trailing $ sign is optional, and
 * (2) uppercase A-Z is also ok (and case is significant, 'A' != 'a').
 *
 * We deal with (1) by using the [$]? form where the ? means zero or more characters (aka "greedy").
 * We deal with (2) by using the CASE_INSENSITIVE option.
 *
 * Another way to express this is:
 *  1st character:                      a-z_         required at least one char
 *  chars other than first and last:    a-z0-9_-     optional
 *  last character:                     $            optional
 * Max length is 31.  Min length is 1.
 *
 * NOTE: The initial ^ and final $ below are important since we need the entire string to satisfy the rule,
 * from beginning to end.
 *
 * See http://download.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html for reference info on pattern matching.
 */

private static final String  LINUX_USERNAME_REGEX     = "^[a-z_][a-z0-9_-]*[$]?$";
private static final Pattern LINUX_USERNAME_PATTERN   = Pattern.compile(LINUX_USERNAME_REGEX, Pattern.CASE_INSENSITIVE);
private static final int     LINUX_USERNAME_MINLENGTH = 1;
private static final int     LINUX_USERNAME_MAXLENGTH = 31;

/**
 * See if username is compatible with standard Linux rules for usernames, in terms of length and
 * in terms of content.
 *
 * @param username the name to be checked for validity
 * @return true if Linux compatible, else false
 */
public boolean isNameLinuxCompatible (final String username) {
    boolean nameOK = false;
    if (username != null) {
        int len = username.length();
        if ((len >= LINUX_USERNAME_MINLENGTH) && (len <= LINUX_USERNAME_MAXLENGTH)) {
            Matcher m = LINUX_USERNAME_PATTERN.matcher(username);
            nameOK = m.find();
        }
    }
    return (nameOK);
}

采纳答案by Pablo Castellazzi

A basic gnu/linux username is a 32 character string (useradd(8)). This is a legacy format from the BSD 4.3 standard. passwd(5)adds some additional restrictions like, do not use capital letters, do not use dots, do not end it in dash, it must not include colons.

基本的 gnu/linux 用户名是一个 32 个字符的字符串 ( useradd(8))。这是来自 BSD 4.3 标准的遗留格式。passwd(5)添加了一些额外的限制,例如,不要使用大写字母,不要使用点,不要以破折号结尾,不能包含冒号。

To be on the safe side of things, follow the same rules of a C identifier:

为了安全起见,请遵循 C 标识符的相同规则:

([a-z_][a-z0-9_]{0,30})

That's half the problem. Modern GNU/Linux distributions use PAM for user authentication. With it you can choose any rule you want and also any data source.

这是问题的一半。现代 GNU/Linux 发行版使用 PAM 进行用户身份验证。有了它,您可以选择所需的任何规则以及任何数据源。

Since you are writing a program it's better to define your own format, and then use something like pam_ldap, pam_mysql, etc. to access it.

既然你正在编写一个程序这是更好地定义自己的格式,然后使用类似的pam_ldappam_mysql等来访问它。