Программирование PC FAQ программирования Linux: информация о системе Sat, May 18 2024  

Поделиться

Нашли опечатку?

Пожалуйста, сообщите об этом - просто выделите ошибочное слово или фразу и нажмите Shift Enter.

FAQ программирования Linux: информация о системе Печать
Добавил(а) microsin   

Здесь приведен перевод главы 4 из FAQ по программированию Linux [1], посвященной работе с системной информацией. Описание незнакомых терминов и аббревиатур см. в Словарике статьи [2].

[Список вопросов]

4. Информация о системе

  4.1 Как узнать, сколько памяти в моей системе?

  4.2 Как проверить пароль пользователя?

    4.2.1 Как получить пароль пользователя?

    4.2.2 Как получить теневые пароли (shadow passwords) по uid?

    4.2.3 Как проверить пароль пользователя?

4.1 Как узнать, сколько памяти в моей системе?
==============================================

Это еще один "Часто остающийся без ответа вопрос". В большинстве случаев вы даже не должны ПЫТАТЬСЯ это выяснить.

Если же все-таки это по какой-то причине нужно, то это можно сделать, однако способ очень зависит от системы. Например, на Solaris вы можете использовать sysconf(_SC_PHYS_PAGES) и sysconf(_SC_PAGESIZE). На FreeBSD вы можете использовать sysctl(). На Linux вы можете прочитать и пропарсить /proc/meminfo (будьте внимательны, поскольку исторически существует несколько форматов этого файла). На других системах могут быть свои методы. Портируемых методов скорее всего не существует.

На HP-UX (9 и 10) можно использовать следующий код:

   struct pst_static pst;
   
   if (pstat_getstatic(&pst, sizeof(pst), (size_t) 1, 0) != -1)
   {
      printf(" Page Size: %lu\n", pst.page_size);
      printf("Phys Pages: %lu\n", pst.physical_memory);
   }

4.2 Как проверить пароль пользователя?
======================================

4.2.1 Как получить пароль пользователя?
---------------------------------------

По традиции на большинстве UNIX-подобных систем пароли пользователя хранятся в файле /etc/passwd. У него обычно следующий формат:

username:password:uid:gid:gecos field:home directory:login shell

Хотя это изменилось со временем, теперь информация о пользователях может храниться на других хостах, или необязательно в файле /etc/passwd. На современных реализациях также сделаны файлы теневых паролей (shadow password files), где хранятся пароли и чувствительная в плане безопасности информация. Этот файл могут читать только привилегированные пользователи.

Пароль обычно не хранится как чистый открытый текст, он зашифрован по соображениям безопасности.

POSIX определяет набор утилит, которые могут использоваться для доступа к этой базе данных паролей по запросу. Самый быстрой путь получения отдельной записи для пользователя - вызов подпрограмм getpwnam() и getpwuid(). Оба они вернут указатель на структуру passwd, которая хранит информацию пользователей в различных полях. Функция getpwnam() принимает строку с именем пользователя, а функция getpwuid() принимает идентификатор пользователя uid (тип uid_t, как это определено POSIX). Обе они возвратят NULL в случае неудачи.

Однако, как упоминалось выше, теневая база паролей существует на большинстве современных систем для хранения чувствительной информации пользователя, а именно пароля. Некоторые системы возвратят пароль только если вызов был от uid суперпользователя, другие требуют использовать другие функции для доступа к теневой базе паролей. Если это ваш случай, то нужно вызвать функцию getspnam(), которая принимает имя пользователя и вернет структуру spwd. И опять-таки, чтобы этот вызов был успешным, у вас должны быть соответствующие привилегии. На некоторых системах, в частности HP-UX и SCO, вам может понадобиться использовать вместо этого функцию getprpwnam().

4.2.2 Как получить теневые пароли (shadow passwords) по uid?
------------------------------------------------------------

Моя система использует набор подпрограмм getsp* для получения чувствительной пользовательской информации. Однако нет функции getspuid(), есть только getspnam(). Как работать с этим, и как получить информацию по uid?

Обходной путь довольно прост. Следующая функция должна помочь выполнить задачу:

   #include < stdlib.h>
   #include < stdio.h>
   
   #include < pwd.h>
   #include < shadow.h>
   
   struct spwd *getspuid(uid_t pw_uid)
   {
      struct spwd *shadow;
      struct passwd *ppasswd;
   
      if( ((ppasswd = getpwuid(pw_uid)) == NULL)
         || ((shadow = getspnam(ppasswd->pw_name)) == NULL))
       return NULL;
   
      return shadow;
   }

Существует проблема в том, что некоторые системы не хранят uid или другую информацию в теневой базе данных.

4.2.3 Как проверить пароль пользователя?
----------------------------------------

Основная проблема здесь в том, что существуют различные системы аутентификации, пароли не всегда то, что можно увидеть. Также с традиционным методом одностороннего шифрования, используемым на большинстве UNIX (из коробки), алгоритм шифрования может отличаться. Некоторые системы используют однонаправленное шифрование DES, другие наподобие интернационального релиза FreeBSD используют MD5.

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

   /* На входе у нас пароль в виде открытого текста plainpw, а также
    * зашифрованный пароль cryptpw. В случае совпадения функция
    * вернет 1, иначе 0. */
   int check_pass(const char *plainpw, const char *cryptpw)
   {
      return strcmp(crypt(plainpw,cryptpw), cryptpw) == 0;
   }

Это работает, поскольку соль, используемая при шифровании пароля, сохраняется как начальная подстрока зашифрованного значения.

Предупреждение: на некоторых системах шифрование пароля обычно делается с вариантом шифрования, который называется bigcrypt().

[Ссылки]

1. Unix Programming FAQ (v1.37) site:opennet.ru.
2. FAQ программирования Linux: управление процессами.
3Опции GCC для поддержки отладки.

 

Добавить комментарий


Защитный код
Обновить

Top of Page