summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArthur de Jong <arthur@arthurdejong.org>2007-02-01 21:51:56 +0000
committerArthur de Jong <arthur@arthurdejong.org>2007-02-01 21:51:56 +0000
commit7e126ec34ee493043efc55971135d7e132e2e175 (patch)
treebf2a764459d1f567e1fe4bf0ae1f0b339c1b0d98
parent20481e8d3b817d2f9c560aaf4a56581325ad1572 (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.am1
-rw-r--r--nslcd/cfg.c97
-rw-r--r--nslcd/cfg.h3
-rw-r--r--nslcd/dict.c148
-rw-r--r--nslcd/dict.h66
-rw-r--r--nslcd/ldap-nss.c47
-rw-r--r--nslcd/util.c14
-rw-r--r--nslcd/util.h6
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);