POSIX-совместимый способ получить имя пользователя, связанное с идентификатором пользователя.

debsecanпроверяет установленные пакеты по умолчанию, поэтому все, что вам нужно сделать, это отфильтровать его вывод (, поскольку в нем перечислены все уязвимости, влияющие на установленные пакеты, что означает, что он часто перечисляет несколько уязвимостей для каждого пакета):

debsecan | awk '/remotely exploitable/ { vuln[$2]++ } END { for (package in vuln) print package }' | sort

Чтобы получить лучшие результаты, вы, конечно, должны указать комплект.

Вы также можете использовать debsecan-create-cronдля создания задания cron, которое будет отправлять вам отчет по электронной почте каждый день.

23
12.09.2019, 17:16
4 ответа

Один из распространенных способов сделать это — проверить, существует ли нужная вам программа и доступна ли она на вашем PATH. Например:

get_username(){
  uid="$1"

  # First try using getent
  if command -v getent > /dev/null 2>&1; then 
    getent passwd "$uid" | cut -d: -f1

  # Next try using the UID as an operand to id.
  elif command -v id > /dev/null 2>&1 && \
       id -nu "$uid" > /dev/null 2>&1; then
    id -nu "$uid"

  # Next try perl - perl's getpwuid just calls the system's C library getpwuid
  elif command -v perl >/dev/null 2>&1; then
    perl -e '@u=getpwuid($ARGV[0]);
             if ($u[0]) {print $u[0]} else {exit 2}' "$uid"

  # As a last resort, parse `/etc/passwd`.
  else
      awk -v uid="$uid" -F: '
         BEGIN {ec=2};
         $3 == uid {print $1; ec=0; exit 0};
         END {exit ec}' /etc/passwd
  fi
}

Поскольку POSIX idне поддерживает аргументы UID, предложение elifдля idдолжно проверять не только наличие idв PATH, но также и его выполнение без ошибок. Это означает, что он может запустить idдважды, что, к счастью, не окажет заметного влияния на производительность. Также возможно, что и id, и awkбудут запущены с одинаковым незначительным снижением производительности.

Кстати, при использовании этого метода нет необходимости сохранять выходные данные. Будет запущен только один из них, поэтому только один из них будет печатать выходные данные для возврата функции.

15
27.01.2020, 19:42

В POSIX нет ничего, что могло бы помочь, кроме id. Попытка idи возвращение к синтаксическому анализу /etc/passwd, вероятно, настолько переносимы, насколько это возможно на практике.

BusyBox idне принимает идентификаторы пользователей, но системы с BusyBox обычно представляют собой автономные встраиваемые системы, где разбора /etc/passwdдостаточно.

Если вы столкнулись с системой, отличной от -GNU, где idне принимает идентификаторы пользователей, вы также можете попробовать вызватьgetpwuidчерез Perl, если он доступен:

username=$(perl -e 'print((getpwuid($ARGV[0]))[0])) 2>/dev/null
if [ -n "$username" ]; then echo "$username"; return; fi

Или Питон:

if python -c 'import pwd, sys; print(pwd.getpwuid(int(sys.argv[1]))).pw_name' 2>/dev/null; then return; fi
7
27.01.2020, 19:42

В общем, я бы не рекомендовал этого делать. Сопоставление имен пользователей с uid не одно -в -, и предположения о кодировании, что вы можете преобразовать обратно из uid для получения имени пользователя, сломают ситуацию. Например, я часто запускаю контейнеры пространств имен полностью root -free user -, заставляя файлы passwdи groupв контейнере сопоставлять имена всех пользователей и групп с идентификатором 0; это позволяет устанавливать пакеты без сбоев chown. Но если что-то попытается преобразовать 0 обратно в uid и не получит ожидаемого результата, оно безвозмездно сломается. Итак, в этом примере вместо обратного преобразования и сравнения имен пользователейвы должны преобразовать в uids и сравнить в этом пространстве.

Если вам действительно нужно выполнить эту операцию, можно было бы сделать semi -переносимым, если вы root, создав временный файл, chownдобавив его в uid, а затем используя lsчтобы прочитать и проанализировать имя владельца. Но я бы просто использовал хорошо -известный подход, который не стандартизирован, но «переносим на практике», как один из тех, которые вы уже нашли.

Но опять же, не делайте этого. Иногда что-то, что трудно сделать, посылает вам сообщение.

3
27.01.2020, 19:42

POSIX определяетgetpwuidкак стандартную функцию C для поиска в пользовательской базе данных идентификатора пользователя, позволяющего преобразовывать идентификатор в имя пользователя. Я скачал исходный код для GNU coreutils и вижу, что эта функция используется в их реализации таких утилит, как idи ls.

В качестве обучающего упражнения я написал эту быструю -и -грязную программу на языке C, чтобы она просто выполняла роль оболочки для этой функции. Имейте в виду, что я не программировал на C со времен колледжа (много лет назад )и я не собираюсь использовать это в производстве, но я решил опубликовать это здесь в качестве доказательства концепции (если кто-то хочет отредактировать, не стесняйтесь):

#include <stdio.h>
#include <stdlib.h>  /* atoi */
#include <pwd.h>

int main( int argc, char *argv[] ) {
    uid_t uid;
    if ( argc >= 2 ) {
        /* NB: atoi returns 0 (super-user ID) if argument is not a number) */
        uid = atoi(argv[1]);
    }
    /* Ignore any other arguments after the first one. */
    else {
        fprintf(stderr, "One numeric argument must be supplied.\n");
        return 1;
    }

    struct passwd *pwd;
    pwd = getpwuid(uid);
    if (pwd) {
        printf("The login name for %d is: %s\n", uid, pwd->pw_name);
        return 0;
    }
    else {
        fprintf(stderr, "Invalid user ID: %d\n", uid);
        return 1;
    }
}

У меня не было возможности протестировать его с помощью NIS/LDAP, но я заметил, что если в /etc/passwdесть несколько записей для одного и того же пользователя, он игнорирует все, кроме первого.

Пример использования:

$./get_user ""
The login name for 0 is: root

$./get_user 99
Invalid user ID: 99
6
27.01.2020, 19:42

Теги

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