Читать «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)

5  {

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, содержащую информацию о клиенте: