From 26a60f90c7a143e29793cddc721b8e5427fa2a6c Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Mon, 1 Jun 1998 13:10:54 +0000 Subject: [PATCH] Update. 1998-06-01 Thorsten Kukuk * nis/nis_call.c: Make directory search faster. * nis/nis_callback.c: Insert public key of user in callback data. * nis/nis_clone_obj.c: Make size from type u_long, not u_int. * nis/nis_creategroup.c: Check for NULL pointer, fill in more fields. * nis/nis_findserv.c: Rename __pmap_getport to __pmap_getnisport. * nis/nis_intern.h: Remove duplicated prototype. 1998-06-01 Thorsten Kukuk * sunrpc/auth_des.c: Move prototypes from here ... * sunrpc/rpc/auth.h: ... to here. * sunrpc/clnt_tcp.c: Add more control flags. * sunrpc/clnt_udp.c: Likewise. * sunrpc/netname.c (host2netname): Remove prefixing dot from domainname. * sunrpc/rpc/clnt.h: Document, which control flags are not implementable. * sunrpc/svcauth_des.c: Use key_decryptsession_pk to avoid deadlock. --- ChangeLog | 30 +++++++++++ nis/nis_call.c | 114 +++++++++++++++++++++++++++++------------- nis/nis_callback.c | 97 +++++++++++++++++++++++++++++------ nis/nis_clone_obj.c | 4 +- nis/nis_creategroup.c | 11 +++- nis/nis_findserv.c | 12 +++-- nis/nis_intern.h | 2 - sunrpc/auth_des.c | 10 ++-- sunrpc/clnt_tcp.c | 62 +++++++++++++++++++++-- sunrpc/clnt_udp.c | 54 ++++++++++++++++++++ sunrpc/netname.c | 1 + sunrpc/rpc/auth.h | 3 ++ sunrpc/rpc/clnt.h | 36 +++++++------ sunrpc/svcauth_des.c | 14 +++++- 14 files changed, 360 insertions(+), 90 deletions(-) diff --git a/ChangeLog b/ChangeLog index a3f71f9c8c..fe910c2e7a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,33 @@ +1998-06-01 Thorsten Kukuk + + * nis/nis_call.c: Make directory search faster. + + * nis/nis_callback.c: Insert public key of user in callback data. + + * nis/nis_clone_obj.c: Make size from type u_long, not u_int. + + * nis/nis_creategroup.c: Check for NULL pointer, fill in more fields. + + * nis/nis_findserv.c: Rename __pmap_getport to __pmap_getnisport. + + * nis/nis_intern.h: Remove duplicated prototype. + +1998-06-01 Thorsten Kukuk + + * sunrpc/auth_des.c: Move prototypes from here ... + * sunrpc/rpc/auth.h: ... to here. + + * sunrpc/clnt_tcp.c: Add more control flags. + * sunrpc/clnt_udp.c: Likewise. + + * sunrpc/netname.c (host2netname): Remove prefixing dot from + domainname. + + * sunrpc/rpc/clnt.h: Document, which control flags are not + implementable. + + * sunrpc/svcauth_des.c: Use key_decryptsession_pk to avoid deadlock. + 1998-05-29 Ulrich Drepper * locale/loadlocale.c (_nl_load_locale): Don't allow too small diff --git a/nis/nis_call.c b/nis/nis_call.c index affae099cf..957399ee98 100644 --- a/nis/nis_call.c +++ b/nis/nis_call.c @@ -31,6 +31,9 @@ static struct timeval RPCTIMEOUT = {10, 0}; static struct timeval UDPTIMEOUT = {5, 0}; +extern u_short __pmap_getnisport (struct sockaddr_in *address, u_long program, + u_long version, u_int protocol); + unsigned long inetstr2int (const char *str) { @@ -134,6 +137,11 @@ __bind_connect (dir_binding *dbp) if (dbp->addr.sin_addr.s_addr == 0) return NIS_FAIL; + /* Check, if the host is online and rpc.nisd is running. Much faster + then the clnt*_create functions: */ + if (__pmap_getnisport (&dbp->addr, NIS_PROG, NIS_VERSION, IPPROTO_UDP) == 0) + return NIS_RPCERROR; + dbp->socket = RPC_ANYSOCK; if (dbp->use_udp) dbp->clnt = clntudp_create (&dbp->addr, NIS_PROG, NIS_VERSION, @@ -152,7 +160,7 @@ __bind_connect (dir_binding *dbp) if (dbp->use_auth) { - if (serv->key_type == NIS_PK_DH) + if (serv->key_type == NIS_PK_DH && key_secretkey_is_set ()) { char netname[MAXNETNAMELEN+1]; char *p; @@ -220,6 +228,7 @@ __bind_create (const nis_server *serv_val, u_int serv_len, u_long flags, else dbp->master_only = FALSE; + /* We try the first server */ dbp->trys = 1; for (i = 0; i < serv_len; ++i) @@ -317,7 +326,6 @@ __do_niscall2 (const nis_server *server, u_int server_len, u_long prog, if (result != RPC_SUCCESS) { - clnt_perror (dbp->clnt, "__do_niscall2: clnt_call"); __bind_destroy (dbp); retcode = NIS_RPCERROR; } @@ -424,31 +432,8 @@ rec_dirsearch (const_nis_name name, directory_obj *dir, u_long flags, { fd_result *fd_res; XDR xdrs; - char domain [strlen (name) + 3]; - nis_domain_of_r (name, domain, sizeof (domain)); - if (strncmp (domain, "org_dir.", 8) == 0) - { - char tmp[strlen (name) + 3]; - - nis_domain_of_r (domain, tmp, sizeof (tmp)); - strcpy (domain, tmp); - } - else - if (strncmp (domain, "groups_dir.", 11) == 0) - { - char tmp[strlen (name) + 3]; - - nis_domain_of_r (domain, tmp, sizeof (tmp)); - strcpy (domain, tmp); - } - else - { - /* We have no grous_dir or org_dir, so try the complete name */ - strcpy (domain, name); - } - - switch (nis_dir_cmp (domain, dir->do_name)) + switch (nis_dir_cmp (name, dir->do_name)) { case SAME_NAME: *status = NIS_SUCCESS; @@ -469,9 +454,9 @@ rec_dirsearch (const_nis_name name, directory_obj *dir, u_long flags, *status = fd_res->status; if (fd_res->status != NIS_SUCCESS) { - nis_free_directory (dir); + /* Try the current directory obj, maybe it works */ __free_fdresult (fd_res); - return NULL; + return dir; } obj = calloc(1, sizeof(directory_obj)); xdrmem_create(&xdrs, fd_res->dir_data.dir_data_val, @@ -498,8 +483,12 @@ rec_dirsearch (const_nis_name name, directory_obj *dir, u_long flags, { directory_obj *obj; char leaf [strlen (name) + 3]; + char domain [strlen (name) + 3]; char ndomain [strlen (name) + 3]; char *cp; + u_int run = 0; + + strcpy (domain, name); do { @@ -511,8 +500,16 @@ rec_dirsearch (const_nis_name name, directory_obj *dir, u_long flags, nis_leaf_of_r (domain, leaf, sizeof (leaf)); nis_domain_of_r (domain, ndomain, sizeof (ndomain)); strcpy (domain, ndomain); + ++run; } while (nis_dir_cmp (domain, dir->do_name) != SAME_NAME); + + if (run == 1) + { + /* We have found the directory above. Use it. */ + return dir; + } + cp = strchr (leaf, '\0'); *cp++ = '.'; strcpy (cp, domain); @@ -521,9 +518,9 @@ rec_dirsearch (const_nis_name name, directory_obj *dir, u_long flags, *status = fd_res->status; if (fd_res->status != NIS_SUCCESS) { - nis_free_directory (dir); + /* Try the current directory object, maybe it works */ __free_fdresult (fd_res); - return NULL; + return dir; } obj = calloc(1, sizeof(directory_obj)); xdrmem_create(&xdrs, fd_res->dir_data.dir_data_val, @@ -550,6 +547,46 @@ rec_dirsearch (const_nis_name name, directory_obj *dir, u_long flags, return NULL; } +/* We try to query the current server for the searched object, + maybe he know about it ? */ +static directory_obj * +first_shoot (const_nis_name name, directory_obj *dir, u_long flags) +{ + directory_obj *obj; + fd_result *fd_res; + XDR xdrs; + char domain [strlen (name) + 3]; + + if (nis_dir_cmp (name, dir->do_name) == SAME_NAME) + return dir; + + nis_domain_of_r (name, domain, sizeof (domain)); + + if (nis_dir_cmp (domain, dir->do_name) == SAME_NAME) + return dir; + + fd_res = __nis_finddirectory (dir, domain); + if (fd_res->status != NIS_SUCCESS) + { + __free_fdresult (fd_res); + return NULL; + } + obj = calloc(1, sizeof(directory_obj)); + if (obj == NULL) + return NULL; + xdrmem_create(&xdrs, fd_res->dir_data.dir_data_val, + fd_res->dir_data.dir_data_len, XDR_DECODE); + xdr_directory_obj(&xdrs, obj); + xdr_destroy(&xdrs); + __free_fdresult (fd_res); + if (obj != NULL) + { + nis_free_directory (dir); + return obj; + } + return NULL; +} + nis_error __do_niscall (const_nis_name name, u_long prog, xdrproc_t xargs, caddr_t req, xdrproc_t xres, caddr_t resp, u_long flags, @@ -572,6 +609,8 @@ __do_niscall (const_nis_name name, u_long prog, xdrproc_t xargs, if (dir == NULL) { nis_error status; + directory_obj *obj; + dir = readColdStartFile (); if (dir == NULL) /* No /var/nis/NIS_COLD_START->no NIS+ installed */ { @@ -579,12 +618,19 @@ __do_niscall (const_nis_name name, u_long prog, xdrproc_t xargs, return NIS_UNAVAIL; } - dir = rec_dirsearch (name, dir, flags, &status); - if (dir == NULL) + /* Try at first, if servers in "dir" know our object */ + obj = first_shoot (name, dir, flags); + if (obj == NULL) { - __set_errno (saved_errno); - return status; + dir = rec_dirsearch (name, dir, flags, &status); + if (dir == NULL) + { + __set_errno (saved_errno); + return status; + } } + else + dir = obj; } if (flags & MASTER_ONLY) diff --git a/nis/nis_callback.c b/nis/nis_callback.c index 054b462053..7dfab8ff25 100644 --- a/nis/nis_callback.c +++ b/nis/nis_callback.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1997 Free Software Foundation, Inc. +/* Copyright (C) 1997, 1998 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Thorsten Kukuk , 1997. @@ -29,13 +29,12 @@ #include #include #include +#include #include #include #include "nis_intern.h" -extern void get_myaddress (struct sockaddr_in *addr); - /* Sorry, we are not able to make this threadsafe. Stupid. But some functions doesn't send us a nis_result obj, so we don't have a cookie. Maybe we could use keys for threads ? Have to learn more @@ -64,6 +63,53 @@ static nis_cb *data; __libc_lock_define_initialized (static, callback) + +static char * +__nis_getpkey(const char *sname) +{ + char buf[(strlen (sname) + 1) * 2 + 40]; + char pkey[HEXKEYBYTES + 1]; + char *cp, *domain; + nis_result *res; + u_int len = 0; + + domain = strchr (sname, '.'); + if (domain == NULL) + return NULL; + + /* Remove prefixing dot */ + ++domain; + + cp = stpcpy (buf, "[cname="); + cp = stpcpy (cp, sname); + cp = stpcpy (cp, ",auth_type=DES],cred.org_dir."); + cp = stpcpy (cp, domain); + + res = nis_list (buf, USE_DGRAM|NO_AUTHINFO|FOLLOW_LINKS|FOLLOW_PATH, + NULL, NULL); + + if (res == NULL) + return NULL; + + if (res->status != NIS_SUCCESS) + { + nis_freeresult (res); + return NULL; + } + + len = ENTRY_LEN(NIS_RES_OBJECT(res), 3); + strncpy (pkey, ENTRY_VAL(NIS_RES_OBJECT(res), 3), len); + pkey[len] = '\0'; + cp = strchr (pkey, ':'); + if (cp != NULL) + *cp = '\0'; + + nis_freeresult (res); + + return strdup (pkey); +} + + static bool_t xdr_cback_data (XDR *, cback_data *); static void @@ -82,12 +128,11 @@ cb_prog_1 (struct svc_req *rqstp, SVCXPRT *transp) switch (rqstp->rq_proc) { case NULLPROC: - (void) svc_sendreply (transp, (xdrproc_t) xdr_void, (char *) NULL); + svc_sendreply (transp, (xdrproc_t) xdr_void, (char *) NULL); return; case CBPROC_RECEIVE: { - char name[NIS_MAXNAMELEN + 1]; u_long i; xdr_argument = (xdrproc_t) xdr_cback_data; @@ -101,13 +146,18 @@ cb_prog_1 (struct svc_req *rqstp, SVCXPRT *transp) bool_result = FALSE; for (i = 0; i < argument.cbproc_receive_1_arg.entries.entries_len; ++i) { - snprintf (name, NIS_MAXNAMELEN, "%s.%s", - argument.cbproc_receive_1_arg.entries.entries_val[i]->zo_name, - argument.cbproc_receive_1_arg.entries.entries_val[i]->zo_domain); +#define cbproc_entry(a) argument.cbproc_receive_1_arg.entries.entries_val[a] + char name[strlen (cbproc_entry(i)->zo_name) + + strlen (cbproc_entry(i)->zo_domain) + 3]; + char *cp; - if ((data->callback) - (name, argument.cbproc_receive_1_arg.entries.entries_val[i], - data->userdata)) + cp = stpcpy (name, cbproc_entry(i)->zo_name); + *cp++ = '.'; + cp = stpcpy (cp, cbproc_entry(i)->zo_domain); + + fprintf (stderr, "name=%s\n", name); + + if ((data->callback) (name, cbproc_entry(i), data->userdata)) { bool_result = TRUE; data->nomore = 1; @@ -273,17 +323,32 @@ __nis_create_callback (int (*callback) (const_nis_name, const nis_object *, syslog (LOG_ERR, "NIS+: out of memory allocating callback"); return (NULL); } - cb->serv->name = strdup (nis_local_host ()); + cb->serv->name = strdup (nis_local_principal ()); cb->serv->ep.ep_val = (endpoint *) calloc (2, sizeof (endpoint)); cb->serv->ep.ep_len = 1; cb->serv->ep.ep_val[0].family = strdup ("inet"); cb->callback = callback; cb->userdata = userdata; - /* XXX Sometimes, we should add the public key of the user here ! */ - cb->serv->key_type = NIS_PK_NONE; - cb->serv->pkey.n_bytes = NULL; - cb->serv->pkey.n_len = 0; + if ((flags & NO_AUTHINFO) && key_secretkey_is_set ()) + { + cb->serv->key_type = NIS_PK_NONE; + cb->serv->pkey.n_bytes = NULL; + cb->serv->pkey.n_len = 0; + } + else + { + if ((cb->serv->pkey.n_bytes = __nis_getpkey (cb->serv->name)) == NULL) + { + cb->serv->pkey.n_len = 0; + cb->serv->key_type = NIS_PK_NONE; + } + else + { + cb->serv->key_type = NIS_PK_DH; + cb->serv->pkey.n_len = strlen(cb->serv->pkey.n_bytes); + } + } if (flags & USE_DGRAM) { diff --git a/nis/nis_clone_obj.c b/nis/nis_clone_obj.c index 291148fc0f..133c2558b4 100644 --- a/nis/nis_clone_obj.c +++ b/nis/nis_clone_obj.c @@ -1,4 +1,4 @@ -/* Copyright (c) 1997 Free Software Foundation, Inc. +/* Copyright (c) 1997, 1998 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Thorsten Kukuk , 1997. @@ -25,7 +25,7 @@ nis_object * nis_clone_object (const nis_object *src, nis_object *dest) { unsigned char *addr; - unsigned int size; + unsigned long size; XDR xdrs; nis_object *res; diff --git a/nis/nis_creategroup.c b/nis/nis_creategroup.c index 240573145f..a96d67d29c 100644 --- a/nis/nis_creategroup.c +++ b/nis/nis_creategroup.c @@ -1,4 +1,4 @@ -/* Copyright (c) 1997 Free Software Foundation, Inc. +/* Copyright (c) 1997, 1998 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Thorsten Kukuk , 1997. @@ -45,16 +45,23 @@ nis_creategroup (const_nis_name group, u_long flags) return NIS_BADNAME; obj = calloc (1, sizeof (nis_object)); + if (obj == NULL) + return NIS_NOMEMORY; + + obj->zo_name = strdup (leafbuf); obj->zo_owner = strdup (__nis_default_owner (NULL)); obj->zo_group = strdup (__nis_default_group (NULL)); + obj->zo_domain = strdup (domainbuf); obj->zo_access = __nis_default_access (NULL, 0); - obj->zo_ttl = __nis_default_ttl (0); + obj->zo_ttl = 60 * 60; obj->zo_data.zo_type = NIS_GROUP_OBJ; obj->zo_data.objdata_u.gr_data.gr_flags = flags; obj->zo_data.objdata_u.gr_data.gr_members.gr_members_len = 0; obj->zo_data.objdata_u.gr_data.gr_members.gr_members_val = NULL; res = nis_add (buf, obj); + if (res == NULL) + return NIS_NOMEMORY; status = res->status; nis_freeresult (res); nis_free_object (obj); diff --git a/nis/nis_findserv.c b/nis/nis_findserv.c index b6abff133d..0e9f01700d 100644 --- a/nis/nis_findserv.c +++ b/nis/nis_findserv.c @@ -60,9 +60,9 @@ struct cu_data * Calls the pmap service remotely to do the lookup. * Returns 0 if no map exists. */ -static u_short -__pmap_getport (struct sockaddr_in *address, u_long program, - u_long version, u_int protocol) +u_short +__pmap_getnisport (struct sockaddr_in *address, u_long program, + u_long version, u_int protocol) { const struct timeval timeout = {1, 0}; const struct timeval tottimeout = {1, 0}; @@ -144,8 +144,9 @@ __nis_findfastest (dir_binding * bind) inetstr2int (bind->server_val[i].ep.ep_val[j].uaddr); if (sin.sin_addr.s_addr == 0) continue; - sin.sin_port = htons (__pmap_getport (&sin, NIS_PROG, - NIS_VERSION, IPPROTO_UDP)); + sin.sin_port = htons (__pmap_getnisport (&sin, NIS_PROG, + NIS_VERSION, + IPPROTO_UDP)); if (sin.sin_port == 0) continue; @@ -184,6 +185,7 @@ __nis_findfastest (dir_binding * bind) free (pings); return -1; } + auth_destroy (clnt->cl_auth); clnt->cl_auth = authunix_create_default (); cu = (struct cu_data *) clnt->cl_private; clnt_control (clnt, CLSET_TIMEOUT, (char *) &TIMEOUT00); diff --git a/nis/nis_intern.h b/nis/nis_intern.h index 22b753d246..311555d3b9 100644 --- a/nis/nis_intern.h +++ b/nis/nis_intern.h @@ -74,8 +74,6 @@ extern nis_error __do_niscall __P ((const_nis_name name, u_long prog, xdrproc_t xargs, caddr_t req, xdrproc_t xres, caddr_t resp, u_long flags, nis_cb *cb)); -extern AUTH *authdes_pk_create __P ((const char *, const netobj *, u_int, - struct sockaddr *, des_block *)); /* NIS+ callback */ extern nis_error __nis_do_callback __P ((struct dir_binding *bptr, diff --git a/sunrpc/auth_des.c b/sunrpc/auth_des.c index bd29abd3bc..8536e62b79 100644 --- a/sunrpc/auth_des.c +++ b/sunrpc/auth_des.c @@ -62,10 +62,6 @@ extern bool_t xdr_authdes_verf (XDR *, struct authdes_verf *); /* * DES authenticator operations vector */ -AUTH *authdes_create (const char *, u_int, struct sockaddr *, - des_block *); -AUTH *authdes_pk_create (const char *, netobj *, u_int, - struct sockaddr *, des_block *); static void authdes_nextverf (AUTH *); static bool_t authdes_marshal (AUTH *, XDR *); static bool_t authdes_validate (AUTH *, struct opaque_auth *); @@ -111,7 +107,7 @@ struct ad_private */ AUTH * authdes_create (const char *servername, u_int window, - struct sockaddr *syncaddr, des_block * ckey) + struct sockaddr *syncaddr, des_block *ckey) /* servername - network name of server */ /* window - time to live */ /* syncaddr - optional addr of host to sync with */ @@ -129,8 +125,8 @@ authdes_create (const char *servername, u_int window, } AUTH * -authdes_pk_create (const char *servername, netobj * pkey, u_int window, - struct sockaddr * syncaddr, des_block * ckey) +authdes_pk_create (const char *servername, netobj *pkey, u_int window, + struct sockaddr *syncaddr, des_block *ckey) { AUTH *auth; struct ad_private *ad; diff --git a/sunrpc/clnt_tcp.c b/sunrpc/clnt_tcp.c index 82b34b6259..d4fd7c448c 100644 --- a/sunrpc/clnt_tcp.c +++ b/sunrpc/clnt_tcp.c @@ -365,15 +365,19 @@ clnttcp_abort () } static bool_t -clnttcp_control (cl, request, info) - CLIENT *cl; - int request; - char *info; +clnttcp_control (CLIENT *cl, int request, char *info) { struct ct_data *ct = (struct ct_data *) cl->cl_private; + switch (request) { + case CLSET_FD_CLOSE: + ct->ct_closeit = TRUE; + break; + case CLSET_FD_NCLOSE: + ct->ct_closeit = FALSE; + break; case CLSET_TIMEOUT: ct->ct_wait = *(struct timeval *) info; ct->ct_waitset = TRUE; @@ -384,6 +388,56 @@ clnttcp_control (cl, request, info) case CLGET_SERVER_ADDR: *(struct sockaddr_in *) info = ct->ct_addr; break; + case CLGET_FD: + *(int *)info = ct->ct_sock; + break; + case CLGET_XID: + /* + * use the knowledge that xid is the + * first element in the call structure *. + * This will get the xid of the PREVIOUS call + */ + *(u_long *)info = ntohl (*(u_long *)ct->ct_mcall); + break; + case CLSET_XID: + /* This will set the xid of the NEXT call */ + *(u_long *)ct->ct_mcall = htonl (*(u_long *)info - 1); + /* decrement by 1 as clnttcp_call() increments once */ + case CLGET_VERS: + /* + * This RELIES on the information that, in the call body, + * the version number field is the fifth field from the + * begining of the RPC header. MUST be changed if the + * call_struct is changed + */ + *(u_long *)info = ntohl (*(u_long *)(ct->ct_mcall + + 4 * BYTES_PER_XDR_UNIT)); + break; + case CLSET_VERS: + *(u_long *)(ct->ct_mcall + 4 * BYTES_PER_XDR_UNIT) + = htonl (*(u_long *)info); + break; + case CLGET_PROG: + /* + * This RELIES on the information that, in the call body, + * the program number field is the field from the + * begining of the RPC header. MUST be changed if the + * call_struct is changed + */ + *(u_long *)info = ntohl(*(u_long *)(ct->ct_mcall + + 3 * BYTES_PER_XDR_UNIT)); + break; + case CLSET_PROG: + *(u_long *)(ct->ct_mcall + 3 * BYTES_PER_XDR_UNIT) + = htonl(*(u_long *)info); + break; + /* The following are only possible with TI-RPC */ + case CLGET_RETRY_TIMEOUT: + case CLSET_RETRY_TIMEOUT: + case CLGET_SVC_ADDR: + case CLSET_SVC_ADDR: + case CLSET_PUSH_TIMOD: + case CLSET_POP_TIMOD: default: return FALSE; } diff --git a/sunrpc/clnt_udp.c b/sunrpc/clnt_udp.c index 3ce124f5d7..c3545db65a 100644 --- a/sunrpc/clnt_udp.c +++ b/sunrpc/clnt_udp.c @@ -439,6 +439,12 @@ clntudp_control (CLIENT *cl, int request, char *info) switch (request) { + case CLSET_FD_CLOSE: + cu->cu_closeit = TRUE; + break; + case CLSET_FD_NCLOSE: + cu->cu_closeit = FALSE; + break; case CLSET_TIMEOUT: cu->cu_total = *(struct timeval *) info; break; @@ -454,6 +460,54 @@ clntudp_control (CLIENT *cl, int request, char *info) case CLGET_SERVER_ADDR: *(struct sockaddr_in *) info = cu->cu_raddr; break; + case CLGET_FD: + *(int *)info = cu->cu_sock; + break; + case CLGET_XID: + /* + * use the knowledge that xid is the + * first element in the call structure *. + * This will get the xid of the PREVIOUS call + */ + *(u_long *)info = ntohl(*(u_long *)cu->cu_outbuf); + break; + case CLSET_XID: + /* This will set the xid of the NEXT call */ + *(u_long *)cu->cu_outbuf = htonl(*(u_long *)info - 1); + /* decrement by 1 as clntudp_call() increments once */ + case CLGET_VERS: + /* + * This RELIES on the information that, in the call body, + * the version number field is the fifth field from the + * begining of the RPC header. MUST be changed if the + * call_struct is changed + */ + *(u_long *)info = ntohl(*(u_long *)(cu->cu_outbuf + + 4 * BYTES_PER_XDR_UNIT)); + break; + case CLSET_VERS: + *(u_long *)(cu->cu_outbuf + 4 * BYTES_PER_XDR_UNIT) + = htonl(*(u_long *)info); + break; + case CLGET_PROG: + /* + * This RELIES on the information that, in the call body, + * the program number field is the field from the + * begining of the RPC header. MUST be changed if the + * call_struct is changed + */ + *(u_long *)info = ntohl(*(u_long *)(cu->cu_outbuf + + 3 * BYTES_PER_XDR_UNIT)); + break; + case CLSET_PROG: + *(u_long *)(cu->cu_outbuf + 3 * BYTES_PER_XDR_UNIT) + = htonl(*(u_long *)info); + break; + /* The following are only possible with TI-RPC */ + case CLGET_SVC_ADDR: + case CLSET_SVC_ADDR: + case CLSET_PUSH_TIMOD: + case CLSET_POP_TIMOD: default: return FALSE; } diff --git a/sunrpc/netname.c b/sunrpc/netname.c index be6c2f2ae1..176967a905 100644 --- a/sunrpc/netname.c +++ b/sunrpc/netname.c @@ -82,6 +82,7 @@ host2netname (char netname[MAXNETNAMELEN + 1], const char *host, p = dot_in_host; if (p) { + ++p; strncpy (domainname, p, MAXHOSTNAMELEN); domainname[MAXHOSTNAMELEN] = '\0'; } diff --git a/sunrpc/rpc/auth.h b/sunrpc/rpc/auth.h index 9519ca27f4..aa2c6144a1 100644 --- a/sunrpc/rpc/auth.h +++ b/sunrpc/rpc/auth.h @@ -166,6 +166,9 @@ extern AUTH *authnone_create __P ((void)); extern AUTH *authdes_create __P ((const char *__servername, u_int __window, struct sockaddr *__syncaddr, des_block *__ckey)); +extern AUTH *authdes_pk_create __P ((const char *, netobj *, u_int, + struct sockaddr *, des_block *)); + #define AUTH_NONE 0 /* no authentication */ #define AUTH_NULL 0 /* backward compatibility */ diff --git a/sunrpc/rpc/clnt.h b/sunrpc/rpc/clnt.h index 38f40909dc..ed12add102 100644 --- a/sunrpc/rpc/clnt.h +++ b/sunrpc/rpc/clnt.h @@ -211,23 +211,27 @@ struct CLIENT { /* * control operations that apply to all transports + * + * Note: options marked XXX are no-ops in this implementation of RPC. + * The are present in TI-RPC but can't be implemented here since they + * depend on the presence of STREAMS/TLI, which we don't have. */ -#define CLSET_TIMEOUT 1 /* set timeout (timeval) */ -#define CLGET_TIMEOUT 2 /* get timeout (timeval) */ -#define CLGET_SERVER_ADDR 3 /* get server's address (sockaddr) */ -#define CLGET_FD 6 /* get connections file descriptor */ -#define CLGET_SVC_ADDR 7 /* get server's address (netbuf) */ -#define CLSET_FD_CLOSE 8 /* close fd while clnt_destroy */ -#define CLSET_FD_NCLOSE 9 /* Do not close fd while clnt_destroy*/ -#define CLGET_XID 10 /* Get xid */ -#define CLSET_XID 11 /* Set xid */ -#define CLGET_VERS 12 /* Get version number */ -#define CLSET_VERS 13 /* Set version number */ -#define CLGET_PROG 14 /* Get program number */ -#define CLSET_PROG 15 /* Set program number */ -#define CLSET_SVC_ADDR 16 /* get server's address (netbuf) */ -#define CLSET_PUSH_TIMOD 17 /* push timod if not already present */ -#define CLSET_POP_TIMOD 18 /* pop timod */ +#define CLSET_TIMEOUT 1 /* set timeout (timeval) */ +#define CLGET_TIMEOUT 2 /* get timeout (timeval) */ +#define CLGET_SERVER_ADDR 3 /* get server's address (sockaddr) */ +#define CLGET_FD 6 /* get connections file descriptor */ +#define CLGET_SVC_ADDR 7 /* get server's address (netbuf) XXX */ +#define CLSET_FD_CLOSE 8 /* close fd while clnt_destroy */ +#define CLSET_FD_NCLOSE 9 /* Do not close fd while clnt_destroy*/ +#define CLGET_XID 10 /* Get xid */ +#define CLSET_XID 11 /* Set xid */ +#define CLGET_VERS 12 /* Get version number */ +#define CLSET_VERS 13 /* Set version number */ +#define CLGET_PROG 14 /* Get program number */ +#define CLSET_PROG 15 /* Set program number */ +#define CLSET_SVC_ADDR 16 /* get server's address (netbuf) XXX */ +#define CLSET_PUSH_TIMOD 17 /* push timod if not already present XXX */ +#define CLSET_POP_TIMOD 18 /* pop timod XXX */ /* * Connectionless only control operations */ diff --git a/sunrpc/svcauth_des.c b/sunrpc/svcauth_des.c index 7160726e86..c74e06b5c1 100644 --- a/sunrpc/svcauth_des.c +++ b/sunrpc/svcauth_des.c @@ -174,9 +174,19 @@ _svcauth_des (register struct svc_req *rqst, register struct rpc_msg *msg) */ if (cred->adc_namekind == ADN_FULLNAME) { + netobj pkey; + char pkey_data[1024]; + sessionkey = &cred->adc_fullname.key; - if (key_decryptsession (cred->adc_fullname.name, - sessionkey) < 0) + if (!getpublickey (cred->adc_fullname.name, pkey_data)) + { + debug("getpublickey"); + return AUTH_BADCRED; + } + pkey.n_bytes = pkey_data; + pkey.n_len = strlen (pkey_data) + 1; + if (key_decryptsession_pk (cred->adc_fullname.name, &pkey, + sessionkey) < 0) { debug ("decryptsessionkey"); return AUTH_BADCRED; /* key not found */