8 if (rqstp-rq_cred.oa_flavor == AUTH_SYS) {
9 struct authsys_parms *au;
10 au = (struct authsys_parms *)rqstp-rq_clntcred;
11 printf("AUTH_SYS: host %s, uid %ld, gid %ld\n",
12 au-aup_machname, (long) au-aup_uid, (long) au-aup_gid);
13 }
14 sleep(5);
15 outp-res1 = inp-arg1 * inp-arg1;
16 printf("thread %ld done\n", pr_thread_id(NULL));
17 return(TRUE);
18 }
6-8 Теперь мы используем указатель на структуру svc_req, которая всегда передается в качестве одного из аргументов процедуры сервера:
struct svc_req {
u_long rq_prog; /* номер программы */
u_long rq_vers; /* номер версии */
u_long rq_proc; /* номер процедуры */
struct opaque_auth rq_cred:/* данные о клиенте */
caddr_t rq_clntcred; /* готовые данные (только для чтения) */
SVCXPRT *rq_xprt; /* транспортный дескриптор */
};
struct opaque_auth {
enum_t oa_flavor; /* flavor: константа AUTH_xxx */
caddr_t oa_base; /* адрес дополнительной аутентификационной информации */
u_int oa_length; /* не должно превосходить MAX_AUTH_BYTES */
};
Поле rq_cred содержит неформатированную информацию о клиенте, а его поле oa_flavor содержит целое число, определяющее тип аутентификации. Термин «неформатированная» означает, что библиотека не обработала информацию, на которую указывает oa_base. Но если тип идентификации относится к одному из поддерживаемых библиотекой, то в готовой информации о клиенте, на которую указывает rq_clntcred, содержится некоторая структура, соответствующая данному типу аутентификации. Программа выводит тип аутентификации и прове-9_12 ряет, соответствует ли он AUTH_SYS.
Для аутентификации Unix указатель на готовую информацию (rq_clntcred) указывает на структуру authsys_parms, содержащую информацию о клиенте:
struct authsys_parms {
u_long aup_time; /* время создания информации */
char *aup_machname; /* имя узла клиента */
uid_t aup_uid; /* действующий идентификатор пользователя */
gid_t aup_gid; /* действующий идентификатор группы */
u_int aup_len; /* количество элементов в aup_gids[] */
gid_t *aup_gidsl; /* дополнительные идентификаторы группы */
};
Мы получаем указатель на эту структуру и выводим имя узла клиента, его EUID и EGID.
Запустив сервер и один экземпляр клиента, посмотрим на выводимый сервером текст:
solaris % server
thread 1 started, arg = 44, auth = 1
AUTH_SYS: host solaris.kohala.com, uid 765, gid 870
thread 1 done
Аутентификация Unix используется редко, поскольку ее легко обойти. Мы можем легко построить собственные пакеты RPC, содержащие аутентификационную информацию в формате Unix, присвоив идентификатору пользователя и группы произвольные значения, и отправить их на сервер. Сервер никак не может проверить, те ли мы, кем представляемся.