10/3 patch from Savitha R, part 1, patch-ldap-schema.diff
authorKen Raeburn <raeburn@mit.edu>
Fri, 6 Oct 2006 23:53:38 +0000 (23:53 +0000)
committerKen Raeburn <raeburn@mit.edu>
Fri, 6 Oct 2006 23:53:38 +0000 (23:53 +0000)
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@18657 dc483132-0cff-0310-8789-dd5450dbe970

17 files changed:
src/plugins/kdb/ldap/ldap_util/kdb5_ldap_policy.c
src/plugins/kdb/ldap/ldap_util/kdb5_ldap_realm.c
src/plugins/kdb/ldap/ldap_util/kdb5_ldap_util.c
src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.h
src/plugins/kdb/ldap/libkdb_ldap/ldap_krbcontainer.c
src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c
src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.h
src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c
src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.h
src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c
src/plugins/kdb/ldap/libkdb_ldap/ldap_pwd_policy.c
src/plugins/kdb/ldap/libkdb_ldap/ldap_realm.c
src/plugins/kdb/ldap/libkdb_ldap/ldap_realm.h
src/plugins/kdb/ldap/libkdb_ldap/ldap_service_rights.c
src/plugins/kdb/ldap/libkdb_ldap/ldap_services.h
src/plugins/kdb/ldap/libkdb_ldap/ldap_tkt_policy.c
src/plugins/kdb/ldap/libkdb_ldap/ldap_tkt_policy.h

index 8b9227888a35cc1bd3cea18e9bfc03f4421ad759..60963d2d9a1ea110e254e0f4b9e7b8dbd881ca92 100644 (file)
@@ -36,6 +36,7 @@
 #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"
@@ -45,6 +46,45 @@ static void print_policy_params(krb5_ldap_policy_params *policyparams, int mask)
 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
@@ -221,12 +261,12 @@ kdb5_ldap_create_policy(argc, argv)
        } 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;
@@ -235,9 +275,14 @@ kdb5_ldap_create_policy(argc, argv)
     }
 
     /* 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;
@@ -282,7 +327,7 @@ kdb5_ldap_destroy_policy(argc, argv)
     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};
@@ -298,12 +343,12 @@ kdb5_ldap_destroy_policy(argc, argv)
        } 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;
@@ -311,11 +356,11 @@ kdb5_ldap_destroy_policy(argc, argv)
        }
     }
 
-    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) {
@@ -329,14 +374,17 @@ kdb5_ldap_destroy_policy(argc, argv)
        }
     }
 
-    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;
 
 
@@ -350,8 +398,8 @@ cleanup:
     /* Clean-up structure */
     krb5_ldap_free_policy (util_context, policyparams);
 
-    if (policydn) {
-       free (policydn);
+    if (policy) {
+       free (policy);
     }
 
     if (print_usage) {
@@ -383,7 +431,7 @@ kdb5_ldap_modify_policy(argc, argv)
     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;
@@ -421,12 +469,12 @@ kdb5_ldap_modify_policy(argc, argv)
        } 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;
@@ -434,12 +482,15 @@ kdb5_ldap_modify_policy(argc, argv)
        }
     }
 
-    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;
     }
 
@@ -606,8 +657,8 @@ cleanup:
     /* 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);
@@ -636,22 +687,25 @@ kdb5_ldap_view_policy(argc, argv)
     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;
     }
@@ -666,8 +720,8 @@ err_usage:
 cleanup:
     krb5_ldap_free_policy (util_context, policyparams);
 
-    if (policydn)
-       free (policydn);
+    if (policy)
+       free (policy);
 
     if (print_usage) {
        db_usage(VIEW_POLICY);
@@ -687,7 +741,7 @@ print_policy_params(policyparams, mask)
     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)
@@ -774,6 +828,9 @@ void kdb5_ldap_list_policies(argc, argv)
        }
     }
 
+    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;
index 1f658b423b1dd4869564ad7eec3952b9add8a067..870f2bd7422c97de83469d340fb5ffd5c2962ea4 100644 (file)
@@ -81,6 +81,9 @@
  * 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>
@@ -130,7 +133,8 @@ static int kdb_ldap_create_principal (krb5_context context, krb5_principal
 
 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;
@@ -312,11 +316,12 @@ void kdb5_ldap_create(argc, argv)
     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
@@ -333,16 +338,50 @@ void kdb5_ldap_create(argc, argv)
 
     /* 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
@@ -634,12 +673,11 @@ void kdb5_ldap_create(argc, argv)
        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' ... */
@@ -728,10 +766,10 @@ void kdb5_ldap_create(argc, argv)
        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
@@ -826,9 +864,6 @@ cleanup:
 
     memset (pw_str, 0, sizeof (pw_str));
 
-    if (oldsubtree)
-       ldap_context->lrparams->subtree = oldsubtree;
-
     if (print_usage)
        db_usage(CREATE_REALM);
 
@@ -851,17 +886,19 @@ void kdb5_ldap_modify(argc, argv)
     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;
@@ -869,9 +906,10 @@ void kdb5_ldap_modify(argc, argv)
     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
@@ -893,32 +931,75 @@ void kdb5_ldap_modify(argc, argv)
                                         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
@@ -1337,20 +1418,50 @@ void kdb5_ldap_modify(argc, argv)
 
        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)) {
@@ -1374,7 +1485,7 @@ void kdb5_ldap_modify(argc, argv)
 
            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*));
@@ -1399,12 +1510,12 @@ void kdb5_ldap_modify(argc, argv)
            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);
@@ -1452,7 +1563,7 @@ void kdb5_ldap_modify(argc, argv)
 
            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*));
@@ -1477,13 +1588,13 @@ void kdb5_ldap_modify(argc, argv)
            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);
@@ -1533,7 +1644,7 @@ void kdb5_ldap_modify(argc, argv)
 
            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*));
@@ -1558,12 +1669,12 @@ void kdb5_ldap_modify(argc, argv)
            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);
@@ -1605,6 +1716,7 @@ err_nomsg:
 cleanup:
     krb5_ldap_free_realm_params(rparams);
 
+
 #ifdef HAVE_EDIRECTORY
     if (oldkdcdns) {
        for (i=0; oldkdcdns[i] != NULL; i++)
@@ -1636,8 +1748,16 @@ cleanup:
            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);
@@ -1729,12 +1849,16 @@ static char *strdur(duration)
 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)) {
@@ -1904,6 +2028,123 @@ void kdb5_ldap_list(argc, argv)
     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
@@ -1971,6 +2212,15 @@ kdb_ldap_create_principal (context, princ, op, pblock)
 
     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;
index d5e7134e4f6bdefa24919dc5ac71d70415b040e2..3cc0f0f912db6412172388b6b57f5102ccbe44f6 100644 (file)
@@ -111,7 +111,7 @@ void usage()
 "\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"
@@ -121,7 +121,7 @@ void usage()
 "\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"
@@ -173,21 +173,21 @@ void usage()
 #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"
 
        );
 }
@@ -300,7 +300,7 @@ int main(argc, argv)
     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);
@@ -417,12 +417,9 @@ int main(argc, argv)
     /* 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) {
index f9f965c46b1ba687eac1e7af3400afdff18abaa6..a8ec7aa6ddeeac151c5e2fb4f39dada2dcfd715a 100644 (file)
@@ -151,7 +151,7 @@ extern void prepend_err_str (krb5_context ctx, const char *s, krb5_error_code er
 #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 \
@@ -280,9 +280,6 @@ krb5_ldap_read_startup_information(krb5_context );
 int
 has_sasl_external_mech(krb5_context, char *);
 
-krb5_error_code
-krb5_get_policydn(krb5_context, krb5_db_entry *, char **);
-
 /* DAL functions */
 
 
index d784e0ff570dd3a3511e3b128fdaf9635c28f6ea..6a9c6b6e2c8ddda3e719f361fa7f818d66af53d4 100644 (file)
@@ -32,7 +32,7 @@
 #include "kdb_ldap.h"
 #include "ldap_err.h"
 
-char    *policyrefattribute[] = {"krbPolicyReference",NULL};
+char    *policyrefattribute[] = {"krbTicketPolicyReference",NULL};
 char    *krbcontainerrefattr[] = {"krbContainerReference", NULL};
 
 /*
@@ -169,7 +169,7 @@ krb5_ldap_read_krbcontainer_params(krb5_context     context,
 #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;
     }
index f0001623975a2af52fb761049372013af2ded38d..e37295b848430f0de6d95b38da99cbf9d7be8e9f 100644 (file)
@@ -421,9 +421,9 @@ is_principal_in_realm(ldap_context, searchfor)
 
 /*
  * 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
@@ -432,7 +432,7 @@ is_principal_in_realm(ldap_context, searchfor)
  *    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
@@ -442,70 +442,79 @@ is_principal_in_realm(ldap_context, searchfor)
 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;
 }
 
 /*
@@ -561,7 +570,7 @@ store_tl_data(tl_data, tl_type, value)
     }
 
     case KDB_TL_USERDN:
-    case KDB_TL_TKTPOLICYDN:
+    case KDB_TL_LINKDN:
     {
        char *cptr = (char *)value;
 
@@ -591,36 +600,6 @@ store_tl_data(tl_data, tl_type, 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;
 
@@ -649,9 +628,10 @@ decode_tl_data(tl_data, tl_type, data)
     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;
 
@@ -691,12 +671,12 @@ decode_tl_data(tl_data, tl_type, data)
                    *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 */
@@ -708,49 +688,36 @@ decode_tl_data(tl_data, tl_type, data)
                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 {
@@ -759,13 +726,7 @@ decode_tl_data(tl_data, tl_type, data)
            curr += 2 + sublen;
        }
     }
-    if (tl_type == KDB_TL_KEYINFO) {
-       if (keyfound)
-           return 0;
-       else
-           return EINVAL;
-    }
-    return EINVAL;
+    return st;
 }
 
 /*
@@ -829,24 +790,25 @@ krb5_get_princ_count(context, entries, pcount)
 }
 
 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;
 }
 
@@ -861,7 +823,7 @@ krb5_get_str_from_tl_data(context, entries, type, strval)
     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;
     }
@@ -898,15 +860,6 @@ krb5_get_containerdn(context, entries, containerdn)
     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
@@ -1301,6 +1254,59 @@ krb5_ldap_get_string(ld, ent, attribute, retstr, attr_present)
     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;
@@ -1375,6 +1381,8 @@ krb5_add_str_mem_ldap_mod(mods, attribute, op, values)
        return ENOMEM;
     (*mods)[i]->mod_op = op;
 
+    (*mods)[i]->mod_values = NULL;
+
     if (values != NULL) {
        for (j=0; values[j] != NULL; ++j)
            ;
@@ -1550,3 +1558,274 @@ krb5_ldap_release_errcode_string(krb5_context kcontext, const char *msg)
 {
     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;
+}
index 954e71ccccdd5a29245e56ffe9f983ea67f0f835..ce9250d5c44b173de580a41ab9c456f3b09080dd 100644 (file)
@@ -63,7 +63,7 @@ krb5_error_code
 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 **);
@@ -81,7 +81,7 @@ krb5_error_code
 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);
@@ -101,6 +101,9 @@ krb5_ldap_get_value(LDAP *, LDAPMessage *, 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 *);
 
@@ -122,6 +125,15 @@ krb5_add_int_mem_ldap_mod(LDAPMod  ***, char *, int , int);
 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 **);
 
index b0488eb52f775926efde96a02a5ef9dfa3f533a6..ad4fef975787e86c94574c954efb6b57ca1dd881 100644 (file)
 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
@@ -131,7 +140,7 @@ krb5_ldap_iterate(context, match_expr, func, func_arg)
 {
     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;
@@ -163,7 +172,7 @@ krb5_ldap_iterate(context, match_expr, func, func_arg)
     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();
@@ -217,7 +226,7 @@ krb5_ldap_delete_principal(context, searchfor, nentries)
     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;
@@ -226,7 +235,6 @@ krb5_ldap_delete_principal(context, searchfor, nentries)
     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);
@@ -239,9 +247,7 @@ krb5_ldap_delete_principal(context, searchfor, nentries)
     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) {
@@ -252,8 +258,13 @@ krb5_ldap_delete_principal(context, searchfor, nentries)
 
     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;
@@ -267,7 +278,7 @@ krb5_ldap_delete_principal(context, searchfor, nentries)
        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;
            }
@@ -290,15 +301,11 @@ krb5_ldap_delete_principal(context, searchfor, nentries)
                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)
@@ -320,12 +327,6 @@ krb5_ldap_delete_principal(context, searchfor, nentries)
            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:
index 65224c8d3f5fd452a64db1d2726bc8e588562720..c4f5e93b76dc0ea94d34637740c3052925c521d3 100644 (file)
 
 #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
@@ -94,6 +98,8 @@
 #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[];
 
index 5f0c30fba173ba2933d5ea16ccd281e8f1f9696a..cc59c1fbeb2784b6e5017993e2b5bb2c76317b97 100644 (file)
@@ -48,11 +48,30 @@ static krb5_error_code
 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.
  */
@@ -65,12 +84,13 @@ krb5_ldap_get_principal(context, searchfor, entries, nentries, more)
     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;
@@ -115,7 +135,7 @@ krb5_ldap_get_principal(context, searchfor, entries, nentries, more)
     }
     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();
@@ -126,7 +146,7 @@ krb5_ldap_get_principal(context, searchfor, entries, nentries, more)
 
            /* 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.
@@ -153,7 +173,9 @@ krb5_ldap_get_principal(context, searchfor, entries, nentries, more)
                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);
@@ -161,8 +183,7 @@ krb5_ldap_get_principal(context, searchfor, entries, nentries, more)
 
                /* 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;
            }
 
@@ -172,6 +193,24 @@ krb5_ldap_get_principal(context, searchfor, entries, nentries, more)
 
            /* 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;
@@ -200,13 +239,13 @@ krb5_ldap_get_principal(context, searchfor, entries, nentries, more)
 
            /* 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 */
@@ -216,32 +255,69 @@ krb5_ldap_get_principal(context, searchfor, entries, nentries, more)
                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 */
@@ -292,10 +368,11 @@ krb5_ldap_get_principal(context, searchfor, entries, nentries, more)
     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;
@@ -303,7 +380,7 @@ krb5_ldap_get_principal(context, searchfor, entries, nentries, more)
 
        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);
@@ -332,9 +409,12 @@ cleanup:
     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);
@@ -345,24 +425,35 @@ cleanup:
     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;
@@ -374,6 +465,8 @@ free_xargs(xargs)
 {
     if (xargs.dn)
        free (xargs.dn);
+    if (xargs.linkdn)
+       free(xargs.linkdn);
     if (xargs.containerdn)
        free (xargs.containerdn);
     if (xargs.tktpolicydn)
@@ -381,102 +474,87 @@ free_xargs(xargs)
 }
 
 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;
 }
@@ -520,6 +598,24 @@ krb5_encode_krbsecretkey(krb5_key_data *key_data, int n_key_data) {
     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;
@@ -527,15 +623,18 @@ krb5_ldap_put_principal(context, entries, nentries, db_args)
     register int               *nentries;         /* number of entry structs to update */
     char                       **db_args;
 {
-    int                        i=0, l=0, plen=0;
+    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;
@@ -543,7 +642,8 @@ krb5_ldap_put_principal(context, entries, nentries, db_args)
     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);
@@ -569,21 +669,29 @@ krb5_ldap_put_principal(context, entries, nentries, db_args)
                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) {
@@ -600,28 +708,58 @@ krb5_ldap_put_principal(context, entries, nentries, db_args)
                    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) {
@@ -629,9 +767,9 @@ krb5_ldap_put_principal(context, entries, nentries, db_args)
                    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;
                    }
@@ -647,87 +785,113 @@ krb5_ldap_put_principal(context, entries, nentries, db_args)
                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;
@@ -789,7 +953,9 @@ krb5_ldap_put_principal(context, entries, nentries, db_args)
 
            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 {
@@ -800,8 +966,7 @@ krb5_ldap_put_principal(context, entries, nentries, db_args)
        }
 
        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;
        }
 
@@ -812,7 +977,7 @@ krb5_ldap_put_principal(context, entries, nentries, db_args)
            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;
 
@@ -828,91 +993,169 @@ krb5_ldap_put_principal(context, entries, nentries, db_args)
                }
                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;
            }
@@ -926,6 +1169,15 @@ 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);
 
@@ -948,11 +1200,11 @@ cleanup:
 }
 
 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;
@@ -962,49 +1214,44 @@ krb5_read_tkt_policyreference(context, ldap_context, entries, policydn)
     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;
@@ -1017,12 +1264,10 @@ krb5_decode_krbsecretkey(context, entries, bvalues, userinfo_tl_data)
     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;
index 7aa78010ee710ee768759c8b02945a4c966f822f..87c576efc9f212c47ae71cff51b96afe7c938590 100644 (file)
@@ -33,9 +33,9 @@
 #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.
@@ -52,7 +52,7 @@ krb5_ldap_create_password_policy (context, policy)
     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);
@@ -64,8 +64,12 @@ krb5_ldap_create_password_policy (context, policy)
     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");
@@ -89,13 +93,11 @@ krb5_ldap_create_password_policy (context, policy)
        || ((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;
     }
@@ -104,6 +106,8 @@ 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);
@@ -118,6 +122,7 @@ krb5_ldap_put_password_policy (context, policy)
     krb5_context                context;
     osa_policy_ent_t            policy;
 {
+    char                        *policy_dn;
     krb5_error_code            st=0;
     LDAP                       *ld=NULL;
     LDAPMod                    **mods=NULL;
@@ -135,6 +140,10 @@ krb5_ldap_put_password_policy (context, policy)
     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,
@@ -144,25 +153,30 @@ krb5_ldap_put_password_policy (context, policy)
        || ((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;
@@ -205,7 +219,13 @@ krb5_ldap_get_password_policy (context, name, policy, cnt)
        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:
@@ -216,15 +236,53 @@ 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;
@@ -241,13 +299,20 @@ krb5_ldap_delete_password_policy (context, policy)
     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;
 }
 
@@ -259,14 +324,13 @@ krb5_ldap_iterate_password_policy(context, match_expr, func, func_arg)
     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);
@@ -278,13 +342,23 @@ krb5_ldap_iterate_password_policy(context, match_expr, func, func_arg)
     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);
 
index 221b38c65ec13cb8add665d4ace48f00852f4918..eac20a4c90e704c88c5bf4a208d16b9450166e52 100644 (file)
 #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};
@@ -51,12 +51,12 @@ char  *policy_attributes[] = { "krbMaxTicketLife",
 
 
 
-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,
@@ -99,8 +99,7 @@ ignore_duplicates(int_list)
  * 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;
@@ -263,7 +262,6 @@ cleanup:
     return st;
 }
 
-
 /*
  * Delete the realm along with the principals belonging to the realm in the Directory.
  */
@@ -275,8 +273,8 @@ krb5_ldap_delete_realm (context, lrealm)
 {
     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;
@@ -313,9 +311,15 @@ krb5_ldap_delete_realm (context, lrealm)
        /* 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;
@@ -348,6 +352,28 @@ krb5_ldap_delete_realm (context, lrealm)
        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;
@@ -357,10 +383,20 @@ krb5_ldap_delete_realm (context, lrealm)
     }
 
 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;
@@ -388,8 +424,8 @@ krb5_ldap_modify_realm(context, rparams, mask)
     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;
@@ -398,7 +434,7 @@ krb5_ldap_modify_realm(context, rparams, mask)
     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;
@@ -418,6 +454,7 @@ krb5_ldap_modify_realm(context, rparams, mask)
        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) ||
@@ -467,16 +504,35 @@ krb5_ldap_modify_realm(context, rparams, mask)
 
     /* 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 */
@@ -728,9 +784,11 @@ krb5_ldap_modify_realm(context, rparams, mask)
 #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
@@ -932,7 +990,7 @@ krb5_ldap_create_krbcontainer(context, krbcontparams)
     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);
@@ -940,7 +998,7 @@ krb5_ldap_create_krbcontainer(context, krbcontparams)
 
        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;
     }
@@ -1016,8 +1074,9 @@ krb5_ldap_create_realm(context, rparams, mask)
     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;
@@ -1034,6 +1093,7 @@ krb5_ldap_create_realm(context, rparams, mask)
        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) ||
@@ -1069,7 +1129,7 @@ krb5_ldap_create_realm(context, rparams, mask)
 
     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)
@@ -1077,17 +1137,34 @@ krb5_ldap_create_realm(context, rparams, mask)
 
     /* 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 */
@@ -1124,110 +1201,6 @@ krb5_ldap_create_realm(context, rparams, mask)
     }
 
 
-    /* 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 */
@@ -1347,6 +1320,7 @@ krb5_ldap_read_realm_params(context, lrealm, rlparamp, mask)
     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 ();
 
@@ -1402,6 +1376,15 @@ krb5_ldap_read_realm_params(context, lrealm, rlparamp, mask)
 
     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);
@@ -1413,17 +1396,35 @@ krb5_ldap_read_realm_params(context, lrealm, rlparamp, mask)
 
     /* 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 */
@@ -1600,8 +1601,11 @@ krb5_ldap_free_realm_params(rparams)
        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);
index 9ffd3e86ec79f79f300e75cfaaaf0e1fa5327a05..3879bf437385fe084b8b3a4f85799731f1b75d60 100644 (file)
@@ -47,6 +47,7 @@
 #define LDAP_REALM_MAXTICKETLIFE      0x1000
 #define LDAP_REALM_MAXRENEWLIFE       0x2000
 #define LDAP_REALM_KRBTICKETFLAGS     0x4000
+#define LDAP_REALM_CONTREF           0x8000 
 
 extern char *policy_attributes[];
 
@@ -57,10 +58,12 @@ extern char *realm_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;
index 01045ce32a6167f1a6c95054b0a0aec2f9d06542..e4a28a5ac3baa7220d5708b9e768234a6440ffb9 100644 (file)
@@ -40,7 +40,7 @@ static char *kdcrights_subtree[][2] = {
     {"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"},
@@ -49,7 +49,7 @@ static char *kdcrights_subtree[][2] = {
     {"2#subtree#","#krbMaxTicketLife"},
     {"2#subtree#","#krbMaxRenewableAge"},
     {"2#subtree#","#krbPrincipalName"},
-    {"6#subtree#","#krbSecretKey"},
+    {"6#subtree#","#krbPrincipalKey"},
     {"2#subtree#","#krbPrincipalExpiration"},
     {"2#subtree#","#krbPwdPolicyReference"},
     {"2#subtree#","#krbMaxPwdLife"},
@@ -76,7 +76,7 @@ static char *adminrights_subtree[][2]={
     {"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"},
@@ -85,7 +85,7 @@ static char *adminrights_subtree[][2]={
     {"6#subtree#","#krbMaxTicketLife"},
     {"6#subtree#","#krbMaxRenewableAge"},
     {"6#subtree#","#krbPrincipalName"},
-    {"6#subtree#","#krbSecretKey"},
+    {"6#subtree#","#krbPrincipalKey"},
     {"6#subtree#","#krbPrincipalExpiration"},
     {"6#subtree#","#ModifiersName"},
     {"6#subtree#","#PasswordExpirationTime"},
@@ -110,7 +110,6 @@ static char *adminrights_subtree[][2]={
     {"6#subtree#","#krbMaxPwdLife"},
     {"6#subtree#","#krbPwdMinDiffChars"},
     {"6#subtree#","#krbPwdMinLength"},
-    {"6#subtree#","#krbPwdPolicyRefCount"},
     {"6#subtree#","#krbPwdPolicyReference"},
     { "","" }
 };
@@ -119,7 +118,7 @@ static char *pwdrights_subtree[][2] = {
     {"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"},
@@ -128,7 +127,7 @@ static char *pwdrights_subtree[][2] = {
     {"2#subtree#","#krbMaxTicketLife"},
     {"2#subtree#","#krbMaxRenewableAge"},
     {"2#subtree#","#krbPrincipalName"},
-    {"6#subtree#","#krbSecretKey"},
+    {"6#subtree#","#krbPrincipalKey"},
     {"2#subtree#","#krbPrincipalExpiration"},
     {"4#subtree#","#passwordManagement"},
     {"6#subtree#","#ModifiersName"},
@@ -137,7 +136,6 @@ static char *pwdrights_subtree[][2] = {
     {"2#subtree#","#krbMaxPwdLife"},
     {"2#subtree#","#krbPwdMinDiffChars"},
     {"2#subtree#","#krbPwdMinLength"},
-    {"2#subtree#","#krbPwdPolicyRefCount"},
     {"2#subtree#","#krbPwdPolicyReference"},
     { "", "" }
 };
@@ -146,10 +144,11 @@ static char *kdcrights_realmcontainer[][2]={
     {"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"},
@@ -162,7 +161,7 @@ static char *kdcrights_realmcontainer[][2]={
     {"2#subtree#","#krbMaxTicketLife"},
     {"2#subtree#","#krbMaxRenewableAge"},
     {"2#subtree#","#krbPrincipalName"},
-    {"6#subtree#","#krbSecretKey"},
+    {"6#subtree#","#krbPrincipalKey"},
     {"2#subtree#","#krbPrincipalExpiration"},
     {"2#subtree#","#krbPwdPolicyReference"},
     {"2#subtree#","#krbMaxPwdLife"},
@@ -189,10 +188,11 @@ static char *adminrights_realmcontainer[][2]={
     {"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"},
@@ -205,7 +205,7 @@ static char *adminrights_realmcontainer[][2]={
     {"6#subtree#","#krbMaxTicketLife"},
     {"6#subtree#","#krbMaxRenewableAge"},
     {"6#subtree#","#krbPrincipalName"},
-    {"6#subtree#","#krbSecretKey"},
+    {"6#subtree#","#krbPrincipalKey"},
     {"6#subtree#","#krbPrincipalExpiration"},
     {"6#subtree#","#ModifiersName"},
     {"6#subtree#","#PasswordExpirationTime"},
@@ -228,7 +228,6 @@ static char *adminrights_realmcontainer[][2]={
     {"6#subtree#","#krbMaxPwdLife"},
     {"6#subtree#","#krbPwdMinDiffChars"},
     {"6#subtree#","#krbPwdMinLength"},
-    {"6#subtree#","#krbPwdPolicyRefCount"},
     {"6#subtree#","#krbPwdPolicyReference"},
     { "","" }
 };
@@ -238,10 +237,11 @@ static char *pwdrights_realmcontainer[][2]={
     {"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"},
@@ -254,7 +254,7 @@ static char *pwdrights_realmcontainer[][2]={
     {"2#subtree#","#krbMaxTicketLife"},
     {"2#subtree#","#krbMaxRenewableAge"},
     {"2#subtree#","#krbPrincipalName"},
-    {"6#subtree#","#krbSecretKey"},
+    {"6#subtree#","#krbPrincipalKey"},
     {"2#subtree#","#krbPrincipalExpiration"},
     {"6#subtree#","#ModifiersName"},
     {"2#subtree#","#krbPwdHistoryLength"},
@@ -262,7 +262,6 @@ static char *pwdrights_realmcontainer[][2]={
     {"2#subtree#","#krbMaxPwdLife"},
     {"2#subtree#","#krbPwdMinDiffChars"},
     {"2#subtree#","#krbPwdMinLength"},
-    {"2#subtree#","#krbPwdPolicyRefCount"},
     {"2#subtree#","#krbPwdPolicyReference"},
     { "", "" }
 };
@@ -275,7 +274,7 @@ static char *security_container[][2] = {
 
 static char *kerberos_container[][2] = {
     {"1#subtree#","#[Entry Rights]"},
-    {"2#subtree#","#krbPolicyReference"},
+    {"2#subtree#","#krbTicketPolicyReference"},
     { "", "" }
 };
 
@@ -298,7 +297,7 @@ krb5_ldap_add_service_rights(context, servicetype, serviceobjdn, realmname, subt
     int                 servicetype;
     char                *serviceobjdn;
     char                *realmname;
-    char                *subtreeparam;
+    char                **subtreeparam;                         
     int                 mask;
 {
 
@@ -307,10 +306,11 @@ krb5_ldap_add_service_rights(context, servicetype, serviceobjdn, realmname, subt
     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();
@@ -321,15 +321,29 @@ krb5_ldap_add_service_rights(context, servicetype, serviceobjdn, realmname, subt
        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 */
@@ -490,16 +504,19 @@ krb5_ldap_add_service_rights(context, servicetype, serviceobjdn, realmname, subt
 
                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) {
@@ -513,16 +530,19 @@ krb5_ldap_add_service_rights(context, servicetype, serviceobjdn, realmname, subt
 
                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) {
@@ -536,16 +556,19 @@ krb5_ldap_add_service_rights(context, servicetype, serviceobjdn, realmname, subt
 
                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]);
            }
        }
@@ -583,7 +606,7 @@ krb5_ldap_delete_service_rights(context, servicetype, serviceobjdn, realmname, s
     int             servicetype;
     char            *serviceobjdn;
     char            *realmname;
-    char            *subtreeparam;
+    char            **subtreeparam; 
     int             mask;
 {
 
@@ -593,29 +616,45 @@ krb5_ldap_delete_service_rights(context, servicetype, serviceobjdn, realmname, s
     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;
+        }
     }
 
 
@@ -722,16 +761,18 @@ krb5_ldap_delete_service_rights(context, servicetype, serviceobjdn, realmname, s
 
                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) {
@@ -745,16 +786,18 @@ krb5_ldap_delete_service_rights(context, servicetype, serviceobjdn, realmname, s
 
                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) {
@@ -768,16 +811,18 @@ krb5_ldap_delete_service_rights(context, servicetype, serviceobjdn, realmname, s
 
                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]);
            }
        }
index d2676a3d449ceb42e6a9ac771b2bb59a16a880c8..d4bbb077de6407aa5f001757f7825e593db59794 100644 (file)
@@ -88,10 +88,10 @@ krb5_error_code
 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
index 292cf7ae66218f0d596eb151b6b2ce73ad796aac..face0385989b302cb5068d758474defdf8ade8be 100644 (file)
 
 /* 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.
  */
@@ -106,36 +46,33 @@ krb5_ldap_create_policy(context, policy, mask)
 {
     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;
 
@@ -156,21 +93,16 @@ krb5_ldap_create_policy(context, policy, mask)
                                          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);
@@ -191,29 +123,33 @@ krb5_ldap_modify_policy(context, policy, mask)
     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;
     }
@@ -236,17 +172,15 @@ krb5_ldap_modify_policy(context, policy, mask)
            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;
@@ -259,9 +193,9 @@ cleanup:
  */
 
 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;
 {
@@ -269,15 +203,15 @@ krb5_ldap_read_policy(context, policydn, policy, 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;
@@ -286,8 +220,11 @@ krb5_ldap_read_policy(context, policydn, policy, omask)
     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 */
@@ -295,15 +232,18 @@ krb5_ldap_read_policy(context, policydn, policy, omask)
     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) {
@@ -315,9 +255,6 @@ krb5_ldap_read_policy(context, policydn, policy, omask)
 
        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);
 
@@ -351,19 +288,19 @@ cleanup:
  */
 
 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;
@@ -373,13 +310,18 @@ krb5_ldap_delete_policy(context, policydn, policy, mask)
     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;
@@ -391,6 +333,8 @@ krb5_ldap_delete_policy(context, policydn, policy, mask)
     }
 
 cleanup:
+    if (policy_dn != NULL)
+        free (policy_dn);
     krb5_ldap_put_handle_to_pool(ldap_context, ldap_server_handle);
     return st;
 }
@@ -406,10 +350,39 @@ krb5_ldap_list_policy(context, containerdn, policy)
     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;
 }
 
@@ -430,8 +403,8 @@ krb5_ldap_free_policy(context, policy)
     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)
index a5d1987772a9f22278c2c1910abfed20b6b26d36..9a1f2ea11e5e2047bfddd7d95e6383254cde6058 100644 (file)
 /* 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;
 
@@ -59,7 +58,7 @@ krb5_error_code
 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 *);