Add LDAP back end support for canonical name attribute
authorGreg Hudson <ghudson@mit.edu>
Sun, 15 Mar 2009 04:21:12 +0000 (04:21 +0000)
committerGreg Hudson <ghudson@mit.edu>
Sun, 15 Mar 2009 04:21:12 +0000 (04:21 +0000)
Add a krbCanonicalName attribute to the schema.  When looking up a
principal, if the canonical name is set and does not match the
requested name, then return the entry only if canonicalization was
requested, and use the entry's canonical name.

ticket: 6420
tags: pullup
target_version: 1.7

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@22090 dc483132-0cff-0310-8789-dd5450dbe970

src/plugins/kdb/ldap/libkdb_ldap/kerberos.ldif
src/plugins/kdb/ldap/libkdb_ldap/kerberos.schema
src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c
src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c

index 4b4f70a1a36e9164e12d85b0c62027042eabc3c2..0bbdcf878306aef73a18eb486967c71c0bd92b3d 100644 (file)
 #                    specific syntax definitions
 #                 Kerberos Object Class(6) class# version#
 #                    specific class definitions
+#
+#    iso(1)
+#      member-body(2)
+#        United States(840)
+#          mit (113554)
+#            infosys(1)
+#              ldap(4)
+#                attributeTypes(1)
+#                  Kerberos(6)
 
 ########################################################################
 
@@ -40,6 +49,21 @@ attributetypes: ( 2.16.840.1.113719.1.301.4.1.1
                 SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
 
 
+##### If there are multiple krbPrincipalName values for an entry, this
+##### is the canonical principal name in the RFC 1964 specified
+##### format.  (If this attribute does not exist, then all
+##### krbPrincipalName values are treated as canonical.)
+
+dn: cn=schema
+changetype: modify
+add: attributetypes
+attributetypes: ( 1.2.840.113554.1.4.1.6.1
+                NAME 'krbCanonicalName'
+                EQUALITY caseExactIA5Match
+                SUBSTR caseExactSubstringsMatch
+                SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+                SINGLE-VALUE)
+
 ##### This specifies the type of the principal, the types could be any of
 ##### the types mentioned in section 6.2 of RFC 4120
 
@@ -685,7 +709,7 @@ add: objectclasses
 objectClasses: ( 2.16.840.1.113719.1.301.6.8.1
                 NAME 'krbPrincipalAux'
                 AUXILIARY
-                MAY ( krbPrincipalName $ krbUPEnabled $ krbPrincipalKey $ krbTicketPolicyReference $ krbPrincipalExpiration $ krbPasswordExpiration $ krbPwdPolicyReference $ krbPrincipalType $ krbPwdHistory $ krbLastPwdChange $ krbPrincipalAliases $ krbLastSuccessfulAuth $ krbLastFailedAuth $ krbLoginFailedCount $ krbExtraData ) )
+                MAY ( krbPrincipalName $ krbCanonicalName $ krbUPEnabled $ krbPrincipalKey $ krbTicketPolicyReference $ krbPrincipalExpiration $ krbPasswordExpiration $ krbPwdPolicyReference $ krbPrincipalType $ krbPwdHistory $ krbLastPwdChange $ krbPrincipalAliases $ krbLastSuccessfulAuth $ krbLastFailedAuth $ krbLoginFailedCount $ krbExtraData ) )
 
 
 ###### This class is used to create additional principals and stand alone principals.
index 851c23a92a9492138137fe59a0c187755067a19b..9352cf1e46e4dadabc324f7c5d6b0e2fe94d57c5 100644 (file)
 #                    specific syntax definitions
 #                 Kerberos Object Class(6) class# version#
 #                    specific class definitions
+#
+#    iso(1)
+#      member-body(2)
+#        United States(840)
+#          mit (113554)
+#            infosys(1)
+#              ldap(4)
+#                attributeTypes(1)
+#                  Kerberos(6)
 
 ########################################################################
 
@@ -36,6 +45,17 @@ attributetype ( 2.16.840.1.113719.1.301.4.1.1
                SUBSTR caseExactSubstringsMatch
                 SYNTAX 1.3.6.1.4.1.1466.115.121.1.26)
 
+##### If there are multiple krbPrincipalName values for an entry, this
+##### is the canonical principal name in the RFC 1964 specified
+##### format.  (If this attribute does not exist, then all
+##### krbPrincipalName values are treated as canonical.)
+
+attributetype ( 1.2.840.113554.1.4.1.6.1
+                NAME 'krbCanonicalName'
+                EQUALITY caseExactIA5Match
+                SUBSTR caseExactSubstringsMatch
+                SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+                SINGLE-VALUE)
 
 ##### This specifies the type of the principal, the types could be any of
 ##### the types mentioned in section 6.2 of RFC 4120
@@ -422,7 +442,7 @@ attributetype ( 2.16.840.1.113719.1.301.4.46.1
                 SYNTAX 1.3.6.1.4.1.1466.115.121.1.40)
 
 
-##### This stores the alternate principal names for the principal in the RFC 1961 specified format
+##### This stores the alternate principal names for the principal in the RFC 1964 specified format
 
 attributetype ( 2.16.840.1.113719.1.301.4.47.1
                 NAME 'krbPrincipalAliases'
@@ -556,7 +576,7 @@ objectclass ( 2.16.840.1.113719.1.301.6.8.1
                 NAME 'krbPrincipalAux'
                SUP top
                 AUXILIARY
-                MAY ( krbPrincipalName $ krbUPEnabled $ krbPrincipalKey $ krbTicketPolicyReference $ krbPrincipalExpiration $ krbPasswordExpiration $ krbPwdPolicyReference $ krbPrincipalType $ krbPwdHistory $ krbLastPwdChange $ krbPrincipalAliases $ krbLastSuccessfulAuth $ krbLastFailedAuth $ krbLoginFailedCount $ krbExtraData ) )
+                MAY ( krbPrincipalName $ krbCanonicalName $ krbUPEnabled $ krbPrincipalKey $ krbTicketPolicyReference $ krbPrincipalExpiration $ krbPasswordExpiration $ krbPwdPolicyReference $ krbPrincipalType $ krbPwdHistory $ krbLastPwdChange $ krbPrincipalAliases $ krbLastSuccessfulAuth $ krbLastFailedAuth $ krbLoginFailedCount $ krbExtraData ) )
 
 
 ###### This class is used to create additional principals and stand alone principals.
index 6625570efc9825386d24f8dd2cbe359113b0fbbf..8b3c7a14a3dc3db1497b6d2dce599eb9477abb4e 100644 (file)
@@ -40,6 +40,7 @@
 
 struct timeval timelimit = {300, 0};  /* 5 minutes */
 char     *principal_attributes[] = { "krbprincipalname",
+                                    "krbcanonicalname",
                                     "objectclass",
                                     "krbprincipalkey",
                                     "krbmaxrenewableage",
index e52a61897f637d85cf1e60d8af1436f1fcb04027..14d029c452b5ba3f567306fdda65fd72273987e6 100644 (file)
@@ -85,12 +85,13 @@ krb5_ldap_get_principal(context, searchfor, flags, entries, nentries, more)
     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;
+    char                        **values=NULL, *cname=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             cprinc=NULL;
 
     /* Clear the global error string */
     krb5_clear_error_message(context);
@@ -145,7 +146,7 @@ krb5_ldap_get_principal(context, searchfor, flags, entries, nentries, more)
                 * NOTE: a principalname k* in ldap server will return all the principals starting with a k
                 */
                for (i=0; values[i] != NULL; ++i) {
-                   if (strcasecmp(values[i], user) == 0) {
+                   if (strcmp(values[i], user) == 0) {
                        *nentries = 1;
                        break;
                    }
@@ -156,8 +157,27 @@ krb5_ldap_get_principal(context, searchfor, flags, entries, nentries, more)
                    continue;
            }
 
-           if ((st = populate_krb5_db_entry(context, ldap_context, ld, ent, searchfor,
-                       entries)) != 0)
+           if ((values=ldap_get_values(ld, ent, "krbcanonicalname")) != NULL) {
+               if (values[0] && strcmp(values[0], user) != 0) {
+                   /* We matched an alias, not the canonical name. */
+                   if (flags & KRB5_KDB_FLAG_CANONICALIZE) {
+                       st = krb5_ldap_parse_principal_name(values[0], &cname);
+                       if (st != 0)
+                           goto cleanup;
+                       st = krb5_parse_name(context, cname, &cprinc);
+                       if (st != 0)
+                           goto cleanup;
+                   } else /* No canonicalization, so don't return aliases. */
+                       *nentries = 0;
+               }
+               ldap_value_free(values);
+               if (*nentries == 0)
+                   continue;
+           }
+
+           if ((st = populate_krb5_db_entry(context, ldap_context, ld, ent,
+                                            cprinc ? cprinc : searchfor,
+                                            entries)) != 0)
                goto cleanup;
        }
        ldap_msgfree(result);
@@ -190,6 +210,12 @@ cleanup:
     if (user)
        free(user);
 
+    if (cname)
+       free(cname);
+
+    if (cprinc)
+       krb5_free_principal(context, cprinc);
+
     return st;
 }