&& (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;
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;
*/
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);
* 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;
}
#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
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;
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
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;
/* 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) {
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;
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;
}
}
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;
}
}
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;
}
}
#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);
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
}
#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);
}
#include "ldap_tkt_policy.h"
#include "ldap_pwd_policy.h"
#include "ldap_err.h"
+#include <kadm5/admin.h>
extern char* principal_attributes[];
extern char* max_pwd_life_attr[];
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;
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;
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;
/* 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
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) {
create_standalone_prinicipal = TRUE;
free(subtree);
subtree = NULL;
-
}
/*
*/
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);
}
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;
}
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;
}
}
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;
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) {
}
-
if (establish_links == TRUE) {
memset(strval, 0, sizeof(strval));
strval[0] = xargs.linkdn;
* 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)
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);
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);
goto cleanup;
}
}
-
}
cleanup:
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;
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