"Fossies" - the Fresh Open Source Software Archive

Member "nss_ldap-265/ldap-service.c" (6 Nov 2009, 9417 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-service.c,v 2.33 2008/10/30 20:49:47 lukeh Exp $
   21  */
   22 
   23 /*
   24    Determine the canonical name of the RPC with _nss_ldap_getrdnvalue(),
   25    and assign any values of "cn" which do NOT match this canonical name
   26    as aliases.
   27  */
   28 
   29 
   30 static char rcsId[] =
   31   "$Id: ldap-service.c,v 2.33 2008/10/30 20:49:47 lukeh Exp $";
   32 
   33 #include "config.h"
   34 
   35 #ifdef HAVE_PORT_BEFORE_H
   36 #include <port_before.h>
   37 #endif
   38 
   39 #if defined(HAVE_THREAD_H) && !defined(_AIX)
   40 #include <thread.h>
   41 #elif defined(HAVE_PTHREAD_H)
   42 #include <pthread.h>
   43 #endif
   44 
   45 #include <stdio.h>
   46 #include <stdlib.h>
   47 #include <string.h>
   48 #include <netdb.h>
   49 #include <netinet/in.h>
   50 
   51 #ifdef HAVE_SYS_BYTEORDER_H
   52 #include <sys/byteorder.h>
   53 #endif
   54 
   55 #ifdef HAVE_LBER_H
   56 #include <lber.h>
   57 #endif
   58 #ifdef HAVE_LDAP_H
   59 #include <ldap.h>
   60 #endif
   61 
   62 #include "ldap-nss.h"
   63 #include "ldap-service.h"
   64 #include "util.h"
   65 
   66 #ifdef HAVE_PORT_AFTER_H
   67 #include <port_after.h>
   68 #endif
   69 
   70 #ifdef HAVE_NSS_H
   71 static ent_context_t *serv_context = NULL;
   72 #endif
   73 
   74 static NSS_STATUS
   75 _nss_ldap_parse_serv (LDAPMessage * e,
   76               ldap_state_t * state,
   77               void *result, char *buffer, size_t buflen)
   78 {
   79   struct servent *service = (struct servent *) result;
   80   char *portstr;
   81   int port;
   82   NSS_STATUS stat = NSS_SUCCESS;
   83 
   84   /* this is complicated and ugly, because some git (me) specified that service
   85    * entries should expand to two entities (or more) if they have multi-valued
   86    * ipServiceProtocol fields.
   87    */
   88 
   89   if (state->ls_type == LS_TYPE_KEY)
   90     {
   91       if (state->ls_info.ls_key == NULL)
   92     {
   93       /* non-deterministic behaviour is ok */
   94       stat =
   95         _nss_ldap_assign_attrval (e, AT (ipServiceProtocol),
   96                       &service->s_proto, &buffer, &buflen);
   97       if (stat != NSS_SUCCESS)
   98         {
   99           return stat;
  100         }
  101     }
  102       else
  103     {
  104       register int len;
  105       len = strlen (state->ls_info.ls_key);
  106       if (buflen < (size_t) (len + 1))
  107         {
  108           return NSS_TRYAGAIN;
  109         }
  110       strncpy (buffer, state->ls_info.ls_key, len);
  111       buffer[len] = '\0';
  112       service->s_proto = buffer;
  113       buffer += len + 1;
  114       buflen -= len + 1;
  115     }
  116     }
  117   else
  118     {
  119       char **vals = _nss_ldap_get_values (e, AT (ipServiceProtocol));
  120       int len;
  121       if (vals == NULL)
  122     {
  123       state->ls_info.ls_index = -1;
  124       return NSS_NOTFOUND;
  125     }
  126 
  127       switch (state->ls_info.ls_index)
  128     {
  129     case 0:
  130       /* last time. decrementing ls_index to -1 AND returning !NSS_SUCCESS
  131          will force this entry to be discarded.
  132        */
  133       stat = NSS_NOTFOUND;
  134       break;
  135     case -1:
  136       /* first time */
  137       state->ls_info.ls_index = ldap_count_values (vals);
  138       /* fall off to default ... */
  139     default:
  140       len = strlen (vals[state->ls_info.ls_index - 1]);
  141       if (buflen < (size_t) (len + 1))
  142         {
  143           return NSS_TRYAGAIN;
  144         }
  145       strncpy (buffer, vals[state->ls_info.ls_index - 1], len);
  146       buffer[len] = '\0';
  147       service->s_proto = buffer;
  148       buffer += len + 1;
  149       buflen -= len + 1;
  150       stat = NSS_SUCCESS;
  151     }
  152 
  153       ldap_value_free (vals);
  154       state->ls_info.ls_index--;
  155     }
  156 
  157   if (stat != NSS_SUCCESS)
  158     {
  159       return stat;
  160     }
  161 
  162   stat =
  163     _nss_ldap_getrdnvalue (e, ATM (LM_SERVICES, cn), &service->s_name,
  164                            &buffer, &buflen);
  165   if (stat != NSS_SUCCESS)
  166     {
  167       return stat;
  168     }
  169 
  170   stat =
  171     _nss_ldap_assign_attrvals (e, ATM (LM_SERVICES, cn), service->s_name,
  172                    &service->s_aliases, &buffer, &buflen, NULL);
  173   if (stat != NSS_SUCCESS)
  174     {
  175       return stat;
  176     }
  177 
  178   stat =
  179     _nss_ldap_assign_attrval (e, AT (ipServicePort), &portstr, &buffer,
  180                   &buflen);
  181   if (stat != NSS_SUCCESS)
  182     {
  183       return stat;
  184     }
  185 
  186   stat = _nss_ldap_parse_int (portstr, 0, &port);
  187   if (stat != NSS_SUCCESS)
  188     {
  189       return stat;
  190     }
  191 
  192   service->s_port = htons(port);
  193 
  194   return NSS_SUCCESS;
  195 }
  196 
  197 #ifdef HAVE_NSSWITCH_H
  198 static NSS_STATUS
  199 _nss_ldap_getservbyname_r (nss_backend_t * be, void *args)
  200 {
  201   ldap_args_t a;
  202   NSS_STATUS status;
  203 
  204   LA_INIT (a);
  205   LA_STRING (a) = NSS_ARGS (args)->key.serv.serv.name;
  206   LA_TYPE (a) = (NSS_ARGS (args)->key.serv.proto == NULL) ?
  207     LA_TYPE_STRING : LA_TYPE_STRING_AND_STRING;
  208   LA_STRING2 (a) = NSS_ARGS (args)->key.serv.proto;
  209 
  210   status = _nss_ldap_getbyname (&a,
  211                 NSS_ARGS (args)->buf.result,
  212                 NSS_ARGS (args)->buf.buffer,
  213                 NSS_ARGS (args)->buf.buflen,
  214                 &NSS_ARGS (args)->erange,
  215                 (NSS_ARGS (args)->key.serv.proto == NULL) ?
  216                 _nss_ldap_filt_getservbyname :
  217                 _nss_ldap_filt_getservbynameproto, LM_SERVICES,
  218                 _nss_ldap_parse_serv);
  219 
  220   if (status == NSS_SUCCESS)
  221     NSS_ARGS (args)->returnval = NSS_ARGS (args)->buf.result;
  222 
  223   return status;
  224 }
  225 #elif defined(HAVE_NSS_H)
  226 NSS_STATUS
  227 _nss_ldap_getservbyname_r (const char *name,
  228                const char *proto,
  229                struct servent * result,
  230                char *buffer, size_t buflen, int *errnop)
  231 {
  232   ldap_args_t a;
  233 
  234   LA_INIT (a);
  235   LA_STRING (a) = name;
  236   LA_TYPE (a) = (proto == NULL) ? LA_TYPE_STRING : LA_TYPE_STRING_AND_STRING;
  237   LA_STRING2 (a) = proto;
  238 
  239   return _nss_ldap_getbyname (&a, result, buffer, buflen, errnop,
  240                   ((proto == NULL) ? _nss_ldap_filt_getservbyname
  241                    : _nss_ldap_filt_getservbynameproto),
  242                   LM_SERVICES, _nss_ldap_parse_serv);
  243 }
  244 #endif
  245 
  246 #ifdef HAVE_NSSWITCH_H
  247 static NSS_STATUS
  248 _nss_ldap_getservbyport_r (nss_backend_t * be, void *args)
  249 {
  250   ldap_args_t a;
  251   NSS_STATUS status;
  252 
  253   LA_INIT (a);
  254   LA_NUMBER (a) = htons (NSS_ARGS (args)->key.serv.serv.port);
  255   LA_TYPE (a) = (NSS_ARGS (args)->key.serv.proto == NULL) ?
  256     LA_TYPE_NUMBER : LA_TYPE_NUMBER_AND_STRING;
  257   LA_STRING2 (a) = NSS_ARGS (args)->key.serv.proto;
  258 
  259   status = _nss_ldap_getbyname (&a,
  260                 NSS_ARGS (args)->buf.result,
  261                 NSS_ARGS (args)->buf.buffer,
  262                 NSS_ARGS (args)->buf.buflen,
  263                 &NSS_ARGS (args)->erange,
  264                 (NSS_ARGS (args)->key.serv.proto == NULL) ?
  265                 _nss_ldap_filt_getservbyport :
  266                 _nss_ldap_filt_getservbyportproto, LM_SERVICES,
  267                 _nss_ldap_parse_serv);
  268 
  269   if (status == NSS_SUCCESS)
  270     NSS_ARGS (args)->returnval = NSS_ARGS (args)->buf.result;
  271 
  272   return status;
  273 }
  274 #elif defined(HAVE_NSS_H)
  275 NSS_STATUS
  276 _nss_ldap_getservbyport_r (int port,
  277                const char *proto,
  278                struct servent * result,
  279                char *buffer, size_t buflen, int *errnop)
  280 {
  281   ldap_args_t a;
  282 
  283   LA_INIT (a);
  284   LA_NUMBER (a) = htons (port);
  285   LA_TYPE (a) = (proto == NULL) ? LA_TYPE_NUMBER : LA_TYPE_NUMBER_AND_STRING;
  286   LA_STRING2 (a) = proto;
  287   return _nss_ldap_getbyname (&a, result, buffer, buflen, errnop,
  288                   (proto ==
  289                    NULL) ? _nss_ldap_filt_getservbyport :
  290                   _nss_ldap_filt_getservbyportproto,
  291                   LM_SERVICES, _nss_ldap_parse_serv);
  292 }
  293 #endif
  294 
  295 #ifdef HAVE_NSSWITCH_H
  296 static NSS_STATUS
  297 _nss_ldap_setservent_r (nss_backend_t * serv_context, void *args)
  298 #elif defined(HAVE_NSS_H)
  299      NSS_STATUS _nss_ldap_setservent (void)
  300 #endif
  301 #if defined(HAVE_NSS_H) || defined(HAVE_NSSWITCH_H)
  302 {
  303   LOOKUP_SETENT (serv_context);
  304 }
  305 #endif
  306 
  307 #ifdef HAVE_NSSWITCH_H
  308 static NSS_STATUS
  309 _nss_ldap_endservent_r (nss_backend_t * serv_context, void *args)
  310 #elif defined(HAVE_NSS_H)
  311      NSS_STATUS _nss_ldap_endservent (void)
  312 #endif
  313 #if defined(HAVE_NSS_H) || defined(HAVE_NSSWITCH_H)
  314 {
  315   LOOKUP_ENDENT (serv_context);
  316 }
  317 #endif
  318 
  319 #ifdef HAVE_NSSWITCH_H
  320 static NSS_STATUS
  321 _nss_ldap_getservent_r (nss_backend_t * serv_context, void *args)
  322 {
  323   LOOKUP_GETENT (args, serv_context, _nss_ldap_filt_getservent, LM_SERVICES,
  324          _nss_ldap_parse_serv, LDAP_NSS_BUFLEN_DEFAULT);
  325 }
  326 #elif defined(HAVE_NSS_H)
  327 NSS_STATUS
  328 _nss_ldap_getservent_r (struct servent *result, char *buffer, size_t buflen,
  329             int *errnop)
  330 {
  331   LOOKUP_GETENT (serv_context, result, buffer, buflen, errnop,
  332          _nss_ldap_filt_getservent, LM_SERVICES,
  333          _nss_ldap_parse_serv, LDAP_NSS_BUFLEN_DEFAULT);
  334 }
  335 #endif
  336 
  337 #ifdef HAVE_NSSWITCH_H
  338 static NSS_STATUS
  339 _nss_ldap_services_destr (nss_backend_t * serv_context, void *args)
  340 {
  341   return _nss_ldap_default_destr (serv_context, args);
  342 }
  343 
  344 static nss_backend_op_t services_ops[] = {
  345   _nss_ldap_services_destr,
  346   _nss_ldap_endservent_r,
  347   _nss_ldap_setservent_r,
  348   _nss_ldap_getservent_r,
  349   _nss_ldap_getservbyname_r,
  350   _nss_ldap_getservbyport_r
  351 };
  352 
  353 nss_backend_t *
  354 _nss_ldap_services_constr (const char *db_name,
  355                const char *src_name, const char *cfg_args)
  356 {
  357   nss_ldap_backend_t *be;
  358 
  359   if (!(be = (nss_ldap_backend_t *) malloc (sizeof (*be))))
  360     return NULL;
  361 
  362   be->ops = services_ops;
  363   be->n_ops = sizeof (services_ops) / sizeof (nss_backend_op_t);
  364 
  365   if (_nss_ldap_default_constr (be) != NSS_SUCCESS)
  366     return NULL;
  367 
  368   return (nss_backend_t *) be;
  369 }
  370 
  371 #endif /* !HAVE_NSS_H */
  372 
  373 #ifdef HAVE_IRS_H
  374 #include "irs-service.c"
  375 #endif