diff options
| author | Barry Jaspan <bjaspan@mit.edu> | 1997-04-23 19:53:16 +0000 |
|---|---|---|
| committer | Barry Jaspan <bjaspan@mit.edu> | 1997-04-23 19:53:16 +0000 |
| commit | 47a32a44d71b8433300739dbd3b6899c12b53227 (patch) | |
| tree | 16a579383eaf958832b98c4c54f93fce6c47713c /src/lib | |
| parent | 76e9c5c254f618b90542b3e309ac5e3a0a888786 (diff) | |
add kadm5_setkey_principal
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@10072 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/kadm5/ChangeLog | 5 | ||||
| -rw-r--r-- | src/lib/kadm5/clnt/ChangeLog | 5 | ||||
| -rw-r--r-- | src/lib/kadm5/clnt/client_principal.c | 25 | ||||
| -rw-r--r-- | src/lib/kadm5/clnt/client_rpc.c | 14 | ||||
| -rw-r--r-- | src/lib/kadm5/kadm_err.et | 2 | ||||
| -rw-r--r-- | src/lib/kadm5/kadm_rpc.h | 11 | ||||
| -rw-r--r-- | src/lib/kadm5/kadm_rpc_xdr.c | 17 | ||||
| -rw-r--r-- | src/lib/kadm5/srv/ChangeLog | 5 | ||||
| -rw-r--r-- | src/lib/kadm5/srv/server_acl.c | 1 | ||||
| -rw-r--r-- | src/lib/kadm5/srv/server_acl.h | 1 | ||||
| -rw-r--r-- | src/lib/kadm5/srv/svr_principal.c | 142 | ||||
| -rw-r--r-- | src/lib/kadm5/unit-test/ChangeLog | 4 | ||||
| -rw-r--r-- | src/lib/kadm5/unit-test/Makefile.in | 12 | ||||
| -rw-r--r-- | src/lib/kadm5/unit-test/setkey-test.c | 212 |
14 files changed, 456 insertions, 0 deletions
diff --git a/src/lib/kadm5/ChangeLog b/src/lib/kadm5/ChangeLog index 2aa7cc99b..dc016db57 100644 --- a/src/lib/kadm5/ChangeLog +++ b/src/lib/kadm5/ChangeLog @@ -1,3 +1,8 @@ +Mon Mar 31 17:41:11 1997 Barry Jaspan <bjaspan@mit.edu> + + * kadm_err.et, kadm_rpc.h, kadm_rpc_xdr.c: add support for + setkey_principal + Thu Jan 16 19:01:00 1997 Tom Yu <tlyu@mit.edu> * Makefile.in (all-prerecurse): Update to use double-colon rules. diff --git a/src/lib/kadm5/clnt/ChangeLog b/src/lib/kadm5/clnt/ChangeLog index 0497aba54..3635a324f 100644 --- a/src/lib/kadm5/clnt/ChangeLog +++ b/src/lib/kadm5/clnt/ChangeLog @@ -1,3 +1,8 @@ +Mon Mar 31 17:40:48 1997 Barry Jaspan <bjaspan@mit.edu> + + * client_principal.c, client_rpc.c: add support for + setkey_principal + Sat Feb 22 01:35:19 1997 Sam Hartman <hartmans@tertius.mit.edu> * Makefile.in (SHLIB_EXPDEPS): s/.so/$(SHLIBEXT) diff --git a/src/lib/kadm5/clnt/client_principal.c b/src/lib/kadm5/clnt/client_principal.c index 14cd55d80..adcbb291f 100644 --- a/src/lib/kadm5/clnt/client_principal.c +++ b/src/lib/kadm5/clnt/client_principal.c @@ -262,6 +262,31 @@ kadm5_chpass_principal(void *server_handle, } kadm5_ret_t +kadm5_setkey_principal(void *server_handle, + krb5_principal princ, + krb5_keyblock *keyblocks, + int n_keys) +{ + setkey_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; + + if(princ == NULL || keyblocks == NULL) + return EINVAL; + r = setkey_principal_1(&arg, handle->clnt); + if(r == NULL) + return KADM5_RPC_ERROR; + return r->code; +} + +kadm5_ret_t kadm5_randkey_principal(void *server_handle, krb5_principal princ, krb5_keyblock **key, int *n_keys) diff --git a/src/lib/kadm5/clnt/client_rpc.c b/src/lib/kadm5/clnt/client_rpc.c index 547844a2c..ecb5943b3 100644 --- a/src/lib/kadm5/clnt/client_rpc.c +++ b/src/lib/kadm5/clnt/client_rpc.c @@ -106,6 +106,20 @@ chpass_principal_1(argp, clnt) return (&res); } +generic_ret * +setkey_principal_1(argp, clnt) + setkey_arg *argp; + CLIENT *clnt; +{ + static generic_ret res; + + memset((char *)&res, 0, sizeof(res)); + if (clnt_call(clnt, SETKEY_PRINCIPAL, xdr_setkey_arg, argp, xdr_generic_ret, &res, TIMEOUT) != RPC_SUCCESS) { + return (NULL); + } + return (&res); +} + chrand_ret * chrand_principal_1(argp, clnt) chrand_arg *argp; diff --git a/src/lib/kadm5/kadm_err.et b/src/lib/kadm5/kadm_err.et index fbddc237d..a43a9b557 100644 --- a/src/lib/kadm5/kadm_err.et +++ b/src/lib/kadm5/kadm_err.et @@ -54,4 +54,6 @@ error_code KADM5_GSS_ERROR, "GSS-API (or Kerberos) error" error_code KADM5_BAD_TL_TYPE, "Programmer error! Illegal tagged data list type" error_code KADM5_MISSING_CONF_PARAMS, "Required parameters in kdc.conf missing" error_code KADM5_BAD_SERVER_NAME, "Bad krb5 admin server hostname" +error_code KADM5_AUTH_SETKEY, "Operation requires ``set-key'' privilege" +error_code KADM5_SETKEY_DUP_ENCTYPES, "Multiple values for single or folded enctype" end diff --git a/src/lib/kadm5/kadm_rpc.h b/src/lib/kadm5/kadm_rpc.h index b0f97e6cb..82bf3d57c 100644 --- a/src/lib/kadm5/kadm_rpc.h +++ b/src/lib/kadm5/kadm_rpc.h @@ -66,6 +66,15 @@ struct chpass_arg { typedef struct chpass_arg chpass_arg; bool_t xdr_chpass_arg(); +struct setkey_arg { + krb5_ui_4 api_version; + krb5_principal princ; + krb5_keyblock *keyblocks; + int n_keys; +}; +typedef struct setkey_arg setkey_arg; +bool_t xdr_setkey_arg(); + struct chrand_arg { krb5_ui_4 api_version; krb5_principal princ; @@ -202,4 +211,6 @@ extern generic_ret *init_1(); extern gprincs_ret *get_princs_1(); #define GET_POLS ((krb5_ui_4) 15) extern gpols_ret *get_pols_1(); +#define SETKEY_PRINCIPAL ((krb5_ui_4) 16) +extern generic_ret *setkey_principal_1(); diff --git a/src/lib/kadm5/kadm_rpc_xdr.c b/src/lib/kadm5/kadm_rpc_xdr.c index 67b94c921..fd253043d 100644 --- a/src/lib/kadm5/kadm_rpc_xdr.c +++ b/src/lib/kadm5/kadm_rpc_xdr.c @@ -586,6 +586,23 @@ xdr_chpass_arg(XDR *xdrs, chpass_arg *objp) } bool_t +xdr_setkey_arg(XDR *xdrs, setkey_arg *objp) +{ + if (!xdr_ui_4(xdrs, &objp->api_version)) { + return (FALSE); + } + if (!xdr_krb5_principal(xdrs, &objp->princ)) { + 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) { if (!xdr_ui_4(xdrs, &objp->api_version)) { diff --git a/src/lib/kadm5/srv/ChangeLog b/src/lib/kadm5/srv/ChangeLog index d462a0d77..fcca8b1a3 100644 --- a/src/lib/kadm5/srv/ChangeLog +++ b/src/lib/kadm5/srv/ChangeLog @@ -1,3 +1,8 @@ +Mon Mar 31 17:40:24 1997 Barry Jaspan <bjaspan@mit.edu> + + * server_acl.c, server_acl.h, svr_pricipal.c: add support for + setkey_principal + Sun Mar 9 13:40:33 1997 Tom Yu <tlyu@mit.edu> * svr_principal.c (add_to_history): Don't call realloc() on a NULL diff --git a/src/lib/kadm5/srv/server_acl.c b/src/lib/kadm5/srv/server_acl.c index 6f5c01499..35da5dd80 100644 --- a/src/lib/kadm5/srv/server_acl.c +++ b/src/lib/kadm5/srv/server_acl.c @@ -56,6 +56,7 @@ static const aop_t acl_op_table[] = { { 'c', ACL_CHANGEPW }, { 'i', ACL_INQUIRE }, { 'l', ACL_LIST }, + { 's', ACL_SETKEY }, { 'x', ACL_ALL_MASK }, { '*', ACL_ALL_MASK }, { '\0', 0 } diff --git a/src/lib/kadm5/srv/server_acl.h b/src/lib/kadm5/srv/server_acl.h index 9dfc8daba..4323d6319 100644 --- a/src/lib/kadm5/srv/server_acl.h +++ b/src/lib/kadm5/srv/server_acl.h @@ -56,6 +56,7 @@ #define ACL_INQUIRE 32 /* #define ACL_EXTRACT 64 */ #define ACL_LIST 128 +#define ACL_SETKEY 256 #define ACL_RENAME (ACL_ADD+ACL_DELETE) #define ACL_ALL_MASK (ACL_ADD | \ diff --git a/src/lib/kadm5/srv/svr_principal.c b/src/lib/kadm5/srv/svr_principal.c index 5ff1b4976..e7bfe0394 100644 --- a/src/lib/kadm5/srv/svr_principal.c +++ b/src/lib/kadm5/srv/svr_principal.c @@ -86,6 +86,21 @@ static krb5_tl_data *dup_tl_data(krb5_tl_data *tl) return n; } +/* This is in lib/kdb/kdb_cpw.c, but is static */ +static void cleanup_key_data(context, count, data) + krb5_context context; + int count; + krb5_key_data * data; +{ + int i, j; + + for (i = 0; i < count; i++) + for (j = 0; j < data[i].key_data_ver; j++) + if (data[i].key_data_length[j]) + free(data[i].key_data_contents[j]); + free(data); +} + kadm5_ret_t kadm5_create_principal(void *server_handle, kadm5_principal_ent_t entry, long mask, @@ -1246,6 +1261,133 @@ done: return ret; } +kadm5_ret_t +kadm5_setkey_principal(void *server_handle, + krb5_principal principal, + 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; + 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 || keyblocks == 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; + + for (i = 0, deskeys = 0; i < n_keys; i++) { + if (keyblocks[i].enctype == ENCTYPE_DES_CBC_MD4 || + keyblocks[i].enctype == ENCTYPE_DES_CBC_MD5 || + keyblocks[i].enctype == ENCTYPE_DES_CBC_RAW || + keyblocks[i].enctype == ENCTYPE_DES_CBC_CRC) + deskeys++; + if (deskeys > 1) + return KADM5_SETKEY_DUP_ENCTYPES; + } + + 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(n_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; + + for (i = 0; i < n_keys; i++) { + if (ret = krb5_dbekd_encrypt_key_data(handle->context, + &master_encblock, + &keyblocks[i], NULL, + kvno + 1, + &kdb.key_data[i])) + return ret; + } + + 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; +} + /* * Allocate an array of n_key_data krb5_keyblocks, fill in each * element with the results of decrypting the nth key in key_data with diff --git a/src/lib/kadm5/unit-test/ChangeLog b/src/lib/kadm5/unit-test/ChangeLog index 7ec91fa00..4401065c9 100644 --- a/src/lib/kadm5/unit-test/ChangeLog +++ b/src/lib/kadm5/unit-test/ChangeLog @@ -1,3 +1,7 @@ +Mon Mar 31 17:39:52 1997 Barry Jaspan <bjaspan@mit.edu> + + * Makefile.in, setkey-test.c: add support for setkey + Wed Mar 12 15:49:46 1997 Barry Jaspan <bjaspan@mit.edu> * Makefile.in (unit-test-server-body): depend on test-randkey, not diff --git a/src/lib/kadm5/unit-test/Makefile.in b/src/lib/kadm5/unit-test/Makefile.in index 656a6ea2b..dd0522c80 100644 --- a/src/lib/kadm5/unit-test/Makefile.in +++ b/src/lib/kadm5/unit-test/Makefile.in @@ -4,6 +4,7 @@ PROG_RPATH=$(KRB5_LIBDIR) all:: init-test destroy-test client-handle-test client-iter-test all:: randkey-test server-handle-test lock-test server-iter-test +all:: server-setkey-test client-setkey-test # # The client-side test programs. @@ -28,6 +29,10 @@ client-iter-test: iter-test.o $(KADMLCNT_DEPLIBS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o client-iter-test iter-test.o \ $(KADMCLNT_LIBS) $(KRB5_BASE_LIBS) +client-setkey-test: setkey-test.o $(KADMCLNT_DEPLIBS) $(KRB5_BASE_DEPLIBS) + $(CC_LINK) -o client-setkey-test setkey-test.o \ + $(KADMCLNT_LIBS) $(KRB5_BASE_LIBS) + # # The server-side test programs. # @@ -48,6 +53,13 @@ server-iter-test: iter-test.o $(KADMSRV_DEPLIBS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o server-iter-test iter-test.o \ $(KADMSRV_LIBS) $(KRB5_BASE_LIBS) +setkey-test.o: $(SRCTOP)/lib/kadm5/unit-test/setkey-test.c + $(CC) $(CFLAGS) -UUSE_KADM5_API_VERSION -DUSE_KADM5_API_VERSION=2 -c $(SRCTOP)/lib/kadm5/unit-test/setkey-test.c + +server-setkey-test: setkey-test.o $(KADMSRV_DEPLIBS) $(KRB5_BASE_DEPLIBS) + $(CC_LINK) -o server-setkey-test setkey-test.o \ + $(KADMSRV_LIBS) $(KRB5_BASE_LIBS) + # # The unit-test targets # diff --git a/src/lib/kadm5/unit-test/setkey-test.c b/src/lib/kadm5/unit-test/setkey-test.c new file mode 100644 index 000000000..e329fce25 --- /dev/null +++ b/src/lib/kadm5/unit-test/setkey-test.c @@ -0,0 +1,212 @@ +#include <stdio.h> +#include <krb5.h> +#include <kadm5/admin.h> + +krb5_keyblock test1[] = { + 0, ENCTYPE_DES_CBC_CRC, 0, 0, + -1, +}; +krb5_keyblock test2[] = { + 0, ENCTYPE_DES_CBC_RAW, 0, 0, + -1, +}; +krb5_keyblock test3[] = { + 0, ENCTYPE_DES_CBC_MD5, 0, 0, + -1, +}; + +krb5_keyblock *tests[] = { + test1, test2, test3, NULL +}; + +int keyblocks_equal(krb5_keyblock *kb1, krb5_keyblock *kb2) +{ + return (kb1->enctype == kb2->enctype && + kb1->length == kb2->length && + memcmp(kb1->contents, kb2->contents, kb1->length) == 0); +} + +krb5_data tgtname = { + 0, + KRB5_TGS_NAME_SIZE, + KRB5_TGS_NAME +}; + +unsigned int ktypes[] = { 0, 0 }; + +extern krb5_kt_ops krb5_ktf_writable_ops; + +main(int argc, char **argv) +{ + krb5_context context; + krb5_keytab kt; + krb5_keytab_entry ktent; + krb5_encrypt_block eblock; + krb5_creds my_creds; + kadm5_principal_ent_rec princ_ent; + krb5_principal princ, server; + char pw[16]; + char *whoami, *principal, *authprinc; + krb5_data pwdata; + void *handle; + int ret, i, test, encnum; + + whoami = argv[0]; + + if (argc != 2 && argc != 3) { + fprintf(stderr, "Usage: %s principal [authuser]\n", whoami); + exit(1); + } + principal = argv[1]; + authprinc = argv[2] ? argv[2] : argv[0]; + + /* + * Setup. Initialize data structures, open keytab, open connection + * to kadm5 server. + */ + + memset((char *) &context, 0, sizeof(context)); + krb5_init_context(&context); + + ret = krb5_parse_name(context, principal, &princ); + if (ret) { + com_err(whoami, ret, "while parsing principal name %s", principal); + exit(1); + } + + if((ret = krb5_build_principal_ext(context, &server, + krb5_princ_realm(kcontext, princ)->length, + krb5_princ_realm(kcontext, princ)->data, + tgtname.length, tgtname.data, + krb5_princ_realm(kcontext, princ)->length, + krb5_princ_realm(kcontext, princ)->data, + 0))) { + com_err(whoami, ret, "while building server name"); + exit(1); + } + + /* register the WRFILE keytab type */ + if (ret = krb5_kt_register(context, &krb5_ktf_writable_ops)) { + com_err(whoami, ret, + "while registering writable key table functions"); + exit(1); + } + + ret = krb5_kt_default(context, &kt); + if (ret) { + com_err(whoami, ret, "while opening keytab"); + exit(1); + } + + ret = kadm5_init(authprinc, NULL, KADM5_ADMIN_SERVICE, NULL, + KADM5_STRUCT_VERSION, KADM5_API_VERSION_2, + &handle); + if (ret) { + com_err(whoami, ret, "while initializing connection"); + exit(1); + } + + /* these pw's don't need to be secure, just different every time */ + srandom(getpid() ^ time(0)); + pwdata.data = pw; + pwdata.length = sizeof(pw); + + /* + * For each test: + * + * For each enctype in the test, construct a random password/key. + * Assign all keys to principal with kadm5_setkey_principal. Add + * each key to the keytab, and acquire an initial ticket with the + * keytab (XXX can I specify the enctype & kvno explicitly?). If + * krb5_get_in_tkt_with_keytab succeeds, then the keys were set + * successfully. + */ + for (test = 0; tests[test] != NULL; test++) { + krb5_keyblock *testp = tests[test]; + printf("+ Test %d:\n", test); + + for (encnum = 0; testp[encnum].magic != -1; encnum++) { + for (i = 0; i < sizeof(pw); i++) + pw[i] = (random() % 26) + '0'; /* XXX */ + + krb5_use_enctype(context, &eblock, testp[encnum].enctype); + if (ret = krb5_string_to_key(context, &eblock, &testp[encnum], + &pwdata, NULL)) { + com_err(whoami, ret, "while converting string to key"); + exit(1); + } + } + + /* now, encnum == # of keyblocks in testp */ + ret = kadm5_setkey_principal(handle, princ, testp, encnum); + if (ret) { + com_err(whoami, ret, "while setting keys"); + exit(1); + } + + ret = kadm5_get_principal(handle, princ, &princ_ent, KADM5_KVNO); + if (ret) { + com_err(whoami, ret, "while retrieving principal"); + exit(1); + } + + for (encnum = 0; testp[encnum].magic != -1; encnum++) { + printf("+ enctype %d\n", testp[encnum].enctype); + + memset((char *) &ktent, 0, sizeof(ktent)); + ktent.principal = princ; + ktent.key = testp[encnum]; + ktent.vno = princ_ent.kvno; + + ret = krb5_kt_add_entry(context, kt, &ktent); + if (ret) { + com_err(whoami, ret, "while adding keytab entry"); + exit(1); + } + + memset((char *)&my_creds, 0, sizeof(my_creds)); + my_creds.client = princ; + my_creds.server = server; + + ktypes[0] = testp[encnum].enctype; + ret = krb5_get_in_tkt_with_keytab(context, + 0 /* options */, + NULL /* addrs */, + ktypes, + NULL /* preauth */, + kt, 0, + &my_creds, 0); + if (ret) { + com_err(whoami, ret, "while acquiring initial ticket"); + exit(1); + } + + /* since I can't specify enctype explicitly ... */ + ret = krb5_kt_remove_entry(context, kt, &ktent); + if (ret) { + com_err(whoami, ret, "while removing keytab entry"); + exit(1); + } + } + } + + ret = krb5_kt_close(context, kt); + if (ret) { + com_err(whoami, ret, "while closing keytab"); + exit(1); + } + + ret = kadm5_destroy(handle); + if (ret) { + com_err(whoami, ret, "while closing kadmin connection"); + exit(1); + } + + return 0; +} + + + + + + |
