diff options
Diffstat (limited to 'crypto/heimdal/lib/hdb/hdb-ldap.c')
-rw-r--r-- | crypto/heimdal/lib/hdb/hdb-ldap.c | 199 |
1 files changed, 110 insertions, 89 deletions
diff --git a/crypto/heimdal/lib/hdb/hdb-ldap.c b/crypto/heimdal/lib/hdb/hdb-ldap.c index 8e90798..aed29b3 100644 --- a/crypto/heimdal/lib/hdb/hdb-ldap.c +++ b/crypto/heimdal/lib/hdb/hdb-ldap.c @@ -32,7 +32,7 @@ #include "hdb_locl.h" -RCSID("$Id: hdb-ldap.c,v 1.10 2002/09/04 18:42:22 joda Exp $"); +RCSID("$Id: hdb-ldap.c,v 1.10.4.1 2003/09/18 20:49:09 lha Exp $"); #ifdef OPENLDAP @@ -62,69 +62,101 @@ static char *krb5principal_attrs[] = NULL }; -/* based on samba: source/passdb/ldap.c */ static krb5_error_code -LDAP_addmod_len(LDAPMod *** modlist, int modop, const char *attribute, - unsigned char *value, size_t len) +LDAP__setmod(LDAPMod *** modlist, int modop, const char *attribute, + int *pIndex) { - LDAPMod **mods = *modlist; - int i, j; + int cMods; - if (mods == NULL) { - mods = (LDAPMod **) calloc(1, sizeof(LDAPMod *)); - if (mods == NULL) { + if (*modlist == NULL) { + *modlist = (LDAPMod **)ber_memcalloc(1, sizeof(LDAPMod *)); + if (*modlist == NULL) { return ENOMEM; } - mods[0] = NULL; } - for (i = 0; mods[i] != NULL; ++i) { - if ((mods[i]->mod_op & (~LDAP_MOD_BVALUES)) == modop - && (!strcasecmp(mods[i]->mod_type, attribute))) { + for (cMods = 0; (*modlist)[cMods] != NULL; cMods++) { + if ((*modlist)[cMods]->mod_op == modop && + strcasecmp((*modlist)[cMods]->mod_type, attribute) == 0) { break; } } - if (mods[i] == NULL) { - mods = (LDAPMod **) realloc(mods, (i + 2) * sizeof(LDAPMod *)); - if (mods == NULL) { + *pIndex = cMods; + + if ((*modlist)[cMods] == NULL) { + LDAPMod *mod; + + *modlist = (LDAPMod **)ber_memrealloc(*modlist, + (cMods + 2) * sizeof(LDAPMod *)); + if (*modlist == NULL) { return ENOMEM; } - mods[i] = (LDAPMod *) malloc(sizeof(LDAPMod)); - if (mods[i] == NULL) { + (*modlist)[cMods] = (LDAPMod *)ber_memalloc(sizeof(LDAPMod)); + if ((*modlist)[cMods] == NULL) { return ENOMEM; } - mods[i]->mod_op = modop | LDAP_MOD_BVALUES; - mods[i]->mod_bvalues = NULL; - mods[i]->mod_type = strdup(attribute); - if (mods[i]->mod_type == NULL) { + + mod = (*modlist)[cMods]; + mod->mod_op = modop; + mod->mod_type = ber_strdup(attribute); + if (mod->mod_type == NULL) { + ber_memfree(mod); + (*modlist)[cMods] = NULL; return ENOMEM; } - mods[i + 1] = NULL; + + if (modop & LDAP_MOD_BVALUES) { + mod->mod_bvalues = NULL; + } else { + mod->mod_values = NULL; + } + + (*modlist)[cMods + 1] = NULL; + } + + return 0; +} + +static krb5_error_code +LDAP_addmod_len(LDAPMod *** modlist, int modop, const char *attribute, + unsigned char *value, size_t len) +{ + int cMods, cValues = 0; + krb5_error_code ret; + + ret = LDAP__setmod(modlist, modop | LDAP_MOD_BVALUES, attribute, &cMods); + if (ret != 0) { + return ret; } if (value != NULL) { - j = 0; - if (mods[i]->mod_bvalues != NULL) { - for (; mods[i]->mod_bvalues[j] != NULL; j++); + struct berval *bValue; + struct berval ***pbValues = &((*modlist)[cMods]->mod_bvalues); + + if (*pbValues != NULL) { + for (cValues = 0; (*pbValues)[cValues] != NULL; cValues++) + ; + *pbValues = (struct berval **)ber_memrealloc(*pbValues, (cValues + 2) + * sizeof(struct berval *)); + } else { + *pbValues = (struct berval **)ber_memalloc(2 * sizeof(struct berval *)); } - mods[i]->mod_bvalues = - (struct berval **) realloc(mods[i]->mod_bvalues, - (j + 2) * sizeof(struct berval *)); - if (mods[i]->mod_bvalues == NULL) { + if (*pbValues == NULL) { return ENOMEM; } - /* Caller allocates memory on our behalf, unlike LDAP_addmod. */ - mods[i]->mod_bvalues[j] = - (struct berval *) malloc(sizeof(struct berval)); - if (mods[i]->mod_bvalues[j] == NULL) { + (*pbValues)[cValues] = (struct berval *)ber_memalloc(sizeof(struct berval));; + if ((*pbValues)[cValues] == NULL) { return ENOMEM; } - mods[i]->mod_bvalues[j]->bv_val = value; - mods[i]->mod_bvalues[j]->bv_len = len; - mods[i]->mod_bvalues[j + 1] = NULL; + + bValue = (*pbValues)[cValues]; + bValue->bv_val = value; + bValue->bv_len = len; + + (*pbValues)[cValues + 1] = NULL; } - *modlist = mods; + return 0; } @@ -132,59 +164,34 @@ static krb5_error_code LDAP_addmod(LDAPMod *** modlist, int modop, const char *attribute, const char *value) { - LDAPMod **mods = *modlist; - int i, j; + int cMods, cValues = 0; + krb5_error_code ret; - if (mods == NULL) { - mods = (LDAPMod **) calloc(1, sizeof(LDAPMod *)); - if (mods == NULL) { - return ENOMEM; - } - mods[0] = NULL; + ret = LDAP__setmod(modlist, modop, attribute, &cMods); + if (ret != 0) { + return ret; } - for (i = 0; mods[i] != NULL; ++i) { - if (mods[i]->mod_op == modop - && (!strcasecmp(mods[i]->mod_type, attribute))) { - break; - } - } + if (value != NULL) { + char ***pValues = &((*modlist)[cMods]->mod_values); - if (mods[i] == NULL) { - mods = (LDAPMod **) realloc(mods, (i + 2) * sizeof(LDAPMod *)); - if (mods == NULL) { - return ENOMEM; + if (*pValues != NULL) { + for (cValues = 0; (*pValues)[cValues] != NULL; cValues++) + ; + *pValues = (char **)ber_memrealloc(*pValues, (cValues + 2) * sizeof(char *)); + } else { + *pValues = (char **)ber_memalloc(2 * sizeof(char *)); } - mods[i] = (LDAPMod *) malloc(sizeof(LDAPMod)); - if (mods[i] == NULL) { + if (*pValues == NULL) { return ENOMEM; } - mods[i]->mod_op = modop; - mods[i]->mod_values = NULL; - mods[i]->mod_type = strdup(attribute); - if (mods[i]->mod_type == NULL) { + (*pValues)[cValues] = ber_strdup(value); + if ((*pValues)[cValues] == NULL) { return ENOMEM; } - mods[i + 1] = NULL; + (*pValues)[cValues + 1] = NULL; } - if (value != NULL) { - j = 0; - if (mods[i]->mod_values != NULL) { - for (; mods[i]->mod_values[j] != NULL; j++); - } - mods[i]->mod_values = (char **) realloc(mods[i]->mod_values, - (j + 2) * sizeof(char *)); - if (mods[i]->mod_values == NULL) { - return ENOMEM; - } - mods[i]->mod_values[j] = strdup(value); - if (mods[i]->mod_values[j] == NULL) { - return ENOMEM; - } - mods[i]->mod_values[j + 1] = NULL; - } - *modlist = mods; return 0; } @@ -421,12 +428,10 @@ LDAP_entry2mods(krb5_context context, HDB * db, hdb_entry * ent, } } - memset(&oflags, 0, sizeof(oflags)); - memcpy(&oflags, &orig.flags, sizeof(HDBFlags)); - memset(&nflags, 0, sizeof(nflags)); - memcpy(&nflags, &ent->flags, sizeof(HDBFlags)); + oflags = HDBFlags2int(orig.flags); + nflags = HDBFlags2int(ent->flags); - if (memcmp(&oflags, &nflags, sizeof(HDBFlags))) { + if (oflags != nflags) { rc = asprintf(&tmp, "%lu", nflags); if (rc < 0) { krb5_set_error_string(context, "asprintf: out of memory"); @@ -629,7 +634,7 @@ LDAP_message2entry(krb5_context context, HDB * db, LDAPMessage * msg, char **values; memset(ent, 0, sizeof(*ent)); - memset(&ent->flags, 0, sizeof(HDBFlags)); + ent->flags = int2HDBFlags(0); ret = LDAP_get_string_value(db, msg, "krb5PrincipalName", @@ -801,7 +806,7 @@ LDAP_message2entry(krb5_context context, HDB * db, LDAPMessage * msg, } else { tmp = 0; } - memcpy(&ent->flags, &tmp, sizeof(HDBFlags)); + ent->flags = int2HDBFlags(tmp); values = ldap_get_values((LDAP *) db->db, msg, "krb5EncryptionType"); if (values != NULL) { @@ -953,6 +958,13 @@ LDAP_rename(krb5_context context, HDB * db, const char *new_name) static krb5_error_code LDAP__connect(krb5_context context, HDB * db) { int rc, version = LDAP_VERSION3; + /* + * Empty credentials to do a SASL bind with LDAP. Note that empty + * different from NULL credentials. If you provide NULL + * credentials instead of empty credentials you will get a SASL + * bind in progress message. + */ + struct berval bv = { 0, "" }; if (db->db != NULL) { /* connection has been opened. ping server. */ @@ -986,6 +998,14 @@ static krb5_error_code LDAP__connect(krb5_context context, HDB * db) return HDB_ERR_BADVERSION; } + rc = ldap_sasl_bind_s((LDAP *) db->db, NULL, "EXTERNAL", &bv, NULL, NULL, NULL); + if (rc != LDAP_SUCCESS) { + krb5_set_error_string(context, "ldap_sasl_bind_s: %s", ldap_err2string(rc)); + ldap_unbind_ext((LDAP *) db->db, NULL, NULL); + db->db = NULL; + return HDB_ERR_BADVERSION; + } + return 0; } @@ -1104,7 +1124,7 @@ LDAP_store(krb5_context context, HDB * db, unsigned flags, ret = asprintf(&dn, "cn=%s,%s", name, db->name); } else { /* A bit bogus, but we don't have a search base */ - ret = asprintf(&dn, "cn=%s", name, db->name); + ret = asprintf(&dn, "cn=%s", name); } if (ret < 0) { krb5_set_error_string(context, "asprintf: out of memory"); @@ -1134,7 +1154,8 @@ LDAP_store(krb5_context context, HDB * db, unsigned flags, if (rc == LDAP_SUCCESS) { ret = 0; } else { - krb5_set_error_string(context, "%s: %s", errfn, ldap_err2string(rc)); + krb5_set_error_string(context, "%s: %s (dn=%s) %s", + errfn, name, dn, ldap_err2string(rc)); ret = HDB_ERR_CANT_LOCK_DB; } |