From 32c0d6a3f5fb389a7751a6470e5743c2facabae7 Mon Sep 17 00:00:00 2001 From: William Brown Date: Tue, 14 Nov 2017 16:55:21 +1000 Subject: [PATCH 9/9] Ticket 49218 - Certmap - Remove old certmap types Bug Description: This adds support for pluggable certificate mapping libraries. To achieve this, this replaces the existing baked in certificate mapping code. Fix Description: Remove all un-needed certmap types and examples. https://pagure.io/389-ds-base/issue/49218 https://pagure.io/lib389/issue/95 https://pagure.io/lib389/issue/84 Author: wibrown Review by: ??? --- lib/ldaputil/.cvsignore | 1 - lib/ldaputil/cert.c | 489 ----------- lib/ldaputil/certmap.c | 1721 --------------------------------------- lib/ldaputil/dbconf.c | 686 ---------------- lib/ldaputil/encode.c | 151 ---- lib/ldaputil/errors.c | 210 ----- lib/ldaputil/examples/Makefile | 89 -- lib/ldaputil/examples/README | 100 --- lib/ldaputil/examples/init.c | 43 - lib/ldaputil/examples/plugin.c | 240 ------ lib/ldaputil/examples/plugin.h | 35 - lib/ldaputil/init.c | 138 ---- lib/ldaputil/ldapauth.c | 214 ----- lib/ldaputil/ldapu-changes.html | 406 --------- lib/ldaputil/ldaputili.h | 68 -- lib/ldaputil/vtable.c | 210 ----- 16 files changed, 4801 deletions(-) delete mode 100644 lib/ldaputil/.cvsignore delete mode 100644 lib/ldaputil/cert.c delete mode 100644 lib/ldaputil/certmap.c delete mode 100644 lib/ldaputil/dbconf.c delete mode 100644 lib/ldaputil/encode.c delete mode 100644 lib/ldaputil/errors.c delete mode 100644 lib/ldaputil/examples/Makefile delete mode 100644 lib/ldaputil/examples/README delete mode 100644 lib/ldaputil/examples/init.c delete mode 100644 lib/ldaputil/examples/plugin.c delete mode 100644 lib/ldaputil/examples/plugin.h delete mode 100644 lib/ldaputil/init.c delete mode 100644 lib/ldaputil/ldapauth.c delete mode 100644 lib/ldaputil/ldapu-changes.html delete mode 100644 lib/ldaputil/ldaputili.h delete mode 100644 lib/ldaputil/vtable.c diff --git a/lib/ldaputil/.cvsignore b/lib/ldaputil/.cvsignore deleted file mode 100644 index e7b97c5..0000000 --- a/lib/ldaputil/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -.depends diff --git a/lib/ldaputil/cert.c b/lib/ldaputil/cert.c deleted file mode 100644 index 65a4815..0000000 --- a/lib/ldaputil/cert.c +++ /dev/null @@ -1,489 +0,0 @@ -/** BEGIN COPYRIGHT BLOCK - * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. - * Copyright (C) 2005 Red Hat, Inc. - * All rights reserved. - * - * License: GPL (version 3 or any later version). - * See LICENSE for details. - * END COPYRIGHT BLOCK **/ - -#ifdef HAVE_CONFIG_H -#include -#endif - - -#include -/* This was malloc.h - but it's moved to stdlib.h on most platforms, and FBSD is strict */ -/* Make it stdlib.h, and revert to malloc.h with ifdefs if we have issues here. WB 2016 */ -#include - -/* removed for ns security integration -#include -*/ -#include "prmem.h" -#include -#include -#include -#include -#include -#include -#include "ldaputili.h" - -#include "slapi-plugin.h" - -NSAPI_PUBLIC int -ldapu_get_cert(void *SSLendpoint __attribute__((unused)), void **cert __attribute__((unused))) -{ - /* TEMPORARY -- not implemented yet*/ - return LDAPU_FAILED; -} - - -NSAPI_PUBLIC int -ldapu_get_cert_subject_dn(void *cert_in, char **subjectDN) -{ - CERTCertificate *cert = (CERTCertificate *)cert_in; - char *cert_subject = CERT_NameToAscii(&cert->subject); - - if (cert_subject != NULL) - *subjectDN = strdup(cert_subject); - else - *subjectDN = NULL; - - PR_Free(cert_subject); - return *subjectDN ? LDAPU_SUCCESS : LDAPU_ERR_EXTRACT_SUBJECTDN_FAILED; -} - -NSAPI_PUBLIC int -ldapu_get_cert_issuer_dn(void *cert_in, char **issuerDN) -{ - CERTCertificate *cert = (CERTCertificate *)cert_in; - char *cert_issuer = CERT_NameToAscii(&cert->issuer); - - *issuerDN = strdup(cert_issuer); - PR_Free(cert_issuer); - - return *issuerDN ? LDAPU_SUCCESS : LDAPU_ERR_EXTRACT_ISSUERDN_FAILED; -} - -NSAPI_PUBLIC int -ldapu_get_cert_der(void *cert_in, unsigned char **der, unsigned int *len) -{ - CERTCertificate *cert = (CERTCertificate *)cert_in; - SECItem derCert = ((CERTCertificate *)cert)->derCert; - unsigned char *data = derCert.data; - - *len = derCert.len; - *der = (unsigned char *)malloc(*len); - - if (!*der) - return LDAPU_ERR_OUT_OF_MEMORY; - - memcpy(*der, data, *len); - - return *len ? LDAPU_SUCCESS : LDAPU_ERR_EXTRACT_DERCERT_FAILED; -} - -static int -certmap_name_to_secoid(const char *str) -{ - if (!ldapu_strcasecmp(str, "c")) - return SEC_OID_AVA_COUNTRY_NAME; - if (!ldapu_strcasecmp(str, "o")) - return SEC_OID_AVA_ORGANIZATION_NAME; - if (!ldapu_strcasecmp(str, "cn")) - return SEC_OID_AVA_COMMON_NAME; - if (!ldapu_strcasecmp(str, "l")) - return SEC_OID_AVA_LOCALITY; - if (!ldapu_strcasecmp(str, "st")) - return SEC_OID_AVA_STATE_OR_PROVINCE; - if (!ldapu_strcasecmp(str, "ou")) - return SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME; - if (!ldapu_strcasecmp(str, "uid")) - return SEC_OID_RFC1274_UID; - if (!ldapu_strcasecmp(str, "e")) - return SEC_OID_PKCS9_EMAIL_ADDRESS; - if (!ldapu_strcasecmp(str, "mail")) - return SEC_OID_RFC1274_MAIL; - if (!ldapu_strcasecmp(str, "dc")) - return SEC_OID_AVA_DC; - - return SEC_OID_AVA_UNKNOWN; /* return invalid OID */ -} - -NSAPI_PUBLIC int -ldapu_get_cert_ava_val(void *cert_in, int which_dn, const char *attr, char ***val_out) -{ - CERTCertificate *cert = (CERTCertificate *)cert_in; - CERTName *cert_dn; - CERTRDN **rdns; - CERTRDN **rdn; - CERTAVA **avas; - CERTAVA *ava; - int attr_tag = certmap_name_to_secoid(attr); - char **val; - char **ptr; - int rv; - - *val_out = 0; - - if (attr_tag == SEC_OID_AVA_UNKNOWN) { - return LDAPU_ERR_INVALID_ARGUMENT; - } - - if (which_dn == LDAPU_SUBJECT_DN) - cert_dn = &cert->subject; - else if (which_dn == LDAPU_ISSUER_DN) - cert_dn = &cert->issuer; - else - return LDAPU_ERR_INVALID_ARGUMENT; - - val = (char **)malloc(32 * sizeof(char *)); - - if (!val) - return LDAPU_ERR_OUT_OF_MEMORY; - - ptr = val; - - rdns = cert_dn->rdns; - - if (rdns) { - for (rdn = rdns; *rdn; rdn++) { - avas = (*rdn)->avas; - while ((ava = *avas++) != NULL) { - int tag = CERT_GetAVATag(ava); - - if (tag == attr_tag) { - char buf[BIG_LINE]; - int lenLen; - int vallen; - /* Found it */ - - /* Copied from ns/lib/libsec ... - * XXX this code is incorrect in general - * -- should use a DER template. - */ - lenLen = 2; - if (ava->value.len >= 128) - lenLen = 3; - vallen = ava->value.len - lenLen; - - rv = CERT_RFC1485_EscapeAndQuote(buf, - BIG_LINE, - (char *)ava->value.data + lenLen, - vallen); - - if (rv == SECSuccess) { - *ptr++ = strdup(buf); - } - break; - } - } - } - } - - *ptr = 0; - - if (*val) { - /* At least one value found */ - *val_out = val; - rv = LDAPU_SUCCESS; - } else { - free(val); - rv = LDAPU_FAILED; - } - - return rv; -} - -static void -_rdns_free(char ***rdns) -{ - auto char ***rdn; - for (rdn = rdns; *rdn; ++rdn) { - slapi_ldap_value_free(*rdn); - } - free(rdns); -} - -static char *** -_explode_dn(const char *dn) -{ - auto char ***exp = NULL; - if (dn && *dn) { - auto char **rdns = slapi_ldap_explode_dn(dn, 0); - if (rdns) { - auto size_t expLen = 0; - auto char **rdn; - for (rdn = rdns; *rdn; ++rdn) { - auto char **avas = slapi_ldap_explode_rdn(*rdn, 0); - if (avas && *avas) { - exp = (char ***)ldapu_realloc(exp, sizeof(char **) * (expLen + 2)); - if (exp) { - exp[expLen++] = avas; - } else { - slapi_ldap_value_free(avas); - break; - } - } else { /* parse error */ - if (avas) { - slapi_ldap_value_free(avas); - } - if (exp) { - exp[expLen] = NULL; - _rdns_free(exp); - exp = NULL; - } - break; - } - } - if (exp) { - exp[expLen] = NULL; - } - slapi_ldap_value_free(rdns); - } - } - return exp; -} - -static size_t -_rdns_count(char ***rdns) -{ - auto size_t count = 0; - auto char ***rdn; - for (rdn = rdns; *rdn; ++rdn) { - auto char **ava; - for (ava = *rdn; *ava; ++ava) { - ++count; - } - } - return count; -} - -static int -_replaceAVA(char *attr, char **avas) -{ - if (attr && avas) { - for (; *avas; ++avas) { - if (!ldapu_strcasecmp(*avas, attr)) { - *avas = attr; - return 1; - } - } - } - return 0; -} - -struct _attr_getter_pair -{ -#if NSS_VMAJOR < 3 || (NSS_VMAJOR == 3 && NSS_VMINOR < 15) - char *(*getter)(CERTName *dn); -#else - /* in 3.15.x "const" was added to the declarations */ - char *(*getter)(const CERTName *dn); -#endif - const char *name1; - const char *name2; -} _attr_getter_table[] = - { - {NULL, "OU", "organizationalUnitName"}, - {CERT_GetOrgName, "O", "organizationName"}, - {CERT_GetCommonName, "CN", "commonName"}, - {CERT_GetCertEmailAddress, "E", NULL}, - {CERT_GetCertEmailAddress, "MAIL", "rfc822mailbox"}, - {CERT_GetCertUid, "uid", NULL}, - {CERT_GetCountryName, "C", "country"}, - {CERT_GetStateName, "ST", "state"}, - {CERT_GetLocalityName, "L", "localityName"}, - {CERT_GetDomainComponentName, "DC", "dc"}, - {NULL, NULL, NULL}}; - -static int -_is_OU(const char *attr) -{ - auto struct _attr_getter_pair *descAttr; - for (descAttr = _attr_getter_table; descAttr->name1; ++descAttr) { - if (descAttr->getter == NULL) { /* OU attribute */ - if (!ldapu_strcasecmp(attr, descAttr->name1) || (descAttr->name2 && - !ldapu_strcasecmp(attr, descAttr->name2))) { - return 1; - } - break; - } - } - return 0; -} - -static char ** -_previous_OU(char **ava, char **avas) -{ - while (ava != avas) { - --ava; - if (_is_OU(*ava)) { - return ava; - } - } - return NULL; -} - -static char * -_value_normalize(char *value) -/* Remove leading and trailing spaces, and - change consecutive spaces to a single space. - */ -{ - auto char *t; - auto char *f; - t = f = value; - while (*f == ' ') - ++f; /* ignore leading spaces */ - for (; *f; ++f) { - if (*f != ' ' || t[-1] != ' ') { - *t++ = *f; /* no consecutive spaces */ - } - } - if (t > value && t[-1] == ' ') { - --t; /* ignore trailing space */ - } - *t = '\0'; - return value; -} - -static int -_explode_AVA(char *AVA) -/* Change an attributeTypeAndValue a la , - to the type name, followed immediately by the attribute value, - both normalized. - */ -{ - auto char *value = strchr(AVA, '='); - if (!value) - return LDAPU_FAILED; - *value++ = '\0'; - _value_normalize(AVA); - _value_normalize(value); - { - auto char *typeEnd = AVA + strlen(AVA); - if ((typeEnd + 1) != value) { - memmove(typeEnd + 1, value, strlen(value) + 1); - } - } - return LDAPU_SUCCESS; -} - -static char * -_AVA_value(char *AVA) -{ - return (AVA + strlen(AVA) + 1); -} - -static int -_value_match(char *value, char *desc) -{ - auto const int result = - !ldapu_strcasecmp(_value_normalize(value), desc); - return result; -} - -int -ldapu_member_certificate_match(void *cert, const char *desc) -/* - * Return Values: (same as ldapu_find) - * LDAPU_SUCCESS cert matches desc - * LDAPU_FAILED cert doesn't match desc - * Something went wrong. - */ -{ - auto int err = LDAPU_FAILED; - auto char ***descRDNs; - if (!cert || !desc || desc[0] != '{') - return LDAPU_FAILED; - if (desc[1] == '\0') - return LDAPU_SUCCESS; /* no AVAs */ - descRDNs = _explode_dn(desc + 1); - if (descRDNs) { - auto char **descAVAs = (char **)ldapu_malloc(sizeof(char *) * (_rdns_count(descRDNs) + 1)); - if (!descAVAs) { - err = LDAPU_ERR_OUT_OF_MEMORY; - } else { - auto CERTName *subject = &(((CERTCertificate *)cert)->subject); - auto char **descAVA; - - err = LDAPU_SUCCESS; - { /* extract all the AVAs, but not duplicate types, except OU */ - auto size_t descAVAsLen = 0; - auto char ***descRDN; - descAVAs[0] = NULL; - for (descRDN = descRDNs; err == LDAPU_SUCCESS && *descRDN; ++descRDN) { - for (descAVA = *descRDN; err == LDAPU_SUCCESS && *descAVA; ++descAVA) { - err = _explode_AVA(*descAVA); - if (err == LDAPU_SUCCESS) { - if (_is_OU(*descAVA) || - !_replaceAVA(*descAVA, descAVAs)) { - descAVAs[descAVAsLen++] = *descAVA; - descAVAs[descAVAsLen] = NULL; - } - } - } - } - } - - /* match all the attributes except OU */ - for (descAVA = descAVAs; err == LDAPU_SUCCESS && *descAVA; ++descAVA) { - auto struct _attr_getter_pair *descAttr; - err = LDAPU_FAILED; /* if no match */ - for (descAttr = _attr_getter_table; descAttr->name1; ++descAttr) { - if (!ldapu_strcasecmp(*descAVA, descAttr->name1) || (descAttr->name2 && - !ldapu_strcasecmp(*descAVA, descAttr->name2))) { - if (descAttr->getter == NULL) { /* OU attribute */ - err = LDAPU_SUCCESS; /* for now */ - } else { - auto char *certVal = (*(descAttr->getter))(subject); - if (certVal && _value_match(certVal, _AVA_value(*descAVA))) { - err = LDAPU_SUCCESS; - } - PR_Free(certVal); - } - break; - } - } - } - - /* match the OU attributes */ - if (err == LDAPU_SUCCESS && descAVA != descAVAs) { - /* Iterate over the OUs in the certificate subject */ - auto CERTRDN **certRDN = subject->rdns; - descAVA = _previous_OU(descAVA, descAVAs); - for (; descAVA && *certRDN; ++certRDN) { - auto CERTAVA **certAVA = (*certRDN)->avas; - for (; descAVA && *certAVA; ++certAVA) { - auto const int tag = CERT_GetAVATag(*certAVA); - if (tag == SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME) { - auto const size_t certValLen = (*certAVA)->value.len; - auto const size_t lenLen = (certValLen < 128) ? 2 : 3; - auto const size_t buflen = certValLen - lenLen; - auto char *buf = (char *)ldapu_malloc(buflen + 1); - if (!buf) { - err = LDAPU_ERR_OUT_OF_MEMORY; - descAVA = NULL; - } else { - memcpy(buf, (*certAVA)->value.data + lenLen, buflen); - buf[buflen] = 0; - if (_value_match(buf, _AVA_value(*descAVA))) { - descAVA = _previous_OU(descAVA, descAVAs); - } - free(buf); - } - } - } - } - if (descAVA) { - err = LDAPU_FAILED; /* no match for descAVA in subject */ - } - } - free(descAVAs); - } - _rdns_free(descRDNs); - } - return err; -} diff --git a/lib/ldaputil/certmap.c b/lib/ldaputil/certmap.c deleted file mode 100644 index 78bb363..0000000 --- a/lib/ldaputil/certmap.c +++ /dev/null @@ -1,1721 +0,0 @@ -/** BEGIN COPYRIGHT BLOCK - * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. - * Copyright (C) 2005 Red Hat, Inc. - * All rights reserved. - * - * License: GPL (version 3 or any later version). - * See LICENSE for details. - * END COPYRIGHT BLOCK **/ - -#ifdef HAVE_CONFIG_H -#include -#endif - - -#include -#include -#include -/* This was malloc.h - but it's moved to stdlib.h on most platforms, and FBSD is strict */ -/* Make it stdlib.h, and revert to malloc.h with ifdefs if we have issues here. WB 2016 */ -#include - -/* removed for ns security integration -#include -*/ -#include -#include -#include - -#include -#include -#define DEFINE_LDAPU_STRINGS 1 -#include -#include -#include -#include -#include "ldaputili.h" - -#ifndef BIG_LINE -#define BIG_LINE 1024 -#endif - -/* This is hack, the function is defined in cert/alg1485.c */ -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -} -#endif - -static char this_dllname[256]; -static const char *LIB_DIRECTIVE = "certmap"; -static const int LIB_DIRECTIVE_LEN = 7; /* strlen("LIB_DIRECTIVE") */ - -static char *ldapu_dn_normalize(char *dn); -static void *ldapu_propval_free(void *propval_in, void *arg); - -typedef struct -{ - FILE *fp; - void *arg; -} LDAPUPrintInfo_t; - -static LDAPUCertMapListInfo_t *certmap_listinfo = 0; -static LDAPUCertMapInfo_t *default_certmap_info = 0; - -static const char *certmap_attrs[] = { - 0, - 0, - 0, - 0}; - -const long CERTMAP_BIT_POS_UNKNOWN = 0; /* unknown OID */ -const long CERTMAP_BIT_POS_CN = 1L << 1; /* Common Name */ -const long CERTMAP_BIT_POS_OU = 1L << 2; /* Organization unit */ -const long CERTMAP_BIT_POS_O = 1L << 3; /* Organization */ -const long CERTMAP_BIT_POS_C = 1L << 4; /* Country */ -const long CERTMAP_BIT_POS_L = 1L << 5; /* Locality */ -const long CERTMAP_BIT_POS_ST = 1L << 6; /* State or Province */ -const long CERTMAP_BIT_POS_MAIL = 1L << 7; /* E-mail Address */ -const long CERTMAP_BIT_POS_UID = 1L << 8; /* UID */ -const long CERTMAP_BIT_POS_DC = 1L << 9; /* DC */ - -const int SEC_OID_AVA_UNKNOWN = 0; /* unknown OID */ - -static long -certmap_secoid_to_bit_pos(int oid) -{ - switch (oid) { - case SEC_OID_AVA_COUNTRY_NAME: - return CERTMAP_BIT_POS_C; - case SEC_OID_AVA_ORGANIZATION_NAME: - return CERTMAP_BIT_POS_O; - case SEC_OID_AVA_COMMON_NAME: - return CERTMAP_BIT_POS_CN; - case SEC_OID_AVA_LOCALITY: - return CERTMAP_BIT_POS_L; - case SEC_OID_AVA_STATE_OR_PROVINCE: - return CERTMAP_BIT_POS_ST; - case SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME: - return CERTMAP_BIT_POS_OU; - case SEC_OID_RFC1274_UID: - return CERTMAP_BIT_POS_UID; - /* Map "E" and "MAIL" to the same bit position */ - case SEC_OID_PKCS9_EMAIL_ADDRESS: - return CERTMAP_BIT_POS_MAIL; - case SEC_OID_RFC1274_MAIL: - return CERTMAP_BIT_POS_MAIL; - case SEC_OID_AVA_DC: - return CERTMAP_BIT_POS_DC; - default: - return CERTMAP_BIT_POS_UNKNOWN; - } -} - -static const char * -certmap_secoid_to_name(int oid) -{ - switch (oid) { - case SEC_OID_AVA_COUNTRY_NAME: - return "C"; - case SEC_OID_AVA_ORGANIZATION_NAME: - return "O"; - case SEC_OID_AVA_COMMON_NAME: - return "CN"; - case SEC_OID_AVA_LOCALITY: - return "L"; - case SEC_OID_AVA_STATE_OR_PROVINCE: - return "ST"; - case SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME: - return "OU"; - case SEC_OID_RFC1274_UID: - return "UID"; - /* Map both 'e' and 'mail' to 'mail' in LDAP */ - case SEC_OID_PKCS9_EMAIL_ADDRESS: - return "MAIL"; - case SEC_OID_RFC1274_MAIL: - return "MAIL"; - case SEC_OID_AVA_DC: - return "DC"; - default: - return 0; - } -} - -static void -tolower_string(char *str) -{ - if (str) { - while (*str) { - *str = tolower(*str); - str++; - } - } -} - -static long -certmap_name_to_bit_pos(const char *str) -{ - if (!ldapu_strcasecmp(str, "c")) - return CERTMAP_BIT_POS_C; - if (!ldapu_strcasecmp(str, "o")) - return CERTMAP_BIT_POS_O; - if (!ldapu_strcasecmp(str, "cn")) - return CERTMAP_BIT_POS_CN; - if (!ldapu_strcasecmp(str, "l")) - return CERTMAP_BIT_POS_L; - if (!ldapu_strcasecmp(str, "st")) - return CERTMAP_BIT_POS_ST; - if (!ldapu_strcasecmp(str, "ou")) - return CERTMAP_BIT_POS_OU; - if (!ldapu_strcasecmp(str, "uid")) - return CERTMAP_BIT_POS_UID; - /* Map "E" and "MAIL" to the same bit position */ - if (!ldapu_strcasecmp(str, "e")) - return CERTMAP_BIT_POS_MAIL; - if (!ldapu_strcasecmp(str, "mail")) - return CERTMAP_BIT_POS_MAIL; - if (!ldapu_strcasecmp(str, "dc")) - return CERTMAP_BIT_POS_DC; - - return CERTMAP_BIT_POS_UNKNOWN; -} - -#if 0 /* may need this in the future */ -static int certmap_name_to_secoid (const char *str) -{ - if (!ldapu_strcasecmp(str, "c")) return SEC_OID_AVA_COUNTRY_NAME; - if (!ldapu_strcasecmp(str, "o")) return SEC_OID_AVA_ORGANIZATION_NAME; - if (!ldapu_strcasecmp(str, "cn")) return SEC_OID_AVA_COMMON_NAME; - if (!ldapu_strcasecmp(str, "l")) return SEC_OID_AVA_LOCALITY; - if (!ldapu_strcasecmp(str, "st")) return SEC_OID_AVA_STATE_OR_PROVINCE; - if (!ldapu_strcasecmp(str, "ou")) return SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME; - if (!ldapu_strcasecmp(str, "uid")) return SEC_OID_RFC1274_UID; - if (!ldapu_strcasecmp(str, "e")) return SEC_OID_PKCS9_EMAIL_ADDRESS; - if (!ldapu_strcasecmp(str, "mail")) return SEC_OID_RFC1274_MAIL; - if (!ldapu_strcasecmp(str, "dc")) return SEC_OID_AVA_DC; - - return SEC_OID_AVA_UNKNOWN; /* return invalid OID */ -} -#endif - -NSAPI_PUBLIC int -ldapu_list_alloc(LDAPUList_t **list) -{ - *list = (LDAPUList_t *)calloc(1, sizeof(LDAPUList_t)); - - if (!*list) - return LDAPU_ERR_OUT_OF_MEMORY; - - return LDAPU_SUCCESS; -} - -static int -ldapu_list_add_node(LDAPUList_t *list, LDAPUListNode_t *node) -{ - if (list->head) { - node->prev = list->tail; - list->tail->next = node; - } else { - node->prev = 0; - list->head = node; - } - - node->next = 0; - list->tail = node; - return LDAPU_SUCCESS; -} - -NSAPI_PUBLIC int -ldapu_list_add_info(LDAPUList_t *list, void *info) -{ - LDAPUListNode_t *node; - - /* Allocate the list node and set info in the node. */ - node = (LDAPUListNode_t *)calloc(1, sizeof(LDAPUListNode_t)); - - if (!node) { - return LDAPU_ERR_OUT_OF_MEMORY; - } - - node->info = info; - - return ldapu_list_add_node(list, node); -} - - -static void -ldapu_list_free(LDAPUList_t *list, LDAPUListNodeFn_t free_fn) -{ - if (list) { - auto LDAPUListNode_t *node = list->head; - while (node) { - auto LDAPUListNode_t *next = node->next; - if (free_fn) { - (*free_fn)(node->info, 0); - node->info = 0; - } - node->info = 0; - free(node); - node = next; - } - list->head = 0; - list->tail = 0; - } - return; -} - -NSAPI_PUBLIC int -ldapu_propval_alloc(const char *prop, const char *val, LDAPUPropVal_t **propval) -{ - *propval = (LDAPUPropVal_t *)malloc(sizeof(LDAPUPropVal_t)); - - if (!*propval) - return LDAPU_ERR_OUT_OF_MEMORY; - - (*propval)->prop = prop ? strdup(prop) : 0; - (*propval)->val = val ? strdup(val) : 0; - - if ((!prop || (*propval)->prop) && (!val || (*propval)->val)) { - /* strdup worked */ - return LDAPU_SUCCESS; - } else { - return LDAPU_ERR_OUT_OF_MEMORY; - } -} - - -static int -PresentInComps(long comps_bitmask, int tag) -{ - long bit = certmap_secoid_to_bit_pos(tag); - - if (comps_bitmask & bit) - return 1; - else - return 0; -} - - -static int -dbconf_to_certmap_err(int err) -{ - switch (err) { - case LDAPU_ERR_DBNAME_IS_MISSING: - return LDAPU_ERR_CANAME_IS_MISSING; - case LDAPU_ERR_PROP_IS_MISSING: - return LDAPU_ERR_CAPROP_IS_MISSING; - default: - return err; - } -} - -/* CAUTION: this function hijacks some substructures from db_info and make - * the pointers to it NULL in the db_info. It is safe to deallocate db_info. - */ -static int -dbinfo_to_certinfo(DBConfDBInfo_t *db_info, - LDAPUCertMapInfo_t **certinfo_out) -{ - LDAPUCertMapInfo_t *certinfo = NULL; - LDAPUPropValList_t *propval_list = NULL; - int rv = LDAPU_SUCCESS; - - *certinfo_out = 0; - - certinfo = (LDAPUCertMapInfo_t *)calloc(1, sizeof(LDAPUCertMapInfo_t)); - - if (!certinfo) { - rv = LDAPU_ERR_OUT_OF_MEMORY; - goto error; - } - - /* hijack few structures rather then copy. Make the pointers to the - structures NULL in the original structure so that they don't freed up - when db_info is freed. */ - certinfo->issuerName = db_info->dbname; - db_info->dbname = 0; - - certinfo->issuerDN = ldapu_dn_normalize(db_info->url); - db_info->url = 0; - - /* hijack actual prop-vals from dbinfo -- to avoid strdup calls */ - if (db_info->firstprop) { - LDAPUPropVal_t *propval; - DBPropVal_t *dbpropval; - - dbpropval = db_info->firstprop; - - rv = ldapu_list_alloc(&propval_list); - - if (rv != LDAPU_SUCCESS) { - goto error; - } - - while (dbpropval) { - propval = (LDAPUPropVal_t *)malloc(sizeof(LDAPUPropVal_t)); - - if (!propval) { - rv = LDAPU_ERR_OUT_OF_MEMORY; - goto error; - } - - propval->prop = dbpropval->prop; - dbpropval->prop = 0; - - propval->val = dbpropval->val; - dbpropval->val = 0; - - rv = ldapu_list_add_info(propval_list, propval); - - if (rv != LDAPU_SUCCESS) { - goto error; - } - - dbpropval = dbpropval->next; - } - - certinfo->propval = propval_list; - } - - *certinfo_out = certinfo; - goto done; - -error: - if (propval_list) - ldapu_propval_list_free(propval_list); - if (certinfo) - free(certinfo); - -done: - return rv; -} - -static int -ldapu_binary_cmp_certs(void *subject_cert, - void *entry_cert_binary, - unsigned long entry_cert_len) -{ - SECItem derCert = ((CERTCertificate *)subject_cert)->derCert; - int rv; - - /* binary compare the two certs */ - if (derCert.len == entry_cert_len && - !memcmp(derCert.data, entry_cert_binary, entry_cert_len)) { - rv = LDAPU_SUCCESS; - } else { - rv = LDAPU_ERR_CERT_VERIFY_FAILED; - } - - return rv; -} - - -static int -ldapu_cert_verifyfn_default(void *subject_cert, LDAP *ld, void *certmap_info __attribute__((unused)), LDAPMessage *res, LDAPMessage **entry_out) -{ - LDAPMessage *entry; - struct berval **bvals; - int i; - int rv = LDAPU_ERR_CERT_VERIFY_FAILED; - char *cert_attr = ldapu_strings[LDAPU_STR_ATTR_CERT]; - char *cert_attr_nosubtype = ldapu_strings[LDAPU_STR_ATTR_CERT_NOSUBTYPE]; - - *entry_out = 0; - - for (entry = ldapu_first_entry(ld, res); entry != NULL; - entry = ldapu_next_entry(ld, entry)) { - if (((bvals = ldapu_get_values_len(ld, entry, cert_attr)) == NULL) && - ((bvals = ldapu_get_values_len(ld, entry, cert_attr_nosubtype)) == NULL)) { - rv = LDAPU_ERR_CERT_VERIFY_NO_CERTS; - continue; - } - - for (i = 0; bvals[i] != NULL; i++) { - rv = ldapu_binary_cmp_certs(subject_cert, - bvals[i]->bv_val, - bvals[i]->bv_len); - - if (rv == LDAPU_SUCCESS) { - break; - } - } - - ldapu_value_free_len(ld, bvals); - - if (rv == LDAPU_SUCCESS) { - *entry_out = entry; - break; - } - } - - return rv; -} - -static int -parse_into_bitmask(const char *comps_in, long *bitmask_out, long default_val) -{ - long bitmask; - char *comps = comps_in ? strdup(comps_in) : 0; - - if (!comps) { - /* Not present in the config file */ - bitmask = default_val; - } else if (!*comps) { - /* present but empty */ - bitmask = 0; - } else { - char *ptr = comps; - char *name = comps; - long bit; - int break_loop = 0; - - bitmask = 0; - - while (*name) { - /* advance ptr to delimeter */ - while (*ptr && !isspace(*ptr) && *ptr != ',') - ptr++; - - if (!*ptr) - break_loop = 1; - else - *ptr++ = 0; - - bit = certmap_name_to_bit_pos(name); - bitmask |= bit; - - if (break_loop) - break; - /* skip delimeters */ - while (*ptr && (isspace(*ptr) || *ptr == ',')) - ptr++; - name = ptr; - } - } - - if (comps) - free(comps); - *bitmask_out = bitmask; - /* print_oid_bitmask(bitmask); */ - return LDAPU_SUCCESS; -} - -static int -process_certinfo(LDAPUCertMapInfo_t *certinfo) -{ - int rv = LDAPU_SUCCESS; - char *dncomps = 0; - char *filtercomps = 0; - char *libname = 0; - char *verify = 0; - char *fname = 0; - char *searchAttr = 0; - - if (!ldapu_strcasecmp(certinfo->issuerName, "default")) { - default_certmap_info = certinfo; - } else if (!certinfo->issuerDN) { - return LDAPU_ERR_NO_ISSUERDN_IN_CONFIG_FILE; - } else { - rv = ldapu_list_add_info(certmap_listinfo, certinfo); - } - - if (rv != LDAPU_SUCCESS) - return rv; - - /* look for dncomps property and parse it into the dncomps bitmask */ - rv = ldapu_certmap_info_attrval(certinfo, LDAPU_ATTR_DNCOMPS, &dncomps); - - if (rv == LDAPU_SUCCESS && dncomps) { - certinfo->dncompsState = COMPS_HAS_ATTRS; - tolower_string(dncomps); - } else if (rv == LDAPU_FAILED) { - certinfo->dncompsState = COMPS_COMMENTED_OUT; - rv = LDAPU_SUCCESS; - } else if (rv == LDAPU_SUCCESS && !dncomps) { - certinfo->dncompsState = COMPS_EMPTY; - dncomps = strdup(""); /* present but empty */ - } - - rv = parse_into_bitmask(dncomps, &certinfo->dncomps, -1); - - free(dncomps); - dncomps = NULL; - - if (rv != LDAPU_SUCCESS) - return rv; - - /* look for filtercomps property and parse it into the filtercomps bitmask */ - rv = ldapu_certmap_info_attrval(certinfo, LDAPU_ATTR_FILTERCOMPS, - &filtercomps); - - if (rv == LDAPU_SUCCESS && filtercomps) { - certinfo->filtercompsState = COMPS_HAS_ATTRS; - tolower_string(filtercomps); - } else if (rv == LDAPU_FAILED) { - certinfo->filtercompsState = COMPS_COMMENTED_OUT; - rv = LDAPU_SUCCESS; - } else if (rv == LDAPU_SUCCESS && !filtercomps) { - certinfo->filtercompsState = COMPS_EMPTY; - filtercomps = strdup(""); /* present but empty */ - } - - rv = parse_into_bitmask(filtercomps, &certinfo->filtercomps, 0); - - free(filtercomps); - filtercomps = NULL; - - if (rv != LDAPU_SUCCESS) - return rv; - - /* look for "CmapLdapAttr" property and store it into searchAttr */ - rv = ldapu_certmap_info_attrval(certinfo, LDAPU_ATTR_CERTMAP_LDAP_ATTR, - &searchAttr); - - if (rv == LDAPU_FAILED || !searchAttr) { - rv = LDAPU_SUCCESS; - } else { - certinfo->searchAttr = searchAttr; - - if (searchAttr && !certinfo->searchAttr) - rv = LDAPU_ERR_OUT_OF_MEMORY; - else - rv = LDAPU_SUCCESS; - } - - if (rv != LDAPU_SUCCESS) - return rv; - - /* look for verifycert property and set the default verify function */ - /* The value of the verifycert property is ignored */ - rv = ldapu_certmap_info_attrval(certinfo, LDAPU_ATTR_VERIFYCERT, &verify); - - if (rv == LDAPU_SUCCESS) { - if (!ldapu_strcasecmp(verify, "on")) - certinfo->verifyCert = 1; - else if (!ldapu_strcasecmp(verify, "off")) - certinfo->verifyCert = 0; - else if (!verify || !*verify) /* for mail/news backward compatibilty */ - certinfo->verifyCert = 1; /* otherwise, this should be an error */ - else - rv = LDAPU_ERR_MISSING_VERIFYCERT_VAL; - } else if (rv == LDAPU_FAILED) - rv = LDAPU_SUCCESS; - - if (verify) - free(verify); - - if (rv != LDAPU_SUCCESS) - return rv; - - { - PRLibrary *lib = 0; - - /* look for the library property and load it */ - rv = ldapu_certmap_info_attrval(certinfo, LDAPU_ATTR_LIBRARY, &libname); - - if (rv == LDAPU_SUCCESS) { - if (libname && *libname) { - lib = PR_LoadLibrary(libname); - if (!lib) - rv = LDAPU_ERR_UNABLE_TO_LOAD_PLUGIN; - } else { - rv = LDAPU_ERR_MISSING_LIBNAME; - } - } else if (rv == LDAPU_FAILED) - rv = LDAPU_SUCCESS; - - if (libname) - free(libname); - if (rv != LDAPU_SUCCESS) - return rv; - - /* look for the InitFn property, find it in the libray and call it */ - rv = ldapu_certmap_info_attrval(certinfo, LDAPU_ATTR_INITFN, &fname); - - if (rv == LDAPU_SUCCESS) { - if (fname && *fname) { - /* If lib is NULL, PR_FindSymbol will search all libs loaded - * through PR_LoadLibrary. - */ - CertMapInitFn_t fn = (CertMapInitFn_t)PR_FindSymbol(lib, fname); - - if (!fn) { - rv = LDAPU_ERR_MISSING_INIT_FN_IN_LIB; - } else { - rv = (*fn)(certinfo, certinfo->issuerName, - certinfo->issuerDN, this_dllname); - } - } else { - rv = LDAPU_ERR_MISSING_INIT_FN_NAME; - } - } else if (lib) { - /* If library is specified, init function must be specified */ - /* If init fn is specified, library may not be specified */ - rv = LDAPU_ERR_MISSING_INIT_FN_IN_CONFIG; - } else if (rv == LDAPU_FAILED) { - rv = LDAPU_SUCCESS; - } - - if (fname) - free(fname); - - if (rv != LDAPU_SUCCESS) - return rv; - } - - return rv; -} - -/* This function will read multiple certmap directives and set the information - * in the global certmap_listinfo structure. - */ -int -certmap_read_certconfig_file(const char *file) -{ - DBConfInfo_t *conf_info = 0; - int rv; - - /* Read the config file */ - rv = dbconf_read_config_file_sub(file, LIB_DIRECTIVE, LIB_DIRECTIVE_LEN, - &conf_info); - - /* Convert the conf_info into certmap_listinfo. Some of the - * sub-structures are simply hijacked rather than copied since we are - * going to (carefully) free the conf_info anyway. - */ - - if (rv == LDAPU_SUCCESS && conf_info) { - DBConfDBInfo_t *nextdb; - DBConfDBInfo_t *curdb; - LDAPUCertMapInfo_t *certinfo; - - curdb = conf_info->firstdb; - - while (curdb) { - nextdb = curdb->next; - rv = dbinfo_to_certinfo(curdb, &certinfo); - - if (rv != LDAPU_SUCCESS) { - dbconf_free_confinfo(conf_info); - return rv; - } - - rv = process_certinfo(certinfo); - - if (rv != LDAPU_SUCCESS) { - dbconf_free_confinfo(conf_info); - return rv; - } - - curdb = nextdb; - } - - dbconf_free_confinfo(conf_info); - } else { - rv = dbconf_to_certmap_err(rv); - } - - return rv; -} - -/* This function will read the "certmap default" directive from the config - * file and set the information in the global certmap_info. - */ -int -certmap_read_default_certinfo(const char *file) -{ - DBConfDBInfo_t *db_info = 0; - int rv; - - rv = dbconf_read_default_dbinfo_sub(file, LIB_DIRECTIVE, LIB_DIRECTIVE_LEN, - &db_info); - - if (rv != LDAPU_SUCCESS) - return rv; - - rv = dbinfo_to_certinfo(db_info, &default_certmap_info); - - dbconf_free_dbinfo(db_info); - return rv; -} - -static int -ldapu_cert_searchfn_default(void *cert, LDAP *ld, void *certmap_info_in, const char *basedn, const char *dn, const char *filter, const char **attrs, LDAPMessage ***res) -{ - int rv = LDAPU_FAILED; - const char *ldapdn; - LDAPUCertMapInfo_t *certmap_info = (LDAPUCertMapInfo_t *)certmap_info_in; - LDAPMessage *single_res = NULL; - LDAPMessage **multiple_res = NULL; - - - if (certmap_info && certmap_info->searchAttr) { - char *subjectDN = 0; - char *certFilter = 0; - int len; - - rv = ldapu_get_cert_subject_dn(cert, &subjectDN); - - if (rv != LDAPU_SUCCESS || !subjectDN) { - return rv; - } - len = strlen(certmap_info->searchAttr) + strlen(subjectDN) + - strlen("=") + 1; - certFilter = (char *)ldapu_malloc(len * sizeof(char)); - if (!certFilter) { - free(subjectDN); - return LDAPU_ERR_OUT_OF_MEMORY; - } - sprintf(certFilter, "%s=%s", certmap_info->searchAttr, subjectDN); - free(subjectDN); - if (ldapu_strcasecmp(basedn, "")) { - rv = ldapu_find(ld, basedn, LDAP_SCOPE_SUBTREE, certFilter, attrs, 0, &single_res); - ldapu_free((void *)certFilter); - if (rv == LDAPU_SUCCESS || rv == LDAPU_ERR_MULTIPLE_MATCHES) { - *res = (LDAPMessage **)ldapu_malloc(2 * sizeof(LDAPMessage *)); - (*res)[0] = single_res; - (*res)[1] = NULL; - return rv; - } else if (single_res) { - ldapu_msgfree(ld, single_res); - single_res = 0; - } - } else { - rv = ldapu_find_entire_tree(ld, LDAP_SCOPE_SUBTREE, certFilter, attrs, 0, &multiple_res); - ldapu_free((void *)certFilter); - if (rv == LDAPU_SUCCESS || rv == LDAPU_ERR_MULTIPLE_MATCHES) { - *res = multiple_res; - return rv; - } else if (multiple_res) { - int n; - for (n = 0; multiple_res[n] != NULL; n++) - ldapu_msgfree(ld, multiple_res[n]); - ldapu_memfree(ld, multiple_res); - } - } - } - - if (dn && *dn) { - /* First do the base level search --- NOT ANY MORE!! */ - /* We actually do the search on the whole subtree hanging from "ldapdn" since we want to - * find all the entries that match the filter. - * If we get more than one matching entry in return, it'll be at verify time that we'll - * choose the correct one among them all. - * However, if certificate verify is not active, certificate mapping will fail and will - * consequently display an error message (something done at 'handle_handshake_done' level, - * for instance). */ - ldapdn = dn; - - if (ldapu_strcasecmp(ldapdn, "")) { - rv = ldapu_find(ld, ldapdn, LDAP_SCOPE_SUBTREE, filter, attrs, 0, &single_res); - if (rv == LDAPU_SUCCESS || rv == LDAPU_ERR_MULTIPLE_MATCHES) { - *res = (LDAPMessage **)ldapu_malloc(2 * sizeof(LDAPMessage *)); - (*res)[0] = single_res; - (*res)[1] = NULL; - return rv; - } else if (single_res) { - ldapu_msgfree(ld, single_res); - single_res = 0; - } - } else { - rv = ldapu_find_entire_tree(ld, LDAP_SCOPE_SUBTREE, filter, attrs, 0, &multiple_res); - if (rv == LDAPU_SUCCESS || rv == LDAPU_ERR_MULTIPLE_MATCHES) { - *res = multiple_res; - return rv; - } else if (multiple_res) { - int n; - for (n = 0; multiple_res[n] != NULL; n++) - ldapu_msgfree(ld, multiple_res[n]); - ldapu_memfree(ld, multiple_res); - } - } - } else { - /* default the dn and filter for subtree search */ - ldapdn = basedn; - if (!filter || !*filter) { - if (certmap_info && certmap_info->searchAttr) { - /* dn & filter returned by the mapping function are both NULL - and 'searchAttr' based search has failed. Don't do brute - force search if 'searchAttr' is being used. Otherwise, - this search will result in all LDAP entries being - returned. - */ - } else { - filter = "objectclass=*"; - } - } - } - - /* For local LDAP DB, the LDAP_SCOPE_BASE search may fail for dn == basedn - * since that object doesn't actually exists. - */ - if ((rv == LDAPU_FAILED || rv == LDAP_NO_SUCH_OBJECT) && filter && (!dn || !*dn)) { - - /* Try the subtree search only if the filter is non-NULL */ - if (ldapu_strcasecmp(ldapdn, "")) { - rv = ldapu_find(ld, ldapdn, LDAP_SCOPE_SUBTREE, filter, 0, 0, &single_res); - if (rv == LDAPU_SUCCESS || rv == LDAPU_ERR_MULTIPLE_MATCHES) { - *res = (LDAPMessage **)ldapu_malloc(2 * sizeof(LDAPMessage *)); - (*res)[0] = single_res; - (*res)[1] = NULL; - return rv; - } else if (single_res) { - ldapu_msgfree(ld, single_res); - single_res = 0; - } - } else { - rv = ldapu_find_entire_tree(ld, LDAP_SCOPE_SUBTREE, filter, 0, 0, &multiple_res); - if (rv == LDAPU_SUCCESS || rv == LDAPU_ERR_MULTIPLE_MATCHES) { - *res = multiple_res; - return rv; - } else if (multiple_res) { - int n; - for (n = 0; multiple_res[n] != NULL; n++) - ldapu_msgfree(ld, multiple_res[n]); - ldapu_memfree(ld, multiple_res); - } - } - } - - if (rv == LDAPU_FAILED) { - /* Not an error but couldn't map the cert */ - rv = LDAPU_ERR_MAPPED_ENTRY_NOT_FOUND; - } else if ((!dn || !*dn) && (rv == LDAP_NO_SUCH_OBJECT)) { - rv = LDAPU_ERR_INVALID_SUFFIX; - } - - return rv; -} - -NSAPI_PUBLIC int -ldapu_issuer_certinfo(const char *issuerDN, void **certmap_info) -{ - *certmap_info = 0; - - if (!issuerDN || !*issuerDN || !ldapu_strcasecmp(issuerDN, "default")) { - *certmap_info = default_certmap_info; - } else if (certmap_listinfo) { - char *n_issuerDN = ldapu_dn_normalize(ldapu_strdup(issuerDN)); - LDAPUListNode_t *cur = certmap_listinfo->head; - while (cur) { - if (!ldapu_strcasecmp(n_issuerDN, ((LDAPUCertMapInfo_t *)cur->info)->issuerDN)) { - *certmap_info = cur->info; - break; - } - cur = cur->next; - } - if (n_issuerDN) - ldapu_free(n_issuerDN); - } - return *certmap_info ? LDAPU_SUCCESS : LDAPU_FAILED; -} - -NSAPI_PUBLIC int -ldapu_certmap_info_attrval(void *certmap_info_in, - const char *attr, - char **val) -{ - /* Look for given attr in the certmap_info and return its value */ - LDAPUCertMapInfo_t *certmap_info = (LDAPUCertMapInfo_t *)certmap_info_in; - LDAPUListNode_t *curprop = certmap_info->propval ? certmap_info->propval->head : 0; - LDAPUPropVal_t *propval; - int rv = LDAPU_FAILED; - - *val = 0; - while (curprop) { - propval = (LDAPUPropVal_t *)curprop->info; - if (!ldapu_strcasecmp(propval->prop, attr)) { - *val = propval->val ? strdup(propval->val) : 0; - rv = LDAPU_SUCCESS; - break; - } - curprop = curprop->next; - } - - return rv; -} - -static int -AddAVAToBuf(char *buf, int size, int *len, const char *tagName, CERTAVA *ava) -{ - int lenLen; - int taglen; - SECStatus rv; - - buf += *len; - - /* Copied from ns/lib/libsec ... - * XXX this code is incorrect in general - * -- should use a DER template. - */ - lenLen = 2; - if (ava->value.len >= 128) - lenLen = 3; - - taglen = PL_strlen(tagName); - memcpy(buf, tagName, taglen); - buf[taglen++] = '='; - - rv = CERT_RFC1485_EscapeAndQuote(buf + taglen, - size - taglen, - (char *)ava->value.data + lenLen, - ava->value.len - lenLen); - - *len += strlen(buf); - - return (rv == SECSuccess ? LDAPU_SUCCESS : LDAPU_FAILED); -} - -static int -AddToLdapDN(char *ldapdn, int size, int *dnlen, const char *tagName, CERTAVA *ava) -{ - char *dn = ldapdn + *dnlen; - - if (*dnlen) { - strcat(dn, ", "); - dn += 2; - *dnlen += 2; - } - return AddAVAToBuf(ldapdn, size, dnlen, tagName, ava); -} - -static int -AddToFilter(char *filter, int size, int *flen, const char *tagName, CERTAVA *ava) -{ - int rv; - - /* Append opening parenthesis */ - strcat(filter + *flen, " ("); - *flen += 2; - rv = AddAVAToBuf(filter, size, flen, tagName, ava); - - if (rv != LDAPU_SUCCESS) - return rv; - - /* Append closing parenthesis */ - strcat(filter + *flen, ")"); - (*flen)++; - - return rv; -} - -NSAPI_PUBLIC int -ldapu_free_cert_ava_val(char **val) -{ - char **ptr = val; - - if (!val) - return LDAPU_SUCCESS; - - while (*ptr) - free(*ptr++); - free(val); - - return LDAPU_SUCCESS; -} - -static int -ldapu_cert_mapfn_default(void *cert_in, LDAP *ld __attribute__((unused)), void *certmap_info_in, char **ldapDN_out, char **filter_out) -{ - CERTCertificate *cert = (CERTCertificate *)cert_in; - LDAPUCertMapInfo_t *certmap_info = (LDAPUCertMapInfo_t *)certmap_info_in; - int rv = LDAPU_SUCCESS; - - *ldapDN_out = *filter_out = 0; - - if (!certmap_info) { - /* Use subject DN as is -- identity mapping function */ - rv = ldapu_get_cert_subject_dn(cert, ldapDN_out); - - return rv; - } else { - /* - * Iterate over rdns from the subject and collect AVAs depending on - * dnComps and filtercomps to form ldapDN and filter respectively. - * certmap_info->dncomps - */ - CERTName *subject = &cert->subject; - CERTRDN **rdns = subject->rdns; - CERTRDN **lastRdn; - CERTRDN **rdn; - CERTAVA **avas; - CERTAVA *ava; - char ldapdn[BIG_LINE]; - char filter[BIG_LINE]; - int dnlen = 0; /* ldap DN length */ - int flen = 0; /* filter length */ - int numfavas = 0; /* no of avas added to filter */ - - if (rdns == NULL) { - /* error */ - return LDAPU_ERR_INTERNAL; - } - - /* find last RDN */ - lastRdn = rdns; - while (*lastRdn) - lastRdn++; - lastRdn--; - - /* Initialize filter to "(&" */ - strcpy(filter, "(&"); - flen = 2; - - /* - * Loop over subject rdns in the _reverse_ order while forming ldapDN - * and filter. - */ - for (rdn = lastRdn; rdn >= rdns; rdn--) { - avas = (*rdn)->avas; - while ((ava = *avas++) != NULL) { - int tag = CERT_GetAVATag(ava); - const char *tagName = certmap_secoid_to_name(tag); - - if (PresentInComps(certmap_info->dncomps, tag)) { - rv = AddToLdapDN(ldapdn, BIG_LINE, &dnlen, tagName, ava); - if (rv != LDAPU_SUCCESS) - return rv; - } - - if (PresentInComps(certmap_info->filtercomps, tag)) { - rv = AddToFilter(filter, BIG_LINE, &flen, tagName, ava); - if (rv != LDAPU_SUCCESS) - return rv; - numfavas++; - } - } - } - - if (numfavas == 0) { - /* nothing added to filter */ - *filter = 0; - } else if (numfavas == 1) { - /* one ava added to filter -- remove "(& (" from the front and ")" - * from the end. - */ - *filter_out = strdup(filter + 4); - if (!*filter_out) - return LDAPU_ERR_OUT_OF_MEMORY; - (*filter_out)[strlen(*filter_out) - 1] = 0; - } else { - /* Add the closing parenthesis to filter */ - strcat(filter + flen, ")"); - *filter_out = strdup(filter); - } - - if (dnlen >= BIG_LINE) - return LDAPU_FAILED; - ldapdn[dnlen] = 0; - *ldapDN_out = *ldapdn ? strdup(ldapdn) : 0; - - if ((numfavas && !*filter_out) || (dnlen && !*ldapDN_out)) { - /* strdup failed */ - return LDAPU_ERR_OUT_OF_MEMORY; - } - - if ((certmap_info->dncompsState == COMPS_HAS_ATTRS && dnlen == 0) || - (certmap_info->filtercompsState == COMPS_HAS_ATTRS && - numfavas == 0)) { - /* At least one attr in DNComps should be present in the cert */ - /* Same is true for FilterComps */ - rv = LDAPU_ERR_MAPPED_ENTRY_NOT_FOUND; - } - } - - return rv; -} - -NSAPI_PUBLIC int -ldapu_set_cert_mapfn(const char *issuerDN, - CertMapFn_t mapfn) -{ - LDAPUCertMapInfo_t *certmap_info; - int rv; - - /* don't free the certmap_info -- its a pointer to an internal structure */ - rv = ldapu_issuer_certinfo(issuerDN, (void **)&certmap_info); - - /* Don't set the mapping function if certmap_info doesen't exist */ - if (rv != LDAPU_SUCCESS) - return rv; - - certmap_info->mapfn = mapfn; - return LDAPU_SUCCESS; -} - -static CertMapFn_t -ldapu_get_cert_mapfn_sub(LDAPUCertMapInfo_t *certmap_info) -{ - CertMapFn_t mapfn; - - if (certmap_info && certmap_info->mapfn) - mapfn = certmap_info->mapfn; - else if (default_certmap_info && default_certmap_info->mapfn) - mapfn = default_certmap_info->mapfn; - else - mapfn = ldapu_cert_mapfn_default; - - return mapfn; -} - -NSAPI_PUBLIC CertMapFn_t -ldapu_get_cert_mapfn(const char *issuerDN) -{ - LDAPUCertMapInfo_t *certmap_info = 0; - - /* don't free the certmap_info -- its a pointer to an internal structure */ - ldapu_issuer_certinfo(issuerDN, (void **)&certmap_info); - /* certmap_info may be NULL -- use the default */ - - return ldapu_get_cert_mapfn_sub(certmap_info); -} - -NSAPI_PUBLIC int -ldapu_set_cert_searchfn(const char *issuerDN, - CertSearchFn_t searchfn) -{ - LDAPUCertMapInfo_t *certmap_info; - int rv; - - /* don't free the certmap_info -- its a pointer to an internal structure */ - rv = ldapu_issuer_certinfo(issuerDN, (void **)&certmap_info); - - /* Don't set the mapping function if certmap_info doesen't exist */ - if (rv != LDAPU_SUCCESS) - return rv; - - certmap_info->searchfn = searchfn; - return LDAPU_SUCCESS; -} - -static CertSearchFn_t -ldapu_get_cert_searchfn_sub(LDAPUCertMapInfo_t *certmap_info) -{ - CertSearchFn_t searchfn; - - if (certmap_info && certmap_info->searchfn) - searchfn = certmap_info->searchfn; - else if (default_certmap_info && default_certmap_info->searchfn) - searchfn = default_certmap_info->searchfn; - else - searchfn = ldapu_cert_searchfn_default; - - return searchfn; -} - -NSAPI_PUBLIC CertSearchFn_t -ldapu_get_cert_searchfn(const char *issuerDN) -{ - LDAPUCertMapInfo_t *certmap_info = 0; - - /* don't free the certmap_info -- its a pointer to an internal structure */ - ldapu_issuer_certinfo(issuerDN, (void **)&certmap_info); - /* certmap_info may be NULL -- use the default */ - - return ldapu_get_cert_searchfn_sub(certmap_info); -} - -NSAPI_PUBLIC int -ldapu_set_cert_verifyfn(const char *issuerDN, - CertVerifyFn_t verifyfn) -{ - LDAPUCertMapInfo_t *certmap_info; - int rv; - - /* don't free the certmap_info -- its a pointer to an internal structure */ - rv = ldapu_issuer_certinfo(issuerDN, (void **)&certmap_info); - - /* Don't set the verify function if certmap_info doesen't exist */ - if (rv != LDAPU_SUCCESS) - return rv; - - certmap_info->verifyfn = verifyfn; - return LDAPU_SUCCESS; -} - -static CertVerifyFn_t -ldapu_get_cert_verifyfn_sub(LDAPUCertMapInfo_t *certmap_info) -{ - CertVerifyFn_t verifyfn; - - if (certmap_info && certmap_info->verifyfn) - verifyfn = certmap_info->verifyfn; - else if (default_certmap_info && default_certmap_info->verifyfn) - verifyfn = default_certmap_info->verifyfn; - else - verifyfn = ldapu_cert_verifyfn_default; - - return verifyfn; -} - -NSAPI_PUBLIC CertVerifyFn_t -ldapu_get_cert_verifyfn(const char *issuerDN) -{ - LDAPUCertMapInfo_t *certmap_info = 0; - - /* don't free the certmap_info -- its a pointer to an internal structure */ - ldapu_issuer_certinfo(issuerDN, (void **)&certmap_info); - /* certmap_info may be NULL -- use the default */ - - return ldapu_get_cert_verifyfn_sub(certmap_info); -} - -#if 0 /* may need this in the future */ -static int ldapu_certinfo_copy (const LDAPUCertMapInfo_t *from, - const char *newIssuerName, - const char *newIssuerDN, - LDAPUCertMapInfo_t *to) -{ - /* This function is not tested and is not used */ - int rv; - - to->issuerName = newIssuerName ? strdup(newIssuerName) : 0; - to->issuerDN = newIssuerDN ? strdup(newIssuerDN) : 0; - if (from->propval) { - rv = ldapu_list_copy(from->propval, &to->propval, ldapu_propval_copy); - if (rv != LDAPU_SUCCESS) return rv; - } - else { - to->propval = 0; - } - - return process_certinfo(to); -} -#endif - -NSAPI_PUBLIC int -ldapu_cert_to_ldap_entry(void *cert, LDAP *ld, const char *basedn, LDAPMessage **res) -{ - char *issuerDN = 0; - char *ldapDN = 0; - char *filter = 0; - LDAPUCertMapInfo_t *certmap_info; - LDAPMessage **res_array = NULL; - CertMapFn_t mapfn; - CertVerifyFn_t verifyfn; - CertSearchFn_t searchfn; - int rv, i, j; - - *res = 0; - - if (!certmap_attrs[0]) { - /* Initialize certmap_attrs */ - certmap_attrs[0] = ldapu_strings[LDAPU_STR_ATTR_USER]; - certmap_attrs[1] = ldapu_strings[LDAPU_STR_ATTR_CERT]; - certmap_attrs[2] = ldapu_strings[LDAPU_STR_ATTR_CERT_NOSUBTYPE]; - certmap_attrs[3] = 0; - } - - rv = ldapu_get_cert_issuer_dn(cert, &issuerDN); - - if (rv != LDAPU_SUCCESS) - return LDAPU_ERR_NO_ISSUERDN_IN_CERT; - - /* don't free the certmap_info -- its a pointer to an internal structure */ - rv = ldapu_issuer_certinfo(issuerDN, (void **)&certmap_info); - free(issuerDN); - - if (!certmap_info) - certmap_info = default_certmap_info; - - /* Get the mapping function from the certmap_info */ - mapfn = ldapu_get_cert_mapfn_sub(certmap_info); - - rv = (*mapfn)(cert, ld, certmap_info, &ldapDN, &filter); - - if (rv != LDAPU_SUCCESS) - return rv; - - /* Get the search function from the certmap_info - certinfo maybe NULL */ - searchfn = ldapu_get_cert_searchfn_sub(certmap_info); - - rv = (*searchfn)(cert, ld, certmap_info, basedn, ldapDN, filter, - certmap_attrs, &res_array); - - if (ldapDN) - free(ldapDN); - if (filter) - free(filter); - - /* - * Get the verify cert function & call it. - */ - j = 0; - if ((rv == LDAPU_SUCCESS || rv == LDAPU_ERR_MULTIPLE_MATCHES) && - (certmap_info ? certmap_info->verifyCert : 0)) { - verifyfn = ldapu_get_cert_verifyfn_sub(certmap_info); - - if (verifyfn) { - int verify_rv; - - i = 0; - do { - LDAPMessage *entry; - verify_rv = (*verifyfn)(cert, ld, certmap_info, res_array[i], &entry); - - if (rv == LDAPU_ERR_MULTIPLE_MATCHES) { - if (verify_rv == LDAPU_SUCCESS) { - /* 'entry' points to the matched entry */ - /* Get the 'res' which only contains this entry */ - char *dn = ldapu_get_dn(ld, entry); - if (*res) - ldapu_msgfree(ld, *res); - rv = ldapu_find(ld, dn, LDAP_SCOPE_BASE, 0, certmap_attrs, 0, res); - ldapu_memfree(ld, dn); - } else { - /* Verify failed for multiple matches -- keep rv */ - /* multiple matches err is probably more interesting to - the caller then any other error returned by the verify - fn */ - } - } else /* rv == LDAPU_SUCCESS */ { - if (verify_rv == LDAPU_SUCCESS) { - *res = res_array[0]; - j = 1; - } else { - rv = verify_rv; - } - } - } while ((verify_rv != LDAPU_SUCCESS) && (res_array[++i] != NULL)); - } - } else { - if (rv == LDAPU_SUCCESS) { - *res = res_array[0]; - j = 1; - } - } - - - if (rv != LDAPU_SUCCESS) { - if (*res) { - ldapu_msgfree(ld, *res); - *res = 0; - } - } - - i = j; /* ugaston - if the search had been successful, despite verifyCert being "off", - * mapping is considered successful, so we keep the first (and only) response message. - * If, on the other hand, the search had returned multiple matches, the fact - * of having verifyCert "off" automatically turns the mapping faulty, so we - * don't need to care about keeping any response at all. - */ - - if (res_array) { - while (res_array[i] != NULL) { - ldapu_msgfree(ld, res_array[i]); - res_array[i++] = 0; - } - ldapu_memfree(ld, res_array); - } - return rv; -} - -/* The caller shouldn't free the entry */ -NSAPI_PUBLIC int -ldapu_cert_to_user(void *cert, LDAP *ld, const char *basedn, LDAPMessage **res_out, char **user) -{ - int rv; - LDAPMessage *res; - LDAPMessage *entry; - int numEntries; - char **attrVals = NULL; - - *res_out = 0; - *user = 0; - - rv = ldapu_cert_to_ldap_entry(cert, ld, basedn, &res); - - if (rv != LDAPU_SUCCESS) { - goto done; - } - - if (!res) { - rv = LDAPU_ERR_EMPTY_LDAP_RESULT; - goto done; - } - - /* Extract user login (the 'uid' attr) from 'res' */ - numEntries = ldapu_count_entries(ld, res); - - if (numEntries != 1) { - rv = LDAPU_ERR_MULTIPLE_MATCHES; - goto done; - } - - entry = ldapu_first_entry(ld, res); - - if (!entry) { - rv = LDAPU_ERR_MISSING_RES_ENTRY; - goto done; - } - - attrVals = ldapu_get_values(ld, entry, - ldapu_strings[LDAPU_STR_ATTR_USER]); - - if (!attrVals || !attrVals[0]) { - rv = LDAPU_ERR_MISSING_UID_ATTR; - goto done; - } - - *user = strdup(attrVals[0]); - - /* ldapu_msgfree(res); */ - - if (!*user) { - rv = LDAPU_ERR_OUT_OF_MEMORY; - goto done; - } - - *res_out = res; - -done: - if (attrVals) { - ldapu_value_free(ld, attrVals); - } - - return rv; -} - -static void * -ldapu_propval_free(void *propval_in, void *arg __attribute__((unused))) -{ - LDAPUPropVal_t *propval = (LDAPUPropVal_t *)propval_in; - - if (propval->prop) - free(propval->prop); - if (propval->val) - free(propval->val); - memset((void *)propval, 0, sizeof(LDAPUPropVal_t)); - free(propval); - return 0; -} - -void -ldapu_certinfo_free(void *info_in) -{ - LDAPUCertMapInfo_t *certmap_info = (LDAPUCertMapInfo_t *)info_in; - - if (certmap_info->issuerName) - free(certmap_info->issuerName); - if (certmap_info->issuerDN) - free(certmap_info->issuerDN); - if (certmap_info->propval) - ldapu_list_free(certmap_info->propval, ldapu_propval_free); - if (certmap_info->searchAttr) - free(certmap_info->searchAttr); - memset((void *)certmap_info, 0, sizeof(LDAPUCertMapInfo_t)); - free(certmap_info); -} - -static void * -ldapu_certinfo_free_helper(void *info, void *arg __attribute__((unused))) -{ - ldapu_certinfo_free(info); - return (void *)LDAPU_SUCCESS; -} - -void -ldapu_certmap_listinfo_free(void *_certmap_listinfo) -{ - LDAPUCertMapListInfo_t *list = (LDAPUCertMapListInfo_t *)_certmap_listinfo; - ldapu_list_free(list, ldapu_certinfo_free_helper); -} - -void -ldapu_propval_list_free(void *propval_list) -{ - LDAPUPropValList_t *list = (LDAPUPropValList_t *)propval_list; - ldapu_list_free(list, ldapu_propval_free); - free(list); -} - -int -ldapu_certmap_init(const char *config_file, - const char *dllname, - LDAPUCertMapListInfo_t **certmap_list, - LDAPUCertMapInfo_t **certmap_default) -{ - int rv; - certmap_listinfo = (LDAPUCertMapListInfo_t *)calloc(1, sizeof(LDAPUCertMapListInfo_t)); - - *certmap_list = 0; - *certmap_default = 0; - PR_snprintf(this_dllname, sizeof(this_dllname), "%s", dllname); - - if (!certmap_listinfo) - return LDAPU_ERR_OUT_OF_MEMORY; - - rv = certmap_read_certconfig_file(config_file); - - if (rv == LDAPU_SUCCESS) { - *certmap_list = certmap_listinfo; - *certmap_default = default_certmap_info; - } - - return rv; -} - -NSAPI_PUBLIC int -ldaputil_exit() -{ - if (default_certmap_info) { - ldapu_certinfo_free(default_certmap_info); - default_certmap_info = 0; - } - - if (certmap_listinfo) { - ldapu_certmap_listinfo_free(certmap_listinfo); - certmap_listinfo = 0; - } - - return LDAPU_SUCCESS; -} - - -NSAPI_PUBLIC void -ldapu_free(void *ptr) -{ - if (ptr) - free(ptr); -} - -NSAPI_PUBLIC void -ldapu_free_old(char *ptr) -{ - free((void *)ptr); -} - -NSAPI_PUBLIC void * -ldapu_malloc(int size) -{ - return malloc(size); -} - -NSAPI_PUBLIC char * -ldapu_strdup(const char *ptr) -{ - return strdup(ptr); -} - -NSAPI_PUBLIC void * -ldapu_realloc(void *ptr, int size) -{ - return realloc(ptr, size); -} - -#define DNSEPARATOR(c) (c == ',' || c == ';') -#define SEPARATOR(c) (c == ',' || c == ';' || c == '+') -#define SPACE(c) (c == ' ' || c == '\n') -#define NEEDSESCAPE(c) (c == '\\' || c == '"') -#define B4TYPE 0 -#define INTYPE 1 -#define B4EQUAL 2 -#define B4VALUE 3 -#define INVALUE 4 -#define INQUOTEDVALUE 5 -#define B4SEPARATOR 6 - -static char * -ldapu_dn_normalize(char *dn) -{ - char *d, *s; - int state, gotesc; - - gotesc = 0; - state = B4TYPE; - for (d = s = dn; *s; s++) { - switch (state) { - case B4TYPE: - if (!SPACE(*s)) { - state = INTYPE; - *d++ = *s; - } - break; - case INTYPE: - if (*s == '=') { - state = B4VALUE; - *d++ = *s; - } else if (SPACE(*s)) { - state = B4EQUAL; - } else { - *d++ = *s; - } - break; - case B4EQUAL: - if (*s == '=') { - state = B4VALUE; - *d++ = *s; - } else if (!SPACE(*s)) { - /* not a valid dn - but what can we do here? */ - *d++ = *s; - } - break; - case B4VALUE: - if (*s == '"') { - state = INQUOTEDVALUE; - *d++ = *s; - } else if (!SPACE(*s)) { - state = INVALUE; - *d++ = *s; - } - break; - case INVALUE: - if (!gotesc && SEPARATOR(*s)) { - while (SPACE(*(d - 1))) - d--; - state = B4TYPE; - if (*s == '+') { - *d++ = *s; - } else { - *d++ = ','; - } - } else if (gotesc && !NEEDSESCAPE(*s) && - !SEPARATOR(*s)) { - *--d = *s; - d++; - } else { - *d++ = *s; - } - break; - case INQUOTEDVALUE: - if (!gotesc && *s == '"') { - state = B4SEPARATOR; - *d++ = *s; - } else if (gotesc && !NEEDSESCAPE(*s)) { - *--d = *s; - d++; - } else { - *d++ = *s; - } - break; - case B4SEPARATOR: - if (SEPARATOR(*s)) { - state = B4TYPE; - if (*s == '+') { - *d++ = *s; - } else { - *d++ = ','; - } - } - break; - default: - break; - } - if (*s == '\\') { - gotesc = 1; - } else { - gotesc = 0; - } - } - *d = '\0'; - - /* Trim trailing spaces */ - d--; - while (d >= dn && *d == ' ') { - *d-- = '\0'; - } - - return (dn); -} diff --git a/lib/ldaputil/dbconf.c b/lib/ldaputil/dbconf.c deleted file mode 100644 index 76654e7..0000000 --- a/lib/ldaputil/dbconf.c +++ /dev/null @@ -1,686 +0,0 @@ -/** BEGIN COPYRIGHT BLOCK - * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. - * Copyright (C) 2005 Red Hat, Inc. - * All rights reserved. - * - * License: GPL (version 3 or any later version). - * See LICENSE for details. - * END COPYRIGHT BLOCK **/ - -#ifdef HAVE_CONFIG_H -#include -#endif - - -#include -/* This was malloc.h - but it's moved to stdlib.h on most platforms, and FBSD is strict */ -/* Make it stdlib.h, and revert to malloc.h with ifdefs if we have issues here. WB 2016 */ -#include -#include - -#include -#include -#include -#include - -#define BIG_LINE 1024 - -static const char *DB_DIRECTIVE = "directory"; -static const int DB_DIRECTIVE_LEN = 9; /* strlen("DB_DIRECTIVE") */ - -static const char *ENCODED = "encoded"; - -static void -insert_dbinfo_propval(DBConfDBInfo_t *db_info, - DBPropVal_t *propval) -{ - if (db_info->lastprop) { - db_info->lastprop->next = propval; - } else { - db_info->firstprop = propval; - } - - db_info->lastprop = propval; -} - -static void -insert_dbconf_dbinfo(DBConfInfo_t *conf_info, - DBConfDBInfo_t *db_info) -{ - if (conf_info->lastdb) { - conf_info->lastdb->next = db_info; - } else { - conf_info->firstdb = db_info; - } - - conf_info->lastdb = db_info; -} - -void -dbconf_free_propval(DBPropVal_t *propval) -{ - if (propval) { - if (propval->prop) - free(propval->prop); - if (propval->val) - free(propval->val); - memset((void *)propval, 0, sizeof(DBPropVal_t)); - free(propval); - } -} - -NSAPI_PUBLIC void -dbconf_free_dbinfo(DBConfDBInfo_t *db_info) -{ - if (db_info) { - DBPropVal_t *next; - DBPropVal_t *cur; - - if (db_info->dbname) - free(db_info->dbname); - if (db_info->url) - free(db_info->url); - - cur = db_info->firstprop; - - while (cur) { - next = cur->next; - dbconf_free_propval(cur); - cur = next; - } - - memset((void *)db_info, 0, sizeof(DBConfDBInfo_t)); - free(db_info); - } -} - -NSAPI_PUBLIC void -dbconf_free_confinfo(DBConfInfo_t *conf_info) -{ - DBConfDBInfo_t *next; - DBConfDBInfo_t *cur; - - if (conf_info) { - cur = conf_info->firstdb; - - while (cur) { - next = cur->next; - dbconf_free_dbinfo(cur); - cur = next; - } - - memset((void *)conf_info, 0, sizeof(DBConfInfo_t)); - free(conf_info); - } -} - -static int -skip_blank_lines_and_spaces(FILE *fp, char *buf, char **ptr_out, int *eof) -{ - char *ptr = buf; - char *end; - - while (buf && (*buf || fgets(buf, BIG_LINE, fp))) { - ptr = buf; - - /* skip leading whitespace */ - while (*ptr && isspace(*ptr)) - ++ptr; - - /* skip blank line or comment */ - if (!*ptr || *ptr == '#') { - *buf = 0; /* to force reading of next line */ - continue; - } - - /* Non-blank line found */ - break; - } - - *ptr_out = ptr; - if (!*ptr) { - *eof = 1; - } else { - /* skip trailing whitespace */ - end = ptr + strlen(ptr) - 1; - while (isspace(*end)) - *end-- = 0; - } - - return LDAPU_SUCCESS; -} - -static int -dbconf_parse_propval(char *buf, char *ptr, DBConfDBInfo_t *db_info) -{ - char *dbname = db_info->dbname; - int dbname_len = strlen(dbname); - char *prop; - char *val; - DBPropVal_t *propval; - char *delimeter_chars = " \t"; - char *lastchar; - int end_of_prop; - char *encval = 0; /* encoded value */ - char *origprop = 0; - - if ((ptr - buf + dbname_len > BIG_LINE) || - strncmp(ptr, dbname, dbname_len) || - !(ptr[dbname_len] == ':' || isspace(ptr[dbname_len]))) { - /* Not a prop-val for the current db but not an error */ - return LDAPU_ERR_NOT_PROPVAL; - } - - /* remove the last char if it is newline */ - lastchar = strrchr(buf, '\n'); - if (lastchar) - *lastchar = '\0'; - - prop = ptr + dbname_len + 1; - - while (*prop && (isspace(*prop) || *prop == ':')) - ++prop; - - if (!*prop) { - return LDAPU_ERR_PROP_IS_MISSING; - } - - end_of_prop = strcspn(prop, delimeter_chars); - - if (prop[end_of_prop] != '\0') { - /* buf doesn't end here -- val is present */ - prop[end_of_prop] = '\0'; - val = &prop[end_of_prop + 1]; - - while (*val && isspace(*val)) - ++val; - if (*val == '\0') - val = 0; - } else { - val = 0; - } - - /* - * The prop-val line could be one of the following: - * ":prop val" OR ":encoded prop encval" - * If (prop == "encoded") then the val has "prop encval". - * Get the actual prop from val and get encval (i.e. encoded value) - * and decode it. If it is encoded then the val part must be non-NULL. - */ - if (val && *val && !strcmp(prop, ENCODED)) { - /* val has the actual prop followed by the encoded value */ - origprop = prop; - prop = val; - while (*prop && (isspace(*prop) || *prop == ':')) - ++prop; - - if (!*prop) { - return LDAPU_ERR_PROP_IS_MISSING; - } - - end_of_prop = strcspn(prop, delimeter_chars); - - if (prop[end_of_prop] != '\0') { - /* buf doesn't end here -- encval is present */ - prop[end_of_prop] = '\0'; - encval = &prop[end_of_prop + 1]; - - while (*encval && isspace(*encval)) - ++encval; - if (*encval == '\0') - encval = 0; - } else { - encval = 0; - } - - if (!encval) { - /* special case - if encval is null, "encoded" itself is a - * property and what we have in prop now is the value. */ - val = prop; - prop = origprop; - } else { - /* decode the value */ - val = dbconf_decodeval(encval); - } - } - - /* Success - we have prop & val */ - propval = (DBPropVal_t *)malloc(sizeof(DBPropVal_t)); - - if (!propval) { - if (encval && val) - free(val); - return LDAPU_ERR_OUT_OF_MEMORY; - } - memset((void *)propval, 0, sizeof(DBPropVal_t)); - propval->prop = strdup(prop); - propval->val = val ? strdup(val) : 0; - - if (encval && val) - free(val); /* val was allocated by dbconf_decodeval */ - - if (!propval->prop || (val && !propval->val)) { - dbconf_free_propval(propval); - return LDAPU_ERR_OUT_OF_MEMORY; - } - - insert_dbinfo_propval(db_info, propval); - return LDAPU_SUCCESS; -} - -static int -dbconf_read_propval(FILE *fp, char *buf, DBConfDBInfo_t *db_info, int *eof) -{ - int rv; - char *ptr = buf; - - while (buf && (*buf || fgets(buf, BIG_LINE, fp))) { - ptr = buf; - - rv = skip_blank_lines_and_spaces(fp, buf, &ptr, eof); - - if (rv != LDAPU_SUCCESS || *eof) - return rv; - - /* We have a non-blank line which could be prop-val pair for the - * dbname in the db_info. parse the prop-val pair and continue. - */ - rv = dbconf_parse_propval(buf, ptr, db_info); - - if (rv == LDAPU_ERR_NOT_PROPVAL) - return LDAPU_SUCCESS; - if (rv != LDAPU_SUCCESS) - return rv; - - *buf = 0; /* to force reading of next line */ - } - - if (!*buf) - *eof = 1; - - return LDAPU_SUCCESS; -} - -static int -parse_directive(char *buf, const char *directive, const int directive_len, DBConfDBInfo_t **db_info_out) -{ - DBConfDBInfo_t *db_info; - char *dbname; - char *url; - int end_of_dbname; - char *delimeter_chars = " \t"; - char *lastchar; - - /* remove the last char if it is newline */ - lastchar = strrchr(buf, '\n'); - if (lastchar) - *lastchar = '\0'; - - if (strncmp(buf, directive, directive_len) || - !isspace(buf[directive_len])) { - return LDAPU_ERR_DIRECTIVE_IS_MISSING; - } - - dbname = buf + directive_len + 1; - - while (*dbname && isspace(*dbname)) - ++dbname; - - if (!*dbname) { - return LDAPU_ERR_DBNAME_IS_MISSING; - } - - end_of_dbname = strcspn(dbname, delimeter_chars); - - if (dbname[end_of_dbname] != '\0') { - /* buf doesn't end here -- url is present */ - dbname[end_of_dbname] = '\0'; - url = &dbname[end_of_dbname + 1]; - - while (*url && isspace(*url)) - ++url; - - if (*url == '\0') - url = 0; - } else { - url = 0; - } - - /* Success - we have dbname & url */ - db_info = (DBConfDBInfo_t *)malloc(sizeof(DBConfDBInfo_t)); - - if (!db_info) - return LDAPU_ERR_OUT_OF_MEMORY; - memset((void *)db_info, 0, sizeof(DBConfDBInfo_t)); - db_info->dbname = strdup(dbname); - db_info->url = url ? strdup(url) : 0; - - if (!db_info->dbname || (url && !db_info->url)) { - dbconf_free_dbinfo(db_info); - return LDAPU_ERR_OUT_OF_MEMORY; - } - - *db_info_out = db_info; - return LDAPU_SUCCESS; -} - -/* Read the next database info from the file and put it in db_info_out. The - * buf may contain first line of the database info. When this function - * finishes, the buf may contain unprocessed information (which should be - * passed to the next call to read_db_info). - */ -static int -read_db_info(FILE *fp, char *buf, DBConfDBInfo_t **db_info_out, const char *directive, const int directive_len, int *eof) -{ - char *ptr; - DBConfDBInfo_t *db_info; - int rv; - - *db_info_out = 0; - - rv = skip_blank_lines_and_spaces(fp, buf, &ptr, eof); - - if (rv != LDAPU_SUCCESS || *eof) - return rv; - - /* We possibly have a directive of the form "directory " */ - rv = parse_directive(ptr, directive, directive_len, &db_info); - if (rv != LDAPU_SUCCESS) - return rv; - - /* We have parsed the directive successfully -- lets look for additional - * property-value pairs for the database. - */ - if (!fgets(buf, BIG_LINE, fp)) { - *eof = 1; - rv = LDAPU_SUCCESS; - } else { - rv = dbconf_read_propval(fp, buf, db_info, eof); - } - - if (rv != LDAPU_SUCCESS) { - dbconf_free_dbinfo(db_info); - *db_info_out = 0; - } else { - *db_info_out = db_info; - } - - return rv; -} - -int -dbconf_read_config_file_sub(const char *file, - const char *directive, - const int directive_len, - DBConfInfo_t **conf_info_out) -{ - FILE *fp; - DBConfInfo_t *conf_info; - DBConfDBInfo_t *db_info; - char buf[BIG_LINE]; - int rv; - int eof; - - buf[0] = 0; - - if ((fp = fopen(file, "r")) == NULL) { - return LDAPU_ERR_CANNOT_OPEN_FILE; - } - - /* Allocate DBConfInfo_t */ - conf_info = (DBConfInfo_t *)malloc(sizeof(DBConfInfo_t)); - - if (!conf_info) { - fclose(fp); - return LDAPU_ERR_OUT_OF_MEMORY; - } - - memset((void *)conf_info, 0, sizeof(DBConfInfo_t)); - - /* Read each db info */ - eof = 0; - while (!eof && - ((rv = read_db_info(fp, buf, &db_info, directive, directive_len, &eof)) == LDAPU_SUCCESS)) { - insert_dbconf_dbinfo(conf_info, db_info); - } - - if (rv != LDAPU_SUCCESS) { - dbconf_free_confinfo(conf_info); - *conf_info_out = 0; - } else { - *conf_info_out = conf_info; - } - - fclose(fp); - return rv; -} - -NSAPI_PUBLIC int -dbconf_read_config_file(const char *file, DBConfInfo_t **conf_info_out) -{ - return dbconf_read_config_file_sub(file, DB_DIRECTIVE, DB_DIRECTIVE_LEN, - conf_info_out); -} - -int -dbconf_read_default_dbinfo_sub(const char *file, - const char *directive, - const int directive_len, - DBConfDBInfo_t **db_info_out) -{ - FILE *fp; - DBConfDBInfo_t *db_info; - char buf[BIG_LINE]; - int rv; - int eof; - - buf[0] = 0; - - if ((fp = fopen(file, "r")) == NULL) { - return LDAPU_ERR_CANNOT_OPEN_FILE; - } - - /* Read each db info until eof or dbname == default*/ - eof = 0; - - while (!eof && - ((rv = read_db_info(fp, buf, &db_info, directive, directive_len, &eof)) == LDAPU_SUCCESS)) { - if (!strcmp(db_info->dbname, DBCONF_DEFAULT_DBNAME)) - break; - dbconf_free_dbinfo(db_info); - db_info = NULL; - } - - if (rv != LDAPU_SUCCESS) { - *db_info_out = 0; - } else { - *db_info_out = db_info; - } - - fclose(fp); - return rv; -} - - -NSAPI_PUBLIC int -dbconf_read_default_dbinfo(const char *file, - DBConfDBInfo_t **db_info_out) -{ - return dbconf_read_default_dbinfo_sub(file, DB_DIRECTIVE, DB_DIRECTIVE_LEN, - db_info_out); -} - -/* - * ldapu_strcasecmp - is like strcasecmp on UNIX but also accepts null strings. - */ -int -ldapu_strcasecmp(const char *s1, const char *s2) -{ - - if (!s1) - return !s2 ? 0 : 0 - tolower(*s2); - else if (!s2) - return tolower(*s1); - - return strcasecmp(s1, s2); -} - -NSAPI_PUBLIC int -ldapu_dbinfo_attrval(DBConfDBInfo_t *db_info, - const char *attr, - char **val) -{ - /* Look for given attr in the db_info and return its value */ - int rv = LDAPU_ATTR_NOT_FOUND; - DBPropVal_t *next; - - *val = 0; - - if (db_info) { - next = db_info->firstprop; - while (next) { - rv = ldapu_strcasecmp(attr, next->prop); - if (!rv) { - /* Found the property */ - *val = next->val ? strdup(next->val) : 0; - - if (next->val && !*val) { - rv = LDAPU_ERR_OUT_OF_MEMORY; - } else { - rv = LDAPU_SUCCESS; - } - break; - } - next = next->next; - } - } - - return rv; -} - -void -dbconf_print_propval(DBPropVal_t *propval) -{ - if (propval) { - fprintf(stderr, "\tprop: \"%s\"\tval: \"%s\"\n", propval->prop, - propval->val ? propval->val : ""); - } else { - fprintf(stderr, "Null propval\n"); - } -} - -void -dbconf_print_dbinfo(DBConfDBInfo_t *db_info) -{ - DBPropVal_t *next; - - if (db_info) { - fprintf(stderr, "dbname: \"%s\"\n", db_info->dbname); - fprintf(stderr, "url: \t\"%s\"\n", db_info->url ? db_info->url : ""); - next = db_info->firstprop; - while (next) { - dbconf_print_propval(next); - next = next->next; - } - } else { - fprintf(stderr, "Null db_info\n"); - } -} - -void -dbconf_print_confinfo(DBConfInfo_t *conf_info) -{ - DBConfDBInfo_t *next; - - if (conf_info) { - next = conf_info->firstdb; - while (next) { - dbconf_print_dbinfo(next); - next = next->next; - } - } else { - fprintf(stderr, "Null conf_info\n"); - } -} - - -NSAPI_PUBLIC int -dbconf_output_db_directive(FILE *fp, const char *dbname, const char *url) -{ - fprintf(fp, "%s %s %s\n", DB_DIRECTIVE, dbname, url); - return LDAPU_SUCCESS; -} - -NSAPI_PUBLIC int -dbconf_output_propval(FILE *fp, const char *dbname, const char *prop, const char *val, const int encoded) -{ - if (encoded && val && *val) { - char *new_val = dbconf_encodeval(val); - - if (!new_val) - return LDAPU_ERR_OUT_OF_MEMORY; - fprintf(fp, "%s:%s %s %s\n", dbname, ENCODED, - prop, new_val); - free(new_val); - } else { - fprintf(fp, "%s:%s %s\n", dbname, prop, val ? val : ""); - } - - return LDAPU_SUCCESS; -} - - -NSAPI_PUBLIC int -dbconf_get_dbnames(const char *dbmap, char ***dbnames_out, int *cnt_out) -{ - DBConfInfo_t *conf_info = 0; - DBConfDBInfo_t *db = 0; - int cnt = 0; - char **dbnames = 0; - char *heap = 0; - int rv; - - *dbnames_out = 0; - *cnt_out = 0; - - rv = dbconf_read_config_file(dbmap, &conf_info); - - if (rv != LDAPU_SUCCESS) - return rv; - - db = conf_info->firstdb; - - - dbnames = (char **)malloc(32 * 1024); - heap = (char *)dbnames + 2 * 1024; - - if (!dbnames) { - dbconf_free_confinfo(conf_info); - return LDAPU_ERR_OUT_OF_MEMORY; - } - - *dbnames_out = dbnames; - - while (db) { - *dbnames++ = heap; - strcpy(heap, db->dbname); - heap += strlen(db->dbname) + 1; - db = db->next; - cnt++; - } - - *dbnames = NULL; - *cnt_out = cnt; - dbconf_free_confinfo(conf_info); - - return LDAPU_SUCCESS; -} - -NSAPI_PUBLIC int -dbconf_free_dbnames(char **dbnames) -{ - if (dbnames) - free(dbnames); - - return LDAPU_SUCCESS; -} diff --git a/lib/ldaputil/encode.c b/lib/ldaputil/encode.c deleted file mode 100644 index 3219c8d..0000000 --- a/lib/ldaputil/encode.c +++ /dev/null @@ -1,151 +0,0 @@ -/** BEGIN COPYRIGHT BLOCK - * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. - * Copyright (C) 2005 Red Hat, Inc. - * All rights reserved. - * - * License: GPL (version 3 or any later version). - * See LICENSE for details. - * END COPYRIGHT BLOCK **/ - -#ifdef HAVE_CONFIG_H -#include -#endif - - -/* This was malloc.h - but it's moved to stdlib.h on most platforms, and FBSD is strict */ -/* Make it stdlib.h, and revert to malloc.h with ifdefs if we have issues here. WB 2016 */ -#include -#include -#include -#include - -/* The magic set of 64 chars in the uuencoded data */ -static unsigned char uuset[] = { - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', - 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', - 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', '+', '/'}; - -static int -do_uuencode(unsigned char *src, unsigned char *dst, int srclen) -{ - int i, r; - unsigned char *p; - - /* To uuencode, we snip 8 bits from 3 bytes and store them as -6 bits in 4 bytes. 6*4 == 8*3 (get it?) and 6 bits per byte -yields nice clean bytes - -It goes like this: - AAAAAAAA BBBBBBBB CCCCCCCC -turns into the standard set of uuencode ascii chars indexed by numbers: - 00AAAAAA 00AABBBB 00BBBBCC 00CCCCCC - -Snip-n-shift, snip-n-shift, etc.... - -*/ - - for (p = dst, i = 0; i < srclen; i += 3) { - /* Do 3 bytes of src */ - register char b0, b1, b2; - - b0 = src[0]; - if (i == srclen - 1) - b1 = b2 = '\0'; - else if (i == srclen - 2) { - b1 = src[1]; - b2 = '\0'; - } else { - b1 = src[1]; - b2 = src[2]; - } - - *p++ = uuset[b0 >> 2]; - *p++ = uuset[(((b0 & 0x03) << 4) | ((b1 & 0xf0) >> 4))]; - *p++ = uuset[(((b1 & 0x0f) << 2) | ((b2 & 0xc0) >> 6))]; - *p++ = uuset[b2 & 0x3f]; - src += 3; - } - *p = 0; /* terminate the string */ - r = (unsigned char *)p - (unsigned char *)dst; /* remember how many we did */ - - /* Always do 4-for-3, but if not round threesome, have to go - clean up the last extra bytes */ - - for (; i != srclen; i--) - *--p = '='; - - return r; -} - -const unsigned char pr2six[256] = { - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64, 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64, 64, 26, 27, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64}; - -static char * -_uudecode(const char *bufcoded) -{ - register const char *bufin = bufcoded; - register unsigned char *bufout; - register int nprbytes; - unsigned char *bufplain; - int nbytesdecoded; - - /* Find the length */ - while (pr2six[(int)*(bufin++)] <= 63) - ; - nprbytes = bufin - bufcoded - 1; - nbytesdecoded = ((nprbytes + 3) / 4) * 3; - - bufout = (unsigned char *)malloc(nbytesdecoded + 1); - bufplain = bufout; - - bufin = bufcoded; - - while (nprbytes > 0) { - *(bufout++) = (unsigned char)(pr2six[(int)(*bufin)] << 2 | pr2six[(int)bufin[1]] >> 4); - *(bufout++) = (unsigned char)(pr2six[(int)bufin[1]] << 4 | pr2six[(int)bufin[2]] >> 2); - *(bufout++) = (unsigned char)(pr2six[(int)bufin[2]] << 6 | pr2six[(int)bufin[3]]); - bufin += 4; - nprbytes -= 4; - } - - if (nprbytes & 03) { - if (pr2six[(int)bufin[-2]] > 63) - nbytesdecoded -= 2; - else - nbytesdecoded -= 1; - } - bufplain[nbytesdecoded] = '\0'; - - return (char *)bufplain; -} - - -char * -dbconf_encodeval(const char *val) -{ - int len = strlen(val); - char *dst = (char *)malloc(2 * len); - - if (dst) { - do_uuencode((unsigned char *)val, (unsigned char *)dst, len); - } - - return dst; -} - -char * -dbconf_decodeval(const char *val) -{ - return _uudecode(val); -} diff --git a/lib/ldaputil/errors.c b/lib/ldaputil/errors.c deleted file mode 100644 index ada1d31..0000000 --- a/lib/ldaputil/errors.c +++ /dev/null @@ -1,210 +0,0 @@ -/** BEGIN COPYRIGHT BLOCK - * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. - * Copyright (C) 2005 Red Hat, Inc. - * All rights reserved. - * - * License: GPL (version 3 or any later version). - * See LICENSE for details. - * END COPYRIGHT BLOCK **/ - -#ifdef HAVE_CONFIG_H -#include -#endif - - -#include -#include - -NSAPI_PUBLIC char * -ldapu_err2string(int err) -{ - char *rv; - - switch (err) { - - /* Error codes defined in certmap.h */ - case LDAPU_SUCCESS: - rv = "success"; - break; - case LDAPU_FAILED: - rv = "ldap search didn't find an ldap entry"; - break; - case LDAPU_CERT_MAP_FUNCTION_FAILED: - rv = "Cert mapping function failed"; - break; - case LDAPU_CERT_SEARCH_FUNCTION_FAILED: - rv = "Cert search function failed"; - break; - case LDAPU_CERT_VERIFY_FUNCTION_FAILED: - rv = "Cert verify function failed"; - break; - case LDAPU_CERT_MAP_INITFN_FAILED: - rv = "Certmap InitFn function failed"; - break; - - - /* Error codes returned by ldapdb.c */ - case LDAPU_ERR_URL_INVALID_PREFIX: - rv = "invalid local ldap database url prefix -- must be ldapdb://"; - break; - case LDAPU_ERR_URL_NO_BASEDN: - rv = "base dn is missing in ldapdb url"; - break; - case LDAPU_ERR_OUT_OF_MEMORY: - rv = "out of memory"; - break; - case LDAPU_ERR_LDAP_INIT_FAILED: - rv = "Couldn't initialize connection to the ldap directory server"; - break; - case LDAPU_ERR_LCACHE_INIT_FAILED: - rv = "Couldn't initialize connection to the local ldap directory"; - break; - case LDAPU_ERR_LDAP_SET_OPTION_FAILED: - rv = "ldap_set_option failed for local ldap database"; - break; - case LDAPU_ERR_NO_DEFAULT_CERTDB: - rv = "default cert database not initialized when using LDAP over SSL"; - break; - - - /* Errors returned by ldapauth.c */ - case LDAPU_ERR_CIRCULAR_GROUPS: - rv = "Circular groups were detected during group membership check"; - break; - case LDAPU_ERR_INVALID_STRING: - rv = "Invalid string"; - break; - case LDAPU_ERR_INVALID_STRING_INDEX: - rv = "Invalid string index"; - break; - case LDAPU_ERR_MISSING_ATTR_VAL: - rv = "Missing attribute value from the search result"; - break; - - - /* Errors returned by dbconf.c */ - case LDAPU_ERR_CANNOT_OPEN_FILE: - rv = "cannot open the config file"; - break; - case LDAPU_ERR_DBNAME_IS_MISSING: - rv = "database name is missing"; - break; - case LDAPU_ERR_PROP_IS_MISSING: - rv = "database property is missing"; - break; - case LDAPU_ERR_DIRECTIVE_IS_MISSING: - rv = "illegal directive in the config file"; - break; - case LDAPU_ERR_NOT_PROPVAL: - rv = "internal error - LDAPU_ERR_NOT_PROPVAL"; - break; - - - /* Error codes returned by certmap.c */ - case LDAPU_ERR_NO_ISSUERDN_IN_CERT: - rv = "cannot extract issuer DN from the cert"; - break; - case LDAPU_ERR_NO_ISSUERDN_IN_CONFIG_FILE: - rv = "issuer DN missing for non-default certmap"; - break; - case LDAPU_ERR_CERTMAP_INFO_MISSING: - rv = "cert to ldap entry mapping information is missing"; - break; - case LDAPU_ERR_MALFORMED_SUBJECT_DN: - rv = "Found malformed subject DN in the certificate"; - break; - case LDAPU_ERR_MAPPED_ENTRY_NOT_FOUND: - rv = "Certificate couldn't be mapped to an ldap entry"; - break; - case LDAPU_ERR_UNABLE_TO_LOAD_PLUGIN: - rv = "Unable to load certmap plugin library"; - break; - case LDAPU_ERR_MISSING_INIT_FN_IN_CONFIG: - rv = "InitFn must be provided when using certmap plugin library"; - break; - case LDAPU_ERR_MISSING_INIT_FN_IN_LIB: - rv = "Could not find InitFn in the certmap plugin library"; - break; - case LDAPU_ERR_CERT_VERIFY_FAILED: - rv = "Could not matching certificate in User's LDAP entry"; - break; - case LDAPU_ERR_CERT_VERIFY_NO_CERTS: - rv = "User's LDAP entry doesn't have any certificates to compare"; - break; - case LDAPU_ERR_MISSING_LIBNAME: - rv = "Library name is missing in the config file"; - break; - case LDAPU_ERR_MISSING_INIT_FN_NAME: - rv = "Init function name is missing in the config file"; - break; - case LDAPU_ERR_WRONG_ARGS: - rv = "ldaputil API function called with wrong arguments"; - break; - case LDAPU_ERR_RENAME_FILE_FAILED: - rv = "Renaming of file failed"; - break; - case LDAPU_ERR_MISSING_VERIFYCERT_VAL: - rv = "VerifyCert property value must be on or off"; - break; - case LDAPU_ERR_CANAME_IS_MISSING: - rv = "Cert issuer name is missing"; - break; - case LDAPU_ERR_CAPROP_IS_MISSING: - rv = "property name is missing"; - break; - case LDAPU_ERR_UNKNOWN_CERT_ATTR: - rv = "unknown cert attribute"; - break; - - - case LDAPU_ERR_EMPTY_LDAP_RESULT: - rv = "ldap search returned empty result"; - break; - case LDAPU_ERR_MULTIPLE_MATCHES: - rv = "ldap search returned multiple matches when one expected"; - break; - case LDAPU_ERR_MISSING_RES_ENTRY: - rv = "Could not extract entry from the ldap search result"; - break; - case LDAPU_ERR_MISSING_UID_ATTR: - rv = "ldap entry is missing the 'uid' attribute value"; - break; - case LDAPU_ERR_INVALID_ARGUMENT: - rv = "invalid argument passed to the certmap API function"; - break; - case LDAPU_ERR_INVALID_SUFFIX: - rv = "invalid LDAP directory suffix"; - break; - - - /* Error codes returned by cert.c */ - case LDAPU_ERR_EXTRACT_SUBJECTDN_FAILED: - rv = "Couldn't extract the subject DN from the certificate"; - break; - case LDAPU_ERR_EXTRACT_ISSUERDN_FAILED: - rv = "Couldn't extract the issuer DN from the certificate"; - break; - case LDAPU_ERR_EXTRACT_DERCERT_FAILED: - rv = "Couldn't extract the original DER encoding from the certificate"; - break; - - - case LDAPU_ERR_NOT_IMPLEMENTED: - rv = "function not implemented yet"; - break; - case LDAPU_ERR_INTERNAL: - rv = "ldaputil internal error"; - break; - - default: - if (err > 0) { - /* LDAP errors are +ve */ - rv = ldap_err2string(err); - } else { - rv = "internal error - unknown error code"; - } - break; - } - - return rv; -} diff --git a/lib/ldaputil/examples/Makefile b/lib/ldaputil/examples/Makefile deleted file mode 100644 index d7aa9d6..0000000 --- a/lib/ldaputil/examples/Makefile +++ /dev/null @@ -1,89 +0,0 @@ -# -# BEGIN COPYRIGHT BLOCK -# Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. -# Copyright (C) 2005 Red Hat, Inc. -# All rights reserved. -# -# License: GPL (version 3 or any later version). -# See LICENSE for details. -# END COPYRIGHT BLOCK -# -# -# Makefile for certmap example program. -# - -# -# Please set the ARCH variable to one of the following: -# SOLARIS, IRIX, HPUX -# -ARCH = - - -# -# Please set the SROOT to be same as your server root -# -SROOT = - -# -# Uncomment the following if you need the debug build -# -#COMMON_DEFS = -g - -ifndef ARCH -arch: - @echo "Please edit the Makefile and set the variable: ARCH" - @exit 1 -endif - -ifndef SROOT -sroot: - @echo "Please edit the Makefile and set the server root variable: SROOT" - @exit 1 -endif - -ifeq ($(ARCH), SOLARIS) -CC_CMD = cc -DSOLARIS -D_REENTRANT -LD_SHAREDCMD = ld -G -endif - -ifeq ($(ARCH), HPUX) - BIN = certmap.sl -else - BIN = certmap.so -endif - -OBJS = init.o plugin.o - -INCLUDE_FLAGS=-I. -I$(SROOT)/include - -INC_FILES = \ - $(SROOT)/include/certmap.h \ - $(SROOT)/include/ldap.h \ - $(SROOT)/include/lber.h - -all: $(BIN) - -$(INC_FILES): - @echo - @echo "To extend the Certificate to LDAP entry mapping by" - @echo "writing your own functions, you need to download the" - @echo "Certmap API (version 1.0) and LDAP SDK (version 1.0)." - @echo "Please download these from http://???" - @echo "Make sure the following files exist:" - @echo "\t$(SROOT)/include/certmap.h" - @echo "\t$(SROOT)/include/ldap.h" - @echo "\t$(SROOT)/include/lber.h" - @echo - @exit 1 - -$(BIN): $(INC_FILES) $(OBJS) - $(LD_SHAREDCMD) $(OBJS) -o $@ $(EXTRA_LDDEFINES) - -certmap.dll: $(OBJS) - $(LD_SHAREDCMD) $(OBJS) -o $@ $(EXTRA_LDDEFINES) - -.c.o: - $(CC_CMD) $(COMMON_DEFS) $(INCLUDE_FLAGS) -c $< - -clean: - rm -f $(OBJS) certmap.so $(EXTRA_CLEAN) diff --git a/lib/ldaputil/examples/README b/lib/ldaputil/examples/README deleted file mode 100644 index 3ea7a74..0000000 --- a/lib/ldaputil/examples/README +++ /dev/null @@ -1,100 +0,0 @@ -# BEGIN COPYRIGHT BLOCK -# Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. -# Copyright (C) 2005 Red Hat, Inc. -# All rights reserved. -# -# License: GPL (version 3 or any later version). -# See LICENSE for details. -# END COPYRIGHT BLOCK -# - -This directory contains an example program to demonstrate -writing plugins using the "Certificate to LDAP Mapping" API. -Please read the "Managing Servers" manual to find out -about how certificate to ldap mapping can be configured using -the /userdb/certmap.conf file. Also refer to the -"Certificate to LDAP Mapping API" documentation to find out -about the various API functions and how you can write your -plugin. - -This example demonstrate use of most of the API functions. It -defines a mapping function, a search function, and a verify -function. Read the API doc to learn about these functions. -The init.c file also contains an init function which sets the -mapping, search and verify functions. - -The Mapping Function --------------------- - -The mapping function extracts the attributes "CN", "E", "O" and -"C" from the certificate's subject DN using the function -ldapu_get_cert_ava_val. If the attributes "C" doesn't exists -then it defaults to "US". It then gets the value of a custom -certmap.conf property "defaultOU" using the function -ldapu_certmap_info_attrval. This demonstrates how you can have -your own custom properties defined in the certmap.conf file. -The mapping function then returns an ldapdn of the form: -"cn=, ou=, o=, c=". - -If the "E" attribute has a value, it returns a filter -"mail=". Finally, the mapping function frees the structures -returned by some of the API functions it called. - - -The Search Function -------------------- - -The search function calls a dummy function to get the -certificate's serial number. It then does a subtree search in -the entire directory for the filter -"certSerialNumber=". If this fails, it calls the -default search function. This demonstrates how you can use the -default functions in your custom functions. - -The Verify Function -------------------- - -The verify function returns LDAPU_SUCCESS if only one entry was -returned by the search function. Otherwise, it returns -LDAPU_CERT_VERIFY_FUNCTION_FAILED. - - -Error Reporting ---------------- - -To report errors/warning, there is a function defined called -plugin_ereport. This function demonstrates how to get the -subject DN and the issuer DN from the certificate. - -Build Procedure ---------------- -On UNIX: Edit the Makefile, and set the variables ARCH & SROOT -according to the comments in the Makefile. Download LDAP C SDK -from the mozilla.org site and make the ldap include -files available in /include. Copy the -../include/certmap.h file to the /include directory. -Use 'gmake' to build the plugin. A shared library plugin.so -(plugin.sl on HP) will be created in the current directory. - -On NT: Execute the following command: -NMAKE /f "Certmap.mak" CFG="Certmap - Win32 Debug" -Certmap.dll will be created in the Debug subdirectory. - -Certmap.conf Configuration --------------------------- -Save a copy of certmap.conf file. -Change the certmap.conf file as follows: - -certmap default default -default:defaultOU marketing -default:library -default:InitFn plugin_init_fn - - -After experimenting with this example, restore the old copy of -certmap.conf file. Or else, set the certmap.conf file as follows: - -certmap default default -default:DNComps -default:FilterComps e, mail, uid -default:VerifyCert on diff --git a/lib/ldaputil/examples/init.c b/lib/ldaputil/examples/init.c deleted file mode 100644 index 74db977..0000000 --- a/lib/ldaputil/examples/init.c +++ /dev/null @@ -1,43 +0,0 @@ -/** BEGIN COPYRIGHT BLOCK - * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. - * Copyright (C) 2005 Red Hat, Inc. - * All rights reserved. - * - * License: GPL (version 3 or any later version). - * See LICENSE for details. - * END COPYRIGHT BLOCK **/ - -#ifdef HAVE_CONFIG_H -#include -#endif - - -#include -#include -#include -#include "certmap.h" /* Public Certmap API */ -#include "plugin.h" /* must define extern "C" functions */ - - -NSAPI_PUBLIC int -plugin_init_fn(void *certmap_info, const char *issuerName, const char *issuerDN, const char *libname) -{ - static int initialized = 0; - int rv; - - /* Make sure CertmapDLLInit is initialized only once */ - if (!initialized) { - - initialized = 1; - } - - fprintf(stderr, "plugin_init_fn called.\n"); - ldapu_set_cert_mapfn(issuerDN, plugin_mapping_fn); - ldapu_set_cert_verifyfn(issuerDN, plugin_verify_fn); - - if (!default_searchfn) - default_searchfn = ldapu_get_cert_searchfn(issuerDN); - - ldapu_set_cert_searchfn(issuerDN, plugin_search_fn); - return LDAPU_SUCCESS; -} diff --git a/lib/ldaputil/examples/plugin.c b/lib/ldaputil/examples/plugin.c deleted file mode 100644 index baacb70..0000000 --- a/lib/ldaputil/examples/plugin.c +++ /dev/null @@ -1,240 +0,0 @@ -/** BEGIN COPYRIGHT BLOCK - * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. - * Copyright (C) 2005 Red Hat, Inc. - * All rights reserved. - * - * License: GPL (version 3 or any later version). - * See LICENSE for details. - * END COPYRIGHT BLOCK **/ - -#ifdef HAVE_CONFIG_H -#include -#endif - - -#include -#include -#include -#include "certmap.h" /* Public Certmap API */ -#include "plugin.h" /* must define extern "C" functions */ - - -CertSearchFn_t default_searchfn = 0; - - -/* plugin_ereport - - This function prints an error message to stderr. It prints the issuerDN - and subjectDN alongwith the given message. - */ -static void -plugin_ereport(const char *msg, void *cert) -{ - int rv; - char *subjectDN; - char *issuerDN; - char *default_subjectDN = "Failed to get the subject DN"; - char *default_issuerDN = "Failed to get the issuer DN"; - - rv = ldapu_get_cert_subject_dn(cert, &subjectDN); - - if (rv != LDAPU_SUCCESS || !subjectDN) { - subjectDN = default_subjectDN; - } - - rv = ldapu_get_cert_issuer_dn(cert, &issuerDN); - - if (rv != LDAPU_SUCCESS || !issuerDN) { - issuerDN = default_issuerDN; - } - - fprintf(stderr, "%s. Issuer: %s, Subject: %s\n", msg, issuerDN, - subjectDN); - - if (default_subjectDN != subjectDN) - ldapu_free(subjectDN); - if (default_issuerDN != issuerDN) - ldapu_free(issuerDN); -} - - -/* plugin_mapping_fn - - This mapping function extracts "CN", "O" and "C" attributes from the - subject DN to form ldapDN. It inserts "ou=" between the - "CN" and the "O" attr-value pair. The can be configured in - the certmap.conf config file. - If the "C" attr is absent, it defaults to "US". - It extracts the "E" attribute to form the filter. - */ -int -plugin_mapping_fn(void *cert, LDAP *ld, void *certmap_info, char **ldapDN, char **filter) -{ - char **cn_val; /* get this from the cert */ - char **o_val; /* get this from the cert */ - char **c_val; /* get this from the cert */ - char **e_val; /* get this from the cert */ - char *ou_val; /* get this from the config file */ - int len; - int rv; - - fprintf(stderr, "plugin_mapping_fn called.\n"); - - rv = ldapu_get_cert_ava_val(cert, LDAPU_SUBJECT_DN, "CN", &cn_val); - - if (rv != LDAPU_SUCCESS || !cn_val) { - plugin_ereport("plugin_mapping_fn: Failed to extract \"CN\" from the cert", cert); - return LDAPU_CERT_MAP_FUNCTION_FAILED; - } - - rv = ldapu_get_cert_ava_val(cert, LDAPU_SUBJECT_DN, "O", &o_val); - - if (rv != LDAPU_SUCCESS || !o_val) { - plugin_ereport("plugin_mapping_fn: Failed to extract \"O\" from the cert", cert); - return LDAPU_CERT_MAP_FUNCTION_FAILED; - } - - rv = ldapu_get_cert_ava_val(cert, LDAPU_SUBJECT_DN, "C", &c_val); - - if (rv != LDAPU_SUCCESS || !c_val) { - plugin_ereport("plugin_mapping_fn: Failed to extract \"C\" from the cert", cert); - } - - rv = ldapu_get_cert_ava_val(cert, LDAPU_SUBJECT_DN, "E", &e_val); - - if (rv != LDAPU_SUCCESS || !e_val) { - /* Don't return error -- just print the warning */ - plugin_ereport("plugin_mapping_fn: Failed to extract \"E\" from the cert", cert); - } - - /* Get the "OU" from the "defaultOU" property from the config file */ - rv = ldapu_certmap_info_attrval(certmap_info, "defaultOU", &ou_val); - - if (rv != LDAPU_SUCCESS || !ou_val) { - plugin_ereport("plugin_mapping_fn: Failed to get \"defaultOU\" from the configuration", cert); - return LDAPU_CERT_MAP_FUNCTION_FAILED; - } - - len = strlen("cn=, ou=, o=, c=") + strlen(cn_val[0]) + strlen(ou_val) + - strlen(o_val[0]) + (c_val ? strlen(c_val[0]) : strlen("US")) + 1; - *ldapDN = (char *)ldapu_malloc(len); - - if (!*ldapDN) { - plugin_ereport("plugin_mapping_fn: Ran out of memory", cert); - return LDAPU_CERT_MAP_FUNCTION_FAILED; - } - - if (e_val) { - len = strlen("mail=") + strlen(e_val[0]) + 1; - *filter = (char *)ldapu_malloc(len); - - if (!*filter) { - free(*ldapDN); - plugin_ereport("plugin_mapping_fn: Ran out of memory", cert); - return LDAPU_CERT_MAP_FUNCTION_FAILED; - } - sprintf(*filter, "mail=%s", e_val[0]); - } else { - *filter = 0; - } - - sprintf(*ldapDN, "cn=%s, ou=%s, o=%s, c=%s", cn_val[0], ou_val, - o_val[0], c_val ? c_val[0] : "US"); - - ldapu_free_cert_ava_val(cn_val); - ldapu_free_cert_ava_val(o_val); - ldapu_free_cert_ava_val(c_val); - ldapu_free_cert_ava_val(e_val); - ldapu_free(ou_val); - - fprintf(stderr, "plugin_mapping_fn Returned:\n\tldapDN: \"%s\"\n\tfilter: \"%s\"\n", - *ldapDN, *filter ? *filter : ""); - - return LDAPU_SUCCESS; -} - - -int -plugin_cert_serial_number(void *cert) -{ - /* Just a stub function. You can get the DER encoded cert by using the - function ldapu_get_cert_der: - */ - unsigned char *derCert; - unsigned int len; - int rv; - int sno; - - rv = ldapu_get_cert_der(cert, &derCert, &len); - - /* extract the serial number from derCert */ - sno = 43534754; /* a fake value for now */ - - ldapu_free((char *)derCert); - - return sno; -} - -/* plugin_search_fn - - This function first does a search based on the cert's serial number. - If that fails, it calls the default search function. - */ -int -plugin_search_fn(void *cert, LDAP *ld, void *certmap_info, const char *suffix, const char *ldapdn, const char *filter, const char **attrs, LDAPMessage **res) -{ - int rv; - char snoFilter[256]; - - fprintf(stderr, "plugin_search_fn called.\n"); - sprintf(snoFilter, "certSerialNumber=%d", - plugin_cert_serial_number(cert)); - - /* Search the entire LDAP tree for "certSerialNumber=" */ - rv = ldap_search_s(ld, suffix, LDAP_SCOPE_SUBTREE, snoFilter, - (char **)attrs, 0, res); - - /* ldap_search_s returns LDAP_SUCCESS (rather than LDAPU_SUCCESS) - if there is no error but there may not be any matching entries. - */ - if (rv == LDAP_SUCCESS) { - /* There was no error but check if any entries matched */ - int numEntries = ldap_count_entries(ld, *res); - - if (numEntries > 0) { - /* at least one entry matched */ - /* change the return value to LDAPU_SUCCESS from LDAP_SUCCESS */ - rv = LDAPU_SUCCESS; - } else { - /* Try the default search function */ - rv = (*default_searchfn)(cert, ld, certmap_info, suffix, ldapdn, - filter, attrs, res); - } - } - - /* It's ok to return the error code from ldap_search_s */ - return rv; -} - -/* - plugin_verify_fn - - This function returns success if only one entry exists in 'res'. - */ -int -plugin_verify_fn(void *cert, LDAP *ld, void *certmap_info, LDAPMessage *res, LDAPMessage **entry) -{ - int rv; - int numEntries; - - fprintf(stderr, "plugin_verify_fn called.\n"); - numEntries = ldap_count_entries(ld, res); - - if (numEntries == 1) { - *entry = ldap_first_entry(ld, res); - rv = LDAPU_SUCCESS; - } else { - plugin_ereport("plugin_verify_fn: Failing because multiple entries matched.", - cert); - *entry = 0; - rv = LDAPU_CERT_VERIFY_FUNCTION_FAILED; - } - - return rv; -} diff --git a/lib/ldaputil/examples/plugin.h b/lib/ldaputil/examples/plugin.h deleted file mode 100644 index e7e5282..0000000 --- a/lib/ldaputil/examples/plugin.h +++ /dev/null @@ -1,35 +0,0 @@ -/** BEGIN COPYRIGHT BLOCK - * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. - * Copyright (C) 2005 Red Hat, Inc. - * All rights reserved. - * - * License: GPL (version 3 or any later version). - * See LICENSE for details. - * END COPYRIGHT BLOCK **/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#ifndef _CERTMAP_PLUGIN_H -#define _CERTMAP_PLUGIN_H - -extern CertSearchFn_t default_searchfn; - -#ifdef __cplusplus -extern "C" { -#endif - -extern int plugin_mapping_fn(void *cert, LDAP *ld, void *certmap_info, char **ldapDN, char **filter); - -extern int plugin_search_fn(void *cert, LDAP *ld, void *certmap_info, const char *basedn, const char *dn, const char *filter, const char **attrs, LDAPMessage **res); - -extern int plugin_verify_fn(void *cert, LDAP *ld, void *certmap_info, LDAPMessage *res, LDAPMessage **entry); - -NSAPI_PUBLIC int plugin_init_fn(void *certmap_info, const char *issuerName, const char *issuerDN, const char *dllname); - -#ifdef __cplusplus -} -#endif - -#endif /* _CERTMAP_PLUGIN_H */ diff --git a/lib/ldaputil/init.c b/lib/ldaputil/init.c deleted file mode 100644 index c7d59d1..0000000 --- a/lib/ldaputil/init.c +++ /dev/null @@ -1,138 +0,0 @@ -/** BEGIN COPYRIGHT BLOCK - * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. - * Copyright (C) 2005 Red Hat, Inc. - * All rights reserved. - * - * License: GPL (version 3 or any later version). - * See LICENSE for details. - * END COPYRIGHT BLOCK **/ - -#ifdef HAVE_CONFIG_H -#include -#endif - - -#include -#include -#include -#include - -/*#include "base/file.h"*/ -#include "ldaputil/certmap.h" -/*#include "ldaputil/ldapdb.h"*/ -#include "ldaputil/ldaputil.h" -#include "ldaputil/cert.h" -#include "ldaputil/errors.h" -#include "ldaputil/init.h" - -#include "slapi-plugin.h" - -#ifndef FILE_PATHSEP -#define FILE_PATHSEP '/' -#endif -#ifdef HPUX -#ifdef __ia64 -#define DLL_SUFFIX ".so" -#else -#define DLL_SUFFIX ".sl" -#endif -#else -#define DLL_SUFFIX ".so" -#endif - -static int -load_server_libs(const char *dir) -{ - int rv = LDAPU_SUCCESS; - PRDir *ds; - int suffix_len = strlen(DLL_SUFFIX); - - if ((ds = PR_OpenDir(dir)) != NULL) { - PRDirEntry *d; - - /* Dir exists */ - while ((d = PR_ReadDir(ds, PR_SKIP_BOTH))) { - PRLibrary *lib = 0; - const char *libname = d->name; - int len = strlen(libname); - int is_lib; - - is_lib = (len > suffix_len && !strcmp(libname + len - suffix_len, DLL_SUFFIX)); - - if (is_lib) { - char path[1024]; - - PR_snprintf(path, sizeof(path), "%s%c%s", dir, FILE_PATHSEP, libname); - lib = PR_LoadLibrary(path); - if (!lib) - rv = LDAPU_ERR_UNABLE_TO_LOAD_PLUGIN; - } - } - } else { - /* It's ok if dir doesn't exists */ - } - - return rv; -} - -NSAPI_PUBLIC int -ldaputil_init(const char *config_file, - const char *dllname, - const char *serv_root, - const char *serv_type, - const char *serv_id) -{ - int rv = LDAPU_SUCCESS; - static int initialized = 0; - - /* If already initialized, cleanup the old structures */ - if (initialized) - ldaputil_exit(); - - if (config_file && *config_file) { - char dir[1024]; - - LDAPUCertMapListInfo_t *certmap_list; - LDAPUCertMapInfo_t *certmap_default; - - if (serv_root && *serv_root) { - /* Load common libraries */ - PR_snprintf(dir, sizeof(dir), "%s%clib%c%s", serv_root, FILE_PATHSEP, - FILE_PATHSEP, "common"); - rv = load_server_libs(dir); - - if (rv != LDAPU_SUCCESS) - return rv; - - if (serv_type && *serv_type) { - /* Load server type specific libraries */ - sprintf(dir, "%s%clib%c%s", serv_root, FILE_PATHSEP, - FILE_PATHSEP, serv_type); - rv = load_server_libs(dir); - - if (rv != LDAPU_SUCCESS) - return rv; - - if (serv_id && *serv_id) { - /* Load server instance specific libraries */ - sprintf(dir, "%s%clib%c%s", serv_root, FILE_PATHSEP, - FILE_PATHSEP, serv_id); - rv = load_server_libs(dir); - - if (rv != LDAPU_SUCCESS) - return rv; - } - } - } - - rv = ldapu_certmap_init(config_file, dllname, &certmap_list, - &certmap_default); - } - - initialized = 1; - - if (rv != LDAPU_SUCCESS) - return rv; - - return rv; -} diff --git a/lib/ldaputil/ldapauth.c b/lib/ldaputil/ldapauth.c deleted file mode 100644 index 3420519..0000000 --- a/lib/ldaputil/ldapauth.c +++ /dev/null @@ -1,214 +0,0 @@ -/** BEGIN COPYRIGHT BLOCK - * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. - * Copyright (C) 2005 Red Hat, Inc. - * All rights reserved. - * - * License: GPL (version 3 or any later version). - * See LICENSE for details. - * END COPYRIGHT BLOCK **/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -/* - * ldapauth.cpp: Implements LDAP integration in the web server. - * - * Nitin More, John Kristian - */ - -/* #define DBG_PRINT */ - -#include /* for BUFSIZ */ -#include /* for strncpy, strcat */ -#include -#include - -#define DEFINE_LDAPU_STRINGS 1 -#include -#include -#include - -#include - -#include "slapi-plugin.h" - -/* - * ldapu_find - * Description: - * Caller should free res if it is not NULL. - * Arguments: - * ld Pointer to LDAP (assumes connection has been - * established and the client has called the - * appropriate bind routine) - * base basedn (where to start the search) - * scope scope for the search. One of - * LDAP_SCOPE_SUBTREE, LDAP_SCOPE_ONELEVEL, and - * LDAP_SCOPE_BASE - * filter LDAP filter - * attrs A NULL-terminated array of strings indicating which - * attributes to return for each matching entry. Passing - * NULL for this parameter causes all available - * attributes to be retrieved. - * attrsonly A boolean value that should be zero if both attribute - * types and values are to be returned, non-zero if only - * types are wanted. - * res A result parameter which will contain the results of - * the search upon completion of the call. - * Return Values: - * LDAPU_SUCCESS if entry is found - * LDAPU_FAILED if entry is not found - * if error, where can be passed to - * ldap_err2string to get an error string. - */ -int -ldapu_find(LDAP *ld, const char *base, int scope, const char *filter, const char **attrs, int attrsonly, LDAPMessage **res) -{ - int retval; -#ifdef USE_THIS_CODE /* ASYNCHRONOUS */ - int msgid; -#endif - int numEntries; - - *res = 0; - - /* If base is NULL set it to null string */ - if (!base) { - DBG_PRINT1("ldapu_find: basedn is missing -- assuming null string\n"); - base = ""; - } - - if (!filter || !*filter) { - DBG_PRINT1("ldapu_find: filter is missing -- assuming objectclass=*\n"); - filter = ldapu_strings[LDAPU_STR_FILTER_DEFAULT]; - } - - DBG_PRINT2("\tbase:\t\"%s\"\n", base); - DBG_PRINT2("\tfilter:\t\"%s\"\n", filter ? filter : ""); - DBG_PRINT2("\tscope:\t\"%s\"\n", - (scope == LDAP_SCOPE_SUBTREE ? "LDAP_SCOPE_SUBTREE" - : (scope == LDAP_SCOPE_ONELEVEL ? "LDAP_SCOPE_ONELEVEL" - : "LDAP_SCOPE_BASE"))); - - retval = ldapu_search_s(ld, base, scope, filter, (char **)attrs, - attrsonly, res); - - if (retval != LDAP_SUCCESS) { - /* retval = ldap_result2error(ld, *res, 0); */ - DBG_PRINT2("ldapu_search_s: %s\n", ldapu_err2string(retval)); - return (retval); - } - - numEntries = ldapu_count_entries(ld, *res); - - if (numEntries == 1) { - /* success */ - return LDAPU_SUCCESS; - } else if (numEntries == 0) { - /* not found -- but not an error */ - DBG_PRINT1("ldapu_search_s: Entry not found\n"); - return LDAPU_FAILED; - } else if (numEntries > 0) { - /* Found more than one entry! */ - DBG_PRINT1("ldapu_search_s: Found more than one entry\n"); - return LDAPU_ERR_MULTIPLE_MATCHES; - } else { - /* should never get here */ - DBG_PRINT1("ldapu_search_s: should never reach here\n"); - ldapu_msgfree(ld, *res); - return LDAP_OPERATIONS_ERROR; - } -} - - -/* Search function for the cases where base = "" = NULL suffix, that is, search to - * be performed on the entire DIT tree. - * We actually do various searches taking a naming context at a time as the base for - * the search. */ - -int -ldapu_find_entire_tree(LDAP *ld, int scope, const char *filter, const char **attrs, int attrsonly, LDAPMessage ***res) -{ - int retval = LDAPU_FAILED; - int rv, i, num_namingcontexts; - LDAPMessage *result_entry, *result = NULL; - const char *suffix_attr[2] = {"namingcontexts", NULL}; - /* these are private suffixes that may contain pseudo users - e.g. replication manager that may have certs */ - int num_private_suffix = 1; - const char *private_suffix_list[2] = {"cn=config", NULL}; - char **suffix_list, **suffix = NULL; - - rv = ldapu_find(ld, "", LDAP_SCOPE_BASE, "objectclass=*", suffix_attr, 0, &result); - if (rv != LDAP_SUCCESS) { - if (result) - ldapu_msgfree(ld, result); - return rv; - } - - result_entry = ldapu_first_entry(ld, result); - suffix = ldapu_get_values(ld, result_entry, suffix_attr[0]); - suffix_list = suffix; - num_namingcontexts = slapi_ldap_count_values(suffix); - /* add private suffixes to our list of suffixes to search */ - if (num_private_suffix) { - suffix_list = ldapu_realloc(suffix_list, - sizeof(char *) * (num_namingcontexts + num_private_suffix + 1)); - if (!suffix_list) { - if (result) { - ldapu_msgfree(ld, result); - } - retval = LDAPU_FAILED; - return retval; - } - for (i = num_namingcontexts; i < (num_namingcontexts + num_private_suffix); ++i) { - suffix_list[i] = strdup(private_suffix_list[i - num_namingcontexts]); - } - suffix_list[i] = NULL; - num_namingcontexts += num_private_suffix; - suffix = suffix_list; - } - if (result) - ldapu_msgfree(ld, result); - result = 0; - i = 0; - - /* ugaston - the caller function must remember to free the memory allocated here */ - *res = (LDAPMessage **)ldapu_malloc((num_namingcontexts + 1) * sizeof(LDAPMessage *)); - while (suffix && *suffix) { - rv = ldapu_find(ld, *suffix, scope, filter, attrs, attrsonly, &result); - if (scope == LDAP_SCOPE_BASE && rv == LDAP_SUCCESS) { - retval = rv; - (*res)[i++] = result; - break; - } - - switch (rv) { - case LDAP_SUCCESS: - if (retval == LDAP_SUCCESS) { - retval = LDAPU_ERR_MULTIPLE_MATCHES; - (*res)[i++] = result; - break; - } - /* FALLTHROUGH */ - case LDAPU_ERR_MULTIPLE_MATCHES: - retval = rv; - (*res)[i++] = result; - break; - default: - if (retval != LDAP_SUCCESS && retval != LDAPU_ERR_MULTIPLE_MATCHES) { - retval = rv; - } - if (result) - ldapu_msgfree(ld, result); - result = 0; - break; - } - - suffix++; - } - - (*res)[i] = NULL; - ldapu_value_free(ld, suffix_list); - return retval; -} diff --git a/lib/ldaputil/ldapu-changes.html b/lib/ldaputil/ldapu-changes.html deleted file mode 100644 index 00ec08f..0000000 --- a/lib/ldaputil/ldapu-changes.html +++ /dev/null @@ -1,406 +0,0 @@ - - - - - - - - - -
-

-Change Log for the ldaputil library

- -
-Author: Nitin More
- -
-E-mail:  nitin@netscape.com
- -
-Phone: (415) 937-4240
- -
- -
-
- -
- -
Changes since Apr 17, 1997
- - -

Last Update: Aug 25, 1997 - -

All the new changes have been checked into the server3_tier_branch.  -The server3_branch is frozen & contains the version of 'ldaputil' for -the SuiteSpot 3.0 release. -

-Changed:

-Several bug fixes went in since I last modified this file.  The important -ones are: -
    -
  • -79373: Attributes -listed multiple times in certmap.conf were turining that attribute off -and enabling some other attribute.  (For example, if you have "E" -as well as "MAIL" in FilterComps, they cancelled each other).
  • - -
  • -58474: If nested -group checks goes on for 30 recursions, a circular groups error is returned.
  • - -
  • -80004: after -thoroughly testing the certmap utility, several (mostly minor) oddities -were found & fixed.
  • -
- -

-Added:

- -
    -
  • -79370: Group -membership check is optimized now through the new function ldapu_auth_userdn_groupids.  -Use this new function to get the optimization.  This function's algorithm -is as follows:
  • - -
    The first search uses the following filter (w/o the group names!): -
      (| (& (objectclass=groupofuniquenames) -
            (uniquemember=<userDN>)) -
         (& (objectclass=groupofnames)(member=<userDN>))) -
       
    -This gives us all the groups the user is member of.  We ask for only -the "CN" attributes of the returned groups.  We check if "CN" of any -of the returned groups is one of the groups we have.  If yes, we have -succeeded.  If there are no groups returned then we have failed.  -Otherwise, we continue with the nested group check.  To perform that -check, we need DNs of all the groups the user is member of, which we already -have from the previous search.  Now we repeat the search as follows: -
      (| (& (objectclass=groupofuniquenames) -
            (| (uniquemember=<grp1DN>)... -(uniquemember=<grpNDN>)) -
         (& (objectclass=groupofnames) -
            (| (member=<grp1DN>)... (member=<grpNDN>))
    -We check the list of groups returned by this search with the groups in -the ACL and recursively continue until we succeed or no more groups are -returned from the searches. - -

    Advantages of this new function is it checks multiple groups at the -same time.  Previously we were performing 2 ldap lookups per group.  -Now we achieve this in a single ldap lookup! - -

    Caution: this function allows multiple groups -with the same "CN". - -

    To use this function, you need to provide a list of group names in any -form (e.g comma separated string, a hash table, array of strings, etc.) -and a function to compare the name returned by the ldap lookup with your -group names.

- -
Changes since Mar 22, 1997
- - -

Last Update: Apr 17, 1997 - -

Now that all beta releases are out for servers using this library, I -could do some incompatible changes to make this library more flexible. -No more incompatible changes are planned (except for possibly one: see -http://scopus/bugsplat/show_bug.cgi?id=58482). All 3.0 SuiteSpot -servers supporting client auth need to upgrade to this version. -

-Changed:

- -
    -
  • -Exchanged certmap.h & ldaputil.h: ldaputil.h had public API -but when the file was installed on the server root, it was called certmap.h. -Since we already had a certmap.h, this was causing lot of confusion. If -you were including "certmap.h", now include "ldaputil.h" and vice versa.
  • - -
  • -Renamed 'SearchComps' to 'FilterComps': Shouldn't affect your code -but may affect tests and documentation.
  • - -
  • -'VerifyCert' must be either "on" or "off": VerifyCert didn't have -a value. Now it must have a value. If it has a value of "on" then the "verification" -step is on, otherwise it is off.
  • - -
  • -Important bug fixes: One bug was causing stack corruption & -weird unpredictable results. The other important bug was to map 'E' in -cert to 'MAIL' in LDAP.
  • -
- -

-Added:

- -
    -
  • -Settable 'search function': User defined search function can be -set for cert to ldap mapping.
  • - -
  • -ldapu_get_cert_ava_val & ldapu_free_cert_ava_val: API functions -to get & free an attribute's value(s) from either the subject DN or -the issuer DN from a cert.
  • -
- -

-Open Bugs:

- -
    Following bugs may not get fixed by RTM.
- -
    -
  • -51279: 'uniquemember' -bug
  • - -
  • -58474:  -'circular groups' results in infinite loop
  • - -
  • -58478: Don't -allow a space as a valid delimeter for DNComps & FilterComps.
  • - -
  • -58482: Make -the 'search function' configurable.
  • - -
    -
- -
-

-Changes since Mar 18, 1997

- -
-Last Update: Mar 22, 1997
- -
-A query on how to map a verisign certificate prompted these changes.  -I was hoping I don't have to do any major changes when I wrote this document -on Mar 18. These are incompatible changes -- please review them before -you upgrade.  I have checked in this file in CVS under "ns/netsite/lib/ldaputil/ldapu-changes.html". -I have added all the "XYZ_branch" and "XYZ_point" tags to this file so -that you can easily see this file in your tree.  When I make significant -changes to this file/library, I will retag this file for your branch to -make it same as the server3_branch. [Let me know if I shouldn't do it for -your branch].
- -

-Changed:

- -
    -
  • -ldapu_cert_to_ldap_entry: The major change was to allow for the -mapped DN to be NULL and in that case, start the search from the basedn -of the LDAP server. This required API change so that the basedn can be -passed to the ldapu_cert_to_ldap_entry function. This change was required -for correctly mapping certs from verisign w/o writing plugins. The Verisign -certs can be mapped correctly using the following setting in the <ServerRoot>/userdb/certmap.conf -file:
  • - -
      certmap verisign <verisign's DN> -
      verisign:dncomps -
      verisign:searchcomps cn, e
    -The mapped DN will be NULL so basedn will be used.  The filter will -be -
    (& (cn="<user's CN>") (mail="<user's mail>")).  The -new signature of ldapu_cert_to_ldap_entry is as follows: -
        int ldapu_cert_to_ldap_entry(void *cert, LDAP *ld, -const char *basedn, LDAPMessage **res); -
  • -verify cert functions: A major change in how verify cert functions -work.  This is function is now called even when multiple potential -matches are found for the cert.  The mapping is successful if the -verify function can reduce the number of matches to exactly one.  -For example, if there are multiple "Joe Smith" entries, at most one of -those will have the cert in it's "userCertificate" attr.  The verify -function will select that entry.  The verify function is called with -"LDAPMessage *res" containing all the potential matches.  It should -return a pointer to the matched entry in the new "LDAPMessage **entry" -parameter.  The new signature for CertVerifyFn_t is as follows:
  • - -
        typedef int (*CertVerifyFn_t)(void *cert, LDAP *ld, -LDAPMessage *res, -
      - -

                                                           -LDAPMessage **entry); -

  • -typedef int (*CertMapInitiFn_t): Renamed from CertmapInitFn_t.  -Now this has two extra parameters to make it easy to use it in a plugin. -Other API functions require "issuerDN" but this function was called with -"LDAPUCertMapInfo_t *certinfo".  There was no public API function -to get the issuerDN from "certinfo". The new signature for CertMapInitFn_t -is as follows:
  • - -
        typedef int (*CertMapInitFn_t)(void *certmap_info, -const char *issuerName, -
                                                              -const char *issuerDN); -
  • -(ldapauth.h) ldapu_auth_* functions: For multiple matches, these -functions now return LDAPU_ERR_MULTIPLE_MATCHES instead of LDAPU_FAILED. -This change was required to make nested group membership work efficiently -and enable the new functionality of verify cert function.
  • -
- -
- -
- -
-

-Changes since Feb 1, 1997

- -
-Last Update: Mar 18, 1997
- -
-There have been several changes to the netsite/lib/ldaputil recently. If -you use this library, please start using the latest version of ldaputil -on the server3_branch so that all the servers go out with the same API -and behavior. Review the changes before you upgrade. If you don't plan -to upgrade, please let me know.
- -

-Renamed:

-Following structures and functions are renamed. But this shouldn't affect -you unless you have written a certmap plugin. -
-struct CertMappingFunction_t ---> CertMapFn_t
- -
-struct CertVerifyFunction_t ---> CertVerifyFn_t
- -
-ldapu_set_cert_mapping_function ---> ldapu_set_cert_mapfn
- -
-ldapu_get_cert_mapping_function ---> ldapu_get_cert_mapfn
- -
-ldapu_set_cert_verify_function ---> ldapu_set_cert_verifyfn
- -
-ldapu_get_cert_verify_function ---> ldapu_get_cert_verifyfn
- -

-Removed: (from .h)

-Removed the following functions from .h files. They are still in the .c -file as static functions. I don't think these should be public. If you -think otherwise, let me know. -
-ldapu_cert_mapping_function_default
- -
-ldapu_cert_verify_function_default
- -
-ldapu_search_cert_dn
- -
-ldapu_subject_dn_to_ldap_dn
- -

-Changed:

-The following changes may affect you. Please review them carefully before -you upgrade to the latest version of ldaputil. -
    -
  • -ldapu_auth_userdn_groupdn -- added const char *base argument -for group within group membership check
  • - -
  • -ldap_init and bind calls using LDAPDatabase_t *ldb retry once -if the LDAP server is/went down.
  • - -
  • -typedef CertVerifyFn_t has different arguments.
  • - -
  • -DNs from cert with escaped/quoted characters are correctly handled now.
  • - -
  • -cert to ldap entry mapping is optimized by not using string comparisons -during thruntime. A bitmask is created when the config file is read, cert -data is mapped to bits and compared against the bitmask.
  • - -
  • -Only the required attrs are retrieved in most ldap_search_s calls -from ldaputil. Some new functions were added to keep older functions the -same.
  • - -
  • -Fixed a core dump in ldapu_free_LDAPDatabase_t when using the local db.
  • - -
  • -ldaputil functions for initializing connection to the LDAP server and binding -to the server are thread-safe now. This requires linking to netsite/lib/base. -If you don't use libbase, you can turn off the thread-safe code using a -compile time option.
  • -
- -

-Added:

- -
    -
  • -Documentation to functions in ldaputil.h (customer API) - ldaputil.h is -the external public API for customers to write there plugins.
  • - -
  • -ldapu_get_cert_der - returns raw DER encoded cert data
  • - -
  • -ldapu_cert_to_user - Similar to ldapu_cert_to_ldap_entry but only -retrieves the 'uid' and 'userCertificate' attributes from LDAP and also -extracts the user id.
  • - -
  • -ldapu_find_uid_attrs and ldapu_find_group_attrs - Similar -to ldapu_find_uid and ldapu_find_group resp., but only retrieves the specified -attributes. Internally used during password verification and group membership -checks.
  • - -
  • -ldapu_certinfo_delete, ldapu_certinfo_modify and ldapu_certinfo_save -- API for the certmap config file GUI tool which is not yet developed. -Any volunteers?
  • -
- -

-TODO/Bugs:

- -
    -
  • -uniquemember attribute is not handled correctly in the group membership -check. If the user's entry has 'x500UniqueIdentifier' attribute populated, -the group could refer to the user entry by the user's dn followed by '#' -and an unique identifier. For example, the group entry could have:
  • - -
    -uniquemember: cn=Joe Smith,o=Netscape,c=US#jsmith
    - -
    -where, 'jsmith' is one of the values of the 'x500UniqueIdentifier' attribute -for the Joe Smith entry.
    - -
    -
    -
- - - diff --git a/lib/ldaputil/ldaputili.h b/lib/ldaputil/ldaputili.h deleted file mode 100644 index d1d2708..0000000 --- a/lib/ldaputil/ldaputili.h +++ /dev/null @@ -1,68 +0,0 @@ -/** BEGIN COPYRIGHT BLOCK - * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. - * Copyright (C) 2005 Red Hat, Inc. - * All rights reserved. - * - * License: GPL (version 3 or any later version). - * See LICENSE for details. - * END COPYRIGHT BLOCK **/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#ifndef _LDAPU_LDAPUTILI_H -#define _LDAPU_LDAPUTILI_H - -#include - -#include - -#define BIG_LINE 1024 - -extern const int SEC_OID_AVA_UNKNOWN; /* unknown OID */ - -#ifdef __cplusplus -extern "C" { -#endif - -SECStatus CERT_RFC1485_EscapeAndQuote(char *dst, int dstlen, char *src, int srclen); - -extern void *ldapu_list_empty(LDAPUList_t *list, LDAPUListNodeFn_t free_fn, void *arg); -extern void ldapu_list_move(LDAPUList_t *from, LDAPUList_t *into); - -extern int ldapu_get_cert_ava_val(void *cert_in, int which_dn, const char *attr, char ***val_out); - -extern int ldapu_member_certificate_match(void *cert, const char *desc); - -/* Each of several LDAP API functions has a counterpart here. - * They behave the same, but their implementation may be replaced - * by calling ldapu_VTable_set(); as Directory Server does. - */ -#ifdef USE_LDAP_SSL -extern LDAP *ldapu_ssl_init(const char *host, int port, int encrypted); -#else -extern LDAP *ldapu_init(const char *host, int port); -#endif -extern int ldapu_set_option(LDAP *ld, int opt, void *val); -extern int ldapu_simple_bind_s(LDAP *ld, const char *username, const char *passwd); -extern int ldapu_unbind(LDAP *ld); -extern int ldapu_search_s(LDAP *ld, const char *base, int scope, const char *filter, char **attrs, int attrsonly, LDAPMessage **res); -extern int ldapu_count_entries(LDAP *ld, LDAPMessage *chain); -extern LDAPMessage *ldapu_first_entry(LDAP *ld, LDAPMessage *chain); -extern LDAPMessage *ldapu_next_entry(LDAP *ld, LDAPMessage *entry); -extern int ldapu_msgfree(LDAP *ld, LDAPMessage *chain); -extern char *ldapu_get_dn(LDAP *ld, LDAPMessage *entry); -extern void ldapu_memfree(LDAP *ld, void *dn); -extern char *ldapu_first_attribute(LDAP *ld, LDAPMessage *entry, BerElement **ber); -extern char *ldapu_next_attribute(LDAP *ld, LDAPMessage *entry, BerElement *ber); -extern void ldapu_ber_free(LDAP *ld, BerElement *ber, int freebuf); -extern char **ldapu_get_values(LDAP *ld, LDAPMessage *entry, const char *target); -extern struct berval **ldapu_get_values_len(LDAP *ld, LDAPMessage *entry, const char *target); -extern void ldapu_value_free(LDAP *ld, char **vals); -extern void ldapu_value_free_len(LDAP *ld, struct berval **vals); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/lib/ldaputil/vtable.c b/lib/ldaputil/vtable.c deleted file mode 100644 index 15b833a..0000000 --- a/lib/ldaputil/vtable.c +++ /dev/null @@ -1,210 +0,0 @@ -/** BEGIN COPYRIGHT BLOCK - * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. - * Copyright (C) 2005 Red Hat, Inc. - * All rights reserved. - * - * License: GPL (version 3 or any later version). - * See LICENSE for details. - * END COPYRIGHT BLOCK **/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "ldaputili.h" -#include - -static LDAPUVTable_t ldapu_VTable = {0}; - -/* Replace ldapu_VTable. Subsequently, ldaputil will call the - functions in 'from' (not the LDAP API) to access the directory. - */ -void -ldapu_VTable_set(LDAPUVTable_t *from) -{ - if (from) { - memcpy(&ldapu_VTable, from, sizeof(LDAPUVTable_t)); - } -} - -int -ldapu_set_option(LDAP *ld, int option, void *optdata) -{ - if (ldapu_VTable.ldapuV_set_option) { - return ldapu_VTable.ldapuV_set_option(ld, option, optdata); - } - return LDAP_LOCAL_ERROR; -} - -int -ldapu_simple_bind_s(LDAP *ld, const char *who, const char *passwd) -{ - if (ldapu_VTable.ldapuV_simple_bind_s) { - return ldapu_VTable.ldapuV_simple_bind_s(ld, who, passwd); - } - return LDAP_LOCAL_ERROR; -} - -int -ldapu_unbind(LDAP *ld) -{ - if (ldapu_VTable.ldapuV_unbind) { - return ldapu_VTable.ldapuV_unbind(ld); - } - return LDAP_LOCAL_ERROR; -} - -int -ldapu_search_s(LDAP *ld, const char *base, int scope, const char *filter, char **attrs, int attrsonly, LDAPMessage **res) -{ - if (ldapu_VTable.ldapuV_search_s) { - return ldapu_VTable.ldapuV_search_s(ld, base, scope, filter, attrs, attrsonly, res); - } - return LDAP_LOCAL_ERROR; -} - -int -ldapu_count_entries(LDAP *ld, LDAPMessage *chain) -{ - if (ldapu_VTable.ldapuV_count_entries) { - return ldapu_VTable.ldapuV_count_entries(ld, chain); - } - return 0; -} - -LDAPMessage * -ldapu_first_entry(LDAP *ld, LDAPMessage *chain) -{ - if (ldapu_VTable.ldapuV_first_entry) { - return ldapu_VTable.ldapuV_first_entry(ld, chain); - } - return NULL; -} - -LDAPMessage * -ldapu_next_entry(LDAP *ld, LDAPMessage *entry) -{ - if (ldapu_VTable.ldapuV_next_entry) { - return ldapu_VTable.ldapuV_next_entry(ld, entry); - } - return NULL; -} - -int -ldapu_msgfree(LDAP *ld, LDAPMessage *chain) -{ - if (ldapu_VTable.ldapuV_msgfree) { - return ldapu_VTable.ldapuV_msgfree(ld, chain); - } - return LDAP_SUCCESS; -} - -char * -ldapu_get_dn(LDAP *ld, LDAPMessage *entry) -{ - if (ldapu_VTable.ldapuV_get_dn) { - return ldapu_VTable.ldapuV_get_dn(ld, entry); - } - return NULL; -} - -void -ldapu_memfree(LDAP *ld, void *p) -{ - if (ldapu_VTable.ldapuV_memfree) { - ldapu_VTable.ldapuV_memfree(ld, p); - } -} - -char * -ldapu_first_attribute(LDAP *ld, LDAPMessage *entry, BerElement **ber) -{ - if (ldapu_VTable.ldapuV_first_attribute) { - return ldapu_VTable.ldapuV_first_attribute(ld, entry, ber); - } - return NULL; -} - -char * -ldapu_next_attribute(LDAP *ld, LDAPMessage *entry, BerElement *ber) -{ - if (ldapu_VTable.ldapuV_next_attribute) { - return ldapu_VTable.ldapuV_next_attribute(ld, entry, ber); - } - return NULL; -} - -void -ldapu_ber_free(LDAP *ld, BerElement *ber, int freebuf) -{ - if (ldapu_VTable.ldapuV_ber_free) { - ldapu_VTable.ldapuV_ber_free(ld, ber, freebuf); - } -} - -char ** -ldapu_get_values(LDAP *ld, LDAPMessage *entry, const char *desc) -{ - if (ldapu_VTable.ldapuV_get_values) { - return ldapu_VTable.ldapuV_get_values(ld, entry, desc); - } else if (!ldapu_VTable.ldapuV_value_free && ldapu_VTable.ldapuV_get_values_len) { - auto struct berval **bvals = - ldapu_VTable.ldapuV_get_values_len(ld, entry, desc); - if (bvals) { - auto char **vals = (char **) - ldapu_malloc((ldap_count_values_len(bvals) + 1) * sizeof(char *)); - if (vals) { - auto char **val; - auto struct berval **bval; - for (val = vals, bval = bvals; *bval; ++val, ++bval) { - auto const size_t len = (*bval)->bv_len; - *val = (char *)ldapu_malloc(len + 1); - memcpy(*val, (*bval)->bv_val, len); - (*val)[len] = '\0'; - } - *val = NULL; - ldapu_value_free_len(ld, bvals); - return vals; - } - } - ldapu_value_free_len(ld, bvals); - } - return NULL; -} - -void -ldapu_value_free(LDAP *ld, char **vals) -{ - if (ldapu_VTable.ldapuV_value_free) { - ldapu_VTable.ldapuV_value_free(ld, vals); - } else if (!ldapu_VTable.ldapuV_get_values && vals) { - auto char **val; - for (val = vals; *val; ++val) { - free(*val); - } - free(vals); - } -} - -struct berval ** -ldapu_get_values_len(LDAP *ld, LDAPMessage *entry, const char *desc) -{ - if (ldapu_VTable.ldapuV_get_values_len) { - return ldapu_VTable.ldapuV_get_values_len(ld, entry, desc); - } - return NULL; -} - -void -ldapu_value_free_len(LDAP *ld, struct berval **vals) -{ - if (ldapu_VTable.ldapuV_value_free_len) { - ldapu_VTable.ldapuV_value_free_len(ld, vals); - } else if (!ldapu_VTable.ldapuV_get_values_len && vals) { - auto struct berval **val; - for (val = vals; *val; ++val) { - free(*val); - } - free(vals); - } -} -- 1.8.3.1