"Fossies" - the Fresh Open Source Software Archive

Member "nss_ldap-265/aix_authmeth.c" (6 Nov 2009, 22675 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) 2002-2005 Luke Howard.
    2    This file is part of the nss_ldap library.
    3    Contributed by Luke Howard, <lukeh@padl.com>, 2002.
    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 
   21 /*
   22  * Shim to support AIX loadable authentication modules
   23  */
   24 
   25 #include "config.h"
   26 
   27 static char rcsId[] =
   28   "$Id: aix_authmeth.c,v 2.33 2009/11/06 10:15:26 lukeh Exp $";
   29 
   30 #ifdef HAVE_USERSEC_H
   31 
   32 #include <stdlib.h>
   33 #include <string.h>
   34 #include <usersec.h>
   35 
   36 #ifdef HAVE_LBER_H
   37 #include <lber.h>
   38 #endif
   39 #ifdef HAVE_LDAP_H
   40 #include <ldap.h>
   41 #endif
   42 
   43 #include "ldap-nss.h"
   44 #include "util.h"
   45 
   46 #define TABLE_KEY_ALL   "ALL"
   47 #define TABLE_USER  "user"
   48 #define TABLE_GROUP "group"
   49 
   50 #define S_LDAPDN    "ldapdn"
   51 
   52 static struct irs_gr *uess_gr_be = NULL;
   53 static struct irs_pw *uess_pw_be = NULL;
   54 
   55 extern void *gr_pvtinit (void); /* irs-grp.c */
   56 extern void *pw_pvtinit (void); /* irs-pwd.c */
   57 
   58 /* from ldap-grp.c */
   59 extern char *_nss_ldap_getgrset (char *user);
   60 
   61 /* search arguments for getentry method */
   62 typedef struct ldap_uess_args
   63 {
   64   /* argument block */
   65   const char *lua_key;
   66   const char *lua_table;
   67   char **lua_attributes;
   68   attrval_t *lua_results;
   69   int lua_size;
   70 
   71   /* private */
   72   ldap_map_selector_t lua_map;
   73   size_t lua__bufsiz;
   74   size_t lua__buflen;
   75   char *lua__buffer;
   76   const char *lua_naming_attribute;
   77 }
   78 ldap_uess_args_t;
   79 
   80 static NSS_STATUS uess_get_char (LDAPMessage * e, ldap_uess_args_t * arg, int index);
   81 static NSS_STATUS uess_get_char_ex (LDAPMessage * e, ldap_uess_args_t * arg, int index, const char *attribute);
   82 static NSS_STATUS uess_get_int (LDAPMessage * e, ldap_uess_args_t * arg, int index);
   83 static NSS_STATUS uess_get_pgrp (LDAPMessage * e, ldap_uess_args_t * arg, int index);
   84 static NSS_STATUS uess_get_groupsids (LDAPMessage * e, ldap_uess_args_t * arg, int index);
   85 static NSS_STATUS uess_get_gecos (LDAPMessage * e, ldap_uess_args_t * arg, int index);
   86 static NSS_STATUS uess_get_pwd (LDAPMessage * e, ldap_uess_args_t * arg, int index);
   87 static NSS_STATUS uess_get_dn (LDAPMessage * e, ldap_uess_args_t * arg, int index);
   88 
   89 /* dispatch table for retrieving UESS attribute from an LDAP entry */
   90 struct ldap_uess_fn
   91 {
   92   const char *luf_attribute;
   93   NSS_STATUS (*luf_translator) (LDAPMessage * e,
   94                 ldap_uess_args_t *, int);
   95 }
   96 ldap_uess_fn_t;
   97 
   98 static struct ldap_uess_fn __uess_fns[] = {
   99   {S_GECOS, uess_get_gecos},
  100   {S_GROUPSIDS, uess_get_groupsids},
  101   {S_HOME, uess_get_char},
  102   {S_ID, uess_get_int},
  103   {S_PWD, uess_get_pwd},
  104   {S_SHELL, uess_get_char},
  105   {S_PGRP, uess_get_pgrp},
  106   {SEC_PASSWD, uess_get_char},
  107   {SEC_LASTUP, uess_get_int},
  108   {S_MAXAGE, uess_get_int},
  109   {S_MINAGE, uess_get_int},
  110   {S_MAXEXPIRED, uess_get_int},
  111   {S_PWDWARNTIME, uess_get_int},
  112   /* add additional attributes we know about here */
  113   {S_LDAPDN, uess_get_dn},
  114   {NULL, NULL}
  115 };
  116 
  117 #define GR_PVTINIT()    do { \
  118         if (uess_gr_be == NULL) { \
  119             uess_gr_be = (struct irs_gr *) gr_pvtinit (); \
  120             if (uess_gr_be == NULL) \
  121                 return NULL; \
  122         } \
  123     } while (0)
  124 
  125 #define PW_PVTINIT()    do { \
  126         if (uess_pw_be == NULL) { \
  127             uess_pw_be = (struct irs_pw *) pw_pvtinit (); \
  128             if (uess_pw_be == NULL) \
  129                 return NULL; \
  130         } \
  131     } while (0)
  132     
  133 static void *
  134 _nss_ldap_uess_open (const char *name, const char *domain,
  135              const int mode, char *options)
  136 {
  137   /* Currently we do not use the above parameters */
  138   GR_PVTINIT();
  139   PW_PVTINIT();
  140 
  141   return NULL;
  142 }
  143 
  144 static void
  145 _nss_ldap_uess_close (void *token)
  146 {
  147   if (uess_gr_be != NULL)
  148     {
  149       (uess_gr_be->close) (uess_gr_be);
  150       uess_gr_be = NULL;
  151     }
  152 
  153   if (uess_pw_be != NULL)
  154     {
  155       (uess_pw_be->close) (uess_pw_be);
  156       uess_pw_be = NULL;
  157     }
  158 }
  159 
  160 static struct group *
  161 _nss_ldap_getgrgid (gid_t gid)
  162 {
  163   GR_PVTINIT ();
  164 
  165   return (uess_gr_be->bygid) (uess_gr_be, gid);
  166 }
  167 
  168 static struct group *
  169 _nss_ldap_getgrnam (const char *name)
  170 {
  171   GR_PVTINIT ();
  172 
  173   return (uess_gr_be->byname) (uess_gr_be, name);
  174 }
  175 
  176 static struct passwd *
  177 _nss_ldap_getpwuid (uid_t uid)
  178 {
  179   PW_PVTINIT ();
  180 
  181   return (uess_pw_be->byuid) (uess_pw_be, uid);
  182 }
  183 
  184 static struct passwd *
  185 _nss_ldap_getpwnam (const char *name)
  186 {
  187   PW_PVTINIT ();
  188 
  189   return (uess_pw_be->byname) (uess_pw_be, name);
  190 }
  191 
  192 static struct group *
  193 _nss_ldap_getgracct (void *id, int type)
  194 {
  195   GR_PVTINIT ();
  196 
  197   if (type == SEC_INT)
  198     return (uess_gr_be->bygid) (uess_gr_be, *(gid_t *) id);
  199   else
  200     return (uess_gr_be->byname) (uess_gr_be, (char *) id);
  201 }
  202 
  203 static int
  204 _nss_ldap_authenticate (char *user, char *response, int *reenter,
  205             char **message)
  206 {
  207   NSS_STATUS stat;
  208   int rc;
  209 
  210   debug ("==> _nss_ldap_authenticate");
  211 
  212   *reenter = FALSE;
  213   *message = NULL;
  214 
  215   stat = _nss_ldap_proxy_bind (user, response);
  216 
  217   switch (stat)
  218     {
  219     case NSS_TRYAGAIN:
  220       rc = AUTH_FAILURE;
  221       break;
  222     case NSS_NOTFOUND:
  223       rc = AUTH_NOTFOUND;
  224       break;
  225     case NSS_SUCCESS:
  226       rc = AUTH_SUCCESS;
  227       break;
  228     default:
  229     case NSS_UNAVAIL:
  230       rc = AUTH_UNAVAIL;
  231       break;
  232     }
  233 
  234   debug ("<== _nss_ldap_authenticate");
  235 
  236   return rc;
  237 }
  238 
  239 /*
  240  * Support this for when proxy authentication is disabled.
  241  * There may be some re-entrancy issues here; not sure
  242  * if we are supposed to return allocated memory or not,
  243  * this is not documented. I am assuming not in line with
  244  * the other APIs.
  245  */
  246 static char *
  247 _nss_ldap_getpasswd (char *user)
  248 {
  249   struct passwd *pw;
  250   static char pwdbuf[32];
  251   char *p = NULL;
  252 
  253   debug ("==> _nss_ldap_getpasswd");
  254 
  255   pw = _nss_ldap_getpwnam (user);
  256   if (pw != NULL)
  257     {
  258       if (strlen (pw->pw_passwd) > sizeof (pwdbuf) - 1)
  259     {
  260       errno = ERANGE;
  261     }
  262       else
  263     {
  264       strcpy (pwdbuf, pw->pw_passwd);
  265       p = pwdbuf;
  266     }
  267     }
  268   else
  269     {
  270       errno = ENOENT;       /* user does not exist */
  271     }
  272 
  273   debug ("<== _nss_ldap_getpasswd");
  274 
  275   return p;
  276 }
  277 
  278 /*
  279  * Convert a UESS table string to an nss_ldap map type
  280  */
  281 static ldap_map_selector_t
  282 table2map (const char *table)
  283 {
  284   if (strcmp (table, TABLE_USER) == 0)
  285     return LM_PASSWD;
  286   else if (strcmp (table, TABLE_GROUP) == 0)
  287     return LM_GROUP;
  288 
  289   return LM_NONE;
  290 }
  291 
  292 /*
  293  * Convert a UESS key to an nss_ldap internal search query
  294  */
  295 static ldap_args_t *
  296 key2filter (char *key, ldap_map_selector_t map,
  297         ldap_args_t * a, const char **filter)
  298 {
  299   if (strcmp (key, TABLE_KEY_ALL) == 0)
  300     {
  301       if (map == LM_PASSWD)
  302     *filter = _nss_ldap_filt_getpwent;
  303       else
  304     *filter = _nss_ldap_filt_getgrent;
  305 
  306       return NULL;      /* indicates enumeration */
  307     }
  308 
  309   LA_INIT (*a);
  310   LA_TYPE (*a) = LA_TYPE_STRING;
  311   LA_STRING (*a) = key;
  312 
  313   if (map == LM_PASSWD)
  314     *filter = _nss_ldap_filt_getpwnam;
  315   else
  316     *filter = _nss_ldap_filt_getgrnam;
  317 
  318   return a;
  319 }
  320 
  321 /*
  322  * Map a UESS attribute to an LDAP attribute
  323  */
  324 static const char *
  325 uess2ldapattr (ldap_map_selector_t map, const char *attribute)
  326 {
  327   if (strcmp (attribute, "username") == 0)
  328     return ATM (LM_PASSWD, uid);
  329   else if (strcmp (attribute, "groupname") == 0)
  330     return ATM (LM_GROUP, cn);
  331   else if (strcmp (attribute, S_ID) == 0)
  332     {
  333       if (map == LM_PASSWD)
  334     return ATM (LM_PASSWD, uidNumber);
  335       else
  336     return ATM (LM_GROUP, gidNumber);
  337     }
  338   else if (strcmp (attribute, S_PWD) == 0)
  339     return ATM (LM_PASSWD, userPassword);
  340   else if (strcmp (attribute, S_HOME) == 0)
  341     return ATM (LM_PASSWD, homeDirectory);
  342   else if (strcmp (attribute, S_SHELL) == 0)
  343     return ATM (LM_PASSWD, loginShell);
  344   else if (strcmp (attribute, S_GECOS) == 0)
  345     return ATM (LM_PASSWD, gecos);
  346   else if (strcmp (attribute, SEC_PASSWD) == 0)
  347     return ATM (LM_SHADOW, userPassword);
  348   else if (strcmp (attribute, SEC_LASTUP) == 0)
  349     return ATM (LM_SHADOW, shadowLastChange);
  350   else if (strcmp (attribute, S_MAXAGE) == 0)
  351     return ATM (LM_SHADOW, shadowMax);
  352   else if (strcmp (attribute, S_MINAGE) == 0)
  353     return ATM (LM_SHADOW, shadowMin);
  354   else if (strcmp (attribute, S_MAXEXPIRED) == 0)
  355     return ATM (LM_SHADOW, shadowExpire);
  356   else if (strcmp (attribute, S_PWDWARNTIME) == 0)
  357     return ATM (LM_SHADOW, shadowWarning);
  358   else if (strcmp (attribute, S_PGRP) == 0)
  359     return ATM (LM_GROUP, cn);
  360   else if (strcmp (attribute, S_USERS) == 0)
  361     return ATM (LM_GROUP, memberUid);
  362 
  363   return NULL;
  364 }
  365 
  366 /*
  367  * Get primary group name for a user
  368  */
  369 static NSS_STATUS
  370 uess_get_pgrp (LDAPMessage * e, ldap_uess_args_t * lua, int i)
  371 {
  372   char **vals;
  373   LDAPMessage *res;
  374   const char *attrs[2];
  375   NSS_STATUS stat;
  376   ldap_args_t a;
  377 
  378   vals = _nss_ldap_get_values (e, ATM (LM_PASSWD, gidNumber));
  379   if (vals == NULL)
  380     return NSS_NOTFOUND;
  381 
  382   LA_INIT (a);
  383   LA_TYPE (a) = LA_TYPE_NUMBER;
  384   stat = _nss_ldap_parse_long (vals[0], 0, &(LA_NUMBER(a)));
  385   if (stat != NSS_SUCCESS)
  386     {
  387       ldap_value_free (vals);
  388       return stat;
  389     }
  390 
  391   attrs[0] = ATM (LM_GROUP, cn);
  392   attrs[1] = NULL;
  393 
  394   stat = _nss_ldap_search_s (&a, _nss_ldap_filt_getgrgid, LM_GROUP,
  395                  attrs, 1, &res);
  396   if (stat != NSS_SUCCESS)
  397     {
  398       ldap_value_free (vals);
  399       return NSS_NOTFOUND;
  400     }
  401 
  402   ldap_value_free (vals);
  403 
  404   e = _nss_ldap_first_entry (res);
  405   if (e == NULL)
  406     {
  407       ldap_msgfree (res);
  408       return NSS_NOTFOUND;
  409     }
  410 
  411   stat = uess_get_char_ex (e, lua, i, attrs[0]);
  412 
  413   ldap_msgfree (res);
  414 
  415   return stat;
  416 }
  417 
  418 /*
  419  * Get groups to which a user belongs 
  420  */
  421 static NSS_STATUS
  422 uess_get_groupsids (LDAPMessage * e, ldap_uess_args_t * lua, int i)
  423 {
  424   char *p, *q;
  425   size_t len;
  426 
  427   p = _nss_ldap_getgrset ((char *) lua->lua_key);
  428   if (p == NULL)
  429     return NSS_NOTFOUND;
  430 
  431   len = strlen (p);
  432   q = malloc (len + 2);
  433   if (q == NULL)
  434     {
  435       errno = ENOMEM;
  436       return NSS_NOTFOUND;
  437     }
  438 
  439   memcpy (q, p, len + 1);
  440   q[len + 1] = '\0';
  441 
  442   free (p);
  443   p = NULL;
  444 
  445   for (p = q; *p != '\0'; p++)
  446     {
  447       if (*p == ',')
  448     *p++ = '\0';
  449     }
  450 
  451   lua->lua_results[i].attr_un.au_char = q;
  452 
  453   return NSS_SUCCESS;
  454 }
  455 
  456 /*
  457  * Get a mapped UESS string attribute
  458  */
  459 static NSS_STATUS
  460 uess_get_char (LDAPMessage * e, ldap_uess_args_t * lua, int i)
  461 {
  462   const char *attribute;
  463 
  464   attribute = uess2ldapattr (lua->lua_map, lua->lua_attributes[i]);
  465   if (attribute == NULL)
  466     return NSS_NOTFOUND;
  467 
  468   return uess_get_char_ex (e, lua, i, attribute);
  469 }
  470 
  471 /*
  472  * Get a specific LDAP attribute
  473  */
  474 static NSS_STATUS
  475 uess_get_char_ex (LDAPMessage * e,
  476           ldap_uess_args_t * lua, int i, const char *attribute)
  477 {
  478   char **vals;
  479   attrval_t *av = &lua->lua_results[i];
  480 
  481   vals = _nss_ldap_get_values (e, attribute);
  482   if (vals == NULL)
  483     return NSS_NOTFOUND;
  484 
  485   if (vals[0] == NULL)
  486     {
  487       ldap_value_free (vals);
  488       return NSS_NOTFOUND;
  489     }
  490 
  491   av->attr_un.au_char = strdup (vals[0]);
  492   if (av->attr_un.au_char == NULL)
  493     {
  494       ldap_value_free (vals);
  495       return NSS_TRYAGAIN;
  496     }
  497 
  498   ldap_value_free (vals);
  499   return NSS_SUCCESS;
  500 }
  501 
  502 /*
  503  * Get an encoded crypt password
  504  */
  505 static NSS_STATUS
  506 uess_get_pwd (LDAPMessage * e, ldap_uess_args_t * lua, int i)
  507 {
  508   char **vals;
  509   attrval_t *av = &lua->lua_results[i];
  510   const char *pwd;
  511   const char *attribute;
  512 
  513   attribute = uess2ldapattr (lua->lua_map, lua->lua_attributes[i]);
  514   if (attribute == NULL)
  515     return NSS_NOTFOUND;
  516 
  517   vals = _nss_ldap_get_values (e, attribute);
  518   pwd = _nss_ldap_locate_userpassword (vals);
  519 
  520   av->attr_un.au_char = strdup (pwd);
  521   if (vals != NULL)
  522     ldap_value_free (vals);
  523 
  524   return (av->attr_un.au_char == NULL) ? NSS_TRYAGAIN : NSS_SUCCESS;
  525 }
  526 
  527 /*
  528  * Get a UESS integer attribute
  529  */
  530 static NSS_STATUS
  531 uess_get_int (LDAPMessage * e, ldap_uess_args_t * lua, int i)
  532 {
  533   const char *attribute;
  534   char **vals;
  535   attrval_t *av = &lua->lua_results[i];
  536 
  537   attribute = uess2ldapattr (lua->lua_map, lua->lua_attributes[i]);
  538   if (attribute == NULL)
  539     return NSS_NOTFOUND;
  540 
  541   vals = _nss_ldap_get_values (e, attribute);
  542   if (vals == NULL)
  543     return NSS_NOTFOUND;
  544 
  545   if (vals[0] == NULL)
  546     {
  547       ldap_value_free (vals);
  548       return NSS_NOTFOUND;
  549     }
  550 
  551   stat = _nss_ldap_parse_int(vals[0], 0, &av->attr_un.au_int);
  552 
  553   ldap_value_free (vals);
  554 
  555   return stat;
  556 }
  557 
  558 /*
  559  * Get the GECOS/cn attribute
  560  */
  561 static NSS_STATUS
  562 uess_get_gecos (LDAPMessage * e, ldap_uess_args_t * lua, int i)
  563 {
  564   NSS_STATUS stat;
  565 
  566   stat = uess_get_char (e, lua, i);
  567   if (stat == NSS_NOTFOUND)
  568     {
  569       stat = uess_get_char_ex (e, lua, i, ATM (LM_PASSWD, cn));
  570     }
  571 
  572   return stat;
  573 }
  574 
  575 /*
  576  * Get the DN 
  577  */
  578 static NSS_STATUS
  579 uess_get_dn (LDAPMessage * e, ldap_uess_args_t * lua, int i)
  580 {
  581   lua->lua_results[i].attr_un.au_char = _nss_ldap_get_dn (e);
  582   if (lua->lua_results[i].attr_un.au_char == NULL)
  583     return NSS_NOTFOUND;
  584 
  585   return NSS_SUCCESS;
  586 }
  587 
  588 static NSS_STATUS
  589 do_parse_uess_getentry (LDAPMessage * e,
  590             ldap_state_t * pvt, void *result,
  591             char *buffer, size_t buflen)
  592 {
  593   ldap_uess_args_t *lua = (ldap_uess_args_t *) result;
  594   int i;
  595   char **vals;
  596   size_t len;
  597   NSS_STATUS stat;
  598 
  599   /* If a buffer is supplied, then we are enumerating. */
  600   if (lua->lua__buffer != NULL)
  601     {
  602       attrval_t *av = lua->lua_results;
  603 
  604       vals = _nss_ldap_get_values (e, lua->lua_naming_attribute);
  605       if (vals == NULL)
  606     return NSS_NOTFOUND;
  607 
  608       if (vals[0] == NULL)
  609     {
  610       ldap_value_free (vals);
  611       return NSS_NOTFOUND;
  612     }
  613 
  614       len = strlen (vals[0]) + 1;   /* for string terminator */
  615 
  616       if (lua->lua__buflen < len + 1)   /* for list terminator */
  617     {
  618       size_t grow = len + 1;
  619       size_t offset = (lua->lua__buffer - av->attr_un.au_char);
  620 
  621       grow += NSS_BUFSIZ - 1;
  622       grow -= (grow % NSS_BUFSIZ);
  623 
  624       av->attr_un.au_char =
  625         realloc (lua->lua__buffer, lua->lua__bufsiz + grow);
  626       if (av->attr_un.au_char == NULL)
  627         {
  628           ldap_value_free (vals);
  629           return NSS_TRYAGAIN;
  630         }
  631       /* reset buffer pointer in case realloc() returned a new region */
  632       lua->lua__buffer = &av->attr_un.au_char[offset];
  633       lua->lua__buflen += grow;
  634       lua->lua__bufsiz += grow;
  635     }
  636 
  637       memcpy (lua->lua__buffer, vals[0], len);
  638       lua->lua__buflen -= len;
  639       lua->lua__buffer += len;
  640       ldap_value_free (vals);
  641 
  642       lua->lua__buffer[0] = '\0';   /* ensure _list_ is always terminated */
  643 
  644       if (av->attr_flag != 0)
  645     av->attr_flag = 0;
  646 
  647       return NSS_NOTFOUND; /* trick caller into calling us again */
  648     }
  649   else
  650     {
  651       for (i = 0; i < lua->lua_size; i++)
  652     {
  653       int j;
  654       attrval_t *av = &lua->lua_results[i];
  655 
  656       av->attr_flag = -1;
  657       av->attr_un.au_char = NULL;
  658 
  659       for (j = 0; __uess_fns[j].luf_attribute != NULL; j++)
  660         {
  661           if (strcmp (__uess_fns[j].luf_attribute, lua->lua_attributes[i])
  662           == 0)
  663         {
  664           stat = (__uess_fns[j].luf_translator) (e, lua, i);
  665           switch (stat)
  666             {
  667             case NSS_SUCCESS:
  668               av->attr_flag = 0;
  669               break;
  670             case NSS_TRYAGAIN:
  671               return NSS_TRYAGAIN;
  672               break;
  673             default:
  674               break;
  675             }
  676         }
  677         }
  678     }
  679     }
  680 
  681   return NSS_SUCCESS;
  682 }
  683 
  684 static int
  685 _nss_ldap_getentry (char *key, char *table, char *attributes[],
  686             attrval_t results[], int size)
  687 {
  688   NSS_STATUS stat;
  689   ent_context_t *ctx = NULL;
  690   ldap_args_t a, *ap;
  691   const char *filter;
  692   int erange = 0;
  693   ldap_uess_args_t lua;
  694   const char *namingAttributes[2];
  695 
  696   debug ("==> _nss_ldap_getentry (key=%s table=%s attributes[0]=%s size=%d)",
  697      (key != NULL) ? key : "(null)",
  698      (table != NULL) ? table : "(null)",
  699      (size >= 1) ? attributes[0] : "(null)",
  700      size);
  701 
  702   lua.lua_key = key;
  703   lua.lua_table = table;
  704   lua.lua_attributes = attributes;
  705   lua.lua_results = results;
  706   lua.lua_size = size;
  707   lua.lua_naming_attribute = NULL;
  708 
  709   lua.lua_map = table2map (table);
  710   if (lua.lua_map == LM_NONE)
  711     {
  712       errno = ENOSYS;
  713       debug ("<== _nss_ldap_getentry (no such map)");
  714       return -1;
  715     }
  716 
  717   lua.lua__buffer = NULL;
  718   lua.lua__bufsiz = 0;
  719   lua.lua__buflen = 0;
  720 
  721   ap = key2filter (key, lua.lua_map, &a, &filter);
  722   if (ap == NULL)       /* enumeration */
  723     {
  724       const char **attrs;
  725 
  726       if (size != 1)
  727     {
  728       errno = EINVAL;
  729       debug ("<== _nss_ldap_getentry (size != 1)");
  730       return -1;
  731     }
  732 
  733       debug (":== _nss_ldap_getentry filter=%s attribute=%s",
  734          filter, lua.lua_attributes[0]);
  735 
  736       lua.lua__bufsiz = NSS_BUFSIZ;
  737       lua.lua__buflen = lua.lua__bufsiz;
  738       lua.lua__buffer = results[0].attr_un.au_char = malloc (lua.lua__bufsiz);
  739       if (lua.lua__buffer == NULL)
  740     {
  741       errno = ENOMEM;
  742       debug ("<== _nss_ldap_getentry (no memory)");
  743       return -1;
  744     }
  745       results[0].attr_flag = -1;
  746 
  747       /* just request the naming attributes */
  748       attrs = _nss_ldap_get_attributes (lua.lua_map);
  749       if (attrs == NULL || attrs[0] == NULL)
  750     {
  751       errno = ENOENT;
  752       debug ("<== _nss_ldap_getentry (could not read schema)");
  753       return -1;
  754     }
  755 
  756       lua.lua_naming_attribute = attrs[0];
  757       namingAttributes[0] = lua.lua_naming_attribute;
  758       namingAttributes[1] = NULL;
  759     }
  760   else
  761     {
  762       /* Check at least one attribute is mapped before searching */
  763       int i, found = 0;
  764 
  765       for (i = 0; i < size; i++)
  766     {
  767       if (uess2ldapattr (lua.lua_map, lua.lua_attributes[i]) != NULL)
  768         {
  769           found++;
  770           break;
  771         }
  772     }
  773 
  774       if (!found)
  775     {
  776       errno = ENOENT;
  777       debug ("<== _nss_ldap_getentry (no mappable attribute requested)");
  778       return -1;
  779     }
  780     }
  781 
  782   _nss_ldap_enter ();
  783   if (_nss_ldap_ent_context_init_locked (&ctx) == NULL)
  784     {
  785       _nss_ldap_leave ();
  786       if (results[0].attr_un.au_char != NULL)
  787     free (results[0].attr_un.au_char);
  788       errno = ENOMEM;
  789       debug ("<== _nss_ldap_getentry (ent_context_init failed)");
  790       return -1;
  791     }
  792 
  793   stat = _nss_ldap_getent_ex (ap, &ctx, (void *) &lua, NULL, 0,
  794                   &erange, filter, lua.lua_map,
  795                   (ap == NULL) ? namingAttributes : NULL,
  796                   do_parse_uess_getentry);
  797 
  798   _nss_ldap_ent_context_release (&ctx);
  799   _nss_ldap_leave ();
  800 
  801   /*
  802    * Whilst enumerating, we have the parser always return
  803    * NSS_NOTFOUND so that it will be called for each entry.
  804    *
  805    * Although this is probably bogus overloading of the
  806    * _nss_ldap_getent_ex() API, it does allow us to share
  807    * the same code for matches and enumerations. However,
  808    * for the enumeration case we need to treat NSS_NOTFOUND
  809    * as a success code; hence, we use the attr_flag to
  810    * indicate failure.
  811    */
  812   if (ap == NULL)
  813     {
  814       if (stat == NSS_NOTFOUND && results[0].attr_flag == 0)
  815     stat = NSS_SUCCESS;
  816     }
  817 
  818   if (stat != NSS_SUCCESS)
  819     {
  820       if (stat == NSS_TRYAGAIN)
  821     errno = ERANGE;
  822       else
  823     errno = ENOENT;
  824 
  825       debug ("<== _nss_ldap_getentry (failed with stat=%d)", stat);
  826       return -1;
  827     }
  828 
  829   debug ("<== _nss_ldap_getentry (success)");
  830   return AUTH_SUCCESS;
  831 }
  832 
  833 /*
  834  *
  835  */
  836 static NSS_STATUS
  837 uess_get_pwuid(const char *user, uid_t *uid)
  838 {
  839   char **vals;
  840   LDAPMessage *res, *e;
  841   const char *attrs[2];
  842   NSS_STATUS stat;
  843   ldap_args_t a;
  844 
  845   LA_INIT (a);
  846   LA_TYPE (a) = LA_TYPE_STRING;
  847   LA_STRING (a) = user;
  848 
  849   attrs[0] = ATM (LM_PASSWD, uidNumber);
  850   attrs[1] = NULL;
  851 
  852   stat = _nss_ldap_search_s (&a, _nss_ldap_filt_getpwuid, LM_PASSWD,
  853                  attrs, 1, &res);
  854   if (stat != NSS_SUCCESS)
  855       return stat;
  856 
  857   e = _nss_ldap_first_entry (res);
  858   if (e == NULL)
  859     {
  860       ldap_msgfree (res);
  861       return NSS_NOTFOUND;
  862     }
  863 
  864   vals = _nss_ldap_get_values (e, attrs[0]);
  865   if (vals == NULL)
  866     {
  867       ldap_msgfree (res);
  868       return NSS_NOTFOUND;
  869     }
  870 
  871   if (vals[0] == NULL || (vals[0])[0] == '\0')
  872     {
  873       ldap_value_free (vals);
  874       ldap_msgfree (res);
  875       return NSS_NOTFOUND;
  876     }
  877 
  878   stat = _nss_ldap_parse_uid_t (vals[0], 0, uid);
  879 
  880   ldap_value_free (vals);
  881   ldap_msgfree (res);
  882 
  883   return stat;
  884 }
  885 
  886 /*
  887  * Get membership for a group
  888  */
  889 static int
  890 _nss_ldap_getgrusers (char *group, void *result, int type, int *size)
  891 {
  892   struct group *gr;
  893   struct irs_gr *be;
  894   char **memp;
  895   size_t i;
  896 
  897   be = (struct irs_gr *) gr_pvtinit ();
  898   if (be == NULL)
  899     {
  900       errno = ENOSYS;
  901       return -1;
  902     }
  903 
  904   gr = (be->byname) (be, group);
  905   if (gr == NULL)
  906     {
  907       (be->close) (be);
  908       errno = ENOENT;
  909       return -1;
  910     }
  911 
  912   if (gr->gr_mem == NULL)
  913     {
  914       (be->close) (be);
  915       *size = 0;
  916       return 0;
  917     }
  918 
  919   for (i = 0; gr->gr_mem[i] != NULL; i++)
  920     ;
  921 
  922   if (i > *size)
  923     {
  924       (be->close) (be);
  925       *size = i;
  926       errno = ERANGE;
  927       return -1;
  928     }
  929 
  930   _nss_ldap_enter ();
  931 
  932   for (i = 0, memp = gr->gr_mem; *memp != NULL; memp++)
  933     {
  934       if (type == SEC_INT)
  935     {
  936       if (uess_get_pwuid(*memp, &(((uid_t *)result)[i])) != NSS_SUCCESS)
  937         continue;
  938     }
  939       else
  940     {
  941       ((char **)result)[i] = strdup(*memp);
  942       if (((char **)result)[i] == NULL)
  943         {
  944           _nss_ldap_leave ();
  945           (be->close) (be);
  946           errno = ENOMEM;
  947           return -1;
  948         }
  949     }
  950       i++;
  951     }
  952 
  953   _nss_ldap_leave ();
  954 
  955   *size = i;
  956 
  957   (be->close) (be);
  958 
  959   return AUTH_SUCCESS;
  960 }
  961 
  962 #if 0
  963 /*
  964  * Additional attributes supported
  965  */
  966 static attrlist_t **
  967 _nss_ldap_attrlist(void)
  968 {
  969   attrlist_t **a;
  970 
  971   a = malloc(2 * sizeof(attrlist_t *) + sizeof(attrlist_t));
  972   if (a == NULL)
  973     {
  974       errno = ENOMEM;
  975       return NULL;
  976     }
  977 
  978   a[0] = (attrlist_t *)(a + 2);
  979 
  980   a[0]->al_name = strdup(S_LDAPDN);
  981   a[0]->al_flags = AL_USERATTR;
  982   a[0]->al_type = SEC_CHAR;
  983 
  984   a[1] = NULL;
  985 
  986   return a;
  987 }
  988 #endif /* notdef */
  989 
  990 #if 0
  991 /* not implemented yet */
  992 static int
  993 _nss_ldap_normalize (char *longname, char *shortname)
  994 {
  995 }
  996 #endif
  997 
  998 int
  999 nss_ldap_initialize (struct secmethod_table *meths)
 1000 {
 1001   memset (meths, 0, sizeof (*meths));
 1002 
 1003   /* Initialize schema */
 1004   (void) _nss_ldap_init();
 1005 
 1006   /* Identification methods */
 1007   meths->method_getpwnam = _nss_ldap_getpwnam;
 1008   meths->method_getpwuid = _nss_ldap_getpwuid;
 1009   meths->method_getgrnam = _nss_ldap_getgrnam;
 1010   meths->method_getgrgid = _nss_ldap_getgrgid;
 1011   meths->method_getgrset = _nss_ldap_getgrset;
 1012   meths->method_getentry = _nss_ldap_getentry;
 1013 /*  meths->method_attrlist = _nss_ldap_attrlist; */
 1014   meths->method_getgrusers = _nss_ldap_getgrusers;
 1015 /*  meths->method_normalize = _nss_ldap_normalize; */
 1016   meths->method_getgracct = _nss_ldap_getgracct;
 1017   meths->method_getpasswd = _nss_ldap_getpasswd;
 1018 
 1019   /* Support methods */
 1020   meths->method_open = _nss_ldap_uess_open;
 1021   meths->method_close = _nss_ldap_uess_close;
 1022 
 1023   /* Authentication methods */
 1024   meths->method_authenticate = _nss_ldap_authenticate;
 1025 
 1026   return AUTH_SUCCESS;
 1027 }
 1028 
 1029 #endif /* HAVE_USERSEC_H */