"Fossies" - the Fresh Open Source Software Archive

Member "nss_ldap-265/ldap-automount.c" (6 Nov 2009, 8929 Bytes) of package /linux/privat/old/nss_ldap-265.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 /* Copyright (C) 2005 Luke Howard.
    2    This file is part of the nss_ldap library.
    3    Contributed by Luke Howard, <lukeh@padl.com>, 2005.
    4 
    5    The nss_ldap library is free software; you can redistribute it and/or
    6    modify it under the terms of the GNU Library General Public License as
    7    published by the Free Software Foundation; either version 2 of the
    8    License, or (at your option) any later version.
    9 
   10    The nss_ldap library is distributed in the hope that it will be useful,
   11    but WITHOUT ANY WARRANTY; without even the implied warranty of
   12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   13    Library General Public License for more details.
   14 
   15    You should have received a copy of the GNU Library General Public
   16    License along with the nss_ldap library; see the file COPYING.LIB.  If not,
   17    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   18    Boston, MA 02111-1307, USA.
   19 
   20    $Id: ldap-automount.c,v 2.10 2009/11/06 10:15:26 lukeh Exp $
   21  */
   22 
   23 
   24 static char rcsId[] = "$Id: ldap-automount.c,v 2.10 2009/11/06 10:15:26 lukeh Exp $";
   25 
   26 #include "config.h"
   27 
   28 #ifdef HAVE_PORT_BEFORE_H
   29 #include <port_before.h>
   30 #endif
   31 
   32 #if defined(HAVE_THREAD_H) && !defined(_AIX)
   33 #include <thread.h>
   34 #elif defined(HAVE_PTHREAD_H)
   35 #include <pthread.h>
   36 #endif
   37 
   38 #include <stdio.h>
   39 #include <stdlib.h>
   40 #include <string.h>
   41 #include <assert.h>
   42 #include <netdb.h>
   43 #include <sys/types.h>
   44 #include <sys/socket.h>
   45 #include <netinet/in.h>
   46 
   47 #ifdef HAVE_LBER_H
   48 #include <lber.h>
   49 #endif
   50 #ifdef HAVE_LDAP_H
   51 #include <ldap.h>
   52 #endif
   53 
   54 #include "ldap-nss.h"
   55 #include "ldap-automount.h"
   56 #include "util.h"
   57 
   58 #ifdef HAVE_PORT_AFTER_H
   59 #include <port_after.h>
   60 #endif
   61 
   62 static NSS_STATUS
   63 _nss_ldap_parse_automount (LDAPMessage * e,
   64                ldap_state_t * pvt,
   65                void *result, char *buffer, size_t buflen)
   66 {
   67   NSS_STATUS stat;
   68   char ***keyval = result;
   69 
   70   stat = 
   71     _nss_ldap_assign_attrval (e, AT (automountKey), keyval[0],
   72                   &buffer, &buflen);
   73   if (stat != NSS_SUCCESS)
   74     return stat;
   75 
   76   stat = 
   77     _nss_ldap_assign_attrval (e, AT (automountInformation), keyval[1],
   78                   &buffer, &buflen);
   79   if (stat != NSS_SUCCESS)
   80     return stat;
   81 
   82   return NSS_SUCCESS;
   83 }
   84 
   85 NSS_STATUS
   86 _nss_ldap_am_context_alloc(ldap_automount_context_t **pContext)
   87 {
   88   ldap_automount_context_t *context;
   89 
   90   context = (ldap_automount_context_t *)malloc (sizeof(*context));
   91   if (context == NULL)
   92     {
   93       return NSS_TRYAGAIN;
   94     }
   95 
   96   context->lac_state = NULL;
   97 
   98   context->lac_dn_size = 1;   /* number of slots allocated */
   99   context->lac_dn_count = 0;  /* number of slots used */
  100   context->lac_dn_index = 0;  /* enumeration index */
  101 
  102   /* List of DNs, grown on demand */
  103   context->lac_dn_list = (char **)malloc (context->lac_dn_size *
  104                       sizeof(char *));
  105   if (context->lac_dn_list == NULL)
  106     {
  107       free (context);
  108       return NSS_TRYAGAIN;
  109     }
  110 
  111   if (_nss_ldap_ent_context_init_locked (&context->lac_state) == NULL)
  112     {
  113       free (context->lac_dn_list);
  114       free (context);
  115       return NSS_UNAVAIL;
  116     }
  117 
  118   *pContext = context;
  119 
  120   return NSS_SUCCESS;
  121 }
  122 
  123 void
  124 _nss_ldap_am_context_free(ldap_automount_context_t **pContext)
  125 {
  126   ldap_automount_context_t *context;
  127   size_t i;
  128 
  129   context = *pContext;
  130 
  131   if (context == NULL)
  132     return;
  133 
  134   if (context->lac_dn_list != NULL)
  135     {
  136       for (i = 0; i < context->lac_dn_count; i++)
  137     {
  138 #ifdef HAVE_LDAP_MEMFREE
  139       ldap_memfree (context->lac_dn_list[i]);
  140 #else
  141       free (context->lac_dn_list[i]);
  142 #endif /* HAVE_LDAP_MEMFREE */
  143     }
  144       free (context->lac_dn_list);
  145     }
  146 
  147   if (context->lac_state != NULL)
  148     {
  149       _nss_ldap_ent_context_release (&(context->lac_state));
  150     }
  151 
  152   memset (context, 0, sizeof (*context));
  153   free (context);
  154 
  155   *pContext = NULL;
  156 
  157   return;
  158 }
  159 
  160 static NSS_STATUS
  161 am_context_add_dn (LDAPMessage * e,
  162            ldap_state_t * pvt,
  163            void *result, char *buffer, size_t buflen)
  164 {
  165   ldap_automount_context_t *context = (ldap_automount_context_t *) result;
  166   char *dn;
  167 
  168   dn = _nss_ldap_get_dn (e);
  169   if (dn == NULL)
  170     {
  171       return NSS_NOTFOUND;
  172     }
  173 
  174   if (context->lac_dn_count >= context->lac_dn_size)
  175     {
  176       char **new_dns;
  177 
  178       new_dns = (char **)realloc(context->lac_dn_list,
  179                  2 * context->lac_dn_size * sizeof(char *));
  180       if (new_dns == NULL)
  181     {
  182 #ifdef HAVE_LDAP_MEMFREE
  183       ldap_memfree (dn);
  184 #else
  185       free (dn);
  186 #endif /* HAVE_LDAP_MEMFREE */
  187       return NSS_TRYAGAIN;
  188     }
  189 
  190       context->lac_dn_list = new_dns;
  191       context->lac_dn_size *= 2;
  192     }
  193 
  194   context->lac_dn_list[context->lac_dn_count++] = dn;
  195 
  196   return NSS_SUCCESS;
  197 }
  198 
  199 NSS_STATUS
  200 _nss_ldap_am_context_init(const char *mapname, ldap_automount_context_t **pContext)
  201 {
  202   NSS_STATUS stat;
  203   ldap_automount_context_t *context = NULL;
  204   const char *no_attrs[] = { NULL };
  205   ldap_args_t a;
  206   ent_context_t *key = NULL;
  207   int errnop;
  208 
  209   *pContext = NULL;
  210 
  211   stat = _nss_ldap_am_context_alloc (&context);
  212   if (stat != NSS_SUCCESS)
  213       return stat;
  214 
  215   LA_INIT (a);
  216   LA_TYPE (a) = LA_TYPE_STRING;
  217   LA_STRING (a) = mapname;
  218 
  219   do
  220     {
  221       stat = _nss_ldap_getent_ex (&a, &key,
  222                   (void *)context,
  223                   NULL, 0, &errnop,
  224                   _nss_ldap_filt_setautomntent,
  225                   LM_AUTOMOUNT,
  226                   no_attrs,
  227                   am_context_add_dn);
  228     }
  229   while (stat == NSS_SUCCESS);
  230 
  231   if (key != NULL)
  232     {
  233       _nss_ldap_ent_context_release (&key);
  234     }
  235 
  236   if (context->lac_dn_count == 0)
  237     {
  238       _nss_ldap_am_context_free (&context);
  239       return NSS_NOTFOUND;
  240     }
  241   else if (stat == NSS_NOTFOUND)
  242     {
  243       stat = NSS_SUCCESS;
  244     }
  245 
  246   context->lac_dn_index = 0;
  247 
  248   *pContext = context;
  249   return NSS_SUCCESS;
  250 }
  251 
  252 #ifdef HAVE_NSS_H
  253 NSS_STATUS _nss_ldap_setautomntent(const char *mapname, void **private)
  254 {
  255   ldap_automount_context_t *context = NULL;
  256   NSS_STATUS stat;
  257 
  258   debug ("==> _nss_ldap_setautomntent");
  259 
  260   _nss_ldap_enter ();
  261 
  262   stat = _nss_ldap_init ();
  263   if (stat != NSS_SUCCESS)
  264     {
  265       _nss_ldap_leave ();
  266       debug ("<== _nss_ldap_setautomntent");
  267       return stat;
  268     }
  269 
  270   stat = _nss_ldap_am_context_init (mapname, &context);
  271   if (stat != NSS_SUCCESS)
  272     {
  273       _nss_ldap_leave ();
  274       debug ("<== _nss_ldap_setautomntent");
  275       return stat;
  276     }
  277 
  278   *private = (void *)context;
  279   _nss_ldap_leave ();
  280 
  281   debug ("<== _nss_ldap_setautomntent");
  282 
  283   return stat;
  284 }
  285 
  286 NSS_STATUS _nss_ldap_getautomntent_r(void *private, const char **key, const char **value,
  287                      char *buffer, size_t buflen, int *errnop)
  288 {
  289   NSS_STATUS stat;
  290   ldap_automount_context_t *context = (ldap_automount_context_t *)private;
  291   ldap_args_t a;
  292   char **keyval[2];
  293 
  294   if (context == NULL)
  295     return NSS_NOTFOUND;
  296 
  297   debug ("==> _nss_ldap_getautomntent_r");
  298 
  299   keyval[0] = (char **)key;
  300   keyval[1] = (char **)value;
  301 
  302   _nss_ldap_enter ();
  303 
  304   do
  305     {
  306       assert (context->lac_dn_index < context->lac_dn_count);
  307 
  308       LA_INIT (a);
  309       LA_TYPE (a) = LA_TYPE_NONE;
  310       LA_BASE (a) = context->lac_dn_list[context->lac_dn_index];
  311 
  312       stat = _nss_ldap_getent_ex (&a, &context->lac_state,
  313                   (void *)keyval,
  314                   buffer, buflen, errnop,
  315                   _nss_ldap_filt_getautomntent,
  316                   LM_AUTOMOUNT,
  317                   NULL,
  318                   _nss_ldap_parse_automount);
  319       if (stat == NSS_NOTFOUND)
  320     {
  321       if (context->lac_dn_index < context->lac_dn_count - 1)
  322         context->lac_dn_index++;
  323       else
  324         break; /* move along, nothing more to see here */
  325     }
  326     }
  327   while (stat == NSS_NOTFOUND);
  328 
  329   _nss_ldap_leave ();
  330 
  331   debug ("<== _nss_ldap_getautomntent_r");
  332 
  333   return stat;
  334 }
  335 
  336 NSS_STATUS _nss_ldap_endautomntent(void **private)
  337 {
  338   ldap_automount_context_t **pContext = (ldap_automount_context_t **)private;
  339 
  340   debug ("==> _nss_ldap_endautomntent");
  341 
  342   _nss_ldap_enter ();
  343   _nss_ldap_am_context_free (pContext);
  344   /* workaround because Linux automounter spawns a lot of processes */
  345   _nss_ldap_close ();
  346   _nss_ldap_leave ();
  347 
  348   debug ("<== _nss_ldap_endautomntent");
  349 
  350   return NSS_SUCCESS;
  351 }
  352 
  353 NSS_STATUS _nss_ldap_getautomntbyname_r(void *private, const char *key,
  354                     const char **canon_key, const char **value,
  355                     char *buffer, size_t buflen, int *errnop)
  356 {
  357   NSS_STATUS stat = NSS_NOTFOUND;
  358   ldap_automount_context_t *context = (ldap_automount_context_t *)private;
  359   ldap_args_t a;
  360   char **keyval[2];
  361   size_t i;
  362 
  363   if (context == NULL)
  364     return NSS_NOTFOUND;
  365 
  366   debug ("==> _nss_ldap_getautomntbyname_r");
  367 
  368   keyval[0] = (char **)canon_key;
  369   keyval[1] = (char **)value;
  370 
  371   for (i = 0; i < context->lac_dn_count; i++)
  372     {
  373       LA_INIT (a);
  374       LA_TYPE (a) = LA_TYPE_STRING;
  375       LA_STRING (a) = key;
  376       LA_BASE (a) = context->lac_dn_list[i];
  377 
  378       /* we do not acquire lock in this case */
  379       stat = _nss_ldap_getbyname (&a,
  380                   (void *)keyval,
  381                   buffer, buflen, errnop,
  382                   _nss_ldap_filt_getautomntbyname,
  383                   LM_AUTOMOUNT,
  384                   _nss_ldap_parse_automount);
  385 
  386       if (stat != NSS_NOTFOUND)
  387     {
  388       break; /* on success or error other than not found */
  389     }
  390     }
  391 
  392   debug ("<== _nss_ldap_getautomntbyname_r");
  393 
  394   return stat;
  395 }
  396 
  397 #endif /* HAVE_NSS_H */
  398