Пользователи по доступу разбиваются на группы . Каждый процесс
имеет также и групповой id-шник . В сумме эти 2 id-шника есть persona .
Процесс может менять собственный persona.
Также каждый файл имеет user id и group id . В линуксе есть 2 базы - одна для
зарегистрированных пользователей , вторая - для групп .
Каждый пользовательский аккаунт , кроме id , имеет user name .
Пользователь может принадлежать нескольким группам .
Каждый процесс имеет 3 группы параметров :
1. effective user ID
2. effective group ID
3. supplementary group IDs
Нельзя произвольно менять пользовательский и групповой id-шники , можно лишь
назначать уже существующие .
Функция int getgroups (int count, gid_t *groups) возвращает IDs процесса .
Функция int seteuid (uid_t neweuid) устанавливает новый effective user ID для процесса .
Функция int setegid (gid_t newgid) устанавливает новый int setegid (gid_t newgid) для процесса .
Функция int getgrouplist (const char *user, gid_t group, gid_t *groups, int *ngroups) сканирует групповую базу данных .
Пример использования последней :
gid_t * supplementary_groups (char *user)
{
int ngroups = 16;
gid_t *groups = (gid_t *) xmalloc (ngroups * sizeof (gid_t));
struct passwd *pw = getpwnam (user);
if (pw == NULL)
return NULL;
if (getgrouplist (pw->pw_name, pw->pw_gid, groups, &ngroups) < 0)
{
groups = xrealloc (ngroups * sizeof (gid_t));
getgrouplist (pw->pw_name, pw->pw_gid, groups, &ngroups);
}
return groups;
}
Следующий пример показывает , как изменить effective user ID .
#include < stdio.h >
#include < sys/types.h >
#include < unistd.h >
#include < stdlib.h >
/* Remember the effective and real UIDs. */
static uid_t euid, ruid;
/* Restore the effective UID to its original value. */
void do_setuid (void)
{
int status;
#ifdef _POSIX_SAVED_IDS
status = seteuid (euid);
#else
status = setreuid (ruid, euid);
#endif
if (status < 0) {
fprintf (stderr, "Couldn't set uid.\n");
exit (status);
}
}
/* Set the effective UID to the real UID. */
void undo_setuid (void)
{
int status;
#ifdef _POSIX_SAVED_IDS
status = seteuid (ruid);
#else
status = setreuid (euid, ruid);
#endif
if (status < 0) {
fprintf (stderr, "Couldn't set uid.\n");
exit (status);
}
}
/* Main program. */
int main (void)
{
/* Remember the real and effective user IDs. */
ruid = getuid ();
euid = geteuid ();
undo_setuid ();
/* Do the game and record the score. */
...
}
Правила для изменения привилегий :
1.Не нужно без особой на то необходимости давать процессам рут-овские права
2.Использование команд execlp и execvp - это потенциальный риск
3.При изменении effective user ID , его всегда нужно возвращать к actual user's ID
Для идентификации пользователей можно использовать функции :
char * getlogin (void) - имя пользователя или логин
База данных пользователей обычно живет в `/etc/passwd' .
Для доступа в нее используется структура struct passwd
Функция для чтения struct passwd * fgetpwent (FILE *stream)
Функция для записи в базу int putpwent (const struct passwd *p, FILE *stream)
База групп обычно лежит в '/etc/group'.
Для доступа в нее используется структура struct group
Функция для поиска группы struct group * getgrgid (gid_t gid)
Функция для сканирования групп struct group * fgetgrent (FILE *stream)
Следующий пример печатает информацию о пользователе , выполняющем эту программу :
#include < grp.h >
#include < pwd.h >
#include < sys/types.h >
#include < unistd.h >
#include < stdlib.h >
int main (void)
{
uid_t me;
struct passwd *my_passwd;
struct group *my_group;
char **members;
/* Get information about the user ID. */
me = getuid ();
my_passwd = getpwuid (me);
if (!my_passwd)
{
printf ("Couldn't find out about user %d.\n", (int) me);
exit (EXIT_FAILURE);
}
/* Print the information. */
printf ("I am %s.\n", my_passwd->pw_gecos);
printf ("My login name is %s.\n", my_passwd->pw_name);
printf ("My uid is %d.\n", (int) (my_passwd->pw_uid));
printf ("My home directory is %s.\n", my_passwd->pw_dir);
printf ("My default shell is %s.\n", my_passwd->pw_shell);
/* Get information about the default group ID. */
my_group = getgrgid (my_passwd->pw_gid);
if (!my_group)
{
printf ("Couldn't find out about group %d.\n",(int) my_passwd->pw_gid);
exit (EXIT_FAILURE);
}
/* Print the information. */
printf ("My default group is %s (%d).\n",
my_group->gr_name, (int) (my_passwd->pw_gid));
printf ("The members of this group are:\n");
members = my_group->gr_mem;
while (*members)
{
printf (" %s\n", *(members));
members++;
}
return EXIT_SUCCESS;
}
|
|