From 452e98c1320aa63d03adde3742ba32660410e086 Mon Sep 17 00:00:00 2001 From: Johan Danielsson Date: Fri, 31 Aug 2001 18:19:49 +0000 Subject: [PATCH] some pretty much untested changes from Luke Howard git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@10616 ec53bebd-3082-4978-b11e-865c3cabbd6b --- lib/hdb/hdb-ldap.c | 262 +++++++++++++++++++++------------------------ 1 file changed, 120 insertions(+), 142 deletions(-) diff --git a/lib/hdb/hdb-ldap.c b/lib/hdb/hdb-ldap.c index 5988608fc..60487a10d 100644 --- a/lib/hdb/hdb-ldap.c +++ b/lib/hdb/hdb-ldap.c @@ -335,6 +335,7 @@ LDAP_entry2mods(krb5_context context, HDB * db, hdb_entry * ent, if (ent->kvno != orig.kvno) { rc = asprintf(&tmp, "%d", ent->kvno); if (rc < 0) { + krb5_set_error_string(context, "asprintf: out of memory"); ret = ENOMEM; goto out; } @@ -390,6 +391,7 @@ LDAP_entry2mods(krb5_context context, HDB * db, hdb_entry * ent, || (*(ent->max_life) != *(orig.max_life))) { rc = asprintf(&tmp, "%d", *(ent->max_life)); if (rc < 0) { + krb5_set_error_string(context, "asprintf: out of memory"); ret = ENOMEM; goto out; } @@ -406,6 +408,7 @@ LDAP_entry2mods(krb5_context context, HDB * db, hdb_entry * ent, || (*(ent->max_renew) != *(orig.max_renew))) { rc = asprintf(&tmp, "%d", *(ent->max_renew)); if (rc < 0) { + krb5_set_error_string(context, "asprintf: out of memory"); ret = ENOMEM; goto out; } @@ -426,6 +429,7 @@ LDAP_entry2mods(krb5_context context, HDB * db, hdb_entry * ent, if (memcmp(&oflags, &nflags, sizeof(HDBFlags))) { rc = asprintf(&tmp, "%lu", nflags); if (rc < 0) { + krb5_set_error_string(context, "asprintf: out of memory"); ret = ENOMEM; goto out; } @@ -457,6 +461,7 @@ LDAP_entry2mods(krb5_context context, HDB * db, hdb_entry * ent, len = length_Key(&new); buf = malloc(len); if (buf == NULL) { + krb5_set_error_string(context, "malloc: out of memory"); ret = ENOMEM; free_Key(&new); goto out; @@ -487,6 +492,7 @@ LDAP_entry2mods(krb5_context context, HDB * db, hdb_entry * ent, for (i = 0; i < ent->etypes->len; i++) { rc = asprintf(&tmp, "%d", ent->etypes->val[i]); if (rc < 0) { + krb5_set_error_string(context, "asprintf: out of memory"); ret = ENOMEM; goto out; } @@ -524,17 +530,22 @@ LDAP_dn2principal(krb5_context context, HDB * db, const char *dn, krb5_principal * principal) { krb5_error_code ret; - int rc; + int rc, limit = 1; char **values; LDAPMessage *res = NULL, *e; - rc = 1; - (void) ldap_set_option((LDAP *) db->db, LDAP_OPT_SIZELIMIT, &rc); - rc = ldap_search_s((LDAP *) db->db, db->name, LDAP_SCOPE_BASE, + rc = ldap_set_option((LDAP *) db->db, LDAP_OPT_SIZELIMIT, (const void *)&limit); + if (rc != LDAP_SUCCESS) { + krb5_set_error_string(context, "ldap_set_option: %s", ldap_err2string(rc)); + ret = HDB_ERR_BADVERSION; + goto out; + } + + rc = ldap_search_s((LDAP *) db->db, dn, LDAP_SCOPE_BASE, "(objectclass=krb5Principal)", krb5principal_attrs, 0, &res); - if (rc != LDAP_SUCCESS) { + krb5_set_error_string(context, "ldap_search_s: %s", ldap_err2string(rc)); ret = HDB_ERR_NOENTRY; goto out; } @@ -566,7 +577,7 @@ LDAP__lookup_princ(krb5_context context, HDB * db, const char *princname, LDAPMessage ** msg) { krb5_error_code ret; - int rc; + int rc, limit = 1; char *filter = NULL; (void) LDAP__connect(context, db); @@ -576,16 +587,22 @@ LDAP__lookup_princ(krb5_context context, HDB * db, const char *princname, "(&(objectclass=krb5KDCEntry)(krb5PrincipalName=%s))", princname); if (rc < 0) { + krb5_set_error_string(context, "asprintf: out of memory"); ret = ENOMEM; goto out; } - rc = 1; - (void) ldap_set_option((LDAP *) db->db, LDAP_OPT_SIZELIMIT, (void *) &rc); + rc = ldap_set_option((LDAP *) db->db, LDAP_OPT_SIZELIMIT, (const void *)&limit); + if (rc != LDAP_SUCCESS) { + krb5_set_error_string(context, "ldap_set_option: %s", ldap_err2string(rc)); + ret = HDB_ERR_BADVERSION; + goto out; + } rc = ldap_search_s((LDAP *) db->db, db->name, LDAP_SCOPE_ONELEVEL, filter, krb5kdcentry_attrs, 0, msg); if (rc != LDAP_SUCCESS) { + krb5_set_error_string(context, "ldap_search_s: %s", ldap_err2string(rc)); ret = HDB_ERR_NOENTRY; goto out; } @@ -659,6 +676,11 @@ LDAP_message2entry(krb5_context context, HDB * db, LDAPMessage * msg, ent->keys.len = ldap_count_values_len(keys); ent->keys.val = (Key *) calloc(ent->keys.len, sizeof(Key)); + if (ent->keys.val == NULL) { + krb5_set_error_string(context, "calloc: out of memory"); + ret = ENOMEM; + goto out; + } for (i = 0; i < ent->keys.len; i++) { decode_Key((unsigned char *) keys[i]->bv_val, (size_t) keys[i]->bv_len, &ent->keys.val[i], &l); @@ -699,6 +721,7 @@ LDAP_message2entry(krb5_context context, HDB * db, LDAPMessage * msg, ent->modified_by = (Event *) malloc(sizeof(Event)); if (ent->modified_by == NULL) { + krb5_set_error_string(context, "malloc: out of memory"); ret = ENOMEM; goto out; } @@ -719,6 +742,7 @@ LDAP_message2entry(krb5_context context, HDB * db, LDAPMessage * msg, if ((ent->valid_start = (KerberosTime *) malloc(sizeof(KerberosTime))) == NULL) { + krb5_set_error_string(context, "malloc: out of memory"); ret = ENOMEM; goto out; } @@ -732,7 +756,9 @@ LDAP_message2entry(krb5_context context, HDB * db, LDAPMessage * msg, } if ((ent->valid_end = (KerberosTime *) malloc(sizeof(KerberosTime))) == - NULL) {ret = ENOMEM; + NULL) { + krb5_set_error_string(context, "malloc: out of memory"); + ret = ENOMEM; goto out; } ret = @@ -745,7 +771,9 @@ LDAP_message2entry(krb5_context context, HDB * db, LDAPMessage * msg, } if ((ent->pw_end = (KerberosTime *) malloc(sizeof(KerberosTime))) == - NULL) {ret = ENOMEM; + NULL) { + krb5_set_error_string(context, "malloc: out of memory"); + ret = ENOMEM; goto out; } ret = @@ -759,6 +787,7 @@ LDAP_message2entry(krb5_context context, HDB * db, LDAPMessage * msg, ent->max_life = (int *) malloc(sizeof(int)); if (ent->max_life == NULL) { + krb5_set_error_string(context, "malloc: out of memory"); ret = ENOMEM; goto out; } @@ -770,6 +799,7 @@ LDAP_message2entry(krb5_context context, HDB * db, LDAPMessage * msg, ent->max_renew = (int *) malloc(sizeof(int)); if (ent->max_renew == NULL) { + krb5_set_error_string(context, "malloc: out of memory"); ret = ENOMEM; goto out; } @@ -783,6 +813,7 @@ LDAP_message2entry(krb5_context context, HDB * db, LDAPMessage * msg, if (values != NULL) { tmp = strtoul(values[0], (char **) NULL, 10); if (tmp == ULONG_MAX && errno == ERANGE) { + krb5_set_error_string(context, "strtoul: could not convert flag"); ret = ERANGE; goto out; } @@ -797,6 +828,7 @@ LDAP_message2entry(krb5_context context, HDB * db, LDAPMessage * msg, ent->etypes = malloc(sizeof(*(ent->etypes))); if (ent->etypes == NULL) { + krb5_set_error_string(context, "malloc: out of memory"); ret = ENOMEM; goto out; } @@ -825,10 +857,9 @@ LDAP_message2entry(krb5_context context, HDB * db, LDAPMessage * msg, static krb5_error_code LDAP_close(krb5_context context, HDB * db) { - LDAP *ld = (LDAP *) db->db; - - ldap_unbind(ld); + ldap_unbind_ext((LDAP *) db->db, NULL, NULL); db->db = NULL; + return 0; } @@ -870,6 +901,7 @@ LDAP_seq(krb5_context context, HDB * db, unsigned flags, hdb_entry * entry) NULL, NULL, 1); if (parserc != LDAP_SUCCESS && parserc != LDAP_MORE_RESULTS_TO_RETURN) { + krb5_set_error_string(context, "ldap_parse_result: %s", ldap_err2string(parserc)); ldap_abandon((LDAP *) db->db, msgid); } ret = HDB_ERR_NOENTRY; @@ -902,12 +934,15 @@ static krb5_error_code LDAP_firstkey(krb5_context context, HDB * db, unsigned flags, hdb_entry * entry) { - int msgid; + int msgid, limit = LDAP_NO_LIMIT, rc; (void) LDAP__connect(context, db); - msgid = LDAP_NO_LIMIT; - (void) ldap_set_option((LDAP *) db->db, LDAP_OPT_SIZELIMIT, &msgid); + rc = ldap_set_option((LDAP *) db->db, LDAP_OPT_SIZELIMIT, (const void *)&limit); + if (rc != LDAP_SUCCESS) { + krb5_set_error_string(context, "ldap_set_option: %s", ldap_err2string(rc)); + return HDB_ERR_BADVERSION; + } msgid = ldap_search((LDAP *) db->db, db->name, LDAP_SCOPE_ONELEVEL, "(objectclass=krb5KDCEntry)", @@ -934,33 +969,9 @@ LDAP_rename(krb5_context context, HDB * db, const char *new_name) return HDB_ERR_DB_INUSE; } -static krb5_boolean LDAP__is_user_namingcontext(const char *ctx, - char *const *subschema) -{ - char *const *p; - - if (!strcasecmp(ctx, "CN=MONITOR") - || !strcasecmp(ctx, "CN=CONFIG")) { - return FALSE; - } - - if (subschema != NULL) { - for (p = subschema; *p != NULL; p++) { - if (!strcasecmp(ctx, *p)) { - return FALSE; - } - } - } - - return TRUE; -} - static krb5_error_code LDAP__connect(krb5_context context, HDB * db) { - int rc; - krb5_error_code ret; - char *attrs[] = { "namingContexts", "subschemaSubentry", NULL }; - LDAPMessage *res = NULL, *e; + int rc, version = LDAP_VERSION3; if (db->db != NULL) { /* connection has been opened. ping server. */ @@ -982,111 +993,38 @@ static krb5_error_code LDAP__connect(krb5_context context, HDB * db) rc = ldap_initialize((LDAP **) & db->db, "ldapi:///"); if (rc != LDAP_SUCCESS) { + krb5_set_error_string(context, "ldap_initialize: %s", ldap_err2string(rc)); return HDB_ERR_NOENTRY; } - rc = LDAP_VERSION3; - (void) ldap_set_option((LDAP *) db->db, LDAP_OPT_PROTOCOL_VERSION, &rc); - - /* XXX set db->name to the search base */ - rc = ldap_search_s((LDAP *) db->db, "", LDAP_SCOPE_BASE, - "(objectclass=*)", attrs, 0, &res); + rc = ldap_set_option((LDAP *) db->db, LDAP_OPT_PROTOCOL_VERSION, (const void *)&version); if (rc != LDAP_SUCCESS) { - ret = HDB_ERR_BADVERSION; - goto out; + krb5_set_error_string(context, "ldap_set_option: %s", ldap_err2string(rc)); + ldap_unbind_ext((LDAP *) db->db, NULL, NULL); + db->db = NULL; + return HDB_ERR_BADVERSION; } - e = ldap_first_entry((LDAP *) db->db, res); - if (e == NULL) { - ret = HDB_ERR_NOENTRY; - goto out; - } - - if (db->name == NULL) { - char **contexts = NULL, **schema_contexts, **p; - - contexts = ldap_get_values((LDAP *) db->db, e, "namingContexts"); - if (contexts == NULL) { - ret = HDB_ERR_NOENTRY; - goto out; - } - - schema_contexts = - ldap_get_values((LDAP *) db->db, e, "subschemaSubentry"); - - if (db->name != NULL) { - free(db->name); - db->name = NULL; - } - - for (p = contexts; *p != NULL; p++) { - if (LDAP__is_user_namingcontext(*p, schema_contexts)) { - break; - } - } - - db->name = strdup(*p); - if (db->name == NULL) { - ldap_value_free(contexts); - ret = ENOMEM; - goto out; - } - - ldap_value_free(contexts); - if (schema_contexts != NULL) { - ldap_value_free(schema_contexts); - } - } - - ret = 0; - - out: - - if (res != NULL) { - ldap_msgfree(res); - } - - if (ret != 0) { - if (db->db != NULL) { - ldap_unbind((LDAP *) db->db); - db->db = NULL; - } - } - - return ret; + return 0; } static krb5_error_code LDAP_open(krb5_context context, HDB * db, int flags, mode_t mode) { - krb5_error_code ret; - /* Not the right place for this. */ #ifdef HAVE_SIGACTION - { - struct sigaction sa; + struct sigaction sa; - sa.sa_flags = 0; - sa.sa_handler = SIG_IGN; - sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + sa.sa_handler = SIG_IGN; + sigemptyset(&sa.sa_mask); - sigaction(SIGPIPE, &sa, NULL); - } + sigaction(SIGPIPE, &sa, NULL); #else signal(SIGPIPE, SIG_IGN); -#endif +#endif /* HAVE_SIGACTION */ - if (db->name != NULL) { - free(db->name); - db->name = NULL; - } - - ret = LDAP__connect(context, db); - if (ret != 0) { - return ret; - } - - return ret; + return LDAP__connect(context, db); } static krb5_error_code @@ -1128,6 +1066,8 @@ LDAP_store(krb5_context context, HDB * db, unsigned flags, { LDAPMod **mods = NULL; krb5_error_code ret; + const char *errfn; + int rc; LDAPMessage *msg = NULL, *e = NULL; char *dn = NULL, *name = NULL; @@ -1142,8 +1082,9 @@ LDAP_store(krb5_context context, HDB * db, unsigned flags, } ret = hdb_seal_keys(context, db, entry); - if (ret) + if (ret != 0) { goto out; + } /* turn new entry into LDAPMod array */ ret = LDAP_entry2mods(context, db, entry, e, &mods); @@ -1178,8 +1119,14 @@ LDAP_store(krb5_context context, HDB * db, unsigned flags, goto out; } - ret = asprintf(&dn, "cn=%s,%s", name, db->name); + if (db->name != NULL) { + 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); + } if (ret < 0) { + krb5_set_error_string(context, "asprintf: out of memory"); ret = ENOMEM; goto out; } @@ -1195,15 +1142,18 @@ LDAP_store(krb5_context context, HDB * db, unsigned flags, /* write entry into directory */ if (e == NULL) { /* didn't exist before */ - ret = ldap_add_s((LDAP *) db->db, dn, mods); + rc = ldap_add_s((LDAP *) db->db, dn, mods); + errfn = "ldap_add_s"; } else { /* already existed, send deltas only */ - ret = ldap_modify_s((LDAP *) db->db, dn, mods); + rc = ldap_modify_s((LDAP *) db->db, dn, mods); + errfn = "ldap_modify_s"; } - if (ret == LDAP_SUCCESS) { + if (rc == LDAP_SUCCESS) { ret = 0; } else { + krb5_set_error_string(context, "%s: %s", errfn, ldap_err2string(rc)); ret = HDB_ERR_CANT_LOCK_DB; } @@ -1234,6 +1184,7 @@ LDAP_remove(krb5_context context, HDB * db, hdb_entry * entry) krb5_error_code ret; LDAPMessage *msg, *e; char *dn = NULL; + int rc, limit = LDAP_NO_LIMIT; ret = LDAP_principal2message(context, db, entry->principal, &msg); if (ret != 0) { @@ -1252,13 +1203,18 @@ LDAP_remove(krb5_context context, HDB * db, hdb_entry * entry) goto out; } - ret = LDAP_NO_LIMIT; - (void) ldap_set_option((LDAP *) db->db, LDAP_OPT_SIZELIMIT, &ret); + rc = ldap_set_option((LDAP *) db->db, LDAP_OPT_SIZELIMIT, (const void *)&limit); + if (rc != LDAP_SUCCESS) { + krb5_set_error_string(context, "ldap_set_option: %s", ldap_err2string(rc)); + ret = HDB_ERR_BADVERSION; + goto out; + } - ret = ldap_delete_s((LDAP *) db->db, dn); - if (ret == LDAP_SUCCESS) { + rc = ldap_delete_s((LDAP *) db->db, dn); + if (rc == LDAP_SUCCESS) { ret = 0; } else { + krb5_set_error_string(context, "ldap_delete_s: %s", ldap_err2string(rc)); ret = HDB_ERR_CANT_LOCK_DB; } @@ -1304,22 +1260,44 @@ static krb5_error_code LDAP_destroy(krb5_context context, HDB * db) krb5_error_code ret; ret = hdb_clear_master_key(context, db); - free(db->name); + if (db->name != NULL) { + free(db->name); + } free(db); return ret; } krb5_error_code -hdb_ldap_create(krb5_context context, HDB ** db, const char *filename) +hdb_ldap_create(krb5_context context, HDB ** db, const char *arg) { *db = malloc(sizeof(**db)); - if (*db == NULL) + if (*db == NULL) { + krb5_set_error_string(context, "malloc: out of memory"); return ENOMEM; + } (*db)->db = NULL; -/* (*db)->name = strdup(filename); */ - (*db)->name = NULL; + + if (arg == NULL || arg[0] == '\0') { + /* + * if no argument specified in the configuration file + * then use NULL, which tells OpenLDAP to look in + * the ldap.conf file. This doesn't work for + * writing entries because we don't know where to + * put new principals. + */ + (*db)->name = NULL; + } else { + (*db)->name = strdup(arg); + if ((*db)->name == NULL) { + krb5_set_error_string(context, "strdup: out of memory"); + free(*db); + *db = NULL; + return ENOMEM; + } + } + (*db)->master_key_set = 0; (*db)->openp = 0; (*db)->open = LDAP_open;