svn rev #24604: trunk/src/ kadmin/cli/ lib/kadm5/srv/ tests/

ghudson@MIT.EDU ghudson at MIT.EDU
Tue Jan 25 00:20:07 EST 2011


http://src.mit.edu/fisheye/changelog/krb5/?cs=24604
Commit By: ghudson
Log Message:
ticket: 6323

Make principal renaming work in libkadm5srv by converting to explicit
salts as necessary.  Add a principal rename command to the client.
(The RPC infrastructure was already present.)

Adapted from patches submitted by mdw at umich.edu and lha at apple.com.



Changed Files:
U   trunk/src/kadmin/cli/kadmin.c
U   trunk/src/kadmin/cli/kadmin.h
U   trunk/src/kadmin/cli/kadmin_ct.ct
U   trunk/src/lib/kadm5/srv/svr_principal.c
U   trunk/src/tests/Makefile.in
A   trunk/src/tests/t_renprinc.py
Modified: trunk/src/kadmin/cli/kadmin.c
===================================================================
--- trunk/src/kadmin/cli/kadmin.c	2011-01-25 00:23:48 UTC (rev 24603)
+++ trunk/src/kadmin/cli/kadmin.c	2011-01-25 05:20:07 UTC (rev 24604)
@@ -645,6 +645,69 @@
     free(canon);
 }
 
+void
+kadmin_renameprinc(int argc, char *argv[])
+{
+    kadm5_ret_t retval;
+    krb5_principal oprinc = NULL, nprinc = NULL;
+    char *ocanon = NULL, *ncanon = NULL;
+    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");
+        goto cleanup;
+    }
+    retval = kadmin_parse_name(argv[argc - 1], &nprinc);
+    if (retval) {
+        com_err("rename_principal", retval,
+                "while parsing new principal name");
+        goto cleanup;
+    }
+    retval = krb5_unparse_name(context, oprinc, &ocanon);
+    if (retval) {
+        com_err("rename_principal", retval,
+                "while canonicalizing old principal");
+        goto cleanup;
+    }
+    retval = krb5_unparse_name(context, nprinc, &ncanon);
+    if (retval) {
+        com_err("rename_principal", retval,
+                "while canonicalizing new principal");
+        goto cleanup;
+    }
+    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);
+            goto cleanup;
+        }
+    }
+    retval = kadm5_rename_principal(handle, oprinc, nprinc);
+    if (retval) {
+        com_err("rename_principal", retval,
+                "while renaming principal \"%s\" to \"%s\"", ocanon, ncanon);
+        goto cleanup;
+    }
+    printf("Principal \"%s\" renamed to \"%s\".\n"
+           "Make sure that you have removed the old principal from all ACLs "
+           "before reusing.\n", ocanon, ncanon);
+
+cleanup:
+    krb5_free_principal(context, nprinc);
+    krb5_free_principal(context, oprinc);
+    free(ncanon);
+    free(ocanon);
+}
+
 static void
 cpw_usage(const char *str)
 {

Modified: trunk/src/kadmin/cli/kadmin.h
===================================================================
--- trunk/src/kadmin/cli/kadmin.h	2011-01-25 00:23:48 UTC (rev 24603)
+++ trunk/src/kadmin/cli/kadmin.h	2011-01-25 05:20:07 UTC (rev 24604)
@@ -37,6 +37,7 @@
 extern void kadmin_lock(int argc, char *argv[]);
 extern void kadmin_unlock(int argc, char *argv[]);
 extern void kadmin_delprinc(int argc, char *argv[]);
+extern void kadmin_renameprinc(int argc, char *argv[]);
 extern void kadmin_cpw(int argc, char *argv[]);
 extern void kadmin_addprinc(int argc, char *argv[]);
 extern void kadmin_modprinc(int argc, char *argv[]);

Modified: trunk/src/kadmin/cli/kadmin_ct.ct
===================================================================
--- trunk/src/kadmin/cli/kadmin_ct.ct	2011-01-25 00:23:48 UTC (rev 24603)
+++ trunk/src/kadmin/cli/kadmin_ct.ct	2011-01-25 05:20:07 UTC (rev 24604)
@@ -35,6 +35,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;
 

Modified: trunk/src/lib/kadm5/srv/svr_principal.c
===================================================================
--- trunk/src/lib/kadm5/srv/svr_principal.c	2011-01-25 00:23:48 UTC (rev 24603)
+++ trunk/src/lib/kadm5/srv/svr_principal.c	2011-01-25 05:20:07 UTC (rev 24604)
@@ -4,21 +4,14 @@
  *
  * $Header$
  */
-#include <assert.h>
-#include        <sys/types.h>
+#include "k5-int.h"
 #include        <sys/time.h>
-#include        <errno.h>
 #include        <kadm5/admin.h>
 #include        <kdb.h>
-#include        <stdio.h>
-#include        <string.h>
 #include        "server_internal.h"
-#include        <stdarg.h>
-#include        <stdlib.h>
 #ifdef USE_PASSWORD_SERVER
 #include        <sys/wait.h>
 #include        <signal.h>
-
 #endif
 
 #include <krb5/kadm5_hook_plugin.h>
@@ -730,10 +723,12 @@
 kadm5_rename_principal(void *server_handle,
                        krb5_principal source, krb5_principal target)
 {
-    krb5_db_entry       *kdb;
-    osa_princ_ent_rec   adb;
-    int                 ret, i;
+    krb5_db_entry *kdb;
+    osa_princ_ent_rec adb;
+    int ret, i;
     kadm5_server_handle_t handle = server_handle;
+    krb5_int32 stype;
+    krb5_data sdata;
 
     CHECK_HANDLE(server_handle);
 
@@ -750,14 +745,53 @@
     if ((ret = kdb_get_entry(handle, source, &kdb, &adb)))
         return ret;
 
-    /* this is kinda gross, but unavoidable */
+    /* Transform salts as necessary. */
+    for (i = 0; i < kdb->n_key_data; i++) {
+        sdata = empty_data();
+        if (kdb->key_data[i].key_data_ver > 1)
+            stype = kdb->key_data[i].key_data_type[1];
+        else
+            stype = KRB5_KDB_SALTTYPE_NORMAL;
 
-    for (i=0; i<kdb->n_key_data; i++) {
-        if ((kdb->key_data[i].key_data_ver == 1) ||
-            (kdb->key_data[i].key_data_type[1] == KRB5_KDB_SALTTYPE_NORMAL)) {
+        /* For salt types which compute a salt from the principal name, compute
+         * the salt based on the old principal name into sdata. */
+        switch (stype) {
+        case KRB5_KDB_SALTTYPE_NORMAL:
+            ret = krb5_principal2salt(handle->context, kdb->princ, &sdata);
+            if (ret)
+                goto done;
+            break;
+        case KRB5_KDB_SALTTYPE_NOREALM:
+            krb5_principal2salt_norealm(handle->context, kdb->princ, &sdata);
+            if (ret)
+                goto done;
+            break;
+        case KRB5_KDB_SALTTYPE_ONLYREALM:
+            ret = alloc_data(&sdata, kdb->princ->realm.length);
+            if (ret)
+                goto done;
+            memcpy(sdata.data, kdb->princ->realm.data,
+                   kdb->princ->realm.length);
+            break;
+        case KRB5_KDB_SALTTYPE_SPECIAL:
+        case KRB5_KDB_SALTTYPE_V4:
+        case KRB5_KDB_SALTTYPE_AFS3:
+            /* Don't compute a new salt.  Assume the realm doesn't change for
+             * V4 and AFS3. */
+            break;
+        default:
+            /* We don't recognize this salt type.  Be conservative. */
             ret = KADM5_NO_RENAME_SALT;
             goto done;
         }
+        /* If we computed a salt, store it as an explicit salt. */
+        if (sdata.data != NULL) {
+            kdb->key_data[i].key_data_type[1] = KRB5_KDB_SALTTYPE_SPECIAL;
+            free(kdb->key_data[i].key_data_contents[1]);
+            kdb->key_data[i].key_data_contents[1] = (krb5_octet *)sdata.data;
+            kdb->key_data[i].key_data_length[1] = sdata.length;
+            kdb->key_data[i].key_data_ver = 2;
+        }
     }
 
     kadm5_free_principal(handle->context, kdb->princ);

Modified: trunk/src/tests/Makefile.in
===================================================================
--- trunk/src/tests/Makefile.in	2011-01-25 00:23:48 UTC (rev 24603)
+++ trunk/src/tests/Makefile.in	2011-01-25 05:20:07 UTC (rev 24604)
@@ -67,6 +67,7 @@
 	$(RUNPYTEST) $(srcdir)/t_kadm5_hook.py $(PYTESTFLAGS)
 	$(RUNPYTEST) $(srcdir)/t_keyrollover.py $(PYTESTFLAGS)
 	$(RUNPYTEST) $(srcdir)/t_renew.py $(PYTESTFLAGS)
+	$(RUNPYTEST) $(srcdir)/t_renprinc.py $(PYTESTFLAGS)
 
 clean::
 	$(RM) kdc.conf

Added: trunk/src/tests/t_renprinc.py
===================================================================
--- trunk/src/tests/t_renprinc.py	                        (rev 0)
+++ trunk/src/tests/t_renprinc.py	2011-01-25 05:20:07 UTC (rev 24604)
@@ -0,0 +1,46 @@
+# Copyright (C) 2011 by the Massachusetts Institute of Technology.
+# All rights reserved.
+
+# Export of this software from the United States of America may
+#   require a specific license from the United States Government.
+#   It is the responsibility of any person or organization contemplating
+#   export to obtain such a license before exporting.
+#
+# WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+# distribute this software and its documentation for any purpose and
+# without fee is hereby granted, provided that the above copyright
+# notice appear in all copies and that both that copyright notice and
+# this permission notice appear in supporting documentation, and that
+# the name of M.I.T. not be used in advertising or publicity pertaining
+# to distribution of the software without specific, written prior
+# permission.  Furthermore if you modify this software you must label
+# your software as modified software and not distribute it in such a
+# fashion that it might be confused with the original M.I.T. software.
+# M.I.T. makes no representations about the suitability of
+# this software for any purpose.  It is provided "as is" without express
+# or implied warranty.
+
+#!/usr/bin/python
+from k5test import *
+
+enctype = "aes128-cts"
+
+realm = K5Realm(create_host=False, create_user=False, start_kadmind=False)
+salttypes = ('normal', 'v4', 'norealm', 'onlyrealm')
+
+# For a variety of salt types, test that we can rename a principal and
+# still get tickets with the same password.
+for st in salttypes:
+    realm.run_kadminl('addprinc -e %s:%s -pw %s %s' %
+                      (enctype, st, password(st), st))
+    realm.kinit(st, password(st))
+    newprinc = 'new' + st
+    realm.run_kadminl('renprinc -force %s %s' % (st, newprinc))
+    realm.kinit(newprinc, password(st))
+
+# Rename the normal salt again to test renaming a principal with
+# special salt type (which it will have after the first rename).
+realm.run_kadminl('renprinc -force newnormal newnormal2')
+realm.kinit('newnormal2', password('normal'))
+
+success('Principal renaming tests.')




More information about the cvs-krb5 mailing list