]> git.ipfire.org Git - thirdparty/glibc.git/blobdiff - sunrpc/svcauth_des.c
support: Expose sbindir as support_sbindir_prefix
[thirdparty/glibc.git] / sunrpc / svcauth_des.c
index d808e95f05f4f3c53c74c7e0897e5b16f76b8859..c5a512d6f80ff3908375d6fd7fa92d9184395dff 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:
@@ -43,7 +41,9 @@
  *
  */
 
+#include <limits.h>
 #include <string.h>
+#include <stdint.h>
 #include <sys/param.h>
 #include <netinet/in.h>
 #include <rpc/rpc.h>
@@ -53,6 +53,7 @@
 #include <rpc/svc_auth.h>
 #include <rpc/svc.h>
 #include <rpc/des_crypt.h>
+#include <shlib-compat.h>
 
 #define debug(msg)             /*printf("svcauth_des: %s\n", msg) */
 
@@ -71,33 +72,31 @@ struct cache_entry
     struct rpc_timeval laststamp;      /* detect replays of creds */
     char *localcred;           /* generic local credential */
   };
-#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 *)
-     internal_function;                /* find an entry in the cache */
-static void cache_ref (uint32_t sid) internal_function;
-                               /* note that sid was ref'd */
+static void cache_init (void); /* initialize the cache */
+static short cache_spot (des_block *, char *, struct rpc_timeval *);
+  /* find an entry in the cache */
+static void cache_ref (uint32_t sid); /* note that sid was ref'd */
 
-static void invalidate (char *cred) internal_function;
-                               /* invalidate entry in cache */
+static void invalidate (char *cred); /* invalidate entry in cache */
 
-/*
- * cache statistics
- */
+/* Cache statistics.  Accidental historic export without a matching
+   declaration in any header file.  */
+#ifndef SHARED
+static
+#endif
 struct
   {
     u_long ncachehits;         /* times cache hit, and is not replay */
     u_long ncachereplays;      /* times cache hit, and is replay */
     u_long ncachemisses;       /* times cache missed */
   }
-svcauthdes_stats;
+svcauthdes_stats __attribute__ ((nocommon));
+#ifdef SHARED
+compat_symbol (libc, svcauthdes_stats, svcauthdes_stats, GLIBC_2_0);
+#endif
 
 /*
  * Service side authenticator for AUTH_DES
@@ -314,7 +313,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);
 
@@ -389,17 +388,14 @@ _svcauth_des (register struct svc_req *rqst, register struct rpc_msg *msg)
  * Initialize the cache
  */
 static void
-internal_function
 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);
   /*
@@ -423,7 +419,6 @@ cache_victim (void)
  * Note that sid was referenced
  */
 static void
-internal_function
 cache_ref (register uint32_t sid)
 {
   register int i;
@@ -446,7 +441,6 @@ cache_ref (register uint32_t sid)
  * return the spot in the cache.
  */
 static short
-internal_function
 cache_spot (register des_block *key, char *name,
            struct rpc_timeval *timestamp)
 {
@@ -487,8 +481,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 */
 };
 
 /*
@@ -515,13 +510,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
@@ -530,15 +519,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)
@@ -554,14 +571,18 @@ 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
 invalidate (char *cred)
 {
   if (cred == NULL)