Update.
authorUlrich Drepper <drepper@redhat.com>
Mon, 1 Jun 1998 13:10:54 +0000 (13:10 +0000)
committerUlrich Drepper <drepper@redhat.com>
Mon, 1 Jun 1998 13:10:54 +0000 (13:10 +0000)
1998-06-01  Thorsten Kukuk  <kukuk@vt.uni-paderborn.de>

* 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  <kukuk@vt.uni-paderborn.de>

* 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.

14 files changed:
ChangeLog
nis/nis_call.c
nis/nis_callback.c
nis/nis_clone_obj.c
nis/nis_creategroup.c
nis/nis_findserv.c
nis/nis_intern.h
sunrpc/auth_des.c
sunrpc/clnt_tcp.c
sunrpc/clnt_udp.c
sunrpc/netname.c
sunrpc/rpc/auth.h
sunrpc/rpc/clnt.h
sunrpc/svcauth_des.c

index a3f71f9..fe910c2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,33 @@
+1998-06-01  Thorsten Kukuk  <kukuk@vt.uni-paderborn.de>
+
+       * 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  <kukuk@vt.uni-paderborn.de>
+
+       * 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  <drepper@cygnus.com>
 
        * locale/loadlocale.c (_nl_load_locale): Don't allow too small
index affae09..957399e 100644 (file)
@@ -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)
index 054b462..7dfab8f 100644 (file)
@@ -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 <kukuk@vt.uni-paderborn.de>, 1997.
 
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
+#include <rpc/key_prot.h>
 #include <rpcsvc/nis.h>
 #include <bits/libc-lock.h>
 
 #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;
+
+           cp = stpcpy (name, cbproc_entry(i)->zo_name);
+           *cp++ = '.';
+           cp = stpcpy (cp, cbproc_entry(i)->zo_domain);
 
-           if ((data->callback)
-               (name, argument.cbproc_receive_1_arg.entries.entries_val[i],
-                data->userdata))
+           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)
     {
index 291148f..133c255 100644 (file)
@@ -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 <kukuk@vt.uni-paderborn.de>, 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;
 
index 2405731..a96d67d 100644 (file)
@@ -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 <kukuk@vt.uni-paderborn.de>, 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);
index b6abff1..0e9f017 100644 (file)
@@ -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);
index 22b753d..311555d 100644 (file)
@@ -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,
index bd29abd..8536e62 100644 (file)
@@ -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;
index 82b34b6..d4fd7c4 100644 (file)
@@ -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;
     }
index 3ce124f..c3545db 100644 (file)
@@ -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;
     }
index be6c2f2..176967a 100644 (file)
@@ -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';
        }
index 9519ca2..aa2c614 100644 (file)
@@ -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 */
index 38f4090..ed12add 100644 (file)
@@ -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
  */
index 7160726..c74e06b 100644 (file)
@@ -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 */