Что такое "вход в подсистему"?

sed -E 's/([^\t]+)\t([^\t]+)/\1-\2/g'

Пояснение

  • sed -E 's/foo/bar/g':запустить sedс -Eрасширенным регулярным выражением, заменив fooна bar, несколько раз в строке /g.
  • ([^\t]+)\t([^\t]+):соответствует не -символу табуляции [^\t], состоящему из одного или нескольких символов +, и фиксирует его в группе ([^\t]+). Затем следует табуляция, затем символы табуляции, отличные от -, снова в другой группе захвата.
  • \1-\2:замените это первой группой захвата, -, затем второй группой захвата. По сути, замените вкладку на -.

Почему это работает

sedявляется "жадным", т.е. пытается захватить как можно больше символов. Следовательно, две группы захвата будут стараться быть как можно дольше. например. он захватит все a antartica(, заменив его наa-antartica). При следующем запуске поиска он уже прошел antartica, и снова начинает поиск на вкладке после этого слова. Следовательно, следующим совпадением будет 1 1, которое будет заменено на 1-1. Затем этот шаблон будет повторяться для каждой пары столбцов. Жадный +важен. Если вы опустите его, шаблон просто изменит каждую вкладку.

0
26.10.2021, 21:27
1 ответ

Вход в подсистему кажется действительно -плохо документированной функцией. Чтобы разобраться, может понадобиться немного поиска по исходному коду. Давайте посмотрим на Debian 11login.c.

Часть, связанная с входом в подсистему , начинается с строки 1151:

if (pwd->pw_shell[0] == '*') {  /* subsystem root */
        pwd->pw_shell++;    /* skip the '*' */
        subsystem (pwd);    /* figure out what to execute */
        subroot = true; /* say I was here again */
        endpwent ();    /* close all of the file which were */
        endgrent ();    /* open in the original rooted file */
        endspent ();    /* system. they will be re-opened */
#ifdef  SHADOWGRP
        endsgent ();    /* in the new rooted file system */
#endif
        goto top;   /* go do all this all over again */
}

Если звездочка обнаружена в начале поля shell, звездочка удаляется (, поэтому вы никогда не увидите *-bashв списке процессов ), а функция subsystem()вызывается для входа этого пользователя. Здесь pwd— это структура, содержащая информацию, эквивалентную пользовательской строке в /etc/passwd.

Когда инициируется вход в подсистему, вся обработка паролей и групповых записей также прекращается. Из комментариев здесь вы должны догадаться, что вход в подсистему как-то связан с chroot().

goto top;возвращается к строке #717 , эффективно перезапуская процесс аутентификации и установки сеанса -, теперь используя файлы конфигурации внутри chroot.

Функция subsystem()определена в sub.c-фактически, это единственная функция в этом файле:

/*
 * subsystem - change to subsystem root
 *
 *  A subsystem login is indicated by the presence of a "*" as
 *  the first character of the login shell.  The given home
 *  directory will be used as the root of a new filesystem which
 *  the user is actually logged into.
 */

void subsystem (const struct passwd *pw)
{
    /*
     * The new root directory must begin with a "/" character.
     */

    if (pw->pw_dir[0] != '/') {
        printf (_("Invalid root directory '%s'\n"), pw->pw_dir);
        SYSLOG ((LOG_WARN, BAD_SUBROOT2, pw->pw_dir, pw->pw_name));
        closelog ();
        exit (EXIT_FAILURE);
    }

    /*
     * The directory must be accessible and the current process
     * must be able to change into it.
     */

    if (   (chdir (pw->pw_dir) != 0)
        || (chroot (pw->pw_dir) != 0)) {
        (void) printf (_("Can't change root directory to '%s'\n"),
                       pw->pw_dir);
        SYSLOG ((LOG_WARN, NO_SUBROOT2, pw->pw_dir, pw->pw_name));
        closelog ();
        exit (EXIT_FAILURE);
    }
}

И вот что у нас есть :a логин подсистемы — это логин, chroot()привязанный к домашнему каталогу пользователя, как указано в /etc/passwd. Например, если у вас есть пользователь subsys, определенный таким образом в/etc/passwd:

subsys:x:999:999:Subsystem login example:/home/subsys:*chrooted*

Когда этот пользователь входит в систему, используя login(, т. е. с текстовой консоли или через последовательный порт ), пользователь будет chroot, так что он увидит свой домашний каталог /home/subsysкак /. Затем процесс аутентификации повторяется с использованием файлов конфигурации в /home/subsys/etc.

Обратите внимание, что в случае входа в подсистему содержимое поля оболочки фактического /etc/passwdпосле первого символа *фактически игнорируется. Как только chroot будет выполнен, процесс loginбудет читать /home/subsys/etc/passwdдля реальной оболочки, которая будет использоваться для этого пользователя.

Как всегда, при настройке chroot вы должны убедиться, что все необходимые файлы библиотек, файлы конфигурации и устройства существуют в chroot, так как программы, запущенные в chroot, не смогут получить доступ к чему-либо за пределами chroot. Таким образом, в этом примере вам нужно будет создать хотя бы минимальный /home/subsys/lib, /home/subsys/etc(, включая как минимум /home/subsys/etc/passwd, /home/subsys/etc/shadow, /home/subsys/etc/pam.d/loginи, возможно, другие файлы )и обычно не менее /home/subsys/dev/null.

В зависимости от того, для чего вы используете вход в подсистему, вам могут понадобиться и другие устройства :для оболочек, вам, вероятно, понадобится /home/subsys/dev/ptmxи файловая система devptsв /home/subsys/dev/pts. Вы можете настроить их так:

# these steps need only be done once:
mkdir -p /home/subsys/dev/pts
mknod /home/subsys/dev/null c 1 3
mknod /home/subsys/dev/ptmx c 5 2
chmod 0666 /home/subsys/dev/null /home/subsys/dev/ptmx
# this needs to be re-done after every boot:
mount -t devpts none /home/subsys/dev/pts

Таким образом, ваш /home/subsys/etc/passwdдолжен иметь запись для chroot-пользователя subsys, что-то вроде этого:

subsys:x:999:999:A subsystem user:/subsyshome:/bin/bash

Это будет означать, что фактический домашний каталог пользователя будет находиться в /home/subsys/subsyshome, и вам также потребуется указать /home/subsys/bin/bashи все необходимые для него библиотеки.

2
27.10.2021, 11:42

Теги

Похожие вопросы