summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib/kadm5/srv/ChangeLog4
-rw-r--r--src/lib/kadm5/srv/svr_principal.c130
2 files changed, 134 insertions, 0 deletions
diff --git a/src/lib/kadm5/srv/ChangeLog b/src/lib/kadm5/srv/ChangeLog
index fcca8b1a3..248179e6a 100644
--- a/src/lib/kadm5/srv/ChangeLog
+++ b/src/lib/kadm5/srv/ChangeLog
@@ -1,3 +1,7 @@
+Sun Jun 29 14:52:51 1997 Tom Yu <tlyu@mit.edu>
+
+ * svr_principal.c: Add new function kadm5_setv4key_principal.
+
Mon Mar 31 17:40:24 1997 Barry Jaspan <bjaspan@mit.edu>
* server_acl.c, server_acl.h, svr_pricipal.c: add support for
diff --git a/src/lib/kadm5/srv/svr_principal.c b/src/lib/kadm5/srv/svr_principal.c
index e7bfe0394..a9d5ba35b 100644
--- a/src/lib/kadm5/srv/svr_principal.c
+++ b/src/lib/kadm5/srv/svr_principal.c
@@ -1261,6 +1261,136 @@ done:
return ret;
}
+/*
+ * kadm5_setv4key_principal:
+ *
+ * Set only ONE key of the principal, removing all others. This key
+ * must have the DES_CBC_CRC enctype and is entered as having the
+ * krb4 salttype. This is to enable things like kadmind4 to work.
+ */
+kadm5_ret_t
+kadm5_setv4key_principal(void *server_handle,
+ krb5_principal principal,
+ krb5_keyblock *keyblock)
+{
+ krb5_db_entry kdb;
+ osa_princ_ent_rec adb;
+ krb5_int32 now;
+ kadm5_policy_ent_rec pol;
+ krb5_key_data *key_data;
+ krb5_keysalt keysalt;
+ int i, kvno, ret, last_pwd, have_pol = 0;
+ int deskeys;
+ kadm5_server_handle_t handle = server_handle;
+
+ CHECK_HANDLE(server_handle);
+
+ if (principal == NULL || keyblock == NULL)
+ return EINVAL;
+ if (hist_princ && /* this will be NULL when initializing the databse */
+ ((krb5_principal_compare(handle->context,
+ principal, hist_princ)) == TRUE))
+ return KADM5_PROTECT_PRINCIPAL;
+
+ if (keyblock->enctype != ENCTYPE_DES_CBC_CRC)
+ return KADM5_SETV4KEY_INVAL_ENCTYPE;
+
+ if ((ret = kdb_get_entry(handle, principal, &kdb, &adb)))
+ return(ret);
+
+ for (kvno = 0, i=0; i<kdb.n_key_data; i++)
+ if (kdb.key_data[i].key_data_kvno > kvno)
+ kvno = kdb.key_data[i].key_data_kvno;
+
+ if (kdb.key_data != NULL)
+ cleanup_key_data(handle->context, kdb.n_key_data, kdb.key_data);
+
+ kdb.key_data = (krb5_key_data*)malloc(sizeof(krb5_key_data));
+ if (kdb.key_data == NULL)
+ return ENOMEM;
+ memset(kdb.key_data, 0, sizeof(krb5_key_data));
+ kdb.n_key_data = 1;
+ keysalt.type = KRB5_KDB_SALTTYPE_V4;
+ /* XXX data.magic? */
+ keysalt.data.length = 0;
+ keysalt.data.data = NULL;
+
+ if (ret = krb5_dbekd_encrypt_key_data(handle->context,
+ &master_encblock,
+ keyblock, &keysalt,
+ kvno + 1,
+ &kdb.key_data[i])) {
+ goto done;
+ }
+
+ kdb.attributes &= ~KRB5_KDB_REQUIRES_PWCHANGE;
+
+ if (ret = krb5_timeofday(handle->context, &now))
+ goto done;
+
+ if ((adb.aux_attributes & KADM5_POLICY)) {
+ if ((ret = kadm5_get_policy(handle->lhandle, adb.policy,
+ &pol)) != KADM5_OK)
+ goto done;
+ have_pol = 1;
+
+#if 0
+ /*
+ * The spec says this check is overridden if the caller has
+ * modify privilege. The admin server therefore makes this
+ * check itself (in chpass_principal_wrapper, misc.c). A
+ * local caller implicitly has all authorization bits.
+ */
+ if (ret = krb5_dbe_lookup_last_pwd_change(handle->context,
+ &kdb, &last_pwd))
+ goto done;
+ if((now - last_pwd) < pol.pw_min_life &&
+ !(kdb.attributes & KRB5_KDB_REQUIRES_PWCHANGE)) {
+ ret = KADM5_PASS_TOOSOON;
+ goto done;
+ }
+#endif
+#if 0
+ /*
+ * Should we be checking/updating pw history here?
+ */
+ if(pol.pw_history_num > 1) {
+ if(adb.admin_history_kvno != hist_kvno) {
+ ret = KADM5_BAD_HIST_KEY;
+ goto done;
+ }
+
+ if (ret = check_pw_reuse(handle->context,
+ &hist_encblock,
+ kdb.n_key_data, kdb.key_data,
+ adb.old_key_len, adb.old_keys))
+ goto done;
+ }
+#endif
+
+ if (pol.pw_max_life)
+ kdb.pw_expiration = now + pol.pw_max_life;
+ else
+ kdb.pw_expiration = 0;
+ } else {
+ kdb.pw_expiration = 0;
+ }
+
+ if (ret = krb5_dbe_update_last_pwd_change(handle->context, &kdb, now))
+ goto done;
+
+ if ((ret = kdb_put_entry(handle, &kdb, &adb)))
+ goto done;
+
+ ret = KADM5_OK;
+done:
+ kdb_free_entry(handle, &kdb, &adb);
+ if (have_pol)
+ kadm5_free_policy_ent(handle->lhandle, &pol);
+
+ return ret;
+}
+
kadm5_ret_t
kadm5_setkey_principal(void *server_handle,
krb5_principal principal,