当/ etc / {passwd,shadow,group}是符号链接(debian squeeze)时,不能使用radd / adduser

我在使用useradd时遇到了麻烦
当我移动
/ etc / passwd文件
/ etc / shadow中
的/ etc /组
从/ etc到/ home并创建一个符号链接,以便/ etc / {passwd,shadow,group}分别指向/ home / {passwd,group}

我无法创建任何用户并使用useradd输出

root@client:/home# useradd testuser
Adding user `testuser' ...
Adding new group `testuser' (1000) ...
groupadd: cannot open /etc/group

btw useradd输出

root@client:/home# adduser testuser
useradd: cannot open /etc/passwd

解决方法

为什么useradd拒绝打开符号链接的/ etc / passwd?

要回答这个问题,我们需要看看useradd的源代码(我在Ubuntu 12.04上做了这个,在Debian上它可能略有不同):

>找出拥有/usr/sbin / useradd的软件包:

$dpkg-query -S /usr/sbin/useradd
passwd: /usr/sbin/useradd

>安装源:

$apt-get source passwd
Reading package lists... Done
Building dependency tree       
Reading state information... Done
Picking 'shadow' as source package instead of 'passwd'
(...)
dpkg-source: info: extracting shadow in shadow-4.1.4.2+svn3283
dpkg-source: info: unpacking shadow_4.1.4.2+svn3283.orig.tar.gz
dpkg-source: info: applying shadow_4.1.4.2+svn3283-3ubuntu5.1.diff.gz
(...)

> cd到源目录:

$cd shadow-4.1.4.2+svn3283/

>在目录中搜索useradd的源文件,理想情况下应该将其命名为useradd.c:

$find . -name useradd.c
./src/useradd.c

答对了!
>查找错误消息无法打开/ etc / passwd(实际上我只搜索无法打开,因为整个字符串不返回任何结果):

$grep -B 1 'cannot open' src/useradd.c
(...)
  if (pw_open (O_RDWR) == 0) {
      fprintf (stderr,_("%s: cannot open %s\n"),Prog,pw_dbname ());
(...)

-B 1表示在匹配行之前打印1行前导上下文.

这是您生成错误消息的位置.函数pw_open控制是否可以打开/ etc / passwd或是否应该抛出错误.

pw_open不是Linux syscall(apropos pw_open不会返回任何结果),所以它可能在这个包中实现.让我们来搜索它.
>跟踪pw_open会导致:

$grep -R pw_open * 
(...)
lib/pwio.c:int pw_open (int mode)
(...)

pw_open实现是:

$grep -A 3 'int pw_open (int mode)' lib/pwio.c 
int pw_open (int mode)
{
    return commonio_open (&passwd_db,mode);
}

越来越近了,但我们还没有. commonio_open是我们的新目标.
>搜索commonio_open:

$grep -R commonio_open *
(...)
lib/commonio.c:int commonio_open (struct commonio_db *db,int mode)

>打开lib / commonio.c并滚动到函数commonio_open:

int commonio_open (struct commonio_db *db,int mode)
{
(...)

    fd = open (db->filename,(db->readonly ? O_RDONLY : O_RDWR)
               | O_NOCTTY | O_NONBLOCK | O_nofollow);

你看到O_nofollow了吗?这是罪魁祸首(来自男子2开放):

O_nofollow 
      If pathname is a symbolic link,then the open fails.

总结一下,useradd.c使用pw_open,后者又使用commonio_open,它使用带有选项O_nofollow的系统调用打开/ etc / passwd,拒绝符号链接.

尽管在很多(我说的是大多数情况)情况下,符号链接可以用作文件的替换,但是useradd非常挑剔并拒绝它,可能是因为符号链接/ etc / passwd强烈暗示/ etc已被篡改.

我为什么要在/ etc中留下passwd?

/ etc中有几个文件需要引导和登录,例如(但不限于):fstab,inittab,passwd,shadow和init.d /中的init脚本.任何系统管理员都希望这些文件存在,而不是符号链接到/ home或者任何地方.

所以,即使你可以,你也应该把密码留在/ etc中.

此外,Linux中的文件系统结构已经明确定义,请在此处查看:http://www.pathname.com/fhs/pub/fhs-2.3.html.还有一章为/etc.不推荐移动.

相关文章

insmod和modprobe加-f参数导致Invalid module format错误 这...
将ArchLinux安装到U盘 几个月前入门Arch的时候上网搜了不少安...
1、安装Apache。 1)执行如下命令,安装Apache服务及其扩展包...
一、先说一下用ansible批量采集机器信息的实现办法: 1、先把...
安装配置 1. 安装vsftpd 检查是否安装了vsftpd # rpm -qa | ...
如何抑制stable_secret读取关键的“net.ipv6.conf.all.stabl...