Назад | Перейти на главную страницу

невозможно использовать radd / adduser, если / etc / {passwd, shadow, group} являются символической ссылкой (debian squeeze)

У меня проблемы с useradd, когда я перемещаю / etc / passwd / etc / shadow / etc / group из / etc в / home и создаю символическую ссылку, чтобы / etc / {passwd, shadow, group} соответственно указывали на / главная / {passwd, shadow, 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 это может немного отличаться):

  1. Узнайте, какой пакет принадлежит /usr/sbin/useradd:

    $ dpkg-query -S /usr/sbin/useradd
    passwd: /usr/sbin/useradd
    
  2. Установите исходник:

    $ 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
    (...)
    
  3. cd в исходный каталог:

    $ cd shadow-4.1.4.2+svn3283/
    
  4. Найдите в каталоге useraddисходный файл, который в идеале должен называться useradd.c:

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

    Бинго!

  5. Ищите сообщение об ошибке cannot open /etc/passwd (на самом деле я ищу только cannot open, поскольку вся строка не возвращает результатов):

    $ 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 системный вызов (apropos pw_open не возвращает никаких результатов), поэтому, вероятно, он реализован в этом пакете. Поищем его.

  6. Отслеживание 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 наша новая цель.

  7. Ищи commonio_open:

    $ grep -R commonio_open *
    (...)
    lib/commonio.c:int commonio_open (struct commonio_db *db, int mode)
    
  8. открыто 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? Это виновник (от man 2 open):

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

Подводя итог, useradd.c использует pw_open, который, в свою очередь, использует commonio_open, который открывает /etc/passwd используя системный вызов open с опцией O_NOFOLLOW, который отклоняет символические ссылки.

Хотя символическая ссылка может использоваться как замена файла во многих (я бы сказал, в большинстве) ситуациях, useradd довольно придирчив и отвергает его, вероятно, из-за символической ссылки /etc/passwd настоятельно предполагает, что /etc был подделан.

Почему я должен уйти passwd в /etc?

Есть несколько файлов в /etc необходимо, например, для загрузки и входа в систему (но не ограничиваясь этим): fstab, inittab, passwd, shadow и сценарии инициализации в init.d/. Любой системный администратор ожидает, что эти файлы будут там, а не привязаны к /home или где угодно.

Так что даже если бы ты мог, ты должен уйти passwd в /etc.

Кроме того, структура файловой системы в Linux четко определена, взгляните на нее здесь: http://www.pathname.com/fhs/pub/fhs-2.3.html. Также есть глава для /etc. Перемещать вещи не рекомендуется.

Доктор, мне больно, когда я это делаю.

Что ж, тогда не делай этого!

Серьезно, не помещайте такие важные файлы в неожиданное место. Что бы вы ни пытались проверить: найдите лучший способ. Если вы пытаетесь выполнить централизованную аутентификацию: используйте ldap. Или ниш, если нужно.