Various wrote:
> To: "Christopher P. Lindsey" <[EMAIL PROTECTED]>
> Cc: [EMAIL PROTECTED]
> Subject: Re: Can we rename a principal yet?
> References: <[EMAIL PROTECTED]>
> From: Tom Yu <[EMAIL PROTECTED]>
> Date: 01 Aug 2001 01:56:38 -0400
> In-Reply-To: "Christopher P. Lindsey"'s message of "Wed, 1 Aug 2001 00:32:33 -0500"
> Message-ID: <[EMAIL PROTECTED]>
> Lines: 31
> X-Mailer: Gnus v5.7/Emacs 20.7
> 
> >>>>> "lindsey" == Christopher P Lindsey <[EMAIL PROTECTED]> writes:
> 
> lindsey> Yes, I know it's a FAQ, and yes, I know the key is (usually)
> lindsey> salted with the entire principal name.
> 
> This still isn't quite possible yet through the kadm5 API; it is
> tentatively on our todo list for the next release.

It may not matter what you used for the salt.  It's quite feasible to
support kerberos principal renaming, even when the principal was used
in the old salt.  The trick is that when renaming principals, you have
to diddle the salt - there's a "KRB5_KDB_SALTTYPE_SPECIAL" which allows
you to specify an arbitrary salt data in the kdc database, and this
allows you to use whatever salt was associated with the old principal
name and keep on using it, even with a different princpal name.  This
trick won't always work - it depends on what you had for old salt
types.

Here's some experimental patches to do at least some of the grunt
work.  I do have these particular patches working in an experimental
version, so if I've left anything out, let me know.  We use similar but
not identical patches in production at umich.edu, so any weirdnesses in
this set is just me (and I can dig up what we actually use if there's
any interest in that.)  Sounds like Douglas E. Engert
<[EMAIL PROTECTED]> has similar patches.  Maybe his are better.  You may
need to extra torque to get this wedged into your source depending on
how much it's mutated since krb-current as of 19990817.  You'll
probably want to ignore the lines that say "/* experimental */, and
you'll probably want to change KRB5_WILD back to -1 -- those were
unrelated experiments of which you probably aren't interested.

I think there was also something unpleasant involving DES3 and this
stuff, so if you use DES3, you'll have to figure out what it was.  (I
think the trick was remembering that DES3 doesn't conflict with DES --
I'm not sure there's a pretty way to tell the difference between a DES3
family key and a DES family key.)

There was some discussion later about salt types and preauth and all that.
The preauth code is overloaded with the salt logic, which was not
well documented (in fact, is there *any* real documentation on it?)
To make matters worse, there were at least 2 different client side paths
with similar, but not identical functionality, and I recall there
were some other nasties, but not exactly what they were.  I do think the KDC
always supplies padata salt data on the key actually used when
it returns a ticket, even if preauthentication is not used.  I
think it also always supplies ETYPE_INFO padata which describes
all salt types for the principal in the db.
        [ Looks to me like lib/krb5/krb/preauth2.c didn't contain
        logic to handle KRB5_PADATA_ETYPE_INFO in krb5-current
        of 19990817. ]

                                -Marcus Watts
                                UM ITCS Umich Systems Group

Index: kadmin/cli/kadmin.M
===================================================================
RCS file: /afs/umich.edu/group/itd/build/mdw/krb5.cvs/krb5/src/kadmin/cli/kadmin.M,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- kadmin/cli/kadmin.M 1996/12/06 03:24:09     1.1.1.1
+++ kadmin/cli/kadmin.M 1998/12/17 04:17:29     1.2
@@ -363,7 +363,7 @@
 kadmin:
 .TP
 ERRORS:
-KADM5_AUTH_DELETE (reequires "delete" privilege)
+KADM5_AUTH_DELETE (requires "delete" privilege)
 KADM5_UNK_PRINC (principal does not exist)
 .RE
 .fi
@@ -396,6 +396,13 @@
 .I old
 to
 .IR new .
+The principal may have one or more keys that have a salt type that
+require the use of the principal's name when converting the password
+to the key.  Some versions of kadmind
+.IR kadmind (8)
+can convert up to one such key to the \fBspecial\fP salt type.
+Other versions may reject all attempts to rename principals
+with these salt types.
 Prompts for confirmation, unless the
 .B \-force
 option is given.  Requires both the
@@ -424,6 +431,7 @@
 KADM5_AUTH_DELETE (requires "delete" privilege)
 KADM5_UNK_PRINC (source principal does not exist)
 KADM5_DUP (target principal already exists)
+KADM5_NO_RENAME_SALT (One or more salt types uses the principal's name)
 .RE
 .fi
 .TP
Index: kadmin/cli/kadmin.c
===================================================================
RCS file: /afs/umich.edu/group/itd/build/mdw/krb5.cvs/krb5/src/kadmin/cli/kadmin.c,v
retrieving revision 1.1.1.2
retrieving revision 1.3
diff -u -r1.1.1.2 -r1.3
--- kadmin/cli/kadmin.c 1998/06/04 07:04:07     1.1.1.2
+++ kadmin/cli/kadmin.c 1998/12/17 04:17:30     1.3
@@ -505,6 +505,76 @@
     return;
 }
 
+void kadmin_renameprinc(argc, argv)
+    int argc;
+    char *argv[];
+{
+    kadm5_ret_t retval;
+    krb5_principal oprinc, nprinc;
+    char *ocanon, *ncanon;
+    char reply[5];
+    
+    if (! (argc == 3 ||
+          (argc == 4 && !strcmp("-force", argv[1])))) {
+       fprintf(stderr, "usage: rename_principal [-force] old_principal 
+new_principal\n");
+       return;
+    }
+    retval = kadmin_parse_name(argv[argc - 2], &oprinc);
+    if (retval) {
+       com_err("rename_principal", retval, "while parsing old principal name");
+       return;
+    }
+    retval = kadmin_parse_name(argv[argc - 1], &nprinc);
+    if (retval) {
+       com_err("rename_principal", retval, "while parsing new principal name");
+       krb5_free_principal(context, oprinc);
+       return;
+    }
+    retval = krb5_unparse_name(context, oprinc, &ocanon);
+    if (retval) {
+       com_err("rename_principal", retval,
+               "while canonicalizing old principal");
+       krb5_free_principal(context, nprinc);
+       krb5_free_principal(context, oprinc);
+       return;
+    }
+    retval = krb5_unparse_name(context, nprinc, &ncanon);
+    if (retval) {
+       com_err("rename_principal", retval,
+               "while canonicalizing new principal");
+       free(ocanon);
+       krb5_free_principal(context, nprinc);
+       krb5_free_principal(context, oprinc);
+       return;
+    }
+    if (argc == 3) {
+       printf("Are you sure you want to rename the principal \"%s\" to \"%s\"? 
+(yes/no): ",
+           ocanon, ncanon);
+       fgets(reply, sizeof (reply), stdin);
+       if (strcmp("yes\n", reply)) {
+           fprintf(stderr, "Principal \"%s\" not renamed\n", ocanon);
+           free(ncanon);
+           free(ocanon);
+           krb5_free_principal(context, nprinc);
+           krb5_free_principal(context, oprinc);
+           return;
+       }
+    }
+    retval = kadm5_rename_principal(handle, oprinc, nprinc);
+    krb5_free_principal(context, nprinc);
+    krb5_free_principal(context, oprinc);
+    if (retval) {
+       com_err("rename_principal", retval,
+               "while renaming principal \"%s\" to \"%s\"", ocanon, ncanon); 
+free(ncanon);
+       free(ocanon);
+       return;
+    }
+    printf("Principal \"%s\" renamed to \"%s\".\nMake sure that you have removed this 
+principal from all ACLs before reusing.\n", ocanon, ncanon);
+    free(ncanon);
+    free(ocanon);
+    return;
+}
+
 void kadmin_cpw(argc, argv)
     int argc;
     char *argv[];
Index: kadmin/cli/kadmin_ct.ct
===================================================================
RCS file: 
/afs/umich.edu/group/itd/build/mdw/krb5.cvs/krb5/src/kadmin/cli/kadmin_ct.ct,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- kadmin/cli/kadmin_ct.ct     1996/08/12 15:48:12     1.1.1.1
+++ kadmin/cli/kadmin_ct.ct     1998/12/17 04:17:29     1.2
@@ -32,6 +32,9 @@
 request kadmin_modprinc, "Modify principal",
        modify_principal, modprinc;
 
+request kadmin_renameprinc, "Rename principal",
+       rename_principal, renprinc;
+
 request kadmin_cpw, "Change password",
        change_password, cpw;
 
Index: lib/kadm5/srv/svr_principal.c
===================================================================
RCS file: 
/afs/umich.edu/group/itd/build/mdw/krb5.cvs/krb5/src/lib/kadm5/srv/svr_principal.c,v
retrieving revision 1.1.1.7
retrieving revision 1.5
diff -u -r1.1.1.7 -r1.5
--- lib/kadm5/srv/svr_principal.c       1999/02/01 08:04:03     1.1.1.7
+++ lib/kadm5/srv/svr_principal.c       1999/08/19 10:20:12     1.5
@@ -600,6 +600,39 @@
     if ((ret = kdb_get_entry(handle, source, &kdb, &adb)))
        return ret;
 
+#if 1
+    /* this is real gross */
+
+    ret = 0;
+    for (i=0; i<kdb.n_key_data; i++) {
+       if (kdb.key_data[i].key_data_ver == 2)
+           switch(kdb.key_data[i].key_data_type[1]) {
+           /* these salt types depend on the principal's name */
+#ifdef KRB5_KDB_SALTTYPE_GREX                  /* experimental */
+           case KRB5_KDB_SALTTYPE_GREX:        /* experimental */
+#endif                                         /* experimental */
+           case KRB5_KDB_SALTTYPE_SPECIAL:
+           case KRB5_KDB_SALTTYPE_NORMAL:
+           case KRB5_KDB_SALTTYPE_NOREALM:
+               if (ret) goto done;
+               kdb.key_data[i].key_data_type[1] = KRB5_KDB_SALTTYPE_SPECIAL;
+               ret = KADM5_NO_RENAME_SALT;
+               break;
+           }
+       else if (kdb.n_key_data != handle->params.num_keysalts)
+           continue;   /* presumably a random key; no salt */
+       else {
+           krb5_data sdata;
+           if (ret) goto done;
+           krb5_principal2salt(handle->context, kdb.princ, &sdata);
+           kdb.key_data[i].key_data_type[1] = KRB5_KDB_SALTTYPE_SPECIAL;
+           kdb.key_data[i].key_data_contents[1] = sdata.data;
+           kdb.key_data[i].key_data_length[1] = sdata.length;
+           kdb.key_data[i].key_data_ver = 2;
+           ret = KADM5_NO_RENAME_SALT;
+       }
+    }
+#else
     /* this is kinda gross, but unavoidable */
 
     for (i=0; i<kdb.n_key_data; i++) {
@@ -609,6 +642,7 @@
            goto done;
        }
     }
+#endif
 
     krb5_free_principal(handle->context, kdb.princ);
     if (ret = krb5_copy_principal(handle->context, target, &kdb.princ)) {
@@ -1270,7 +1304,7 @@
              /* Version 1 clients will expect to see a DES_CRC enctype. */
              if (ret = krb5_dbe_find_enctype(handle->context, &kdb,
                                              ENCTYPE_DES_CBC_CRC,
-                                             -1, -1, &key_data))
+                                             KRB5_WILD, KRB5_WILD, &key_data))
                   goto done;
 
              if (ret = decrypt_key_data(handle->context, 1, key_data,
@@ -1602,9 +1636,9 @@
  *
  *     server_handle   (r) kadm5 handle
  *     entry           (r) principal retrieved with kadm5_get_principal
- *     ktype           (r) enctype to search for, or -1 to ignore
- *     stype           (r) salt type to search for, or -1 to ignore
- *     kvno            (r) kvno to search for, -1 for max, 0 for max
+ *     ktype           (r) enctype to search for, or KRB5_WILD to ignore
+ *     stype           (r) salt type to search for, or KRB5_WILD to ignore
+ *     kvno            (r) kvno to search for, KRB5_WILD for max, 0 for max
  *                     only if it also matches ktype and stype
  *     keyblock        (w) keyblock to fill in
  *     keysalt         (w) keysalt to fill in, or NULL
@@ -1617,8 +1651,8 @@
  * it with the master key, and return the key in keyblock, the salt
  * in salttype, and the key version number in kvno.
  *
- * If ktype or stype is -1, it is ignored for the search.  If kvno is
- * -1, ktype and stype are ignored and the key with the max kvno is
+ * If ktype or stype is KRB5_WILD, it is ignored for the search.  If kvno is
+ * KRB5_WILD, ktype and stype are ignored and the key with the max kvno is
  * returned.  If kvno is 0, only the key with the max kvno is returned
  * and only if it matches the ktype and stype; otherwise, ENOENT is
  * returned.

Reply via email to