diff options
author | Arthur de Jong <arthur@arthurdejong.org> | 2006-10-12 11:01:56 +0000 |
---|---|---|
committer | Arthur de Jong <arthur@arthurdejong.org> | 2006-10-12 11:01:56 +0000 |
commit | dba09bb1389491f82beb862323a5ccab428a7f2d (patch) | |
tree | e617b84715ab650b6cd162876f7ff6d0b897a05a /ldap-netgrp.c | |
parent | 54845e6fb6d0fa0f7f77b4a7d8520897e0e98496 (diff) |
first round of cleanups, all non-glibc NSS stuff has been removed, because we are going to do some major restructuring it will not likely remain valid anyway and we can always re-add it later
git-svn-id: http://arthurdejong.org/svn/nss-pam-ldapd/libnss_ldapd@10 ef36b2f9-881f-0410-afb5-c4e39611909c
Diffstat (limited to 'ldap-netgrp.c')
-rw-r--r-- | ldap-netgrp.c | 665 |
1 files changed, 10 insertions, 655 deletions
diff --git a/ldap-netgrp.c b/ldap-netgrp.c index 675d4e4..c17ba02 100644 --- a/ldap-netgrp.c +++ b/ldap-netgrp.c @@ -1,4 +1,5 @@ -/* Copyright (C) 2002-2005 Luke Howard. +/* + Copyright (C) 2002-2005 Luke Howard This file is part of the nss_ldap library. Linux support contributed by Larry Lile, <llile@dreamworks.com>, 2002. Solaris support contributed by Luke Howard, <lukeh@padl.com>, 2004. @@ -19,10 +20,7 @@ Boston, MA 02111-1307, USA. $Id$ - */ - -static char rcsId[] = - "$Id$"; +*/ #include "config.h" @@ -53,10 +51,6 @@ static char rcsId[] = #include <ldap.h> #endif -#ifndef HAVE_SNPRINTF -#include "snprintf.h" -#endif - #include "ldap-nss.h" #include "ldap-netgrp.h" #include "util.h" @@ -65,38 +59,10 @@ static char rcsId[] = #include <port_after.h> #endif -#ifdef HAVE_NSS_H static ent_context_t *_ngbe = NULL; -#endif -#ifdef HAVE_IRS_H -enum nss_netgr_status { - NSS_NETGR_FOUND, - NSS_NETGR_NO, - NSS_NETGR_NOMEM -}; -struct pvt; /* forward declaration for IRS backend type */ -#endif /* HAVE_IRS_H */ -#ifdef HAVE_NSSWITCH_H -static nss_backend_op_t netgroup_ops[]; -#endif - -#if defined(HAVE_NSSWITCH_H) || defined(HAVE_IRS_H) -struct ldap_innetgr_args -{ - const char *lia_netgroup; - enum nss_netgr_status lia_netgr_status; - int lia_depth; - int lia_erange; -}; - -typedef struct ldap_innetgr_args ldap_innetgr_args_t; - -static NSS_STATUS do_innetgr_nested (ldap_innetgr_args_t * li_args, - const char *nested); -#endif /* HAVE_NSSWITCH_H || HAVE_IRS_H */ /* * I pulled the following macro (EXPAND), functions (strip_whitespace and @@ -180,7 +146,7 @@ strip_whitespace (char *str) return *str == '\0' ? NULL : str; } -static NSS_STATUS +static enum nss_status _nss_ldap_parse_netgr (void *vresultp, char *buffer, size_t buflen) { struct __netgrent *result = (struct __netgrent *) vresultp; @@ -264,8 +230,7 @@ _nss_ldap_parse_netgr (void *vresultp, char *buffer, size_t buflen) return NSS_SUCCESS; } -#ifdef HAVE_NSS_H -static NSS_STATUS +static enum nss_status _nss_ldap_load_netgr (LDAPMessage * e, ldap_state_t * pvt, void *vresultp, char *buffer, size_t buflen) @@ -276,7 +241,7 @@ _nss_ldap_load_netgr (LDAPMessage * e, char **vals; char **valiter; struct __netgrent *result = vresultp; - NSS_STATUS stat = NSS_SUCCESS; + enum nss_status stat = NSS_SUCCESS; for (attr = 0; attr < 2; attr++) { @@ -333,7 +298,7 @@ out: return stat; } -NSS_STATUS +enum nss_status _nss_ldap_endnetgrent (struct __netgrent * result) { if (result->data != NULL) @@ -347,13 +312,13 @@ _nss_ldap_endnetgrent (struct __netgrent * result) LOOKUP_ENDENT (_ngbe); } -NSS_STATUS +enum nss_status _nss_ldap_setnetgrent (char *group, struct __netgrent *result) { int errnop = 0, buflen = 0; char *buffer = (char *) NULL; ldap_args_t a; - NSS_STATUS stat = NSS_SUCCESS; + enum nss_status stat = NSS_SUCCESS; if (group[0] == '\0') return NSS_UNAVAIL; @@ -375,619 +340,9 @@ _nss_ldap_setnetgrent (char *group, struct __netgrent *result) LOOKUP_SETENT (_ngbe); } -NSS_STATUS +enum nss_status _nss_ldap_getnetgrent_r (struct __netgrent *result, char *buffer, size_t buflen, int *errnop) { return _nss_ldap_parse_netgr (result, buffer, buflen); } -#endif /* HAVE_NSS_H */ - -#if defined(HAVE_NSSWITCH_H) || defined(HAVE_IRS_H) -/* - * Chase nested netgroups. If we can't find a nested netgroup, we try - * the next one - don't want to fail authoritatively because of bad - * user data. - */ -static NSS_STATUS -nn_chase (nss_ldap_netgr_backend_t * ngbe, LDAPMessage ** pEntry) -{ - ldap_args_t a; - NSS_STATUS stat = NSS_NOTFOUND; - - debug ("==> nn_chase"); - - if (ngbe->state->ec_res != NULL) - { - ldap_msgfree (ngbe->state->ec_res); - ngbe->state->ec_res = NULL; - } - - while (ngbe->needed_groups != NULL) - { - /* If this netgroup has already been seen, avoid it */ - if (_nss_ldap_namelist_find (ngbe->known_groups, ngbe->needed_groups->name)) - { - _nss_ldap_namelist_pop (&ngbe->needed_groups); - continue; - } - - LA_INIT (a); - LA_TYPE (a) = LA_TYPE_STRING; - LA_STRING (a) = ngbe->needed_groups->name; - - debug (":== nn_chase: nested netgroup=%s", LA_STRING (a)); - - _nss_ldap_enter (); - stat = _nss_ldap_search_s (&a, _nss_ldap_filt_getnetgrent, - LM_NETGROUP, NULL, 1, &ngbe->state->ec_res); - _nss_ldap_leave (); - - if (stat == NSS_SUCCESS) - { - /* we have "seen" this netgroup; track it for loop detection */ - stat = _nss_ldap_namelist_push (&ngbe->known_groups, ngbe->needed_groups->name); - if (stat != NSS_SUCCESS) - { - _nss_ldap_namelist_pop (&ngbe->needed_groups); - break; - } - } - - _nss_ldap_namelist_pop (&ngbe->needed_groups); - - if (stat == NSS_SUCCESS) - { - /* Check we got an entry, not just a result. */ - *pEntry = _nss_ldap_first_entry (ngbe->state->ec_res); - if (*pEntry == NULL) - { - ldap_msgfree (ngbe->state->ec_res); - ngbe->state->ec_res = NULL; - stat = NSS_NOTFOUND; - } - } - - if (stat == NSS_SUCCESS) - { - /* found one. */ - break; - } - } - - debug ("<== nn_chase result=%d", stat); - - return stat; -} -#endif /* HAVE_NSSWITCH_H || HAVE_IRS_H */ - -#if defined(HAVE_NSSWITCH_H) || defined(HAVE_IRS_H) -/* - * getnetgrent() inner implementation, used by both Solaris NSS - * and IRS/AIX - */ -static NSS_STATUS -do_getnetgrent (nss_ldap_netgr_backend_t *be, - char *buffer, size_t buflen, - enum nss_netgr_status *status, - char **machine, char **user, char **domain) -{ - ent_context_t *ctx; - NSS_STATUS parseStat = NSS_NOTFOUND; - - /* - * This function is called with the pseudo-backend that - * we created in _nss_ldap_setnetgrent() (see below) - */ - debug ("==> do_getnetgrent"); - - ctx = be->state; - assert (ctx != NULL); - - *status = NSS_NETGR_NO; - *machine = NULL; - *user = NULL; - *domain = NULL; - - do - { - NSS_STATUS resultStat = NSS_SUCCESS; - char **vals, **p; - ldap_state_t *state = &ctx->ec_state; - struct __netgrent __netgrent; - LDAPMessage *e; - - if (state->ls_retry == 0 && state->ls_info.ls_index == -1) - { - resultStat = NSS_NOTFOUND; - - if (ctx->ec_res != NULL) - { - e = _nss_ldap_first_entry (ctx->ec_res); - if (e != NULL) - resultStat = NSS_SUCCESS; - } - - if (resultStat != NSS_SUCCESS) - { - /* chase nested netgroups */ - resultStat = nn_chase (be, &e); - } - - if (resultStat != NSS_SUCCESS) - { - parseStat = resultStat; - break; - } - - assert (e != NULL); - - /* Push nested netgroups onto stack for deferred chasing */ - vals = _nss_ldap_get_values (e, AT (memberNisNetgroup)); - if (vals != NULL) - { - for (p = vals; *p != NULL; p++) - { - parseStat = _nss_ldap_namelist_push (&be->needed_groups, *p); - if (parseStat != NSS_SUCCESS) - break; - } - ldap_value_free (vals); - - if (parseStat != NSS_SUCCESS) - break; /* out of memory */ - } - } - else - { - assert (ctx->ec_res != NULL); - e = _nss_ldap_first_entry (ctx->ec_res); - if (e == NULL) - { - /* This should never happen, but we fail gracefully. */ - parseStat = NSS_UNAVAIL; - break; - } - } - - /* We have an entry; now, try to parse it. */ - vals = _nss_ldap_get_values (e, AT (nisNetgroupTriple)); - if (vals == NULL) - { - state->ls_info.ls_index = -1; - parseStat = NSS_NOTFOUND; - ldap_msgfree (ctx->ec_res); - ctx->ec_res = NULL; - continue; - } - - switch (state->ls_info.ls_index) - { - case 0: - /* last time. decrementing ls_index to -1 AND returning - * an error code will force this entry to be discared. - */ - parseStat = NSS_NOTFOUND; - break; - case -1: - /* first time */ - state->ls_info.ls_index = ldap_count_values (vals); - /* fall off to default... */ - default: - __netgrent.data = vals[state->ls_info.ls_index - 1]; - __netgrent.data_size = strlen (vals[state->ls_info.ls_index - 1]); - __netgrent.cursor = __netgrent.data; - __netgrent.first = 1; - - parseStat = _nss_ldap_parse_netgr (&__netgrent, buffer, buflen); - if (parseStat != NSS_SUCCESS) - { - break; - } - if (__netgrent.type != triple_val) - { - parseStat = NSS_NOTFOUND; - break; - } - *machine = (char *) __netgrent.val.triple.host; - *user = (char *) __netgrent.val.triple.user; - *domain = (char *) __netgrent.val.triple.domain; - break; - } - - ldap_value_free (vals); - state->ls_info.ls_index--; - - /* hold onto the state if we're out of memory XXX */ - state->ls_retry = (parseStat == NSS_TRYAGAIN ? 1 : 0); - *status = (parseStat == NSS_SUCCESS) ? NSS_NETGR_FOUND : NSS_NETGR_NOMEM; - - if (state->ls_retry == 0 && state->ls_info.ls_index == -1) - { - ldap_msgfree (ctx->ec_res); - ctx->ec_res = NULL; - } - } - while (parseStat == NSS_NOTFOUND); - - if (parseStat == NSS_TRYAGAIN) - { - errno = ERANGE; - } - - debug ("<== do_getnetgrent"); - - return parseStat; -} - -/* - * Test a 4-tuple - */ -static NSS_STATUS -do_parse_innetgr (LDAPMessage * e, ldap_state_t * pvt, - void *result, char *buffer, size_t buflen) -{ - ldap_innetgr_args_t *li_args = (ldap_innetgr_args_t *) result; - int count; - char **values = NULL; - NSS_STATUS stat = NSS_NOTFOUND; - - debug ("==> do_parse_innetgr"); - - values = _nss_ldap_get_values (e, ATM (LM_NETGROUP, cn)); - if (values == NULL) - return NSS_NOTFOUND; - - count = ldap_count_values (values); - - while (--count >= 0) - { - assert (values[count] != NULL); - - if (strcasecmp (li_args->lia_netgroup, values[count]) == 0) - { - li_args->lia_netgr_status = NSS_NETGR_FOUND; - stat = NSS_SUCCESS; - } - else - { - stat = do_innetgr_nested (li_args, values[count]); - } - - if (stat == NSS_SUCCESS) - break; - } - - ldap_value_free (values); - - debug ("<== do_parse_innetgr"); - - return stat; -} - -/* - * NB: caller has acquired the global lock - */ -static NSS_STATUS -do_innetgr_nested (ldap_innetgr_args_t * li_args, const char *nested) -{ - NSS_STATUS stat; - ldap_args_t a; - ent_context_t *ctx = NULL; - - debug ("==> do_innetgr_nested netgroup=%s assertion=%s", - li_args->lia_netgroup, nested); - - if (li_args->lia_depth >= LDAP_NSS_MAXNETGR_DEPTH) - { - debug ("<== do_innetgr_nested: maximum depth exceeded"); - return NSS_NOTFOUND; - } - - LA_INIT (a); - LA_TYPE (a) = LA_TYPE_STRING; - LA_STRING (a) = nested; /* memberNisNetgroup */ - - if (_nss_ldap_ent_context_init_locked (&ctx) == NULL) - { - debug ("<== do_innetgr_nested: failed to initialize context"); - return NSS_UNAVAIL; - } - - li_args->lia_depth++; - - stat = _nss_ldap_getent_ex (&a, &ctx, (void *) li_args, NULL, 0, - &li_args->lia_erange, _nss_ldap_filt_innetgr, - LM_NETGROUP, NULL, do_parse_innetgr); - - li_args->lia_depth--; - - _nss_ldap_ent_context_release (ctx); - free (ctx); - - debug ("<== do_innetgr_nested status=%d netgr_status=%d", - stat, li_args->lia_netgr_status); - - return stat; -} - -/* - * NB: caller has acquired the global lock - */ -static NSS_STATUS -do_innetgr (ldap_innetgr_args_t * li_args, - const char *machine, const char *user, const char *domain) -{ - NSS_STATUS stat; - ldap_args_t a; - ent_context_t *ctx = NULL; - - debug ("==> do_innetgr netgroup=%s", li_args->lia_netgroup); - - /* - * First, find which netgroup the 3-tuple belongs to. - */ - LA_INIT (a); - LA_TYPE (a) = LA_TYPE_TRIPLE; - LA_TRIPLE (a).user = user; - LA_TRIPLE (a).host = machine; - LA_TRIPLE (a).domain = domain; - - if (_nss_ldap_ent_context_init_locked (&ctx) == NULL) - { - debug ("<== do_innetgr: failed to initialize context"); - return NSS_UNAVAIL; - } - - stat = _nss_ldap_getent_ex (&a, &ctx, (void *) li_args, NULL, 0, - &li_args->lia_erange, NULL, LM_NETGROUP, - NULL, do_parse_innetgr); - - _nss_ldap_ent_context_release (ctx); - free (ctx); - - debug ("<== do_innetgr status=%d netgr_status=%d", - stat, li_args->lia_netgr_status); - - return stat; -} -#endif /* HAVE_NSSWITCH_H || HAVE_IRS_H */ - -#ifdef HAVE_NSSWITCH_H -static NSS_STATUS -_nss_ldap_getnetgroup_endent (nss_backend_t * be, void *_args) -{ - LOOKUP_ENDENT (be); -} - -static NSS_STATUS -_nss_ldap_getnetgroup_setent (nss_backend_t * be, void *_args) -{ - return NSS_SUCCESS; -} - -static NSS_STATUS -_nss_ldap_getnetgroup_getent (nss_backend_t * _be, void *_args) -{ - nss_ldap_netgr_backend_t *be = (nss_ldap_netgr_backend_t *) _be; - struct nss_getnetgrent_args *args = (struct nss_getnetgrent_args *) _args; - NSS_STATUS stat; - - _nss_ldap_enter (); - - stat = do_getnetgrent (be, - args->buffer, - args->buflen, - &args->status, - &args->retp[NSS_NETGR_MACHINE], - &args->retp[NSS_NETGR_USER], - &args->retp[NSS_NETGR_DOMAIN]); - - _nss_ldap_leave (); - - return stat; -} - -static NSS_STATUS -_nss_ldap_innetgr (nss_backend_t * be, void *_args) -{ - NSS_STATUS stat = NSS_NOTFOUND; - struct nss_innetgr_args *args = (struct nss_innetgr_args *) _args; - int i; - - /* - * Enumerate the groups in args structure and see whether - * any 4-tuple was satisfied. This really needs LDAP - * component matching to be done efficiently. - */ - - debug - ("==> _nss_ldap_innetgr MACHINE.argc=%d USER.argc=%d DOMAIN.argc=%d groups.argc=%d", - args->arg[NSS_NETGR_MACHINE].argc, args->arg[NSS_NETGR_USER].argc, - args->arg[NSS_NETGR_DOMAIN].argc, args->groups.argc); - - /* Presume these are harmonized -- this is a strange interface */ - assert (args->arg[NSS_NETGR_MACHINE].argc == 0 || - args->arg[NSS_NETGR_MACHINE].argc == args->groups.argc); - assert (args->arg[NSS_NETGR_USER].argc == 0 || - args->arg[NSS_NETGR_USER].argc == args->groups.argc); - assert (args->arg[NSS_NETGR_DOMAIN].argc == 0 || - args->arg[NSS_NETGR_DOMAIN].argc == args->groups.argc); - - _nss_ldap_enter (); - - for (i = 0; i < args->groups.argc; i++) - { - NSS_STATUS parseStat; - ldap_innetgr_args_t li_args; - - const char *machine = (args->arg[NSS_NETGR_MACHINE].argc != 0) ? - args->arg[NSS_NETGR_MACHINE].argv[i] : NULL; - const char *user = (args->arg[NSS_NETGR_USER].argc != 0) ? - args->arg[NSS_NETGR_USER].argv[i] : NULL; - const char *domain = (args->arg[NSS_NETGR_DOMAIN].argc != 0) ? - args->arg[NSS_NETGR_DOMAIN].argv[i] : NULL; - - li_args.lia_netgroup = args->groups.argv[i]; - li_args.lia_netgr_status = NSS_NETGR_NO; - li_args.lia_depth = 0; - li_args.lia_erange = 0; - - parseStat = do_innetgr (&li_args, machine, user, domain); - if (parseStat != NSS_SUCCESS && parseStat != NSS_NOTFOUND) - { - /* fatal error */ - if (li_args.lia_erange != 0) - errno = ERANGE; - break; - } - - args->status = li_args.lia_netgr_status; - - if (args->status == NSS_NETGR_FOUND) - { - stat = NSS_SUCCESS; - } - } - - _nss_ldap_leave (); - - debug ("<== _nss_ldap_innetgr"); - - return stat; -} - -/* - * According to the "documentation", setnetgrent() is really - * a getXXXbyYYY() operation that returns a pseudo-backend - * through which one may enumerate the netgroup's members. - * - * ie. this is the constructor for the pseudo-backend. - */ -static NSS_STATUS -_nss_ldap_setnetgrent (nss_backend_t * be, void *_args) -{ - NSS_STATUS stat; - struct nss_setnetgrent_args *args; - nss_ldap_netgr_backend_t *ngbe; - ldap_args_t a; - - debug ("==> _nss_ldap_setnetgrent"); - - args = (struct nss_setnetgrent_args *) _args; - args->iterator = NULL; /* initialize */ - - /* - * This retrieves the top-level netgroup; nested netgroups - * are chased inside the pseudo-backend. - */ - - LA_INIT (a); - LA_TYPE (a) = LA_TYPE_STRING; - LA_STRING (a) = args->netgroup; /* cn */ - - ngbe = (nss_ldap_netgr_backend_t *) malloc (sizeof (*ngbe)); - if (ngbe == NULL) - { - debug ("<== _nss_ldap_setnetgrent"); - return NSS_UNAVAIL; - } - - ngbe->ops = netgroup_ops; - ngbe->n_ops = 6; - ngbe->state = NULL; - ngbe->known_groups = NULL; - ngbe->needed_groups = NULL; - - stat = _nss_ldap_default_constr ((nss_ldap_backend_t *) ngbe); - if (stat != NSS_SUCCESS) - { - free (ngbe); - debug ("<== _nss_ldap_setnetgrent"); - return stat; - } - - if (_nss_ldap_ent_context_init (&ngbe->state) == NULL) - { - _nss_ldap_default_destr ((nss_backend_t *) ngbe, NULL); - debug ("<== _nss_ldap_setnetgrent"); - return NSS_UNAVAIL; - } - - assert (ngbe->state != NULL); - assert (ngbe->state->ec_res == NULL); - - _nss_ldap_enter (); - stat = _nss_ldap_search_s (&a, _nss_ldap_filt_getnetgrent, - LM_NETGROUP, NULL, 1, &ngbe->state->ec_res); - _nss_ldap_leave (); - - if (stat == NSS_SUCCESS) - { - /* we have "seen" this netgroup; track it for loop detection */ - stat = _nss_ldap_namelist_push (&ngbe->known_groups, args->netgroup); - } - - if (stat == NSS_SUCCESS) - { - args->iterator = (nss_backend_t *) ngbe; - } - else - { - _nss_ldap_default_destr ((nss_backend_t *) ngbe, NULL); - } - - debug ("<== _nss_ldap_setnetgrent"); - - return stat; -} - -static NSS_STATUS -_nss_ldap_netgroup_destr (nss_backend_t * _ngbe, void *args) -{ - nss_ldap_netgr_backend_t *ngbe = (nss_ldap_netgr_backend_t *) _ngbe; - - /* free list of nested netgroups */ - _nss_ldap_namelist_destroy (&ngbe->known_groups); - _nss_ldap_namelist_destroy (&ngbe->needed_groups); - - return _nss_ldap_default_destr (_ngbe, args); -} - -static nss_backend_op_t netgroup_ops[] = { - _nss_ldap_netgroup_destr, /* NSS_DBOP_DESTRUCTOR */ - _nss_ldap_getnetgroup_endent, /* NSS_DBOP_ENDENT */ - _nss_ldap_getnetgroup_setent, /* NSS_DBOP_SETENT */ - _nss_ldap_getnetgroup_getent, /* NSS_DBOP_GETENT */ - _nss_ldap_innetgr, /* NSS_DBOP_NETGROUP_IN */ - _nss_ldap_setnetgrent /* NSS_DBOP_NETGROUP_SET */ -}; - -nss_backend_t * -_nss_ldap_netgroup_constr (const char *db_name, - const char *src_name, const char *cfg_args) -{ - nss_ldap_netgr_backend_t *be; - - if (!(be = (nss_ldap_netgr_backend_t *) malloc (sizeof (*be)))) - return NULL; - - be->ops = netgroup_ops; - be->n_ops = sizeof (netgroup_ops) / sizeof (nss_backend_op_t); - be->known_groups = NULL; - be->needed_groups = NULL; - - if (_nss_ldap_default_constr ((nss_ldap_backend_t *) be) != NSS_SUCCESS) - { - free (be); - return NULL; - } - - return (nss_backend_t *) be; -} - -#endif /* !HAVE_NSS_H */ - -#ifdef HAVE_IRS_H -#include "irs-netgrp.c" -#endif /* HAVE_IRS_H */ |