From 5658348b5929bed246dcc58cfd8eb0f8ac61c2f3 Mon Sep 17 00:00:00 2001 From: Will Fiveash Date: Sat, 21 Oct 2006 00:33:24 +0000 Subject: [PATCH] enabling LDAP mix-in support for kdb5_util load I now have mix-in working for the kdb5_util load. If the krbSubTrees realm attr contains a base DN where non-krb entries live the load/krb5_ldap_put_principal() code will modify those entries whose krbPrincipalName attr matches that of the dump princ record being loaded otherwise a standalone krbprinc entry will be created under the realm container. I also fixed a small bug in krb5_ldap_policydn_to_name() for the version that uses ldap_explode_dn(). ticket: new git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@18729 dc483132-0cff-0310-8789-dd5450dbe970 --- src/kadmin/dbutil/dump.c | 36 +++++- src/lib/kadm5/admin.h | 3 + src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.c | 15 ++- .../kdb/ldap/libkdb_ldap/ldap_create.c | 50 ++++--- .../kdb/ldap/libkdb_ldap/ldap_krbcontainer.h | 4 + src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c | 17 +-- .../kdb/ldap/libkdb_ldap/ldap_principal2.c | 122 +++++++++++++++--- src/plugins/kdb/ldap/libkdb_ldap/ldap_realm.c | 50 ++++++- 8 files changed, 238 insertions(+), 59 deletions(-) diff --git a/src/kadmin/dbutil/dump.c b/src/kadmin/dbutil/dump.c index e1f1d8848..314156ea0 100644 --- a/src/kadmin/dbutil/dump.c +++ b/src/kadmin/dbutil/dump.c @@ -1608,7 +1608,7 @@ process_k5beta_record(fname, kcontext, filep, verbose, linenop) && (akey->key_data_length[1] == 0)) dbent.n_key_data--; - dbent.mask = KADM5_PRINCIPAL | KADM5_ATTRIBUTES | + dbent.mask = KADM5_LOAD | KADM5_PRINCIPAL | KADM5_ATTRIBUTES | KADM5_MAX_LIFE | KADM5_MAX_RLIFE | KADM5_KEY_DATA | KADM5_PRINC_EXPIRE_TIME | KADM5_LAST_SUCCESS | KADM5_LAST_FAILED | KADM5_FAIL_AUTH_COUNT; @@ -1762,7 +1762,7 @@ process_k5beta6_record(fname, kcontext, filep, verbose, linenop) dbentry.last_success = (krb5_timestamp) t7; dbentry.last_failed = (krb5_timestamp) t8; dbentry.fail_auth_count = (krb5_kvno) t9; - dbentry.mask = KADM5_PRINCIPAL | KADM5_ATTRIBUTES | + dbentry.mask = KADM5_LOAD | KADM5_PRINCIPAL | KADM5_ATTRIBUTES | KADM5_MAX_LIFE | KADM5_MAX_RLIFE | KADM5_PRINC_EXPIRE_TIME | KADM5_LAST_SUCCESS | KADM5_LAST_FAILED | KADM5_FAIL_AUTH_COUNT; @@ -2294,8 +2294,19 @@ load_db(argc, argv) */ if (!update) { if((kret = krb5_db_create(kcontext, db5util_db_args))) { - fprintf(stderr, dbcreaterr_fmt, - programname, dbname, error_message(kret)); + const char *emsg = krb5_get_error_message(kcontext, kret); + /* + * See if something (like DAL KDB plugin) has set a specific error + * message and use that otherwise use default. + */ + + if (emsg != NULL) { + fprintf(stderr, "%s: %s\n", programname, emsg); + krb5_free_error_message (kcontext, emsg); + } else { + fprintf(stderr, dbcreaterr_fmt, + programname, dbname, error_message(kret)); + } exit_status++; kadm5_free_config_params(kcontext, &newparams); if (dumpfile) fclose(f); @@ -2307,9 +2318,20 @@ load_db(argc, argv) * Initialize the database. */ if ((kret = krb5_db_open(kcontext, db5util_db_args, - KRB5_KDB_OPEN_RW | KRB5_KDB_SRV_TYPE_OTHER))) { - fprintf(stderr, dbinit_err_fmt, - programname, error_message(kret)); + KRB5_KDB_OPEN_RW | KRB5_KDB_SRV_TYPE_ADMIN))) { + const char *emsg = krb5_get_error_message(kcontext, kret); + /* + * See if something (like DAL KDB plugin) has set a specific + * error message and use that otherwise use default. + */ + + if (emsg != NULL) { + fprintf(stderr, "%s: %s\n", programname, emsg); + krb5_free_error_message (kcontext, emsg); + } else { + fprintf(stderr, dbinit_err_fmt, + programname, error_message(kret)); + } exit_status++; goto error; } diff --git a/src/lib/kadm5/admin.h b/src/lib/kadm5/admin.h index b64e9e7fc..99d18d4e2 100644 --- a/src/lib/kadm5/admin.h +++ b/src/lib/kadm5/admin.h @@ -92,9 +92,12 @@ typedef long kadm5_ret_t; #define KADM5_CPW_FUNCTION 0x080000 #define KADM5_RANDKEY_USED 0x100000 #endif +#define KADM5_LOAD 0x200000 + /* all but KEY_DATA and TL_DATA */ #define KADM5_PRINCIPAL_NORMAL_MASK 0x01ffff + /* kadm5_policy_ent_t */ #define KADM5_PW_MAX_LIFE 0x004000 #define KADM5_PW_MIN_LIFE 0x008000 diff --git a/src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.c b/src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.c index 5aed96237..e5bf6c11d 100644 --- a/src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.c +++ b/src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.c @@ -374,13 +374,20 @@ krb5_error_code krb5_ldap_open(krb5_context context, sprintf(ldap_context->root_certificate_file,"%s %s", oldstr, val); free (oldstr); } - } else if (opt && !strcmp(opt, "temporary")) { - /* ignore temporary argument, it is a kdb5_util arg meant for db2 */ } else { /* ignore hash argument. Might have been passed from create */ status = EINVAL; - krb5_set_error_message (context, status, "unknown option \'%s\'", - opt?opt:val); + if (opt && !strcmp(opt, "temporary")) { + /* + * temporary is passed in when kdb5_util load without -update is done. + * This is unsupported by the LDAP plugin. + */ + krb5_set_error_message (context, status, + "open of LDAP directory aborted, plugin requires -update argument"); + } else { + krb5_set_error_message (context, status, "unknown option \'%s\'", + opt?opt:val); + } free(opt); free(val); goto clean_n_exit; diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_create.c b/src/plugins/kdb/ldap/libkdb_ldap/ldap_create.c index 54f0576ae..3162bdc26 100644 --- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_create.c +++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_create.c @@ -54,6 +54,7 @@ krb5_ldap_create (krb5_context context, char *conf_section, char **db_args) krb5_ldap_context *ldap_context=NULL; krb5_boolean realm_obj_created = FALSE; krb5_boolean krbcontainer_obj_created = FALSE; + krb5_ldap_krbcontainer_params kparams = {0}; int srv_cnt = 0; int mask = 0; #ifdef HAVE_EDIRECTORY @@ -218,13 +219,20 @@ krb5_ldap_create (krb5_context context, char *conf_section, char **db_args) sprintf(ldap_context->root_certificate_file,"%s %s", oldstr, val); free (oldstr); } - } else if (opt && !strcmp(opt, "temporary")) { - /* ignore temporary argument, it is a kdb5_util arg meant for db2 */ } else { /* ignore hash argument. Might have been passed from create */ status = EINVAL; - krb5_set_error_message (context, status, "unknown option \'%s\'", - opt?opt:val); + if (opt && !strcmp(opt, "temporary")) { + /* + * temporary is passed in when kdb5_util load without -update is done. + * This is unsupported by the LDAP plugin. + */ + krb5_set_error_message (context, status, + "creation of LDAP entries aborted, plugin requires -update argument"); + } else { + krb5_set_error_message (context, status, "unknown option \'%s\'", + opt?opt:val); + } free(opt); free(val); goto cleanup; @@ -252,10 +260,6 @@ krb5_ldap_create (krb5_context context, char *conf_section, char **db_args) /* read the kerberos container */ if ((status = krb5_ldap_read_krbcontainer_params(context, &(ldap_context->krbcontainer))) == KRB5_KDB_NOENTRY) { - krb5_ldap_krbcontainer_params kparams; - - /* The kerberos container does not exist so try to create. */ - memset(&kparams, 0, sizeof(kparams)); /* Read the kerberos container location from configuration file */ if (ldap_context->conf_section) { @@ -289,6 +293,7 @@ krb5_ldap_create (krb5_context context, char *conf_section, char **db_args) krb5_set_error_message(context, status, "while reading kerberos container information"); goto cleanup; } + } else if (status) { krb5_set_error_message(context, status, "while reading kerberos container information"); goto cleanup; @@ -333,8 +338,8 @@ krb5_ldap_create (krb5_context context, char *conf_section, char **db_args) if ((rparams != NULL) && (rparams->kdcservers != NULL)) { for (i=0; (rparams->kdcservers[i] != NULL); i++) { if ((status=krb5_ldap_add_service_rights(context, - LDAP_KDC_SERVICE, rparams->kdcservers[i], - rparams->realm_name, rparams->subtree, rightsmask)) != 0) { + LDAP_KDC_SERVICE, rparams->kdcservers[i], + rparams->realm_name, rparams->subtree, rightsmask)) != 0) { goto cleanup; } } @@ -346,8 +351,8 @@ krb5_ldap_create (krb5_context context, char *conf_section, char **db_args) if ((rparams != NULL) && (rparams->adminservers != NULL)) { for (i=0; (rparams->adminservers[i] != NULL); i++) { if ((status=krb5_ldap_add_service_rights(context, - LDAP_ADMIN_SERVICE, rparams->adminservers[i], - rparams->realm_name, rparams->subtree, rightsmask)) != 0) { + LDAP_ADMIN_SERVICE, rparams->adminservers[i], + rparams->realm_name, rparams->subtree, rightsmask)) != 0) { goto cleanup; } } @@ -359,8 +364,8 @@ krb5_ldap_create (krb5_context context, char *conf_section, char **db_args) if ((rparams != NULL) && (rparams->passwdservers != NULL)) { for (i=0; (rparams->passwdservers[i] != NULL); i++) { if ((status=krb5_ldap_add_service_rights(context, - LDAP_PASSWD_SERVICE, rparams->passwdservers[i], - rparams->realm_name, rparams->subtree, rightsmask)) != 0) { + LDAP_PASSWD_SERVICE, rparams->passwdservers[i], + rparams->realm_name, rparams->subtree, rightsmask)) != 0) { goto cleanup; } } @@ -369,12 +374,19 @@ krb5_ldap_create (krb5_context context, char *conf_section, char **db_args) #endif cleanup: -#if 0 /************** Begin IFDEF'ed OUT *******************************/ + /* If the krbcontainer/realm creation is not complete, do the roll-back here */ - if ((krbcontainer_obj_created) && (!realm_obj_created)) - /* XXX WAF this needs to be created !!! */ - krb5_ldap_delete_krbcontainer(context); -#endif /**************** END IFDEF'ed OUT *******************************/ + if ((krbcontainer_obj_created) && (!realm_obj_created)) { + int rc; + rc = krb5_ldap_delete_krbcontainer(context, + ((kparams.DN != NULL) ? &kparams : NULL)); + krb5_set_error_message(context, rc, + "could not complete roll-back, error deleting Kerberos Container"); + } + + /* should call krb5_ldap_free_krbcontainer_params() but can't */ + if (kparams.DN != NULL) + krb5_xfree(kparams.DN); if (rparams) krb5_ldap_free_realm_params(rparams); diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_krbcontainer.h b/src/plugins/kdb/ldap/libkdb_ldap/ldap_krbcontainer.h index 7dfc2a55d..f4510d69c 100644 --- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_krbcontainer.h +++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_krbcontainer.h @@ -53,4 +53,8 @@ krb5_ldap_read_krbcontainer_params(krb5_context , krb5_ldap_krbcontainer_params krb5_error_code krb5_ldap_create_krbcontainer(krb5_context, const krb5_ldap_krbcontainer_params *); +krb5_error_code +krb5_ldap_delete_krbcontainer(krb5_context, + const krb5_ldap_krbcontainer_params *); + #endif diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c b/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c index aa9388adc..1d0a32036 100644 --- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c +++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c @@ -1730,21 +1730,16 @@ krb5_error_code krb5_ldap_policydn_to_name (context, policy_dn, name) } #elif defined HAVE_LDAP_EXPLODE_DN { - char *parsed_dn; + char **parsed_dn; - parsed_dn = ldap_explode_dn(policy_dn, 0); + /* 1 = return DN components without type prefix */ + parsed_dn = ldap_explode_dn(policy_dn, 1); if (parsed_dn == NULL) { st = EINVAL; - } - else { - if (strncasecmp(parsed_dn[0], "cn=", 3) != 0) { + } else { + *name = strdup(parsed_dn[0]); + if (*name == NULL) st = EINVAL; - } - else { - *name = strdup(parsed_dn[0]); - if (*name == NULL) - st = EINVAL; - } ldap_value_free(parsed_dn); } diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c index 2a28a4e0e..9ba4cb6d9 100644 --- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c +++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c @@ -36,6 +36,7 @@ #include "ldap_tkt_policy.h" #include "ldap_pwd_policy.h" #include "ldap_err.h" +#include extern char* principal_attributes[]; extern char* max_pwd_life_attr[]; @@ -662,7 +663,7 @@ krb5_ldap_put_principal(context, entries, nentries, db_args) register int *nentries; /* number of entry structs to update */ char **db_args; { - int i=0, l=0, plen=0, kerberos_principal_object_type=0; + int i=0, l=0, kerberos_principal_object_type=0; krb5_error_code st=0, tempst=0; LDAP *ld=NULL; LDAPMessage *result=NULL, *ent=NULL; @@ -670,7 +671,7 @@ krb5_ldap_put_principal(context, entries, nentries, db_args) char **values=NULL, *strval[10]={NULL}, errbuf[1024]; struct berval **bersecretkey=NULL; LDAPMod **mods=NULL; - krb5_boolean tktpolicy_set=FALSE, create_standalone_prinicipal=FALSE; + krb5_boolean create_standalone_prinicipal=FALSE; krb5_boolean krb_identity_exists=FALSE, establish_links=FALSE; char *standalone_principal_dn=NULL; krb5_tl_data *tl_data=NULL; @@ -679,7 +680,7 @@ krb5_ldap_put_principal(context, entries, nentries, db_args) krb5_ldap_context *ldap_context=NULL; krb5_ldap_server_handle *ldap_server_handle=NULL; osa_princ_ent_rec princ_ent; - xargs_t xargs={0}; + xargs_t xargs = {0}; char *polname = NULL; OPERATION optype; @@ -702,10 +703,9 @@ krb5_ldap_put_principal(context, entries, nentries, db_args) /* get the principal information to act on */ if (entries->princ) { - if (((st=krb5_unparse_name(context,entries->princ, &user)) !=0) || + if (((st=krb5_unparse_name(context, entries->princ, &user)) != 0) || ((st=krb5_ldap_unparse_principal_name(user)) != 0)) goto cleanup; - plen = strlen(user); } /* Identity the type of operation, it can be @@ -725,11 +725,81 @@ krb5_ldap_put_principal(context, entries, nentries, db_args) if ((st=process_db_args(context, db_args, &xargs, optype)) != 0) goto cleanup; + if (entries->mask & KADM5_LOAD && principal_dn == NULL) { + int tree = 0, ntrees = 0, princlen = 0, numlentries = 0; + char **subtreelist = NULL, *filter = NULL; + /* A load operation is special, will do a mix-in (add krbprinc + * attrs to a non-krb object entry) if an object exists with a + * matching krbprincipalname attribute so try to find existing + * object and set principal_dn. This assumes that the + * krbprincipalname attribute is unique (only one object entry has + * a particular krbprincipalname attribute). + */ + if (user == NULL) { + /* must have principal name for search */ + st = EINVAL; + krb5_set_error_message(context, st, "operation can not continue, principal name not found"); + goto cleanup; + } + princlen = strlen(FILTER) + strlen(user) + 2 + 1; /* 2 for closing brackets */ + if ((filter = malloc(princlen)) == NULL) { + st = ENOMEM; + goto cleanup; + } + snprintf(filter, princlen, FILTER"%s))", user); + + /* get the current subtree list */ + if ((st = krb5_get_subtree_info(ldap_context, &subtreelist, &ntrees)) != 0) + goto cleanup; + + /* search for entry with matching krbprincipalname attribute */ + for (tree = 0; principal_dn == NULL && tree < ntrees; ++tree) { + result = NULL; + LDAP_SEARCH_1(subtreelist[tree], ldap_context->lrparams->search_scope, filter, principal_attributes, IGNORE_STATUS); + if (st == LDAP_SUCCESS) { + numlentries = ldap_count_entries(ld, result); + if (numlentries > 1) { + ldap_msgfree(result); + free(filter); + st = EINVAL; + krb5_set_error_message(context, st, + "operation can not continue, more than one entry with principal name \"%s\" found", + user); + goto cleanup; + } else if (numlentries == 1) { + ent = ldap_first_entry(ld, result); + if (ent != NULL) { + /* setting principal_dn will cause that entry to be modified further down */ + if ((principal_dn = ldap_get_dn(ld, ent)) == NULL) { + ldap_get_option (ld, LDAP_OPT_RESULT_CODE, &st); + st = set_ldap_error (context, st, 0); + ldap_msgfree(result); + free(filter); + goto cleanup; + } + } + } + if (result) + ldap_msgfree(result); + } else { + /* could not perform search, return with failure */ + st = set_ldap_error (context, st, 0); + free(filter); + goto cleanup; + } + /* + * If it isn't found then assume a standalone princ entry is to + * be created. + */ + } /* end for (tree = 0; principal_dn == ... */ + free(filter); + } /* end if (entries->mask & KADM5_LOAD && principal_dn == NULL */ + /* time to generate the DN information with the help of * containerdn, principalcontainerreference or * realmcontainerdn information */ - if (principal_dn ==NULL && xargs.dn == NULL) { /* creation of standalone principal */ + if (principal_dn == NULL && xargs.dn == NULL) { /* creation of standalone principal */ /* get the subtree information */ if (entries->princ->length == 2 && entries->princ->data[0].length == strlen("krbtgt") && strncmp(entries->princ->data[0].data, "krbtgt", entries->princ->data[0].length) == 0) { @@ -768,7 +838,6 @@ krb5_ldap_put_principal(context, entries, nentries, db_args) create_standalone_prinicipal = TRUE; free(subtree); subtree = NULL; - } /* @@ -844,12 +913,11 @@ krb5_ldap_put_principal(context, entries, nentries, db_args) */ char *attributes[]={"krbticketpolicyreference", "krbprincipalname", NULL}; - LDAP_SEARCH_1(dn, LDAP_SCOPE_BASE, 0, attributes,IGNORE_STATUS); + LDAP_SEARCH_1(dn, LDAP_SCOPE_BASE, 0, attributes, IGNORE_STATUS); if (st == LDAP_SUCCESS) { ent = ldap_first_entry(ld, result); if (ent != NULL) { if ((values=ldap_get_values(ld, ent, "krbticketpolicyreference")) != NULL) { - tktpolicy_set = TRUE; ldap_value_free(values); } @@ -894,7 +962,8 @@ krb5_ldap_put_principal(context, entries, nentries, db_args) if (optype == MODIFY_PRINCIPAL && kerberos_principal_object_type != KDB_STANDALONE_PRINCIPAL_OBJECT) { st = EINVAL; - snprintf(errbuf, sizeof(errbuf), "link information can't be set/updated as the kerberos principal belongs to an ldap object"); + snprintf(errbuf, sizeof(errbuf), + "link information can not be set/updated as the kerberos principal belongs to an ldap object"); krb5_set_error_message(context, st, "%s", errbuf); goto cleanup; } @@ -950,7 +1019,7 @@ krb5_ldap_put_principal(context, entries, nentries, db_args) if (entries->mask & KDB_PRINCIPAL) { memset(strval, 0, sizeof(strval)); strval[0] = user; - if ((st=krb5_add_str_mem_ldap_mod(&mods, "krbprincipalname", LDAP_MOD_ADD, strval)) != 0) + if ((st=krb5_add_str_mem_ldap_mod(&mods, "krbprincipalname", LDAP_MOD_REPLACE, strval)) != 0) goto cleanup; } @@ -979,9 +1048,9 @@ krb5_ldap_put_principal(context, entries, nentries, db_args) } if (entries->mask & KDB_POLICY) { + memset(&princ_ent, 0, sizeof(princ_ent)); for (tl_data=entries->tl_data; tl_data; tl_data=tl_data->tl_data_next) { if (tl_data->tl_data_type == KRB5_TL_KADM_DATA) { - memset(&princ_ent, 0, sizeof(princ_ent)); /* FIX ME: I guess the princ_ent should be freed after this call */ if ((st = krb5_lookup_tl_kadm_data(tl_data, &princ_ent)) != 0) { goto cleanup; @@ -1001,6 +1070,13 @@ krb5_ldap_put_principal(context, entries, nentries, db_args) krb5_set_error_message(context, st, "Password policy value null"); goto cleanup; } + } else if (entries->mask & KADM5_LOAD && principal_dn != NULL) { + /* + * a load is special in that existing entries must have attrs that + * removed. + */ + if ((st=krb5_add_str_mem_ldap_mod(&mods, "krbpwdpolicyreference", LDAP_MOD_REPLACE, NULL)) != 0) + goto cleanup; } if (entries->mask & KDB_POLICY_CLR) { @@ -1121,7 +1197,6 @@ krb5_ldap_put_principal(context, entries, nentries, db_args) } - if (establish_links == TRUE) { memset(strval, 0, sizeof(strval)); strval[0] = xargs.linkdn; @@ -1133,7 +1208,7 @@ krb5_ldap_put_principal(context, entries, nentries, db_args) * in case mods is NULL then return * not sure but can happen in a modprinc * so no need to return an error - * addprinc will atleast have the principal name + * addprinc will at least have the principal name * and the keys passed in */ if (mods == NULL) @@ -1148,7 +1223,20 @@ krb5_ldap_put_principal(context, entries, nentries, db_args) if ((st=krb5_add_str_mem_ldap_mod(&mods, "objectclass", LDAP_MOD_ADD, strval)) != 0) goto cleanup; - st=ldap_add_ext_s(ld, standalone_principal_dn, mods, NULL, NULL); + st = ldap_add_ext_s(ld, standalone_principal_dn, mods, NULL, NULL); + if (st == LDAP_ALREADY_EXISTS && entries->mask & KADM5_LOAD) { + /* a load operation must replace an existing entry */ + st = ldap_delete_ext_s(ld, standalone_principal_dn, NULL, NULL); + if (st != LDAP_SUCCESS) { + sprintf(errbuf, "Principal delete failed (trying to replace entry): %s", + ldap_err2string(st)); + st = translate_ldap_error (st, OP_ADD); + krb5_set_error_message(context, st, "%s", errbuf); + goto cleanup; + } else { + st = ldap_add_ext_s(ld, standalone_principal_dn, mods, NULL, NULL); + } + } if (st != LDAP_SUCCESS) { sprintf(errbuf, "Principal add failed: %s", ldap_err2string(st)); st = translate_ldap_error (st, OP_ADD); @@ -1185,7 +1273,8 @@ krb5_ldap_put_principal(context, entries, nentries, db_args) if (xargs.dn != NULL) st=ldap_modify_ext_s(ld, xargs.dn, mods, NULL, NULL); else - st=ldap_modify_ext_s(ld, principal_dn, mods, NULL, NULL); + st = ldap_modify_ext_s(ld, principal_dn, mods, NULL, NULL); + if (st != LDAP_SUCCESS) { sprintf(errbuf, "User modification failed: %s", ldap_err2string(st)); st = translate_ldap_error (st, OP_MOD); @@ -1193,7 +1282,6 @@ krb5_ldap_put_principal(context, entries, nentries, db_args) goto cleanup; } } - } cleanup: diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_realm.c b/src/plugins/kdb/ldap/libkdb_ldap/ldap_realm.c index 0d5357e00..dee22cccd 100644 --- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_realm.c +++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_realm.c @@ -189,7 +189,8 @@ krb5_ldap_list_realm(context, realms) char ***realms; { char **values = NULL; - unsigned int i = 0, count = 0; + unsigned int i = 0; + int count = 0; krb5_error_code st = 0, tempst = 0; LDAP *ld = NULL; LDAPMessage *result = NULL, *ent = NULL; @@ -1057,6 +1058,53 @@ cleanup: return(st); } +/* + * Delete the Kerberos container in the Directory + */ + +krb5_error_code +krb5_ldap_delete_krbcontainer(krb5_context context, + const krb5_ldap_krbcontainer_params *krbcontparams) +{ + LDAP *ld=NULL; + char *kerberoscontdn=NULL; + krb5_error_code st=0; + kdb5_dal_handle *dal_handle=NULL; + krb5_ldap_context *ldap_context=NULL; + krb5_ldap_server_handle *ldap_server_handle=NULL; + + SETUP_CONTEXT (); + + /* get ldap handle */ + GET_HANDLE (); + + if (krbcontparams != NULL && krbcontparams->DN != NULL) { + kerberoscontdn = krbcontparams->DN; + } else { + /* If the user has not given, use the default cn=Kerberos,cn=Security */ +#ifdef HAVE_EDIRECTORY + kerberoscontdn = KERBEROS_CONTAINER; +#else + st = EINVAL; + krb5_set_error_message (context, st, "Kerberos Container information is missing"); + goto cleanup; +#endif + } + + /* delete the kerberos container */ + if ((st = ldap_delete_ext_s(ld, kerberoscontdn, NULL, NULL)) != LDAP_SUCCESS) { + int ost = st; + st = translate_ldap_error (st, OP_ADD); + krb5_set_error_message (context, st, "Kerberos Container delete FAILED: %s", ldap_err2string(ost)); + goto cleanup; + } + +cleanup: + + krb5_ldap_put_handle_to_pool(ldap_context, ldap_server_handle); + return(st); +} + /* * Create Realm in eDirectory. This is used by kdb5_util -- 2.26.2