mirror of
https://github.com/samba-team/samba.git
synced 2025-01-11 05:18:09 +03:00
s4-credentials Add explicit event context handling to Kerberos calls (only)
By setting the event context to use for this operation (only) onto the krb5_context just before we call that operation, we can try and emulate the specification of an event context to the actual send_to_kdc() This eliminates the specification of an event context to many other cli_credentials calls, and the last use of event_context_find() Special care is taken to restore the event context in the event of nesting in the send_to_kdc function. Andrew Bartlett
This commit is contained in:
parent
5cd9495fb3
commit
42127cdbb0
@ -727,7 +727,7 @@ _PUBLIC_ void cli_credentials_guess(struct cli_credentials *cred,
|
||||
}
|
||||
|
||||
if (cli_credentials_get_kerberos_state(cred) != CRED_DONT_USE_KERBEROS) {
|
||||
cli_credentials_set_ccache(cred, event_context_find(cred), lp_ctx, NULL, CRED_GUESS_FILE,
|
||||
cli_credentials_set_ccache(cred, lp_ctx, NULL, CRED_GUESS_FILE,
|
||||
&error_string);
|
||||
}
|
||||
}
|
||||
|
@ -168,7 +168,6 @@ NTSTATUS cli_credentials_get_ntlm_response(struct cli_credentials *cred, TALLOC_
|
||||
const char *cli_credentials_get_realm(struct cli_credentials *cred);
|
||||
const char *cli_credentials_get_username(struct cli_credentials *cred);
|
||||
int cli_credentials_get_krb5_context(struct cli_credentials *cred,
|
||||
struct tevent_context *event_ctx,
|
||||
struct loadparm_context *lp_ctx,
|
||||
struct smb_krb5_context **smb_krb5_context);
|
||||
int cli_credentials_get_ccache(struct cli_credentials *cred,
|
||||
@ -182,7 +181,6 @@ int cli_credentials_get_named_ccache(struct cli_credentials *cred,
|
||||
char *ccache_name,
|
||||
struct ccache_container **ccc, const char **error_string);
|
||||
int cli_credentials_get_keytab(struct cli_credentials *cred,
|
||||
struct tevent_context *event_ctx,
|
||||
struct loadparm_context *lp_ctx,
|
||||
struct keytab_container **_ktc);
|
||||
const char *cli_credentials_get_domain(struct cli_credentials *cred);
|
||||
@ -193,7 +191,6 @@ void cli_credentials_set_conf(struct cli_credentials *cred,
|
||||
struct loadparm_context *lp_ctx);
|
||||
const char *cli_credentials_get_principal(struct cli_credentials *cred, TALLOC_CTX *mem_ctx);
|
||||
int cli_credentials_get_server_gss_creds(struct cli_credentials *cred,
|
||||
struct tevent_context *event_ctx,
|
||||
struct loadparm_context *lp_ctx,
|
||||
struct gssapi_creds_container **_gcc);
|
||||
int cli_credentials_get_client_gss_creds(struct cli_credentials *cred,
|
||||
@ -238,7 +235,6 @@ void cli_credentials_set_netlogon_creds(struct cli_credentials *cred,
|
||||
NTSTATUS cli_credentials_set_krb5_context(struct cli_credentials *cred,
|
||||
struct smb_krb5_context *smb_krb5_context);
|
||||
NTSTATUS cli_credentials_set_stored_principal(struct cli_credentials *cred,
|
||||
struct tevent_context *event_ctx,
|
||||
struct loadparm_context *lp_ctx,
|
||||
const char *serviceprincipal);
|
||||
NTSTATUS cli_credentials_set_machine_account(struct cli_credentials *cred,
|
||||
@ -265,14 +261,12 @@ bool cli_credentials_set_ntlm_response(struct cli_credentials *cred,
|
||||
const DATA_BLOB *nt_response,
|
||||
enum credentials_obtained obtained);
|
||||
int cli_credentials_set_keytab_name(struct cli_credentials *cred,
|
||||
struct tevent_context *event_ctx,
|
||||
struct loadparm_context *lp_ctx,
|
||||
const char *keytab_name,
|
||||
enum credentials_obtained obtained);
|
||||
void cli_credentials_set_gensec_features(struct cli_credentials *creds, uint32_t gensec_features);
|
||||
uint32_t cli_credentials_get_gensec_features(struct cli_credentials *creds);
|
||||
int cli_credentials_set_ccache(struct cli_credentials *cred,
|
||||
struct tevent_context *event_ctx,
|
||||
struct loadparm_context *lp_ctx,
|
||||
const char *name,
|
||||
enum credentials_obtained obtained,
|
||||
@ -291,7 +285,6 @@ const char *cli_credentials_get_target_service(struct cli_credentials *cred);
|
||||
enum credentials_use_kerberos cli_credentials_get_kerberos_state(struct cli_credentials *creds);
|
||||
enum credentials_krb_forwardable cli_credentials_get_krb_forwardable(struct cli_credentials *creds);
|
||||
NTSTATUS cli_credentials_set_secrets(struct cli_credentials *cred,
|
||||
struct tevent_context *event_ctx,
|
||||
struct loadparm_context *lp_ctx,
|
||||
struct ldb_context *ldb,
|
||||
const char *base,
|
||||
|
@ -32,7 +32,6 @@
|
||||
#include "param/param.h"
|
||||
|
||||
_PUBLIC_ int cli_credentials_get_krb5_context(struct cli_credentials *cred,
|
||||
struct tevent_context *event_ctx,
|
||||
struct loadparm_context *lp_ctx,
|
||||
struct smb_krb5_context **smb_krb5_context)
|
||||
{
|
||||
@ -42,7 +41,7 @@ _PUBLIC_ int cli_credentials_get_krb5_context(struct cli_credentials *cred,
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = smb_krb5_init_context(cred, event_ctx, lp_ctx,
|
||||
ret = smb_krb5_init_context(cred, NULL, lp_ctx,
|
||||
&cred->smb_krb5_context);
|
||||
if (ret) {
|
||||
cred->smb_krb5_context = NULL;
|
||||
@ -126,7 +125,6 @@ static int free_dccache(struct ccache_container *ccc) {
|
||||
}
|
||||
|
||||
_PUBLIC_ int cli_credentials_set_ccache(struct cli_credentials *cred,
|
||||
struct tevent_context *event_ctx,
|
||||
struct loadparm_context *lp_ctx,
|
||||
const char *name,
|
||||
enum credentials_obtained obtained,
|
||||
@ -145,7 +143,7 @@ _PUBLIC_ int cli_credentials_set_ccache(struct cli_credentials *cred,
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
ret = cli_credentials_get_krb5_context(cred, event_ctx, lp_ctx,
|
||||
ret = cli_credentials_get_krb5_context(cred, lp_ctx,
|
||||
&ccc->smb_krb5_context);
|
||||
if (ret) {
|
||||
(*error_string) = error_message(ret);
|
||||
@ -204,7 +202,6 @@ _PUBLIC_ int cli_credentials_set_ccache(struct cli_credentials *cred,
|
||||
|
||||
|
||||
static int cli_credentials_new_ccache(struct cli_credentials *cred,
|
||||
struct tevent_context *event_ctx,
|
||||
struct loadparm_context *lp_ctx,
|
||||
char *ccache_name,
|
||||
struct ccache_container **_ccc,
|
||||
@ -217,7 +214,7 @@ static int cli_credentials_new_ccache(struct cli_credentials *cred,
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
ret = cli_credentials_get_krb5_context(cred, event_ctx, lp_ctx,
|
||||
ret = cli_credentials_get_krb5_context(cred, lp_ctx,
|
||||
&ccc->smb_krb5_context);
|
||||
if (ret) {
|
||||
talloc_free(ccc);
|
||||
@ -294,12 +291,12 @@ _PUBLIC_ int cli_credentials_get_named_ccache(struct cli_credentials *cred,
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
ret = cli_credentials_new_ccache(cred, event_ctx, lp_ctx, ccache_name, ccc, error_string);
|
||||
ret = cli_credentials_new_ccache(cred, lp_ctx, ccache_name, ccc, error_string);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = kinit_to_ccache(cred, cred, (*ccc)->smb_krb5_context, (*ccc)->ccache, &obtained, error_string);
|
||||
ret = kinit_to_ccache(cred, cred, (*ccc)->smb_krb5_context, event_ctx, (*ccc)->ccache, &obtained, error_string);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
@ -529,7 +526,6 @@ _PUBLIC_ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred,
|
||||
*/
|
||||
|
||||
int cli_credentials_set_client_gss_creds(struct cli_credentials *cred,
|
||||
struct tevent_context *event_ctx,
|
||||
struct loadparm_context *lp_ctx,
|
||||
gss_cred_id_t gssapi_cred,
|
||||
enum credentials_obtained obtained,
|
||||
@ -549,7 +545,7 @@ _PUBLIC_ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred,
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
ret = cli_credentials_new_ccache(cred, event_ctx, lp_ctx, NULL, &ccc, error_string);
|
||||
ret = cli_credentials_new_ccache(cred, lp_ctx, NULL, &ccc, error_string);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
@ -589,9 +585,8 @@ _PUBLIC_ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred,
|
||||
* it will be generated from the password.
|
||||
*/
|
||||
_PUBLIC_ int cli_credentials_get_keytab(struct cli_credentials *cred,
|
||||
struct tevent_context *event_ctx,
|
||||
struct loadparm_context *lp_ctx,
|
||||
struct keytab_container **_ktc)
|
||||
struct loadparm_context *lp_ctx,
|
||||
struct keytab_container **_ktc)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
struct keytab_container *ktc;
|
||||
@ -608,7 +603,7 @@ _PUBLIC_ int cli_credentials_get_keytab(struct cli_credentials *cred,
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
ret = cli_credentials_get_krb5_context(cred, event_ctx, lp_ctx,
|
||||
ret = cli_credentials_get_krb5_context(cred, lp_ctx,
|
||||
&smb_krb5_context);
|
||||
if (ret) {
|
||||
return ret;
|
||||
@ -640,10 +635,9 @@ _PUBLIC_ int cli_credentials_get_keytab(struct cli_credentials *cred,
|
||||
* FILE:/etc/krb5.keytab), open it and attach it */
|
||||
|
||||
_PUBLIC_ int cli_credentials_set_keytab_name(struct cli_credentials *cred,
|
||||
struct tevent_context *event_ctx,
|
||||
struct loadparm_context *lp_ctx,
|
||||
const char *keytab_name,
|
||||
enum credentials_obtained obtained)
|
||||
struct loadparm_context *lp_ctx,
|
||||
const char *keytab_name,
|
||||
enum credentials_obtained obtained)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
struct keytab_container *ktc;
|
||||
@ -654,7 +648,7 @@ _PUBLIC_ int cli_credentials_set_keytab_name(struct cli_credentials *cred,
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = cli_credentials_get_krb5_context(cred, event_ctx, lp_ctx, &smb_krb5_context);
|
||||
ret = cli_credentials_get_krb5_context(cred, lp_ctx, &smb_krb5_context);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
@ -682,9 +676,8 @@ _PUBLIC_ int cli_credentials_set_keytab_name(struct cli_credentials *cred,
|
||||
/* Get server gss credentials (in gsskrb5, this means the keytab) */
|
||||
|
||||
_PUBLIC_ int cli_credentials_get_server_gss_creds(struct cli_credentials *cred,
|
||||
struct tevent_context *event_ctx,
|
||||
struct loadparm_context *lp_ctx,
|
||||
struct gssapi_creds_container **_gcc)
|
||||
struct loadparm_context *lp_ctx,
|
||||
struct gssapi_creds_container **_gcc)
|
||||
{
|
||||
int ret = 0;
|
||||
OM_uint32 maj_stat, min_stat;
|
||||
@ -701,7 +694,7 @@ _PUBLIC_ int cli_credentials_get_server_gss_creds(struct cli_credentials *cred,
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
ret = cli_credentials_get_krb5_context(cred, event_ctx, lp_ctx, &smb_krb5_context);
|
||||
ret = cli_credentials_get_krb5_context(cred, lp_ctx, &smb_krb5_context);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
@ -720,7 +713,7 @@ _PUBLIC_ int cli_credentials_get_server_gss_creds(struct cli_credentials *cred,
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = cli_credentials_get_keytab(cred, event_ctx, lp_ctx, &ktc);
|
||||
ret = cli_credentials_get_keytab(cred, lp_ctx, &ktc);
|
||||
if (ret) {
|
||||
DEBUG(1, ("Failed to get keytab for GSSAPI server: %s\n", error_message(ret)));
|
||||
return ret;
|
||||
|
@ -33,7 +33,6 @@ struct gssapi_creds_container {
|
||||
|
||||
/* Manually prototyped here to avoid needing gss headers in most callers */
|
||||
int cli_credentials_set_client_gss_creds(struct cli_credentials *cred,
|
||||
struct tevent_context *event_ctx,
|
||||
struct loadparm_context *lp_ctx,
|
||||
gss_cred_id_t gssapi_cred,
|
||||
enum credentials_obtained obtained,
|
||||
|
@ -42,7 +42,6 @@
|
||||
* @retval NTSTATUS error detailing any failure
|
||||
*/
|
||||
_PUBLIC_ NTSTATUS cli_credentials_set_secrets(struct cli_credentials *cred,
|
||||
struct tevent_context *event_ctx,
|
||||
struct loadparm_context *lp_ctx,
|
||||
struct ldb_context *ldb,
|
||||
const char *base,
|
||||
@ -180,7 +179,7 @@ _PUBLIC_ NTSTATUS cli_credentials_set_secrets(struct cli_credentials *cred,
|
||||
* (chewing CPU time) from the password */
|
||||
keytab = keytab_name_from_msg(cred, ldb, msg);
|
||||
if (keytab) {
|
||||
cli_credentials_set_keytab_name(cred, event_ctx, lp_ctx, keytab, CRED_SPECIFIED);
|
||||
cli_credentials_set_keytab_name(cred, lp_ctx, keytab, CRED_SPECIFIED);
|
||||
talloc_free(keytab);
|
||||
}
|
||||
talloc_free(mem_ctx);
|
||||
@ -205,9 +204,9 @@ _PUBLIC_ NTSTATUS cli_credentials_set_machine_account(struct cli_credentials *cr
|
||||
* any more */
|
||||
cred->machine_account_pending = false;
|
||||
filter = talloc_asprintf(cred, SECRETS_PRIMARY_DOMAIN_FILTER,
|
||||
cli_credentials_get_domain(cred));
|
||||
status = cli_credentials_set_secrets(cred, event_context_find(cred), lp_ctx, NULL,
|
||||
SECRETS_PRIMARY_DOMAIN_DN,
|
||||
cli_credentials_get_domain(cred));
|
||||
status = cli_credentials_set_secrets(cred, lp_ctx, NULL,
|
||||
SECRETS_PRIMARY_DOMAIN_DN,
|
||||
filter, &error_string);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
DEBUG(1, ("Could not find machine account in secrets database: %s: %s", nt_errstr(status), error_string));
|
||||
@ -223,7 +222,6 @@ _PUBLIC_ NTSTATUS cli_credentials_set_machine_account(struct cli_credentials *cr
|
||||
* @retval NTSTATUS error detailing any failure
|
||||
*/
|
||||
NTSTATUS cli_credentials_set_krbtgt(struct cli_credentials *cred,
|
||||
struct tevent_context *event_ctx,
|
||||
struct loadparm_context *lp_ctx)
|
||||
{
|
||||
NTSTATUS status;
|
||||
@ -236,7 +234,7 @@ NTSTATUS cli_credentials_set_krbtgt(struct cli_credentials *cred,
|
||||
filter = talloc_asprintf(cred, SECRETS_KRBTGT_SEARCH,
|
||||
cli_credentials_get_realm(cred),
|
||||
cli_credentials_get_domain(cred));
|
||||
status = cli_credentials_set_secrets(cred, event_ctx, lp_ctx, NULL,
|
||||
status = cli_credentials_set_secrets(cred, lp_ctx, NULL,
|
||||
SECRETS_PRINCIPALS_DN,
|
||||
filter, &error_string);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
@ -253,7 +251,6 @@ NTSTATUS cli_credentials_set_krbtgt(struct cli_credentials *cred,
|
||||
* @retval NTSTATUS error detailing any failure
|
||||
*/
|
||||
_PUBLIC_ NTSTATUS cli_credentials_set_stored_principal(struct cli_credentials *cred,
|
||||
struct tevent_context *event_ctx,
|
||||
struct loadparm_context *lp_ctx,
|
||||
const char *serviceprincipal)
|
||||
{
|
||||
@ -268,7 +265,7 @@ _PUBLIC_ NTSTATUS cli_credentials_set_stored_principal(struct cli_credentials *c
|
||||
cli_credentials_get_realm(cred),
|
||||
cli_credentials_get_domain(cred),
|
||||
serviceprincipal);
|
||||
status = cli_credentials_set_secrets(cred, event_ctx, lp_ctx, NULL,
|
||||
status = cli_credentials_set_secrets(cred, lp_ctx, NULL,
|
||||
SECRETS_PRINCIPALS_DN, filter,
|
||||
&error_string);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
|
@ -147,7 +147,6 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security)
|
||||
{
|
||||
struct gensec_gssapi_state *gensec_gssapi_state;
|
||||
krb5_error_code ret;
|
||||
struct gsskrb5_send_to_kdc send_to_kdc;
|
||||
const char *realm;
|
||||
|
||||
gensec_gssapi_state = talloc(gensec_security, struct gensec_gssapi_state);
|
||||
@ -209,7 +208,7 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security)
|
||||
gensec_gssapi_state->pac = data_blob(NULL, 0);
|
||||
|
||||
ret = smb_krb5_init_context(gensec_gssapi_state,
|
||||
gensec_security->event_ctx,
|
||||
NULL,
|
||||
gensec_security->settings->lp_ctx,
|
||||
&gensec_gssapi_state->smb_krb5_context);
|
||||
if (ret) {
|
||||
@ -237,16 +236,6 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security)
|
||||
|
||||
talloc_set_destructor(gensec_gssapi_state, gensec_gssapi_destructor);
|
||||
|
||||
send_to_kdc.func = smb_krb5_send_and_recv_func;
|
||||
send_to_kdc.ptr = gensec_security->event_ctx;
|
||||
|
||||
ret = gsskrb5_set_send_to_kdc(&send_to_kdc);
|
||||
if (ret) {
|
||||
DEBUG(1,("gensec_krb5_start: gsskrb5_set_send_to_kdc failed\n"));
|
||||
talloc_free(gensec_gssapi_state);
|
||||
return NT_STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
realm = lpcfg_realm(gensec_security->settings->lp_ctx);
|
||||
if (realm != NULL) {
|
||||
ret = gsskrb5_set_default_realm(realm);
|
||||
@ -290,7 +279,6 @@ static NTSTATUS gensec_gssapi_server_start(struct gensec_security *gensec_securi
|
||||
return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
|
||||
} else {
|
||||
ret = cli_credentials_get_server_gss_creds(machine_account,
|
||||
gensec_security->event_ctx,
|
||||
gensec_security->settings->lp_ctx, &gcc);
|
||||
if (ret) {
|
||||
DEBUG(1, ("Aquiring acceptor credentials failed: %s\n",
|
||||
@ -469,6 +457,17 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security,
|
||||
switch (gensec_security->gensec_role) {
|
||||
case GENSEC_CLIENT:
|
||||
{
|
||||
struct gsskrb5_send_to_kdc send_to_kdc;
|
||||
krb5_error_code ret;
|
||||
send_to_kdc.func = smb_krb5_send_and_recv_func;
|
||||
send_to_kdc.ptr = gensec_security->event_ctx;
|
||||
|
||||
min_stat = gsskrb5_set_send_to_kdc(&send_to_kdc);
|
||||
if (min_stat) {
|
||||
DEBUG(1,("gensec_krb5_start: gsskrb5_set_send_to_kdc failed\n"));
|
||||
return NT_STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
maj_stat = gss_init_sec_context(&min_stat,
|
||||
gensec_gssapi_state->client_cred->creds,
|
||||
&gensec_gssapi_state->gssapi_context,
|
||||
@ -485,6 +484,16 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security,
|
||||
if (gss_oid_p) {
|
||||
gensec_gssapi_state->gss_oid = gss_oid_p;
|
||||
}
|
||||
|
||||
send_to_kdc.func = smb_krb5_send_and_recv_func;
|
||||
send_to_kdc.ptr = NULL;
|
||||
|
||||
ret = gsskrb5_set_send_to_kdc(&send_to_kdc);
|
||||
if (ret) {
|
||||
DEBUG(1,("gensec_krb5_start: gsskrb5_set_send_to_kdc failed\n"));
|
||||
return NT_STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case GENSEC_SERVER:
|
||||
@ -1369,7 +1378,6 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi
|
||||
cli_credentials_set_anonymous(session_info->credentials);
|
||||
|
||||
ret = cli_credentials_set_client_gss_creds(session_info->credentials,
|
||||
gensec_security->event_ctx,
|
||||
gensec_security->settings->lp_ctx,
|
||||
gensec_gssapi_state->delegated_cred_handle,
|
||||
CRED_SPECIFIED, &error_string);
|
||||
|
@ -119,7 +119,6 @@ static NTSTATUS gensec_krb5_start(struct gensec_security *gensec_security, bool
|
||||
talloc_set_destructor(gensec_krb5_state, gensec_krb5_destroy);
|
||||
|
||||
if (cli_credentials_get_krb5_context(creds,
|
||||
gensec_security->event_ctx,
|
||||
gensec_security->settings->lp_ctx, &gensec_krb5_state->smb_krb5_context)) {
|
||||
talloc_free(gensec_krb5_state);
|
||||
return NT_STATUS_INTERNAL_ERROR;
|
||||
@ -240,6 +239,7 @@ static NTSTATUS gensec_krb5_common_client_start(struct gensec_security *gensec_s
|
||||
const char *error_string;
|
||||
const char *principal;
|
||||
krb5_data in_data;
|
||||
struct tevent_context *previous_ev;
|
||||
|
||||
hostname = gensec_get_target_hostname(gensec_security);
|
||||
if (!hostname) {
|
||||
@ -299,6 +299,12 @@ static NTSTATUS gensec_krb5_common_client_start(struct gensec_security *gensec_s
|
||||
}
|
||||
in_data.length = 0;
|
||||
|
||||
/* Do this every time, in case we have weird recursive issues here */
|
||||
ret = smb_krb5_context_set_event_ctx(gensec_krb5_state->smb_krb5_context, gensec_security->event_ctx, &previous_ev);
|
||||
if (ret != 0) {
|
||||
DEBUG(1, ("gensec_krb5_start: Setting event context failed\n"));
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
if (principal) {
|
||||
krb5_principal target_principal;
|
||||
ret = krb5_parse_name(gensec_krb5_state->smb_krb5_context->krb5_context, principal,
|
||||
@ -322,6 +328,9 @@ static NTSTATUS gensec_krb5_common_client_start(struct gensec_security *gensec_s
|
||||
&in_data, ccache_container->ccache,
|
||||
&gensec_krb5_state->enc_ticket);
|
||||
}
|
||||
|
||||
smb_krb5_context_remove_event_ctx(gensec_krb5_state->smb_krb5_context, previous_ev, gensec_security->event_ctx);
|
||||
|
||||
switch (ret) {
|
||||
case 0:
|
||||
return NT_STATUS_OK;
|
||||
@ -488,7 +497,6 @@ static NTSTATUS gensec_krb5_update(struct gensec_security *gensec_security,
|
||||
|
||||
/* Grab the keytab, however generated */
|
||||
ret = cli_credentials_get_keytab(gensec_get_credentials(gensec_security),
|
||||
gensec_security->event_ctx,
|
||||
gensec_security->settings->lp_ctx, &keytab);
|
||||
if (ret) {
|
||||
return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
|
||||
|
@ -21,8 +21,9 @@
|
||||
*/
|
||||
|
||||
krb5_error_code kinit_to_ccache(TALLOC_CTX *parent_ctx,
|
||||
struct cli_credentials *credentials,
|
||||
struct smb_krb5_context *smb_krb5_context,
|
||||
krb5_ccache ccache,
|
||||
enum credentials_obtained *obtained,
|
||||
const char **error_string);
|
||||
struct cli_credentials *credentials,
|
||||
struct smb_krb5_context *smb_krb5_context,
|
||||
struct tevent_context *event_ctx,
|
||||
krb5_ccache ccache,
|
||||
enum credentials_obtained *obtained,
|
||||
const char **error_string);
|
||||
|
@ -332,6 +332,7 @@ krb5_error_code principal_from_credentials(TALLOC_CTX *parent_ctx,
|
||||
krb5_error_code kinit_to_ccache(TALLOC_CTX *parent_ctx,
|
||||
struct cli_credentials *credentials,
|
||||
struct smb_krb5_context *smb_krb5_context,
|
||||
struct tevent_context *event_ctx,
|
||||
krb5_ccache ccache,
|
||||
enum credentials_obtained *obtained,
|
||||
const char **error_string)
|
||||
@ -392,6 +393,13 @@ krb5_error_code principal_from_credentials(TALLOC_CTX *parent_ctx,
|
||||
|
||||
tries = 2;
|
||||
while (tries--) {
|
||||
struct tevent_context *previous_ev;
|
||||
/* Do this every time, in case we have weird recursive issues here */
|
||||
ret = smb_krb5_context_set_event_ctx(smb_krb5_context, event_ctx, &previous_ev);
|
||||
if (ret) {
|
||||
talloc_free(mem_ctx);
|
||||
return ret;
|
||||
}
|
||||
if (password) {
|
||||
ret = kerberos_kinit_password_cc(smb_krb5_context->krb5_context, ccache,
|
||||
princ, password,
|
||||
@ -399,6 +407,7 @@ krb5_error_code principal_from_credentials(TALLOC_CTX *parent_ctx,
|
||||
krb_options,
|
||||
NULL, &kdc_time);
|
||||
} else if (impersonate_principal) {
|
||||
talloc_free(mem_ctx);
|
||||
(*error_string) = "INTERNAL error: Cannot impersonate principal with just a keyblock. A password must be specified in the credentials";
|
||||
return EINVAL;
|
||||
} else {
|
||||
@ -411,6 +420,7 @@ krb5_error_code principal_from_credentials(TALLOC_CTX *parent_ctx,
|
||||
talloc_free(mem_ctx);
|
||||
(*error_string) = "kinit_to_ccache: No password available for kinit\n";
|
||||
krb5_get_init_creds_opt_free(smb_krb5_context->krb5_context, krb_options);
|
||||
smb_krb5_context_remove_event_ctx(smb_krb5_context, previous_ev, event_ctx);
|
||||
return EINVAL;
|
||||
}
|
||||
ret = krb5_keyblock_init(smb_krb5_context->krb5_context,
|
||||
@ -427,6 +437,8 @@ krb5_error_code principal_from_credentials(TALLOC_CTX *parent_ctx,
|
||||
}
|
||||
}
|
||||
|
||||
smb_krb5_context_remove_event_ctx(smb_krb5_context, previous_ev, event_ctx);
|
||||
|
||||
if (ret == KRB5KRB_AP_ERR_SKEW || ret == KRB5_KDCREP_SKEW) {
|
||||
/* Perhaps we have been given an invalid skew, so try again without it */
|
||||
time_t t = time(NULL);
|
||||
@ -460,6 +472,7 @@ krb5_error_code principal_from_credentials(TALLOC_CTX *parent_ctx,
|
||||
ret = kinit_to_ccache(parent_ctx,
|
||||
credentials,
|
||||
smb_krb5_context,
|
||||
event_ctx,
|
||||
ccache, obtained,
|
||||
error_string);
|
||||
}
|
||||
|
@ -211,18 +211,37 @@ krb5_error_code smb_krb5_send_and_recv_func(krb5_context context,
|
||||
struct addrinfo *ai, *a;
|
||||
struct smb_krb5_socket *smb_krb5;
|
||||
|
||||
struct tevent_context *ev = talloc_get_type(data, struct tevent_context);
|
||||
DATA_BLOB send_blob;
|
||||
|
||||
DATA_BLOB send_blob = data_blob_const(send_buf->data, send_buf->length);
|
||||
struct tevent_context *ev;
|
||||
TALLOC_CTX *tmp_ctx = talloc_new(NULL);
|
||||
if (!tmp_ctx) {
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
if (!data) {
|
||||
/* If no event context was available, then create one for this loop */
|
||||
ev = tevent_context_init(tmp_ctx);
|
||||
if (!ev) {
|
||||
talloc_free(tmp_ctx);
|
||||
return ENOMEM;
|
||||
}
|
||||
} else {
|
||||
ev = talloc_get_type_abort(data, struct tevent_context);
|
||||
}
|
||||
|
||||
send_blob = data_blob_const(send_buf->data, send_buf->length);
|
||||
|
||||
ret = krb5_krbhst_get_addrinfo(context, hi, &ai);
|
||||
if (ret) {
|
||||
talloc_free(tmp_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (a = ai; a; a = ai->ai_next) {
|
||||
smb_krb5 = talloc(NULL, struct smb_krb5_socket);
|
||||
smb_krb5 = talloc(tmp_ctx, struct smb_krb5_socket);
|
||||
if (!smb_krb5) {
|
||||
talloc_free(tmp_ctx);
|
||||
return ENOMEM;
|
||||
}
|
||||
smb_krb5->hi = hi;
|
||||
@ -237,7 +256,7 @@ krb5_error_code smb_krb5_send_and_recv_func(krb5_context context,
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
talloc_free(smb_krb5);
|
||||
talloc_free(tmp_ctx);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
@ -250,7 +269,7 @@ krb5_error_code smb_krb5_send_and_recv_func(krb5_context context,
|
||||
status = socket_create(name, SOCKET_TYPE_STREAM, &smb_krb5->sock, 0);
|
||||
break;
|
||||
case KRB5_KRBHST_HTTP:
|
||||
talloc_free(smb_krb5);
|
||||
talloc_free(tmp_ctx);
|
||||
return EINVAL;
|
||||
}
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
@ -319,14 +338,28 @@ krb5_error_code smb_krb5_send_and_recv_func(krb5_context context,
|
||||
packet_send(smb_krb5->packet, smb_krb5->request);
|
||||
break;
|
||||
case KRB5_KRBHST_HTTP:
|
||||
talloc_free(smb_krb5);
|
||||
talloc_free(tmp_ctx);
|
||||
return EINVAL;
|
||||
}
|
||||
while ((NT_STATUS_IS_OK(smb_krb5->status)) && !smb_krb5->reply.length) {
|
||||
if (tevent_loop_once(ev) != 0) {
|
||||
talloc_free(smb_krb5);
|
||||
talloc_free(tmp_ctx);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
/* After each and every event loop, reset the
|
||||
* send_to_kdc pointers to what they were when
|
||||
* we entered this loop. That way, if a
|
||||
* nested event has invalidated them, we put
|
||||
* it back before we return to the heimdal
|
||||
* code */
|
||||
ret = krb5_set_send_to_kdc_func(context,
|
||||
smb_krb5_send_and_recv_func,
|
||||
data);
|
||||
if (ret != 0) {
|
||||
talloc_free(tmp_ctx);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
if (NT_STATUS_EQUAL(smb_krb5->status, NT_STATUS_IO_TIMEOUT)) {
|
||||
talloc_free(smb_krb5);
|
||||
@ -341,13 +374,14 @@ krb5_error_code smb_krb5_send_and_recv_func(krb5_context context,
|
||||
|
||||
ret = krb5_data_copy(recv_buf, smb_krb5->reply.data, smb_krb5->reply.length);
|
||||
if (ret) {
|
||||
talloc_free(smb_krb5);
|
||||
talloc_free(tmp_ctx);
|
||||
return ret;
|
||||
}
|
||||
talloc_free(smb_krb5);
|
||||
|
||||
break;
|
||||
}
|
||||
talloc_free(tmp_ctx);
|
||||
if (a) {
|
||||
return 0;
|
||||
}
|
||||
@ -415,7 +449,7 @@ smb_krb5_init_context_basic(TALLOC_CTX *tmp_ctx,
|
||||
krb5_error_code smb_krb5_init_context(void *parent_ctx,
|
||||
struct tevent_context *ev,
|
||||
struct loadparm_context *lp_ctx,
|
||||
struct smb_krb5_context **smb_krb5_context)
|
||||
struct smb_krb5_context **smb_krb5_context)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
TALLOC_CTX *tmp_ctx;
|
||||
@ -423,7 +457,7 @@ krb5_error_code smb_krb5_init_context(void *parent_ctx,
|
||||
initialize_krb5_error_table();
|
||||
|
||||
tmp_ctx = talloc_new(parent_ctx);
|
||||
*smb_krb5_context = talloc(tmp_ctx, struct smb_krb5_context);
|
||||
*smb_krb5_context = talloc_zero(tmp_ctx, struct smb_krb5_context);
|
||||
|
||||
if (!*smb_krb5_context || !tmp_ctx) {
|
||||
talloc_free(tmp_ctx);
|
||||
@ -463,14 +497,14 @@ krb5_error_code smb_krb5_init_context(void *parent_ctx,
|
||||
krb5_set_warn_dest((*smb_krb5_context)->krb5_context, (*smb_krb5_context)->logf);
|
||||
|
||||
/* Set use of our socket lib */
|
||||
ret = krb5_set_send_to_kdc_func((*smb_krb5_context)->krb5_context,
|
||||
smb_krb5_send_and_recv_func,
|
||||
ev);
|
||||
if (ret) {
|
||||
DEBUG(1,("krb5_set_send_recv_func failed (%s)\n",
|
||||
smb_get_krb5_error_message((*smb_krb5_context)->krb5_context, ret, tmp_ctx)));
|
||||
talloc_free(tmp_ctx);
|
||||
return ret;
|
||||
if (ev) {
|
||||
struct tevent_context *previous_ev;
|
||||
ret = smb_krb5_context_set_event_ctx(*smb_krb5_context,
|
||||
ev, &previous_ev);
|
||||
if (ret) {
|
||||
talloc_free(tmp_ctx);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
talloc_steal(parent_ctx, *smb_krb5_context);
|
||||
@ -484,3 +518,58 @@ krb5_error_code smb_krb5_init_context(void *parent_ctx,
|
||||
return 0;
|
||||
}
|
||||
|
||||
krb5_error_code smb_krb5_context_set_event_ctx(struct smb_krb5_context *smb_krb5_context,
|
||||
struct tevent_context *ev,
|
||||
struct tevent_context **previous_ev)
|
||||
{
|
||||
int ret;
|
||||
if (!ev) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
if (smb_krb5_context->current_ev) {
|
||||
*previous_ev = smb_krb5_context->current_ev;
|
||||
}
|
||||
|
||||
smb_krb5_context->current_ev = talloc_reference(smb_krb5_context, ev);
|
||||
if (!smb_krb5_context->current_ev) {
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
/* Set use of our socket lib */
|
||||
ret = krb5_set_send_to_kdc_func(smb_krb5_context->krb5_context,
|
||||
smb_krb5_send_and_recv_func,
|
||||
ev);
|
||||
if (ret) {
|
||||
TALLOC_CTX *tmp_ctx = talloc_new(NULL);
|
||||
DEBUG(1,("krb5_set_send_recv_func failed (%s)\n",
|
||||
smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, tmp_ctx)));
|
||||
talloc_free(tmp_ctx);
|
||||
talloc_unlink(smb_krb5_context, smb_krb5_context->current_ev);
|
||||
smb_krb5_context->current_ev = NULL;
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
krb5_error_code smb_krb5_context_remove_event_ctx(struct smb_krb5_context *smb_krb5_context,
|
||||
struct tevent_context *previous_ev,
|
||||
struct tevent_context *ev)
|
||||
{
|
||||
int ret;
|
||||
talloc_unlink(smb_krb5_context, ev);
|
||||
/* If there was a mismatch with things happening on a stack, then don't wipe things */
|
||||
smb_krb5_context->current_ev = previous_ev;
|
||||
/* Set use of our socket lib */
|
||||
ret = krb5_set_send_to_kdc_func(smb_krb5_context->krb5_context,
|
||||
smb_krb5_send_and_recv_func,
|
||||
previous_ev);
|
||||
if (ret) {
|
||||
TALLOC_CTX *tmp_ctx = talloc_new(NULL);
|
||||
DEBUG(1,("krb5_set_send_recv_func failed (%s)\n",
|
||||
smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, tmp_ctx)));
|
||||
talloc_free(tmp_ctx);
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -20,6 +20,7 @@
|
||||
struct smb_krb5_context {
|
||||
krb5_context krb5_context;
|
||||
krb5_log_facility *logf;
|
||||
struct tevent_context *current_ev;
|
||||
};
|
||||
|
||||
struct tevent_context;
|
||||
|
@ -55,8 +55,7 @@ static int samdb_credentials_destructor(struct cli_credentials *creds)
|
||||
this returns a static set of system credentials. It is static so
|
||||
that we always get the same pointer in ldb_wrap_connect()
|
||||
*/
|
||||
struct cli_credentials *samdb_credentials(struct tevent_context *event_ctx,
|
||||
struct loadparm_context *lp_ctx)
|
||||
struct cli_credentials *samdb_credentials(struct loadparm_context *lp_ctx)
|
||||
{
|
||||
static struct cli_credentials *static_credentials;
|
||||
struct cli_credentials *cred;
|
||||
@ -77,7 +76,7 @@ struct cli_credentials *samdb_credentials(struct tevent_context *event_ctx,
|
||||
* anyway */
|
||||
cli_credentials_set_kerberos_state(cred, CRED_DONT_USE_KERBEROS);
|
||||
|
||||
if (!NT_STATUS_IS_OK(cli_credentials_set_secrets(cred, event_ctx, lp_ctx, NULL, NULL,
|
||||
if (!NT_STATUS_IS_OK(cli_credentials_set_secrets(cred, lp_ctx, NULL, NULL,
|
||||
SECRETS_LDAP_FILTER, &error_string))) {
|
||||
DEBUG(5, ("(normal if no LDAP backend) %s", error_string));
|
||||
/* Perfectly OK - if not against an LDAP backend */
|
||||
@ -106,7 +105,7 @@ struct ldb_context *samdb_connect(TALLOC_CTX *mem_ctx,
|
||||
int ret;
|
||||
|
||||
url = lpcfg_sam_url(lp_ctx);
|
||||
credentials = samdb_credentials(ev_ctx, lp_ctx);
|
||||
credentials = samdb_credentials(lp_ctx);
|
||||
|
||||
ldb = ldb_wrap_find(url, ev_ctx, lp_ctx, session_info, credentials, flags);
|
||||
if (ldb != NULL)
|
||||
|
@ -519,7 +519,7 @@ bool kpasswdd_process(struct kdc_server *kdc,
|
||||
keytab_name = talloc_asprintf(server_credentials, "HDB:samba4&%p", kdc->base_ctx);
|
||||
|
||||
cli_credentials_set_username(server_credentials, "kadmin/changepw", CRED_SPECIFIED);
|
||||
ret = cli_credentials_set_keytab_name(server_credentials, kdc->task->event_ctx, kdc->task->lp_ctx, keytab_name, CRED_SPECIFIED);
|
||||
ret = cli_credentials_set_keytab_name(server_credentials, kdc->task->lp_ctx, keytab_name, CRED_SPECIFIED);
|
||||
if (ret != 0) {
|
||||
ret = kpasswdd_make_unauth_error_reply(kdc, mem_ctx,
|
||||
KRB5_KPASSWD_HARDERROR,
|
||||
|
@ -226,7 +226,6 @@ static void named_pipe_accept_done(struct tevent_req *subreq)
|
||||
cli_credentials_set_anonymous(creds);
|
||||
|
||||
ret = cli_credentials_set_client_gss_creds(creds,
|
||||
conn->event.ctx,
|
||||
conn->lp_ctx,
|
||||
cred_handle,
|
||||
CRED_SPECIFIED,
|
||||
|
Loading…
Reference in New Issue
Block a user