return -1; /* или пустая строка */

u = strtol(name, &endptr, 10); /* Для удобства вызывающего */

if (*endptr == '\0') /* разрешение числовой строки */

return u;

pwd = getpwnam(name);

if (pwd == NULL)

return -1;

return pwd->pw_uid;

}

char * /* Возвращает имя, соответствующее 'gid', или NULL при ошибке */

groupNameFromId(gid_t gid)

{

struct group *grp;

grp = getgrgid(gid);

return (grp == NULL)? NULL: grp->gr_name;

}

gid_t /* Возвращает идентификатор группы, */

/* соответствующего 'name',или -1 при ошибке */

groupIdFromName(const char *name)

{

struct group *grp;

gid_t g;

char *endptr;

if (name == NULL || *name == '\0') /* Возвращает ошибку, если передан NULL*/

return -1; /* или пустая строка */

g = strtol(name, &endptr, 10); /* Для удобства вызывающего */

if (*endptr == '\0') /* разрешение числовой строки */

return g;

grp = getgrnam(name);

if (grp == NULL)

return -1;

return grp->gr_gid;

}

users_groups/ugid_functions.c

Сканирование всех записей в файлах паролей и групп

Функции setpwent(), getpwent() и endpwent() используются для выполнения последовательного сканирования записей в файле паролей.

#include

struct passwd *getpwent(void);

Возвращает указатель при успешном завершении или NULL в случае конца потока или при ошибке

void setpwent(void);

void endpwent(void);

Функция getpwent() поочередно возвращает записи из файла паролей, выдавая NULL, когда записей уже больше нет (или при возникновении ошибки). При первом вызове функция автоматически открывает файл паролей. Когда работа с файлом завершена, для его закрытия вызывается функция endpwent().

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

struct passwd *pwd;

while ((pwd = getpwent())!= NULL)

printf("%-8s %5ld\n", pwd->pw_name, (long) pwd->pw_uid);

endpwent();

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

Функции getgrent(), setgrent() и endgrent() выполняют аналогичные задачи для файла групп. Здесь не будет приводиться их описание, поскольку они аналогичны уже рассмотренным функциям для файла паролей. Соответствующие подробности, относящиеся к этим функциям, можно найти на страницах руководства.

Извлечение записей из теневого файла паролей

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

#include

struct spwd *getspnam(const char *name);

Возвращает при успешном завершении указатель или NULL, если запись не найдена либо произошла ошибка

struct spwd *getspent(void);

Возвращает указатель при успешном завершении или NULL в случае конца потока либо при ошибке

void setspent(void);

void endspent(void);

Мы не станем рассматривать эти функции во всех подробностях, поскольку их работа похожа на работу соответствующих функций, относящихся к файлу паролей. (Эти функции не указаны в SUSv3 и представлены не во всех реализациях UNIX.)

Функции getspnam() и getspent() возвращают указатели на структуру типа spwd. Она имеет следующую форму:

struct spwd {

char *sp_namp; /* Имя для входа в систему (имя пользователя) */

char *sp_pwdp; /* Зашифрованный пароль */

/* Остальные поля поддерживают «устаревание пароля», дополнительное средство,

заставляющее пользователей регулярно менять свои пароли, чтобы, даже если

злоумышленник сумел получить пароль, тот со временем стал для него

бесполезным. */

long sp_lstchg; /* Время последнего изменения пароля (количество

дней, прошедших с 1 января 1970 года) */

long sp_min; /* Минимальное количество дней между сменами пароля */

long sp_max; /* Максимальное количество дней до требуемой смены пароля */

long sp_warn; /* Количество дней, за которое пользователь

заранее получает предупреждение о скором

истечении срока действия пароля */

long sp_inact; /* Количество дней после истечения срока действия пароля

до признания учетной записи неактивнойи заблокированной */

long sp_expire; /* Дата, когда истекает срок действия учетной

записи (количество дней, прошедших с 1 января 1970 года) */

unsigned long sp_flag; /* Зарезервировано для будущего использования */

};

Применение функции getspnam() будет показано в листинге 8.2.

8.5. Шифрование пароля и аутентификация пользователя
Перейти на страницу:

Похожие книги