diff options
author | Arthur de Jong <arthur@arthurdejong.org> | 2007-02-01 21:51:56 +0000 |
---|---|---|
committer | Arthur de Jong <arthur@arthurdejong.org> | 2007-02-01 21:51:56 +0000 |
commit | 7e126ec34ee493043efc55971135d7e132e2e175 (patch) | |
tree | bf2a764459d1f567e1fe4bf0ae1f0b339c1b0d98 | |
parent | 20481e8d3b817d2f9c560aaf4a56581325ad1572 (diff) |
add new dictionary module and use it for the attribute mapping stuff
git-svn-id: http://arthurdejong.org/svn/nss-pam-ldapd/nss-ldapd@231 ef36b2f9-881f-0410-afb5-c4e39611909c
-rw-r--r-- | nslcd/Makefile.am | 1 | ||||
-rw-r--r-- | nslcd/cfg.c | 97 | ||||
-rw-r--r-- | nslcd/cfg.h | 3 | ||||
-rw-r--r-- | nslcd/dict.c | 148 | ||||
-rw-r--r-- | nslcd/dict.h | 66 | ||||
-rw-r--r-- | nslcd/ldap-nss.c | 47 | ||||
-rw-r--r-- | nslcd/util.c | 14 | ||||
-rw-r--r-- | nslcd/util.h | 6 |
8 files changed, 283 insertions, 99 deletions
diff --git a/nslcd/Makefile.am b/nslcd/Makefile.am index 4da31f5..514bc34 100644 --- a/nslcd/Makefile.am +++ b/nslcd/Makefile.am @@ -31,6 +31,7 @@ nslcd_SOURCES = nslcd.c ../nslcd.h ../nslcd-common.h \ pagectrl.c pagectrl.h \ util.c util.h \ cfg.c cfg.h \ + dict.c dict.h \ alias.c ether.c group.c host.c netgroup.c network.c \ passwd.c protocol.c rpc.c service.c shadow.c nslcd_LDADD = @nslcd_LIBS@ diff --git a/nslcd/cfg.c b/nslcd/cfg.c index fabf73f..a9ba6a1 100644 --- a/nslcd/cfg.c +++ b/nslcd/cfg.c @@ -178,7 +178,7 @@ static enum nss_status _nss_ldap_init_config(struct ldap_config *result) { for (j=0;j<=MAP_MAX;j++) { - result->ldc_maps[i][j]=(void *)dict_new(); + result->ldc_maps[i][j]=dict_new(); if (result->ldc_maps[i][j] == NULL) return NSS_STATUS_UNAVAIL; } @@ -283,66 +283,49 @@ static enum nss_status _nss_ldap_map_put( const char *from, const char *to) { - struct ldap_datum key, val; - void **map; - enum nss_status retv; - - switch (type) + DICT *map; + /* we do some special handling for attribute type mapping to do some + basic detection of what kind of LDAP server we're talking to */ + if (type==MAP_ATTRIBUTE) + { + /* special handling for attribute mapping */ + if (strcasecmp(from,"userPassword")==0) { - case MAP_ATTRIBUTE: - /* special handling for attribute mapping */ if (strcmp - (from, - "userPassword") == 0) - { - if (strcasecmp (to, "userPassword") == 0) - config->ldc_password_type = LU_RFC2307_USERPASSWORD; - else if (strcasecmp (to, "authPassword") == 0) - config->ldc_password_type = LU_RFC3112_AUTHPASSWORD; - else - config->ldc_password_type = LU_OTHER_PASSWORD; - } - else if (strcmp (from, "shadowLastChange") == 0) - { - if (strcasecmp (to, "shadowLastChange") == 0) - config->ldc_shadow_type = LS_RFC2307_SHADOW; - else if (strcasecmp (to, "pwdLastSet") == 0) - config->ldc_shadow_type = LS_AD_SHADOW; - else - config->ldc_shadow_type = LS_OTHER_SHADOW; - } - break; - case MAP_OBJECTCLASS: - case MAP_OVERRIDE: - case MAP_DEFAULT: - break; - default: - return NSS_STATUS_NOTFOUND; - break; + if (strcasecmp(to,"userPassword")==0) + config->ldc_password_type=LU_RFC2307_USERPASSWORD; + else if (strcasecmp (to,"authPassword")==0) + config->ldc_password_type=LU_RFC3112_AUTHPASSWORD; + else + config->ldc_password_type=LU_OTHER_PASSWORD; } - - assert (sel <= LM_NONE); - map = &config->ldc_maps[sel][type]; - assert (*map != NULL); - - NSS_LDAP_DATUM_ZERO (&key); - key.data = (void *) from; - key.size = strlen (from) + 1; - - NSS_LDAP_DATUM_ZERO (&val); - val.data = (void *) to; - val.size = strlen (to) + 1; - - retv = dict_put (*map, NSS_LDAP_DB_NORMALIZE_CASE, &key, &val); - if (retv == NSS_STATUS_SUCCESS && - (type == MAP_ATTRIBUTE || type == MAP_OBJECTCLASS)) + else if (strcasecmp(from,"shadowLastChange")==0) { - type = (type == MAP_ATTRIBUTE) ? MAP_ATTRIBUTE_REVERSE : MAP_OBJECTCLASS_REVERSE; - map = &config->ldc_maps[sel][type]; - - retv = dict_put (*map, NSS_LDAP_DB_NORMALIZE_CASE, &val, &key); + if (strcasecmp(to,"shadowLastChange")==0) + config->ldc_shadow_type=LS_RFC2307_SHADOW; + else if (strcasecmp (to,"pwdLastSet")==0) + config->ldc_shadow_type=LS_AD_SHADOW; + else + config->ldc_shadow_type=LS_OTHER_SHADOW; } - - return retv; + } + assert(sel <= LM_NONE); + map=config->ldc_maps[sel][type]; + assert(map!=NULL); + if (dict_put(map,from,to)) + return NSS_STATUS_TRYAGAIN; + if (type==MAP_ATTRIBUTE) + { + map = config->ldc_maps[sel][MAP_ATTRIBUTE_REVERSE]; + if (dict_put(map,to,from)) + return NSS_STATUS_TRYAGAIN; + } + else if (type==MAP_OBJECTCLASS) + { + map = config->ldc_maps[sel][MAP_OBJECTCLASS_REVERSE]; + if (dict_put(map,to,from)) + return NSS_STATUS_TRYAGAIN; + } + return NSS_STATUS_SUCCESS; } static enum nss_status do_parse_map_statement( diff --git a/nslcd/cfg.h b/nslcd/cfg.h index 71b552e..995aa13 100644 --- a/nslcd/cfg.h +++ b/nslcd/cfg.h @@ -27,6 +27,7 @@ #define _CFG_H #include "ldap-nss.h" +#include "dict.h" /* maximum number of URIs */ #define NSS_LDAP_CONFIG_URI_MAX 31 @@ -124,7 +125,7 @@ struct ldap_config char *ldc_krb5_ccname; #endif /* CONFIGURE_KRB5_CCNAME */ /* attribute/objectclass maps relative to this config */ - void *ldc_maps[LM_NONE + 1][6]; /* must match MAP_MAX */ + DICT *ldc_maps[LM_NONE + 1][6]; /* must match MAP_MAX */ /* is userPassword "userPassword" or not? ie. do we need {crypt} to be stripped */ enum ldap_userpassword_selector ldc_password_type; /* Use active directory time offsets? */ diff --git a/nslcd/dict.c b/nslcd/dict.c new file mode 100644 index 0000000..143ab30 --- /dev/null +++ b/nslcd/dict.c @@ -0,0 +1,148 @@ +/* + dict.c - dictionary functions + This file is part of the nss-ldapd library. + + Copyright (C) 2007 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include "config.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <strings.h> + +#include "dict.h" + +struct dict_entry { + const char *key; + const void *value; + struct dict_entry *next; +}; + +struct dictionary { + struct dict_entry *head; + struct dict_entry *ptr; /* for searching */ +}; + +static struct dict_entry *dict_entry_new(const char *key) +{ + struct dict_entry *entry; + entry=(struct dict_entry *)malloc(sizeof(struct dict_entry)); + if (entry==NULL) + return NULL; + entry->key=strdup(key); + if (entry->key==NULL) + { + free(entry); + return NULL; + } + entry->value=NULL; + return entry; +} + +static void dict_entry_free(struct dict_entry *entry) +{ + /* free key */ + free((void *)entry->key); + /* free entry */ + free(entry); +} + +static struct dict_entry *dict_entry_find( + DICT *dict,const char *key) +{ + struct dict_entry *ptr; + for (ptr=dict->head;ptr!=NULL;ptr=ptr->next) + { + if (strcasecmp(ptr->key,key)==0) + return ptr; + } + return NULL; +} + +DICT *dict_new(void) +{ + struct dictionary *dict; + dict=(struct dictionary *)malloc(sizeof(struct dictionary)); + if (dict==NULL) + return NULL; + dict->head=NULL; + dict->ptr=NULL; + return dict; +} + +int dict_put(DICT *dict,const char *key,const void *value) +{ + struct dict_entry *entry; + entry=dict_entry_find(dict,key); + if (entry==NULL) + { + /* create new entry and insert it in the list */ + entry=dict_entry_new(key); + if (entry==NULL) + return -1; + } + /* set value */ + entry->value=value; + /* insert entry in list */ + entry->next=dict->head; + dict->head=entry; + return 0; +} + +const void *dict_get(DICT *dict,const char *key) +{ + struct dict_entry *entry; + entry=dict_entry_find(dict,key); + if (entry==NULL) + return NULL; + return entry->value; +} + +void dict_free(DICT *dict) +{ + struct dict_entry *ptr,*nxt; + /* free all entries */ + ptr=dict->head; + while (ptr!=NULL) + { + nxt=ptr->next; + dict_entry_free(ptr); + ptr=nxt; + } + /* clear some references */ + dict->head=NULL; + dict->ptr=NULL; + /* free struct itself */ + free(dict); +} + +void dict_values_first(DICT *dict) +{ + dict->ptr=dict->head; +} + +const void *dict_values_next(DICT *dict) +{ + struct dict_entry *ptr; + ptr=dict->ptr; + if (dict->ptr!=NULL) + dict->ptr=dict->ptr->next; + return ptr; +} diff --git a/nslcd/dict.h b/nslcd/dict.h new file mode 100644 index 0000000..a65b425 --- /dev/null +++ b/nslcd/dict.h @@ -0,0 +1,66 @@ +/* + dict.h - dictionary functions + This file is part of the nss-ldapd library. + + Copyright (C) 2007 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef _DICT_H +#define _DICT_H + +/* + These functions provide a mapping between a case insensitive + string and a pointer. +*/ +typedef struct dictionary DICT; + +/* Create a new instance of a dictionary. Returns NULL + in case of memory allocation errors. */ +DICT *dict_new(void); + +/* Add a relation in the dictionary. The key is duplicated + and can be reused by the caller. The pointer is just stored. + This function returns non-0 in case of memory allocation + errors. If the key was previously in use the value + is replaced. All key comparisons are case insensitive. */ +int dict_put(DICT *dict,const char *key,const void *value); + +/* Look up a key in the dictionary and return the associated + value. NULL is returned if the key is not found in the dictionary. + All key comparisons are case insensitive. */ +const void *dict_get(DICT *dict,const char *key); + +/* Delete a key-value association from the dictionary. + All key comparisons are case insensitive. */ +/*void dict_del(LEGACYDICT *dict,const char *key);*/ + +/* Remove the dictionary from memory. All allocated storage + for the dictionary and the keys is freed. */ +void dict_free(DICT *dict); + +/* Function for looping over all dictionary values. + This resets the search to the beginning of the dictionary. + This is required before calling dict_values_next(); */ +void dict_values_first(DICT *dict); + +/* Function for looping over all dictionary values. + This returns a stored value. NULL is returned when all + stored values have been returned. */ +const void *dict_values_next(DICT *dict); + +#endif /* _DICT_H */ diff --git a/nslcd/ldap-nss.c b/nslcd/ldap-nss.c index 7423617..9df6cf2 100644 --- a/nslcd/ldap-nss.c +++ b/nslcd/ldap-nss.c @@ -3117,38 +3117,23 @@ _nss_ldap_map_get (enum ldap_map_selector sel, enum ldap_map_type type, const char *from, const char **to) { - struct ldap_datum key, val; - void *map; - enum nss_status stat; - + DICT *map; if (_nss_ldap_map_get == NULL || sel > LM_NONE || type > MAP_MAX) + return NSS_STATUS_NOTFOUND; + map=nslcd_cfg->ldc_maps[sel][type]; + if (map!=NULL) + { + *to=(const char *)dict_get(map,from); + if ((*to==NULL) && (sel!=LM_NONE)) { - return NSS_STATUS_NOTFOUND; - } - - map = nslcd_cfg->ldc_maps[sel][type]; - assert (map != NULL); - - NSS_LDAP_DATUM_ZERO (&key); - key.data = from; - key.size = strlen (from) + 1; - - NSS_LDAP_DATUM_ZERO (&val); - - stat = dict_get (map, NSS_LDAP_DB_NORMALIZE_CASE, &key, &val); - if (stat == NSS_STATUS_NOTFOUND && sel != LM_NONE) - { - map = nslcd_cfg->ldc_maps[LM_NONE][type]; - assert (map != NULL); - stat = dict_get (map, NSS_LDAP_DB_NORMALIZE_CASE, &key, &val); + map=nslcd_cfg->ldc_maps[LM_NONE][type]; + if (map!=NULL) + *to=(const char *)dict_get(map,from); } - - if (stat == NSS_STATUS_SUCCESS) - *to = (char *) val.data; - else - *to = NULL; - - return stat; + } + if (*to==NULL) + return NSS_STATUS_NOTFOUND; + return NSS_STATUS_SUCCESS; } /* @@ -3221,7 +3206,7 @@ do_proxy_rebind (LDAP * ld, char **whop, char **credp, int *methodp, } #endif -enum nss_status +static enum nss_status _nss_ldap_proxy_bind (const char *user, const char *password) { struct ldap_args args; @@ -3322,7 +3307,7 @@ _nss_ldap_proxy_bind (const char *user, const char *password) return stat; } -const char ** +static const char ** _nss_ldap_get_attributes (enum ldap_map_selector sel) { const char **attrs = NULL; diff --git a/nslcd/util.c b/nslcd/util.c index f067160..17b9f9e 100644 --- a/nslcd/util.c +++ b/nslcd/util.c @@ -74,7 +74,7 @@ dn2uid_cache_put (const char *dn, const char *uid) if (__cache == NULL) { - __cache = (void *)dict_new(); + __cache = (void *)old_dict_new(); if (__cache == NULL) { cache_unlock (); @@ -87,7 +87,7 @@ dn2uid_cache_put (const char *dn, const char *uid) val.data = (void *) uid; val.size = strlen (uid); - status = dict_put (__cache, 0, &key, &val); + status = old_dict_put (__cache, 0, &key, &val); cache_unlock (); @@ -111,7 +111,7 @@ dn2uid_cache_get (const char *dn, char **uid, char **buffer, size_t * buflen) key.data = (void *) dn; key.size = strlen (dn); - status = dict_get (__cache, 0, &key, &val); + status = old_dict_get (__cache, 0, &key, &val); if (status != NSS_STATUS_SUCCESS) { cache_unlock (); @@ -459,7 +459,7 @@ int _nss_ldap_escape_string(const char *src,char *buffer,size_t buflen) return 0; } -struct ldap_dictionary *dict_new(void) +struct ldap_dictionary *old_dict_new(void) { struct ldap_dictionary *dict; dict = malloc(sizeof(struct ldap_dictionary)); @@ -516,7 +516,7 @@ do_dup_datum (unsigned flags, struct ldap_datum * dst, const struct ldap_datum * return NSS_STATUS_SUCCESS; } -enum nss_status dict_get( +enum nss_status old_dict_get( struct ldap_dictionary *db, unsigned flags, const struct ldap_datum *key, @@ -542,7 +542,7 @@ enum nss_status dict_get( return NSS_STATUS_NOTFOUND; } -enum nss_status dict_put( +enum nss_status old_dict_put( struct ldap_dictionary *db, unsigned flags, const struct ldap_datum *key, @@ -565,7 +565,7 @@ enum nss_status dict_put( p=do_find_last(dict); assert(p!=NULL); assert(p->next==NULL); - q=dict_new(); + q=old_dict_new(); if (q==NULL) return NSS_STATUS_TRYAGAIN; } diff --git a/nslcd/util.h b/nslcd/util.h index eacc7da..b64ee20 100644 --- a/nslcd/util.h +++ b/nslcd/util.h @@ -72,12 +72,12 @@ struct ldap_dictionary struct ldap_dictionary *next; }; -struct ldap_dictionary *dict_new(void); -enum nss_status dict_put(struct ldap_dictionary *db, +struct ldap_dictionary *old_dict_new(void); +enum nss_status old_dict_put(struct ldap_dictionary *db, unsigned flags, const struct ldap_datum *key, const struct ldap_datum *value); -enum nss_status dict_get(struct ldap_dictionary *db, +enum nss_status old_dict_get(struct ldap_dictionary *db, unsigned flags, const struct ldap_datum *key, struct ldap_datum *value); |