pull up r18750 from trunk
authorTom Yu <tlyu@mit.edu>
Wed, 8 Nov 2006 23:44:31 +0000 (23:44 +0000)
committerTom Yu <tlyu@mit.edu>
Wed, 8 Nov 2006 23:44:31 +0000 (23:44 +0000)
 r18750@cathode-dark-space:  wfiveash | 2006-10-30 15:56:57 -0500
 ticket: new
 subject: latest Novell ldap patches and kdb5_util dump support for ldap
 Target_Version: krb5-1.6
 Tags: pullup

 I've applied Novell's latest patches for their LDAP KDB plugin.  I've
 also implemented and tested support for kdb5_util dump using the LDAP
 KDB plugin.  I also added a Sun copyright on files that I've modified.

ticket: 4562
version_fixed: 1.6

git-svn-id: svn://anonsvn.mit.edu/krb5/branches/krb5-1-6@18774 dc483132-0cff-0310-8789-dd5450dbe970

15 files changed:
src/kdc/main.c
src/lib/krb5/asn.1/ldap_key_seq.c
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_services.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_create.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

index 3cd546f3a298d5d8934518dce9e61a0d15e5d3d7..282d418afbd52927c7f025700e646b0ac5cba0ba 100644 (file)
@@ -382,10 +382,13 @@ setup_signal_handlers(void)
     (void) sigaction(SIGTERM, &s_action, (struct sigaction *) NULL);
     s_action.sa_handler = request_hup;
     (void) sigaction(SIGHUP, &s_action, (struct sigaction *) NULL);
+    s_action.sa_handler = SIG_IGN;
+    (void) sigaction(SIGPIPE, &s_action, (struct sigaction *) NULL);
 #else  /* POSIX_SIGNALS */
     signal(SIGINT, request_exit);
     signal(SIGTERM, request_exit);
     signal(SIGHUP, request_hup);
+    signal(SIGPIPE, SIG_IGN);
 #endif /* POSIX_SIGNALS */
 
     return;
index c77c51c03412a7fadb914199f21e5ab816799343..c25d7afe67a9b281ac89e6017e16f6bc4ea8afb1 100644 (file)
@@ -112,7 +112,7 @@ asn1_encode_key(asn1buf *buf,
 
        ret = asn1_make_sequence(buf, salt_len, &length); checkerr;
        salt_len += length;
-       ret = asn1_make_etag(buf, CONTEXT_SPECIFIC, 1, salt_len, &length); checkerr;
+       ret = asn1_make_etag(buf, CONTEXT_SPECIFIC, 0, salt_len, &length); checkerr;
        salt_len += length;
 
        sum += salt_len;
@@ -138,6 +138,7 @@ asn1_encode_sequence_of_keys (krb5_key_data *key_data,
     asn1_error_code ret = 0;
     asn1buf *buf = NULL;
     unsigned int length, sum = 0;
+    unsigned long tmp_ul;
 
     *code = NULL;
 
@@ -167,7 +168,8 @@ asn1_encode_sequence_of_keys (krb5_key_data *key_data,
     /* mkvno */
     if (mkvno < 0)
        cleanup (ASN1_BAD_FORMAT);
-    ret = asn1_encode_unsigned_integer (buf, (unsigned int)mkvno, &length); checkerr;
+    tmp_ul = (unsigned long)mkvno;
+    ret = asn1_encode_unsigned_integer (buf, tmp_ul, &length); checkerr;
     sum += length;
     ret = asn1_make_etag(buf, CONTEXT_SPECIFIC, 3, length, &length); checkerr;
     sum += length;
@@ -175,7 +177,8 @@ asn1_encode_sequence_of_keys (krb5_key_data *key_data,
     /* kvno (assuming all keys in array have same version) */
     if (key_data[0].key_data_kvno < 0)
        cleanup (ASN1_BAD_FORMAT);
-    ret = asn1_encode_unsigned_integer (buf, (unsigned int)key_data[0].key_data_kvno, &length);
+    tmp_ul = (unsigned long)key_data[0].key_data_kvno;
+    ret = asn1_encode_unsigned_integer (buf, tmp_ul, &length);
     checkerr;
     sum += length;
     ret = asn1_make_etag(buf, CONTEXT_SPECIFIC, 2, length, &length); checkerr;
@@ -202,8 +205,11 @@ asn1_encode_sequence_of_keys (krb5_key_data *key_data,
 last:
     asn1buf_destroy (&buf);
 
-    if (ret != 0 && *code != NULL)
-       free (*code);
+    if (ret != 0 && *code != NULL) {
+        if ((*code)->data != NULL)
+            free ((*code)->data);
+        free (*code);
+    }
 
     return ret;
 }
@@ -219,7 +225,7 @@ last:
        asn1buf_sync((outer), (inner), 0, 0, 0, 0, 0);
 
 static asn1_error_code
-decode_tagged_integer (asn1buf *buf, int expectedtag, long *val)
+decode_tagged_integer (asn1buf *buf, asn1_tagnum expectedtag, long *val)
 {
     int buflen;
     asn1_error_code ret = 0;
@@ -271,7 +277,7 @@ last:
 #endif
 
 static asn1_error_code
-decode_tagged_octetstring (asn1buf *buf, int expectedtag, int *len,
+decode_tagged_octetstring (asn1buf *buf, asn1_tagnum expectedtag, int *len,
                           asn1_octet **val)
 {
     int buflen;
@@ -449,6 +455,11 @@ krb5_error_code asn1_decode_sequence_of_keys (krb5_data *in,
        safe_syncbuf (&subbuf, &keyseq);
     }
 
+    /*
+     * There could be other data inside the outermost sequence ... tags we don't
+     * know about. So, not invoking "safe_syncbuf(&buf,&subbuf)"
+     */
+
 last:
     if (ret != 0) {
        int i;
index 60963d2d9a1ea110e254e0f4b9e7b8dbd881ca92..7a6c6411e3983d602c2e8b29c75fc5c46e748e02 100644 (file)
@@ -52,7 +52,7 @@ 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;
+    krb5_error_code retval = 0;
     kdb5_dal_handle *dal_handle = NULL;
     krb5_ldap_context *ldap_context=NULL;
                                                                                                                              
@@ -816,18 +816,6 @@ void kdb5_ldap_list_policies(argc, argv)
        goto err_usage;
     }
 
-    /* Parse base DN argument if present */
-    if (argc == 3) {
-       if (strcmp(argv[1], "-basedn"))
-           goto err_usage;
-
-       basedn = strdup(argv[2]);
-       if (basedn == NULL) {
-           retval = ENOMEM;
-           goto cleanup;
-       }
-    }
-
     if ((retval = init_ldap_realm (argc, argv)))
        goto cleanup;
 
index 870f2bd7422c97de83469d340fb5ffd5c2962ea4..7e2c71e62ef7a331b909c556254bde19e800291d 100644 (file)
@@ -343,15 +343,17 @@ void kdb5_ldap_create(argc, argv)
                 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);
+                list = (char **) calloc(MAX_LIST_ENTRIES, sizeof(char *));
                 if (list == NULL) {
                     retval = ENOMEM;
                     goto cleanup;
                 }
-                if (( retval = krb5_parse_list(argv[i], LIST_DELIMITER, list)))
+                if ((retval = krb5_parse_list(argv[i], LIST_DELIMITER, list))) {
+                   free(list);
+                   list = NULL;
                     goto cleanup;
-                                                                                                                             
+               }
+
                 rparams->subtreecount=0;
                 while(list[rparams->subtreecount]!=NULL)
                     (rparams->subtreecount)++;
@@ -886,13 +888,13 @@ void kdb5_ldap_modify(argc, argv)
     int argc;
     char *argv[];
 {
-    krb5_error_code retval, st;
+    krb5_error_code retval = 0;
     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, j = 0;
+    int i = 0;
     int mask = 0, rmask = 0, ret_mask = 0;
     char **slist = {NULL};
 #ifdef HAVE_EDIRECTORY
@@ -942,7 +944,6 @@ void kdb5_ldap_modify(argc, argv)
                if (rparams->subtree) {
 #ifdef HAVE_EDIRECTORY
                     oldsubtrees =  (char **) calloc(rparams->subtreecount+1, sizeof(char *));
-                   memset(oldsubtrees, 0, szeof(char *) * rparams->subtreecount+1);
                     if (oldsubtrees == NULL) {
                         retval = ENOMEM;
                         goto cleanup;
@@ -955,20 +956,22 @@ void kdb5_ldap_modify(argc, argv)
                         }
                     }
 #endif
-                    for(k=0;k<rparams->subtreecount && rparams->subtree[k];k++)
+                    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;
+                    retval = ENOMEM;
+                    goto cleanup;
                 }
-                if (( retval = krb5_parse_list(argv[i], LIST_DELIMITER, slist)))
+                if (( retval = krb5_parse_list(argv[i], LIST_DELIMITER, slist))) {
+                    free(slist);
+                    slist = NULL;
                     goto cleanup;
+                }
                                                                                                                              
                 rparams->subtreecount=0;
                 while(slist[rparams->subtreecount]!=NULL)
index 783b44d68aee3987ad2b3d5b1c3ad290cbf9f22b..bd64566f4f1675ea503763ad393d32677ee05a00 100644 (file)
@@ -383,6 +383,10 @@ void kdb5_ldap_create_service(argc, argv)
     if (extra_argc >= 1) {
        /* Set service DN as the last argument */
        extra_argv[extra_argc] = strdup(srvparams->servicedn);
+       if (extra_argv[extra_argc] == NULL) {
+            retval = ENOMEM;
+            goto cleanup;
+        }
        extra_argc++;
 
        if ((retval = kdb5_ldap_set_service_password(extra_argc, extra_argv)) != 0) {
@@ -1924,11 +1928,17 @@ kdb5_ldap_stash_service_password(argc, argv)
     if (argc == 4) {
        /* Find the stash file name */
        if (strcmp (argv[1], "-f") == 0) {
-           file_name = strdup (argv[2]);
-           service_object = strdup (argv[3]);
+           if (((file_name = strdup (argv[2])) == NULL) ||
+               ((service_object = strdup (argv[3])) == NULL)) {
+               com_err(me, ENOMEM, "while setting service object password");
+               goto cleanup;
+           }
        } else if (strcmp (argv[2], "-f") == 0) {
-           file_name = strdup (argv[3]);
-           service_object = strdup (argv[1]);
+           if (((file_name = strdup (argv[3])) == NULL) ||
+               ((service_object = strdup (argv[1])) == NULL)) {
+               com_err(me, ENOMEM, "while setting service object password");
+               goto cleanup;
+           }
        } else {
            print_usage = TRUE;
            goto cleanup;
@@ -1956,6 +1966,10 @@ kdb5_ldap_stash_service_password(argc, argv)
            if (section == NULL) {
                /* Stash file path neither in krb5.conf nor on command line */
                file_name = strdup(DEF_SERVICE_PASSWD_FILE);
+               if (file_name == NULL) {
+                   com_err(me, ENOMEM, "while setting service object password");
+                   goto cleanup;
+               }
                goto done;
            }
        }
index 3cc0f0f912db6412172388b6b57f5102ccbe44f6..38ac03798d54c163e5ceb4c32d33992a51bf3858 100644 (file)
@@ -293,7 +293,6 @@ int main(argc, argv)
     char *bind_dn = NULL;
     char *passwd = NULL;
     char *ldap_server = NULL;
-    char *ldap_port = NULL;
     unsigned int ldapmask = 0;
     unsigned int passwd_len = 0;
     char *prompt = NULL;
index 93a47acf9d44a0cb0edd6ef61833e007087d82c8..97da15d2144e4dd8ddd6071dedd765523a840cf5 100644 (file)
@@ -68,6 +68,10 @@ extern struct timeval timelimit;
 #define  KERBEROS_CONTAINER "cn=Kerberos,cn=Security"
 #endif
 
+#if !defined(LDAP_OPT_RESULT_CODE) && defined(LDAP_OPT_ERROR_NUMBER)
+#define LDAP_OPT_RESULT_CODE LDAP_OPT_ERROR_NUMBER
+#endif
+
 #define NEG(val)   (val <0) ? abs(val) : -val ;
 #define MAXINTLEN  10
 
index 3162bdc26caefaea86eb3951338ac63284320d8b..768ba6a593ba542645af23e87f83f7d1f4d402b7 100644 (file)
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+/*
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
 #include "ldap_main.h"
 #include "ldap_realm.h"
 #include "ldap_principal.h"
index 1d0a3203667ac3f83b9dbce4843bc1bcdc44e1ed..d6b479aa0bcf1c9772289099c115217860dc92a3 100644 (file)
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  */
+/*
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
 #include <string.h>
 #include <time.h>
 #include "kdb_ldap.h"
 #include "ldap_misc.h"
+#include "ldap_handle.h"
 #include "ldap_err.h"
+#include "ldap_principal.h"
+#include "princ_xdr.h"
+#include "ldap_pwd_policy.h"
 
 #ifdef NEED_STRPTIME_PROTO
 extern char *strptime (const char *, const char *, struct tm *);
@@ -508,31 +516,34 @@ krb5_get_subtree_info(ldap_context, subtreearr, ntree)
     }
 
     ncount = i;
-
-    subtree = (char **) malloc(sizeof(char *) * (ncount + 1));
-    if (subtree == NULL) {
-       st = ENOMEM;
-       goto cleanup;
+    newsubtree = (char **) malloc(sizeof(char *) * (ncount + 1));
+    if (newsubtree == NULL) {
+        st = ENOMEM;
+        goto cleanup;
+    }
+    memset(newsubtree, 0, (sizeof(char *) * (ncount+1)));
+    if ((st = remove_overlapping_subtrees(subtarr, newsubtree, &ncount,
+               search_scope)) != 0) {
+        goto cleanup;
     }
-    memset(subtree, 0, (sizeof(char *) * (ncount+1)));
-    remove_overlapping_subtrees(subtarr, &subtree, &ncount, search_scope);
 
     *ntree = ncount;
-    *subtreearr = subtree;
+    *subtreearr = newsubtree;
 
 cleanup:
-    if (subtarr!=NULL) {
-       for (i=0; subtarr[i]!=NULL; i++)
+    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);
+    if (st != 0) {
+        if (newsubtree != NULL) {
+           for (i=0; newsubtree[i] != NULL; i++)
+               free(newsubtree[i]);
+           free(newsubtree);
+        }
     }
-
     return st;
 }
 
@@ -1283,9 +1294,9 @@ krb5_ldap_get_strings(ld, ent, attribute, retarr, attr_present)
     char                        ***retarr;
     krb5_boolean                *attr_present;
 {
-    char                           **values=NULL;
-    krb5_error_code                st=0;
-    int                            i=0, count=0;
+    char                        **values=NULL;
+    krb5_error_code             st=0;
+    unsigned int                i=0, count=0;
 
     *retarr = NULL;
     if (attr_present != NULL)
@@ -1586,8 +1597,10 @@ krb5_ldap_release_errcode_string(krb5_context kcontext, const char *msg)
  */
 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;
+                              int *count, LDAP *ld)
+{
+    int                         i, st = 0, tempst = 0, gothandle = 0;
+    unsigned int               ntrees;
     char                        *refcntattr[2];
     char                        *filter = NULL;
     char                        **subtree = NULL, *ptr = NULL;
@@ -1810,11 +1823,12 @@ cleanup:
 }
 
 /* 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)
+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;
+    char    **subtree = listop;
 
     slen = count-1;
     for (k=0; k<=slen && listin[k]!=NULL ; k++) {
@@ -1870,6 +1884,311 @@ krb5_error_code remove_overlapping_subtrees(char **listin, char ***listop, int *
     return 0;
 }
 
+/*
+ * Fill out a krb5_db_entry princ entry struct given a LDAP message containing
+ * the results of a principal search of the directory.
+ */
+krb5_error_code
+populate_krb5_db_entry (krb5_context context,
+    krb5_ldap_context *ldap_context,
+    LDAP *ld,
+    LDAPMessage *ent,
+    krb5_const_principal princ,
+    krb5_db_entry *entry)
+{
+    krb5_error_code st = 0;
+    unsigned int    mask = 0;
+    krb5_boolean    attr_present = FALSE;
+    char            **values = NULL, *policydn = NULL, *pwdpolicydn = NULL;
+    char            *polname = NULL, *tktpolname = NULL;
+    struct berval   **bvalues = NULL;
+    krb5_tl_data    userinfo_tl_data = {0};
+    char            **link_references = NULL;
+    krb5_ui_2      entry_len;
+    char *DN = NULL;
+
+    if (princ == NULL) {
+       /* XXX WAF probably should just extract princ from ldap result */
+       st = EINVAL;
+       goto cleanup;
+    } else {
+       if ((st=krb5_copy_principal(context, princ, &(entry->princ))) != 0)
+           goto cleanup;
+    }
+    /* get the associated directory user information */
+    if ((values = ldap_get_values(ld, ent, "krbprincipalname")) != NULL) {
+       int i, pcount=0, kerberos_principal_object_type=0;
+       char *user;
+
+       if ((st=krb5_unparse_name(context, princ, &user)) != 0)
+           goto cleanup;
+
+       for (i=0; values[i] != NULL; ++i) {
+           if (strcasecmp(values[i], user) == 0) {
+               pcount = ldap_count_values(values);
+               break;
+           }
+       }
+       ldap_value_free(values);
+       free(user);
+
+       if ((DN = ldap_get_dn(ld, ent)) == NULL) {
+           ldap_get_option(ld, LDAP_OPT_RESULT_CODE, &st);
+           st = set_ldap_error(context, st, 0);
+           goto cleanup;
+       }
+
+       if ((values=ldap_get_values(ld, ent, "objectclass")) != NULL) {
+           for (i=0; values[i] != NULL; ++i)
+               if (strcasecmp(values[i], "krbprincipal") == 0) {
+                   kerberos_principal_object_type = KDB_STANDALONE_PRINCIPAL_OBJECT;
+                   if ((st=store_tl_data(&userinfo_tl_data, KDB_TL_PRINCTYPE,
+                               &kerberos_principal_object_type)) != 0)
+                       goto cleanup;
+                   break;
+               }
+           ldap_value_free(values);
+       }
+
+       /* add principalcount, DN and principaltype user information to tl_data */
+       if (((st=store_tl_data(&userinfo_tl_data, KDB_TL_PRINCCOUNT, &pcount)) != 0) ||
+           ((st=store_tl_data(&userinfo_tl_data, KDB_TL_USERDN, DN)) != 0))
+           goto cleanup;
+    }
+
+    /* read all the kerberos attributes */
+
+    /* KRBLASTSUCCESSFULAUTH */
+    if ((st=krb5_ldap_get_time(ld, ent, "krbLastSuccessfulAuth",
+               &(entry->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",
+               &(entry->last_failed), &attr_present)) != 0)
+       goto cleanup;
+    if (attr_present == TRUE)
+       mask |= KDB_LAST_FAILED;
+
+    /* KRBLOGINFAILEDCOUNT */
+    if (krb5_ldap_get_value(ld, ent, "krbLoginFailedCount",
+           &(entry->fail_auth_count)) == 0)
+       mask |= KDB_FAIL_AUTH_COUNT;
+
+    /* KRBMAXTICKETLIFE */
+    if (krb5_ldap_get_value(ld, ent, "krbmaxticketlife", &(entry->max_life)) == 0)
+       mask |= KDB_MAX_LIFE_ATTR;
+
+    /* KRBMAXRENEWABLEAGE */
+    if (krb5_ldap_get_value(ld, ent, "krbmaxrenewableage",
+           &(entry->max_renewable_life)) == 0)
+       mask |= KDB_MAX_RLIFE_ATTR;
+
+    /* KRBTICKETFLAGS */
+    if (krb5_ldap_get_value(ld, ent, "krbticketflags", &(entry->attributes)) == 0)
+       mask |= KDB_TKT_FLAGS_ATTR;
+
+    /* PRINCIPAL EXPIRATION TIME */
+    if ((st=krb5_ldap_get_time(ld, ent, "krbprincipalexpiration", &(entry->expiration),
+               &attr_present)) != 0)
+       goto cleanup;
+    if (attr_present == TRUE)
+       mask |= KDB_PRINC_EXPIRE_TIME_ATTR;
+
+    /* PASSWORD EXPIRATION TIME */
+    if ((st=krb5_ldap_get_time(ld, ent, "krbpasswordexpiration", &(entry->pw_expiration),
+               &attr_present)) != 0)
+       goto cleanup;
+    if (attr_present == TRUE)
+       mask |= KDB_PWD_EXPIRE_TIME_ATTR;
+
+    /* KRBPOLICYREFERENCE */
+
+    if ((st=krb5_ldap_get_string(ld, ent, "krbticketpolicyreference", &policydn,
+               &attr_present)) != 0)
+       goto cleanup;
+    if (attr_present == TRUE) {
+       /* Ensure that the policy is inside the realm container */
+       if ((st = krb5_ldap_policydn_to_name (context, policydn, &tktpolname)) != 0)
+           goto cleanup;
+    }
+
+    /* KRBPWDPOLICYREFERENCE */
+    if ((st=krb5_ldap_get_string(ld, ent, "krbpwdpolicyreference", &pwdpolicydn,
+               &attr_present)) != 0)
+       goto cleanup;
+    if (attr_present == TRUE) {
+       krb5_tl_data  kadm_tl_data;
+
+       mask |= KDB_PWD_POL_REF_ATTR;
+
+       /* 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, entry, &kadm_tl_data);
+    }
+
+    /* KRBSECRETKEY */
+    if ((bvalues=ldap_get_values_len(ld, ent, "krbprincipalkey")) != NULL) {
+       mask |= KDB_SECRET_KEY;
+       if ((st=krb5_decode_krbsecretkey(context, entry, bvalues, &userinfo_tl_data)) != 0)
+           goto cleanup;
+    }
+
+    /* 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, entry,
+                       lstpwdchng)))
+               goto cleanup;
+           mask |= KDB_LAST_PWD_CHANGE_ATTR;
+       }
+    }
+
+    /* 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, entry, ptr)) != 0)
+                   break;
+           }
+           ldap_value_free_len (ber_tl_data);
+           if (st != 0)
+               goto cleanup;
+           mask |= KDB_EXTRA_DATA;
+       }
+    }
+
+    /* update the mask of attributes present on the directory object to the tl_data */
+    if ((st=store_tl_data(&userinfo_tl_data, KDB_TL_MASK, &mask)) != 0)
+       goto cleanup;
+    if ((st=krb5_dbe_update_tl_data(context, entry, &userinfo_tl_data)) != 0)
+       goto cleanup;
+
+#ifdef HAVE_EDIRECTORY
+    {
+       krb5_timestamp              expiretime=0;
+       char                        *is_login_disabled=NULL;
+
+       /* LOGIN EXPIRATION TIME */
+       if ((st=krb5_ldap_get_time(ld, ent, "loginexpirationtime", &expiretime,
+                   &attr_present)) != 0)
+           goto cleanup;
+
+       if (attr_present == TRUE) {
+           if ((mask & KDB_PRINC_EXPIRE_TIME_ATTR) == 1) {
+               if (expiretime < entry->expiration)
+                   entry->expiration = expiretime;
+           } else {
+               entry->expiration = expiretime;
+           }
+       }
+
+       /* LOGIN DISABLED */
+       if ((st=krb5_ldap_get_string(ld, ent, "logindisabled", &is_login_disabled,
+                   &attr_present)) != 0)
+           goto cleanup;
+       if (attr_present == TRUE) {
+           if (strcasecmp(is_login_disabled, "TRUE")== 0)
+               entry->attributes |= KRB5_KDB_DISALLOW_ALL_TIX;
+           free (is_login_disabled);
+       }
+    }
+#endif
+
+    if ((st=krb5_read_tkt_policy (context, ldap_context, entry, tktpolname)) !=0)
+       goto cleanup;
+
+    /* 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;
+       krb5_ui_4          pw_max_life;
+
+       memset(&pwdpol, 0, sizeof(pwdpol));
+
+       if ((st=krb5_ldap_get_password_policy(context, polname, &pwdpol, &cnt)) != 0)
+           goto cleanup;
+       pw_max_life = pwdpol->pw_max_life;
+       free (pwdpol);
+
+       if (pw_max_life > 0) {
+           if ((st=krb5_dbe_lookup_last_pwd_change(context, entry, &last_pw_changed)) != 0)
+               goto cleanup;
+
+           if ((mask & KDB_PWD_EXPIRE_TIME_ATTR) == 1) {
+               if ((last_pw_changed + pw_max_life) < entry->pw_expiration)
+                   entry->pw_expiration = last_pw_changed + pw_max_life;
+           } else
+               entry->pw_expiration = last_pw_changed + pw_max_life;
+       }
+    }
+    /* XXX so krb5_encode_princ_contents() will be happy */
+    entry->len = KRB5_KDB_V1_BASE_LENGTH;
+
+cleanup:
+
+    if (DN != NULL)
+       ldap_memfree(DN);
+
+    if (userinfo_tl_data.tl_data_contents != NULL)
+       free(userinfo_tl_data.tl_data_contents);
+
+    if (pwdpolicydn != NULL)
+       free(pwdpolicydn);
+
+    if (polname != NULL)
+       free(polname);
+
+    if (tktpolname != NULL)
+       free (tktpolname);
+
+    if (policydn != NULL)
+       free(policydn);
+
+    if (link_references) {
+        int i;
+        for (i=0; link_references[i] != NULL; ++i)
+            free (link_references[i]);
+        free (link_references);
+    }
+
+    return (st);
+}
+
 /*
  * Solaris libldap does not provide the following functions which are in
  * OpenLDAP.
index ce9250d5c44b173de580a41ab9c456f3b09080dd..5fc969f46d55ed20d070f14f324b2b92d8744ef7 100644 (file)
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+/*
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
 #ifndef _HAVE_LDAP_MISC_H
 #define _HAVE_LDAP_MISC_H 1
 
@@ -137,4 +142,12 @@ krb5_ldap_name_to_policydn (krb5_context, char *, char **);
 krb5_error_code
 krb5_ldap_get_db_opt(char *, char **, char **);
 
+krb5_error_code
+populate_krb5_db_entry(krb5_context context,
+    krb5_ldap_context *ldap_context,
+    LDAP *ld,
+    LDAPMessage *ent,
+    krb5_const_principal princ,
+    krb5_db_entry *entry);
+
 #endif
index 3ace96cbad7f8b0d8dd5ea7c9c6a47dd7cd5df63..28507a9f77e0ce4402f5aafbacc7dfad2299bb28 100644 (file)
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  */
+/*
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
 
 #include "ldap_main.h"
 #include "kdb_ldap.h"
@@ -130,7 +134,6 @@ krb5_ldap_free_principal(kcontext , entries, nentries)
     return 0;
 }
 
-
 krb5_error_code
 krb5_ldap_iterate(context, match_expr, func, func_arg)
     krb5_context           context;
@@ -141,7 +144,6 @@ krb5_ldap_iterate(context, match_expr, func, func_arg)
     krb5_db_entry            entry;
     krb5_principal           principal;
     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;
     LDAP                     *ld=NULL;
@@ -184,21 +186,29 @@ krb5_ldap_iterate(context, match_expr, func, func_arg)
 
     GET_HANDLE();
 
-    for (tree=0; tree<ntree; ++tree) {
+    for (tree=0; tree < ntree; ++tree) {
 
-       LDAP_SEARCH(subtree[tree], ldap_context->lrparams->search_scope, filter, krbprincipal_attr);
+       LDAP_SEARCH(subtree[tree], ldap_context->lrparams->search_scope, filter, principal_attributes);
        for (ent=ldap_first_entry(ld, result); ent != NULL; ent=ldap_next_entry(ld, ent)) {
            if ((values=ldap_get_values(ld, ent, "krbprincipalname")) != NULL) {
                for (i=0; values[i] != NULL; ++i) {
+                   if (values[i])
                    if (krb5_ldap_parse_principal_name(values[i], &princ_name) != 0)
                        continue;
                    if (krb5_parse_name(context, princ_name, &principal) != 0)
                        continue;
                    if (is_principal_in_realm(ldap_context, principal) == 0) {
-                       entry.princ = principal;
+                       if ((st = populate_krb5_db_entry(context, ldap_context, ld, ent, principal,
+                                   &entry)) != 0)
+                           goto cleanup;
                        (*func)(func_arg, &entry);
+                       krb5_dbe_free_contents(context, &entry);
+                       (void) krb5_free_principal(context, principal);
+                       if (princ_name)
+                           free(princ_name);
+                       break;
                    }
-                   krb5_free_principal(context, principal);
+                   (void) krb5_free_principal(context, principal);
                    if (princ_name)
                        free(princ_name);
                }
index c4f5e93b76dc0ea94d34637740c3052925c521d3..7d3734bd43d2713b1ff0d89226c15871ef222a89 100644 (file)
@@ -129,4 +129,13 @@ krb5_ldap_unparse_principal_name(char *);
 krb5_error_code
 krb5_ldap_parse_principal_name(char *, char **);
 
+krb5_error_code
+krb5_decode_krbsecretkey(krb5_context, krb5_db_entry *, struct berval **,
+    krb5_tl_data *);
+
+krb5_error_code
+berval2tl_data(struct berval *in, krb5_tl_data **out);
+
+krb5_error_code
+krb5_read_tkt_policy (krb5_context, krb5_ldap_context *, krb5_db_entry *, char *);
 #endif
index 9ba4cb6d9e12ade1eda7cd0e1346125099bf3612..71200eb9ea99de271adaec19403ccf3ded0ba673 100644 (file)
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  */
+/*
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
 
 #include <time.h>
 #include "ldap_main.h"
 
 extern char* principal_attributes[];
 extern char* max_pwd_life_attr[];
-#if !defined(LDAP_OPT_RESULT_CODE) && defined(LDAP_OPT_ERROR_NUMBER)
-#define LDAP_OPT_RESULT_CODE LDAP_OPT_ERROR_NUMBER
-#endif
-
-static krb5_error_code
-krb5_decode_krbsecretkey(krb5_context, krb5_db_entry *, struct berval **, krb5_tl_data *);
-
-static krb5_error_code
-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) {
+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;
@@ -84,21 +81,15 @@ 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=NULL;
-    unsigned int                tree=0, ntrees=1, mask=0, princlen=0;
+    char                        *user=NULL, *filter=NULL, **subtree=NULL;
+    unsigned int                tree=0, ntrees=1, princlen=0;
     krb5_error_code            tempst=0, st=0;
-    char                        **values=NULL, *policydn=NULL, *pwdpolicydn=NULL;
-    char                        *polname = NULL, *tktpolname = NULL;
-    char                        **link_references=NULL;
-    krb5_tl_data                userinfo_tl_data={0};
-    struct berval               **bvalues=NULL;
+    char                        **values=NULL;
     LDAP                       *ld=NULL;
     LDAPMessage                        *result=NULL, *ent=NULL;
     krb5_ldap_context           *ldap_context=NULL;
     kdb5_dal_handle             *dal_handle=NULL;
     krb5_ldap_server_handle     *ldap_server_handle=NULL;
-    krb5_principal              parsed_mod_name=NULL;
-    krb5_boolean                attr_present=FALSE;
 
     /* Clear the global error string */
     krb5_clear_error_message(context);
@@ -129,7 +120,7 @@ krb5_ldap_get_principal(context, searchfor, entries, nentries, more)
        goto cleanup;
 
     princlen = strlen(FILTER) + strlen(user) + 2 + 1;      /* 2 for closing brackets */
-    if ((filter=malloc(princlen)) == NULL) {
+    if ((filter = malloc(princlen)) == NULL) {
        st = ENOMEM;
        goto cleanup;
     }
@@ -139,14 +130,14 @@ krb5_ldap_get_principal(context, searchfor, entries, nentries, more)
        goto cleanup;
 
     GET_HANDLE();
-    for (tree=0; tree<ntrees && *nentries==0; ++tree) {
+    for (tree=0; tree < ntrees && *nentries == 0; ++tree) {
 
        LDAP_SEARCH(subtree[tree], ldap_context->lrparams->search_scope, filter, principal_attributes);
        for (ent=ldap_first_entry(ld, result); ent != NULL && *nentries == 0; ent=ldap_next_entry(ld, ent)) {
 
            /* get the associated directory user information */
            if ((values=ldap_get_values(ld, ent, "krbprincipalname")) != NULL) {
-               int i=0, pcount=0, kerberos_principal_object_type=0;
+               int i;
 
                /* a wild-card in a principal name can return a list of kerberos principals.
                 * Make sure that the correct principal is returned.
@@ -155,7 +146,6 @@ krb5_ldap_get_principal(context, searchfor, entries, nentries, more)
                for (i=0; values[i] != NULL; ++i) {
                    if (strcasecmp(values[i], user) == 0) {
                        *nentries = 1;
-                       pcount = ldap_count_values(values);
                        break;
                    }
                }
@@ -163,198 +153,11 @@ krb5_ldap_get_principal(context, searchfor, entries, nentries, more)
 
                if (*nentries == 0) /* no matching principal found */
                    continue;
-
-               if ((DN = ldap_get_dn(ld, ent)) == NULL) {
-                   ldap_get_option (ld, LDAP_OPT_RESULT_CODE, &st);
-                   st = set_ldap_error (context, st, 0);
-                   goto cleanup;
-               }
-
-               if ((values=ldap_get_values(ld, ent, "objectclass")) != NULL) {
-                   for (i=0; values[i] != NULL; ++i)
-                       if (strcasecmp(values[i], "krbprincipal") == 0) {
-                           kerberos_principal_object_type = KDB_STANDALONE_PRINCIPAL_OBJECT;
-                           if ((st=store_tl_data(&userinfo_tl_data, KDB_TL_PRINCTYPE, &kerberos_principal_object_type)) != 0)
-                               goto cleanup;
-                           break;
-                       }
-                   ldap_value_free(values);
-               }
-
-               /* add principalcount, DN and principaltype user information to tl_data */
-               if (((st=store_tl_data(&userinfo_tl_data, KDB_TL_PRINCCOUNT, &pcount)) != 0) ||
-                   ((st=store_tl_data(&userinfo_tl_data, KDB_TL_USERDN, DN)) != 0))
-                   goto cleanup;
-           }
-
-           /* populate entries->princ with searchfor value */
-           if ((st=krb5_copy_principal(context, searchfor, &(entries->princ))) != 0)
-               goto cleanup;
-
-           /* read all the kerberos attributes */
-
-#ifdef  KRBCONF_KDC_MODIFIES_KDB
-           /* KRBLASTSUCCESSFULAUTH */
-           if ((st=krb5_ldap_get_time(ld, ent, "krbLastSuccessfulAuth", &(entries->last_success),&attr_present)) != 0)
-               goto cleanup;
-           if (attr_present == TRUE)
-               mask |= KDB_LAST_SUCCESS;
-
-           /* KRBLASTFAILEDAUTH */
-           if ((st=krb5_ldap_get_time(ld, ent, "krbLastFailedAuth", &(entries->last_failed),&attr_present)) != 0)
-               goto cleanup;
-           if (attr_present == TRUE)
-               mask |= KDB_LAST_FAILED;
-
-           /* KRBLOGINFAILEDCOUNT */
-           if (krb5_ldap_get_value(ld, ent, "krbLoginFailedCount", &(entries->fail_auth_count)) == 0)
-               mask |= KDB_FAIL_AUTH_COUNT;
-#endif
-
-           /* KRBMAXTICKETLIFE */
-           if (krb5_ldap_get_value(ld, ent, "krbmaxticketlife", &(entries->max_life)) == 0)
-               mask |= KDB_MAX_LIFE_ATTR;
-
-           /* KRBMAXRENEWABLEAGE */
-           if (krb5_ldap_get_value(ld, ent, "krbmaxrenewableage", &(entries->max_renewable_life)) == 0)
-               mask |= KDB_MAX_RLIFE_ATTR;
-
-           /* KRBTICKETFLAGS */
-           if (krb5_ldap_get_value(ld, ent, "krbticketflags", &(entries->attributes)) == 0)
-               mask |= KDB_TKT_FLAGS_ATTR;
-
-           /* PRINCIPAL EXPIRATION TIME */
-           if ((st=krb5_ldap_get_time(ld, ent, "krbprincipalexpiration", &(entries->expiration),
-                                      &attr_present)) != 0)
-               goto cleanup;
-           if (attr_present == TRUE)
-               mask |= KDB_PRINC_EXPIRE_TIME_ATTR;
-
-           /* PASSWORD EXPIRATION TIME */
-           if ((st=krb5_ldap_get_time(ld, ent, "krbpasswordexpiration", &(entries->pw_expiration),
-                                      &attr_present)) != 0)
-               goto cleanup;
-           if (attr_present == TRUE)
-               mask |= KDB_PWD_EXPIRE_TIME_ATTR;
-
-           /* KRBPOLICYREFERENCE */
-
-           if ((st=krb5_ldap_get_string(ld, ent, "krbticketpolicyreference", &policydn, &attr_present)) != 0)
-               goto cleanup;
-
-           if (attr_present == TRUE) {
-               /* Ensure that the policy is inside the realm container */
-               if ((st = krb5_ldap_policydn_to_name (context, policydn, &tktpolname)) != 0)
-                   goto cleanup;
-           }
-
-           /* KRBPWDPOLICYREFERENCE */
-           if ((st=krb5_ldap_get_string(ld, ent, "krbpwdpolicyreference", &pwdpolicydn, &attr_present)) != 0)
-               goto cleanup;
-           if (attr_present == TRUE) {
-               krb5_tl_data  kadm_tl_data;
-
-               mask |= KDB_PWD_POL_REF_ATTR;
-
-               /* 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, "krbprincipalkey")) != NULL) {
-               mask |= KDB_SECRET_KEY;
-               if ((st=krb5_decode_krbsecretkey(context, entries, bvalues, &userinfo_tl_data)) != 0)
-                   goto cleanup;
-           }
-
-           /* 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;
-               }
-           }
-
-           /* KRBOBJECTREFERENCES */
-           {
-               int i=0;
-               if ((st=krb5_ldap_get_strings(ld, ent, "krbobjectreferences", &link_references, &attr_present)) != 0)
-                   goto cleanup;
-               if (link_references != NULL) {
-                   for (i=0; link_references[i] != NULL; ++i) {
-                       if ((st=store_tl_data(&userinfo_tl_data, KDB_TL_LINKDN, link_references[i])) != 0)
-                           goto cleanup;
-                   }
-               }
            }
 
-           /* Set tl_data */
-           {
-               int i;
-               struct berval **ber_tl_data = NULL;
-               krb5_tl_data *ptr = NULL;
-
-               if ((ber_tl_data = ldap_get_values_len (ld, ent, "krbExtraData")) != NULL) {
-                   for (i = 0; ber_tl_data[i] != NULL; i++) {
-                       if ((st = berval2tl_data (ber_tl_data[i] , &ptr)) != 0)
-                           break;
-                       if ((st = krb5_dbe_update_tl_data(context, entries, ptr)) != 0)
-                           break;
-                   }
-                   ldap_value_free_len (ber_tl_data);
-                   if (st != 0)
-                       goto cleanup;
-                   mask |= KDB_EXTRA_DATA;
-               }
-           }
-
-           /* update the mask of attributes present on the directory object to the tl_data */
-           if ((st=store_tl_data(&userinfo_tl_data, KDB_TL_MASK, &mask)) != 0)
-               goto cleanup;
-           if ((st=krb5_dbe_update_tl_data(context, entries, &userinfo_tl_data)) != 0)
+           if ((st = populate_krb5_db_entry(context, ldap_context, ld, ent, searchfor,
+                       entries)) != 0)
                goto cleanup;
-
-#ifdef HAVE_EDIRECTORY
-           {
-               krb5_timestamp              expiretime=0;
-               char                        *is_login_disabled=NULL;
-
-               /* LOGIN EXPIRATION TIME */
-               if ((st=krb5_ldap_get_time(ld, ent, "loginexpirationtime", &expiretime,
-                                          &attr_present)) != 0)
-                   goto cleanup;
-
-               if (attr_present == TRUE) {
-                   if ((mask & KDB_PRINC_EXPIRE_TIME_ATTR) == 1) {
-                       if (expiretime < entries->expiration)
-                           entries->expiration = expiretime;
-                   } else {
-                       entries->expiration = expiretime;
-                   }
-               }
-
-               /* LOGIN DISABLED */
-               if ((st=krb5_ldap_get_string(ld, ent, "logindisabled", &is_login_disabled, &attr_present)) != 0)
-                   goto cleanup;
-               if (attr_present == TRUE) {
-                   if (strcasecmp(is_login_disabled,"TRUE")== 0)
-                       entries->attributes |= KRB5_KDB_DISALLOW_ALL_TIX;
-                   free (is_login_disabled);
-               }
-           }
-#endif
        }
        ldap_msgfree(result);
        result = NULL;
@@ -364,39 +167,6 @@ krb5_ldap_get_principal(context, searchfor, entries, nentries, more)
     krb5_ldap_put_handle_to_pool(ldap_context, ldap_server_handle);
     ldap_server_handle = NULL;
 
-    /* if principal not found */
-    if (*nentries == 0)
-       goto cleanup;
-
-    if ((st=krb5_read_tkt_policy (context, ldap_context, entries, tktpolname)) !=0)
-       goto cleanup;
-
-    /* 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;
-       krb5_ui_4          pw_max_life;
-
-       memset(&pwdpol, 0, sizeof(pwdpol));
-
-       if ((st=krb5_ldap_get_password_policy(context, polname, &pwdpol, &cnt)) != 0)
-           goto cleanup;
-       pw_max_life = pwdpol->pw_max_life;
-       free (pwdpol);
-
-       if (pw_max_life > 0) {
-           if ((st=krb5_dbe_lookup_last_pwd_change(context, entries, &last_pw_changed)) != 0)
-               goto cleanup;
-
-           if ((mask & KDB_PWD_EXPIRE_TIME_ATTR) == 1) {
-               if ((last_pw_changed + pw_max_life) < entries->pw_expiration)
-                   entries->pw_expiration = last_pw_changed + pw_max_life;
-           } else
-               entries->pw_expiration = last_pw_changed + pw_max_life;
-       }
-    }
-
 cleanup:
     ldap_msgfree(result);
 
@@ -406,9 +176,6 @@ cleanup:
     if (filter)
        free (filter);
 
-    if (DN)
-       ldap_memfree (DN);
-
     if (subtree) {
        for (; ntrees; --ntrees)
            if (subtree[ntrees-1])
@@ -416,30 +183,12 @@ cleanup:
        free (subtree);
     }
 
-    if (userinfo_tl_data.tl_data_contents)
-       free(userinfo_tl_data.tl_data_contents);
-
     if (ldap_server_handle)
        krb5_ldap_put_handle_to_pool(ldap_context, ldap_server_handle);
 
     if (user)
        free(user);
 
-    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;
 }
 
@@ -725,9 +474,10 @@ krb5_ldap_put_principal(context, entries, nentries, db_args)
        if ((st=process_db_args(context, db_args, &xargs, optype)) != 0)
            goto cleanup;
 
-       if (entries->mask & KADM5_LOAD && principal_dn == NULL) {
+       if (entries->mask & KADM5_LOAD) {
            int              tree = 0, ntrees = 0, princlen = 0, numlentries = 0;
            char             **subtreelist = NULL, *filter = NULL;
+           krb5_boolean     found_entry = FALSE;
            /*  A load operation is special, will do a mix-in (add krbprinc
             *  attrs to a non-krb object entry) if an object exists with a
             *  matching krbprincipalname attribute so try to find existing
@@ -753,7 +503,7 @@ krb5_ldap_put_principal(context, entries, nentries, db_args)
                goto cleanup;
 
            /* search for entry with matching krbprincipalname attribute */
-           for (tree = 0; principal_dn == NULL && tree < ntrees; ++tree) {
+           for (tree = 0; found_entry == FALSE && tree < ntrees; ++tree) {
                result = NULL;
                LDAP_SEARCH_1(subtreelist[tree], ldap_context->lrparams->search_scope, filter, principal_attributes, IGNORE_STATUS);
                if (st == LDAP_SUCCESS) {
@@ -767,15 +517,18 @@ krb5_ldap_put_principal(context, entries, nentries, db_args)
                            user);
                        goto cleanup;
                    } else if (numlentries == 1) {
-                       ent = ldap_first_entry(ld, result);
-                       if (ent != NULL) {
-                           /* setting principal_dn will cause that entry to be modified further down */
-                           if ((principal_dn = ldap_get_dn(ld, ent)) == NULL) {
-                               ldap_get_option (ld, LDAP_OPT_RESULT_CODE, &st);
-                               st = set_ldap_error (context, st, 0);
-                               ldap_msgfree(result);
-                               free(filter);
-                               goto cleanup;
+                       found_entry = TRUE;
+                       if (principal_dn == NULL) {
+                           ent = ldap_first_entry(ld, result);
+                           if (ent != NULL) {
+                               /* setting principal_dn will cause that entry to be modified further down */
+                               if ((principal_dn = ldap_get_dn(ld, ent)) == NULL) {
+                                   ldap_get_option (ld, LDAP_OPT_RESULT_CODE, &st);
+                                   st = set_ldap_error (context, st, 0);
+                                   ldap_msgfree(result);
+                                   free(filter);
+                                   goto cleanup;
+                               }
                            }
                        }
                    }
@@ -792,7 +545,14 @@ krb5_ldap_put_principal(context, entries, nentries, db_args)
                 * be created.
                 */
            } /* end for (tree = 0; principal_dn == ... */
+
            free(filter);
+
+           if (found_entry == FALSE) {
+               create_standalone_prinicipal = TRUE;
+               standalone_principal_dn = strdup(principal_dn);
+               CHECK_NULL(standalone_principal_dn);
+           }
        } /* end if (entries->mask & KADM5_LOAD && principal_dn == NULL */
 
        /* time to generate the DN information with the help of
@@ -967,10 +727,36 @@ krb5_ldap_put_principal(context, entries, nentries, db_args)
                krb5_set_error_message(context, st, "%s", errbuf);
                goto cleanup;
            }
+            /*
+             * Check the link information. If there is already a link
+             * existing then this operation is not allowed.
+             */
+            {
+                char **linkdns=NULL;
+                int  j=0;
+                                                                                                                             
+                if ((st=krb5_get_linkdn(context, entries, &linkdns)) != 0) {
+                    snprintf(errbuf, sizeof(errbuf),
+                             "Failed getting object references");
+                    krb5_set_error_message(context, st, "%s", errbuf);
+                    goto cleanup;
+                }
+                if (linkdns != NULL) {
+                    st = EINVAL;
+                    snprintf(errbuf, sizeof(errbuf),
+                             "kerberos principal is already linked "
+                             "to a ldap object");
+                    krb5_set_error_message(context, st, "%s", errbuf);
+                    for (j=0; linkdns[j] != NULL; ++j)
+                        free (linkdns[j]);
+                    free (linkdns);
+                    goto cleanup;
+                }
+            }
+
            establish_links = TRUE;
        }
 
-#ifdef  KRBCONF_KDC_MODIFIES_KDB
        if ((entries->last_success)!=0) {
            memset(strval, 0, sizeof(strval));
            if ((strval[0]=getstringtime(entries->last_success)) == NULL)
@@ -997,7 +783,6 @@ krb5_ldap_put_principal(context, entries, nentries, db_args)
            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)
@@ -1320,7 +1105,7 @@ cleanup:
     return(st);
 }
 
-static krb5_error_code
+krb5_error_code
 krb5_read_tkt_policy (context, ldap_context, entries, policy)
     krb5_context                context;
     krb5_ldap_context           *ldap_context;
@@ -1378,7 +1163,7 @@ cleanup:
     return st;
 }
 
-static krb5_error_code
+krb5_error_code
 krb5_decode_krbsecretkey(context, entries, bvalues, userinfo_tl_data)
     krb5_context                context;
     krb5_db_entry               *entries;
index c4b085011071222890f6b08c0060dc648a887e92..ba77b8f23753f20a83171986a0f00aea370840bc 100644 (file)
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  */
+/*
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
 
 #include "ldap_main.h"
 #include "kdb_ldap.h"
 #include "ldap_pwd_policy.h"
 #include "ldap_err.h"
 
-static char *password_policy_attributes[] = { "krbmaxpwdlife", "krbminpwdlife",
+static char *password_policy_attributes[] = { "cn", "krbmaxpwdlife", "krbminpwdlife",
                                              "krbpwdmindiffchars", "krbpwdminlength",
                                              "krbpwdhistorylength", NULL };
 
@@ -176,11 +180,38 @@ cleanup:
 }
 
 krb5_error_code
-krb5_ldap_get_password_policy_from_dn (context, name, policy, cnt)
-    krb5_context                context;
-    char                        *name;
-    osa_policy_ent_t            *policy;
-    int                         *cnt;
+populate_policy(krb5_context context,
+    LDAP *ld,
+    LDAPMessage *ent,
+    char *pol_name,
+    osa_policy_ent_t pol_entry)
+{
+    int st = 0;
+
+    pol_entry->name = strdup(pol_name);
+    CHECK_NULL(pol_entry->name);
+    pol_entry->version = 1;
+
+    krb5_ldap_get_value(ld, ent, "krbmaxpwdlife", &(pol_entry->pw_max_life));
+    krb5_ldap_get_value(ld, ent, "krbminpwdlife", &(pol_entry->pw_min_life));
+    krb5_ldap_get_value(ld, ent, "krbpwdmindiffchars", &(pol_entry->pw_min_classes));
+    krb5_ldap_get_value(ld, ent, "krbpwdminlength", &(pol_entry->pw_min_length));
+    krb5_ldap_get_value(ld, ent, "krbpwdhistorylength", &(pol_entry->pw_history_num));
+
+    /* Get the reference count */
+    st = krb5_ldap_get_reference_count (context, pol_name, "krbPwdPolicyReference",
+           &(pol_entry->policy_refcnt), ld);
+
+cleanup:
+    return st;
+}
+
+krb5_error_code
+krb5_ldap_get_password_policy_from_dn (krb5_context context,
+    char *pol_name,
+    char *pol_dn,
+    osa_policy_ent_t *policy,
+    int *cnt)
 {
     krb5_error_code             st=0, tempst=0;
     LDAP                       *ld=NULL;
@@ -193,9 +224,10 @@ krb5_ldap_get_password_policy_from_dn (context, name, policy, cnt)
     krb5_clear_error_message(context);
 
     /* validate the input parameters */
-    if (name == NULL)
+    if (pol_dn == NULL)
        return EINVAL;
 
+    *policy = NULL;
     SETUP_CONTEXT();
     GET_HANDLE();
 
@@ -207,13 +239,19 @@ krb5_ldap_get_password_policy_from_dn (context, name, policy, cnt)
     }
     memset(*policy, 0, sizeof(osa_policy_ent_rec));
 
-    LDAP_SEARCH(name, LDAP_SCOPE_BASE, "(objectclass=krbPwdPolicy)", password_policy_attributes);
+    LDAP_SEARCH(pol_dn, LDAP_SCOPE_BASE, "(objectclass=krbPwdPolicy)", password_policy_attributes);
     *cnt = 1;
-    (*policy)->name = name;
+#if 0 /************** Begin IFDEF'ed OUT *******************************/
+    (*policy)->name = strdup(name);
+    CHECK_NULL((*policy)->name);
     (*policy)->version = 1;
+#endif /**************** END IFDEF'ed OUT *******************************/
 
     ent=ldap_first_entry(ld, result);
     if (ent != NULL) {
+       if ((st = populate_policy(context, ld, ent, pol_name, *policy)) != 0)
+           goto cleanup;
+#if 0 /************** Begin IFDEF'ed OUT *******************************/
        krb5_ldap_get_value(ld, ent, "krbmaxpwdlife", &((*policy)->pw_max_life));
        krb5_ldap_get_value(ld, ent, "krbminpwdlife", &((*policy)->pw_min_life));
        krb5_ldap_get_value(ld, ent, "krbpwdmindiffchars", &((*policy)->pw_min_classes));
@@ -226,13 +264,14 @@ krb5_ldap_get_password_policy_from_dn (context, name, policy, cnt)
                                            "krbPwdPolicyReference",
                                            &(*policy)->policy_refcnt,
                                            ld);
+#endif /**************** END IFDEF'ed OUT *******************************/
     }
 
 cleanup:
     ldap_msgfree(result);
     if (st != 0) {
        if (*policy != NULL) {
-           free (*policy);
+           krb5_ldap_free_password_policy(context, *policy);
            *policy = NULL;
        }
     }
@@ -264,16 +303,15 @@ krb5_ldap_get_password_policy (context, name, policy, cnt)
        goto cleanup;
     }
 
-    st = krb5_ldap_name_to_policydn (context, name, &policy_dn);
+    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;
+    st = krb5_ldap_get_password_policy_from_dn(context, name, policy_dn, policy, cnt);
 
 cleanup:
+    if (policy_dn != NULL)
+       free (policy_dn);
     return st;
 }
 
@@ -324,7 +362,7 @@ 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 }, *policy=NULL;
+    char                       *policy=NULL;
     krb5_error_code             st=0, tempst=0;
     LDAP                       *ld=NULL;
     LDAPMessage                        *result=NULL, *ent=NULL;
@@ -338,16 +376,12 @@ krb5_ldap_iterate_password_policy(context, match_expr, func, func_arg)
     SETUP_CONTEXT();
     GET_HANDLE();
 
-    entry = (osa_policy_ent_t) malloc(sizeof(osa_policy_ent_rec));
-    CHECK_NULL(entry);
-    memset(entry, 0, sizeof(osa_policy_ent_rec));
-
     if (ldap_context->lrparams->realmdn == NULL) {
        st = EINVAL;
        goto cleanup;
     }
 
-    LDAP_SEARCH(ldap_context->lrparams->realmdn, LDAP_SCOPE_ONELEVEL, "(objectclass=krbpwdpolicy)", attrs);
+    LDAP_SEARCH(ldap_context->lrparams->realmdn, LDAP_SCOPE_ONELEVEL, "(objectclass=krbpwdpolicy)", password_policy_attributes);
     for (ent=ldap_first_entry(ld, result); ent != NULL; ent=ldap_next_entry(ld, ent)) {
        krb5_boolean attr_present;
 
@@ -356,9 +390,34 @@ krb5_ldap_iterate_password_policy(context, match_expr, func, func_arg)
            goto cleanup;
        if (attr_present == FALSE)
            continue;
+
+       entry = (osa_policy_ent_t) malloc(sizeof(osa_policy_ent_rec));
+       CHECK_NULL(entry);
+       memset(entry, 0, sizeof(osa_policy_ent_rec));
+       if ((st = populate_policy(context, ld, ent, policy, entry)) != 0)
+           goto cleanup;
+#if 0 /************** Begin IFDEF'ed OUT *******************************/
        entry->name = policy;
+       entry->version = 1;
+
+       krb5_ldap_get_value(ld, ent, "krbmaxpwdlife", &(entry->pw_max_life));
+       krb5_ldap_get_value(ld, ent, "krbminpwdlife", &(entry->pw_min_life));
+       krb5_ldap_get_value(ld, ent, "krbpwdmindiffchars", &(entry->pw_min_classes));
+       krb5_ldap_get_value(ld, ent, "krbpwdminlength", &(entry->pw_min_length));
+       krb5_ldap_get_value(ld, ent, "krbpwdhistorylength", &(entry->pw_history_num));
+
+       /* Get the reference count */
+       st = krb5_ldap_get_reference_count (context,
+                                           policy,
+                                           "krbPwdPolicyReference",
+                                           &(entry->policy_refcnt),
+                                           ld);
+#endif /**************** END IFDEF'ed OUT *******************************/
+
        (*func)(func_arg, entry);
-       ldap_memfree(policy);
+       /* XXX this will free policy so don't free it */
+       krb5_ldap_free_password_policy(context, entry);
+       entry = NULL;
     }
     ldap_msgfree(result);
 
@@ -375,7 +434,10 @@ krb5_ldap_free_password_policy (context, entry)
     krb5_context                context;
     osa_policy_ent_t            entry;
 {
-    if (entry)
+    if (entry) {
+       if (entry->name)
+           free(entry->name);
        free(entry);
+    }
     return;
 }
index dee22cccd552e7262e23b9cec14e94cda14b8c34..3013838eab389ec44f50bd151b8d2cbbc53266cf 100644 (file)
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+/*
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
 #include "ldap_main.h"
 #include "ldap_realm.h"
 #include "ldap_principal.h"
+#include "ldap_pwd_policy.h"
 #include "ldap_err.h"
 
 #define END_OF_LIST -1