当/ etc / {passwd,shadow,group}是符号链接(debian squeeze)时,
我在使用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 答对了! $grep -B 1 'cannot open' src/useradd.c (...) if (pw_open (O_RDWR) == 0) { fprintf (stderr,_("%s: cannot open %sn"),Prog,pw_dbname ()); (...) -B 1表示在匹配行之前打印1行前导上下文. 这是您生成的错误消息的位置.函数pw_open控制是否可以打开/ etc / passwd或是否应该抛出错误. pw_open不是Linux syscall(apropos 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是我们的新目标. $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.还有一章为 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |