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.