cleanup spec
[platform/upstream/glibc.git] / sunrpc / svcauth_des.c
index 56b683a..a0f961d 100644 (file)
@@ -1,35 +1,33 @@
 /*
- * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part.  Users
- * may copy or modify Sun RPC without charge, but are not authorized
- * to license or distribute it to anyone else except as part of a product or
- * program developed by the user.
+ * Copyright (c) 2010, Oracle America, Inc.
  *
- * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
  *
- * Sun RPC is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials
+ *       provided with the distribution.
+ *     * Neither the name of the "Oracle America, Inc." nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
  *
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- * OR ANY PART THEREOF.
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ *   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ *   COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ *   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ *   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ *   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ *   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ *   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
- *
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California  94043
- */
-/*
- * Copyright (c) 1988 by Sun Microsystems, Inc.
- */
-/*
  * svcauth_des.c, server-side des authentication
  *
  * We insure for the service the following:
  *
  */
 
+#include <limits.h>
 #include <string.h>
+#include <stdint.h>
 #include <sys/param.h>
 #include <netinet/in.h>
-#include <rpc/types.h>
+#include <rpc/rpc.h>
 #include <rpc/xdr.h>
 #include <rpc/auth.h>
 #include <rpc/auth_des.h>
@@ -71,8 +71,13 @@ struct cache_entry
     struct rpc_timeval laststamp;      /* detect replays of creds */
     char *localcred;           /* generic local credential */
   };
-static struct cache_entry *authdes_cache /* [AUTHDES_CACHESZ] */ ;
-static int *authdes_lru /* [AUTHDES_CACHESZ] */ ;
+#ifdef _RPC_THREAD_SAFE_
+#define authdes_cache RPC_THREAD_VARIABLE(authdes_cache_s)
+#define authdes_lru RPC_THREAD_VARIABLE(authdes_lru_s)
+#else
+static struct cache_entry *authdes_cache;
+static int *authdes_lru;
+#endif
 
 static void cache_init (void) internal_function; /* initialize the cache */
 static short cache_spot (des_block *, char *, struct rpc_timeval *)
@@ -145,7 +150,7 @@ _svcauth_des (register struct svc_req *rqst, register struct rpc_msg *msg)
          return AUTH_BADCRED;
        }
       cred->adc_fullname.name = area->area_netname;
-      bcopy ((char *) ixdr, cred->adc_fullname.name, namelen);
+      memcpy (cred->adc_fullname.name, (char *) ixdr, namelen);
       cred->adc_fullname.name[namelen] = 0;
       ixdr += (RNDUP (namelen) / BYTES_PER_XDR_UNIT);
       cred->adc_fullname.key.key.high = *ixdr++;
@@ -309,7 +314,7 @@ _svcauth_des (register struct svc_req *rqst, register struct rpc_msg *msg)
   /*
    * xdr the timestamp before encrypting
    */
-  ixdr = (int32_t *) cryptbuf;
+  ixdr = (uint32_t *) cryptbuf;
   IXDR_PUT_INT32 (ixdr, timestamp.tv_sec - 1);
   IXDR_PUT_INT32 (ixdr, timestamp.tv_usec);
 
@@ -390,11 +395,9 @@ cache_init (void)
   register int i;
 
   authdes_cache = (struct cache_entry *)
-    mem_alloc (sizeof (struct cache_entry) * AUTHDES_CACHESZ);
+    calloc (sizeof (struct cache_entry) * AUTHDES_CACHESZ, 1);
   if (authdes_cache == NULL)
     return;
-  __bzero ((char *) authdes_cache,
-          sizeof (struct cache_entry) * AUTHDES_CACHESZ);
 
   authdes_lru = (int *) mem_alloc (sizeof (int) * AUTHDES_CACHESZ);
   /*
@@ -482,8 +485,9 @@ struct bsdcred
 {
   uid_t uid;                   /* cached uid */
   gid_t gid;                   /* cached gid */
-  short grouplen;              /* length of cached groups */
-  gid_t groups[NGROUPS];       /* cached groups */
+  int grouplen;                        /* length of cached groups */
+  int grouplen_max;            /* length of allocated cached groups */
+  gid_t groups[0];             /* cached groups */
 };
 
 /*
@@ -510,13 +514,7 @@ authdes_getucred (const struct authdes_cred *adc, uid_t * uid, gid_t * gid,
       return 0;
     }
   cred = (struct bsdcred *) authdes_cache[sid].localcred;
-  if (cred == NULL)
-    {
-      cred = (struct bsdcred *) mem_alloc (sizeof (struct bsdcred));
-      authdes_cache[sid].localcred = (char *) cred;
-      cred->grouplen = INVALID;
-    }
-  if (cred->grouplen == INVALID)
+  if (cred == NULL || cred->grouplen == INVALID)
     {
       /*
        * not in cache: lookup
@@ -525,15 +523,43 @@ authdes_getucred (const struct authdes_cred *adc, uid_t * uid, gid_t * gid,
                         &i_grouplen, groups))
        {
          debug ("unknown netname");
-         cred->grouplen = UNKNOWN;     /* mark as lookup up, but not found */
+         if (cred != NULL)
+           cred->grouplen = UNKNOWN;   /* mark as lookup up, but not found */
          return 0;
        }
+
+      if (cred != NULL && cred->grouplen_max < i_grouplen)
+       {
+         /* We already have an allocated data structure.  But it is
+            too small.  */
+         free (cred);
+         authdes_cache[sid].localcred = NULL;
+         cred = NULL;
+       }
+
+      if (cred == NULL)
+       {
+         /* We should allocate room for at least NGROUPS groups.  */
+         int ngroups_max = MAX (i_grouplen, NGROUPS);
+
+         cred = (struct bsdcred *) mem_alloc (sizeof (struct bsdcred)
+                                              + ngroups_max * sizeof (gid_t));
+         if (cred == NULL)
+           return 0;
+
+         authdes_cache[sid].localcred = (char *) cred;
+         cred->grouplen = INVALID;
+         cred->grouplen_max = ngroups_max;
+       }
+
       debug ("missed ucred cache");
       *uid = cred->uid = i_uid;
       *gid = cred->gid = i_gid;
-      *grouplen = cred->grouplen = i_grouplen;
+      cred->grouplen = i_grouplen;
       for (i = i_grouplen - 1; i >= 0; --i)
-       cred->groups[i] = groups[i];    /* int to short */
+       cred->groups[i] = groups[i];
+      /* Make sure no too large values are reported.  */
+      *grouplen = MIN (SHRT_MAX, i_grouplen);
       return 1;
     }
   else if (cred->grouplen == UNKNOWN)
@@ -549,11 +575,16 @@ authdes_getucred (const struct authdes_cred *adc, uid_t * uid, gid_t * gid,
    */
   *uid = cred->uid;
   *gid = cred->gid;
-  *grouplen = cred->grouplen;
-  for (i = cred->grouplen - 1; i >= 0; --i)
-    groups[i] = cred->groups[i];       /* short to int */
+
+  /* Another stupidity in the interface: *grouplen is of type short.
+     So we might have to cut the information passed up short.  */
+  int grouplen_copy = MIN (SHRT_MAX, cred->grouplen);
+  *grouplen = grouplen_copy;
+  for (i = grouplen_copy - 1; i >= 0; --i)
+    groups[i] = cred->groups[i];
   return 1;
 }
+libc_hidden_nolink_sunrpc (authdes_getucred, GLIBC_2_1)
 
 static void
 internal_function