Читать «UNIX: взаимодействие процессов» онлайн - страница 275
Уильям Ричард Стивенс
12 auth_destroy(cl->cl_auth);
13 cl->cl_auth = authsys_create_default();
14 in.arg1 = atol(argv[2]);
15 if (squareproc_2(&in, &out, cl) != RPC_SUCCESS)
16 err_quit("%s", clnt_sperror(cl, argv[1]));
17 printf("result: %ld\n", out.resl);
18 exit(0);
19 }
12-13 Эти строки были добавлены в данной версии программы. Сначала мы вызываем auth_destroy для удаления предыдущей аутентификационной информации, связанной с данным дескриптором клиента (то есть дескриптор нулевой аутентификации, создаваемый по умолчанию). Затем вызов authsys_create_default создает соответствующую аутентификационную структуру Unix и мы сохраняем ее в поле cl_auth структуры CLIENT. Оставшаяся часть клиента не претерпела изменений по сравнению с листингом 16.5.
В листинге 16.8 приведен текст процедуры сервера, измененный по сравнению с листингом 16.6. Мы не приводим текст процедуры square_prog_2_freeresult, которая не меняется.
Листинг 16.8. Процедура сервера, запрашивающая аутентификацию Unix
//sunrpc/square4/server.c
1 #include "unpipc.h"
2 #include "square.h"
3 bool_t
4 squareproc_2_svc(square_in *inp, square_out *outp, struct svc_req *rqstp)
6 printf("thread %Id started, arg = %ld, auth = %d\n",
7 pr_thread_id(NULL), inp->arg1, rqstp->rq_cred.oa_flavor);
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, содержащую информацию о клиенте: