aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Hudson <ghudson@mit.edu>2009-09-21 18:40:02 +0000
committerGreg Hudson <ghudson@mit.edu>2009-09-21 18:40:02 +0000
commitf07bca9fc94a5cf2e3c0f58226c7973a4b86b7a9 (patch)
treed025c8c46724b63e7e92d85ecf290c0f4cbcf7ac
parentf36a5ba4e2fd034d9f261b1b4faaa28e7c7e46e7 (diff)
downloadkrb5-f07bca9fc94a5cf2e3c0f58226c7973a4b86b7a9.zip
krb5-f07bca9fc94a5cf2e3c0f58226c7973a4b86b7a9.tar.gz
krb5-f07bca9fc94a5cf2e3c0f58226c7973a4b86b7a9.tar.bz2
Improve the mechanism used for addprinc -randkey. In the kadmin
server, if the password is null when creating a principal, treat that as a request for a random key. In the kadmin client, try using the new method for random key creation and then fall back to the old one. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@22782 dc483132-0cff-0310-8789-dd5450dbe970
-rw-r--r--src/kadmin/cli/kadmin.c104
-rw-r--r--src/lib/kadm5/srv/svr_principal.c35
-rw-r--r--src/lib/kadm5/unit-test/api.2/crte-principal.exp2
3 files changed, 85 insertions, 56 deletions
diff --git a/src/kadmin/cli/kadmin.c b/src/kadmin/cli/kadmin.c
index e57d497..d4bb2bf 100644
--- a/src/kadmin/cli/kadmin.c
+++ b/src/kadmin/cli/kadmin.c
@@ -207,6 +207,29 @@ static void extended_com_err_fn (const char *myprog, errcode_t code,
fprintf (stderr, "\n");
}
+/* Create a principal using the oldest appropriate kadm5 API. */
+static krb5_error_code
+create_princ(kadm5_principal_ent_rec *princ, long mask, int n_ks,
+ krb5_key_salt_tuple *ks, char *pass)
+{
+ if (ks)
+ return kadm5_create_principal_3(handle, princ, mask, n_ks, ks, pass);
+ else
+ return kadm5_create_principal(handle, princ, mask, pass);
+}
+
+/* Randomize a principal's password using the oldest appropriate kadm5 API. */
+static krb5_error_code
+randkey_princ(krb5_principal princ, krb5_boolean keepold, int n_ks,
+ krb5_key_salt_tuple *ks)
+{
+ if (keepold || ks) {
+ return kadm5_randkey_principal_3(handle, princ, keepold, n_ks, ks,
+ NULL, NULL);
+ } else
+ return kadm5_randkey_principal(handle, princ, NULL, NULL);
+}
+
char *kadmin_startup(argc, argv)
int argc;
char *argv[];
@@ -780,15 +803,9 @@ void kadmin_cpw(argc, argv)
if (db_args) free(db_args);
return;
} else if (randkey) {
- if (keepold || ks_tuple != NULL) {
- retval = kadm5_randkey_principal_3(handle, princ, keepold,
- n_ks_tuple, ks_tuple,
- NULL, NULL);
- if (ks_tuple != NULL)
- free(ks_tuple);
- } else {
- retval = kadm5_randkey_principal(handle, princ, NULL, NULL);
- }
+ retval = randkey_princ(princ, keepold, n_ks_tuple, ks_tuple);
+ if (ks_tuple != NULL)
+ free(ks_tuple);
krb5_free_principal(context, princ);
if (retval) {
com_err("change_password", retval,
@@ -891,7 +908,7 @@ kadmin_parse_princ_args(argc, argv, oprinc, mask, pass, randkey,
kadm5_principal_ent_t oprinc;
long *mask;
char **pass;
- int *randkey;
+ krb5_boolean *randkey;
krb5_key_salt_tuple **ks_tuple;
int *n_ks_tuple;
#if APPLE_PKINIT
@@ -913,7 +930,7 @@ kadmin_parse_princ_args(argc, argv, oprinc, mask, pass, randkey,
*cert_hash = NULL;
#endif /* APPLE_PKINIT */
time(&now);
- *randkey = 0;
+ *randkey = FALSE;
for (i = 1; i < argc - 1; i++) {
attrib_set = 0;
if (strlen(argv[i]) == 2 &&
@@ -1048,7 +1065,7 @@ kadmin_parse_princ_args(argc, argv, oprinc, mask, pass, randkey,
}
if (strlen(argv[i]) == 8 &&
!strcmp("-randkey", argv[i])) {
- ++*randkey;
+ *randkey = TRUE;
continue;
}
#if APPLE_PKINIT
@@ -1150,6 +1167,19 @@ kadmin_modprinc_usage(func)
);
}
+/* Create a dummy password for old-style (pre-1.8) randkey creation. */
+static void
+prepare_dummy_password(char *buf, size_t sz)
+{
+ size_t i;
+
+ /* Must try to pass any password policy in place, and be valid UTF-8. */
+ strcpy(buf, "6F a[");
+ for (i = strlen(buf); i < sz - 1; i++)
+ buf[i] = 'a' + (i % 26);
+ buf[sz - 1] = '\0';
+}
+
void kadmin_addprinc(argc, argv)
int argc;
char *argv[];
@@ -1157,7 +1187,7 @@ void kadmin_addprinc(argc, argv)
kadm5_principal_ent_rec princ;
kadm5_policy_ent_rec defpol;
long mask;
- int randkey = 0, i;
+ krb5_boolean randkey = FALSE, old_style_randkey = FALSE;
int n_ks_tuple;
krb5_key_salt_tuple *ks_tuple;
char *pass, *canon;
@@ -1168,16 +1198,6 @@ void kadmin_addprinc(argc, argv)
char *cert_hash = NULL;
#endif /* APPLE_PKINIT */
- /*
- * We begin with a bad password and DISALLOW_ALL_TIX. The bad
- * password must try to pass any password policy in place, and
- * must be valid UTF-8 for the arcfour string-to-key).
- */
- strcpy(dummybuf, "6F a[");
- for (i = strlen(dummybuf); i < sizeof(dummybuf) - 1; i++)
- dummybuf[i] = 'a' + (random() % 25);
- dummybuf[sizeof(dummybuf) - 1] = '\0';
-
/* Zero all fields in request structure */
memset(&princ, 0, sizeof(princ));
@@ -1235,10 +1255,8 @@ void kadmin_addprinc(argc, argv)
}
mask &= ~KADM5_POLICY_CLR;
- if (randkey) { /* do special stuff if -randkey specified */
- princ.attributes |= KRB5_KDB_DISALLOW_ALL_TIX; /* set notix */
- mask |= KADM5_ATTRIBUTES;
- pass = dummybuf;
+ if (randkey) {
+ pass = NULL;
} else if (pass == NULL) {
unsigned int sz = sizeof (newpw) - 1;
@@ -1261,11 +1279,18 @@ void kadmin_addprinc(argc, argv)
pass = newpw;
}
mask |= KADM5_PRINCIPAL;
- if (ks_tuple != NULL) {
- retval = kadm5_create_principal_3(handle, &princ, mask,
- n_ks_tuple, ks_tuple, pass);
- } else {
- retval = kadm5_create_principal(handle, &princ, mask, pass);
+ retval = create_princ(&princ, mask, n_ks_tuple, ks_tuple, pass);
+ if (retval == EINVAL && randkey) {
+ /*
+ * The server doesn't support randkey creation. Create the principal
+ * with a dummy password and disallow tickets.
+ */
+ prepare_dummy_password(dummybuf, sizeof(dummybuf));
+ princ.attributes |= KRB5_KDB_DISALLOW_ALL_TIX;
+ mask |= KADM5_ATTRIBUTES;
+ pass = dummybuf;
+ retval = create_princ(&princ, mask, n_ks_tuple, ks_tuple, pass);
+ old_style_randkey = 1;
}
if (retval) {
com_err("add_principal", retval, "while creating \"%s\".",
@@ -1277,16 +1302,9 @@ void kadmin_addprinc(argc, argv)
kadmin_free_tl_data(&princ);
return;
}
- if (randkey) { /* more special stuff for -randkey */
- if (ks_tuple != NULL) {
- retval = kadm5_randkey_principal_3(handle, princ.principal,
- FALSE,
- n_ks_tuple, ks_tuple,
- NULL, NULL);
- } else {
- retval = kadm5_randkey_principal(handle, princ.principal,
- NULL, NULL);
- }
+ if (old_style_randkey) {
+ /* Randomize the password and re-enable tickets. */
+ retval = randkey_princ(princ.principal, FALSE, n_ks_tuple, ks_tuple);
if (retval) {
com_err("add_principal", retval,
"while randomizing key for \"%s\".", canon);
@@ -1329,7 +1347,7 @@ void kadmin_modprinc(argc, argv)
long mask;
krb5_error_code retval;
char *pass, *canon;
- int randkey = 0;
+ krb5_boolean randkey = FALSE;
int n_ks_tuple = 0;
krb5_key_salt_tuple *ks_tuple;
#if APPLE_PKINIT
diff --git a/src/lib/kadm5/srv/svr_principal.c b/src/lib/kadm5/srv/svr_principal.c
index 5c5cdc8..1a60f52 100644
--- a/src/lib/kadm5/srv/svr_principal.c
+++ b/src/lib/kadm5/srv/svr_principal.c
@@ -226,7 +226,7 @@ kadm5_create_principal_3(void *server_handle,
return KADM5_BAD_MASK;
if((mask & ~ALL_PRINC_MASK))
return KADM5_BAD_MASK;
- if (entry == (kadm5_principal_ent_t) NULL || password == NULL)
+ if (entry == NULL)
return EINVAL;
/*
@@ -260,11 +260,14 @@ kadm5_create_principal_3(void *server_handle,
return ret;
}
}
- if ((ret = passwd_check(handle, password, (mask & KADM5_POLICY),
- &polent, entry->principal))) {
- if (mask & KADM5_POLICY)
- (void) kadm5_free_policy_ent(handle->lhandle, &polent);
- return ret;
+ if (password) {
+ ret = passwd_check(handle, password, (mask & KADM5_POLICY),
+ &polent, entry->principal);
+ if (ret) {
+ if (mask & KADM5_POLICY)
+ (void) kadm5_free_policy_ent(handle->lhandle, &polent);
+ return ret;
+ }
}
/*
* Start populating the various DB fields, using the
@@ -360,12 +363,20 @@ kadm5_create_principal_3(void *server_handle,
return (ret);
}
- if ((ret = krb5_dbe_cpw(handle->context, act_mkey,
- n_ks_tuple?ks_tuple:handle->params.keysalts,
- n_ks_tuple?n_ks_tuple:handle->params.num_keysalts,
- password,
- (mask & KADM5_KVNO)?entry->kvno:1,
- FALSE, &kdb))) {
+ if (password) {
+ ret = krb5_dbe_cpw(handle->context, act_mkey,
+ n_ks_tuple?ks_tuple:handle->params.keysalts,
+ n_ks_tuple?n_ks_tuple:handle->params.num_keysalts,
+ password, (mask & KADM5_KVNO)?entry->kvno:1,
+ FALSE, &kdb);
+ } else {
+ /* Null password means create with random key (new in 1.8). */
+ ret = krb5_dbe_crk(handle->context, &master_keyblock,
+ n_ks_tuple?ks_tuple:handle->params.keysalts,
+ n_ks_tuple?n_ks_tuple:handle->params.num_keysalts,
+ FALSE, &kdb);
+ }
+ if (ret) {
krb5_db_free_principal(handle->context, &kdb, 1);
if (mask & KADM5_POLICY)
(void) kadm5_free_policy_ent(handle->lhandle, &polent);
diff --git a/src/lib/kadm5/unit-test/api.2/crte-principal.exp b/src/lib/kadm5/unit-test/api.2/crte-principal.exp
index 8a84af2..bb7917b 100644
--- a/src/lib/kadm5/unit-test/api.2/crte-principal.exp
+++ b/src/lib/kadm5/unit-test/api.2/crte-principal.exp
@@ -54,7 +54,7 @@ proc test3 {} {
perror "$test: unexpected failure in init"
return
}
- one_line_fail_test [format {
+ one_line_succeed_test [format {
kadm5_create_principal $server_handle [simple_principal "%s/a"] \
{KADM5_PRINCIPAL} null
} $test] "EINVAL"