diff options
Diffstat (limited to 'third_party/heimdal/lib/kadm5')
-rw-r--r-- | third_party/heimdal/lib/kadm5/ad.c | 38 | ||||
-rw-r--r-- | third_party/heimdal/lib/kadm5/common_glue.c | 15 | ||||
-rw-r--r-- | third_party/heimdal/lib/kadm5/context_s.c | 10 | ||||
-rw-r--r-- | third_party/heimdal/lib/kadm5/create_s.c | 8 | ||||
-rw-r--r-- | third_party/heimdal/lib/kadm5/destroy_s.c | 12 | ||||
-rw-r--r-- | third_party/heimdal/lib/kadm5/get_c.c | 2 | ||||
-rw-r--r-- | third_party/heimdal/lib/kadm5/get_princs_c.c | 186 | ||||
-rw-r--r-- | third_party/heimdal/lib/kadm5/get_princs_s.c | 124 | ||||
-rw-r--r-- | third_party/heimdal/lib/kadm5/init_c.c | 52 | ||||
-rw-r--r-- | third_party/heimdal/lib/kadm5/init_s.c | 15 | ||||
-rw-r--r-- | third_party/heimdal/lib/kadm5/iprop.8 | 46 | ||||
-rw-r--r-- | third_party/heimdal/lib/kadm5/ipropd_slave.c | 46 | ||||
-rw-r--r-- | third_party/heimdal/lib/kadm5/libkadm5srv-exports.def | 2 | ||||
-rw-r--r-- | third_party/heimdal/lib/kadm5/private.h | 2 | ||||
-rw-r--r-- | third_party/heimdal/lib/kadm5/version-script-client.map | 5 | ||||
-rw-r--r-- | third_party/heimdal/lib/kadm5/version-script.map | 2 |
16 files changed, 518 insertions, 47 deletions
diff --git a/third_party/heimdal/lib/kadm5/ad.c b/third_party/heimdal/lib/kadm5/ad.c index 58ccf32eacd..b9b9c9023b9 100644 --- a/third_party/heimdal/lib/kadm5/ad.c +++ b/third_party/heimdal/lib/kadm5/ad.c @@ -1066,6 +1066,33 @@ kadm5_ad_get_principals(void *server_handle, } static kadm5_ret_t +kadm5_ad_iter_principals(void *server_handle, + const char *expression, + int (*cb)(void *, const char *), + void *cbdata) +{ + kadm5_ad_context *context = server_handle; + +#ifdef OPENLDAP + kadm5_ret_t ret; + + ret = ad_get_cred(context, NULL); + if (ret) + return ret; + + ret = _kadm5_ad_connect(server_handle); + if (ret) + return ret; + + krb5_set_error_message(context->context, KADM5_RPC_ERROR, "Function not implemented"); + return KADM5_RPC_ERROR; +#else + krb5_set_error_message(context->context, KADM5_RPC_ERROR, "Function not implemented"); + return KADM5_RPC_ERROR; +#endif +} + +static kadm5_ret_t kadm5_ad_get_privs(void *server_handle, uint32_t*privs) { kadm5_ad_context *context = server_handle; @@ -1169,7 +1196,7 @@ kadm5_ad_modify_principal(void *server_handle, if (entry->attributes & KRB5_KDB_REQUIRES_HW_AUTH) i |= UF_SMARTCARD_REQUIRED; else - i &= UF_SMARTCARD_REQUIRED; + i &= ~UF_SMARTCARD_REQUIRED; if (entry->attributes & KRB5_KDB_DISALLOW_SVR) i &= ~UF_WORKSTATION_TRUST_ACCOUNT; else @@ -1388,6 +1415,9 @@ set_funcs(kadm5_ad_context *c) SET(c, lock); SET(c, unlock); SETNOTIMP(c, setkey_principal_3); + SETNOTIMP(c, prune_principal); + SET(c, iter_principals); + SET(c, dup_context); } kadm5_ret_t @@ -1456,6 +1486,12 @@ kadm5_ad_init_with_password_ctx(krb5_context context, } kadm5_ret_t +kadm5_ad_dup_context(void *in, void **out) +{ + return ENOTSUP; +} + +kadm5_ret_t kadm5_ad_init_with_password(const char *client_name, const char *password, const char *service_name, diff --git a/third_party/heimdal/lib/kadm5/common_glue.c b/third_party/heimdal/lib/kadm5/common_glue.c index 9993b0a349e..210bf93b91c 100644 --- a/third_party/heimdal/lib/kadm5/common_glue.c +++ b/third_party/heimdal/lib/kadm5/common_glue.c @@ -39,6 +39,12 @@ RCSID("$Id$"); #define __CALLABLE(F) (((kadm5_common_context*)server_handle)->funcs.F != 0) kadm5_ret_t +kadm5_dup_context(void *server_handle, void **dup_server_handle) +{ + return __CALL(dup_context, (server_handle, dup_server_handle)); +} + +kadm5_ret_t kadm5_chpass_principal(void *server_handle, krb5_principal princ, const char *password) @@ -223,6 +229,15 @@ kadm5_get_principals(void *server_handle, } kadm5_ret_t +kadm5_iter_principals(void *server_handle, + const char *expression, + int (*cb)(void *, const char *), + void *cbdata) +{ + return __CALL(iter_principals, (server_handle, expression, cb, cbdata)); +} + +kadm5_ret_t kadm5_get_privs(void *server_handle, uint32_t *privs) { diff --git a/third_party/heimdal/lib/kadm5/context_s.c b/third_party/heimdal/lib/kadm5/context_s.c index 0c154ecfef0..5c9b3e31c81 100644 --- a/third_party/heimdal/lib/kadm5/context_s.c +++ b/third_party/heimdal/lib/kadm5/context_s.c @@ -112,6 +112,8 @@ set_funcs(kadm5_server_context *c) SET(c, lock); SET(c, unlock); SET(c, setkey_principal_3); + SET(c, iter_principals); + SET(c, dup_context); } #ifndef NO_UNIX_SOCKETS @@ -250,6 +252,8 @@ _kadm5_s_init_context(kadm5_server_context **ctx, krb5_add_et_list (context, initialize_kadm5_error_table_r); #define is_set(M) (params && params->mask & KADM5_CONFIG_ ## M) + if (params) + (*ctx)->config.mask = params->mask; if (is_set(REALM)) { (*ctx)->config.realm = strdup(params->realm); if ((*ctx)->config.realm == NULL) @@ -275,9 +279,9 @@ _kadm5_s_init_context(kadm5_server_context **ctx, return krb5_enomem(context); } - find_db_spec(*ctx); - - ret = _kadm5_s_init_hooks(*ctx); + ret = find_db_spec(*ctx); + if (ret == 0) + ret = _kadm5_s_init_hooks(*ctx); if (ret != 0) { kadm5_s_destroy(*ctx); *ctx = NULL; diff --git a/third_party/heimdal/lib/kadm5/create_s.c b/third_party/heimdal/lib/kadm5/create_s.c index 1c2ab15f30d..e603497ace2 100644 --- a/third_party/heimdal/lib/kadm5/create_s.c +++ b/third_party/heimdal/lib/kadm5/create_s.c @@ -50,6 +50,14 @@ get_default(kadm5_server_context *context, krb5_principal princ, ret = kadm5_s_get_principal(context, def_principal, def, KADM5_PRINCIPAL_NORMAL_MASK); krb5_free_principal (context->context, def_principal); + + if (ret) { + /* Copy defaults from kadmin/init.c */ + memset(def, 0, sizeof(*def)); + def->max_life = 24 * 60 * 60; + def->max_renewable_life = 7 * def->max_life; + def->attributes = KRB5_KDB_DISALLOW_ALL_TIX; + } return ret; } diff --git a/third_party/heimdal/lib/kadm5/destroy_s.c b/third_party/heimdal/lib/kadm5/destroy_s.c index fc86e5960e6..0558b45c577 100644 --- a/third_party/heimdal/lib/kadm5/destroy_s.c +++ b/third_party/heimdal/lib/kadm5/destroy_s.c @@ -42,10 +42,12 @@ RCSID("$Id$"); static void destroy_config (kadm5_config_params *c) { - free (c->realm); - free (c->dbname); - free (c->acl_file); - free (c->stash_file); + if (!c) + return; + free(c->realm); + free(c->dbname); + free(c->acl_file); + free(c->stash_file); } /* @@ -55,6 +57,8 @@ destroy_config (kadm5_config_params *c) static void destroy_kadm5_log_context (kadm5_log_context *c) { + if (!c) + return; free(c->log_file); if (c->socket_fd != rk_INVALID_SOCKET) rk_closesocket(c->socket_fd); diff --git a/third_party/heimdal/lib/kadm5/get_c.c b/third_party/heimdal/lib/kadm5/get_c.c index 5b2bcca762a..1c1fd9dce80 100644 --- a/third_party/heimdal/lib/kadm5/get_c.c +++ b/third_party/heimdal/lib/kadm5/get_c.c @@ -89,7 +89,7 @@ kadm5_c_get_principal(void *server_handle, out_keep_error: if (ret == 0) - kadm5_ret_principal_ent(sp, ent); + ret = kadm5_ret_principal_ent(sp, ent); krb5_storage_free(sp); krb5_data_free(&reply); return ret; diff --git a/third_party/heimdal/lib/kadm5/get_princs_c.c b/third_party/heimdal/lib/kadm5/get_princs_c.c index 4998223d260..93d7ce7ed1b 100644 --- a/third_party/heimdal/lib/kadm5/get_princs_c.c +++ b/third_party/heimdal/lib/kadm5/get_princs_c.c @@ -66,7 +66,7 @@ kadm5_c_get_principals(void *server_handle, ret = krb5_store_int32(sp, kadm_get_princs); if (ret) goto out; - ret = krb5_store_int32(sp, expression != NULL); + ret = krb5_store_int32(sp, expression != NULL ? 1 : 0); if (ret) goto out; if (expression) { @@ -117,3 +117,187 @@ kadm5_c_get_principals(void *server_handle, krb5_data_free(&reply); return ret; } + +kadm5_ret_t +kadm5_c_iter_principals(void *server_handle, + const char *expression, + int (*cb)(void *, const char *), + void *cbdata) +{ + kadm5_client_context *context = server_handle; + kadm5_ret_t ret; + krb5_storage *sp; + unsigned char buf[1024]; + int32_t tmp; + krb5_data reply; + size_t i; + + ret = _kadm5_connect(server_handle, 0 /* want_write */); + if (ret) + return ret; + + krb5_data_zero(&reply); + + sp = krb5_storage_from_mem(buf, sizeof(buf)); + if (sp == NULL) { + ret = krb5_enomem(context->context); + goto out_keep_error; + } + ret = krb5_store_int32(sp, kadm_get_princs); + if (ret) + goto out; + + /* + * Our protocol has an int boolean for this operation to indicate whether + * there's an expression. What we'll do here is that instead of sending + * just false or trueish, for online iteration we'll send a number other + * than 0 or 1 -- a magic value > 0 and < INT_MAX. + * + * In response we'll expect multiple replies, each with up to some small + * number of principal names. See kadmin/server.c. + */ + ret = krb5_store_int32(sp, 0x55555555); + if (ret) + goto out; + ret = krb5_store_string(sp, expression ? expression : ""); + if (ret) + goto out; + ret = _kadm5_client_send(context, sp); + if (ret) + goto out_keep_error; + ret = _kadm5_client_recv(context, &reply); + if (ret) + goto out_keep_error; + krb5_storage_free(sp); + sp = krb5_storage_from_data (&reply); + if (sp == NULL) { + ret = krb5_enomem(context->context); + goto out_keep_error; + } + ret = krb5_ret_int32(sp, &tmp); + if (ret == 0) + ret = tmp; + + if (ret) + goto out; + + ret = krb5_ret_int32(sp, &tmp); + if (ret) + goto out; + + if (tmp < 0) { + size_t n = -tmp; + int more = 1; + int stop = 0; + + /* The server supports online iteration, hooray! */ + + while (more) { + /* + * We expect any number of chunks, each having `n' names, except + * the last one would have fewer than `n' (possibly zero, even). + * + * After that we expect one more reply with just a final return + * code. + */ + krb5_data_free(&reply); + krb5_storage_free(sp); + sp = NULL; + ret = _kadm5_client_recv(context, &reply); + if (ret == 0 && (sp = krb5_storage_from_data(&reply)) == NULL) + ret = krb5_enomem(context->context); + if (ret) + goto out; + + /* Every chunk begins with a status code */ + ret = krb5_ret_int32(sp, &tmp); + if (ret == 0) + ret = tmp; + if (ret) + goto out; + + /* We expect up to -tmp principals per reply */ + for (i = 0; i < n; i++) { + char *princ = NULL; + + ret = krb5_ret_string(sp, &princ); + if (ret == HEIM_ERR_EOF) { + /* This was the last reply */ + more = 0; + ret = 0; + break; + } + if (ret) + goto out; + if (!stop) { + stop = cb(cbdata, princ); + if (stop) { + /* + * Tell the server to stop. + * + * We use a NOP for this, but with a payload that says + * "don't reply to the NOP" just in case the NOP + * arrives and is processed _after_ the LISTing has + * finished. + */ + krb5_storage_free(sp); + if ((sp = krb5_storage_emem()) && + krb5_store_int32(sp, kadm_nop) == 0 && + krb5_store_int32(sp, 0)) + (void) _kadm5_client_send(context, sp); + } + } + free(princ); + } + + if (!more) { + if (ret == 0) + ret = stop; + break; + } + } + /* Get the final result code */ + krb5_data_free(&reply); + krb5_storage_free(sp); + sp = NULL; + ret = _kadm5_client_recv(context, &reply); + if (ret == 0 && (sp = krb5_storage_from_data(&reply)) == NULL) + ret = krb5_enomem(context->context); + if (ret) + goto out; + ret = krb5_ret_int32(sp, &tmp); + if (ret == 0) + ret = tmp; + if (!stop) { + /* + * Send our "interrupt" after the last chunk if we hand't + * interrupted already. + */ + krb5_storage_free(sp); + if ((sp = krb5_storage_emem()) && + krb5_store_int32(sp, kadm_nop) == 0) + (void) _kadm5_client_send(context, sp); + } + } else { + size_t n = tmp; + + /* Old server -- listing not online */ + for (i = 0; i < n; i++) { + char *princ = NULL; + + ret = krb5_ret_string(sp, &princ); + if (ret) + goto out; + cb(cbdata, princ); + free(princ); + } + } + + out: + krb5_clear_error_message(context->context); + + out_keep_error: + krb5_storage_free(sp); + krb5_data_free(&reply); + return ret; +} diff --git a/third_party/heimdal/lib/kadm5/get_princs_s.c b/third_party/heimdal/lib/kadm5/get_princs_s.c index 27fac2bbb0b..14d3907d759 100644 --- a/third_party/heimdal/lib/kadm5/get_princs_s.c +++ b/third_party/heimdal/lib/kadm5/get_princs_s.c @@ -39,17 +39,27 @@ struct foreach_data { const char *exp; char *exp2; char **princs; - int count; + size_t nalloced; + size_t count; }; static krb5_error_code add_princ(krb5_context context, struct foreach_data *d, char *princ) { - char **tmp; - tmp = realloc(d->princs, (d->count + 1) * sizeof(*tmp)); - if (tmp == NULL) - return krb5_enomem(context); - d->princs = tmp; + + if (d->count == INT_MAX) + return ERANGE; + if (d->nalloced == d->count) { + size_t n = d->nalloced + (d->nalloced >> 1) + 128; /* No O(N^2) pls */ + char **tmp; + + if (SIZE_MAX / sizeof(*tmp) <= n) + return ERANGE; + if ((tmp = realloc(d->princs, n * sizeof(*tmp))) == NULL) + return krb5_enomem(context); + d->princs = tmp; + d->nalloced = n; + } d->princs[d->count++] = princ; return 0; } @@ -84,7 +94,7 @@ kadm5_s_get_principals(void *server_handle, { struct foreach_data d; kadm5_server_context *context = server_handle; - kadm5_ret_t ret; + kadm5_ret_t ret = 0; if (!context->keep_open) { ret = context->db->hdb_open(context->context, context->db, O_RDONLY, 0); @@ -94,33 +104,103 @@ kadm5_s_get_principals(void *server_handle, } } d.exp = expression; - { + d.exp2 = NULL; + if (expression) { krb5_realm r; int aret; ret = krb5_get_default_realm(context->context, &r); - if (ret) - goto out; - aret = asprintf(&d.exp2, "%s@%s", expression, r); - free(r); - if (aret == -1 || d.exp2 == NULL) { - ret = krb5_enomem(context->context); - goto out; - } + if (ret == 0) { + aret = asprintf(&d.exp2, "%s@%s", expression, r); + free(r); + if (aret == -1 || d.exp2 == NULL) + ret = krb5_enomem(context->context); + } } d.princs = NULL; + d.nalloced = 0; d.count = 0; - ret = hdb_foreach(context->context, context->db, HDB_F_ADMIN_DATA, foreach, &d); + if (ret == 0) + ret = hdb_foreach(context->context, context->db, HDB_F_ADMIN_DATA, + foreach, &d); if (ret == 0) ret = add_princ(context->context, &d, NULL); - if (ret == 0){ + if (d.count >= INT_MAX) + *count = INT_MAX; + else + *count = d.count - 1; + if (ret == 0) *princs = d.princs; - *count = d.count - 1; - } else - kadm5_free_name_list(context, d.princs, &d.count); + else + kadm5_free_name_list(context, d.princs, count); + free(d.exp2); + if (!context->keep_open) + context->db->hdb_close(context->context, context->db); + return _kadm5_error_code(ret); +} + +struct foreach_online_data { + const char *exp; + char *exp2; + int (*cb)(void *, const char *); + void *cbdata; +}; + +static krb5_error_code +foreach_online(krb5_context context, HDB *db, hdb_entry *ent, void *data) +{ + struct foreach_online_data *d = data; + krb5_error_code ret; + char *princ = NULL; + + ret = krb5_unparse_name(context, ent->principal, &princ); + if (ret == 0) { + if (!d->exp || + fnmatch(d->exp, princ, 0) == 0 || fnmatch(d->exp2, princ, 0) == 0) + ret = d->cb(d->cbdata, princ); + free(princ); + } + return ret; +} + +kadm5_ret_t +kadm5_s_iter_principals(void *server_handle, + const char *expression, + int (*cb)(void *, const char *), + void *cbdata) +{ + struct foreach_online_data d; + kadm5_server_context *context = server_handle; + kadm5_ret_t ret = 0; + + if (!context->keep_open) { + ret = context->db->hdb_open(context->context, context->db, O_RDONLY, 0); + if (ret) { + krb5_warn(context->context, ret, "opening database"); + return ret; + } + } + d.exp = expression; + d.exp2 = NULL; + d.cb = cb; + d.cbdata = cbdata; + if (expression) { + krb5_realm r; + int aret; + + ret = krb5_get_default_realm(context->context, &r); + if (ret == 0) { + aret = asprintf(&d.exp2, "%s@%s", expression, r); + free(r); + if (aret == -1 || d.exp2 == NULL) + ret = krb5_enomem(context->context); + } + } + if (ret == 0) + ret = hdb_foreach(context->context, context->db, HDB_F_ADMIN_DATA, + foreach_online, &d); free(d.exp2); - out: if (!context->keep_open) context->db->hdb_close(context->context, context->db); return _kadm5_error_code(ret); diff --git a/third_party/heimdal/lib/kadm5/init_c.c b/third_party/heimdal/lib/kadm5/init_c.c index 5d585d1a295..ffbb639581c 100644 --- a/third_party/heimdal/lib/kadm5/init_c.c +++ b/third_party/heimdal/lib/kadm5/init_c.c @@ -78,6 +78,8 @@ set_funcs(kadm5_client_context *c) SET(c, lock); SET(c, unlock); SETNOTIMP(c, setkey_principal_3); + SET(c, iter_principals); + SET(c, dup_context); } kadm5_ret_t @@ -192,6 +194,56 @@ _kadm5_c_init_context(kadm5_client_context **ctx, return 0; } +kadm5_ret_t +kadm5_c_dup_context(void *vin, void **out) +{ + krb5_error_code ret; + kadm5_client_context *in = vin; + krb5_context context = in->context; + kadm5_client_context *ctx; + + *out = NULL; + ctx = malloc(sizeof(*ctx)); + if (ctx == NULL) + return krb5_enomem(in->context); + + + memset(ctx, 0, sizeof(*ctx)); + set_funcs(ctx); + ctx->readonly_kadmind_port = in->readonly_kadmind_port; + ctx->kadmind_port = in->kadmind_port; + + ret = krb5_copy_context(context, &(ctx->context)); + if (ret == 0) { + ctx->my_context = TRUE; + ret = krb5_add_et_list(ctx->context, initialize_kadm5_error_table_r); + } + if (ret == 0 && (ctx->realm = strdup(in->realm)) == NULL) + ret = krb5_enomem(context); + if (ret == 0 && + (ctx->admin_server = strdup(in->admin_server)) == NULL) + ret = krb5_enomem(context); + if (in->readonly_admin_server && + (ctx->readonly_admin_server = strdup(in->readonly_admin_server)) == NULL) + ret = krb5_enomem(context); + if (in->keytab && (ctx->keytab = strdup(in->keytab)) == NULL) + ret = krb5_enomem(context); + if (in->ccache) { + char *fullname = NULL; + + ret = krb5_cc_get_full_name(context, in->ccache, &fullname); + if (ret == 0) + ret = krb5_cc_resolve(context, fullname, &ctx->ccache); + free(fullname); + } + ctx->sock = -1; + if (ret == 0) + *out = ctx; + else + kadm5_c_destroy(ctx); + return ret; +} + static krb5_error_code get_kadm_ticket(krb5_context context, krb5_ccache id, diff --git a/third_party/heimdal/lib/kadm5/init_s.c b/third_party/heimdal/lib/kadm5/init_s.c index 1b1d7f2ff58..35402d88a52 100644 --- a/third_party/heimdal/lib/kadm5/init_s.c +++ b/third_party/heimdal/lib/kadm5/init_s.c @@ -109,6 +109,21 @@ kadm5_s_init_with_context(krb5_context context, } kadm5_ret_t +kadm5_s_dup_context(void *vin, void **out) +{ + kadm5_server_context *in = vin; + kadm5_ret_t ret; + char *p = NULL; + + ret = krb5_unparse_name(in->context, in->caller, &p); + if (ret == 0) + ret = kadm5_s_init_with_context(in->context, p, NULL, + &in->config, 0, 0, out); + free(p); + return ret; +} + +kadm5_ret_t kadm5_s_init_with_password_ctx(krb5_context context, const char *client_name, const char *password, diff --git a/third_party/heimdal/lib/kadm5/iprop.8 b/third_party/heimdal/lib/kadm5/iprop.8 index b881c441a1a..41aac061829 100644 --- a/third_party/heimdal/lib/kadm5/iprop.8 +++ b/third_party/heimdal/lib/kadm5/iprop.8 @@ -68,6 +68,8 @@ .Oo Fl r Ar string \*(Ba Xo Fl Fl realm= Ns Ar string Xc Oc .Oo Fl d Ar file \*(Ba Xo Fl Fl database= Ns Ar file Xc Oc .Oo Fl k Ar kspec \*(Ba Xo Fl Fl keytab= Ns Ar kspec Xc Oc +.Oo Xo Fl Fl no-keytab Xc Oc +.Oo Xo Fl Fl cache= Ns Ar cspec Xc Oc .Op Fl Fl statusfile= Ns Ar file .Op Fl Fl hostname= Ns Ar hostname .Op Fl Fl port= Ns Ar port @@ -125,10 +127,40 @@ This should normally be defined as in .Pa /etc/services or another source of the services database. -The master and slaves -must each have access to a keytab with keys for the -.Nm iprop -service principal on the local host. +.Pp +The +.Nm ipropd-master +and +.Nm ipropd-slave +programs require acceptor and initiator credentials, +respectively, for host-based principals for the +.Ar iprop +service and the fully-qualified hostnames of the hosts on which +they run. +.Pp +The +.Nm ipropd-master +program uses, by default, the HDB-backed keytab +.Ar HDBGET: , +though a file-based keytab can also be specified. +.Pp +The +.Nm ipropd-slave +program uses the default keytab, which is specified by the +.Ev KRB5_KTNAME +environment variable, or the value of the +.Ar default_keytab_name +configuration parameter in the +.Ar [libdefaults] +section. +However, if the +.Fl Fl no-keytab +option is given, then +.Nm ipropd-slave +will use the given or default credentials cache, and it will +expect that cache to be kept fresh externally (such as by the +.Nm kinit +program). .Pp There is a keep-alive feature logged in the master's .Pa slave-stats @@ -150,6 +182,11 @@ Supported options for Keytab for authenticating .Nm ipropd-slave clients. +.It Fl Fl cache= Ns Ar cspec +If the keytab given is the empty string then credentials will be +used from the default credentials cache, or from the +.Ar cspec +if given. .It Fl d Ar file , Fl Fl database= Ns Ar file Database (default per KDC) .It Fl Fl slave-stats-file= Ns Ar file @@ -201,6 +238,7 @@ in the database directory, or in the directory named by the .Ev HEIM_PIDFILE_DIR environment variable. .Sh SEE ALSO +.Xr kinit 1 , .Xr krb5.conf 5 , .Xr hprop 8 , .Xr hpropd 8 , diff --git a/third_party/heimdal/lib/kadm5/ipropd_slave.c b/third_party/heimdal/lib/kadm5/ipropd_slave.c index 2b1be00ea60..f92b20c8569 100644 --- a/third_party/heimdal/lib/kadm5/ipropd_slave.c +++ b/third_party/heimdal/lib/kadm5/ipropd_slave.c @@ -39,6 +39,9 @@ static const char *config_name = "ipropd-slave"; static int verbose; static int async_hdb = 0; +static int no_keytab_flag; +static char *ccache_str; +static char *keytab_str; static krb5_log_facility *log_facility; static char five_min[] = "5 min"; @@ -115,8 +118,7 @@ connect_to_master (krb5_context context, const char *master, } static void -get_creds(krb5_context context, const char *keytab_str, - krb5_ccache *cache, const char *serverhost) +get_creds(krb5_context context, krb5_ccache *cache, const char *serverhost) { krb5_keytab keytab; krb5_principal client; @@ -127,13 +129,33 @@ get_creds(krb5_context context, const char *keytab_str, char keytab_buf[256]; int aret; + if (no_keytab_flag) { + /* We're using an externally refreshed ccache */ + if (*cache == NULL) { + if (ccache_str == NULL) + ret = krb5_cc_default(context, cache); + else + ret = krb5_cc_resolve(context, ccache_str, cache); + if (ret) + krb5_err(context, 1, ret, "Could not resolve the default cache"); + } + return; + } + if (keytab_str == NULL) { ret = krb5_kt_default_name (context, keytab_buf, sizeof(keytab_buf)); - if (ret) - krb5_err (context, 1, ret, "krb5_kt_default_name"); - keytab_str = keytab_buf; + if (ret == 0) { + keytab_str = keytab_buf; + } else { + krb5_warn(context, ret, "Using HDBGET: as the default keytab"); + keytab_str = "HDBGET:"; + } } + if (*cache) + krb5_cc_destroy(context, *cache); + *cache = NULL; + ret = krb5_kt_resolve(context, keytab_str, &keytab); if(ret) krb5_err(context, 1, ret, "%s", keytab_str); @@ -690,7 +712,6 @@ static char *status_file; static char *config_file; static int version_flag; static int help_flag; -static char *keytab_str; static char *port_str; static int detach_from_console; static int daemon_child = -1; @@ -699,8 +720,12 @@ static struct getargs args[] = { { "config-file", 'c', arg_string, &config_file, NULL, NULL }, { "realm", 'r', arg_string, &realm, NULL, NULL }, { "database", 'd', arg_string, &database, "database", "file"}, + { "no-keytab", 0, arg_flag, &no_keytab_flag, + "use externally refreshed cache", NULL }, + { "ccache", 0, arg_string, &ccache_str, + "client credentials", "CCACHE" }, { "keytab", 'k', arg_string, &keytab_str, - "keytab to get authentication from", "kspec" }, + "client credentials keytab", "KEYTAB" }, { "time-lost", 0, arg_string, &server_time_lost, "time before server is considered lost", "time" }, { "status-file", 0, arg_string, &status_file, @@ -740,7 +765,7 @@ main(int argc, char **argv) kadm5_server_context *server_context; kadm5_config_params conf; int master_fd; - krb5_ccache ccache; + krb5_ccache ccache = NULL; krb5_principal server; char **files; int optidx = 0; @@ -858,7 +883,7 @@ main(int argc, char **argv) if (ret) krb5_err(context, 1, ret, "db->close"); - get_creds(context, keytab_str, &ccache, master); + get_creds(context, &ccache, master); ret = krb5_sname_to_principal (context, master, IPROP_NAME, KRB5_NT_SRV_HST, &server); @@ -923,8 +948,7 @@ main(int argc, char **argv) if (auth_context) { krb5_auth_con_free(context, auth_context); auth_context = NULL; - krb5_cc_destroy(context, ccache); - get_creds(context, keytab_str, &ccache, master); + get_creds(context, &ccache, master); } if (verbose) krb5_warnx(context, "authenticating to master"); diff --git a/third_party/heimdal/lib/kadm5/libkadm5srv-exports.def b/third_party/heimdal/lib/kadm5/libkadm5srv-exports.def index 72ba4174c1f..56366ae2046 100644 --- a/third_party/heimdal/lib/kadm5/libkadm5srv-exports.def +++ b/third_party/heimdal/lib/kadm5/libkadm5srv-exports.def @@ -15,6 +15,7 @@ EXPORTS kadm5_delete_policy kadm5_delete_principal kadm5_destroy + kadm5_dup_context kadm5_flush kadm5_free_key_data kadm5_free_name_list @@ -32,6 +33,7 @@ EXPORTS kadm5_init_with_password_ctx kadm5_init_with_skey kadm5_init_with_skey_ctx + kadm5_iter_principals kadm5_lock kadm5_modify_policy kadm5_modify_principal diff --git a/third_party/heimdal/lib/kadm5/private.h b/third_party/heimdal/lib/kadm5/private.h index 88c2f2823d2..1cb8e3918f5 100644 --- a/third_party/heimdal/lib/kadm5/private.h +++ b/third_party/heimdal/lib/kadm5/private.h @@ -68,6 +68,8 @@ struct kadm_func { int, krb5_key_salt_tuple *, krb5_keyblock *, int); kadm5_ret_t (*prune_principal) (void *, krb5_principal, int); + kadm5_ret_t (*iter_principals) (void*, const char*, int (*)(void *, const char *), void *); + kadm5_ret_t (*dup_context) (void*, void **); }; typedef struct kadm5_hook_context { diff --git a/third_party/heimdal/lib/kadm5/version-script-client.map b/third_party/heimdal/lib/kadm5/version-script-client.map index 4d89fabf308..baae30b1173 100644 --- a/third_party/heimdal/lib/kadm5/version-script-client.map +++ b/third_party/heimdal/lib/kadm5/version-script-client.map @@ -11,6 +11,7 @@ HEIMDAL_KADM5_CLIENT_1.0 { kadm5_c_create_principal; kadm5_c_delete_principal; kadm5_c_destroy; + kadm5_c_dup_context; kadm5_c_flush; kadm5_c_get_principal; kadm5_c_get_principals; @@ -21,6 +22,8 @@ HEIMDAL_KADM5_CLIENT_1.0 { kadm5_c_init_with_password_ctx; kadm5_c_init_with_skey; kadm5_c_init_with_skey_ctx; + kadm5_c_iter_principals; + kadm5_c_get_privs; kadm5_c_modify_principal; kadm5_c_prune_principal; kadm5_c_randkey_principal; @@ -30,6 +33,7 @@ HEIMDAL_KADM5_CLIENT_1.0 { kadm5_create_principal; kadm5_delete_principal; kadm5_destroy; + kadm5_dup_context; kadm5_flush; kadm5_free_key_data; kadm5_free_name_list; @@ -43,6 +47,7 @@ HEIMDAL_KADM5_CLIENT_1.0 { kadm5_init_with_password_ctx; kadm5_init_with_skey; kadm5_init_with_skey_ctx; + kadm5_iter_principals; kadm5_modify_principal; kadm5_randkey_principal; kadm5_randkey_principal_3; diff --git a/third_party/heimdal/lib/kadm5/version-script.map b/third_party/heimdal/lib/kadm5/version-script.map index e4b4100f334..6de88fc2217 100644 --- a/third_party/heimdal/lib/kadm5/version-script.map +++ b/third_party/heimdal/lib/kadm5/version-script.map @@ -16,6 +16,7 @@ HEIMDAL_KAMD5_SERVER_1.0 { kadm5_create_principal_3; kadm5_delete_principal; kadm5_destroy; + kadm5_dup_context; kadm5_decrypt_key; kadm5_delete_policy; kadm5_flush; @@ -35,6 +36,7 @@ HEIMDAL_KAMD5_SERVER_1.0 { kadm5_init_with_password_ctx; kadm5_init_with_skey; kadm5_init_with_skey_ctx; + kadm5_iter_principals; kadm5_lock; kadm5_modify_principal; kadm5_modify_policy; |