|
Программирование >> Структура ядра и системные вызовы
путем исправления соответствующей записи в файле /etc/passwd или /etc/shadow). Сменив эффективный идентификатор пользователя при выполнении этих программ, пользователи получают такой же результат, как если бы они обладали правами привилегированного пользователя. Эффективный идентификатор пользователя и эффективный идентификатор группы применяются также в тех случаях, когда процесс создает файл. Идентификатор владельца файла устанавливается равным эффективному идентификатору пользователя, от имени которого вьшолняется процесс, а идентификатор группы файла назначается в зависимости от системы: в UNIX System V.3 идентификатор группы файла устанавливается равным эффективному идентификатору группы процесса, тогда как в BSD UNIX идентификатор группы файла устанавливается равным идентификатору группы каталога, который содержит этот файл. Стандарт POSIX.l допускает применение обоих этих методов назначения идентификатора группы файла. В UNIX System V.4 идентификатор группы нового файла устанавливается равным идентификатору группы каталога, который содержит этот файл (метод BSD), если флаг set-GID этого каталога установлен. В противном случае файлу назначается тот же идентификатор группы, который имеет создавший его процесс (метод System V.3). Если для исполняемого файла установлен sticky-bm, то после заверщения процесса текст программы (код команд) остается в оперативной памяти. Благодаря этому в следующий раз при выполнении программы ядро сможет запустить этот процесс быстрее. Этот флаг зарезервирован для часто выполняемых программ, например для shell ОС UNIX и редактора vi. Устанавливать и сбрасывать для файлов sticky-bm может только привилегированный пользователь. Имя владельца и имя группы, которой принадлежит файл, поддерживаются в ОС UNIX, но стандартом POSIX как обязательные не оговариваются. Функция getpwuid преобразует идентификатор пользователя в имя пользователя, а функция getgrgid преобразует идентификатор группы в имя группы. Эти функции определены соответственно в заголовках <pwd.h> и <grp.h>. Размер файла указывается для файлов, каталогов и именованных каналов. Для файлов устройств функция longjist выводит на экран старший и младший номера устройства, которые извлекаются из поля st rdev записи struct stat. Для обеспечения быстрого доступа к этим числам в некоторых UNIX-системах используются макросы MAJOR и MINOR (они определяются в заголовке <sys/stat.h>). Если они системой не определены, то наша программа-пример определяет их явно. MINOR BITS - это число младших битов в поле st rdev, используемых для хранения младшего номера устройства (в больщинстве UNIX-систем используется 8 битов), а остальные биты поля st rdev служат для хранения старшего номера устройства. Последние два поля хранят информацию о дате последней модификации и имени файла. Они извлекаются соответственно из поля stjntime двух артуметоъ statv и path name. Ниже даны результаты выполнения представленной нами программы: % a.out /etc/motd /dev/fdO /usr/bin -rw-r-xrwx 1 joe Unix 25 July 5, 199T /etc/motd 2 тагу .admin 30 June 25, 1997 /dev/fdO 1 terry sharp 15 Oct. 16, 1996 /usr/bin crw-r-r-x drwxr-xr- 7.1.11. Функция access Функция access проверяет факт существования указанного файла и (или) права доступа, предоставляемые пользователю. Прототип Этой функции выглядит следующим образом: #include <unistd.h> int access ( const char* path name, int flag ); Аргумент path name - это путевое имя файла. Аргумент flag содержит один или несколько битовых флагов, которые определены в заголовке <unistd.h>: Битовый флаг Назначение F OK Проверяет факт существования указанного файла К ОК Проверяет, есть ли у вызывающего процесса право на чтение W OK Проверяет, есть ли у вызывающего процесса право на запись -Q Проверяет, есть ли у вызывающего процесса праю на выполнение Значение аргумента flag вызова access формируется путем побитового логического сложения одного или нескольких из этих битовых флагов. Например, следующий оператор проверяет, есть ли у пользователя права на чтение и запись файла/м5/-/УЬо/асст.с?ос: int ГС = access( /usr/foo/accGss.doc ,R OKW OK); Если значение У7й равно F OK, то функция возвращает О при наличии указанного файла, в противном случае код возврата равен -1. Если значение flag представляет собой любое сочетание ROK, WO К и л ОК, то функция access сверяет реальные идентификаторы пользователя и группы, с правами которых выполняется процесс, с идентификаторами владельца и группы указанного файла. При этом функция access определяет соответствующую категорию доступа (владелец, группа, прочие) и для каждой категории проверяются значения битовых флагов flag. Если все затребованные права доступа предоставляются, функция возвращает 0. В противном случае возвращается -1. В приведенной ниже программе to/ flccm. С функция access используется для того, чтобы определить, существует ли указанный файл. Это делается для каждого аргумента командной строки. Если указанного файла не существует, он создается и инициализируется символьной строкой Hello world. Если файл существует, программа просто читает из него данные: ♦include <sys/types.h> ♦include <unistd.h> ♦include <fcntl.h> int main (int argc, char* argv(]) { char buf1256]; int fdesc, len; while ( -argOO) ( if (access(*++argv,F OK)) новый файл ( fdesc = open(*argv,O WRONLyO CREAT,0744); write(fdesc, Hello world\n ,12); . , ) else файл существует, прочитать данные fdesc = open (*argv, 0 RD0NLY) ; while (len=read(fdesc;buf,256)) write(fdesc,buf,len); close(fdesc); } /* для каждого аргумента командной строки */ return 0; Эту несложную программу можно использовать как основу для построения программы управления базой данных. Если нужно будет создать новую базу данных, то программа будет инициализировать ее файл некоторыми начальными данными бухгалтерского учета; если файл базы данных уже существует, программа будет читать из него некоторую начальную информацию, чтобы проверить совместимость программы и файла базы данных по версиям и т.д. 7.1.12. Функции chmod, fchmod Функции chmod и fchmod изменяют права доступа к файлу для владельца, группы и прочих пользователей, а также флаги set-UID, set-GID и sticky-бит. Процесс, который вызывает одну из этих функций, должен иметь эффективный идентификатор - либо привилегированного пользователя, либо владельца файла. На базе API chmod реализованы UNIX-команды chmod. Прототипы функций chmod и fchmod вьплядят следующим образом: #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> int chmod ( const char* path name, mode t flag ); int fchmod ( Int fdesc, mode t flag ); Аргумент path name функции chmod - это путевое имя файла, а аргумент fdesc функции fchmod - дескриптор файла. Аргумент flag содержит новые права доступа и специальные флаги, которые необходимо установить для данного файла. Значение flag соответствует таковому в API open; его можно задавать либо как восьмеричное целочисленное, либо строить из макросов, определенных в заголовке <sys/stat.h>. Например, следующая функция устанавливает флаг set-UID, отменяет право на запись для категории группа и право на чтение и выполнение для категории прочие для файла /usr/joe/funny. book: ♦include <stdio.h> ♦include <sys/types.h> ♦include <sys/stat.h> tinclude <unistd.h> void change mode() { int flag = (S IWGRP S IR0TH S IX0TH); struct stat statv; if (stat ( /usr/joe/funny.boo]c , sstatv) ) perror( stat ); else ( flag = (statv.st mode S -flag) I if (chmod ( usr/joe/funny.bool< , perror( chmod ); } } . В этой программе сначала вызывается функция stat, которая выявляет текущие права доступа к файлу /usr/joe/funny.book. Затем в statv.stjnode с помощью битовой маски отменяются право на запись для категории группа и право на чтение и выполнение для категории прочие . После этого в statv.stjnode устанавливается флаг set-UID. Все остальные флаги не модифицируются. Полученный в результате аргумент flag передается в функцию chmod для внесения указанных изменений. Если вызов chmod или stat неудачен, программа вызывает функцию perror, которая вьщает диагностическое сообщение. S ISUID; flag)) в отличие от API open, в функции chmod права доступа, указанные в аргументе flag, значением /яоЛ: вызывающего процесса не модифицируются. 7.1.13. Функции chown, fchown, Ichown Функции chown и fchown изменяют идентификатор владельца и идентификатор группы указанного файла. Различаются они только первым аргументом, который обозначает файл (т.е. путевым именем или дескриптором). На базе этих API реализованы UNIX-команды chown и chgrp. Функция Ichown похожа на функцию chown, правда, имеется одно отличие: если аргумент path name - это символическая ссылка на какой-либо файл, то функция Ichown изменяет принадлежность файла-символической ссылки, тогда как функция chown изменяет принадлежность файла, на который эта ссылка указывает. Прототипы этих функций выглядят следующим образом: #include <unistd.h> #include <sys/types.h> int chown ( const char* path name, uid t uid, gid t gid ); int fchown ( int fdesc, uid t uid, gid t gid ); int Ichown ( const char* path name, uid t uid, gid t gid ); Аргумент path name - это путевое имя файла. Аргумент uid задает новый идентификатор владельца файла. Аргумент gid задает новый идентификатор группы, который должен быть присвоен файлу. Если фактическое значение uid или gid равно -1, то соответствующий идентификатор файла не изменяется. В BSD UNIX менять идентификатор владельца и идентификатор группы с помощью рассматриваемых функций может только процесс, обладающий правами привилегированного пользователя. Если, однако, эффективный идентификатор процесса совпадает с идентификатором владельца файла, а эффективный идентификатор группы или один из идентификаторов дополнительных групп, в которые входит владелец процесса, совпадает с идентификатором группы файла, то процесс может менять только идентификатор группы файла. В UNIX System V менять идентификатор пользователя и идентификатор группы файла может только процесс, чей эффективный идентификатор пользователя совпадает либо с идентификатором владельца файла, либо с идентификатором привилегированного пользователя. В POSIX.l установлено, что если переменная POSIX CHOWN RE-STRICTED определена со значением, отличным от -1, то функция chown должна вести себя так же, как в BSD UNIX. Если же эта переменная не определена, то chown должна вести себя, как в UNIX System V. Если chown вызывается процессом, который не имеет прав привилегированного пользователя, и успешно выполняется, изменяя владельца какого-либо файла, то флаги set-UID и set-GID этого файла сбрасываются. Это не позволяет пользователям создавать программы, которые можно выполнять от лица других пользователей (например, root), чтобы затем пользоваться их привилегиями. Если chown вызывается процессом с эффективным идентификатором привилегированного пользователя, то трактовка функцией chown флагов set- UID и set- GID файлов, которые она модифицирует, зависит от реализации. В UNIX System V.3 и V.4 эти флаги остаются без изменений. UNIX-программа chown реализована с помощью следующей программы testjchown. С: ♦include <iostream.h> ♦include <stdio.h> ♦include <sys/types.h ♦include <sys/stat.h> ♦include <unistd.h> ♦include <pwd.h> int main (int argc, char* argv[]) { if (argc 3) { cerr << Osage: argv[0] <! 5У. <usr name> <file> Xi .\n ; return 1; . f., ] , . struct passwd * pwd = getpwnam(argv[l]);/* преобразовать имя пользователя в UID */ uid t UID = pwd->pw uid; struct stat statv; if (UID == (uid t)-l) cerr<< Invalid user name\n ; else for (int i=2; i < argc; i++) /* для каждого из указанных файлов */ :<af (stat(argv[i] ,&statv)==0) { . if (chown (argv[i], UID, statv. st gid)) perror ( chown );) elseperror( stat ); return 0; Данная программа принимает как минимум два аргумента командной строки: первый - это имя нового владельца файла, второй и последующие аргументы - путевые имена файлов. Программа сначала преобразует заданное имя пользователя в идентификатор пользователя (с помощью функции getpwuid). Если преобразование выполнено успешно, программа обрабатывает каждый из указанных файлов следующим образом: вызывает stat для получения идентификатора группы файла, затем вызывает chown для изменения идентификатора владельца файла. Если stat или chown дает сбой, вызывается функция perror, которая выводит на экран диагностическое сообщение.
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |