+2000-02-13 Tom Yu <tlyu@mit.edu>
+
+ * kadm_rpc_xdr.c: Add xdr functions for new kadm rpc functions.
+
+ * kadm_rpc.h: Add arg structs, prototypes, constants for new kadm
+ rpc functions.
+
+ * kadm_err.et: Add error code KADM5_SETKEY3_ETYPE_MISMATCH.
+
+ * admin.h: Add prototype for setkey_principal_3.
+
1999-12-01 Ken Raeburn <raeburn@mit.edu>
* logger.c (klog_vsyslog): Convert pid_t to long for printing.
krb5_keyblock *keyblocks,
int n_keys);
+kadm5_ret_t kadm5_setkey_principal_3(void *server_handle,
+ krb5_principal principal,
+ krb5_boolean keepold,
+ int n_ks_tuple,
+ krb5_key_salt_tuple *ks_tuple,
+ krb5_keyblock *keyblocks,
+ int n_keys);
+
kadm5_ret_t kadm5_create_policy(void *server_handle,
kadm5_policy_ent_t ent,
long mask);
+2000-02-13 Tom Yu <tlyu@mit.edu>
+
+ * client_rpc.c: Add new client stubs.
+
+ * client_principal.c: Add new functions for client-side kadm rpc
+ calls.
+
2000-01-27 Ken Raeburn <raeburn@raeburn.org>
* client_init.c (enctypes): New array, listing only
return r->code;
}
+kadm5_ret_t
+kadm5_create_principal_3(void *server_handle,
+ kadm5_principal_ent_t princ, long mask,
+ krb5_boolean keepold, int n_ks_tuple,
+ krb5_key_salt_tuple *ks_tuple,
+ char *pw)
+{
+ generic_ret *r;
+ cprinc3_arg arg;
+ kadm5_server_handle_t handle = server_handle;
+
+ CHECK_HANDLE(server_handle);
+
+ memset(&arg, 0, sizeof(arg));
+ arg.mask = mask;
+ arg.passwd = pw;
+ arg.api_version = handle->api_version;
+ arg.keepold = keepold;
+ arg.n_ks_tuple = n_ks_tuple;
+ arg.ks_tuple = ks_tuple;
+
+ if(princ == NULL)
+ return EINVAL;
+
+ if (handle->api_version == KADM5_API_VERSION_1) {
+ memcpy(&arg.rec, princ, sizeof(kadm5_principal_ent_rec_v1));
+ } else {
+ memcpy(&arg.rec, princ, sizeof(kadm5_principal_ent_rec));
+ }
+ if (handle->api_version == KADM5_API_VERSION_1) {
+ /*
+ * hack hack cough cough.
+ * krb5_unparse name dumps core if we pass it in garbage
+ * or null. So, since the client is not allowed to set mod_name
+ * anyway, we just fill it in with a dummy principal. The server of
+ * course ignores this.
+ */
+ krb5_parse_name(handle->context, "bogus/bogus", &arg.rec.mod_name);
+ } else
+ arg.rec.mod_name = NULL;
+
+ if(!(mask & KADM5_POLICY))
+ arg.rec.policy = NULL;
+ if (! (mask & KADM5_KEY_DATA)) {
+ arg.rec.n_key_data = 0;
+ arg.rec.key_data = NULL;
+ }
+ if (! (mask & KADM5_TL_DATA)) {
+ arg.rec.n_tl_data = 0;
+ arg.rec.tl_data = NULL;
+ }
+
+ r = create_principal3_1(&arg, handle->clnt);
+
+ if (handle->api_version == KADM5_API_VERSION_1)
+ krb5_free_principal(handle->context, arg.rec.mod_name);
+
+ if(r == NULL)
+ return KADM5_RPC_ERROR;
+ return r->code;
+}
+
kadm5_ret_t
kadm5_delete_principal(void *server_handle, krb5_principal principal)
{
return r->code;
}
+kadm5_ret_t
+kadm5_chpass_principal_3(void *server_handle,
+ krb5_principal princ, krb5_boolean keepold,
+ int n_ks_tuple, krb5_key_salt_tuple *ks_tuple,
+ char *password)
+{
+ chpass3_arg arg;
+ generic_ret *r;
+ kadm5_server_handle_t handle = server_handle;
+
+ CHECK_HANDLE(server_handle);
+
+ arg.princ = princ;
+ arg.pass = password;
+ arg.api_version = handle->api_version;
+ arg.keepold = keepold;
+ arg.n_ks_tuple = n_ks_tuple;
+ arg.ks_tuple = ks_tuple;
+
+ if(princ == NULL)
+ return EINVAL;
+ r = chpass_principal3_1(&arg, handle->clnt);
+ if(r == NULL)
+ return KADM5_RPC_ERROR;
+ return r->code;
+}
+
kadm5_ret_t
kadm5_setv4key_principal(void *server_handle,
krb5_principal princ,
return r->code;
}
+kadm5_ret_t
+kadm5_setkey_principal_3(void *server_handle,
+ krb5_principal princ,
+ krb5_boolean keepold, int n_ks_tuple,
+ krb5_key_salt_tuple *ks_tuple,
+ krb5_keyblock *keyblocks,
+ int n_keys)
+{
+ setkey3_arg arg;
+ generic_ret *r;
+ kadm5_server_handle_t handle = server_handle;
+
+ CHECK_HANDLE(server_handle);
+
+ arg.princ = princ;
+ arg.keyblocks = keyblocks;
+ arg.n_keys = n_keys;
+ arg.api_version = handle->api_version;
+ arg.keepold = keepold;
+ arg.n_ks_tuple = n_ks_tuple;
+ arg.ks_tuple = ks_tuple;
+
+ if(princ == NULL || keyblocks == NULL)
+ return EINVAL;
+ r = setkey_principal3_1(&arg, handle->clnt);
+ if(r == NULL)
+ return KADM5_RPC_ERROR;
+ return r->code;
+}
+
+kadm5_ret_t
+kadm5_randkey_principal_3(void *server_handle,
+ krb5_principal princ,
+ krb5_boolean keepold, int n_ks_tuple,
+ krb5_key_salt_tuple *ks_tuple,
+ krb5_keyblock **key, int *n_keys)
+{
+ chrand3_arg arg;
+ chrand_ret *r;
+ krb5_keyblock new;
+ kadm5_server_handle_t handle = server_handle;
+ int i, ret;
+
+ CHECK_HANDLE(server_handle);
+
+ arg.princ = princ;
+ arg.api_version = handle->api_version;
+ arg.keepold = keepold;
+ arg.n_ks_tuple = n_ks_tuple;
+ arg.ks_tuple = ks_tuple;
+
+ if(princ == NULL)
+ return EINVAL;
+ r = chrand_principal3_1(&arg, handle->clnt);
+ if(r == NULL)
+ return KADM5_RPC_ERROR;
+ if (handle->api_version == KADM5_API_VERSION_1) {
+ if (key)
+ krb5_copy_keyblock(handle->context, &r->key, key);
+ } else {
+ if (n_keys)
+ *n_keys = r->n_keys;
+ if (key) {
+ if(r->n_keys) {
+ *key = (krb5_keyblock *)
+ malloc(r->n_keys*sizeof(krb5_keyblock));
+ if (*key == NULL)
+ return ENOMEM;
+ for (i = 0; i < r->n_keys; i++) {
+ ret = krb5_copy_keyblock_contents(handle->context,
+ &r->keys[i],
+ &(*key)[i]);
+ if (ret) {
+ free(*key);
+ return ENOMEM;
+ }
+ }
+ } else *key = NULL;
+ }
+ }
+
+ return r->code;
+}
+
kadm5_ret_t
kadm5_randkey_principal(void *server_handle,
krb5_principal princ,
return (&res);
}
+generic_ret *
+create_principal3_1(argp, clnt)
+ cprinc_arg *argp;
+ CLIENT *clnt;
+{
+ static generic_ret res;
+
+ memset((char *)&res, 0, sizeof(res));
+ if (clnt_call(clnt, CREATE_PRINCIPAL3, xdr_cprinc3_arg, argp, xdr_generic_ret, &res, TIMEOUT) != RPC_SUCCESS) {
+ return (NULL);
+ }
+ return (&res);
+}
+
generic_ret *
delete_principal_1(argp, clnt)
dprinc_arg *argp;
return (&res);
}
+generic_ret *
+chpass_principal3_1(argp, clnt)
+ chpass_arg *argp;
+ CLIENT *clnt;
+{
+ static generic_ret res;
+
+ memset((char *)&res, 0, sizeof(res));
+ if (clnt_call(clnt, CHPASS_PRINCIPAL3, xdr_chpass3_arg, argp, xdr_generic_ret, &res, TIMEOUT) != RPC_SUCCESS) {
+ return (NULL);
+ }
+ return (&res);
+}
+
generic_ret *
setv4key_principal_1(argp, clnt)
setv4key_arg *argp;
return (&res);
}
+generic_ret *
+setkey_principal3_1(argp, clnt)
+ setkey_arg *argp;
+ CLIENT *clnt;
+{
+ static generic_ret res;
+
+ memset((char *)&res, 0, sizeof(res));
+ if (clnt_call(clnt, SETKEY_PRINCIPAL3, xdr_setkey3_arg, argp, xdr_generic_ret, &res, TIMEOUT) != RPC_SUCCESS) {
+ return (NULL);
+ }
+ return (&res);
+}
+
chrand_ret *
chrand_principal_1(argp, clnt)
chrand_arg *argp;
return (&res);
}
+chrand_ret *
+chrand_principal3_1(argp, clnt)
+ chrand_arg *argp;
+ CLIENT *clnt;
+{
+ static chrand_ret res;
+
+ memset((char *)&res, 0, sizeof(res));
+ if (clnt_call(clnt, CHRAND_PRINCIPAL3, xdr_chrand3_arg, argp, xdr_chrand_ret, &res, TIMEOUT) != RPC_SUCCESS) {
+ return (NULL);
+ }
+ return (&res);
+}
+
generic_ret *
create_policy_1(argp, clnt)
cpol_arg *argp;
error_code KADM5_SETKEY_DUP_ENCTYPES, "Multiple values for single or folded enctype"
error_code KADM5_SETV4KEY_INVAL_ENCTYPE, "Invalid enctype for setv4key"
end
+error_code KADM5_SETKEY3_ETYPE_MISMATCH, "Mismatched enctypes for setkey3"
typedef struct cprinc_arg cprinc_arg;
bool_t xdr_cprinc_arg();
+struct cprinc3_arg {
+ krb5_ui_4 api_version;
+ kadm5_principal_ent_rec rec;
+ long mask;
+ krb5_boolean keepold;
+ int n_ks_tuple;
+ krb5_key_salt_tuple *ks_tuple;
+ char *passwd;
+};
+typedef struct cprinc3_arg cprinc3_arg;
+bool_t xdr_cprinc3_arg();
+
struct generic_ret {
krb5_ui_4 api_version;
kadm5_ret_t code;
typedef struct chpass_arg chpass_arg;
bool_t xdr_chpass_arg();
+struct chpass3_arg {
+ krb5_ui_4 api_version;
+ krb5_principal princ;
+ krb5_boolean keepold;
+ int n_ks_tuple;
+ krb5_key_salt_tuple *ks_tuple;
+ char *pass;
+};
+typedef struct chpass3_arg chpass3_arg;
+bool_t xdr_chpass3_arg();
+
struct setv4key_arg {
krb5_ui_4 api_version;
krb5_principal princ;
typedef struct setkey_arg setkey_arg;
bool_t xdr_setkey_arg();
+struct setkey3_arg {
+ krb5_ui_4 api_version;
+ krb5_principal princ;
+ krb5_boolean keepold;
+ int n_ks_tuple;
+ krb5_key_salt_tuple *ks_tuple;
+ krb5_keyblock *keyblocks;
+ int n_keys;
+};
+typedef struct setkey3_arg setkey3_arg;
+bool_t xdr_setkey3_arg();
+
struct chrand_arg {
krb5_ui_4 api_version;
krb5_principal princ;
typedef struct chrand_arg chrand_arg;
bool_t xdr_chrand_arg();
+struct chrand3_arg {
+ krb5_ui_4 api_version;
+ krb5_principal princ;
+ krb5_boolean keepold;
+ int n_ks_tuple;
+ krb5_key_salt_tuple *ks_tuple;
+};
+typedef struct chrand3_arg chrand3_arg;
+bool_t xdr_chrand3_arg();
+
struct chrand_ret {
krb5_ui_4 api_version;
kadm5_ret_t code;
extern generic_ret *setkey_principal_1();
#define SETV4KEY_PRINCIPAL ((krb5_ui_4) 17)
extern generic_ret *setv4key_principal_1();
+#define CREATE_PRINCIPAL3 ((krb5_ui_4) 18)
+extern generic_ret *create_principal3_1();
+#define CHPASS_PRINCIPAL3 ((krb5_ui_4) 19)
+extern generic_ret *chpass_principal3_1();
+#define CHRAND_PRINCIPAL3 ((krb5_ui_4) 20)
+extern chrand_ret *chrand_principal3_1();
+#define SETKEY_PRINCIPAL3 ((krb5_ui_4) 21)
+extern generic_ret *setkey_principal3_1();
static bool_t
_xdr_kadm5_principal_ent_rec(XDR *xdrs, kadm5_principal_ent_rec *objp,
int v);
-
/*
* Function: xdr_ui_4
*
return (TRUE);
}
+
+bool_t
+xdr_krb5_key_salt_tuple(XDR *xdrs, krb5_key_salt_tuple *objp)
+{
+ if (!xdr_krb5_enctype(xdrs, &objp->ks_enctype))
+ return FALSE;
+ if (!xdr_krb5_salttype(xdrs, &objp->ks_salttype))
+ return FALSE;
+ return TRUE;
+}
+
bool_t xdr_krb5_tl_data(XDR *xdrs, krb5_tl_data **tl_data_head)
{
krb5_tl_data *tl, *tl2;
return (TRUE);
}
+bool_t
+xdr_cprinc3_arg(XDR *xdrs, cprinc3_arg *objp)
+{
+ if (!xdr_ui_4(xdrs, &objp->api_version)) {
+ return (FALSE);
+ }
+ if (objp->api_version == KADM5_API_VERSION_1) {
+ if (!xdr_kadm5_principal_ent_rec_v1(xdrs, &objp->rec)) {
+ return (FALSE);
+ }
+ } else {
+ if (!xdr_kadm5_principal_ent_rec(xdrs, &objp->rec)) {
+ return (FALSE);
+ }
+ }
+ if (!xdr_long(xdrs, &objp->mask)) {
+ return (FALSE);
+ }
+ if (!xdr_bool(xdrs, &objp->keepold)) {
+ return (FALSE);
+ }
+ if (!xdr_array(xdrs, (caddr_t *)&objp->ks_tuple,
+ (unsigned int *)&objp->n_ks_tuple, ~0,
+ sizeof(krb5_key_salt_tuple),
+ xdr_krb5_key_salt_tuple)) {
+ return (FALSE);
+ }
+ if (!xdr_nullstring(xdrs, &objp->passwd)) {
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
bool_t
xdr_generic_ret(XDR *xdrs, generic_ret *objp)
{
return (TRUE);
}
+bool_t
+xdr_chpass3_arg(XDR *xdrs, chpass3_arg *objp)
+{
+ if (!xdr_ui_4(xdrs, &objp->api_version)) {
+ return (FALSE);
+ }
+ if (!xdr_krb5_principal(xdrs, &objp->princ)) {
+ return (FALSE);
+ }
+ if (!xdr_bool(xdrs, &objp->keepold)) {
+ return (FALSE);
+ }
+ if (!xdr_array(xdrs, (caddr_t *)&objp->ks_tuple,
+ objp->n_ks_tuple, ~0,
+ sizeof(krb5_key_salt_tuple),
+ xdr_krb5_key_salt_tuple)) {
+ return (FALSE);
+ }
+ if (!xdr_nullstring(xdrs, &objp->pass)) {
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
bool_t
xdr_setv4key_arg(XDR *xdrs, setv4key_arg *objp)
{
return (TRUE);
}
+bool_t
+xdr_setkey3_arg(XDR *xdrs, setkey3_arg *objp)
+{
+ if (!xdr_ui_4(xdrs, &objp->api_version)) {
+ return (FALSE);
+ }
+ if (!xdr_krb5_principal(xdrs, &objp->princ)) {
+ return (FALSE);
+ }
+ if (!xdr_bool(xdrs, &objp->keepold)) {
+ return (FALSE);
+ }
+ if (!xdr_array(xdrs, (caddr_t *) &objp->ks_tuple,
+ (unsigned int *) &objp->n_ks_tuple, ~0,
+ sizeof(krb5_key_salt_tuple), xdr_krb5_key_salt_tuple)) {
+ return (FALSE);
+ }
+ if (!xdr_array(xdrs, (caddr_t *) &objp->keyblocks,
+ (unsigned int *) &objp->n_keys, ~0,
+ sizeof(krb5_keyblock), xdr_krb5_keyblock)) {
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
bool_t
xdr_chrand_arg(XDR *xdrs, chrand_arg *objp)
{
return (TRUE);
}
+bool_t
+xdr_chrand3_arg(XDR *xdrs, chrand3_arg *objp)
+{
+ if (!xdr_ui_4(xdrs, &objp->api_version)) {
+ return (FALSE);
+ }
+ if (!xdr_krb5_principal(xdrs, &objp->princ)) {
+ return (FALSE);
+ }
+ if (!xdr_bool(xdrs, &objp->keepold)) {
+ return (FALSE);
+ }
+ if (!xdr_array(xdrs, (caddr_t *)&objp->ks_tuple,
+ objp->n_ks_tuple, ~0,
+ sizeof(krb5_key_salt_tuple),
+ xdr_krb5_key_salt_tuple)) {
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
bool_t
xdr_chrand_ret(XDR *xdrs, chrand_ret *objp)
{
return (TRUE);
}
+bool_t
+xdr_krb5_salttype(XDR *xdrs, krb5_int32 *objp)
+{
+ if (!xdr_int32(xdrs, (rpc_int32 *) objp))
+ return FALSE;
+ return TRUE;
+}
+
bool_t
xdr_krb5_keyblock(XDR *xdrs, krb5_keyblock *objp)
{
return FALSE;
return TRUE;
}
-
+2000-02-13 Tom Yu <tlyu@mit.edu>
+
+ * svr_principal.c (kadm5_setkey_principal_3): New function.
+
1999-10-26 Tom Yu <tlyu@mit.edu>
* Makefile.in: Clean up usage of CFLAGS, CPPFLAGS, DEFS, DEFINES,
krb5_principal principal,
krb5_keyblock *keyblocks,
int n_keys)
+{
+ return
+ kadm5_setkey_principal_3(server_handle, principal,
+ FALSE, 0, NULL,
+ keyblocks, n_keys);
+}
+
+kadm5_ret_t
+kadm5_setkey_principal_3(void *server_handle,
+ krb5_principal principal,
+ krb5_boolean keepold,
+ int n_ks_tuple, krb5_key_salt_tuple *ks_tuple,
+ krb5_keyblock *keyblocks,
+ int n_keys)
{
krb5_db_entry kdb;
osa_princ_ent_rec adb;
krb5_int32 now;
kadm5_policy_ent_rec pol;
- krb5_key_data *key_data;
+ krb5_key_data *old_key_data;
+ int n_old_keys;
int i, j, kvno, ret, last_pwd, have_pol = 0;
kadm5_server_handle_t handle = server_handle;
krb5_boolean similar;
+ krb5_keysalt keysalt;
CHECK_HANDLE(server_handle);
&similar))
return(ret);
if (similar)
- return KADM5_SETKEY_DUP_ENCTYPES;
+ if (n_ks_tuple) {
+ if (ks_tuple[i].ks_salttype == ks_tuple[j].ks_salttype)
+ return KADM5_SETKEY_DUP_ENCTYPES;
+ } else
+ return KADM5_SETKEY_DUP_ENCTYPES;
}
}
+ if (n_ks_tuple != n_keys)
+ return KADM5_SETKEY3_ETYPE_MISMATCH;
+
if ((ret = kdb_get_entry(handle, principal, &kdb, &adb)))
return(ret);
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);
+ if (keepold) {
+ old_key_data = kdb.key_data;
+ n_old_keys = kdb.n_key_data;
+ } else {
+ if (kdb.key_data != NULL)
+ cleanup_key_data(handle->context, kdb.n_key_data, kdb.key_data);
+ n_old_keys = 0;
+ old_key_data = NULL;
+ }
- kdb.key_data = (krb5_key_data*)malloc(n_keys*sizeof(krb5_key_data));
+ kdb.key_data = (krb5_key_data*)malloc((n_keys+n_old_keys)
+ *sizeof(krb5_key_data));
if (kdb.key_data == NULL)
return ENOMEM;
- memset(kdb.key_data, 0, n_keys*sizeof(krb5_key_data));
- kdb.n_key_data = n_keys;
+ memset(kdb.key_data, 0, (n_keys+n_old_keys)*sizeof(krb5_key_data));
+ kdb.n_key_data = 0;
for (i = 0; i < n_keys; i++) {
- if (ret = krb5_dbekd_encrypt_key_data(handle->context,
- &master_keyblock,
- &keyblocks[i], NULL,
- kvno + 1,
- &kdb.key_data[i]))
- return ret;
+ if (n_ks_tuple) {
+ keysalt.type = ks_tuple[i].ks_salttype;
+ keysalt.data.length = 0;
+ keysalt.data.data = NULL;
+ if (ks_tuple[i].ks_enctype != keyblocks[i].enctype) {
+ cleanup_key_data(handle->context, kdb.n_key_data,
+ kdb.key_data);
+ return KADM5_SETKEY3_ETYPE_MISMATCH;
+ }
+ }
+ ret = krb5_dbekd_encrypt_key_data(handle->context,
+ &master_keyblock,
+ &keyblocks[i],
+ n_ks_tuple ? &keysalt : NULL,
+ kvno + 1,
+ &kdb.key_data[i]);
+ if (ret) {
+ cleanup_key_data(handle->context, kdb.n_key_data, kdb.key_data);
+ return ret;
+ }
+ kdb.n_key_data++;
}
+ /* copy old key data if necessary */
+ for (i = 0; i < n_old_keys; i++) {
+ kdb.key_data[i+n_keys] = old_key_data[i];
+ memset(&old_key_data[i], 0, sizeof (krb5_key_data));
+ kdb.n_key_data++;
+ }
+ /* assert(kdb.n_key_data == n_keys + n_old_keys) */
kdb.attributes &= ~KRB5_KDB_REQUIRES_PWCHANGE;
if (ret = krb5_timeofday(handle->context, &now))