#include <stdio.h>
#include <time.h>
#include <k5-int.h>
+#include <kadm5/admin.h>
#include "kdb5_ldap_util.h"
#include "kdb5_ldap_list.h"
#include "ldap_tkt_policy.h"
static char *strdur(time_t duration);
extern char *yes;
+extern kadm5_config_params global_params;
+
+static krb5_error_code init_ldap_realm (int argc, char *argv[]) {
+ /* This operation is being performed in the context of a realm. So,
+ * initialize the realm */
+ int mask = 0;
+ krb5_error_code retval;
+ kdb5_dal_handle *dal_handle = NULL;
+ krb5_ldap_context *ldap_context=NULL;
+
+ dal_handle = (kdb5_dal_handle *) util_context->db_context;
+ ldap_context = (krb5_ldap_context *) dal_handle->db_context;
+ if (!ldap_context) {
+ retval = EINVAL;
+ goto cleanup;
+ }
+
+ if (ldap_context->krbcontainer == NULL) {
+ retval = krb5_ldap_read_krbcontainer_params (util_context,
+ &(ldap_context->krbcontainer));
+ if (retval != 0) {
+ com_err(argv[0], retval, "while reading kerberos container information");
+ goto cleanup;
+ }
+ }
+
+ if (ldap_context->lrparams == NULL) {
+ retval = krb5_ldap_read_realm_params(util_context,
+ global_params.realm,
+ &(ldap_context->lrparams),
+ &mask);
+
+ if (retval != 0) {
+ goto cleanup;
+ }
+ }
+cleanup:
+ return retval;
+}
/*
* This function will create a ticket policy object with the
} else { /* Any other argument must be policy DN */
/* First check if policy DN is already provided --
if so, there's a usage error */
- if (policyparams->policydn != NULL)
+ if (policyparams->policy != NULL)
goto err_usage;
/* If not present already, fill up policy DN */
- policyparams->policydn = strdup(argv[i]);
- if (policyparams->policydn == NULL) {
+ policyparams->policy = strdup(argv[i]);
+ if (policyparams->policy == NULL) {
retval = ENOMEM;
com_err(me, retval, "while creating policy object");
goto err_nomsg;
}
/* policy DN is a mandatory argument. If not provided, print usage */
- if (policyparams->policydn == NULL)
+ if (policyparams->policy == NULL)
goto err_usage;
+ if ((retval = init_ldap_realm (argc, argv))) {
+ com_err(me, retval, "while reading realm information");
+ goto err_nomsg;
+ }
+
/* Create object with all attributes provided */
if ((retval = krb5_ldap_create_policy(util_context, policyparams, mask)) != 0)
goto cleanup;
krb5_ldap_policy_params *policyparams = NULL;
krb5_boolean print_usage = FALSE;
krb5_boolean no_msg = FALSE;
- char *policydn = NULL;
+ char *policy = NULL;
int mask = 0;
int force = 0;
char buf[5] = {0};
} else { /* Any other argument must be policy DN */
/* First check if policy DN is already provided --
if so, there's a usage error */
- if (policydn != NULL)
+ if (policy != NULL)
goto err_usage;
/* If not present already, fill up policy DN */
- policydn = strdup(argv[i]);
- if (policydn == NULL) {
+ policy = strdup(argv[i]);
+ if (policy == NULL) {
retval = ENOMEM;
com_err(me, retval, "while destroying policy object");
goto err_nomsg;
}
}
- if (policydn == NULL)
+ if (policy == NULL)
goto err_usage;
if (!force) {
- printf("This will delete the policy object '%s', are you sure?\n", policydn);
+ printf("This will delete the policy object '%s', are you sure?\n", policy);
printf("(type 'yes' to confirm)? ");
if (fgets(buf, sizeof(buf), stdin) == NULL) {
}
}
- if ((retval = krb5_ldap_read_policy(util_context, policydn, &policyparams, &mask)))
+ if ((retval = init_ldap_realm (argc, argv)))
+ goto err_nomsg;
+
+ if ((retval = krb5_ldap_read_policy(util_context, policy, &policyparams, &mask)))
goto cleanup;
- if ((retval = krb5_ldap_delete_policy(util_context, policydn, policyparams, mask)))
+ if ((retval = krb5_ldap_delete_policy(util_context, policy)))
goto cleanup;
- printf("** policy object '%s' deleted.\n", policydn);
+ printf("** policy object '%s' deleted.\n", policy);
goto cleanup;
/* Clean-up structure */
krb5_ldap_free_policy (util_context, policyparams);
- if (policydn) {
- free (policydn);
+ if (policy) {
+ free (policy);
}
if (print_usage) {
krb5_ldap_policy_params *policyparams = NULL;
krb5_boolean print_usage = FALSE;
krb5_boolean no_msg = FALSE;
- char *policydn = NULL;
+ char *policy = NULL;
int in_mask = 0, out_mask = 0;
time_t date = 0;
time_t now = 0;
} else { /* Any other argument must be policy DN */
/* First check if policy DN is already provided --
if so, there's a usage error */
- if (policydn != NULL)
+ if (policy != NULL)
goto err_usage;
/* If not present already, fill up policy DN */
- policydn = strdup(argv[i]);
- if (policydn == NULL) {
+ policy = strdup(argv[i]);
+ if (policy == NULL) {
retval = ENOMEM;
com_err(me, retval, "while modifying policy object");
goto err_nomsg;
}
}
- if (policydn == NULL)
+ if (policy == NULL)
goto err_usage;
- retval = krb5_ldap_read_policy(util_context, policydn, &policyparams, &in_mask);
+ if ((retval = init_ldap_realm (argc, argv)))
+ goto cleanup;
+
+ retval = krb5_ldap_read_policy(util_context, policy, &policyparams, &in_mask);
if (retval) {
- com_err(me, retval, "while reading information of policy '%s'", policydn);
+ com_err(me, retval, "while reading information of policy '%s'", policy);
goto err_nomsg;
}
/* Clean-up structure */
krb5_ldap_free_policy (util_context, policyparams);
- if (policydn)
- free (policydn);
+ if (policy)
+ free (policy);
if (print_usage)
db_usage(MODIFY_POLICY);
krb5_ldap_policy_params *policyparams = NULL;
krb5_error_code retval = 0;
krb5_boolean print_usage = FALSE;
- char *policydn = NULL;
+ char *policy = NULL;
int mask = 0;
if (argc != 2) {
goto err_usage;
}
- policydn = strdup(argv[1]);
- if (policydn == NULL) {
+ policy = strdup(argv[1]);
+ if (policy == NULL) {
com_err(me, ENOMEM, "while viewing policy");
exit_status++;
goto cleanup;
}
- if ((retval = krb5_ldap_read_policy(util_context, policydn, &policyparams, &mask))) {
- com_err(me, retval, "while viewing policy '%s'", policydn);
+ if ((retval = init_ldap_realm (argc, argv)))
+ goto cleanup;
+
+ if ((retval = krb5_ldap_read_policy(util_context, policy, &policyparams, &mask))) {
+ com_err(me, retval, "while viewing policy '%s'", policy);
exit_status++;
goto cleanup;
}
cleanup:
krb5_ldap_free_policy (util_context, policyparams);
- if (policydn)
- free (policydn);
+ if (policy)
+ free (policy);
if (print_usage) {
db_usage(VIEW_POLICY);
int mask;
{
/* Print the policy DN */
- printf("%25s: %s\n", "Ticket policy", policyparams->policydn);
+ printf("%25s: %s\n", "Ticket policy", policyparams->policy);
/* Print max. ticket life and max. renewable life, if present */
if (mask & LDAP_POLICY_MAXTKTLIFE)
}
}
+ if ((retval = init_ldap_realm (argc, argv)))
+ goto cleanup;
+
retval = krb5_ldap_list_policy(util_context, basedn, &list);
if ((retval != 0) || (list == NULL))
goto cleanup;
* Create / Modify / Destroy / View / List realm(s)
*/
+/* Needed for getting the definition of KRB5_TL_DB_ARGS */
+#define SECURID
+
#include <stdio.h>
#include <k5-int.h>
#include <kadm5/admin.h>
static char *strdur(time_t duration);
static int get_ticket_policy(krb5_ldap_realm_params *rparams, int *i, char *argv[],int argc);
-
+static krb5_error_code krb5_dbe_update_mod_princ_data_new (krb5_context context, krb5_db_entry *entry, krb5_timestamp mod_date, krb5_const_principal mod_princ);
+static krb5_error_code krb5_dbe_update_tl_data_new ( krb5_context context, krb5_db_entry *entry, krb5_tl_data *new_tl_data);
static int get_ticket_policy(rparams,i,argv,argc)
krb5_ldap_realm_params *rparams;
krb5_boolean create_complete = FALSE;
krb5_boolean print_usage = FALSE;
krb5_boolean no_msg = FALSE;
- char *oldsubtree = NULL;
+ char *oldcontainerref=NULL;
char pw_str[1024];
int do_stash = 0;
int i = 0;
int mask = 0, ret_mask = 0;
+ char **list = NULL;
#ifdef HAVE_EDIRECTORY
int rightsmask = 0;
#endif
/* Parse the arguments */
for (i = 1; i < argc; i++) {
- if (!strcmp(argv[i], "-subtree")) {
- if (++i > argc-1)
- goto err_usage;
- rparams->subtree = strdup(argv[i]);
- if (rparams->subtree == NULL) {
- retval = ENOMEM;
- goto cleanup;
- }
- mask |= LDAP_REALM_SUBTREE;
- } else if (!strcmp(argv[i], "-sscope")) {
+ if (!strcmp(argv[i], "-subtrees")) {
+ if (++i > argc-1)
+ goto err_usage;
+
+ if(strncmp(argv[i], "", strlen(argv[i]))!=0) {
+ list = (char **) calloc(MAX_LIST_ENTRIES, sizeof(char *));
+ memset(list, 0, sizeof(char*)*MAX_LIST_ENTRIES);
+ if (list == NULL) {
+ retval = ENOMEM;
+ goto cleanup;
+ }
+ if (( retval = krb5_parse_list(argv[i], LIST_DELIMITER, list)))
+ goto cleanup;
+
+ rparams->subtreecount=0;
+ while(list[rparams->subtreecount]!=NULL)
+ (rparams->subtreecount)++;
+ rparams->subtree = list;
+ } else if(strncmp(argv[i], "", strlen(argv[i]))==0) {
+ /* dont allow subtree value to be set at the root(NULL, "") of the tree */
+ com_err(argv[0], EINVAL,
+ "for subtree while creating realm '%s'",
+ global_params.realm);
+ goto err_nomsg;
+ }
+ rparams->subtree[rparams->subtreecount] = NULL;
+ mask |= LDAP_REALM_SUBTREE;
+ } else if (!strcmp(argv[i], "-containerref")) {
+ if (++i > argc-1)
+ goto err_usage;
+ if(strncmp(argv[i], "", strlen(argv[i]))==0) {
+ /* dont allow containerref value to be set at the root(NULL, "") of the tree */
+ com_err(argv[0], EINVAL,
+ "for container reference while creating realm '%s'",
+ global_params.realm);
+ goto err_nomsg;
+ }
+ rparams->containerref = strdup(argv[i]);
+ if (rparams->containerref == NULL) {
+ retval = ENOMEM;
+ goto cleanup;
+ }
+ mask |= LDAP_REALM_CONTREF;
+ } else if (!strcmp(argv[i], "-sscope")) {
if (++i > argc-1)
goto err_usage;
/* Possible values for search scope are
krb5_princ_set_realm_length(util_context, &tgt_princ, strlen(global_params.realm));
krb5_princ_component(util_context, &tgt_princ,1)->data = global_params.realm;
krb5_princ_component(util_context, &tgt_princ,1)->length = strlen(global_params.realm);
-
- oldsubtree = ldap_context->lrparams->subtree;
- ldap_context->lrparams->subtree = strdup(ldap_context->lrparams->realmdn);
- if (ldap_context->lrparams->subtree == NULL) {
- retval = ENOMEM;
- goto cleanup;
+ /* The container reference value is set to NULL, to avoid service principals
+ * getting created within the container reference at realm creation */
+ if (ldap_context->lrparams->containerref != NULL) {
+ oldcontainerref = ldap_context->lrparams->containerref;
+ ldap_context->lrparams->containerref = NULL;
}
/* Create 'K/M' ... */
krb5_free_principal(util_context, temp_p);
krb5_free_principal(util_context, p);
- if (ldap_context->lrparams->subtree != NULL)
- free(ldap_context->lrparams->subtree);
- ldap_context->lrparams->subtree = oldsubtree;
- oldsubtree = NULL;
+ if (oldcontainerref != NULL) {
+ ldap_context->lrparams->containerref = oldcontainerref;
+ oldcontainerref=NULL;
+ }
}
#ifdef HAVE_EDIRECTORY
memset (pw_str, 0, sizeof (pw_str));
- if (oldsubtree)
- ldap_context->lrparams->subtree = oldsubtree;
-
if (print_usage)
db_usage(CREATE_REALM);
int argc;
char *argv[];
{
- krb5_error_code retval;
+ krb5_error_code retval, st;
krb5_ldap_realm_params *rparams = NULL;
krb5_boolean print_usage = FALSE;
krb5_boolean no_msg = FALSE;
kdb5_dal_handle *dal_handle = NULL;
krb5_ldap_context *ldap_context=NULL;
- int i = 0;
+ int i = 0, j = 0;
int mask = 0, rmask = 0, ret_mask = 0;
+ char **slist = {NULL};
#ifdef HAVE_EDIRECTORY
int j = 0;
char *list[MAX_LIST_ENTRIES];
+ char **slist = {NULL};
int existing_entries = 0, list_entries = 0;
int newkdcdn = 0, newadmindn = 0, newpwddn = 0;
char **tempstr = NULL;
char **oldadmindns = NULL;
char **oldpwddns = NULL;
char **newkdcdns = NULL;
+ char **newsubtrees = NULL;
char **newadmindns = NULL;
char **newpwddns = NULL;
- char *oldsubtree = NULL;
+ char **oldsubtrees = {NULL};
int rightsmask = 0;
int subtree_changed = 0;
#endif
global_params.realm, &rparams, &rmask);
if (retval)
goto cleanup;
-
/* Parse the arguments */
for (i = 1; i < argc; i++) {
- if (!strcmp(argv[i], "-subtree")) {
+ int k = 0;
+ if (!strcmp(argv[i], "-subtrees")) {
if (++i > argc-1)
goto err_usage;
if (rmask & LDAP_REALM_SUBTREE) {
if (rparams->subtree) {
#ifdef HAVE_EDIRECTORY
- oldsubtree = strdup(rparams->subtree);
- if (oldsubtree == NULL) {
- retval = ENOMEM;
- goto cleanup;
- }
+ oldsubtrees = (char **) calloc(rparams->subtreecount+1, sizeof(char *));
+ memset(oldsubtrees, 0, szeof(char *) * rparams->subtreecount+1);
+ if (oldsubtrees == NULL) {
+ retval = ENOMEM;
+ goto cleanup;
+ }
+ for(k=0; rparams->subtree[k]!=NULL && rparams->subtreecount; k++) {
+ oldsubtrees[k] = strdup(rparams->subtree[k]);
+ if( oldsubtrees[k] == NULL ) {
+ retval = ENOMEM;
+ goto cleanup;
+ }
+ }
#endif
- free(rparams->subtree);
- }
- }
- rparams->subtree = strdup(argv[i]);
- if (rparams->subtree == NULL) {
- retval = ENOMEM;
- goto cleanup;
- }
- mask |= LDAP_REALM_SUBTREE;
- } else if (!strcmp(argv[i], "-sscope")) {
+ for(k=0;k<rparams->subtreecount && rparams->subtree[k];k++)
+ free(rparams->subtree[k]);
+ rparams->subtreecount=0;
+ }
+ }
+ if (strncmp(argv[i] ,"", strlen(argv[i]))!=0) {
+ slist = (char **) calloc(MAX_LIST_ENTRIES, sizeof(char *));
+ memset(slist, 0, sizeof(char*)*MAX_LIST_ENTRIES);
+ if (slist == NULL) {
+ retval = ENOMEM;
+ goto cleanup;
+ }
+ if (( retval = krb5_parse_list(argv[i], LIST_DELIMITER, slist)))
+ goto cleanup;
+
+ rparams->subtreecount=0;
+ while(slist[rparams->subtreecount]!=NULL)
+ (rparams->subtreecount)++;
+ rparams->subtree = slist;
+ } else if(strncmp(argv[i], "", strlen(argv[i]))==0) {
+ /* dont allow subtree value to be set at the root(NULL, "") of the tree */
+ com_err(argv[0], EINVAL,
+ "for subtree while modifying realm '%s'",
+ global_params.realm);
+ goto err_nomsg;
+ }
+ rparams->subtree[rparams->subtreecount] = NULL;
+ mask |= LDAP_REALM_SUBTREE;
+ } else if (!strncmp(argv[i], "-containerref", strlen(argv[i]))) {
+ if (++i > argc-1)
+ goto err_usage;
+ if(strncmp(argv[i], "", strlen(argv[i]))==0) {
+ /* dont allow containerref value to be set at the root(NULL, "") of the tree */
+ com_err(argv[0], EINVAL,
+ "for container reference while modifying realm '%s'",
+ global_params.realm);
+ goto err_nomsg;
+ }
+ rparams->containerref = strdup(argv[i]);
+ if (rparams->containerref == NULL) {
+ retval = ENOMEM;
+ goto cleanup;
+ }
+ mask |= LDAP_REALM_CONTREF;
+ } else if (!strcmp(argv[i], "-sscope")) {
if (++i > argc-1)
goto err_usage;
/* Possible values for search scope are
if (!(mask & LDAP_REALM_SUBTREE)) {
if (rparams->subtree != NULL) {
- oldsubtree = strdup(rparams->subtree);
- if (oldsubtree == NULL) {
- retval = ENOMEM;
- goto cleanup;
- }
+ for(i=0; rparams->subtree[i]!=NULL;i++) {
+ oldsubtrees[i] = strdup(rparams->subtree[i]);
+ if( oldsubtrees[i] == NULL ) {
+ retval = ENOMEM;
+ goto cleanup;
+ }
+ }
}
}
if ((mask & LDAP_REALM_SUBTREE)) {
- if ((oldsubtree && !rparams->subtree) ||
- (!oldsubtree && rparams->subtree) ||
- (strcmp(oldsubtree, rparams->subtree) != 0)) {
- subtree_changed = 1;
- }
+ newsubtrees = (char**) calloc(rparams->subtreecount, sizeof(char*));
+
+ if (newsubtrees == NULL) {
+ retval = ENOMEM;
+ goto cleanup;
+ }
+
+ if ( (rparams != NULL) && (rparams->subtree != NULL) ) {
+ for (j=0; j<rparams->subtreecount && rparams->subtree[j]!= NULL; j++) {
+ newsubtrees[j] = strdup(rparams->subtree[j]);
+ if (newsubtrees[j] == NULL) {
+ retval = ENOMEM;
+ goto cleanup;
+ }
+ }
+ newsubtrees[j] = NULL;
+ }
+ for(j=0;oldsubtrees[j]!=NULL;j++) {
+ check_subtree = 1;
+ for(i=0; ( (oldsubtrees[j] && !rparams->subtree[i]) ||
+ (!oldsubtrees[j] && rparams->subtree[i]))i; i++) {
+ if(strcasecmp( oldsubtrees[j], rparams->subtree[i]) == 0) {
+ check_subtree = 0;
+ continue;
+ }
+ }
+ if (check_subtree != 0) {
+ subtree_changed=1;
+ break;
+ }
+ }
+ /* this will return list of the disjoint members */
+ disjoint_members( oldsubtrees, newsubtrees);
}
if ((mask & LDAP_REALM_SUBTREE) || (mask & LDAP_REALM_KDCSERVERS)) {
if (!subtree_changed) {
disjoint_members(oldkdcdns, newkdcdns);
- } else { /* Only the subtree was changed. Remove the rights on the old subtree. */
+ } else { /* Only the subtrees was changed. Remove the rights on the old subtrees. */
if (!(mask & LDAP_REALM_KDCSERVERS)) {
oldkdcdns = (char**) calloc(MAX_LIST_ENTRIES, sizeof(char*));
rightsmask =0;
rightsmask |= LDAP_REALM_RIGHTS;
rightsmask |= LDAP_SUBTREE_RIGHTS;
- /* Remove the rights on the old subtree */
+ /* Remove the rights on the old subtrees */
if (oldkdcdns) {
for (i=0; (oldkdcdns[i] != NULL); i++) {
if ((retval=krb5_ldap_delete_service_rights(util_context,
LDAP_KDC_SERVICE, oldkdcdns[i],
- rparams->realm_name, oldsubtree, rightsmask)) != 0) {
+ rparams->realm_name, oldsubtrees, rightsmask)) != 0) {
printf("failed\n");
com_err(argv[0], retval, "while assigning rights '%s'",
rparams->realm_name);
if (!subtree_changed) {
disjoint_members(oldadmindns, newadmindns);
- } else { /* Only the subtree was changed. Remove the rights on the old subtree. */
+ } else { /* Only the subtrees was changed. Remove the rights on the old subtrees. */
if (!(mask & LDAP_REALM_ADMINSERVERS)) {
oldadmindns = (char**) calloc(MAX_LIST_ENTRIES, sizeof(char*));
rightsmask = 0;
rightsmask |= LDAP_REALM_RIGHTS;
rightsmask |= LDAP_SUBTREE_RIGHTS;
- /* Remove the rights on the old subtree */
+ /* Remove the rights on the old subtrees */
if (oldadmindns) {
for (i=0; (oldadmindns[i] != NULL); i++) {
if ((retval=krb5_ldap_delete_service_rights(util_context,
LDAP_ADMIN_SERVICE, oldadmindns[i],
- rparams->realm_name, oldsubtree, rightsmask)) != 0) {
+ rparams->realm_name, oldsubtrees, rightsmask)) != 0) {
printf("failed\n");
com_err(argv[0], retval, "while assigning rights '%s'",
rparams->realm_name);
if (!subtree_changed) {
disjoint_members(oldpwddns, newpwddns);
- } else { /* Only the subtree was changed. Remove the rights on the old subtree. */
+ } else { /* Only the subtrees was changed. Remove the rights on the old subtrees. */
if (!(mask & LDAP_REALM_ADMINSERVERS)) {
oldpwddns = (char**) calloc(MAX_LIST_ENTRIES, sizeof(char*));
rightsmask =0;
rightsmask |= LDAP_REALM_RIGHTS;
rightsmask |= LDAP_SUBTREE_RIGHTS;
- /* Remove the rights on the old subtree */
+ /* Remove the rights on the old subtrees */
if (oldpwddns) {
for (i=0; (oldpwddns[i] != NULL); i++) {
if ((retval = krb5_ldap_delete_service_rights(util_context,
LDAP_PASSWD_SERVICE, oldpwddns[i],
- rparams->realm_name, oldsubtree, rightsmask))) {
+ rparams->realm_name, oldsubtrees, rightsmask))) {
printf("failed\n");
com_err(argv[0], retval, "while assigning rights '%s'",
rparams->realm_name);
cleanup:
krb5_ldap_free_realm_params(rparams);
+
#ifdef HAVE_EDIRECTORY
if (oldkdcdns) {
for (i=0; oldkdcdns[i] != NULL; i++)
free(newadmindns[i]);
free(newadmindns);
}
- if (oldsubtree)
- free(oldsubtree);
+ if (oldsubtrees) {
+ for (i=0;oldsubtrees[i]!=NULL; i++)
+ free(oldsubtrees[i]);
+ free(oldsubtrees);
+ }
+ if (newsubtrees) {
+ for (i=0;newsubtrees[i]!=NULL; i++)
+ free(newsubtrees[i]);
+ free(oldsubtrees);
+ }
#endif
if (print_usage) {
db_usage(MODIFY_REALM);
static void print_realm_params(krb5_ldap_realm_params *rparams, int mask)
{
char **slist = NULL;
- int num_entry_printed = 0;
+ int num_entry_printed = 0, i = 0;
/* Print the Realm Attributes on the standard output */
printf("%25s: %-50s\n", "Realm Name", global_params.realm);
- if (mask & LDAP_REALM_SUBTREE)
- printf("%25s: %-50s\n", "Subtree", rparams->subtree);
+ if (mask & LDAP_REALM_SUBTREE) {
+ for (i=0; rparams->subtree[i]!=NULL; i++)
+ printf("%25s: %-50s\n", "Subtree", rparams->subtree[i]);
+ }
+ if (mask & LDAP_REALM_CONTREF)
+ printf("%25s: %-50s\n", "Principal Container Reference", rparams->containerref);
if (mask & LDAP_REALM_SEARCHSCOPE) {
if ((rparams->search_scope != 1) &&
(rparams->search_scope != 2)) {
return;
}
+/*
+ * Duplicating the following two functions here because
+ * 'krb5_dbe_update_tl_data' uses backend specific memory allocation. The catch
+ * here is that the backend is not initialized - kdb5_ldap_util doesn't go
+ * through DAL.
+ * 1. krb5_dbe_update_tl_data
+ * 2. krb5_dbe_update_mod_princ_data
+ */
+
+/* Start duplicate code ... */
+
+static krb5_error_code
+krb5_dbe_update_tl_data_new(context, entry, new_tl_data)
+ krb5_context context;
+ krb5_db_entry *entry;
+ krb5_tl_data *new_tl_data;
+{
+ krb5_tl_data *tl_data = NULL;
+ krb5_octet *tmp;
+
+ /* copy the new data first, so we can fail cleanly if malloc()
+ * fails */
+/*
+ if ((tmp =
+ (krb5_octet *) krb5_db_alloc(context, NULL,
+ new_tl_data->tl_data_length)) == NULL)
+*/
+ if ((tmp = (krb5_octet *) malloc (new_tl_data->tl_data_length)) == NULL)
+ return (ENOMEM);
+
+ /* Find an existing entry of the specified type and point at
+ * it, or NULL if not found */
+
+ if (new_tl_data->tl_data_type != KRB5_TL_DB_ARGS) { /* db_args can be multiple */
+ for (tl_data = entry->tl_data; tl_data;
+ tl_data = tl_data->tl_data_next)
+ if (tl_data->tl_data_type == new_tl_data->tl_data_type)
+ break;
+ }
+
+ /* if necessary, chain a new record in the beginning and point at it */
+
+ if (!tl_data) {
+/*
+ if ((tl_data =
+ (krb5_tl_data *) krb5_db_alloc(context, NULL,
+ sizeof(krb5_tl_data)))
+ == NULL) {
+*/
+ if ((tl_data = (krb5_tl_data *) malloc (sizeof(krb5_tl_data))) == NULL) {
+ free(tmp);
+ return (ENOMEM);
+ }
+ memset(tl_data, 0, sizeof(krb5_tl_data));
+ tl_data->tl_data_next = entry->tl_data;
+ entry->tl_data = tl_data;
+ entry->n_tl_data++;
+ }
+
+ /* fill in the record */
+
+ if (tl_data->tl_data_contents)
+ krb5_db_free(context, tl_data->tl_data_contents);
+
+ tl_data->tl_data_type = new_tl_data->tl_data_type;
+ tl_data->tl_data_length = new_tl_data->tl_data_length;
+ tl_data->tl_data_contents = tmp;
+ memcpy(tmp, new_tl_data->tl_data_contents, tl_data->tl_data_length);
+
+ return (0);
+}
+
+static krb5_error_code
+krb5_dbe_update_mod_princ_data_new(context, entry, mod_date, mod_princ)
+ krb5_context context;
+ krb5_db_entry * entry;
+ krb5_timestamp mod_date;
+ krb5_const_principal mod_princ;
+{
+ krb5_tl_data tl_data;
+
+ krb5_error_code retval = 0;
+ krb5_octet * nextloc = 0;
+ char * unparse_mod_princ = 0;
+ unsigned int unparse_mod_princ_size;
+
+ if ((retval = krb5_unparse_name(context, mod_princ,
+ &unparse_mod_princ)))
+ return(retval);
+
+ unparse_mod_princ_size = strlen(unparse_mod_princ) + 1;
+
+ if ((nextloc = (krb5_octet *) malloc(unparse_mod_princ_size + 4))
+ == NULL) {
+ free(unparse_mod_princ);
+ return(ENOMEM);
+ }
+
+ tl_data.tl_data_type = KRB5_TL_MOD_PRINC;
+ tl_data.tl_data_length = unparse_mod_princ_size + 4;
+ tl_data.tl_data_contents = nextloc;
+
+ /* Mod Date */
+ krb5_kdb_encode_int32(mod_date, nextloc);
+
+ /* Mod Princ */
+ memcpy(nextloc+4, unparse_mod_princ, unparse_mod_princ_size);
+
+ retval = krb5_dbe_update_tl_data_new(context, entry, &tl_data);
+
+ free(unparse_mod_princ);
+ free(nextloc);
+
+ return(retval);
+}
+
+/* End duplicate code */
/*
* This function creates service principals when
entry.tl_data = tl_data;
entry.n_tl_data += 1;
+ /* Set the creator's name */
+ {
+ krb5_timestamp now;
+ if ((retval = krb5_timeofday(context, &now)))
+ goto cleanup;
+ if ((retval = krb5_dbe_update_mod_princ_data_new(context, &entry,
+ now, &db_create_princ)))
+ goto cleanup;
+ }
entry.attributes = pblock->flags;
entry.max_life = pblock->max_life;
entry.max_renewable_life = pblock->max_rlife;
"\tcmd [cmd_options]\n"
/* Create realm */
-"create [-subtree subtree_dn] [-sscope search_scope]\n"
+"create [-subtrees subtree_dn_list] [-sscope search_scope] [-containerref container_reference_dn]\n"
#ifdef HAVE_EDIRECTORY
"\t\t[-kdcdn kdc_service_list] [-admindn admin_service_list]\n"
"\t\t[-pwddn passwd_service_list]\n"
"\t\t[ticket_flags] [-r realm]\n"
/* modify realm */
-"modify [-subtree subtree_dn] [-sscope search_scope]\n"
+"modify [-subtrees subtree_dn_list] [-sscope search_scope] [-containerref container_reference_dn]\n"
#ifdef HAVE_EDIRECTORY
"\t\t[-kdcdn kdc_service_list |\n"
"\t\t[-clearkdcdn kdc_service_list] [-addkdcdn kdc_service_list]]\n"
#endif
/* Create policy */
-"create_policy [-maxtktlife max_ticket_life]\n"
-"\t\t[-maxrenewlife max_renewable_ticket_life] [ticket_flags] policy_dn\n"
+"create_policy [-r realm] [-maxtktlife max_ticket_life]\n"
+"\t\t[-maxrenewlife max_renewable_ticket_life] [ticket_flags] policy\n"
/* Modify policy */
-"modify_policy [-maxtktlife max_ticket_life]\n"
-"\t\t[-maxrenewlife max_renewable_ticket_life] [ticket_flags] policy_dn\n"
+"modify_policy [-r realm] [-maxtktlife max_ticket_life]\n"
+"\t\t[-maxrenewlife max_renewable_ticket_life] [ticket_flags] policy\n"
/* View policy */
-"view_policy policy_dn\n"
+"view_policy [-r realm] policy\n"
/* Destroy policy */
-"destroy_policy [-force] policy_dn\n"
+"destroy_policy [-r realm] [-force] policy\n"
/* List policies */
-"list_policy [-basedn base_dn]\n"
+"list_policy [-r realm]\n"
);
}
kdb5_dal_handle *dal_handle = NULL;
krb5_ldap_context *ldap_context=NULL;
char *value = NULL, *conf_section = NULL;
- krb5_boolean realm_name_required = FALSE;
+ krb5_boolean realm_name_required = TRUE;
krb5_boolean print_help_message = FALSE;
retval = krb5_init_context(&util_context);
/* We need to check for the presence of default realm name only in
* the case of realm related operations like create, destroy etc.
*/
- if ((strcmp(cmd_argv[0], "create") == 0) ||
- (strcmp(cmd_argv[0], "destroy") == 0) ||
- (strcmp(cmd_argv[0], "modify") == 0) ||
- (strcmp(cmd_argv[0], "view") == 0)
- ) {
- realm_name_required = TRUE;
+ if ((strcmp(cmd_argv[0], "list") == 0) ||
+ (strcmp(cmd_argv[0], "stashsrvpw") == 0)) {
+ realm_name_required = FALSE;
}
if (!util_context->default_realm) {
#define KDB_TL_KEYINFO 0x04
#define KDB_TL_MASK 0x05
#define KDB_TL_CONTAINERDN 0x06
-#define KDB_TL_TKTPOLICYDN 0x07
+#define KDB_TL_LINKDN 0x07
#define CHECK_LDAP_HANDLE(lcontext) if (!(ldap_context \
int
has_sasl_external_mech(krb5_context, char *);
-krb5_error_code
-krb5_get_policydn(krb5_context, krb5_db_entry *, char **);
-
/* DAL functions */
#include "kdb_ldap.h"
#include "ldap_err.h"
-char *policyrefattribute[] = {"krbPolicyReference",NULL};
+char *policyrefattribute[] = {"krbTicketPolicyReference",NULL};
char *krbcontainerrefattr[] = {"krbContainerReference", NULL};
/*
#endif
if ((ent = ldap_first_entry(ld, result))) {
- if ((st=krb5_ldap_get_string(ld, ent, "krbpolicyreference",
+ if ((st=krb5_ldap_get_string(ld, ent, "krbticketpolicyreference",
&(cparams->policyreference), NULL)) != 0)
goto cleanup;
}
/*
* Deduce the subtree information from the context. A realm can have
- * at most 2 subtrees.
+ * multiple subtrees.
* 1. the Realm container
- * 2. the actual subtree associated with the Realm
+ * 2. the actual subtrees associated with the Realm
*
* However, there are some conditions to be considered to deduce the
* actual subtree/s associated with the realm. The conditions are as
* is internal a [Root]) then the realm has only one subtree
* i.e [Root], i.e. whole of the tree.
* 2. If the subtree information of the Realm is missing/absent, then the
- * realm has only one, i.e., the Realm container. NOTE: In call cases
+ * realm has only one, i.e., the Realm container. NOTE: In all cases
* Realm container SHOULD be the one among the subtrees or the only
* one subtree.
* 3. The subtree information of the realm is overlapping the realm
krb5_error_code
krb5_get_subtree_info(ldap_context, subtreearr, ntree)
krb5_ldap_context *ldap_context;
- char **subtreearr;
+ char ***subtreearr;
unsigned int *ntree;
{
- int lendiff=0;
- char *subtree=NULL, *realm_cont_dn=NULL;
-
+ int st=0, i=0, subtreecount=0;
+ int j=0, ncount=0, search_scope=0;
+ char **subtree=NULL, *realm_cont_dn=NULL;
+ char **subtarr=NULL;
+ char *containerref=NULL;
+ char **newsubtree=NULL;
+
+ containerref = ldap_context->lrparams->containerref;
subtree = ldap_context->lrparams->subtree;
realm_cont_dn = ldap_context->lrparams->realmdn;
+ subtreecount = ldap_context->lrparams->subtreecount;
+ search_scope = ldap_context->lrparams->search_scope;
- /*
- * If subtree attribute value is [Root] of the tree which is
- * represented by a "" (null) string, set the ntree value as 1 and
- * do not fill the subtreearr value. In eDirectory the [Root] can
- * be represented as a "" (null) string, however this
- * representation throws a "No such object" error in OpenLDAP.
- * Representing [Root] of the tree as NULL pointer (i.e. no value)
- * works in both case.
- */
- if (subtree == NULL || strcasecmp(subtree, "") == 0) {
- /*
- * XXX WAF to see if I can get around ldapsearch issue with a null base
- * which doesn't work in solaris. This should probably be a Solaris
- * specific #ifdef but I am not sure what define value to use.
- */
- if (realm_cont_dn != NULL) {
- subtreearr[0] = strdup(realm_cont_dn);
- if (subtreearr[0] == NULL)
- return ENOMEM;
- }
- *ntree = 1;
- return 0;
+ subtarr = (char **) malloc(sizeof(char *) * (subtreecount + 1 /*realm dn*/ + 1 /*containerref*/ + 1));
+ if (subtarr == NULL) {
+ st = ENOMEM;
+ goto cleanup;
}
+ memset(subtarr, 0, (sizeof(char *) * (subtreecount+1+1+1)));
- /*
- * The subtree attribute value of the realm can be same as the
- * realm container or can even overlap. If the check is
- * successful, then the subtree attribute value alone is copied to
- * the subtreearr array and the ntree value is set to 1.
- */
- lendiff = strlen(realm_cont_dn) - strlen(subtree);
- if (lendiff >= 0 && (strcasecmp(realm_cont_dn+lendiff, subtree)==0)) {
- subtreearr[0] = strdup(subtree);
- if (subtreearr[0] == NULL)
- return ENOMEM;
- *ntree = 1;
- return 0;
+ /* get the complete subtree list */
+ for (i=0; i<subtreecount && subtree[i]!=NULL; i++) {
+ subtarr[i] = strdup(subtree[i]);
+ if (subtarr[i] == NULL) {
+ st = ENOMEM;
+ goto cleanup;
+ }
}
- /*
- * If the subtree attribute value of the realm and the realm
- * container are different, then both of the values are copied to
- * subtreearr and ntree value is set to 2.
- */
- subtreearr[0] = strdup(realm_cont_dn);
- if (subtreearr[0] == NULL)
- return ENOMEM;
- subtreearr[1] = strdup(subtree);
- if (subtreearr[1] == NULL) {
- if (subtreearr[0])
- free (subtreearr[0]);
- return ENOMEM;
+ subtarr[i] = strdup(realm_cont_dn);
+ if (subtarr[i++] == NULL) {
+ st = ENOMEM;
+ goto cleanup;
}
- *ntree = 2;
- return 0;
+
+ if (containerref != NULL) {
+ subtarr[i] = strdup(containerref);
+ if (subtarr[i++] == NULL) {
+ st = ENOMEM;
+ goto cleanup;
+ }
+ }
+
+ ncount = i;
+
+ subtree = (char **) malloc(sizeof(char *) * (ncount + 1));
+ if (subtree == NULL) {
+ st = ENOMEM;
+ goto cleanup;
+ }
+ memset(subtree, 0, (sizeof(char *) * (ncount+1)));
+ remove_overlapping_subtrees(subtarr, &subtree, &ncount, search_scope);
+
+ *ntree = ncount;
+ *subtreearr = subtree;
+
+cleanup:
+ if(subtarr!=NULL) {
+ for(i=0; subtarr[i]!=NULL; i++)
+ free(subtarr[i]);
+ free(subtarr);
+ }
+
+ if(newsubtree!=NULL) {
+ for(i=0; newsubtree[i]!=NULL; i++)
+ free(newsubtree[i]);
+ free(newsubtree);
+ }
+
+ return st;
}
/*
}
case KDB_TL_USERDN:
- case KDB_TL_TKTPOLICYDN:
+ case KDB_TL_LINKDN:
{
char *cptr = (char *)value;
break;
}
- case KDB_TL_KEYINFO:
- {
- struct berval *key = (struct berval *)value;
-
- currlen = tl_data->tl_data_length;
- tl_data->tl_data_length += 1 + 2 + key->bv_len;
- /* allocate required memory */
- reallocptr = tl_data->tl_data_contents;
- tl_data->tl_data_contents = realloc(tl_data->tl_data_contents,
- tl_data->tl_data_length);
- if (tl_data->tl_data_contents == NULL) {
- if (reallocptr)
- free (reallocptr);
- return ENOMEM;
- }
- curr = (char *) (tl_data->tl_data_contents + currlen);
-
- /* store the tl_type value */
- memset(curr, tl_type, 1);
- curr += 1;
- /* store the content length */
- tldatalen = key->bv_len;
- STORE16_INT(curr, tldatalen);
- curr += 2;
- /* store the content */
- memcpy(curr, key->bv_val, key->bv_len);
- curr += tldatalen;
- break;
- }
-
default:
return 1;
unsigned char *curr=NULL;
int *intptr=NULL;
long *longptr=NULL;
- char *DN=NULL;
+ char *DN=NULL, **DNarr=NULL;
krb5_boolean keyfound=FALSE;
KEY *secretkey = NULL;
+ krb5_error_code st=-1;
*data = NULL;
*data = longptr;
}
curr += sublen;
- return 0;
+ st = 0;
+ return st;
break;
case KDB_TL_CONTAINERDN:
case KDB_TL_USERDN:
- case KDB_TL_TKTPOLICYDN:
/* get the length of the content */
UNSTORE16_INT(curr, sublen);
/* forward by 2 bytes */
DN[sublen] = 0;
*data = DN;
curr += sublen;
- return 0;
+ st = 0;
+ return st;
break;
- case KDB_TL_KEYINFO:
- /* get the length of the content */
- keyfound = TRUE;
- UNSTORE16_INT(curr, sublen);
- /* forward by 2 bytes */
- curr += 2;
- if (secretkey == NULL) {
- secretkey = malloc(sizeof(*secretkey));
- if (secretkey == NULL)
- return ENOMEM;
- secretkey->nkey = 0;
- secretkey->keys = NULL;
- secretkey->keys = realloc(secretkey->keys,
- sizeof(*(secretkey->keys)) * (limit));
- if (secretkey->keys == NULL)
+ case KDB_TL_LINKDN:
+ if (DNarr == NULL) {
+ DNarr = calloc(limit, sizeof(char *));
+ if (DNarr == NULL)
return ENOMEM;
- memset(secretkey->keys, 0, sizeof (*(secretkey->keys)) * (limit));
}
if (i == limit-1) {
limit *= 2;
- secretkey->keys = realloc(secretkey->keys,
- sizeof(*(secretkey->keys)) * (limit));
- if (secretkey->keys == NULL)
+ DNarr = realloc(DNarr, sizeof(char *) * (limit));
+ if (DNarr == NULL)
return ENOMEM;
- memset(secretkey->keys+i, 0, sizeof (*(secretkey->keys)) * (limit-i));
}
-
- secretkey->keys[i] = malloc (sizeof(struct berval));
- if (secretkey->keys[i] == NULL)
- return ENOMEM;
-
- secretkey->keys[i]->bv_len = sublen;
- secretkey->keys[i]->bv_val = malloc (sublen);
- if (secretkey->keys[i]->bv_val == NULL)
+
+ /* get the length of the content */
+ UNSTORE16_INT(curr, sublen);
+ /* forward by 2 bytes */
+ curr += 2;
+ DNarr[i] = malloc (sublen + 1);
+ if (DNarr[i] == NULL)
return ENOMEM;
-
- memcpy(secretkey->keys[i]->bv_val, curr, sublen);
- secretkey->nkey = ++i;
- *data = secretkey;
+ memcpy(DNarr[i], curr, sublen);
+ DNarr[i][sublen] = 0;
+ ++i;
curr += sublen;
+ *data = DNarr;
+ st=0;
break;
}
} else {
curr += 2 + sublen;
}
}
- if (tl_type == KDB_TL_KEYINFO) {
- if (keyfound)
- return 0;
- else
- return EINVAL;
- }
- return EINVAL;
+ return st;
}
/*
}
krb5_error_code
-krb5_get_secretkeys(context, entries, secretkey)
+krb5_get_linkdn(context, entries, link_dn)
krb5_context context;
krb5_db_entry *entries;
- KEY **secretkey;
+ char ***link_dn;
{
krb5_error_code st=0;
krb5_tl_data tl_data;
void *voidptr=NULL;
-
+
+ *link_dn = NULL;
tl_data.tl_data_type = KDB_TL_USER_INFO;
if (((st=krb5_dbe_lookup_tl_data(context, entries, &tl_data)) != 0) || tl_data.tl_data_length == 0)
goto cleanup;
-
- if (decode_tl_data(&tl_data, KDB_TL_KEYINFO, &voidptr) == 0) {
- *secretkey = (KEY *) voidptr;
+
+ if (decode_tl_data(&tl_data, KDB_TL_LINKDN, &voidptr) == 0) {
+ *link_dn = (char **) voidptr;
}
-cleanup:
+ cleanup:
return st;
}
krb5_tl_data tl_data;
void *voidptr=NULL;
- if (type != KDB_TL_USERDN && type != KDB_TL_CONTAINERDN && type != KDB_TL_TKTPOLICYDN) {
+ if (type != KDB_TL_USERDN && type != KDB_TL_CONTAINERDN) {
st = EINVAL;
goto cleanup;
}
return krb5_get_str_from_tl_data(context, entries, KDB_TL_CONTAINERDN, containerdn);
}
-krb5_error_code
-krb5_get_policydn(context, entries, policydn)
- krb5_context context;
- krb5_db_entry *entries;
- char **policydn;
-{
- *policydn = NULL;
- return krb5_get_str_from_tl_data(context, entries, KDB_TL_TKTPOLICYDN, policydn);
-}
/*
* This function reads the attribute values (if the attribute is
* non-null) from the dn. The read attribute values is compared
return st;
}
+/*
+ * krb5_ldap_get_strings() - Returns all the values
+ * of the attribute.
+ */
+krb5_error_code
+krb5_ldap_get_strings(ld, ent, attribute, retarr, attr_present)
+ LDAP *ld;
+ LDAPMessage *ent;
+ char *attribute;
+ char ***retarr;
+ krb5_boolean *attr_present;
+{
+ char **values=NULL;
+ krb5_error_code st=0;
+ int i=0, count=0;
+
+ *retarr = NULL;
+ if (attr_present != NULL)
+ *attr_present = FALSE;
+
+ values=ldap_get_values(ld, ent, attribute);
+ if (values != NULL) {
+ if (attr_present != NULL)
+ *attr_present = TRUE;
+
+ count = ldap_count_values(values);
+ *retarr = (char **) calloc(count+1, sizeof(char *));
+ if (*retarr == NULL) {
+ st = ENOMEM;
+ return st;
+ }
+ for (i=0; i< count; ++i) {
+ (*retarr)[i] = strdup(values[i]);
+ if ((*retarr)[i] == NULL) {
+ st = ENOMEM;
+ goto cleanup;
+ }
+ }
+ ldap_value_free(values);
+ }
+
+cleanup:
+ if (st != 0) {
+ if (*retarr != NULL) {
+ for (i=0; i< count; ++i)
+ if ((*retarr)[i] != NULL)
+ free ((*retarr)[i]);
+ free (*retarr);
+ }
+ }
+ return st;
+}
+
krb5_error_code
krb5_ldap_get_time(ld, ent, attribute, rettime, attr_present)
LDAP *ld;
return ENOMEM;
(*mods)[i]->mod_op = op;
+ (*mods)[i]->mod_values = NULL;
+
if (values != NULL) {
for (j=0; values[j] != NULL; ++j)
;
{
krb5_free_error_message(kcontext, msg);
}
+
+
+/*
+ * Get the number of times an object has been referred to in a realm. this is
+ * needed to find out if deleting the attribute will cause dangling links.
+ *
+ * An LDAP handle may be optionally specified to prevent race condition - there
+ * are a limited number of LDAP handles.
+ */
+krb5_error_code
+krb5_ldap_get_reference_count (krb5_context context, char *dn, char *refattr,
+ int *count, LDAP *ld) {
+ int i, ntrees, st = 0, tempst = 0, gothandle = 0;
+ char *refcntattr[2];
+ char *filter = NULL;
+ char **subtree = NULL, *ptr = NULL;
+ kdb5_dal_handle *dal_handle = NULL;
+ krb5_ldap_context *ldap_context = NULL;
+ krb5_ldap_server_handle *ldap_server_handle = NULL;
+ LDAPMessage *result = NULL;
+
+
+ if (dn == NULL || refattr == NULL) {
+ st = EINVAL;
+ goto cleanup;
+ }
+
+ SETUP_CONTEXT();
+ if (ld == NULL) {
+ GET_HANDLE();
+ gothandle = 1;
+ }
+
+ refcntattr [0] = refattr;
+ refcntattr [1] = NULL;
+
+ ptr = ldap_filter_correct (dn, strlen (dn));
+ if (ptr == NULL) {
+ st = ENOMEM;
+ goto cleanup;
+ }
+
+ filter = (char *) malloc (strlen (refattr) + strlen (ptr) + 2);
+ if (filter == NULL) {
+ st = ENOMEM;
+ goto cleanup;
+ }
+
+ sprintf (filter, "%s=%s", refattr, ptr);
+
+ if ((st = krb5_get_subtree_info(ldap_context, &subtree, &ntrees)) != 0)
+ goto cleanup;
+
+ for (i = 0, *count = 0; i < ntrees; i++) {
+ int n;
+
+ LDAP_SEARCH(subtree[i],
+ LDAP_SCOPE_SUB,
+ filter,
+ refcntattr);
+ n = ldap_count_entries (ld, result);
+ if (n == -1) {
+ int ret, errcode = 0;
+ ret = ldap_parse_result (ld, result, &errcode, NULL, NULL, NULL, NULL, 0);
+ if (ret != LDAP_SUCCESS)
+ errcode = ret;
+ st = translate_ldap_error (errcode, OP_SEARCH);
+ goto cleanup;
+ }
+
+ ldap_msgfree(result);
+ result = NULL;
+
+ *count += n;
+ }
+
+cleanup:
+ if (filter != NULL)
+ free (filter);
+
+ if (result != NULL)
+ ldap_msgfree (result);
+
+ if (subtree != NULL) {
+ for (i = 0; i < ntrees; i++)
+ free (subtree[i]);
+ free (subtree);
+ }
+
+ if (ptr != NULL)
+ free (ptr);
+
+ if (gothandle == 1)
+ krb5_ldap_put_handle_to_pool(ldap_context, ldap_server_handle);
+
+ return st;
+}
+
+/*
+ * For now, policy objects are expected to be directly under the realm
+ * container.
+ */
+krb5_error_code krb5_ldap_policydn_to_name (context, policy_dn, name)
+ krb5_context context;
+ char *policy_dn;
+ char **name;
+{
+ int len1, len2;
+ krb5_error_code st = 0;
+ kdb5_dal_handle *dal_handle=NULL;
+ krb5_ldap_context *ldap_context=NULL;
+
+ SETUP_CONTEXT();
+
+ if (ldap_context->lrparams->realmdn == NULL) {
+ st = EINVAL;
+ goto cleanup;
+ }
+
+ len1 = strlen (ldap_context->lrparams->realmdn);
+ len2 = strlen (policy_dn);
+ if (len1 == 0 || len2 == 0 || len1 > len2) {
+ st = EINVAL;
+ goto cleanup;
+ }
+
+ if (strcmp (ldap_context->lrparams->realmdn, policy_dn + (len2 - len1)) != 0) {
+ st = EINVAL;
+ goto cleanup;
+ }
+
+ {
+ char *rdn;
+ LDAPDN dn;
+ rdn = strndup(policy_dn, len2 - len1 - 1); /* 1 character for ',' */
+
+ if (ldap_str2dn (rdn, &dn, LDAP_DN_FORMAT_LDAPV3 | LDAP_DN_PEDANTIC) != 0) {
+ st = EINVAL;
+ goto cleanup;
+ }
+ if (dn[0] == NULL || dn[1] != NULL)
+ st = EINVAL;
+ else if (strcasecmp (dn[0][0]->la_attr.bv_val, "cn") != 0)
+ st = EINVAL;
+ else
+ *name = strndup(dn[0][0]->la_value.bv_val, dn[0][0]->la_value.bv_len);
+
+ ldap_memfree (dn);
+ }
+cleanup:
+ return st;
+}
+
+krb5_error_code krb5_ldap_name_to_policydn (context, name, policy_dn)
+ krb5_context context;
+ char *name;
+ char **policy_dn;
+{
+ int len;
+ char *ptr = NULL;
+ krb5_error_code st = 0;
+ kdb5_dal_handle *dal_handle=NULL;
+ krb5_ldap_context *ldap_context=NULL;
+
+ *policy_dn = NULL;
+
+ /* validate the input parameters */
+ if(name == NULL) {
+ st = EINVAL;
+ goto cleanup;
+ }
+
+ /* Used for removing policy reference from an object */
+ if (name[0] == '\0') {
+ if ((*policy_dn = strdup ("")) == NULL)
+ st = ENOMEM;
+ goto cleanup;
+ }
+
+ SETUP_CONTEXT();
+
+ if (ldap_context->lrparams->realmdn == NULL) {
+ st = EINVAL;
+ goto cleanup;
+ }
+ len = strlen (ldap_context->lrparams->realmdn);
+
+ ptr = ldap_filter_correct (name, strlen (name));
+ if (ptr == NULL) {
+ st = ENOMEM;
+ goto cleanup;
+ }
+ len += strlen (ptr);
+
+ len += sizeof ("cn=") + 3;
+
+ *policy_dn = (char *) malloc (len);
+ if (*policy_dn == NULL) {
+ st = ENOMEM;
+ goto cleanup;
+ }
+
+ sprintf (*policy_dn, "cn=%s,%s", ptr, ldap_context->lrparams->realmdn);
+
+cleanup:
+ if (ptr != NULL)
+ free (ptr);
+ return st;
+}
+
+/* remove overlapping and repeated subtree entries from the list of subtrees */
+krb5_error_code remove_overlapping_subtrees( char **listin, char ***listop, int *subtcount, int sscope)
+{
+ int slen=0, k=0, j=0, lendiff=0;
+ int count = *subtcount;
+ char **subtree = *listop;
+
+ slen = count-1;
+ for (k=0; k<=slen && listin[k]!=NULL ; k++) {
+ for (j=k+1; j<=slen && listin[j]!=NULL ;j++) {
+ lendiff = strlen(listin[k]) - strlen(listin[j]);
+ if (sscope == 2) {
+ if ((lendiff > 0) && (strcasecmp((listin[k])+lendiff, listin[j])==0)) {
+ if (k != slen ) {
+ free(listin[k]);
+ listin[k] = listin[slen];
+ listin[slen] = NULL;
+ } else {
+ free(listin[k]);
+ listin[k] = NULL;
+ }
+ slen-=1;
+ k-=1;
+ break;
+ }
+ else if ((lendiff < 0) && (strcasecmp((listin[j])+lendiff, listin[k])==0)) {
+ if (j != slen ) {
+ free(listin[j]);
+ listin[j] = listin[slen];
+ listin[slen]=NULL;
+ } else {
+ free(listin[j]);
+ listin[j] = NULL;
+ }
+ slen-=1;
+ j-=1;
+ }
+ }
+ if ((lendiff == 0) && (strcasecmp(listin[j], listin[k])==0)) {
+ if (j != slen) {
+ free(listin[j]);
+ listin[j] = listin[slen];
+ listin[slen]=NULL;
+ } else {
+ free(listin[j]);
+ listin[j] = NULL;
+ }
+ slen -=1;
+ j-=1;
+ }
+ }
+ }
+ *subtcount=slen+1;
+ for(k=0; k<*subtcount && listin[k]!=NULL; k++) {
+ subtree[k] = strdup(listin[k]);
+ if (subtree[k] == NULL) {
+ return ENOMEM;
+ }
+ }
+ return 0;
+}
krb5_get_princ_count(krb5_context, krb5_db_entry *, int *);
krb5_error_code
-krb5_get_secretkeys(krb5_context, krb5_db_entry *, KEY **);
+krb5_get_linkdn(krb5_context, krb5_db_entry *, char ***);
krb5_error_code
krb5_get_userdn(krb5_context, krb5_db_entry *, char **);
is_principal_in_realm(krb5_ldap_context *, krb5_const_principal);
krb5_error_code
-krb5_get_subtree_info(krb5_ldap_context *, char **, unsigned int *);
+krb5_get_subtree_info(krb5_ldap_context *, char ***, unsigned int *);
krb5_error_code
krb5_ldap_read_server_params(krb5_context , char *, int);
krb5_error_code
krb5_ldap_get_string(LDAP *, LDAPMessage *, char *, char **, krb5_boolean *);
+krb5_error_code
+krb5_ldap_get_strings(LDAP *, LDAPMessage *, char *, char ***, krb5_boolean *);
+
krb5_error_code
krb5_ldap_get_time(LDAP *, LDAPMessage *, char *, krb5_timestamp *, krb5_boolean *);
krb5_error_code
krb5_ldap_free_mod_array(LDAPMod **);
+krb5_error_code
+krb5_ldap_get_reference_count (krb5_context, char *, char *, int *, LDAP *);
+
+krb5_error_code
+krb5_ldap_policydn_to_name (krb5_context, char *, char **);
+
+krb5_error_code
+krb5_ldap_name_to_policydn (krb5_context, char *, char **);
+
krb5_error_code
krb5_ldap_get_db_opt(char *, char **, char **);
struct timeval timelimit = {300, 0}; /* 5 minutes */
char *principal_attributes[] = { "krbprincipalname",
"objectclass",
- "krbsecretkey",
+ "krbprincipalkey",
"krbmaxrenewableage",
"krbmaxticketlife",
"krbticketflags",
"krbprincipalexpiration",
- "krbpolicyreference",
+ "krbticketpolicyreference",
"krbUpEnabled",
"krbpwdpolicyreference",
"krbpasswordexpiration",
+#ifdef KRBCONF_KDC_MODIFIES_KDB
+ "krbLastFailedAuth",
+ "krbLoginFailedCount",
+ "krbLastSuccessfulAuth",
+#endif
#ifdef HAVE_EDIRECTORY
"loginexpirationtime",
"logindisabled",
#endif
"loginexpirationtime",
"logindisabled",
- "modifiersname",
"modifytimestamp",
+ "krbLastPwdChange",
+ "krbExtraData",
+ "krbObjectReferences",
NULL };
static char *attributes_set[] = { "krbmaxrenewableage",
"krbmaxticketlife",
"krbticketflags",
"krbprincipalexpiration",
- "krbpolicyreference",
+ "krbticketpolicyreference",
"krbUpEnabled",
"krbpwdpolicyreference",
"krbpasswordexpiration",
- "krbsecretkey",
+ "krbprincipalkey",
+ "krblastpwdchange",
+ "krbextradata",
NULL };
void
{
krb5_db_entry entry;
krb5_principal principal;
- char *subtree[2]={NULL}, *princ_name=NULL, *realm=NULL, **values=NULL, *filter=NULL;
+ char **subtree=NULL, *princ_name=NULL, *realm=NULL, **values=NULL, *filter=NULL;
char *krbprincipal_attr[] = { "krbPrincipalName", NULL };
unsigned int filterlen=0, tree=0, ntree=1, i=0;
krb5_error_code st=0, tempst=0;
memset(filter, 0, filterlen);
sprintf(filter, FILTER"%s))", match_expr);
- if ((st = krb5_get_subtree_info(ldap_context, subtree, &ntree)) != 0)
+ if ((st = krb5_get_subtree_info(ldap_context, &subtree, &ntree)) != 0)
goto cleanup;
GET_HANDLE();
char *user=NULL, *DN=NULL, *strval[10] = {NULL};
LDAPMod **mods=NULL;
LDAP *ld=NULL;
- int j=0, ptype=KDB_USER_PRINCIPAL, pcount=0, attrsetmask=0;
+ int j=0, ptype=0, pcount=0, attrsetmask=0;
krb5_error_code st=0;
krb5_boolean singleentry=FALSE;
KEY *secretkey=NULL;
krb5_ldap_server_handle *ldap_server_handle=NULL;
krb5_db_entry entries;
krb5_boolean more=0;
- char * policydn = NULL;
/* Clear the global error string */
krb5_clear_error_message(context);
if (((st=krb5_get_princ_type(context, &entries, &(ptype))) != 0) ||
((st=krb5_get_attributes_mask(context, &entries, &(attrsetmask))) != 0) ||
((st=krb5_get_princ_count(context, &entries, &(pcount))) != 0) ||
- ((st=krb5_get_userdn(context, &entries, &(DN))) != 0) ||
- ((st=krb5_get_policydn(context, &entries, &policydn)) != 0) ||
- ((st=krb5_get_secretkeys(context, &entries, &secretkey)) != 0))
+ ((st=krb5_get_userdn(context, &entries, &(DN))) != 0))
goto cleanup;
if (DN == NULL) {
GET_HANDLE();
- if (ptype == KDB_USER_PRINCIPAL) {
-
+ if (ptype == KDB_STANDALONE_PRINCIPAL_OBJECT) {
+ st = ldap_delete_ext_s(ld, DN, NULL, NULL);
+ if (st != LDAP_SUCCESS) {
+ st = set_ldap_error (context, st, OP_DEL);
+ goto cleanup;
+ }
+ } else {
if (((st=krb5_unparse_name(context, searchfor, &user)) != 0)
|| ((st=krb5_ldap_unparse_principal_name(user)) != 0))
goto cleanup;
singleentry = (pcount == 1) ? TRUE: FALSE;
if (singleentry == FALSE) {
if (secretkey != NULL) {
- if ((st=krb5_add_ber_mem_ldap_mod(&mods, "krbsecretkey", LDAP_MOD_DELETE | LDAP_MOD_BVALUES,
+ if ((st=krb5_add_ber_mem_ldap_mod(&mods, "krbprincipalkey", LDAP_MOD_DELETE | LDAP_MOD_BVALUES,
secretkey->keys)) != 0)
goto cleanup;
}
attrsetmask >>= 1;
++j;
}
- if (policydn != NULL) {
- if ((st = krb5_ldap_change_count(context, policydn,2)))
- goto cleanup;
-
- }
/* the same should be done with the objectclass attributes */
{
- char *attrvalues[] = {"krbpwdpolicyrefaux", "krbpolicyaux", "krbprincipalaux", NULL};
+ char *attrvalues[] = {"krbticketpolicyaux", "krbprincipalaux", NULL};
+// char *attrvalues[] = {"krbpwdpolicyrefaux", "krbticketpolicyaux", "krbprincipalaux", NULL};
int p, q, r=0, amask=0;
if ((st=checkattributevalue(ld, DN, "objectclass", attrvalues, &amask)) != 0)
st = set_ldap_error(context, st, OP_MOD);
goto cleanup;
}
- } else if (ptype == KDB_SERVICE_PRINCIPAL) {
- st = ldap_delete_ext_s(ld, DN, NULL, NULL);
- if (st != LDAP_SUCCESS) {
- st = set_ldap_error (context, st, OP_DEL);
- goto cleanup;
- }
}
cleanup:
#define MAX_KEY_LENGTH 1024
#define CONTAINERDN_ARG "containerdn"
-#define USERDN_ARG "userdn"
-#define TKTPOLICYDN_ARG "tktpolicydn"
+#define USERDN_ARG "dn"
+#define TKTPOLICY_ARG "tktpolicy"
+#define LINKDN_ARG "linkdn"
+
+/* #define FILTER "(&(objectclass=krbprincipalaux)(krbprincipalname=" */
+ #define FILTER "(&(|(objectclass=krbprincipalaux)(objectclass=krbprincipal))(krbprincipalname="
-#define FILTER "(&(objectclass=krbprincipalaux)(krbprincipalname="
#define KDB_USER_PRINCIPAL 0x01
#define KDB_SERVICE_PRINCIPAL 0x02
+#define KDB_STANDALONE_PRINCIPAL_OBJECT 0x01
/* krb5_db_entry */
#define KDB_PRINCIPAL 0x000001
#define KDB_PWD_POL_REF_ATTR 0x000040
#define KDB_PWD_EXPIRE_TIME_ATTR 0x000080
#define KDB_SECRET_KEY 0x000100
+#define KDB_LAST_PWD_CHANGE_ATTR 0x000200
+#define KDB_EXTRA_DATA 0x000400
extern struct timeval timeout;
extern char *policyclass[];
krb5_decode_krbsecretkey(krb5_context, krb5_db_entry *, struct berval **, krb5_tl_data *);
static krb5_error_code
-krb5_read_tkt_policyreference(krb5_context, krb5_ldap_context *, krb5_db_entry *, char *);
+krb5_read_tkt_policy (krb5_context, krb5_ldap_context *, krb5_db_entry *, char *);
static char *
getstringtime(krb5_timestamp);
+static krb5_error_code berval2tl_data (struct berval *in, krb5_tl_data **out) {
+ *out = (krb5_tl_data *) malloc (sizeof (krb5_tl_data));
+ if (*out == NULL)
+ return ENOMEM;
+
+ (*out)->tl_data_length = in->bv_len - 2;
+ (*out)->tl_data_contents = (krb5_octet *) malloc
+ ((*out)->tl_data_length * sizeof (krb5_octet));
+ if ((*out)->tl_data_contents == NULL) {
+ free (*out);
+ return ENOMEM;
+ }
+
+ UNSTORE16_INT (in->bv_val, (*out)->tl_data_type);
+ memcpy ((*out)->tl_data_contents, in->bv_val + 2, (*out)->tl_data_length);
+
+ return 0;
+}
+
/*
* look up a principal in the directory.
*/
int *nentries; /* how much room/how many found */
krb5_boolean *more; /* are there more? */
{
- char *user=NULL, *DN=NULL, *filter=NULL, *subtree[2]={NULL};
+ char *user=NULL, *DN=NULL, *filter=NULL, **subtree=NULL;
unsigned int tree=0, ntrees=1, mask=0, princlen=0;
krb5_error_code tempst=0, st=0;
- char **values=NULL, *policydn=NULL, *pwdpolicydn=NULL, *modname=NULL;
+ char **values=NULL, *policydn=NULL, *pwdpolicydn=NULL;
+ char *polname = NULL, *tktpolname = NULL;
+ char **link_references=NULL;
krb5_tl_data userinfo_tl_data={0};
- krb5_timestamp modtime=0;
struct berval **bvalues=NULL;
LDAP *ld=NULL;
LDAPMessage *result=NULL, *ent=NULL;
}
snprintf(filter, princlen, FILTER"%s))", user);
- if ((st = krb5_get_subtree_info(ldap_context, subtree, &ntrees)) != 0)
+ if ((st = krb5_get_subtree_info(ldap_context, &subtree, &ntrees)) != 0)
goto cleanup;
GET_HANDLE();
/* get the associated directory user information */
if ((values=ldap_get_values(ld, ent, "krbprincipalname")) != NULL) {
- int i=0, pcount=0, ptype=KDB_USER_PRINCIPAL;
+ int i=0, pcount=0, kerberos_principal_object_type=0;
/* a wild-card in a principal name can return a list of kerberos principals.
* Make sure that the correct principal is returned.
if ((values=ldap_get_values(ld, ent, "objectclass")) != NULL) {
for (i=0; values[i] != NULL; ++i)
if (strcasecmp(values[i], "krbprincipal") == 0) {
- ptype = KDB_SERVICE_PRINCIPAL;
+ kerberos_principal_object_type = KDB_STANDALONE_PRINCIPAL_OBJECT;
+ if ((st=store_tl_data(&userinfo_tl_data, KDB_TL_PRINCTYPE, &kerberos_principal_object_type)) != 0)
+ goto cleanup;
break;
}
ldap_value_free(values);
/* add principalcount, DN and principaltype user information to tl_data */
if (((st=store_tl_data(&userinfo_tl_data, KDB_TL_PRINCCOUNT, &pcount)) != 0) ||
- ((st=store_tl_data(&userinfo_tl_data, KDB_TL_USERDN, DN)) != 0) ||
- ((st=store_tl_data(&userinfo_tl_data, KDB_TL_PRINCTYPE, &ptype)) != 0))
+ ((st=store_tl_data(&userinfo_tl_data, KDB_TL_USERDN, DN)) != 0))
goto cleanup;
}
/* read all the kerberos attributes */
+#ifdef KRBCONF_KDC_MODIFIES_KDB
+ /* KRBLASTSUCCESSFULAUTH */
+ if ((st=krb5_ldap_get_time(ld, ent, "krbLastSuccessfulAuth", &(entries->last_success),&attr_present)) != 0)
+ goto cleanup;
+ if (attr_present == TRUE)
+ mask |= KDB_LAST_SUCCESS;
+
+ /* KRBLASTFAILEDAUTH */
+ if ((st=krb5_ldap_get_time(ld, ent, "krbLastFailedAuth", &(entries->last_failed),&attr_present)) != 0)
+ goto cleanup;
+ if (attr_present == TRUE)
+ mask |= KDB_LAST_FAILED;
+
+ /* KRBLOGINFAILEDCOUNT */
+ if (krb5_ldap_get_value(ld, ent, "krbLoginFailedCount", &(entries->fail_auth_count)) == 0)
+ mask |= KDB_FAIL_AUTH_COUNT;
+#endif
+
/* KRBMAXTICKETLIFE */
if (krb5_ldap_get_value(ld, ent, "krbmaxticketlife", &(entries->max_life)) == 0)
mask |= KDB_MAX_LIFE_ATTR;
/* KRBPOLICYREFERENCE */
- if ((st=krb5_ldap_get_string(ld, ent, "krbpolicyreference", &policydn, &attr_present)) != 0)
+ if ((st=krb5_ldap_get_string(ld, ent, "krbticketpolicyreference", &policydn, &attr_present)) != 0)
goto cleanup;
if (attr_present == TRUE) {
- if ((st=store_tl_data(&userinfo_tl_data, KDB_TL_TKTPOLICYDN, policydn)) != 0)
+ /* Ensure that the policy is inside the realm container */
+ if ((st = krb5_ldap_policydn_to_name (context, policydn, &tktpolname)) != 0)
goto cleanup;
- mask |= KDB_POL_REF_ATTR;
}
/* KRBPWDPOLICYREFERENCE */
krb5_tl_data kadm_tl_data;
mask |= KDB_PWD_POL_REF_ATTR;
- if ((st = krb5_update_tl_kadm_data(pwdpolicydn, &kadm_tl_data)) != 0) {
+
+ /* Ensure that the policy is inside the realm container */
+ if ((st = krb5_ldap_policydn_to_name (context, pwdpolicydn, &polname)) != 0)
+ goto cleanup;
+
+ if ((st = krb5_update_tl_kadm_data(polname, &kadm_tl_data)) != 0) {
goto cleanup;
}
krb5_dbe_update_tl_data(context, entries, &kadm_tl_data);
}
/* KRBSECRETKEY */
- if ((bvalues=ldap_get_values_len(ld, ent, "krbsecretkey")) != NULL) {
+ if ((bvalues=ldap_get_values_len(ld, ent, "krbprincipalkey")) != NULL) {
mask |= KDB_SECRET_KEY;
if ((st=krb5_decode_krbsecretkey(context, entries, bvalues, &userinfo_tl_data)) != 0)
goto cleanup;
}
- /* MODIFY TIMESTAMP */
- if ((st=krb5_ldap_get_time(ld, ent, "modifytimestamp", &modtime, &attr_present)) != 0)
- goto cleanup;
-
- /* MODIFIER'S NAME */
- if ((st=krb5_ldap_get_string(ld, ent, "modifiersname", &modname, &attr_present)) != 0)
- goto cleanup;
- if (attr_present == TRUE) {
- if ((st=krb5_parse_name(context, modname, &parsed_mod_name)) != 0)
+ /* LAST PASSWORD CHANGE */
+ {
+ krb5_timestamp lstpwdchng=0;
+ if ((st=krb5_ldap_get_time(ld, ent, "krbLastPwdChange",
+ &lstpwdchng, &attr_present)) != 0)
goto cleanup;
+ if (attr_present == TRUE) {
+ if ((st=krb5_dbe_update_last_pwd_change(context, entries,
+ lstpwdchng)))
+ goto cleanup;
+ mask |= KDB_LAST_PWD_CHANGE_ATTR;
+ }
+ }
- if ((st=krb5_dbe_update_mod_princ_data(context, entries, modtime, parsed_mod_name)) != 0)
+ /* KRBOBJECTREFERENCES */
+ {
+ int i=0;
+ if ((st=krb5_ldap_get_strings(ld, ent, "krbobjectreferences", &link_references, &attr_present)) != 0)
goto cleanup;
+ if (link_references != NULL) {
+ for (i=0; link_references[i] != NULL; ++i) {
+ if ((st=store_tl_data(&userinfo_tl_data, KDB_TL_LINKDN, link_references[i])) != 0)
+ goto cleanup;
+ }
+ }
+ }
+
+ // Set tl_data
+ {
+ int i;
+ struct berval **ber_tl_data = NULL;
+ krb5_tl_data *ptr = NULL;
+
+ if ((ber_tl_data = ldap_get_values_len (ld, ent, "krbExtraData")) != NULL) {
+ for (i = 0; ber_tl_data[i] != NULL; i++) {
+ if ((st = berval2tl_data (ber_tl_data[i] , &ptr)) != 0)
+ break;
+ if ((st = krb5_dbe_update_tl_data(context, entries, ptr)) != 0)
+ break;
+ }
+ ldap_value_free_len (ber_tl_data);
+ if (st != 0)
+ goto cleanup;
+ mask |= KDB_EXTRA_DATA;
+ }
}
/* update the mask of attributes present on the directory object to the tl_data */
if (*nentries == 0)
goto cleanup;
- if ((st=krb5_read_tkt_policyreference(context, ldap_context, entries, policydn)) !=0)
+ if ((st=krb5_read_tkt_policy (context, ldap_context, entries, tktpolname)) !=0)
goto cleanup;
- if (pwdpolicydn) {
+ /* We already know that the policy is inside the realm container. */
+ if (polname) {
osa_policy_ent_t pwdpol;
int cnt=0;
krb5_timestamp last_pw_changed;
memset(&pwdpol, 0, sizeof(pwdpol));
- if ((st=krb5_ldap_get_password_policy(context, pwdpolicydn, &pwdpol, &cnt)) != 0)
+ if ((st=krb5_ldap_get_password_policy(context, polname, &pwdpol, &cnt)) != 0)
goto cleanup;
pw_max_life = pwdpol->pw_max_life;
free (pwdpol);
if (DN)
ldap_memfree (DN);
- for (; ntrees; --ntrees)
- if (subtree[ntrees-1])
- free (subtree[ntrees-1]);
+ if (subtree) {
+ for (; ntrees; --ntrees)
+ if (subtree[ntrees-1])
+ free (subtree[ntrees-1]);
+ free (subtree);
+ }
if (userinfo_tl_data.tl_data_contents)
free(userinfo_tl_data.tl_data_contents);
if (user)
free(user);
- if (modname)
- free(modname);
-
if (parsed_mod_name)
krb5_free_principal(context, parsed_mod_name);
if (pwdpolicydn)
free(pwdpolicydn);
+ if (polname != NULL)
+ free(polname);
+
+ if (tktpolname != NULL)
+ free (tktpolname);
+
if (policydn)
free(policydn);
return st;
}
+typedef enum{ ADD_PRINCIPAL, MODIFY_PRINCIPAL } OPERATION;
+/*
+ * ptype is creating confusions. Additionally the logic
+ * surronding ptype is redundunt and can be achevied
+ * with the help of dn and containerdn members.
+ * so dropping the ptype member
+ */
+
typedef struct _xargs_t {
- int ptype;
char *dn;
+ char *linkdn;
krb5_boolean dn_from_kbd;
char *containerdn;
char *tktpolicydn;
{
if (xargs.dn)
free (xargs.dn);
+ if (xargs.linkdn)
+ free(xargs.linkdn);
if (xargs.containerdn)
free (xargs.containerdn);
if (xargs.tktpolicydn)
}
static krb5_error_code
-process_db_args(context, db_args, xargs)
+process_db_args(context, db_args, xargs, optype)
krb5_context context;
char **db_args;
xargs_t *xargs;
+ OPERATION optype;
{
int i=0;
krb5_error_code st=0;
char errbuf[1024];
- char *arg=NULL, *arg_val=NULL;
+ char *arg=NULL, *arg_val=NULL;
+ char **dptr=NULL;
unsigned int arg_val_len=0;
- krb5_boolean uflag=FALSE, cflag=FALSE;
if (db_args) {
for (i=0; db_args[i]; ++i) {
arg = strtok_r(db_args[i], "=", &arg_val);
- if (strcmp(arg, USERDN_ARG) == 0) {
- if (cflag == TRUE) {
- st = EINVAL;
- krb5_set_error_message(context, st, "'containerdn' and 'userdn' can not both "
- "be specified");
- goto cleanup;
- }
- if (xargs->dn != NULL || xargs->containerdn != NULL) {
- st = EINVAL;
- snprintf(errbuf, sizeof(errbuf), "%s option not supported", arg);
- krb5_set_error_message(context, st, "%s", errbuf);
- goto cleanup;
- }
- if (strcmp(arg_val, "") == 0 || arg_val == NULL) {
+ if (strcmp(arg, TKTPOLICY_ARG) == 0) {
+ dptr = &xargs->tktpolicydn;
+ } else {
+ if (strcmp(arg, USERDN_ARG) == 0) {
+ if (optype == MODIFY_PRINCIPAL) {
+ st = EINVAL;
+ snprintf(errbuf, sizeof(errbuf), "%s option not supported", arg);
+ krb5_set_error_message(context, st, "%s", errbuf);
+ goto cleanup;
+ }
+ dptr = &xargs->dn;
+ } else if (strcmp(arg, CONTAINERDN_ARG) == 0) {
+ if (optype == MODIFY_PRINCIPAL) {
+ st = EINVAL;
+ snprintf(errbuf, sizeof(errbuf), "%s option not supported", arg);
+ krb5_set_error_message(context, st, "%s", errbuf);
+ goto cleanup;
+ }
+ dptr = &xargs->containerdn;
+ } else if (strcmp(arg, LINKDN_ARG) == 0) {
+ dptr = &xargs->linkdn;
+ } else {
st = EINVAL;
- snprintf(errbuf, sizeof(errbuf), "%s option value missing", arg);
+ snprintf(errbuf, sizeof(errbuf), "unknown option: %s", arg);
krb5_set_error_message(context, st, "%s", errbuf);
goto cleanup;
}
- arg_val_len = strlen(arg_val) + 1;
- xargs->dn = calloc (1, arg_val_len);
- if (xargs->dn == NULL) {
- st = ENOMEM;
- goto cleanup;
- }
- uflag = TRUE;
- xargs->ptype = KDB_USER_PRINCIPAL;
+
xargs->dn_from_kbd = TRUE;
- memcpy(xargs->dn, arg_val, arg_val_len);
- } else if (strcmp(arg, CONTAINERDN_ARG) == 0) {
- if (uflag == TRUE) {
- st = EINVAL;
- krb5_set_error_message(context, st, "'containerdn' and 'userdn' can not both "
- "be specified");
- goto cleanup;
- }
- if (xargs->dn != NULL || xargs->containerdn != NULL) {
+ if (xargs->dn != NULL || xargs->containerdn != NULL || xargs->linkdn != NULL) {
st = EINVAL;
snprintf(errbuf, sizeof(errbuf), "%s option not supported", arg);
krb5_set_error_message(context, st, "%s", errbuf);
goto cleanup;
}
- if (strcmp(arg_val, "") == 0 || arg_val == NULL) {
+ if (arg_val == NULL || strlen(arg_val) == 0) {
st = EINVAL;
snprintf(errbuf, sizeof(errbuf), "%s option value missing", arg);
krb5_set_error_message(context, st, "%s", errbuf);
goto cleanup;
}
- arg_val_len = strlen(arg_val) + 1;
- xargs->containerdn = calloc (1, arg_val_len);
- if (xargs->containerdn == NULL) {
- st = ENOMEM;
- goto cleanup;
- }
- cflag = TRUE;
- xargs->ptype = KDB_SERVICE_PRINCIPAL;
- xargs->dn_from_kbd = TRUE;
- memcpy(xargs->containerdn, arg_val, arg_val_len);
- } else if (strcmp(arg, TKTPOLICYDN_ARG) == 0) {
- if (arg_val == NULL) {
- st = EINVAL;
- snprintf(errbuf, sizeof(errbuf), "%s option value missing", arg);
- krb5_set_error_message(context, st, "%s", errbuf);
- goto cleanup;
- }
- arg_val_len = strlen(arg_val) + 1;
- xargs->tktpolicydn = calloc (1, arg_val_len);
- if (xargs->tktpolicydn == NULL) {
- st = ENOMEM;
- goto cleanup;
- }
- memcpy(xargs->tktpolicydn, arg_val, arg_val_len);
+ }
- } else {
+ if (arg_val == NULL) {
st = EINVAL;
- snprintf(errbuf, sizeof(errbuf), "unknown option: %s", arg);
+ snprintf(errbuf, sizeof(errbuf), "%s option value missing", arg);
krb5_set_error_message(context, st, "%s", errbuf);
goto cleanup;
}
+ arg_val_len = strlen(arg_val) + 1;
+
+ if (strcmp(arg, TKTPOLICY_ARG) == 0) {
+ if ((st = krb5_ldap_name_to_policydn (context, arg_val, dptr)) != 0)
+ goto cleanup;
+ } else {
+ *dptr = calloc (1, arg_val_len);
+ if (*dptr == NULL) {
+ st = ENOMEM;
+ goto cleanup;
+ }
+ memcpy(*dptr, arg_val, arg_val_len);
+ }
}
}
+
cleanup:
return st;
}
return ret;
}
+static krb5_error_code tl_data2berval (krb5_tl_data *in, struct berval **out) {
+ *out = (struct berval *) malloc (sizeof (struct berval));
+ if (*out == NULL)
+ return ENOMEM;
+
+ (*out)->bv_len = in->tl_data_length + 2;
+ (*out)->bv_val = (char *) malloc ((*out)->bv_len);
+ if ((*out)->bv_val == NULL) {
+ free (*out);
+ return ENOMEM;
+ }
+
+ STORE16_INT((*out)->bv_val, in->tl_data_type);
+ memcpy ((*out)->bv_val + 2, in->tl_data_contents, in->tl_data_length);
+
+ return 0;
+}
+
krb5_error_code
krb5_ldap_put_principal(context, entries, nentries, db_args)
krb5_context context;
register int *nentries; /* number of entry structs to update */
char **db_args;
{
- int i=0, l=0, plen=0;
+ int i=0, l=0, plen=0, kerberos_principal_object_type=0;
krb5_error_code st=0, tempst=0;
LDAP *ld=NULL;
LDAPMessage *result=NULL, *ent=NULL;
- char *user=NULL, *subtree=NULL;
+ char *user=NULL, *subtree=NULL, *principal_dn=NULL;
char **values=NULL, *strval[10]={NULL}, errbuf[1024];
struct berval **bersecretkey=NULL;
- LDAPMod **mods=NULL;
- krb5_boolean dnfound=TRUE, tktpolicy_set=FALSE;
+ LDAPMod **mods=NULL, **mod_for_link=NULL;
+ krb5_boolean dnfound=TRUE, tktpolicy_set=FALSE, create_standalone_prinicipal=FALSE;
+ krb5_boolean krb_identity_exists=FALSE, establish_links=FALSE;
+ krb5_boolean extend_object_with_princrefaux=FALSE;
+ char *standalone_principal_dn=NULL;
krb5_tl_data *tl_data=NULL;
krb5_key_data **keys=NULL;
kdb5_dal_handle *dal_handle=NULL;
krb5_ldap_server_handle *ldap_server_handle=NULL;
osa_princ_ent_rec princ_ent;
xargs_t xargs={0};
- char *oldpolicydn = NULL;
+ char *polname = NULL;
+ OPERATION optype;
/* Clear the global error string */
krb5_clear_error_message(context);
goto cleanup;
plen = strlen(user);
}
- xargs.ptype = KDB_SERVICE_PRINCIPAL;
- if (((st=krb5_get_princ_type(context, entries, &(xargs.ptype))) != 0) ||
- ((st=krb5_get_userdn(context, entries, &(xargs.dn))) != 0))
- goto cleanup;
- if ((st=process_db_args(context, db_args, &xargs)) != 0)
+ /* Identity the type of operation, it can be
+ * add principal or modify principal.
+ * hack if the entries->mask has KRB_PRINCIPAL flag set
+ * then it is a add operation
+ */
+ if (entries->mask & KDB_PRINCIPAL == 1)
+ optype = ADD_PRINCIPAL;
+ else
+ optype = MODIFY_PRINCIPAL;
+
+ if (((st=krb5_get_princ_type(context, entries, &kerberos_principal_object_type)) != 0) ||
+ ((st=krb5_get_userdn(context, entries, &principal_dn)) != 0))
goto cleanup;
- if (xargs.dn == NULL) { /* creation of service principal */
- if (xargs.ptype == KDB_USER_PRINCIPAL) {
- st = EINVAL;
- krb5_set_error_message(context, st, "User DN is missing");
- goto cleanup;
- }
+ if ((st=process_db_args(context, db_args, &xargs, optype)) != 0)
+ goto cleanup;
+ /* 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 */
/* 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) {
goto cleanup;
}
subtree = strdup(xargs.containerdn);
- } else if (ldap_context->lrparams->subtree && strlen(ldap_context->lrparams->subtree) != 0) {
- subtree = strdup(ldap_context->lrparams->subtree);
+ } else if (ldap_context->lrparams->containerref && strlen(ldap_context->lrparams->containerref) != 0) {
+ /*
+ * Here the subtree should be changed with
+ * principalcontainerreference attribute value
+ */
+ subtree = strdup(ldap_context->lrparams->containerref);
} else {
subtree = strdup(ldap_context->lrparams->realmdn);
}
CHECK_NULL(subtree);
- xargs.dn = malloc(strlen("krbprincipalname=") + strlen(user) + strlen(",") +
- strlen(subtree) + 1);
- CHECK_NULL(xargs.dn);
- sprintf(xargs.dn, "krbprincipalname=%s,%s", user, subtree);
+ standalone_principal_dn = malloc(strlen("krbprincipalname=") + strlen(user) + strlen(",") +
+ strlen(subtree) + 1);
+ CHECK_NULL(standalone_principal_dn);
+ sprintf(standalone_principal_dn, "krbprincipalname=%s,%s", user, subtree);
+ /*
+ * free subtree when you are done using the subtree
+ * set the boolean create_standalone_prinicipal to TRUE
+ */
+ create_standalone_prinicipal = TRUE;
+ free(subtree);
+ subtree = NULL;
}
+ /*
+ * If the DN information is presented by the user, time to
+ * validate the input to ensure that the DN falls under
+ * any of the subtrees
+ */
if (xargs.dn_from_kbd == TRUE) {
/* make sure the DN falls in the subtree */
int tre=0, dnlen=0, subtreelen=0, ntrees=0;
- char *subtreelist[2]={NULL};
+ char **subtreelist=NULL;
+ char *dn=NULL;
krb5_boolean outofsubtree=TRUE;
+ if (xargs.dn != NULL) {
+ dn = xargs.dn;
+ } else if (xargs.linkdn != NULL) {
+ dn = xargs.linkdn;
+ } else if (standalone_principal_dn != NULL) {
+ /*
+ * Even though the standalone_principal_dn is constructed
+ * within this function, there is the containerdn input
+ * from the user that can become part of the it.
+ */
+ dn = standalone_principal_dn;
+ }
+
/* get the current subtree list */
- if ((st = krb5_get_subtree_info(ldap_context, subtreelist, &ntrees)) != 0)
+ if ((st = krb5_get_subtree_info(ldap_context, &subtreelist, &ntrees)) != 0)
goto cleanup;
for (tre=0; tre<ntrees; ++tre) {
outofsubtree = FALSE;
break;
} else {
- dnlen = strlen (xargs.dn);
+ dnlen = strlen (dn);
subtreelen = strlen(subtreelist[tre]);
- if ((dnlen > subtreelen) && (strcasecmp((xargs.dn + dnlen - subtreelen), subtreelist[tre]) == 0)) {
+ if ((dnlen >= subtreelen) && (strcasecmp((dn + dnlen - subtreelen), subtreelist[tre]) == 0)) {
outofsubtree = FALSE;
break;
}
krb5_set_error_message(context, st, "DN is out of the realm subtree");
goto cleanup;
}
- }
- /* check if the DN exists */
- {
- char *attributes[]={"krbpolicyreference", NULL};
-
- LDAP_SEARCH_1(xargs.dn, LDAP_SCOPE_BASE, 0, attributes,IGNORE_STATUS);
- if (st == LDAP_NO_SUCH_OBJECT) {
- dnfound = FALSE;
- st = LDAP_SUCCESS;
- } else if (st == LDAP_SUCCESS) {
- ent = ldap_first_entry(ld, result);
- if (ent != NULL) {
- if ((values=ldap_get_values(ld, ent, "krbpolicyreference")) != NULL) {
- tktpolicy_set = TRUE;
- ldap_value_free(values);
+ /*
+ * dn value will be set either by dn, linkdn or the standalone_principal_dn
+ * In the first 2 cases, the dn should be existing and in the last case we
+ * are supposed to create the ldap object. so the below should not be
+ * executed for the last case.
+ */
+
+ if (standalone_principal_dn == NULL) {
+ /*
+ * If the ldap object is missing, this results in an error.
+ */
+
+ /*
+ * Search for krbprincipalname attribute here.
+ * This is to find if a kerberos identity is already present
+ * on the ldap object, in which case adding a kerberos identity
+ * on the ldap object should result in an error.
+ */
+ char *attributes[]={"krbticketpolicyreference", "krbprincipalname", NULL};
+
+ 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 ((values=ldap_get_values(ld, ent, "krbprincipalname")) != NULL) {
+ krb_identity_exists = TRUE;
+ ldap_value_free(values);
+ }
}
+ ldap_msgfree(result);
+ } else {
+ st = set_ldap_error(context, st, OP_SEARCH);
+ goto cleanup;
}
- ldap_msgfree(result);
- } else {
- st = set_ldap_error(context, st, OP_SEARCH);
- goto cleanup;
}
}
- if (dnfound == FALSE) { /* create a new object */
- if (xargs.ptype == KDB_USER_PRINCIPAL) {
- memset(strval, 0, sizeof(strval));
- strval[0] = "inetorgperson";
- strval[1] = "Person";
- strval[2] = "krbprincipalaux";
- strval[3] = "krbpolicyaux";
- strval[4] = "krbpwdpolicyrefaux";
- if ((st=krb5_add_str_mem_ldap_mod(&mods, "objectclass", LDAP_MOD_ADD, strval)) != 0)
- goto cleanup;
- values = ldap_explode_dn(xargs.dn, 1);
- if (values == NULL) {
- st = EINVAL;
- krb5_set_error_message(context, st, "Invalid DN");
- goto cleanup;
- }
- memset(strval, 0, sizeof(strval));
- strval[0] = values[0];
- if ((st=krb5_add_str_mem_ldap_mod(&mods, "cn", LDAP_MOD_ADD, strval)) != 0) {
- ldap_value_free(values);
- goto cleanup;
- }
- /* surname is set same as the cn */
- if ((st=krb5_add_str_mem_ldap_mod(&mods, "Surname", LDAP_MOD_ADD, strval)) != 0) {
- ldap_value_free(values);
- goto cleanup;
- }
- ldap_value_free(values);
- } else {
- memset(strval, 0, sizeof(strval));
- strval[0] = "krbprincipal";
- strval[1] = "krbprincipalaux";
- strval[2] = "krbpolicyaux";
- strval[3] = "krbpwdpolicyrefaux";
- if ((st=krb5_add_str_mem_ldap_mod(&mods, "objectclass", LDAP_MOD_ADD, strval)) != 0)
- goto cleanup;
- }
- } else { /* update the objectclass attribute if any of these is missing */
- char *attrvalues[] = {"krbprincipalaux", "krbpolicyaux", "krbpwdpolicyrefaux", NULL};
- int p, q, r=0, amask=0;
+ /*
+ * If xargs.dn is set then the request is to add a
+ * kerberos principal on a ldap object, but if
+ * there is one already on the ldap object this
+ * should result in an error.
+ */
- if ((st=checkattributevalue(ld, xargs.dn, "objectclass", attrvalues, &amask)) != 0) {
- st = KRB5_KDB_UK_RERROR;
+ if (xargs.dn != NULL && krb_identity_exists == TRUE) {
+ st = EINVAL;
+ snprintf(errbuf, sizeof(errbuf), "ldap object is already kerberized");
+ krb5_set_error_message(context, st, "%s", errbuf);
+ goto cleanup;
+ }
+
+ if (xargs.linkdn != NULL) {
+ /*
+ * link information can be changed using modprinc.
+ * However, link information can be changed only on the
+ * standalone kerberos principal objects. A standalone
+ * kerberos principal object is of type krbprincipal
+ * structural objectclass.
+ *
+ * NOTE: kerberos principals on an ldap object can't be
+ * linked to other ldap objects.
+ */
+ 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");
+ krb5_set_error_message(context, st, "%s", errbuf);
goto cleanup;
}
+ establish_links = TRUE;
+ }
+
+#ifdef KRBCONF_KDC_MODIFIES_KDB
+ if ((entries->last_success)!=0) {
memset(strval, 0, sizeof(strval));
- for (p=1, q=0; p<=4; p<<=1, ++q) {
- if ((p & amask) == 0)
- strval[r++] = attrvalues[q];
+ if ((strval[0]=getstringtime(entries->last_success)) == NULL)
+ goto cleanup;
+ if ((st=krb5_add_str_mem_ldap_mod(&mods, "krbLastSuccessfulAuth", LDAP_MOD_REPLACE, strval)) != 0) {
+ free (strval[0]);
+ goto cleanup;
}
- if (r != 0) {
- if ((st=krb5_add_str_mem_ldap_mod(&mods, "objectclass", LDAP_MOD_ADD, strval)) != 0)
- goto cleanup;
+ free (strval[0]);
+ }
+
+ if (entries->last_failed!=0) {
+ memset(strval, 0, sizeof(strval));
+ if ((strval[0]=getstringtime(entries->last_failed)) == NULL)
+ goto cleanup;
+ if ((st=krb5_add_str_mem_ldap_mod(&mods, "krbLastFailedAuth", LDAP_MOD_REPLACE, strval)) != 0) {
+ free (strval[0]);
+ goto cleanup;
}
+ free(strval[0]);
}
+ if (entries->fail_auth_count!=0) {
+ if ((st=krb5_add_int_mem_ldap_mod(&mods, "krbLoginFailedCount", LDAP_MOD_REPLACE, entries->fail_auth_count)) !=0)
+ goto cleanup;
+ }
+#endif
+
if (entries->mask & KDB_MAX_LIFE) {
if ((st=krb5_add_int_mem_ldap_mod(&mods, "krbmaxticketlife", LDAP_MOD_REPLACE, entries->max_life)) != 0)
goto cleanup;
if (princ_ent.aux_attributes & KDB_POLICY) {
memset(strval, 0, sizeof(strval));
- strval[0] = princ_ent.policy;
+ if ((st = krb5_ldap_name_to_policydn (context, princ_ent.policy, &polname)) != 0)
+ goto cleanup;
+ strval[0] = polname;
if ((st=krb5_add_str_mem_ldap_mod(&mods, "krbpwdpolicyreference", LDAP_MOD_REPLACE, strval)) != 0)
goto cleanup;
} else {
}
if (entries->mask & KDB_POLICY_CLR) {
- memset(strval, 0, sizeof(strval));
- if ((st=krb5_add_str_mem_ldap_mod(&mods, "krbpwdpolicyreference", LDAP_MOD_DELETE, strval)) != 0)
+ if ((st=krb5_add_str_mem_ldap_mod(&mods, "krbpwdpolicyreference", LDAP_MOD_DELETE, NULL)) != 0)
goto cleanup;
}
bersecretkey = krb5_encode_krbsecretkey (entries->key_data,
entries->n_key_data);
- if ((st=krb5_add_ber_mem_ldap_mod(&mods, "krbsecretkey",
+ if ((st=krb5_add_ber_mem_ldap_mod(&mods, "krbprincipalkey",
LDAP_MOD_REPLACE | LDAP_MOD_BVALUES, bersecretkey)) != 0)
goto cleanup;
}
free (strval[0]);
}
+
+ /* Update last password change whenever a new key is set */
+ {
+ krb5_timestamp last_pw_changed;
+ if ((st=krb5_dbe_lookup_last_pwd_change(context, entries,
+ &last_pw_changed)) != 0)
+ goto cleanup;
+
+ memset(strval, 0, sizeof(strval));
+ if ((strval[0] = getstringtime(last_pw_changed)) == NULL)
+ goto cleanup;
+
+ if ((st=krb5_add_str_mem_ldap_mod(&mods, "krbLastPwdChange",
+ LDAP_MOD_REPLACE, strval)) != 0) {
+ free (strval[0]);
+ goto cleanup;
+ }
+ free (strval[0]);
+ }
+
} /* Modify Key data ends here */
+ // Set tl_data
+ if (entries->tl_data != NULL) {
+ int count = 0;
+ struct berval **ber_tl_data = NULL;
+ krb5_tl_data *ptr;
+ for (ptr = entries->tl_data; ptr != NULL; ptr = ptr->tl_data_next) {
+ if (ptr->tl_data_type == KRB5_TL_LAST_PWD_CHANGE
+#ifdef SECURID
+ || ptr->tl_data_type == KRB5_TL_DB_ARGS
+#endif
+ || ptr->tl_data_type == KRB5_TL_KADM_DATA
+ || ptr->tl_data_type == KDB_TL_USER_INFO)
+ continue;
+ count ++;
+ }
+ if (count != 0) {
+ int i;
+ ber_tl_data = (struct berval **) calloc (count, sizeof (struct
+ berval*));
+ for (i = 0, ptr = entries->tl_data; ptr != NULL; ptr = ptr->tl_data_next) {
+ /* Ignore tl_data that are stored in separate directory
+ * attributes */
+ if (ptr->tl_data_type == KRB5_TL_LAST_PWD_CHANGE
+#ifdef SECURID
+ || ptr->tl_data_type == KRB5_TL_DB_ARGS
+#endif
+ || ptr->tl_data_type == KRB5_TL_KADM_DATA
+ || ptr->tl_data_type == KDB_TL_USER_INFO)
+ continue;
+ if ((st = tl_data2berval (ptr, &ber_tl_data[i])) != 0)
+ break;
+ i++;
+ }
+ if (st != 0) {
+ for (i = 0; ber_tl_data[i] != NULL; i++) {
+ free (ber_tl_data[i]->bv_val);
+ free (ber_tl_data[i]);
+ }
+ free (ber_tl_data);
+ goto cleanup;
+ }
+ if ((st=krb5_add_ber_mem_ldap_mod(&mods, "krbExtraData",
+ LDAP_MOD_REPLACE | LDAP_MOD_BVALUES,
+ ber_tl_data)) != 0)
+ goto cleanup;
+ }
+ }
+
/* Directory specific attribute */
if (xargs.tktpolicydn != NULL) {
int tmask=0, tkttree = 0, subtreednlen = 0, ntre = 0, tktdnlen = 0;
- char *subtreednlist[2]={NULL};
+ char **subtreednlist=NULL;
krb5_boolean dnoutofsubtree=TRUE;
- if ((st=krb5_get_policydn(context, entries, &oldpolicydn)) != 0)
- goto cleanup;
-
if (strlen(xargs.tktpolicydn) != 0) {
st = checkattributevalue(ld, xargs.tktpolicydn, "objectclass", policyclass, &tmask);
CHECK_CLASS_VALIDITY(st, tmask, "ticket policy object value: ");
- memset(strval, 0, sizeof(strval));
strval[0] = xargs.tktpolicydn;
- if ((st = krb5_get_subtree_info(ldap_context, subtreednlist, &ntre)) != 0)
+ strval[1] = NULL;
+ if ((st=krb5_add_str_mem_ldap_mod(&mods, "krbticketpolicyreference", LDAP_MOD_REPLACE, strval)) != 0)
goto cleanup;
- for (tkttree=0; tkttree<ntre; ++tkttree) {
- if (subtreednlist[tkttree] == NULL || strlen(subtreednlist[tkttree]) == 0) {
- dnoutofsubtree = FALSE;
- break;
- } else {
- tktdnlen = strlen (xargs.tktpolicydn);
- subtreednlen = strlen(subtreednlist[tkttree]);
-
- if ((tktdnlen > subtreednlen) && (strcasecmp((xargs.tktpolicydn + tktdnlen - subtreednlen), subtreednlist[tkttree]) == 0)) {
- dnoutofsubtree = FALSE;
- break;
- }
- }
- }
- for (tkttree=0; tkttree < ntre; ++tkttree) {
- free(subtreednlist[tkttree]);
- }
- if (dnoutofsubtree == TRUE) {
- st = EINVAL;
- prepend_err_str(context,"Ticket Policy DN is out of the realm subtree",st,st);
- goto cleanup;
- }
-
- if ((st=krb5_add_str_mem_ldap_mod(&mods, "krbpolicyreference", LDAP_MOD_REPLACE, strval)) != 0)
- goto cleanup;
- if (oldpolicydn != NULL) {
- if (strncmp(xargs.tktpolicydn,oldpolicydn,strlen(xargs.tktpolicydn)) != 0) {
- if ((st = krb5_ldap_change_count(context, oldpolicydn,2)))
- goto cleanup;
- }
- }
-
- if ((st = krb5_ldap_change_count(context, xargs.tktpolicydn,1)))
- goto cleanup;
} else {
- /* if xargs.tktpolicydn is a empty string, then delete already existing krbpolicyreference attr */
- if (tktpolicy_set == FALSE) { /* if the attribute is not present then abort */
- st = EINVAL;
- prepend_err_str(context,"'ticketpolicydn' empty",st,st);
+ /* if xargs.tktpolicydn is a empty string, then delete
+ * already existing krbticketpolicyreference attr */
+ if ((st=krb5_add_str_mem_ldap_mod(&mods, "krbticketpolicyreference", LDAP_MOD_DELETE, NULL)) != 0)
goto cleanup;
- } else {
- memset(strval, 0, sizeof(strval));
- if ((st=krb5_add_str_mem_ldap_mod(&mods, "krbpolicyreference", LDAP_MOD_DELETE, strval)) != 0)
- goto cleanup;
- }
}
}
- if (dnfound == TRUE) {
- if (mods == NULL) {
+
+
+ if (establish_links == TRUE) {
+ memset(strval, 0, sizeof(strval));
+ strval[0] = xargs.linkdn;
+ if ((st=krb5_add_str_mem_ldap_mod(&mods, "krbObjectReferences", LDAP_MOD_REPLACE, strval)) != 0)
goto cleanup;
- }
- st=ldap_modify_ext_s(ld, xargs.dn, mods, NULL, NULL);
+ }
+
+ /*
+ * 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
+ * and the keys passed in
+ */
+ if (mods == NULL)
+ goto cleanup;
+
+ if (create_standalone_prinicipal == TRUE) {
+ memset(strval, 0, sizeof(strval));
+ strval[0] = "krbprincipal";
+ strval[1] = "krbprincipalaux";
+ strval[2] = "krbTicketPolicyAux";
+
+ 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);
if (st != LDAP_SUCCESS) {
- sprintf(errbuf, "User modification failed: %s", ldap_err2string(st));
- st = translate_ldap_error (st, OP_MOD);
+ sprintf(errbuf, "Principal add failed: %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, xargs.dn, mods, NULL, NULL);
+ /*
+ * Here existing ldap object is modified and can be related
+ * to any attribute, so always ensure that the ldap
+ * object is extended with all the kerberos related
+ * objectclasses so that there are no constraint
+ * violations.
+ */
+ {
+ char *attrvalues[] = {"krbprincipalaux", "krbTicketPolicyAux", NULL};
+ int p, q, r=0, amask=0;
+
+ if ((st=checkattributevalue(ld, (xargs.dn) ? xargs.dn : principal_dn,
+ "objectclass", attrvalues, &amask)) != 0) {
+ st = KRB5_KDB_UK_RERROR;
+ goto cleanup;
+ }
+ memset(strval, 0, sizeof(strval));
+ for (p=1, q=0; p<=2; p<<=1, ++q) {
+ if ((p & amask) == 0)
+ strval[r++] = attrvalues[q];
+ }
+ if (r != 0) {
+ if ((st=krb5_add_str_mem_ldap_mod(&mods, "objectclass", LDAP_MOD_ADD, strval)) != 0)
+ goto cleanup;
+ }
+ }
+ 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);
if (st != LDAP_SUCCESS) {
- sprintf(errbuf, "Principal add failed: %s", ldap_err2string(st));
- st = translate_ldap_error (st, OP_ADD);
+ sprintf(errbuf, "User modification failed: %s", ldap_err2string(st));
+ st = translate_ldap_error (st, OP_MOD);
krb5_set_error_message(context, st, "%s", errbuf);
goto cleanup;
}
free_xargs(xargs);
+ if (standalone_principal_dn)
+ free(standalone_principal_dn);
+
+ if (principal_dn)
+ free (principal_dn);
+
+ if (polname != NULL)
+ free(polname);
+
if (subtree)
free (subtree);
}
static krb5_error_code
-krb5_read_tkt_policyreference(context, ldap_context, entries, policydn)
+krb5_read_tkt_policy (context, ldap_context, entries, policy)
krb5_context context;
krb5_ldap_context *ldap_context;
krb5_db_entry *entries;
- char *policydn;
+ char *policy;
{
krb5_error_code st=0;
unsigned int mask=0, omask=0;
if ((st=krb5_get_attributes_mask(context, entries, &mask)) != 0)
goto cleanup;
- if ((mask & tkt_mask) == 0) {
- if (policydn != NULL) {
- st = krb5_ldap_read_policy(context, policydn, &tktpoldnparam, &omask);
- if (st && st != KRB5_KDB_NOENTRY) {
- prepend_err_str(context, "Error reading ticket policy. ", st, st);
- goto cleanup;
- }
+ if ((mask & tkt_mask) == tkt_mask)
+ goto cleanup;
- st = 0; /* reset the return status */
+ if (policy != NULL) {
+ st = krb5_ldap_read_policy(context, policy, &tktpoldnparam, &omask);
+ if (st && st != KRB5_KDB_NOENTRY) {
+ prepend_err_str(context, "Error reading ticket policy. ", st, st);
+ goto cleanup;
}
- if ((mask & KDB_MAX_LIFE_ATTR) == 0) {
- if ((omask & KDB_MAX_LIFE_ATTR) == KDB_MAX_LIFE_ATTR)
- entries->max_life = tktpoldnparam->maxtktlife;
- else if (ldap_context->lrparams->max_life)
- entries->max_life = ldap_context->lrparams->max_life;
- else if (ldap_context->krbcontainer->max_life)
- entries->max_life = ldap_context->krbcontainer->max_life;
- else
- entries->max_life = KRB5_KDB_MAX_LIFE;
- }
+ st = 0; /* reset the return status */
+ }
- if ((mask & KDB_MAX_RLIFE_ATTR) == 0) {
- if ((omask & KDB_MAX_RLIFE_ATTR) == KDB_MAX_RLIFE_ATTR)
- entries->max_renewable_life = tktpoldnparam->maxrenewlife;
- else if (ldap_context->lrparams->max_renewable_life)
- entries->max_renewable_life = ldap_context->lrparams->max_renewable_life;
- else if (ldap_context->krbcontainer->max_renewable_life)
- entries->max_renewable_life = ldap_context->krbcontainer->max_renewable_life;
- else
- entries->max_renewable_life = KRB5_KDB_MAX_RLIFE;
- }
+ if ((mask & KDB_MAX_LIFE_ATTR) == 0) {
+ if ((omask & KDB_MAX_LIFE_ATTR) == KDB_MAX_LIFE_ATTR)
+ entries->max_life = tktpoldnparam->maxtktlife;
+ else if (ldap_context->lrparams->max_life)
+ entries->max_life = ldap_context->lrparams->max_life;
+ else
+ entries->max_life = KRB5_KDB_MAX_LIFE;
+ }
- if ((mask & KDB_TKT_FLAGS_ATTR) == 0) {
- if ((omask & KDB_TKT_FLAGS_ATTR) == KDB_TKT_FLAGS_ATTR)
- entries->attributes = tktpoldnparam->tktflags;
- else if (ldap_context->lrparams->tktflags)
- entries->attributes |= ldap_context->lrparams->tktflags;
- else if (ldap_context->krbcontainer->tktflags)
- entries->attributes |= ldap_context->krbcontainer->tktflags;
- }
- krb5_ldap_free_policy(context, tktpoldnparam);
+ if ((mask & KDB_MAX_RLIFE_ATTR) == 0) {
+ if ((omask & KDB_MAX_RLIFE_ATTR) == KDB_MAX_RLIFE_ATTR)
+ entries->max_renewable_life = tktpoldnparam->maxrenewlife;
+ else if (ldap_context->lrparams->max_renewable_life)
+ entries->max_renewable_life = ldap_context->lrparams->max_renewable_life;
+ else
+ entries->max_renewable_life = KRB5_KDB_MAX_RLIFE;
+ }
+
+ if ((mask & KDB_TKT_FLAGS_ATTR) == 0) {
+ if ((omask & KDB_TKT_FLAGS_ATTR) == KDB_TKT_FLAGS_ATTR)
+ entries->attributes = tktpoldnparam->tktflags;
+ else if (ldap_context->lrparams->tktflags)
+ entries->attributes |= ldap_context->lrparams->tktflags;
}
+ krb5_ldap_free_policy(context, tktpoldnparam);
cleanup:
return st;
struct berval **bvalues;
krb5_tl_data *userinfo_tl_data;
{
- char *user=NULL, *ptr=NULL, *pname=NULL, *currentkey=NULL, *currentsalt=NULL;
- void *reallocptr=NULL;
- int i=0, j=0, k=0, plen=0, noofkeys=0, ist_pkeyver=0, pkeyver=0, mkeyver=0, keylen=0;
+ char *user=NULL;
+ int i=0, j=0, noofkeys=0;
krb5_key_data *key_data=NULL;
krb5_error_code st=0;
- krb5_timestamp last_pw_changed=0;
if ((st=krb5_unparse_name(context, entries->princ, &user)) != 0)
goto cleanup;
#include "ldap_pwd_policy.h"
#include "ldap_err.h"
-static char *password_policy_attributes[] = { "krbmaxpwdlife", "krbminpwdlife", "krbpwdmindiffchars",
- "krbpwdminlength", "krbpwdhistorylength", "krbpwdpolicyrefcount",
- NULL };
+static char *password_policy_attributes[] = { "krbmaxpwdlife", "krbminpwdlife",
+ "krbpwdmindiffchars", "krbpwdminlength",
+ "krbpwdhistorylength", NULL };
/*
* Function to create password policy object.
kdb5_dal_handle *dal_handle=NULL;
krb5_ldap_context *ldap_context=NULL;
krb5_ldap_server_handle *ldap_server_handle=NULL;
- char **rdns=NULL, *strval[2]={NULL};
+ char **rdns=NULL, *strval[2]={NULL}, *policy_dn;
/* Clear the global error string */
krb5_clear_error_message(context);
SETUP_CONTEXT();
GET_HANDLE();
+ st = krb5_ldap_name_to_policydn (context, policy->name, &policy_dn);
+ if (st != 0)
+ goto cleanup;
+
/* get the first component of the dn to set the cn attribute */
- rdns = ldap_explode_dn(policy->name, 1);
+ rdns = ldap_explode_dn(policy_dn, 1);
if (rdns == NULL) {
st = EINVAL;
krb5_set_error_message(context, st, "Invalid password policy DN syntax");
|| ((st=krb5_add_int_mem_ldap_mod(&mods, "krbpwdminlength", LDAP_MOD_ADD,
(signed) policy->pw_min_length)) != 0)
|| ((st=krb5_add_int_mem_ldap_mod(&mods, "krbpwdhistorylength", LDAP_MOD_ADD,
- (signed) policy->pw_history_num)) != 0)
- || ((st=krb5_add_int_mem_ldap_mod(&mods, "krbpwdpolicyrefcount", LDAP_MOD_ADD,
- (signed) policy->policy_refcnt)) != 0))
+ (signed) policy->pw_history_num)) != 0))
goto cleanup;
/* password policy object creation */
- if ((st=ldap_add_ext_s(ld, policy->name, mods, NULL, NULL)) != LDAP_SUCCESS) {
+ if ((st=ldap_add_ext_s(ld, policy_dn, mods, NULL, NULL)) != LDAP_SUCCESS) {
st = set_ldap_error (context, st, OP_ADD);
goto cleanup;
}
if (rdns)
ldap_value_free(rdns);
+ if (policy_dn != NULL)
+ free (policy_dn);
ldap_mods_free(mods, 1);
krb5_ldap_put_handle_to_pool(ldap_context, ldap_server_handle);
return(st);
krb5_context context;
osa_policy_ent_t policy;
{
+ char *policy_dn;
krb5_error_code st=0;
LDAP *ld=NULL;
LDAPMod **mods=NULL;
SETUP_CONTEXT();
GET_HANDLE();
+ st = krb5_ldap_name_to_policydn (context, policy->name, &policy_dn);
+ if (st != 0)
+ goto cleanup;
+
if (((st=krb5_add_int_mem_ldap_mod(&mods, "krbmaxpwdlife", LDAP_MOD_REPLACE,
(signed) policy->pw_max_life)) != 0)
|| ((st=krb5_add_int_mem_ldap_mod(&mods, "krbminpwdlife", LDAP_MOD_REPLACE,
|| ((st=krb5_add_int_mem_ldap_mod(&mods, "krbpwdminlength", LDAP_MOD_REPLACE,
(signed) policy->pw_min_length)) != 0)
|| ((st=krb5_add_int_mem_ldap_mod(&mods, "krbpwdhistorylength", LDAP_MOD_REPLACE,
- (signed) policy->pw_history_num)) != 0)
- || ((st=krb5_add_int_mem_ldap_mod(&mods, "krbpwdpolicyrefcount", LDAP_MOD_REPLACE,
- (signed) policy->policy_refcnt)) != 0))
+ (signed) policy->pw_history_num)) != 0))
goto cleanup;
/* modify the password policy object. */
- if ((st=ldap_modify_ext_s(ld, policy->name, mods, NULL, NULL)) != LDAP_SUCCESS) {
+ /*
+ * This will fail if the 'policy_dn' is anywhere other than under the realm
+ * container. This is correct behaviour. 'kdb5_ldap_util' will support
+ * management of only such policy objects.
+ */
+ if ((st=ldap_modify_ext_s(ld, policy_dn, mods, NULL, NULL)) != LDAP_SUCCESS) {
st = set_ldap_error (context, st, OP_MOD);
goto cleanup;
}
cleanup:
+ if (policy_dn != NULL)
+ free (policy_dn);
ldap_mods_free(mods, 1);
krb5_ldap_put_handle_to_pool(ldap_context, ldap_server_handle);
return(st);
}
krb5_error_code
-krb5_ldap_get_password_policy (context, name, policy, cnt)
+krb5_ldap_get_password_policy_from_dn (context, name, policy, cnt)
krb5_context context;
char *name;
osa_policy_ent_t *policy;
krb5_ldap_get_value(ld, ent, "krbpwdmindiffchars", &((*policy)->pw_min_classes));
krb5_ldap_get_value(ld, ent, "krbpwdminlength", &((*policy)->pw_min_length));
krb5_ldap_get_value(ld, ent, "krbpwdhistorylength", &((*policy)->pw_history_num));
- krb5_ldap_get_value(ld, ent, "krbpwdpolicyrefcount", &((*policy)->policy_refcnt));
+
+ /* Get the reference count */
+ st = krb5_ldap_get_reference_count (context,
+ name,
+ "krbPwdPolicyReference",
+ &(*policy)->policy_refcnt,
+ ld);
}
cleanup:
*policy = NULL;
}
}
+
krb5_ldap_put_handle_to_pool(ldap_context, ldap_server_handle);
return st;
}
+/*
+ * Convert 'name' into a directory DN and call
+ * 'krb5_ldap_get_password_policy_from_dn'
+ */
+krb5_error_code
+krb5_ldap_get_password_policy (context, name, policy, cnt)
+ krb5_context context;
+ char *name;
+ osa_policy_ent_t *policy;
+ int *cnt;
+{
+ krb5_error_code st = 0;
+ char *policy_dn = NULL;
+
+ /* Clear the global error string */
+ krb5_clear_error_message(context);
+
+ /* validate the input parameters */
+ if(name == NULL) {
+ st = EINVAL;
+ goto cleanup;
+ }
+
+ st = krb5_ldap_name_to_policydn (context, name, &policy_dn);
+ if (st != 0)
+ goto cleanup;
+
+ st = krb5_ldap_get_password_policy_from_dn (context, policy_dn, policy, cnt);
+ free (policy_dn);
+ if (st == 0)
+ (*policy)->name = name;
+
+cleanup:
+ return st;
+}
+
krb5_error_code
krb5_ldap_delete_password_policy (context, policy)
krb5_context context;
char *policy;
{
+ char *policy_dn = NULL;
krb5_error_code st=0;
LDAP *ld=NULL;
kdb5_dal_handle *dal_handle=NULL;
SETUP_CONTEXT();
GET_HANDLE();
- if ((st=ldap_delete_ext_s(ld, policy, NULL, NULL)) != LDAP_SUCCESS) {
+ st = krb5_ldap_name_to_policydn (context, policy, &policy_dn);
+ if (st != 0)
+ goto cleanup;
+
+ if ((st=ldap_delete_ext_s(ld, policy_dn, NULL, NULL)) != LDAP_SUCCESS) {
st = set_ldap_error (context, st, OP_DEL);
goto cleanup;
}
cleanup:
krb5_ldap_put_handle_to_pool(ldap_context, ldap_server_handle);
+ if (policy_dn != NULL)
+ free (policy_dn);
+
return st;
}
krb5_pointer func_arg;
{
osa_policy_ent_rec *entry=NULL;
- char *attrs[] = { "cn", NULL };
+ char *attrs[] = { "cn", NULL }, *policy=NULL;
krb5_error_code st=0, tempst=0;
LDAP *ld=NULL;
LDAPMessage *result=NULL, *ent=NULL;
kdb5_dal_handle *dal_handle=NULL;
krb5_ldap_context *ldap_context=NULL;
krb5_ldap_server_handle *ldap_server_handle=NULL;
- char *policy_dn=NULL;
/* Clear the global error string */
krb5_clear_error_message(context);
CHECK_NULL(entry);
memset(entry, 0, sizeof(osa_policy_ent_rec));
- LDAP_SEARCH(NULL, LDAP_SCOPE_SUBTREE, "(objectclass=krbpwdpolicy)", attrs);
- for (ent=ldap_first_entry(ld, result); ent != NULL; ent=ldap_next_entry(ld, ent)) {
- if ((policy_dn=ldap_get_dn(ld, ent)) == NULL)
- continue;
- entry->name = policy_dn;
- (*func)(func_arg, entry);
- ldap_memfree(policy_dn);
+ if (ldap_context->lrparams->realmdn == NULL) {
+ st = EINVAL;
+ goto cleanup;
+ }
+
+ LDAP_SEARCH(ldap_context->lrparams->realmdn, LDAP_SCOPE_ONELEVEL, "(objectclass=krbpwdpolicy)", attrs);
+ for(ent=ldap_first_entry(ld, result); ent != NULL; ent=ldap_next_entry(ld, ent)) {
+ krb5_boolean attr_present;
+
+ st = krb5_ldap_get_string(ld, ent, "cn", &policy, &attr_present);
+ if (st != 0)
+ goto cleanup;
+ if (attr_present == FALSE)
+ continue;
+ entry->name = policy;
+ (*func)(func_arg, entry);
+ ldap_memfree(policy);
}
ldap_msgfree(result);
#include "ldap_err.h"
#define END_OF_LIST -1
-char *realm_attributes[] = {"krbSearchScope","krbSubTree",
+char *realm_attributes[] = {"krbSearchScope","krbSubTrees", "krbPrincContainerRef",
"krbMaxTicketLife", "krbMaxRenewableAge",
"krbTicketFlags", "krbDefaultEncType",
"krbDefaultSaltType", "krbUpEnabled",
- "krbPolicyReference", "krbSupportedEncTypes",
+ "krbTicketPolicyReference", "krbSupportedEncTypes",
"krbSupportedSaltTypes", "krbLdapServers",
"krbKdcServers", "krbAdmServers",
"krbPwdServers", NULL};
-char *policyclass[] = { "krbPolicy", NULL };
+char *policyclass[] = { "krbTicketPolicy", NULL };
char *kdcclass[] = { "krbKdcService", NULL };
char *adminclass[] = { "krbAdmService", NULL };
char *pwdclass[] = { "krbPwdService", NULL };
-char *subtreeclass[] = { "Organization", "OrganizationalUnit", "Domain",
- "Country", "Locality", NULL };
+char *subtreeclass[] = { "Organization", "OrganizationalUnit", "Domain", "krbContainer",
+ "krbRealmContainer", "Country", "Locality", NULL };
int supportedenctypes[] = { ENCTYPE_DES_CBC_CRC, ENCTYPE_DES_CBC_MD4, ENCTYPE_DES_CBC_MD5,
ENCTYPE_DES3_CBC_SHA1, ENCTYPE_AES128_CTS_HMAC_SHA1_96,
* Function to remove all special characters from a string (rfc2254).
* Use whenever exact matching is to be done ...
*/
-static char *
-ldap_filter_correct (unsigned char *in, unsigned int len)
+char *ldap_filter_correct (unsigned char *in, unsigned int len)
{
int i, count;
char *out, *ptr;
return st;
}
-
/*
* Delete the realm along with the principals belonging to the realm in the Directory.
*/
{
LDAP *ld = NULL;
krb5_error_code st = 0, tempst=0;
- char **values=NULL, *subtrees[2]={NULL};;
- LDAPMessage *result_arr[3]={NULL}, *result = NULL, *ent = NULL;
+ char **values=NULL, **subtrees=NULL, **policy=NULL;
+ LDAPMessage **result_arr=NULL, *result = NULL, *ent = NULL;
krb5_principal principal;
int l=0, ntree=0, i=0, j=0, mask=0;
kdb5_dal_handle *dal_handle = NULL;
/* LDAP_SEARCH(NULL, LDAP_SCOPE_SUBTREE, filter, attr); */
memset(&lcontext, 0, sizeof(krb5_ldap_context));
lcontext.lrparams = rparam;
- if ((st=krb5_get_subtree_info(&lcontext, subtrees, &ntree)) != 0)
+ if ((st=krb5_get_subtree_info(&lcontext, &subtrees, &ntree)) != 0)
goto cleanup;
+ result_arr = (LDAPMessage **) calloc(ntree+1, sizeof(LDAPMessage *));
+ if (result_arr == NULL) {
+ st = ENOMEM;
+ goto cleanup;
+ }
+
for (l=0; l < ntree; ++l) {
LDAP_SEARCH(subtrees[l], rparam->search_scope, filter, attr);
result_arr[l] = result;
ldap_msgfree(result);
}
+ /* Delete all password policies */
+ {
+ char *attr[] = {NULL}, filter[256];
+
+ void delete_password_policy (krb5_pointer ptr, osa_policy_ent_t pol) {
+ krb5_ldap_delete_password_policy (context, pol->name);
+ }
+
+ krb5_ldap_iterate_password_policy (context, "*", delete_password_policy, NULL);
+ }
+
+ /* Delete all ticket policies */
+ {
+ if ((st = krb5_ldap_list_policy (context, ldap_context->lrparams->realmdn, &policy)) != 0) {
+ prepend_err_str (context, "Error reading ticket policy: ", st, st);
+ goto cleanup;
+ }
+
+ for (i = 0; policy [i] != NULL; i++)
+ krb5_ldap_delete_policy(context, policy[i]);
+ }
+
/* Delete the realm object */
if ((st=ldap_delete_ext_s(ld, ldap_context->lrparams->realmdn, NULL, NULL)) != LDAP_SUCCESS) {
int ost = st;
}
cleanup:
- for (l=0; l < ntree; ++l) {
+ if (subtrees) {
+ for (l=0; l < ntree; ++l) {
if (subtrees[l])
free (subtrees[l]);
+ }
+ free (subtrees);
+ }
+
+ if (policy != NULL) {
+ for (i = 0; policy[i] != NULL; i++)
+ free (policy[i]);
+ free (policy);
}
+
krb5_ldap_free_realm_params(rparam);
krb5_ldap_put_handle_to_pool(ldap_context, ldap_server_handle);
return st;
int mask;
{
LDAP *ld=NULL;
- krb5_error_code st=0;
- char *strval[5]={NULL};
+ krb5_error_code st=0, retval=0;
+ char **strval=NULL, *strvalprc[5]={NULL};
#ifdef HAVE_EDIRECTORY
char **values=NULL;
char **oldkdcservers=NULL, **oldadminservers=NULL, **oldpasswdservers=NULL;
char errbuf[1024];
#endif
LDAPMod **mods = NULL;
- int i=0, oldmask=0, objectmask=0;
+ int i=0, oldmask=0, objectmask=0,k=0,part_of_subtree=0;
kdb5_dal_handle *dal_handle=NULL;
krb5_ldap_context *ldap_context=NULL;
krb5_ldap_server_handle *ldap_server_handle=NULL;
rparams->tl_data == NULL ||
rparams->tl_data->tl_data_contents == NULL ||
((mask & LDAP_REALM_SUBTREE) && rparams->subtree == NULL) ||
+ ((mask & LDAP_REALM_CONTREF) && rparams->containerref == NULL) ||
/* This has to be fixed ... */
((mask & LDAP_REALM_DEFENCTYPE) && rparams->suppenctypes == NULL) ||
((mask & LDAP_REALM_DEFSALTTYPE) && rparams->suppsalttypes == NULL) ||
/* SUBTREE ATTRIBUTE */
if (mask & LDAP_REALM_SUBTREE) {
- if (strlen(rparams->subtree) != 0) {
- st = checkattributevalue(ld, rparams->subtree, "Objectclass", subtreeclass,
- &objectmask);
- CHECK_CLASS_VALIDITY(st, objectmask, "subtree value: ");
- }
- memset(strval, 0, sizeof(strval));
- strval[0] = rparams->subtree;
- if ((st=krb5_add_str_mem_ldap_mod(&mods, "krbsubtree", LDAP_MOD_REPLACE,
- strval)) != 0)
- goto cleanup;
+ if ( rparams->subtree!=NULL) {
+ /*replace the subtrees with the present if the subtrees are present*/
+ for(k=0;k<rparams->subtreecount && rparams->subtree[k]!=NULL;k++) {
+ if (strlen(rparams->subtree[k]) != 0) {
+ st = checkattributevalue(ld, rparams->subtree[k], "Objectclass", subtreeclass,
+ &objectmask);
+ CHECK_CLASS_VALIDITY(st, objectmask, "subtree value: ");
+ }
+ }
+ strval = rparams->subtree;
+ if ((st=krb5_add_str_mem_ldap_mod(&mods, "krbsubtrees", LDAP_MOD_REPLACE,
+ strval)) != 0) {
+ goto cleanup;
+ }
+ }
+ }
+
+ /* CONTAINERREF ATTRIBUTE */
+ if (mask & LDAP_REALM_CONTREF) {
+ if (strlen(rparams->containerref) != 0 ) {
+ st = checkattributevalue(ld, rparams->containerref, "Objectclass", subtreeclass,
+ &objectmask);
+ CHECK_CLASS_VALIDITY(st, objectmask, "container reference value: ");
+ strvalprc[0] = rparams->containerref;
+ strvalprc[1] = NULL;
+ if ((st=krb5_add_str_mem_ldap_mod(&mods, "krbPrincContainerRef", LDAP_MOD_REPLACE,
+ strvalprc)) != 0)
+ goto cleanup;
+ }
}
/* SEARCHSCOPE ATTRIBUTE */
#endif
/* Realm modify opearation */
- if ((st=ldap_modify_ext_s(ld, rparams->realmdn, mods, NULL, NULL)) != LDAP_SUCCESS) {
- st = set_ldap_error (context, st, OP_MOD);
- goto cleanup;
+ if (mods != NULL) {
+ if ((st=ldap_modify_ext_s(ld, rparams->realmdn, mods, NULL, NULL)) != LDAP_SUCCESS) {
+ st = set_ldap_error (context, st, OP_MOD);
+ goto cleanup;
+ }
}
#ifdef HAVE_EDIRECTORY
if ((st=krb5_add_str_mem_ldap_mod(&mods, "cn", LDAP_MOD_ADD, strval)) != 0)
goto cleanup;
- /* check if the policy reference value exists and is of krbpolicyreference object class */
+ /* check if the policy reference value exists and is of krbticketpolicyreference object class */
if (krbcontparams && krbcontparams->policyreference) {
st = checkattributevalue(ld, krbcontparams->policyreference, "objectclass", policyclass,
&pmask);
strval[0] = krbcontparams->policyreference;
strval[1] = NULL;
- if ((st=krb5_add_str_mem_ldap_mod(&mods, "krbpolicyreference", LDAP_MOD_ADD,
+ if ((st=krb5_add_str_mem_ldap_mod(&mods, "krbticketpolicyreference", LDAP_MOD_ADD,
strval)) != 0)
goto cleanup;
}
krb5_error_code st=0;
char *dn=NULL;
char *strval[4]={NULL};
+ char *contref[2]={NULL};
LDAPMod **mods = NULL;
- int i=0, objectmask=0;
+ int i=0, objectmask=0, subtreecount=0,k=0, part_of_subtree=0;
kdb5_dal_handle *dal_handle=NULL;
krb5_ldap_context *ldap_context=NULL;
krb5_ldap_server_handle *ldap_server_handle=NULL;
rparams == NULL ||
rparams->realm_name == NULL ||
((mask & LDAP_REALM_SUBTREE) && rparams->subtree == NULL) ||
+ ((mask & LDAP_REALM_CONTREF) && rparams->containerref == NULL) ||
((mask & LDAP_REALM_POLICYREFERENCE) && rparams->policyreference == NULL) ||
((mask & LDAP_REALM_SUPPSALTTYPE) && rparams->suppsalttypes == NULL) ||
((mask & LDAP_REALM_SUPPENCTYPE) && rparams->suppenctypes == NULL) ||
strval[0] = "top";
strval[1] = "krbrealmcontainer";
- strval[2] = "krbpolicyaux";
+ strval[2] = "krbticketpolicyaux";
strval[3] = NULL;
if ((st=krb5_add_str_mem_ldap_mod(&mods, "objectclass", LDAP_MOD_ADD, strval)) != 0)
/* SUBTREE ATTRIBUTE */
if (mask & LDAP_REALM_SUBTREE) {
- if (strlen(rparams->subtree) != 0) {
- st = checkattributevalue(ld, rparams->subtree, "Objectclass", subtreeclass,
- &objectmask);
- CHECK_CLASS_VALIDITY(st, objectmask, "realm object value: ");
-
+ if ( rparams->subtree!=NULL) {
+ subtreecount = rparams->subtreecount;
+ for (i=0; rparams->subtree[i]!=NULL && i<subtreecount; i++) {
+ if (strlen(rparams->subtree[i]) != 0) {
+ st = checkattributevalue(ld, rparams->subtree[i], "Objectclass", subtreeclass,
+ &objectmask);
+ CHECK_CLASS_VALIDITY(st, objectmask, "realm object value: ");
+ }
+ }
+ if ((st=krb5_add_str_mem_ldap_mod(&mods, "krbsubtrees", LDAP_MOD_ADD,
+ rparams->subtree)) != 0) {
+ goto cleanup;
+ }
}
- strval[0] = rparams->subtree;
- strval[1] = NULL;
- if ((st=krb5_add_str_mem_ldap_mod(&mods, "krbsubtree", LDAP_MOD_ADD,
- strval)) != 0)
- goto cleanup;
+ }
+
+ /* CONTAINER REFERENCE ATTRIBUTE */
+ if (mask & LDAP_REALM_CONTREF) {
+ if (strlen(rparams->containerref) != 0 ) {
+ st = checkattributevalue(ld, rparams->containerref, "Objectclass", subtreeclass,
+ &objectmask);
+ CHECK_CLASS_VALIDITY(st, objectmask, "realm object value: ");
+ contref[0] = rparams->containerref;
+ contref[1] = NULL;
+ if ((st=krb5_add_str_mem_ldap_mod(&mods, "krbPrincContainerRef", LDAP_MOD_ADD,
+ contref)) != 0)
+ goto cleanup;
+ }
}
/* SEARCHSCOPE ATTRIBUTE */
}
- /* DEFAULTENCTYPE ATTRIBUTE */
- if (mask & LDAP_REALM_DEFENCTYPE) {
- /* check if the entered enctype is valid */
- if (krb5_c_valid_enctype(rparams->defenctype)) {
-
- /* check if the defenctype exists in the suppenctypes list */
- if (mask & LDAP_REALM_SUPPENCTYPE) {
- for (i=0; rparams->suppenctypes[i] != END_OF_LIST; ++i)
- if (rparams->defenctype == rparams->suppenctypes[i])
- break;
-
- if (rparams->suppenctypes[i] == END_OF_LIST) {
- st = EINVAL;
- krb5_set_error_message (context, st, "Default enctype not in the "
- "supported list");
- goto cleanup;
- }
- }
- if ((st=krb5_add_int_mem_ldap_mod(&mods, "krbdefaultenctype", LDAP_MOD_ADD,
- rparams->defenctype)) != 0)
- goto cleanup;
- } else {
- st = EINVAL;
- krb5_set_error_message (context, st, "Default enctype not valid");
- goto cleanup;
- }
- }
-
- /* DEFAULTSALTTYPE ATTRIBUTE */
- if (mask & LDAP_REALM_DEFSALTTYPE) {
- /* check if the entered salttype is valid */
- if (rparams->defsalttype >=0 && rparams->defsalttype<6) {
-
- /* check if the defsalttype exists in the suppsalttypes list */
- if (mask & LDAP_REALM_SUPPSALTTYPE) {
- for (i=0; rparams->suppsalttypes[i] != END_OF_LIST; ++i)
- if (rparams->defsalttype == rparams->suppsalttypes[i])
- break;
-
- if (rparams->suppsalttypes[i] == END_OF_LIST) {
- st = EINVAL;
- krb5_set_error_message (context, st,
- "Default salttype not in the supported list");
- goto cleanup;
- }
- }
-
- if ((st=krb5_add_int_mem_ldap_mod(&mods, "krbdefaultsalttype", LDAP_MOD_ADD,
- rparams->defsalttype)) != 0)
- goto cleanup;
- } else {
- st = EINVAL;
- krb5_set_error_message (context, st, "Default salttype not valid");
- goto cleanup;
- }
- }
-
- /* SUPPORTEDSALTTYPE ATTRIBUTE */
- if (mask & LDAP_REALM_SUPPSALTTYPE) {
- for (i=0; rparams->suppsalttypes[i] != END_OF_LIST; ++i) {
- /* check if the salttypes entered is valid */
- if (!(rparams->suppsalttypes[i]>=0 && rparams->suppsalttypes[i]<6)) {
- st = EINVAL;
- krb5_set_error_message (context, st, "Salttype %d not valid",
- rparams->suppsalttypes[i]);
- goto cleanup;
- }
- }
- ignore_duplicates(rparams->suppsalttypes);
-
- if ((st=krb5_add_int_arr_mem_ldap_mod(&mods, "krbsupportedsalttypes", LDAP_MOD_ADD,
- rparams->suppsalttypes)) != 0)
- goto cleanup;
- } else {
- /* set all the salt types as the suppsalttypes */
- if ((st=krb5_add_int_arr_mem_ldap_mod(&mods, "krbsupportedsalttypes", LDAP_MOD_ADD,
- supportedsalttypes)) != 0)
- goto cleanup;
- }
-
- /* SUPPORTEDENCTYPE ATTRIBUTE */
- if (mask & LDAP_REALM_SUPPENCTYPE) {
- for (i=0; rparams->suppenctypes[i] != -1; ++i) {
-
- /* check if the enctypes entered is valid */
- if (krb5_c_valid_enctype(rparams->suppenctypes[i]) == 0) {
- st = EINVAL;
- krb5_set_error_message (context, st, "Enctype %d not valid",
- rparams->suppenctypes[i]);
- goto cleanup;
- }
- }
- ignore_duplicates(rparams->suppenctypes);
-
- if ((st=krb5_add_int_arr_mem_ldap_mod(&mods, "krbsupportedenctypes", LDAP_MOD_ADD,
- rparams->suppenctypes)) != 0)
- goto cleanup;
- } else {
- /* set all the enc types as the suppenctypes */
- if ((st=krb5_add_int_arr_mem_ldap_mod(&mods, "krbsupportedenctypes", LDAP_MOD_ADD,
- supportedenctypes)) != 0)
- goto cleanup;
- }
-
#ifdef HAVE_EDIRECTORY
/* KDCSERVERS ATTRIBUTE */
kdb5_dal_handle *dal_handle=NULL;
krb5_ldap_context *ldap_context=NULL;
krb5_ldap_server_handle *ldap_server_handle=NULL;
+ int valcount=0, x=0;
SETUP_CONTEXT ();
LDAP_SEARCH(rlparams->realmdn, LDAP_SCOPE_BASE, "(objectclass=krbRealmContainer)", realm_attributes);
+ if ((st = ldap_count_entries(ld, result)) == 0)
+ {
+ /* This could happen when the DN used to bind and read the realm object
+ * does not have sufficient rights to read its attributes
+ */
+ st = KRB5_KDB_ACCESS_ERROR; /* return some other error ? */
+ goto cleanup;
+ }
+
ent = ldap_first_entry (ld, result);
if (ent == NULL) {
ldap_get_option (ld, LDAP_OPT_ERROR_NUMBER, (void *) &st);
/* Read the attributes */
{
-
- if ((values=ldap_get_values(ld, ent, "krbSubTree")) != NULL) {
- rlparams->subtree = strdup(values[0]);
- if (rlparams->subtree==NULL) {
+ if ((values=ldap_get_values(ld, ent, "krbSubTrees")) != NULL) {
+ rlparams->subtreecount = ldap_count_values(values);
+ rlparams->subtree = (char **) malloc(sizeof(char *) * (rlparams->subtreecount + 1));
+ if (rlparams->subtree == NULL) {
st = ENOMEM;
goto cleanup;
}
+ for (x=0; x<rlparams->subtreecount; x++) {
+ rlparams->subtree[x] = strdup(values[x]);
+ if (rlparams->subtree[x] == NULL) {
+ st = ENOMEM;
+ goto cleanup;
+ }
+ }
+ rlparams->subtree[rlparams->subtreecount] = NULL;
*mask |= LDAP_REALM_SUBTREE;
ldap_value_free(values);
}
+ if((values=ldap_get_values(ld, ent, "krbPrincContainerRef")) != NULL) {
+ rlparams->containerref = strdup(values[0]);
+ if(rlparams->containerref == NULL) {
+ st = ENOMEM;
+ goto cleanup;
+ }
+ *mask |= LDAP_REALM_CONTREF;
+ ldap_value_free(values);
+ }
+
if ((values=ldap_get_values(ld, ent, "krbSearchScope")) != NULL) {
rlparams->search_scope=atoi(values[0]);
/* searchscope can be ONE-LEVEL or SUBTREE, else default to SUBTREE */
if (rparams->realm_name)
krb5_xfree(rparams->realm_name);
- if (rparams->subtree)
+ if (rparams->subtree) {
+ for (i=0; i<rparams->subtreecount && rparams->subtree[i] ; i++)
+ krb5_xfree(rparams->subtree[i]);
krb5_xfree(rparams->subtree);
+ }
if (rparams->suppenctypes)
krb5_xfree(rparams->suppenctypes);
#define LDAP_REALM_MAXTICKETLIFE 0x1000
#define LDAP_REALM_MAXRENEWLIFE 0x2000
#define LDAP_REALM_KRBTICKETFLAGS 0x4000
+#define LDAP_REALM_CONTREF 0x8000
extern char *policy_attributes[];
typedef struct _krb5_ldap_realm_params {
char *realmdn;
char *realm_name;
- char *subtree;
+ char **subtree;
+ char *containerref;
char *policyreference;
int search_scope;
int upenabled;
+ int subtreecount;
krb5_int32 max_life;
krb5_int32 max_renewable_life;
krb5_int32 tktflags;
{"1#subtree#","#[Entry Rights]"},
{"2#subtree#","#CN"},
{"6#subtree#","#ObjectClass"},
- {"2#subtree#","#krbPolicyReference"},
+ {"2#subtree#","#krbTicketPolicyReference"},
{"2#subtree#","#krbUPEnabled"},
{"2#subtree#","#krbHostServer"},
{"2#subtree#","#krbServiceFlags"},
{"2#subtree#","#krbMaxTicketLife"},
{"2#subtree#","#krbMaxRenewableAge"},
{"2#subtree#","#krbPrincipalName"},
- {"6#subtree#","#krbSecretKey"},
+ {"6#subtree#","#krbPrincipalKey"},
{"2#subtree#","#krbPrincipalExpiration"},
{"2#subtree#","#krbPwdPolicyReference"},
{"2#subtree#","#krbMaxPwdLife"},
{"15#subtree#","#[Entry Rights]"},
{"6#subtree#","#CN"},
{"6#subtree#","#ObjectClass"},
- {"6#subtree#","#krbPolicyReference"},
+ {"6#subtree#","#krbTicketPolicyReference"},
{"6#subtree#","#krbUPEnabled"},
{"2#subtree#","#krbHostServer"},
{"2#subtree#","#krbServiceFlags"},
{"6#subtree#","#krbMaxTicketLife"},
{"6#subtree#","#krbMaxRenewableAge"},
{"6#subtree#","#krbPrincipalName"},
- {"6#subtree#","#krbSecretKey"},
+ {"6#subtree#","#krbPrincipalKey"},
{"6#subtree#","#krbPrincipalExpiration"},
{"6#subtree#","#ModifiersName"},
{"6#subtree#","#PasswordExpirationTime"},
{"6#subtree#","#krbMaxPwdLife"},
{"6#subtree#","#krbPwdMinDiffChars"},
{"6#subtree#","#krbPwdMinLength"},
- {"6#subtree#","#krbPwdPolicyRefCount"},
{"6#subtree#","#krbPwdPolicyReference"},
{ "","" }
};
{"1#subtree#","#[Entry Rights]"},
{"2#subtree#","#CN"},
{"2#subtree#","#ObjectClass"},
- {"2#subtree#","#krbPolicyReference"},
+ {"2#subtree#","#krbTicketPolicyReference"},
{"2#subtree#","#krbUPEnabled"},
{"2#subtree#","#krbHostServer"},
{"2#subtree#","#krbServiceFlags"},
{"2#subtree#","#krbMaxTicketLife"},
{"2#subtree#","#krbMaxRenewableAge"},
{"2#subtree#","#krbPrincipalName"},
- {"6#subtree#","#krbSecretKey"},
+ {"6#subtree#","#krbPrincipalKey"},
{"2#subtree#","#krbPrincipalExpiration"},
{"4#subtree#","#passwordManagement"},
{"6#subtree#","#ModifiersName"},
{"2#subtree#","#krbMaxPwdLife"},
{"2#subtree#","#krbPwdMinDiffChars"},
{"2#subtree#","#krbPwdMinLength"},
- {"2#subtree#","#krbPwdPolicyRefCount"},
{"2#subtree#","#krbPwdPolicyReference"},
{ "", "" }
};
{"1#subtree#","#[Entry Rights]"},
{"2#subtree#","#CN"},
{"6#subtree#","#ObjectClass"},
- {"2#subtree#","#krbPolicyReference"},
- {"2#subtree#","#krbMasterKey"},
+ {"2#subtree#","#krbTicketPolicyReference"},
+ {"2#subtree#","#krbMKey"},
{"2#subtree#","#krbUPEnabled"},
- {"2#subtree#","#krbSubTree"},
+ {"2#subtree#","#krbSubTrees"},
+ {"2#subtree#","#krbPrincContainerRef"},
{"2#subtree#","#krbSearchScope"},
{"2#subtree#","#krbLdapServers"},
{"2#subtree#","#krbSupportedEncTypes"},
{"2#subtree#","#krbMaxTicketLife"},
{"2#subtree#","#krbMaxRenewableAge"},
{"2#subtree#","#krbPrincipalName"},
- {"6#subtree#","#krbSecretKey"},
+ {"6#subtree#","#krbPrincipalKey"},
{"2#subtree#","#krbPrincipalExpiration"},
{"2#subtree#","#krbPwdPolicyReference"},
{"2#subtree#","#krbMaxPwdLife"},
{"15#subtree#","#[Entry Rights]"},
{"6#subtree#","#CN"},
{"6#subtree#","#ObjectClass"},
- {"6#subtree#","#krbPolicyReference"},
- {"2#subtree#","#krbMasterKey"},
+ {"6#subtree#","#krbTicketPolicyReference"},
+ {"2#subtree#","#krbMKey"},
{"6#subtree#","#krbUPEnabled"},
- {"2#subtree#","#krbSubTree"},
+ {"2#subtree#","#krbSubTrees"},
+ {"2#subtree#","#krbPrincContainerRef"},
{"2#subtree#","#krbSearchScope"},
{"2#subtree#","#krbLdapServers"},
{"2#subtree#","#krbSupportedEncTypes"},
{"6#subtree#","#krbMaxTicketLife"},
{"6#subtree#","#krbMaxRenewableAge"},
{"6#subtree#","#krbPrincipalName"},
- {"6#subtree#","#krbSecretKey"},
+ {"6#subtree#","#krbPrincipalKey"},
{"6#subtree#","#krbPrincipalExpiration"},
{"6#subtree#","#ModifiersName"},
{"6#subtree#","#PasswordExpirationTime"},
{"6#subtree#","#krbMaxPwdLife"},
{"6#subtree#","#krbPwdMinDiffChars"},
{"6#subtree#","#krbPwdMinLength"},
- {"6#subtree#","#krbPwdPolicyRefCount"},
{"6#subtree#","#krbPwdPolicyReference"},
{ "","" }
};
{"1#subtree#","#[Entry Rights]"},
{"2#subtree#","#CN"},
{"2#subtree#","#ObjectClass"},
- {"2#subtree#","#krbPolicyReference"},
- {"2#subtree#","#krbMasterKey"},
+ {"2#subtree#","#krbTicketPolicyReference"},
+ {"2#subtree#","#krbMKey"},
{"2#subtree#","#krbUPEnabled"},
- {"2#subtree#","#krbSubTree"},
+ {"2#subtree#","#krbSubTrees"},
+ {"2#subtree#","#krbPrincContainerRef"},
{"2#subtree#","#krbSearchScope"},
{"2#subtree#","#krbLdapServers"},
{"2#subtree#","#krbSupportedEncTypes"},
{"2#subtree#","#krbMaxTicketLife"},
{"2#subtree#","#krbMaxRenewableAge"},
{"2#subtree#","#krbPrincipalName"},
- {"6#subtree#","#krbSecretKey"},
+ {"6#subtree#","#krbPrincipalKey"},
{"2#subtree#","#krbPrincipalExpiration"},
{"6#subtree#","#ModifiersName"},
{"2#subtree#","#krbPwdHistoryLength"},
{"2#subtree#","#krbMaxPwdLife"},
{"2#subtree#","#krbPwdMinDiffChars"},
{"2#subtree#","#krbPwdMinLength"},
- {"2#subtree#","#krbPwdPolicyRefCount"},
{"2#subtree#","#krbPwdPolicyReference"},
{ "", "" }
};
static char *kerberos_container[][2] = {
{"1#subtree#","#[Entry Rights]"},
- {"2#subtree#","#krbPolicyReference"},
+ {"2#subtree#","#krbTicketPolicyReference"},
{ "", "" }
};
int servicetype;
char *serviceobjdn;
char *realmname;
- char *subtreeparam;
+ char **subtreeparam;
int mask;
{
LDAP *ld;
LDAPMod realmclass, subtreeclass, seccontclass, krbcontclass;
LDAPMod *realmarr[3]={NULL}, *subtreearr[3]={NULL}, *seccontarr[3]={NULL}, *krbcontarr[3]={NULL};
- char *realmdn=NULL, *subtree=NULL;
+ char *realmdn=NULL, **subtree=NULL;
kdb5_dal_handle *dal_handle=NULL;
krb5_ldap_context *ldap_context=NULL;
krb5_ldap_server_handle *ldap_server_handle=NULL;
+ int subtreecount=0;
SETUP_CONTEXT();
GET_HANDLE();
goto cleanup;
}
- /* If the subtree is null, set the value to root */
- if (subtreeparam== NULL)
- subtree=strdup("");
- else
- subtree=strdup(subtreeparam);
+ subtreecount=ldap_context->lrparams->subtreecount;
+ subtree = (char **) malloc(sizeof(char *) * (subtreecount + 1));
+ if(subtree == NULL) {
+ st = ENOMEM;
+ goto cleanup;
+ }
- if (subtree == NULL) {
- st = ENOMEM;
- goto cleanup;
+ /* If the subtree is null, set the value to root */
+ if(subtreeparam == NULL) {
+ subtree[0] = strdup("");
+ if(subtree[0] == NULL) {
+ st = ENOMEM;
+ goto cleanup;
+ }
+ }
+ else {
+ for (i=0; subtree[i] != NULL && i<subtreecount; i++) {
+ subtree[i] = strdup(subtreeparam[i]);
+ if(subtree[i] == NULL) {
+ st = ENOMEM;
+ goto cleanup;
+ }
+ }
}
/* Set the rights for the service object on the security container */
subtreearr[0] = &subtreeclass;
- st = ldap_modify_ext_s(ld,
- subtree,
- subtreearr,
- NULL,
- NULL);
- if (st != LDAP_SUCCESS && st != LDAP_TYPE_OR_VALUE_EXISTS && st != LDAP_OTHER) {
- free(subtreeacls[0]);
- st = set_ldap_error (context, st, OP_MOD);
- goto cleanup;
- }
+ /* set rights to a list of subtrees */
+ for(i=0; subtree[i]!=NULL && i<subtreecount;i++) {
+ st = ldap_modify_ext_s(ld,
+ subtree[i],
+ subtreearr,
+ NULL,
+ NULL);
+ if (st != LDAP_SUCCESS && st != LDAP_TYPE_OR_VALUE_EXISTS && st != LDAP_OTHER) {
+ free(subtreeacls[0]);
+ st = set_ldap_error (context, st, OP_MOD);
+ goto cleanup;
+ }
+ }
free(subtreeacls[0]);
}
} else if (servicetype == LDAP_ADMIN_SERVICE) {
subtreearr[0] = &subtreeclass;
- st = ldap_modify_ext_s(ld,
- subtree,
- subtreearr,
- NULL,
- NULL);
- if (st != LDAP_SUCCESS && st !=LDAP_TYPE_OR_VALUE_EXISTS && st != LDAP_OTHER) {
- free(subtreeacls[0]);
- st = set_ldap_error (context, st, OP_MOD);
- goto cleanup;
- }
+ /* set rights to a list of subtrees */
+ for(i=0; subtree[i]!=NULL && i<subtreecount;i++) {
+ st = ldap_modify_ext_s(ld,
+ subtree[i],
+ subtreearr,
+ NULL,
+ NULL);
+ if (st != LDAP_SUCCESS && st !=LDAP_TYPE_OR_VALUE_EXISTS && st != LDAP_OTHER) {
+ free(subtreeacls[0]);
+ st = set_ldap_error (context, st, OP_MOD);
+ goto cleanup;
+ }
+ }
free(subtreeacls[0]);
}
} else if (servicetype == LDAP_PASSWD_SERVICE) {
subtreearr[0] = &subtreeclass;
- st = ldap_modify_ext_s(ld,
- subtree,
- subtreearr,
- NULL,
- NULL);
- if (st != LDAP_SUCCESS && st != LDAP_TYPE_OR_VALUE_EXISTS && st != LDAP_OTHER) {
- free(subtreeacls[0]);
- st = set_ldap_error (context, st, OP_MOD);
- goto cleanup;
- }
+ /* set rights to a list of subtrees */
+ for(i=0; subtree[i]!=NULL && i<subtreecount;i++) {
+ st = ldap_modify_ext_s(ld,
+ subtree[i],
+ subtreearr,
+ NULL,
+ NULL);
+ if (st != LDAP_SUCCESS && st != LDAP_TYPE_OR_VALUE_EXISTS && st != LDAP_OTHER) {
+ free(subtreeacls[0]);
+ st = set_ldap_error (context, st, OP_MOD);
+ goto cleanup;
+ }
+ }
free(subtreeacls[0]);
}
}
int servicetype;
char *serviceobjdn;
char *realmname;
- char *subtreeparam;
+ char **subtreeparam;
int mask;
{
LDAPMod realmclass, subtreeclass;
LDAPMod *realmarr[3] = { NULL }, *subtreearr[3] = { NULL };
char *realmdn=NULL;
- char *subtree=NULL;
+ char **subtree=NULL;
kdb5_dal_handle *dal_handle=NULL;
- krb5_ldap_context *ldap_context=NULL;
+ krb5_ldap_context *ldap_context=NULL;
krb5_ldap_server_handle *ldap_server_handle=NULL;
+ int subtreecount = 0;
SETUP_CONTEXT();
GET_HANDLE();
if ((serviceobjdn == NULL) || (realmname == NULL) || (servicetype < 0) || (servicetype > 4)
|| (ldap_context->krbcontainer->DN == NULL)) {
- st=-1;
+ st = -1;
goto cleanup;
}
- /* If the subtree is null, set the value to root */
- if (subtreeparam== NULL)
- subtree=strdup("");
- else
- subtree=strdup(subtreeparam);
+ subtreecount = 1;
+ while(subtreeparam[subtreecount])
+ subtreecount++;
+ subtree = (char **) malloc(sizeof(char *) * subtreecount + 1);
+ if(subtree == NULL) {
+ st = ENOMEM;
+ goto cleanup;
+ }
- if (subtree == NULL) {
- st = ENOMEM;
- goto cleanup;
+ /* If the subtree is null, set the value to root */
+ if(subtreeparam == NULL) {
+ subtree[0] = strdup("");
+ if(subtree[0] == NULL) {
+ st = ENOMEM;
+ goto cleanup;
+ }
+ }
+ else {
+ for(i=0; subtreeparam[i]!=NULL && i<subtreecount; i++)
+ subtree[i] = strdup(subtreeparam[i]);
+ if(subtree[i] == NULL) {
+ st = ENOMEM;
+ goto cleanup;
+ }
}
subtreearr[0]=&subtreeclass;
- st = ldap_modify_ext_s(ld,
- subtree,
- subtreearr,
- NULL,
- NULL);
- if (st != LDAP_SUCCESS && st != LDAP_NO_SUCH_ATTRIBUTE) {
- free(subtreeacls[0]);
- st = set_ldap_error (context, st, OP_MOD);
- goto cleanup;
- }
+ for(i=0; subtree[i]!=NULL && i<subtreecount; i++) {
+ st = ldap_modify_ext_s(ld,
+ subtree[i],
+ subtreearr,
+ NULL,
+ NULL);
+ if (st != LDAP_SUCCESS && st != LDAP_NO_SUCH_ATTRIBUTE) {
+ free(subtreeacls[0]);
+ st = set_ldap_error (context, st, OP_MOD);
+ goto cleanup;
+ }
+ }
free(subtreeacls[0]);
}
} else if (servicetype == LDAP_ADMIN_SERVICE) {
subtreearr[0]=&subtreeclass;
- st = ldap_modify_ext_s(ld,
- subtree,
- subtreearr,
- NULL,
- NULL);
- if (st != LDAP_SUCCESS && st != LDAP_NO_SUCH_ATTRIBUTE) {
- free(subtreeacls[0]);
- st = set_ldap_error (context, st, OP_MOD);
- goto cleanup;
- }
+ for(i=0; subtree[i]!=NULL && i<subtreecount; i++) {
+ st = ldap_modify_ext_s(ld,
+ subtree[i],
+ subtreearr,
+ NULL,
+ NULL);
+ if (st != LDAP_SUCCESS && st != LDAP_NO_SUCH_ATTRIBUTE) {
+ free(subtreeacls[0]);
+ st = set_ldap_error (context, st, OP_MOD);
+ goto cleanup;
+ }
+ }
free(subtreeacls[0]);
}
} else if (servicetype == LDAP_PASSWD_SERVICE) {
subtreearr[0]=&subtreeclass;
- st = ldap_modify_ext_s(ld,
- subtree,
- subtreearr,
- NULL,
- NULL);
- if (st != LDAP_SUCCESS && st != LDAP_NO_SUCH_ATTRIBUTE) {
- free(subtreeacls[0]);
- st = set_ldap_error (context, st, OP_MOD);
- goto cleanup;
- }
+ for(i=0; subtree[i]!=NULL && i<subtreecount; i++) {
+ st = ldap_modify_ext_s(ld,
+ subtree[i],
+ subtreearr,
+ NULL,
+ NULL);
+ if (st != LDAP_SUCCESS && st != LDAP_NO_SUCH_ATTRIBUTE) {
+ free(subtreeacls[0]);
+ st = set_ldap_error (context, st, OP_MOD);
+ goto cleanup;
+ }
+ }
free(subtreeacls[0]);
}
}
krb5_ldap_set_service_passwd( krb5_context, char *, char *);
krb5_error_code
-krb5_ldap_add_service_rights( krb5_context, int, char *, char *, char *, int);
+krb5_ldap_add_service_rights( krb5_context, int, char *, char *, char **, int);
krb5_error_code
-krb5_ldap_delete_service_rights( krb5_context, int, char *, char *, char *, int);
+krb5_ldap_delete_service_rights( krb5_context, int, char *, char *, char **, int);
#endif
#endif
/* Ticket policy object management */
-/*
- * This function changes the value of policyreference count for a
- * particular ticket policy. If flag is 1 it will increment else it
- * will reduce by one.
- */
-
-krb5_error_code
-krb5_ldap_change_count(context ,policydn ,flag)
- krb5_context context;
- char *policydn;
- int flag;
-{
-
- krb5_error_code st=0;
- int objectmask=0;
- LDAP *ld=NULL;
- char *attrvalues[] = { "krbPolicy", NULL};
- kdb5_dal_handle *dal_handle=NULL;
- krb5_ldap_context *ldap_context=NULL;
- krb5_ldap_server_handle *ldap_server_handle=NULL;
- krb5_ldap_policy_params *policyparams=NULL;
- int mask = 0;
-
- /* validate the input parameters */
- if (policydn == NULL) {
- st = EINVAL;
- prepend_err_str(context,"Ticket Policy Object information missing",st,st);
- goto cleanup;
- }
-
- SETUP_CONTEXT();
- GET_HANDLE();
-
- /* the policydn object should be of the krbPolicy object class */
- st = checkattributevalue(ld, policydn, "objectClass", attrvalues, &objectmask);
- CHECK_CLASS_VALIDITY(st, objectmask, "ticket policy object: ");
-
- /* Initialize ticket policy structure */
-
- if ((st = krb5_ldap_read_policy(context, policydn, &policyparams, &mask)))
- goto cleanup;
- if (flag == 1) {
- /*Increment*/
- policyparams->polrefcount +=1;
- } else{
- /*Decrement*/
- if (policyparams->polrefcount >0) {
- policyparams->polrefcount-=1;
- }
- }
- mask |= LDAP_POLICY_COUNT;
-
- if ((st = krb5_ldap_modify_policy(context, policyparams, mask)))
- goto cleanup;
-
-cleanup:
- krb5_ldap_put_handle_to_pool(ldap_context, ldap_server_handle);
- return st;
-}
-
/*
* create the Ticket policy object in Directory.
*/
{
krb5_error_code st=0;
LDAP *ld=NULL;
- char **rdns=NULL, *strval[3]={NULL};
+ char *strval[3]={NULL}, *policy_dn = NULL;
LDAPMod **mods=NULL;
kdb5_dal_handle *dal_handle=NULL;
krb5_ldap_context *ldap_context=NULL;
krb5_ldap_server_handle *ldap_server_handle=NULL;
/* validate the input parameters */
- if (policy == NULL || policy->policydn==NULL) {
+ if (policy == NULL || policy->policy == NULL) {
st = EINVAL;
- krb5_set_error_message (context, st, "Ticket Policy Object DN missing");
+ krb5_set_error_message (context, st, "Ticket Policy Name missing");
goto cleanup;
}
SETUP_CONTEXT();
GET_HANDLE();
- rdns = ldap_explode_dn(policy->policydn, 1);
- if (rdns == NULL) {
- st = LDAP_INVALID_DN_SYNTAX;
+ if ((st = krb5_ldap_name_to_policydn (context, policy->policy, &policy_dn)) != 0)
goto cleanup;
- }
memset(strval, 0, sizeof(strval));
- strval[0] = rdns[0];
+ strval[0] = policy->policy;
if ((st=krb5_add_str_mem_ldap_mod(&mods, "cn", LDAP_MOD_ADD, strval)) != 0)
goto cleanup;
memset(strval, 0, sizeof(strval));
- strval[0] = "krbPolicy";
- strval[1] = "krbPolicyaux";
+ strval[0] = "krbTicketPolicy";
+ strval[1] = "krbTicketPolicyaux";
if ((st=krb5_add_str_mem_ldap_mod(&mods, "objectclass", LDAP_MOD_ADD, strval)) != 0)
goto cleanup;
policy->tktflags)) != 0)
goto cleanup;
}
- /*ticket policy reference count attribute added with value 0 */
-
- if ((st=krb5_add_int_mem_ldap_mod(&mods, "krbPolicyRefCount", LDAP_MOD_ADD,
- 0)) != 0)
- goto cleanup;
/* ldap add operation */
- if ((st=ldap_add_ext_s(ld, policy->policydn, mods, NULL, NULL)) != LDAP_SUCCESS) {
+ if ((st=ldap_add_ext_s(ld, policy_dn, mods, NULL, NULL)) != LDAP_SUCCESS) {
st = set_ldap_error (context, st, OP_ADD);
goto cleanup;
}
cleanup:
- if (rdns)
- ldap_value_free(rdns);
+ if (policy_dn != NULL)
+ free(policy_dn);
ldap_mods_free(mods, 1);
krb5_ldap_put_handle_to_pool(ldap_context, ldap_server_handle);
int objectmask=0;
krb5_error_code st=0;
LDAP *ld=NULL;
- char *attrvalues[]={"krbPolicy", "krbPolicyAux", NULL}, *strval[2]={NULL};
+ char *attrvalues[]={"krbTicketPolicy", "krbTicketPolicyAux", NULL}, *strval[2]={NULL};
+ char *policy_dn = NULL;
LDAPMod **mods=NULL;
kdb5_dal_handle *dal_handle=NULL;
krb5_ldap_context *ldap_context=NULL;
krb5_ldap_server_handle *ldap_server_handle=NULL;
/* validate the input parameters */
- if (policy == NULL || policy->policydn==NULL) {
+ if (policy == NULL || policy->policy==NULL) {
st = EINVAL;
- krb5_set_error_message (context, st, "Ticket Policy Object DN missing");
+ krb5_set_error_message (context, st, "Ticket Policy Name missing");
goto cleanup;
}
SETUP_CONTEXT();
GET_HANDLE();
- /* the policydn object should be of the krbPolicy object class */
- st = checkattributevalue(ld, policy->policydn, "objectClass", attrvalues, &objectmask);
+ if ((st = krb5_ldap_name_to_policydn (context, policy->policy, &policy_dn)) != 0)
+ goto cleanup;
+
+ /* the policydn object should be of the krbTicketPolicy object class */
+ st = checkattributevalue(ld, policy_dn, "objectClass", attrvalues, &objectmask);
CHECK_CLASS_VALIDITY(st, objectmask, "ticket policy object: ");
- if ((objectmask & 0x02) == 0) { /* add krbpolicyaux to the object class list */
+ if ((objectmask & 0x02) == 0) { /* add krbticketpolicyaux to the object class list */
memset(strval, 0, sizeof(strval));
- strval[0] = "krbPolicyAux";
+ strval[0] = "krbTicketPolicyAux";
if ((st=krb5_add_str_mem_ldap_mod(&mods, "objectclass", LDAP_MOD_ADD, strval)) != 0)
goto cleanup;
}
goto cleanup;
}
- if (mask & LDAP_POLICY_COUNT) {
- if ((st=krb5_add_int_mem_ldap_mod(&mods, "krbpolicyrefcount", LDAP_MOD_REPLACE,
- policy->polrefcount)) != 0)
- goto cleanup;
- }
- if ((st=ldap_modify_ext_s(ld, policy->policydn, mods, NULL, NULL)) != LDAP_SUCCESS) {
+ if ((st=ldap_modify_ext_s(ld, policy_dn, mods, NULL, NULL)) != LDAP_SUCCESS) {
st = set_ldap_error (context, st, OP_MOD);
goto cleanup;
}
cleanup:
+ if (policy_dn != NULL)
+ free(policy_dn);
+
ldap_mods_free(mods, 1);
krb5_ldap_put_handle_to_pool(ldap_context, ldap_server_handle);
return st;
*/
krb5_error_code
-krb5_ldap_read_policy(context, policydn, policy, omask)
+krb5_ldap_read_policy(context, policyname, policy, omask)
krb5_context context;
- char *policydn;
+ char *policyname;
krb5_ldap_policy_params **policy;
int *omask;
{
int objectmask=0;
LDAP *ld=NULL;
LDAPMessage *result=NULL,*ent=NULL;
- char *attributes[] = { "krbMaxTicketLife", "krbMaxRenewableAge", "krbTicketFlags", "krbPolicyRefCount", NULL};
- char *attrvalues[] = { "krbPolicy", NULL};
+ char *attributes[] = { "krbMaxTicketLife", "krbMaxRenewableAge", "krbTicketFlags", NULL};
+ char *attrvalues[] = { "krbTicketPolicy", NULL}, *policy_dn = NULL;
krb5_ldap_policy_params *lpolicy=NULL;
kdb5_dal_handle *dal_handle=NULL;
krb5_ldap_context *ldap_context=NULL;
krb5_ldap_server_handle *ldap_server_handle=NULL;
/* validate the input parameters */
- if (policydn == NULL || policy == NULL) {
+ if (policyname == NULL || policy == NULL) {
st = EINVAL;
krb5_set_error_message(context, st, "Ticket Policy Object information missing");
goto cleanup;
SETUP_CONTEXT();
GET_HANDLE();
- /* the policydn object should be of the krbPolicy object class */
- st = checkattributevalue(ld, policydn, "objectClass", attrvalues, &objectmask);
+ if ((st = krb5_ldap_name_to_policydn (context, policyname, &policy_dn)) != 0)
+ goto cleanup;
+
+ /* the policydn object should be of the krbTicketPolicy object class */
+ st = checkattributevalue(ld, policy_dn, "objectClass", attrvalues, &objectmask);
CHECK_CLASS_VALIDITY(st, objectmask, "ticket policy object: ");
/* Initialize ticket policy structure */
CHECK_NULL(lpolicy);
memset(lpolicy, 0, sizeof(krb5_ldap_policy_params));
+ if ((lpolicy->policy = strdup (policyname)) == NULL) {
+ st = ENOMEM;
+ goto cleanup;
+ }
+
lpolicy->tl_data = calloc (1, sizeof(*lpolicy->tl_data));
CHECK_NULL(lpolicy->tl_data);
lpolicy->tl_data->tl_data_type = KDB_TL_USER_INFO;
- LDAP_SEARCH(policydn, LDAP_SCOPE_BASE, "(objectclass=krbPolicy)", attributes);
+ LDAP_SEARCH(policy_dn, LDAP_SCOPE_BASE, "(objectclass=krbTicketPolicy)", attributes);
*omask = 0;
- lpolicy->policydn = strdup(policydn);
- CHECK_NULL(lpolicy->policydn);
ent=ldap_first_entry(ld, result);
if (ent != NULL) {
if (krb5_ldap_get_value(ld, ent, "krbticketflags", (int *) &(lpolicy->tktflags)) == 0)
*omask |= LDAP_POLICY_TKTFLAGS;
- if (krb5_ldap_get_value(ld, ent, "krbPolicyRefCount", (int *) &(lpolicy->polrefcount)) == 0)
- *omask |= LDAP_POLICY_COUNT;
-
}
ldap_msgfree(result);
*/
krb5_error_code
-krb5_ldap_delete_policy(context, policydn, policy, mask)
+krb5_ldap_delete_policy(context, policyname)
krb5_context context;
- char *policydn;
- krb5_ldap_policy_params *policy;
- int mask;
+ char *policyname;
{
+ int refcount = 0;
+ char *policy_dn = NULL;
krb5_error_code st = 0;
LDAP *ld = NULL;
kdb5_dal_handle *dal_handle=NULL;
krb5_ldap_context *ldap_context=NULL;
krb5_ldap_server_handle *ldap_server_handle=NULL;
- if (policy == NULL || policydn==NULL) {
+ if (policyname == NULL) {
st = EINVAL;
prepend_err_str (context,"Ticket Policy Object DN missing",st,st);
goto cleanup;
SETUP_CONTEXT();
GET_HANDLE();
+ if ((st = krb5_ldap_name_to_policydn (context, policyname, &policy_dn)) != 0)
+ goto cleanup;
/* Checking for policy count for 0 and will not permit delete if
* it is greater than 0. */
- if (policy->polrefcount == 0) {
+ if ((st = krb5_ldap_get_reference_count (context, policy_dn,
+ "krbTicketPolicyReference", &refcount, ld)) != 0)
+ goto cleanup;
- if ((st=ldap_delete_ext_s(ld, policydn, NULL, NULL)) != 0) {
+ if (refcount == 0) {
+ if ((st=ldap_delete_ext_s(ld, policy_dn, NULL, NULL)) != 0) {
prepend_err_str (context,ldap_err2string(st),st,st);
goto cleanup;
}
cleanup:
+ if (policy_dn != NULL)
+ free (policy_dn);
krb5_ldap_put_handle_to_pool(ldap_context, ldap_server_handle);
return st;
}
char *containerdn;
char ***policy;
{
+ int i, j, count;
+ char **list = NULL;
+ char *policycontainerdn = containerdn;
+ kdb5_dal_handle *dal_handle=NULL;
+ krb5_ldap_context *ldap_context=NULL;
krb5_error_code st=0;
- st = krb5_ldap_list(context, policy, "krbPolicy", containerdn);
+ SETUP_CONTEXT();
+ if (policycontainerdn == NULL) {
+ policycontainerdn = ldap_context->lrparams->realmdn;
+ }
+
+ if ((st = krb5_ldap_list(context, &list, "krbTicketPolicy", policycontainerdn)) != 0)
+ goto cleanup;
+
+ for (i = 0; list[i] != NULL; i++);
+ count = i;
+
+ *policy = (char **) calloc ((unsigned) count + 1, sizeof(char *));
+ if (*policy == NULL) {
+ st = ENOMEM;
+ goto cleanup;
+ }
+
+ for (i = 0, j = 0; list[i] != NULL; i++, j++) {
+ int ret;
+ ret = krb5_ldap_policydn_to_name (context, list[i], &(*policy)[i]);
+ if (ret != 0)
+ j--;
+ }
+
+cleanup:
return st;
}
if (policy == NULL)
return st;
- if (policy->policydn)
- free (policy->policydn);
+ if (policy->policy)
+ free (policy->policy);
if (policy->tl_data) {
if (policy->tl_data->tl_data_contents)
/* policy object structure */
typedef struct _krb5_ldap_policy_params {
- char *policydn;
+ char *policy;
long mask;
long maxtktlife;
long maxrenewlife;
long tktflags;
- long polrefcount;
krb5_tl_data *tl_data;
}krb5_ldap_policy_params;
krb5_ldap_read_policy(krb5_context, char *, krb5_ldap_policy_params **, int *);
krb5_error_code
-krb5_ldap_delete_policy(krb5_context, char *, krb5_ldap_policy_params *, int);
+krb5_ldap_delete_policy(krb5_context, char *);
krb5_error_code
krb5_ldap_clear_policy(krb5_context, char *);