"Fossies" - the Fresh Open Source Software Archive

Member "nss_ldap-265/ldap-hosts.c" (6 Nov 2009, 11641 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) 1997-2005 Luke Howard.
    2    This file is part of the nss_ldap library.
    3    Contributed by Luke Howard, <lukeh@padl.com>, 1997.
    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-hosts.c,v 2.37 2009/05/26 07:25:12 lukeh Exp $
   21  */
   22 
   23 static char rcsId[] =
   24   "$Id: ldap-hosts.c,v 2.37 2009/05/26 07:25:12 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 <sys/socket.h>
   39 #include <stdio.h>
   40 #include <stdlib.h>
   41 #include <string.h>
   42 #include <netdb.h>
   43 #include <netinet/in.h>
   44 #include <arpa/inet.h>
   45 #include <arpa/nameser.h>
   46 #ifdef HAVE_ARPA_NAMESER_COMPAT_H
   47 #include <arpa/nameser_compat.h>
   48 #endif
   49 #include <resolv.h>
   50 
   51 #ifdef HAVE_LBER_H
   52 #include <lber.h>
   53 #endif
   54 #ifdef HAVE_LDAP_H
   55 #include <ldap.h>
   56 #endif
   57 
   58 #ifdef INET6
   59 #include <resolv/mapv4v6addr.h>
   60 #endif
   61 
   62 #ifndef MAXALIASES
   63 #define MAXALIASES 35
   64 #endif
   65 
   66 #include "ldap-nss.h"
   67 #include "ldap-hosts.h"
   68 #include "util.h"
   69 
   70 #ifdef HAVE_PORT_AFTER_H
   71 #include <port_after.h>
   72 #endif
   73 
   74 #ifdef HAVE_NSS_H
   75 static ent_context_t *hosts_context = NULL;
   76 #endif
   77 
   78 static NSS_STATUS
   79 _nss_ldap_parse_hostv4 (LDAPMessage * e,
   80             ldap_state_t * pvt,
   81             void *result, char *buffer, size_t buflen)
   82 {
   83   return _nss_ldap_parse_host (e, pvt, result, buffer, buflen,
   84                    AF_INET);
   85 }
   86 
   87 #ifdef INET6
   88 static NSS_STATUS
   89 _nss_ldap_parse_hostv6 (LDAPMessage * e,
   90             ldap_state_t * pvt,
   91             void *result, char *buffer, size_t buflen)
   92 {
   93   return _nss_ldap_parse_host (e, pvt, result, buffer, buflen,
   94                    AF_INET6);
   95 }
   96 #endif
   97 
   98 static NSS_STATUS
   99 _nss_ldap_parse_host (LDAPMessage * e,
  100               ldap_state_t * pvt,
  101               void *result, char *buffer, size_t buflen,
  102               int af)
  103 {
  104   /* this code needs reviewing. XXX */
  105   struct hostent *host = (struct hostent *) result;
  106   NSS_STATUS stat;
  107 #ifdef INET6
  108   char addressbuf[sizeof ("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255") *
  109           MAXALIASES];
  110 #else
  111   char addressbuf[sizeof ("255.255.255.255") * MAXALIASES];
  112 #endif
  113   char *p_addressbuf = addressbuf;
  114   char **addresses = NULL;
  115   size_t addresslen = sizeof (addressbuf);
  116   size_t addresscount = 0;
  117   char **host_addresses = NULL;
  118   int i;
  119 
  120   *addressbuf = *buffer = '\0';
  121 
  122   stat = _nss_ldap_assign_attrval (e, ATM (LM_HOSTS, cn), &host->h_name,
  123                    &buffer, &buflen);
  124   if (stat != NSS_SUCCESS)
  125     return stat;
  126 
  127   stat =
  128     _nss_ldap_assign_attrvals (e, ATM (LM_HOSTS, cn), host->h_name,
  129                                &host->h_aliases, &buffer, &buflen, NULL);
  130   if (stat != NSS_SUCCESS)
  131     return stat;
  132 
  133   stat =
  134     _nss_ldap_assign_attrvals (e, AT (ipHostNumber), NULL, &addresses,
  135                    &p_addressbuf, &addresslen, &addresscount);
  136   if (stat != NSS_SUCCESS)
  137     return stat;
  138   if (addresscount == 0)
  139     return NSS_NOTFOUND;
  140 
  141 #ifdef INET6
  142   if (af == AF_INET6)
  143     {
  144       if (bytesleft (buffer, buflen, char *) <
  145       (size_t) ((addresscount + 1) * IN6ADDRSZ))
  146       return NSS_TRYAGAIN;
  147     }
  148   else
  149     {
  150       if (bytesleft (buffer, buflen, char *) <
  151       (size_t) ((addresscount + 1) * INADDRSZ))
  152       return NSS_TRYAGAIN;
  153     }
  154 #else
  155   if (bytesleft (buffer, buflen, char *) <
  156       (size_t) ((addresscount + 1) * INADDRSZ))
  157       return NSS_TRYAGAIN;
  158 #endif
  159 
  160   align (buffer, buflen, char *);
  161   host_addresses = (char **) buffer;
  162   host->h_addr_list = host_addresses;
  163   host_addresses[addresscount] = NULL;
  164 
  165   buffer += (addresscount + 1) * sizeof (char *);
  166   buflen -= (addresscount + 1) * sizeof (char *);
  167 #ifdef INET6
  168   host->h_addrtype = 0;
  169   host->h_length = 0;
  170 #else
  171   host->h_addrtype = AF_INET;
  172   host->h_length = INADDRSZ;
  173 #endif
  174 
  175   for (i = 0; i < (int) addresscount; i++)
  176     {
  177 #ifdef INET6
  178       char *addr = addresses[i];
  179       char entdata[16];
  180       /* from glibc NIS parser. Thanks, Uli. */
  181 
  182       if (af == AF_INET && inet_pton (AF_INET, addr, entdata) > 0)
  183     {
  184       if (_res.options & RES_USE_INET6)
  185         {
  186           map_v4v6_address ((char *) entdata,
  187                 (char *) entdata);
  188           host->h_addrtype = AF_INET6;
  189           host->h_length = IN6ADDRSZ;
  190         }
  191       else
  192         {
  193           host->h_addrtype = AF_INET;
  194           host->h_length = INADDRSZ;
  195         }
  196     }
  197       else if (af == AF_INET6
  198            && inet_pton (AF_INET6, addr, entdata) > 0)
  199     {
  200       host->h_addrtype = AF_INET6;
  201       host->h_length = IN6ADDRSZ;
  202     }
  203       else
  204     /* Illegal address: ignore line.  */
  205     continue;
  206 
  207 #else
  208       unsigned long haddr;
  209       haddr = inet_addr (addresses[i]);
  210 #endif
  211 
  212       if (buflen < (size_t) host->h_length)
  213     return NSS_TRYAGAIN;
  214 
  215 #ifdef INET6
  216       memcpy (buffer, entdata, host->h_length);
  217       *host_addresses = buffer;
  218       buffer += host->h_length;
  219       buflen -= host->h_length;
  220 #else
  221       memcpy (buffer, &haddr, INADDRSZ);
  222       *host_addresses = buffer;
  223       buffer += INADDRSZ;
  224       buflen -= INADDRSZ;
  225 #endif
  226 
  227       host_addresses++;
  228       *host_addresses = NULL;
  229     }
  230 
  231 #ifdef INET6
  232   /* if host->h_addrtype is not changed, this entry does not
  233      have the right IP address.  */
  234   if (host->h_addrtype == 0)
  235     return NSS_NOTFOUND;
  236 #endif
  237 
  238   return NSS_SUCCESS;
  239 }
  240 
  241 #ifdef HAVE_NSSWITCH_H
  242 static NSS_STATUS
  243 _nss_ldap_gethostbyname_r (nss_backend_t * be, void *args)
  244 {
  245   ldap_args_t a;
  246   NSS_STATUS status;
  247 
  248   LA_INIT (a);
  249   LA_STRING (a) = NSS_ARGS (args)->key.name;
  250   LA_TYPE (a) = LA_TYPE_STRING;
  251 
  252   status = _nss_ldap_getbyname (&a,
  253                 NSS_ARGS (args)->buf.result,
  254                 NSS_ARGS (args)->buf.buffer,
  255                 NSS_ARGS (args)->buf.buflen,
  256                 &NSS_ARGS (args)->erange,
  257                 _nss_ldap_filt_gethostbyname,
  258                 LM_HOSTS, _nss_ldap_parse_hostv4);
  259 
  260   if (status == NSS_SUCCESS)
  261     NSS_ARGS (args)->returnval = NSS_ARGS (args)->buf.result;
  262 
  263   MAP_H_ERRNO (status, NSS_ARGS (args)->h_errno);
  264 
  265   return status;
  266 }
  267 #elif defined(HAVE_NSS_H)
  268 NSS_STATUS
  269 _nss_ldap_gethostbyname2_r (const char *name, int af, struct hostent * result,
  270                 char *buffer, size_t buflen, int *errnop,
  271                 int *h_errnop)
  272 {
  273   NSS_STATUS status;
  274   ldap_args_t a;
  275 
  276 #ifndef INET6
  277   if (af == AF_INET6)
  278     {
  279       return NSS_NOTFOUND;
  280     }
  281 #endif
  282 
  283   LA_INIT (a);
  284   LA_STRING (a) = name;
  285   LA_TYPE (a) = LA_TYPE_STRING;
  286 
  287   status = _nss_ldap_getbyname (&a,
  288                 result,
  289                 buffer,
  290                 buflen,
  291                 errnop,
  292                 _nss_ldap_filt_gethostbyname,
  293                 LM_HOSTS,
  294 #ifdef INET6
  295                 (af == AF_INET6) ?
  296                 _nss_ldap_parse_hostv6 :
  297 #endif
  298                 _nss_ldap_parse_hostv4);
  299 
  300   MAP_H_ERRNO (status, *h_errnop);
  301 
  302   return status;
  303 }
  304 
  305 NSS_STATUS
  306 _nss_ldap_gethostbyname_r (const char *name, struct hostent * result,
  307                char *buffer, size_t buflen, int *errnop,
  308                int *h_errnop)
  309 {
  310   return _nss_ldap_gethostbyname2_r (name,
  311 #ifdef INET6
  312                      (_res.options & RES_USE_INET6) ?
  313                      AF_INET6 :
  314 #endif
  315                      AF_INET, result, buffer, buflen,
  316                      errnop, h_errnop);
  317 }
  318 #endif
  319 
  320 #ifdef HAVE_NSSWITCH_H
  321 static NSS_STATUS
  322 _nss_ldap_gethostbyaddr_r (nss_backend_t * be, void *args)
  323 {
  324   struct in_addr iaddr;
  325   ldap_args_t a;
  326   NSS_STATUS status;
  327 
  328   memcpy (&iaddr.s_addr, NSS_ARGS (args)->key.hostaddr.addr,
  329       NSS_ARGS (args)->key.hostaddr.len);
  330   LA_INIT (a);
  331   LA_STRING (a) = inet_ntoa (iaddr);
  332   LA_TYPE (a) = LA_TYPE_STRING;
  333 
  334   status = _nss_ldap_getbyname (&a,
  335                 NSS_ARGS (args)->buf.result,
  336                 NSS_ARGS (args)->buf.buffer,
  337                 NSS_ARGS (args)->buf.buflen,
  338                 &NSS_ARGS (args)->erange,
  339                 _nss_ldap_filt_gethostbyaddr,
  340                 LM_HOSTS, _nss_ldap_parse_hostv4);
  341 
  342   if (status == NSS_SUCCESS)
  343     NSS_ARGS (args)->returnval = NSS_ARGS (args)->buf.result;
  344 
  345   MAP_H_ERRNO (status, NSS_ARGS (args)->h_errno);
  346 
  347   return status;
  348 }
  349 #elif defined(HAVE_NSS_H)
  350 NSS_STATUS
  351 _nss_ldap_gethostbyaddr_r (struct in_addr * addr, int len, int type,
  352                struct hostent * result, char *buffer,
  353                size_t buflen, int *errnop, int *h_errnop)
  354 {
  355   NSS_STATUS status;
  356   ldap_args_t a;
  357 
  358   /* if querying by IPv6 address, make sure the address is "normalized" --
  359    * it should contain no leading zeros and all components of the address.
  360    * still we can't fit an IPv6 address in an int, so who cares for now.
  361    */
  362 
  363   LA_INIT (a);
  364   LA_STRING (a) = inet_ntoa (*addr);
  365   LA_TYPE (a) = LA_TYPE_STRING;
  366 
  367   status = _nss_ldap_getbyname (&a,
  368                 result,
  369                 buffer,
  370                 buflen,
  371                 errnop,
  372                 _nss_ldap_filt_gethostbyaddr,
  373                 LM_HOSTS,
  374 #ifdef INET6
  375                 (type == AF_INET6) ?
  376                 _nss_ldap_parse_hostv6 :
  377 #endif
  378                 _nss_ldap_parse_hostv4);
  379 
  380   MAP_H_ERRNO (status, *h_errnop);
  381 
  382   return status;
  383 }
  384 #endif
  385 
  386 #ifdef HAVE_NSSWITCH_H
  387 static NSS_STATUS
  388 _nss_ldap_sethostent_r (nss_backend_t * hosts_context, void *fakeargs)
  389 #elif defined(HAVE_NSS_H)
  390      NSS_STATUS _nss_ldap_sethostent (void)
  391 #endif
  392 #if defined(HAVE_NSS_H) || defined(HAVE_NSSWITCH_H)
  393 {
  394   LOOKUP_SETENT (hosts_context);
  395 }
  396 #endif
  397 
  398 #ifdef HAVE_NSSWITCH_H
  399 static NSS_STATUS
  400 _nss_ldap_endhostent_r (nss_backend_t * hosts_context, void *fakeargs)
  401 #elif defined(HAVE_NSS_H)
  402      NSS_STATUS _nss_ldap_endhostent (void)
  403 #endif
  404 #if defined(HAVE_NSS_H) || defined(HAVE_NSSWITCH_H)
  405 {
  406   LOOKUP_ENDENT (hosts_context);
  407 }
  408 #endif
  409 
  410 #ifdef HAVE_NSSWITCH_H
  411 static NSS_STATUS
  412 _nss_ldap_gethostent_r (nss_backend_t * hosts_context, void *args)
  413 {
  414   NSS_STATUS status = _nss_ldap_getent (&((nss_ldap_backend_t *)
  415                       hosts_context)->state,
  416                     NSS_ARGS (args)->buf.result,
  417                     NSS_ARGS (args)->buf.buffer,
  418                     NSS_ARGS (args)->buf.buflen,
  419                     &NSS_ARGS (args)->erange,
  420                     _nss_ldap_filt_gethostent,
  421                     LM_HOSTS,
  422                     _nss_ldap_parse_hostv4);
  423 
  424   if (status == NSS_SUCCESS)
  425     NSS_ARGS (args)->returnval = NSS_ARGS (args)->buf.result;
  426 
  427   MAP_H_ERRNO (status, NSS_ARGS (args)->h_errno);
  428 
  429   return status;
  430 }
  431 #elif defined(HAVE_NSS_H)
  432 NSS_STATUS
  433 _nss_ldap_gethostent_r (struct hostent * result, char *buffer, size_t buflen,
  434             int *errnop, int *h_errnop)
  435 {
  436   NSS_STATUS status;
  437 
  438   status = _nss_ldap_getent (&hosts_context,
  439                  result,
  440                  buffer,
  441                  buflen,
  442                  errnop,
  443                  _nss_ldap_filt_gethostent, LM_HOSTS,
  444 #ifdef INET6
  445                  (_res.options & RES_USE_INET6) ?
  446                  _nss_ldap_parse_hostv6 :
  447 #endif
  448                  _nss_ldap_parse_hostv4);
  449 
  450   MAP_H_ERRNO (status, *h_errnop);
  451 
  452   return status;
  453 }
  454 #endif
  455 
  456 #ifdef HAVE_NSSWITCH_H
  457 static NSS_STATUS
  458 _nss_ldap_hosts_destr (nss_backend_t * hosts_context, void *args)
  459 {
  460   return _nss_ldap_default_destr (hosts_context, args);
  461 }
  462 
  463 static nss_backend_op_t host_ops[] = {
  464   _nss_ldap_hosts_destr,
  465   _nss_ldap_endhostent_r,
  466   _nss_ldap_sethostent_r,
  467   _nss_ldap_gethostent_r,
  468   _nss_ldap_gethostbyname_r,
  469   _nss_ldap_gethostbyaddr_r
  470 };
  471 
  472 nss_backend_t *
  473 _nss_ldap_hosts_constr (const char *db_name,
  474             const char *src_name, const char *cfg_args)
  475 {
  476   nss_ldap_backend_t *be;
  477 
  478   if (!(be = (nss_ldap_backend_t *) malloc (sizeof (*be))))
  479     return NULL;
  480 
  481   be->ops = host_ops;
  482   be->n_ops = sizeof (host_ops) / sizeof (nss_backend_op_t);
  483 
  484   if (_nss_ldap_default_constr (be) != NSS_SUCCESS)
  485     return NULL;
  486 
  487   return (nss_backend_t *) be;
  488 }
  489 
  490 #endif /* !HAVE_NSS_H */
  491 
  492 #ifdef HAVE_IRS_H
  493 #include "irs-hosts.c"
  494 #endif