summaryrefslogtreecommitdiff
path: root/nslcd/util.c
diff options
context:
space:
mode:
authorArthur de Jong <arthur@arthurdejong.org>2007-09-14 22:00:21 +0000
committerArthur de Jong <arthur@arthurdejong.org>2007-09-14 22:00:21 +0000
commit90a1cd9e20bedecdd0f366d585d6df82269d17b7 (patch)
tree661d77f95b26a231e1c15deb9e3bde95471a913d /nslcd/util.c
parentb928d6184346cd5a93f103633a5c7e5307437cd5 (diff)
move the two remaining useful functions from util.c to ldap-nss.c
git-svn-id: http://arthurdejong.org/svn/nss-pam-ldapd/nss-ldapd@400 ef36b2f9-881f-0410-afb5-c4e39611909c
Diffstat (limited to 'nslcd/util.c')
-rw-r--r--nslcd/util.c516
1 files changed, 0 insertions, 516 deletions
diff --git a/nslcd/util.c b/nslcd/util.c
deleted file mode 100644
index 3b737c3..0000000
--- a/nslcd/util.c
+++ /dev/null
@@ -1,516 +0,0 @@
-/*
- util.c - LDAP utility functions
- This file was part of the nss_ldap library which has been
- forked into the nss-ldapd library.
-
- Copyright (C) 1997-2005 Luke Howard
- Copyright (C) 2006, 2007 West Consulting
- Copyright (C) 2006, 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 <string.h>
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#include <stdlib.h>
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <netdb.h>
-#include <string.h>
-#include <fcntl.h>
-#include <assert.h>
-#ifdef HAVE_LBER_H
-#include <lber.h>
-#endif
-#ifdef HAVE_LDAP_H
-#include <ldap.h>
-#endif
-#if defined(HAVE_THREAD_H)
-#include <thread.h>
-#elif defined(HAVE_PTHREAD_H)
-#include <pthread.h>
-#endif
-
-/* for glibc, use weak aliases to pthreads functions */
-#ifdef HAVE_LIBC_LOCK_H
-#include <libc-lock.h>
-#elif defined(HAVE_BITS_LIBC_LOCK_H)
-#include <bits/libc-lock.h>
-#endif
-
-#include "ldap-nss.h"
-#include "util.h"
-#include "common.h"
-#include "log.h"
-#include "cfg.h"
-#include "attmap.h"
-
-/*
- * Portable locking macro.
- */
-#if defined(HAVE_THREAD_H)
-#define NSS_LDAP_LOCK(m) mutex_lock(&m)
-#define NSS_LDAP_UNLOCK(m) mutex_unlock(&m)
-#define NSS_LDAP_DEFINE_LOCK(m) static mutex_t m = DEFAULTMUTEX
-#elif defined(HAVE_LIBC_LOCK_H) || defined(HAVE_BITS_LIBC_LOCK_H)
-#define NSS_LDAP_LOCK(m) __libc_lock_lock(m)
-#define NSS_LDAP_UNLOCK(m) __libc_lock_unlock(m)
-#define NSS_LDAP_DEFINE_LOCK(m) static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER
-#elif defined(HAVE_PTHREAD_H)
-#define NSS_LDAP_LOCK(m) pthread_mutex_lock(&m)
-#define NSS_LDAP_UNLOCK(m) pthread_mutex_unlock(&m)
-#define NSS_LDAP_DEFINE_LOCK(m) static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER
-#else
-#define NSS_LDAP_LOCK(m)
-#define NSS_LDAP_UNLOCK(m)
-#define NSS_LDAP_DEFINE_LOCK(m)
-#endif
-
-static void *__cache = NULL;
-
-NSS_LDAP_DEFINE_LOCK (__cache_lock);
-
-#define cache_lock() NSS_LDAP_LOCK(__cache_lock)
-#define cache_unlock() NSS_LDAP_UNLOCK(__cache_lock)
-
-struct ldap_datum
-{
- void *data;
- size_t size;
-};
-
-#define NSS_LDAP_DATUM_ZERO(d) do { \
- (d)->data = NULL; \
- (d)->size = 0; \
- } while (0)
-
-#define NSS_LDAP_DB_NORMALIZE_CASE 0x1
-
-struct ldap_dictionary
-{
- struct ldap_datum key;
- struct ldap_datum value;
- struct ldap_dictionary *next;
-};
-
-static struct ldap_dictionary *old_dict_new(void)
-{
- struct ldap_dictionary *dict;
- dict = malloc(sizeof(struct ldap_dictionary));
- if (dict==NULL)
- {
- return NULL;
- }
- NSS_LDAP_DATUM_ZERO(&dict->key);
- NSS_LDAP_DATUM_ZERO(&dict->value);
- dict->next=NULL;
- return dict;
-}
-
-static struct ldap_dictionary *
-do_find_last (struct ldap_dictionary *dict)
-{
- struct ldap_dictionary *p;
-
- for (p = dict; p->next != NULL; p = p->next)
- ;
-
- return p;
-}
-
-static enum nss_status
-do_dup_datum (struct ldap_datum * dst, const struct ldap_datum * src)
-{
- dst->data = malloc (src->size);
- if (dst->data == NULL)
- return NSS_STATUS_TRYAGAIN;
-
- memcpy (dst->data, src->data, src->size);
- dst->size = src->size;
-
- return NSS_STATUS_SUCCESS;
-}
-
-static void
-do_free_datum (struct ldap_datum * datum)
-{
- if (datum->data != NULL)
- {
- free (datum->data);
- datum->data = NULL;
- }
- datum->size = 0;
-}
-
-static void
-do_free_dictionary (struct ldap_dictionary *dict)
-{
- do_free_datum (&dict->key);
- do_free_datum (&dict->value);
- free (dict);
-}
-
-static enum nss_status old_dict_put(
- struct ldap_dictionary *db,
- const struct ldap_datum *key,
- const struct ldap_datum *value)
-{
- struct ldap_dictionary *dict = (struct ldap_dictionary *) db;
- struct ldap_dictionary *p, *q;
-
- assert(key!=NULL);
- assert(key->data!=NULL);
-
- if (dict->key.data==NULL)
- {
- /* uninitialized */
- q=dict;
- p=NULL;
- }
- else
- {
- p=do_find_last(dict);
- assert(p!=NULL);
- assert(p->next==NULL);
- q=old_dict_new();
- if (q==NULL)
- return NSS_STATUS_TRYAGAIN;
- }
-
- if (do_dup_datum(&q->key,key)!=NSS_STATUS_SUCCESS)
- {
- do_free_dictionary(q);
- return NSS_STATUS_TRYAGAIN;
- }
-
- if (do_dup_datum(&q->value,value)!=NSS_STATUS_SUCCESS)
- {
- do_free_dictionary(q);
- return NSS_STATUS_TRYAGAIN;
- }
-
- if (p!=NULL)
- p->next=q;
-
- return NSS_STATUS_SUCCESS;
-}
-
-static enum nss_status old_dict_get(
- struct ldap_dictionary *db,
- unsigned flags,
- const struct ldap_datum *key,
- struct ldap_datum *value)
-{
- struct ldap_dictionary *p;
- for (p=db;p!=NULL;p=p->next)
- {
- int cmp;
- if (p->key.size != key->size)
- continue;
- if (flags & NSS_LDAP_DB_NORMALIZE_CASE)
- cmp=strncasecmp((char *)p->key.data,(char *)key->data,key->size);
- else
- cmp=memcmp(p->key.data,key->data,key->size);
- if (cmp==0)
- {
- value->data=p->value.data;
- value->size=p->value.size;
- return NSS_STATUS_SUCCESS;
- }
- }
- return NSS_STATUS_NOTFOUND;
-}
-
-static enum nss_status
-dn2uid_cache_put (const char *dn, const char *uid)
-{
- enum nss_status status;
- struct ldap_datum key, val;
-
- cache_lock ();
-
- if (__cache == NULL)
- {
- __cache = (void *)old_dict_new();
- if (__cache == NULL)
- {
- cache_unlock ();
- return NSS_STATUS_TRYAGAIN;
- }
- }
-
- key.data = (const void *) dn;
- key.size = strlen (dn);
- val.data = (const void *) uid;
- val.size = strlen (uid);
-
- status = old_dict_put (__cache, &key, &val);
-
- cache_unlock ();
-
- return status;
-}
-
-static enum nss_status
-dn2uid_cache_get (const char *dn, char **uid, char **buffer, size_t * buflen)
-{
- struct ldap_datum key, val;
- enum nss_status status;
-
- cache_lock ();
-
- if (__cache == NULL)
- {
- cache_unlock ();
- return NSS_STATUS_NOTFOUND;
- }
-
- key.data = (const void *) dn;
- key.size = strlen (dn);
-
- status = old_dict_get (__cache, 0, &key, &val);
- if (status != NSS_STATUS_SUCCESS)
- {
- cache_unlock ();
- return status;
- }
-
- if (*buflen <= val.size)
- {
- cache_unlock ();
- return NSS_STATUS_TRYAGAIN;
- }
-
- *uid = *buffer;
- memcpy (*uid, (const char *) val.data, val.size);
- (*uid)[val.size] = '\0';
- *buffer += val.size + 1;
- *buflen -= val.size + 1;
-
- cache_unlock ();
- return NSS_STATUS_SUCCESS;
-}
-
-static enum nss_status
-do_getrdnvalue (const char *dn,
- const char *rdntype,
- char **rval, char **buffer, size_t * buflen)
-{
- char **exploded_dn;
- char *rdnvalue = NULL;
- char rdnava[64];
- int rdnlen = 0, rdnavalen;
-
- snprintf (rdnava, sizeof rdnava, "%s=", rdntype);
- rdnavalen = strlen (rdnava);
-
- exploded_dn = ldap_explode_dn (dn, 0);
-
- if (exploded_dn != NULL)
- {
- /*
- * attempt to get the naming attribute's principal
- * value by parsing the RDN. We need to support
- * multivalued RDNs (as they're essentially mandated
- * for services)
- */
-#ifdef HAVE_LDAP_EXPLODE_RDN
- /*
- * use ldap_explode_rdn() API, as it's cleaner than
- * strtok(). This code has not been tested!
- */
- char **p, **exploded_rdn;
-
- exploded_rdn = ldap_explode_rdn (*exploded_dn, 0);
- if (exploded_rdn != NULL)
- {
- for (p = exploded_rdn; *p != NULL; p++)
- {
- if (strncasecmp (*p, rdnava, rdnavalen) == 0)
- {
- char *r = *p + rdnavalen;
-
- rdnlen = strlen (r);
- if (*buflen <= rdnlen)
- {
- ldap_value_free (exploded_rdn);
- ldap_value_free (exploded_dn);
- return NSS_STATUS_TRYAGAIN;
- }
- rdnvalue = *buffer;
- strncpy (rdnvalue, r, rdnlen);
- break;
- }
- }
- ldap_value_free (exploded_rdn);
- }
-#else /* HAVE_LDAP_EXPLODE_RDN */
- /*
- * we don't have Netscape's ldap_explode_rdn() API,
- * so we fudge it with strtok(). Note that this will
- * not handle escaping properly.
- */
- char *p, *r = *exploded_dn;
-#ifdef HAVE_STRTOK_R
- char *st = NULL;
-#endif /* HAVE_STRTOK_R */
-
-#ifndef HAVE_STRTOK_R
- for (p = strtok (r, "+");
-#else /* HAVE_STRTOK_R */
- for (p = strtok_r (r, "+", &st);
-#endif /* not HAVE_STRTOK_R */
- p != NULL;
-#ifndef HAVE_STRTOK_R
- p = strtok (NULL, "+"))
-#else /* HAVE_STRTOK_R */
- p = strtok_r (NULL, "+", &st))
-#endif /* not HAVE_STRTOK_R */
- {
- if (strncasecmp (p, rdnava, rdnavalen) == 0)
- {
- p += rdnavalen;
- rdnlen = strlen (p);
- if (*buflen <= rdnlen)
- {
- ldap_value_free (exploded_dn);
- return NSS_STATUS_TRYAGAIN;
- }
- rdnvalue = *buffer;
- strncpy (rdnvalue, p, rdnlen);
- break;
- }
- if (r != NULL)
- r = NULL;
- }
-#endif /* not HAVE_LDAP_EXPLODE_RDN */
- }
-
- if (exploded_dn != NULL)
- {
- ldap_value_free (exploded_dn);
- }
-
- if (rdnvalue != NULL)
- {
- rdnvalue[rdnlen] = '\0';
- *buffer += rdnlen + 1;
- *buflen -= rdnlen + 1;
- *rval = rdnvalue;
- return NSS_STATUS_SUCCESS;
- }
-
- return NSS_STATUS_NOTFOUND;
-}
-
-enum nss_status _nss_ldap_getrdnvalue(
- MYLDAP_SESSION *session,LDAPMessage *entry,const char *rdntype,
- char **rval,char **buffer,size_t * buflen)
-{
- char *dn;
- enum nss_status status;
-
- dn=_nss_ldap_get_dn(session,entry);
- if (dn == NULL)
- {
- return NSS_STATUS_NOTFOUND;
- }
-
- status = do_getrdnvalue (dn, rdntype, rval, buffer, buflen);
-#ifdef HAVE_LDAP_MEMFREE
- ldap_memfree (dn);
-#else /* HAVE_LDAP_MEMFREE */
- free (dn);
-#endif /* not HAVE_LDAP_MEMFREE */
-
- /*
- * If examining the DN failed, then pick the nominal first
- * value of cn as the canonical name (recall that attributes
- * are sets, not sequences)
- */
- if (status == NSS_STATUS_NOTFOUND)
- {
- char **vals;
-
- vals=_nss_ldap_get_values(session,entry,rdntype);
-
- if (vals != NULL)
- {
- int rdnlen = strlen (*vals);
- if (*buflen > rdnlen)
- {
- char *rdnvalue = *buffer;
- strncpy (rdnvalue, *vals, rdnlen);
- rdnvalue[rdnlen] = '\0';
- *buffer += rdnlen + 1;
- *buflen -= rdnlen + 1;
- *rval = rdnvalue;
- status = NSS_STATUS_SUCCESS;
- }
- else
- {
- status = NSS_STATUS_TRYAGAIN;
- }
- ldap_value_free (vals);
- }
- }
-
- return status;
-}
-
-int _nss_ldap_escape_string(const char *src,char *buffer,size_t buflen)
-{
- int pos=0;
- /* go over all characters in source string */
- for (;*src!='\0';src++)
- {
- /* check if char will fit */
- if (pos>=(buflen+4))
- return -1;
- /* do escaping for some characters */
- switch (*src)
- {
- case '*':
- strcpy(buffer+pos,"\\2a");
- pos+=3;
- break;
- case '(':
- strcpy(buffer+pos,"\\28");
- pos+=3;
- break;
- case ')':
- strcpy(buffer+pos,"\\29");
- pos+=3;
- break;
- case '\\':
- strcpy(buffer+pos,"\\5c");
- pos+=3;
- break;
- default:
- /* just copy character */
- buffer[pos++]=*src;
- break;
- }
- }
- /* terminate destination string */
- buffer[pos]='\0';
- return 0;
-}