diff options
author | Arthur de Jong <arthur@arthurdejong.org> | 2010-10-15 10:58:46 +0000 |
---|---|---|
committer | Arthur de Jong <arthur@arthurdejong.org> | 2010-10-15 10:58:46 +0000 |
commit | 1fab81db27cbe228d576ce5bda756d3af42e3817 (patch) | |
tree | 45db8e81253e07a9ecf3a9051c6f4e65e91a4499 | |
parent | 6c1fd9d223e14b80db18058a720a61be415c1936 (diff) | |
parent | f6bbbc5da9d72ec6637ef8fea58c73686abdace1 (diff) |
merge changes from trunk
git-svn-id: http://arthurdejong.org/svn/nss-pam-ldapd/nss-pam-ldapd-solaris@1280 ef36b2f9-881f-0410-afb5-c4e39611909c
-rw-r--r-- | common/dict.c | 22 | ||||
-rw-r--r-- | common/dict.h | 16 | ||||
-rw-r--r-- | common/set.c | 15 | ||||
-rw-r--r-- | common/set.h | 13 | ||||
-rw-r--r-- | nslcd/myldap.c | 42 | ||||
-rw-r--r-- | tests/test_dict.c | 16 | ||||
-rw-r--r-- | tests/test_set.c | 29 |
7 files changed, 102 insertions, 51 deletions
diff --git a/common/dict.c b/common/dict.c index 128321d..c42b8b4 100644 --- a/common/dict.c +++ b/common/dict.c @@ -2,7 +2,7 @@ dict.c - dictionary functions This file is part of the nss-pam-ldapd library. - Copyright (C) 2007, 2008, 2009 Arthur de Jong + Copyright (C) 2007, 2008, 2009, 2010 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 @@ -69,13 +69,12 @@ struct dictionary { struct dict_entry **table; /* the hashtable */ }; -/* Simple hash function that computes the hash value of a lower-cased - string. */ +/* Simple hash function that computes the hash value of a string. */ static uint32_t stringhash(const char *str) { uint32_t hash=0; while (*str!='\0') - hash=3*hash+tolower(*str++); + hash=3*hash+*str++; return hash; } @@ -170,13 +169,24 @@ void *dict_get(DICT *dict,const char *key) for (entry=dict->table[hash%dict->size];entry!=NULL;entry=entry->next) { if ( (entry->hash==hash) && - (strcasecmp(entry->key,key)==0) ) + (strcmp(entry->key,key)==0) ) return entry->value; } /* no matches found */ return NULL; } +const char *dict_getany(DICT *dict) +{ + int i; + /* loop over the linked list in the hashtable */ + for (i=0;i<dict->size;i++) + if (dict->table[i]) + return dict->table[i]->key; + /* no matches found */ + return NULL; +} + int dict_put(DICT *dict,const char *key,void *value) { uint32_t hash; @@ -196,7 +206,7 @@ int dict_put(DICT *dict,const char *key,void *value) prev=entry,entry=entry->next) { if ( (entry->hash==hash) && - (strcasecmp(entry->key,key)==0) ) + (strcmp(entry->key,key)==0) ) { /* check if we should unset the entry */ if (value==NULL) diff --git a/common/dict.h b/common/dict.h index ee231e1..bb244f0 100644 --- a/common/dict.h +++ b/common/dict.h @@ -2,7 +2,7 @@ dict.h - dictionary functions This file is part of the nss-pam-ldapd library. - Copyright (C) 2007, 2008, 2009 Arthur de Jong + Copyright (C) 2007, 2008, 2009, 2010 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 @@ -26,8 +26,7 @@ #include "compat/attrs.h" /* - These functions provide a mapping between a case insensitive - string and a pointer. + These functions provide a mapping between a string and a pointer. */ typedef struct dictionary DICT; @@ -40,17 +39,22 @@ DICT *dict_new(void) 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. */ + is replaced. All key comparisons are case sensitive. */ int dict_put(DICT *dict,const char *key,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. */ + All key comparisons are case sensitive. */ void *dict_get(DICT *dict,const char *key) MUST_USE; +/* Get a key from the dictionary that has a value set. The caller does + not need to free the returned value (it is freed when dict_free() + is called). */ +const char *dict_getany(DICT *dict); + /* Delete a key-value association from the dictionary. - All key comparisons are case insensitive. */ + All key comparisons are case sensitive. */ /*void dict_del(DICT *dict,const char *key);*/ /* Remove the dictionary from memory. All allocated storage diff --git a/common/set.c b/common/set.c index d36ce2d..aec7e83 100644 --- a/common/set.c +++ b/common/set.c @@ -2,7 +2,7 @@ set.c - set functions This file is part of the nss-pam-ldapd library. - Copyright (C) 2008, 2009 Arthur de Jong + Copyright (C) 2008, 2009, 2010 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 @@ -46,6 +46,19 @@ int set_add(SET *set,const char *value) return dict_put((DICT *)set,value,set); } +char *set_pop(SET *set) +{ + const char *key; + char *value; + key=dict_getany((DICT *)set); + if (key==NULL) + return NULL; /* no more entries in set */ + /* remove the entry from the dict and return a copy */ + value=strdup(key); + dict_put((DICT *)set,key,NULL); + return value; +} + int set_contains(SET *set,const char *value) { return dict_get((DICT *)set,value)!=NULL; diff --git a/common/set.h b/common/set.h index 5824bfc..d57c3db 100644 --- a/common/set.h +++ b/common/set.h @@ -2,7 +2,7 @@ set.h - set functions This file is part of the nss-pam-ldapd library. - Copyright (C) 2008, 2009 Arthur de Jong + Copyright (C) 2008, 2009, 2010 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 @@ -26,7 +26,7 @@ #include "compat/attrs.h" /* - These functions provide a set of string in an unordered + These functions provide a set of strings in an unordered collection. */ typedef struct set SET; @@ -39,14 +39,19 @@ SET *set_new(void) /* Add a string in the set. The value is duplicated and can be reused by the caller. This function returns non-0 in case of memory allocation - errors. All value comparisons are case insensitive. */ + errors. All value comparisons are case sensitive. */ int set_add(SET *set,const char *value); /* Return non-zero if the value is in the set. - All value comparisons are case insensitive. */ + All value comparisons are case sensitive. */ int set_contains(SET *set,const char *value) MUST_USE; +/* Get an element from the set and removes it from the set. + Returns NULL on an empty set. A copy of the string in the set + is returned, the caller should use free() to free it. */ +char *set_pop(SET *set); + /* Remove the set from memory. All allocated storage for the set and the values is freed. */ void set_free(SET *set); diff --git a/nslcd/myldap.c b/nslcd/myldap.c index afbc898..902adbc 100644 --- a/nslcd/myldap.c +++ b/nslcd/myldap.c @@ -547,6 +547,20 @@ static void do_close(MYLDAP_SESSION *session) { int i; int rc; + int sd=-1; + struct timeval tv; + /* set timeout options on socket to avoid hang in some cases + (we set a short timeout because we don't care too much about properly + shutting down the connection) */ + if (ldap_get_option(session->ld,LDAP_OPT_DESC,&sd)==LDAP_SUCCESS) + { + /* ignore errors */ + tv.tv_sec=nslcd_cfg->ldc_timelimit/2; + if (!tv.tv_sec) tv.tv_sec=1; + tv.tv_usec=0; + (void)setsockopt(sd,SOL_SOCKET,SO_RCVTIMEO,(void *)&tv,sizeof(tv)); + (void)setsockopt(sd,SOL_SOCKET,SO_SNDTIMEO,(void *)&tv,sizeof(tv)); + } /* if we had reachability problems with the server close the connection */ if (session->ld!=NULL) { @@ -621,7 +635,7 @@ static void myldap_session_check(MYLDAP_SESSION *session) and binds to the server. This returns an LDAP status code. */ static int do_open(MYLDAP_SESSION *session) { - int rc,rc2; + int rc; int sd=-1; struct timeval tv; /* check if the idle time for the connection has expired */ @@ -644,13 +658,7 @@ static int do_open(MYLDAP_SESSION *session) ldap_err2string(rc),(errno==0)?"":": ", (errno==0)?"":strerror(errno)); if (session->ld!=NULL) - { - log_log(LOG_DEBUG,"ldap_unbind()"); - rc2=ldap_unbind(session->ld); - session->ld=NULL; - if (rc2!=LDAP_SUCCESS) - log_log(LOG_WARNING,"ldap_unbind() failed: %s",ldap_err2string(rc2)); - } + do_close(session); return rc; } else if (session->ld==NULL) @@ -662,10 +670,7 @@ static int do_open(MYLDAP_SESSION *session) rc=do_set_options(session); if (rc!=LDAP_SUCCESS) { - rc2=ldap_unbind(session->ld); - session->ld=NULL; - if (rc2!=LDAP_SUCCESS) - log_log(LOG_WARNING,"ldap_unbind() failed: %s",ldap_err2string(rc2)); + do_close(session); return rc; } /* bind to the server */ @@ -679,18 +684,17 @@ static int do_open(MYLDAP_SESSION *session) nslcd_cfg->ldc_uris[session->current_uri].uri, ldap_err2string(rc),(errno==0)?"":": ", (errno==0)?"":strerror(errno)); - rc2=ldap_unbind(session->ld); - session->ld=NULL; - if (rc2!=LDAP_SUCCESS) - log_log(LOG_WARNING,"ldap_unbind() failed: %s",ldap_err2string(rc2)); + do_close(session); return rc; } - /* set timeout options on socket to avoid hang in some cases */ + /* set timeout options on socket to avoid hang in some cases + (twice the normal timeout so this should only be triggered in cases + where the library behaves incorrectly) */ if (ldap_get_option(session->ld,LDAP_OPT_DESC,&sd)==LDAP_SUCCESS) { /* ignore errors */ - tv.tv_sec=nslcd_cfg->ldc_timelimit; - tv.tv_usec=500; + tv.tv_sec=nslcd_cfg->ldc_timelimit*2; + tv.tv_usec=0; (void)setsockopt(sd,SOL_SOCKET,SO_RCVTIMEO,(void *)&tv,sizeof(tv)); (void)setsockopt(sd,SOL_SOCKET,SO_SNDTIMEO,(void *)&tv,sizeof(tv)); } diff --git a/tests/test_dict.c b/tests/test_dict.c index 4e0adf9..05d54eb 100644 --- a/tests/test_dict.c +++ b/tests/test_dict.c @@ -2,7 +2,7 @@ test_dict.c - simple test for the dict module This file is part of the nss-pam-ldapd library. - Copyright (C) 2007, 2008, 2009 Arthur de Jong + Copyright (C) 2007, 2008, 2009, 2010 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 @@ -47,19 +47,21 @@ static void test_simple(void) dict_put(dict,"key1",value1); dict_put(dict,"key2",value2); dict_put(dict,"key3",dict); - dict_put(dict,"KEY2",replace2); + dict_put(dict,"key2",replace2); /* check dictionary contents */ - val=dict_get(dict,"KeY1"); + val=dict_get(dict,"key1"); assert(val==value1); - val=dict_get(dict,"kEy2"); + val=dict_get(dict,"key2"); assert(val==replace2); - val=dict_get(dict,"KeY3"); + val=dict_get(dict,"key3"); assert(val==dict); val=dict_get(dict,"key4"); assert(val==NULL); + val=dict_get(dict,"KEY1"); + assert(val==NULL); /* remove a key */ - dict_put(dict,"kEy3",NULL); - val=dict_get(dict,"keY3"); + dict_put(dict,"key3",NULL); + val=dict_get(dict,"key3"); assert(val==NULL); /* loop over dictionary contents */ keys=dict_keys(dict); diff --git a/tests/test_set.c b/tests/test_set.c index 2623906..6f72b4d 100644 --- a/tests/test_set.c +++ b/tests/test_set.c @@ -2,7 +2,7 @@ test_set.c - simple test for the set module This file is part of the nss-pam-ldapd library. - Copyright (C) 2008, 2009 Arthur de Jong + Copyright (C) 2008, 2009, 2010 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 @@ -30,6 +30,14 @@ #include "common/set.h" #include "compat/attrs.h" +static int isknownvalue(const char *value) +{ + return value!=NULL && ( + (strcmp(value,"key1")==0) || + (strcmp(value,"key2")==0) || + (strcmp(value,"key3")==0) ); +} + /* the main program... */ int main(int UNUSED(argc),char UNUSED(*argv[])) { @@ -44,23 +52,28 @@ int main(int UNUSED(argc),char UNUSED(*argv[])) set_add(set,"key1"); set_add(set,"key2"); set_add(set,"key3"); - set_add(set,"KEY2"); + set_add(set,"key2"); /* check set contents */ - assert(set_contains(set,"KeY1")); - assert(set_contains(set,"kEy2")); - assert(set_contains(set,"KeY3")); + assert(set_contains(set,"key1")); + assert(set_contains(set,"key2")); + assert(set_contains(set,"key3")); assert(!set_contains(set,"key4")); + assert(!set_contains(set,"KEY1")); /* loop over set contents */ list=set_tolist(set); for (i=0;list[i]!=NULL;i++) { - assert( (strcasecmp(list[i],"key1")==0) || - (strcasecmp(list[i],"key2")==0) || - (strcasecmp(list[i],"key3")==0) ); + assert(isknownvalue(list[i])); } + /* remove keys from the set */ + assert(isknownvalue(set_pop(set))); + assert(isknownvalue(set_pop(set))); + assert(isknownvalue(set_pop(set))); + assert(set_pop(set)==NULL); + /* free set */ set_free(set); free(list); |