From e04bab4a19658009e53949b814a58d177966a9cd Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 20 Apr 2011 17:39:50 +1000 Subject: libcli/auth Move Samba4's gssapi_error_string from GENSEC to libcli/auth This will allow the GSSAPI PAC fetch code to use it. Andrew Bartlett --- source4/auth/gensec/gensec_gssapi.c | 38 ------------------------------------- 1 file changed, 38 deletions(-) (limited to 'source4/auth') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 59029e6fc9..0dfc38d288 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -47,44 +47,6 @@ _PUBLIC_ NTSTATUS gensec_gssapi_init(void); static size_t gensec_gssapi_max_input_size(struct gensec_security *gensec_security); static size_t gensec_gssapi_max_wrapped_size(struct gensec_security *gensec_security); -static char *gssapi_error_string(TALLOC_CTX *mem_ctx, - OM_uint32 maj_stat, OM_uint32 min_stat, - const gss_OID mech) -{ - OM_uint32 disp_min_stat, disp_maj_stat; - gss_buffer_desc maj_error_message; - gss_buffer_desc min_error_message; - char *maj_error_string, *min_error_string; - OM_uint32 msg_ctx = 0; - - char *ret; - - maj_error_message.value = NULL; - min_error_message.value = NULL; - maj_error_message.length = 0; - min_error_message.length = 0; - - disp_maj_stat = gss_display_status(&disp_min_stat, maj_stat, GSS_C_GSS_CODE, - mech, &msg_ctx, &maj_error_message); - disp_maj_stat = gss_display_status(&disp_min_stat, min_stat, GSS_C_MECH_CODE, - mech, &msg_ctx, &min_error_message); - - maj_error_string = talloc_strndup(mem_ctx, (char *)maj_error_message.value, maj_error_message.length); - - min_error_string = talloc_strndup(mem_ctx, (char *)min_error_message.value, min_error_message.length); - - ret = talloc_asprintf(mem_ctx, "%s: %s", maj_error_string, min_error_string); - - talloc_free(maj_error_string); - talloc_free(min_error_string); - - gss_release_buffer(&disp_min_stat, &maj_error_message); - gss_release_buffer(&disp_min_stat, &min_error_message); - - return ret; -} - - static int gensec_gssapi_destructor(struct gensec_gssapi_state *gensec_gssapi_state) { OM_uint32 maj_stat, min_stat; -- cgit From 722ec8b34743ad7670a747b9db1f47766752878d Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 21 Apr 2011 12:38:51 +1000 Subject: s4-gensec: Use new common 'obtain the PAC' functions. Andrew Bartlett Autobuild-User: Andrew Bartlett Autobuild-Date: Wed Apr 27 05:08:10 CEST 2011 on sn-devel-104 --- source4/auth/gensec/gensec_gssapi.c | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) (limited to 'source4/auth') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 0dfc38d288..4bdd7f88dc 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -1224,7 +1224,6 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi struct auth_user_info_dc *user_info_dc = NULL; struct auth_session_info *session_info = NULL; OM_uint32 maj_stat, min_stat; - gss_buffer_desc pac; DATA_BLOB pac_blob; struct PAC_SIGNATURE_DATA *pac_srv_sig = NULL; struct PAC_SIGNATURE_DATA *pac_kdc_sig = NULL; @@ -1239,25 +1238,15 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi mem_ctx = talloc_named(gensec_gssapi_state, 0, "gensec_gssapi_session_info context"); NT_STATUS_HAVE_NO_MEMORY(mem_ctx); - maj_stat = gsskrb5_extract_authz_data_from_sec_context(&min_stat, - gensec_gssapi_state->gssapi_context, - KRB5_AUTHDATA_WIN2K_PAC, - &pac); - - - if (maj_stat == 0) { - pac_blob = data_blob_talloc(mem_ctx, pac.value, pac.length); - gss_release_buffer(&min_stat, &pac); - - } else { - pac_blob = data_blob(NULL, 0); - } + nt_status = gssapi_obtain_pac_blob(mem_ctx, gensec_gssapi_state->gssapi_context, + gensec_gssapi_state->client_name, + &pac_blob); /* IF we have the PAC - otherwise we need to get this * data from elsewere - local ldb, or (TODO) lookup of some * kind... */ - if (pac_blob.length) { + if (NT_STATUS_IS_OK(nt_status)) { pac_srv_sig = talloc(mem_ctx, struct PAC_SIGNATURE_DATA); if (!pac_srv_sig) { talloc_free(mem_ctx); -- cgit From dbbc6e9ddac30de869d67410869dba90b4bd4a19 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 29 Apr 2011 12:46:10 +1000 Subject: s4-param Remove config_path() -> lpcfg_config_path() This is consistent with lock_path() Andrew Bartlett --- source4/auth/kerberos/krb5_init_context.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/auth') diff --git a/source4/auth/kerberos/krb5_init_context.c b/source4/auth/kerberos/krb5_init_context.c index db3a5375c9..fbcaad29d9 100644 --- a/source4/auth/kerberos/krb5_init_context.c +++ b/source4/auth/kerberos/krb5_init_context.c @@ -415,7 +415,7 @@ smb_krb5_init_context_basic(TALLOC_CTX *tmp_ctx, return ret; } - config_file = config_path(tmp_ctx, lp_ctx, "krb5.conf"); + config_file = lpcfg_config_path(tmp_ctx, lp_ctx, "krb5.conf"); if (!config_file) { krb5_free_context(krb5_ctx); return ENOMEM; -- cgit From cdd802af8319e0b0744d8e727cef75526269ece2 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 3 May 2011 10:40:33 +1000 Subject: s4-messaging Rename messaging -> imessaging This avoid symbol and structure conflicts between Samba3 and Samba4, and chooses a less generic name. Andrew Bartlett --- source4/auth/auth.h | 10 +++++----- source4/auth/ntlm/auth.c | 4 ++-- source4/auth/ntlm/auth_simple.c | 2 +- source4/auth/pyauth.c | 14 +++++++------- source4/auth/samba_server_gensec.c | 2 +- 5 files changed, 16 insertions(+), 16 deletions(-) (limited to 'source4/auth') diff --git a/source4/auth/auth.h b/source4/auth/auth.h index 9eb3e7db6f..1704b5eaf2 100644 --- a/source4/auth/auth.h +++ b/source4/auth/auth.h @@ -109,7 +109,7 @@ struct auth_context { struct tevent_context *event_ctx; /* the messaging context which can be used by backends */ - struct messaging_context *msg_ctx; + struct imessaging_context *msg_ctx; /* loadparm context */ struct loadparm_context *lp_ctx; @@ -193,7 +193,7 @@ NTSTATUS auth_system_session_info(TALLOC_CTX *parent_ctx, NTSTATUS auth_context_create_methods(TALLOC_CTX *mem_ctx, const char **methods, struct tevent_context *ev, - struct messaging_context *msg, + struct imessaging_context *msg, struct loadparm_context *lp_ctx, struct ldb_context *sam_ctx, struct auth_context **auth_ctx); @@ -201,7 +201,7 @@ const char **auth_methods_from_lp(TALLOC_CTX *mem_ctx, struct loadparm_context * NTSTATUS auth_context_create(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - struct messaging_context *msg, + struct imessaging_context *msg, struct loadparm_context *lp_ctx, struct auth_context **auth_ctx); NTSTATUS auth_context_create_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, struct auth_context **auth_ctx); @@ -215,7 +215,7 @@ NTSTATUS auth_register(const struct auth_operations *ops); NTSTATUS server_service_auth_init(void); NTSTATUS authenticate_username_pw(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - struct messaging_context *msg, + struct imessaging_context *msg, struct loadparm_context *lp_ctx, const char *nt4_domain, const char *nt4_username, @@ -242,7 +242,7 @@ NTSTATUS auth_get_user_info_dc_principal(TALLOC_CTX *mem_ctx, NTSTATUS samba_server_gensec_start(TALLOC_CTX *mem_ctx, struct tevent_context *event_ctx, - struct messaging_context *msg_ctx, + struct imessaging_context *msg_ctx, struct loadparm_context *lp_ctx, struct cli_credentials *server_credentials, const char *target_service, diff --git a/source4/auth/ntlm/auth.c b/source4/auth/ntlm/auth.c index e2deab78bc..771474c803 100644 --- a/source4/auth/ntlm/auth.c +++ b/source4/auth/ntlm/auth.c @@ -425,7 +425,7 @@ static NTSTATUS auth_generate_session_info_wrapper(TALLOC_CTX *mem_ctx, ***************************************************************************/ _PUBLIC_ NTSTATUS auth_context_create_methods(TALLOC_CTX *mem_ctx, const char **methods, struct tevent_context *ev, - struct messaging_context *msg, + struct imessaging_context *msg, struct loadparm_context *lp_ctx, struct ldb_context *sam_ctx, struct auth_context **auth_ctx) @@ -508,7 +508,7 @@ const char **auth_methods_from_lp(TALLOC_CTX *mem_ctx, struct loadparm_context * ***************************************************************************/ _PUBLIC_ NTSTATUS auth_context_create(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - struct messaging_context *msg, + struct imessaging_context *msg, struct loadparm_context *lp_ctx, struct auth_context **auth_ctx) { diff --git a/source4/auth/ntlm/auth_simple.c b/source4/auth/ntlm/auth_simple.c index 75eabe855b..5f86466db9 100644 --- a/source4/auth/ntlm/auth_simple.c +++ b/source4/auth/ntlm/auth_simple.c @@ -30,7 +30,7 @@ */ _PUBLIC_ NTSTATUS authenticate_username_pw(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - struct messaging_context *msg, + struct imessaging_context *msg, struct loadparm_context *lp_ctx, const char *nt4_domain, const char *nt4_username, diff --git a/source4/auth/pyauth.c b/source4/auth/pyauth.c index a4ba88c581..6fd68d2070 100644 --- a/source4/auth/pyauth.c +++ b/source4/auth/pyauth.c @@ -214,12 +214,12 @@ static PyObject *py_auth_context_new(PyTypeObject *type, PyObject *args, PyObjec { PyObject *py_lp_ctx = Py_None; PyObject *py_ldb = Py_None; - PyObject *py_messaging_ctx = Py_None; + PyObject *py_imessaging_ctx = Py_None; PyObject *py_auth_context = Py_None; PyObject *py_methods = Py_None; TALLOC_CTX *mem_ctx; struct auth_context *auth_context; - struct messaging_context *messaging_context = NULL; + struct imessaging_context *imessaging_context = NULL; struct loadparm_context *lp_ctx; struct tevent_context *ev; struct ldb_context *ldb; @@ -230,7 +230,7 @@ static PyObject *py_auth_context_new(PyTypeObject *type, PyObject *args, PyObjec if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOOO", discard_const_p(char *, kwnames), - &py_lp_ctx, &py_messaging_ctx, &py_ldb, &py_methods)) + &py_lp_ctx, &py_imessaging_ctx, &py_ldb, &py_methods)) return NULL; mem_ctx = talloc_new(NULL); @@ -251,12 +251,12 @@ static PyObject *py_auth_context_new(PyTypeObject *type, PyObject *args, PyObjec return NULL; } - if (py_messaging_ctx != Py_None) { - messaging_context = py_talloc_get_type(py_messaging_ctx, struct messaging_context); + if (py_imessaging_ctx != Py_None) { + imessaging_context = py_talloc_get_type(py_imessaging_ctx, struct imessaging_context); } if (py_methods == Py_None && py_ldb == Py_None) { - nt_status = auth_context_create(mem_ctx, ev, messaging_context, lp_ctx, &auth_context); + nt_status = auth_context_create(mem_ctx, ev, imessaging_context, lp_ctx, &auth_context); } else { if (py_methods != Py_None) { methods = PyList_AsStringList(mem_ctx, py_methods, "methods"); @@ -268,7 +268,7 @@ static PyObject *py_auth_context_new(PyTypeObject *type, PyObject *args, PyObjec methods = auth_methods_from_lp(mem_ctx, lp_ctx); } nt_status = auth_context_create_methods(mem_ctx, methods, ev, - messaging_context, lp_ctx, + imessaging_context, lp_ctx, ldb, &auth_context); } diff --git a/source4/auth/samba_server_gensec.c b/source4/auth/samba_server_gensec.c index 07b9b15e17..b1b8687708 100644 --- a/source4/auth/samba_server_gensec.c +++ b/source4/auth/samba_server_gensec.c @@ -29,7 +29,7 @@ NTSTATUS samba_server_gensec_start(TALLOC_CTX *mem_ctx, struct tevent_context *event_ctx, - struct messaging_context *msg_ctx, + struct imessaging_context *msg_ctx, struct loadparm_context *lp_ctx, struct cli_credentials *server_credentials, const char *target_service, -- cgit From 2742ec0e34c06ded2885aa2607f1c1729a57b034 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 3 May 2011 12:16:16 +1000 Subject: Remove strlower_m() and strupper_m() from source4 and common code. This function is problematic because a string may expand in size when changed into upper or lower case. This will then push characters off the end of the string in the s3 implementation, or panic in the former s4 implementation. Andrew Bartlett --- source4/auth/ntlmssp/ntlmssp_server.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'source4/auth') diff --git a/source4/auth/ntlmssp/ntlmssp_server.c b/source4/auth/ntlmssp/ntlmssp_server.c index 9db3b560c1..cdae37262e 100644 --- a/source4/auth/ntlmssp/ntlmssp_server.c +++ b/source4/auth/ntlmssp/ntlmssp_server.c @@ -308,26 +308,26 @@ NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_security) ntlmssp_state->server.netbios_domain = lpcfg_workgroup(gensec_security->settings->lp_ctx); { - char dnsdomname[MAXHOSTNAMELEN], dnsname[MAXHOSTNAMELEN]; - - /* Find out the DNS domain name */ - dnsdomname[0] = '\0'; - safe_strcpy(dnsdomname, lpcfg_dnsdomain(gensec_security->settings->lp_ctx), sizeof(dnsdomname) - 1); + char *dnsdomain = lpcfg_dnsdomain(gensec_security->settings->lp_ctx); + char *dnsname, *lower_netbiosname; + lower_netbiosname = strlower_talloc(ntlmssp_state, ntlmssp_state->server.netbios_name); /* Find out the DNS host name */ - safe_strcpy(dnsname, ntlmssp_state->server.netbios_name, sizeof(dnsname) - 1); - if (dnsdomname[0] != '\0') { - safe_strcat(dnsname, ".", sizeof(dnsname) - 1); - safe_strcat(dnsname, dnsdomname, sizeof(dnsname) - 1); + if (dnsdomain && dnsdomain[0] != '\0') { + dnsname = talloc_asprintf(ntlmssp_state, "%s.%s", + lower_netbiosname, + dnsdomain); + talloc_free(lower_netbiosname); + ntlmssp_state->server.dns_name = dnsname; + } else { + ntlmssp_state->server.dns_name = lower_netbiosname; } - strlower_m(dnsname); - ntlmssp_state->server.dns_name = talloc_strdup(ntlmssp_state, - dnsname); NT_STATUS_HAVE_NO_MEMORY(ntlmssp_state->server.dns_name); - ntlmssp_state->server.dns_domain = talloc_strdup(ntlmssp_state, - dnsdomname); + ntlmssp_state->server.dns_domain + = talloc_strdup(ntlmssp_state, + lpcfg_dnsdomain(gensec_security->settings->lp_ctx)); NT_STATUS_HAVE_NO_MEMORY(ntlmssp_state->server.dns_domain); } -- cgit From 5c53d63348882b17f16bed0cc41f1489dcd6cf66 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 3 May 2011 13:53:30 -0700 Subject: sasl_secret_t ends in a char [1] size. This means the extra character is implicit in the safe_strcpy. When changing to strlcpy ensure we allocate an extra char for it. This fixes a bug where secret->len+1 used with safe_strcpy could actually write into secret->len+2. --- source4/auth/gensec/cyrus_sasl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/auth') diff --git a/source4/auth/gensec/cyrus_sasl.c b/source4/auth/gensec/cyrus_sasl.c index bd7664878c..4a4422645d 100644 --- a/source4/auth/gensec/cyrus_sasl.c +++ b/source4/auth/gensec/cyrus_sasl.c @@ -99,12 +99,12 @@ static int gensec_sasl_get_password(sasl_conn_t *conn, void *context, int id, *psecret = NULL; return SASL_OK; } - secret = talloc_size(gensec_security, sizeof(sasl_secret_t)+strlen(password)); + secret = talloc_size(gensec_security, sizeof(sasl_secret_t)+strlen(password)+1); if (!secret) { return SASL_NOMEM; } secret->len = strlen(password); - safe_strcpy((char*)secret->data, password, secret->len+1); + strlcpy((char*)secret->data, password, secret->len+1); *psecret = secret; return SASL_OK; } -- cgit From 323c7445713d17989452b99bbb541248bb2388eb Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 5 May 2011 13:59:08 +1000 Subject: s4-auth: removed the password combinations code in auth_unix this code never did anything due to a typo, and was untested. We should not be inluding a password cracker in Samba anyway. Pair-Programmed-With: Andrew Bartlett Autobuild-User: Andrew Tridgell Autobuild-Date: Thu May 5 07:00:14 CEST 2011 on sn-devel-104 --- source4/auth/ntlm/auth_unix.c | 43 ++++--------------------------------------- 1 file changed, 4 insertions(+), 39 deletions(-) (limited to 'source4/auth') diff --git a/source4/auth/ntlm/auth_unix.c b/source4/auth/ntlm/auth_unix.c index 743cb8103d..7fdb4b3ae0 100644 --- a/source4/auth/ntlm/auth_unix.c +++ b/source4/auth/ntlm/auth_unix.c @@ -737,46 +737,11 @@ static NTSTATUS check_unix_password(TALLOC_CTX *ctx, struct loadparm_context *lp return nt_status; } - if ( user_info->flags | USER_INFO_CASE_INSENSITIVE_PASSWORD) { - return nt_status; - } - - /* if the password was given to us with mixed case then we don't - * need to proceed as we know it hasn't been case modified by the - * client */ - if (strhasupper(password) && strhaslower(password)) { - return nt_status; - } - - /* make a copy of it */ - pwcopy = talloc_strdup(ctx, password); - if (!pwcopy) - return NT_STATUS_NO_MEMORY; - - /* try all lowercase if it's currently all uppercase */ - if (strhasupper(pwcopy)) { - strlower(pwcopy); - nt_status = password_check(username, pwcopy, crypted, salt); - if NT_STATUS_IS_OK(nt_status) { - *ret_passwd = pws; - return nt_status; - } - } - - /* give up? */ - if (level < 1) { - return NT_STATUS_WRONG_PASSWORD; - } - - /* last chance - all combinations of up to level chars upper! */ - strlower(pwcopy); + /* we no longer try different case combinations here. The use + * of this code is now web auth, where trying different case + * combinations makes no sense + */ -#if 0 - if (NT_STATUS_IS_OK(nt_status = string_combinations(pwcopy, password_check, level))) { - *ret_passwd = pws; - return nt_status; - } -#endif return NT_STATUS_WRONG_PASSWORD; } -- cgit From 5c3e985fb53e7e210d665a6fc8199b0844019340 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 7 May 2011 00:49:38 +1000 Subject: s4-auth: remove unused prototype --- source4/auth/auth.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'source4/auth') diff --git a/source4/auth/auth.h b/source4/auth/auth.h index 1704b5eaf2..74f9f860a6 100644 --- a/source4/auth/auth.h +++ b/source4/auth/auth.h @@ -175,10 +175,7 @@ NTSTATUS authsam_account_ok(TALLOC_CTX *mem_ctx, const char *name_for_logs, bool allow_domain_trust, bool password_change); -NTSTATUS authsam_expand_nested_groups(struct ldb_context *sam_ctx, - struct ldb_val *dn_val, const bool only_childs, const char *filter, - TALLOC_CTX *res_sids_ctx, struct dom_sid ***res_sids, - unsigned int *num_res_sids); + struct auth_session_info *system_session(struct loadparm_context *lp_ctx); NTSTATUS authsam_make_user_info_dc(TALLOC_CTX *mem_ctx, struct ldb_context *sam_ctx, const char *netbios_name, -- cgit From ea0ac9cdfceae96b0e0be2531d9dea3b079bcd7f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 7 May 2011 08:14:06 +0200 Subject: s4-auth Rename auth -> auth4 to avoid conflict with s3 auth --- source4/auth/auth.h | 42 +++++++++++++++++------------------ source4/auth/gensec/gensec.c | 4 ++-- source4/auth/gensec/gensec.h | 6 ++--- source4/auth/gensec/pygensec.c | 4 ++-- source4/auth/ntlm/auth.c | 30 ++++++++++++------------- source4/auth/ntlm/auth_anonymous.c | 4 ++-- source4/auth/ntlm/auth_developer.c | 4 ++-- source4/auth/ntlm/auth_sam.c | 10 ++++----- source4/auth/ntlm/auth_server.c | 4 ++-- source4/auth/ntlm/auth_simple.c | 2 +- source4/auth/ntlm/auth_unix.c | 4 ++-- source4/auth/ntlm/auth_util.c | 2 +- source4/auth/ntlm/auth_winbind.c | 4 ++-- source4/auth/ntlm/wscript_build | 12 +++++----- source4/auth/ntlmssp/ntlmssp.h | 2 +- source4/auth/ntlmssp/ntlmssp_server.c | 8 +++---- source4/auth/pyauth.c | 4 ++-- source4/auth/samba_server_gensec.c | 2 +- 18 files changed, 74 insertions(+), 74 deletions(-) (limited to 'source4/auth') diff --git a/source4/auth/auth.h b/source4/auth/auth.h index 74f9f860a6..04731af019 100644 --- a/source4/auth/auth.h +++ b/source4/auth/auth.h @@ -43,7 +43,7 @@ struct loadparm_context; /* version 3 - subsequent samba4 version - abartlet */ /* version 4 - subsequent samba4 version - metze */ /* version 0 - till samba4 is stable - metze */ -#define AUTH_INTERFACE_VERSION 0 +#define AUTH4_INTERFACE_VERSION 0 #define AUTH_SESSION_INFO_DEFAULT_GROUPS 0x01 /* Add the user to the default world and network groups */ #define AUTH_SESSION_INFO_AUTHENTICATED 0x02 /* Add the user to the 'authenticated users' group */ @@ -51,7 +51,7 @@ struct loadparm_context; struct auth_method_context; struct auth_check_password_request; -struct auth_context; +struct auth4_context; struct auth_session_info; struct ldb_dn; @@ -78,7 +78,7 @@ struct auth_operations { /* Lookup a 'session info interim' return based only on the principal or DN */ NTSTATUS (*get_user_info_dc_principal)(TALLOC_CTX *mem_ctx, - struct auth_context *auth_context, + struct auth4_context *auth_context, const char *principal, struct ldb_dn *user_dn, struct auth_user_info_dc **interim_info); @@ -86,13 +86,13 @@ struct auth_operations { struct auth_method_context { struct auth_method_context *prev, *next; - struct auth_context *auth_ctx; + struct auth4_context *auth_ctx; const struct auth_operations *ops; int depth; void *private_data; }; -struct auth_context { +struct auth4_context { struct { /* Who set this up in the first place? */ const char *set_by; @@ -117,25 +117,25 @@ struct auth_context { /* SAM database for this local machine - to fill in local groups, or to authenticate local NTLM users */ struct ldb_context *sam_ctx; - NTSTATUS (*check_password)(struct auth_context *auth_ctx, + NTSTATUS (*check_password)(struct auth4_context *auth_ctx, TALLOC_CTX *mem_ctx, const struct auth_usersupplied_info *user_info, struct auth_user_info_dc **user_info_dc); - NTSTATUS (*get_challenge)(struct auth_context *auth_ctx, uint8_t chal[8]); + NTSTATUS (*get_challenge)(struct auth4_context *auth_ctx, uint8_t chal[8]); - bool (*challenge_may_be_modified)(struct auth_context *auth_ctx); + bool (*challenge_may_be_modified)(struct auth4_context *auth_ctx); - NTSTATUS (*set_challenge)(struct auth_context *auth_ctx, const uint8_t chal[8], const char *set_by); + NTSTATUS (*set_challenge)(struct auth4_context *auth_ctx, const uint8_t chal[8], const char *set_by); NTSTATUS (*get_user_info_dc_principal)(TALLOC_CTX *mem_ctx, - struct auth_context *auth_ctx, + struct auth4_context *auth_ctx, const char *principal, struct ldb_dn *user_dn, struct auth_user_info_dc **user_info_dc); NTSTATUS (*generate_session_info)(TALLOC_CTX *mem_ctx, - struct auth_context *auth_context, + struct auth4_context *auth_context, struct auth_user_info_dc *user_info_dc, uint32_t session_info_flags, struct auth_session_info **session_info); @@ -151,7 +151,7 @@ struct auth_critical_sizes { int sizeof_auth_user_info_dc; }; - NTSTATUS encrypt_user_info(TALLOC_CTX *mem_ctx, struct auth_context *auth_context, + NTSTATUS encrypt_user_info(TALLOC_CTX *mem_ctx, struct auth4_context *auth_context, enum auth_password_state to_state, const struct auth_usersupplied_info *user_info_in, const struct auth_usersupplied_info **user_info_encrypted); @@ -165,7 +165,7 @@ struct ldb_context; struct gensec_security; struct cli_credentials; -NTSTATUS auth_get_challenge(struct auth_context *auth_ctx, uint8_t chal[8]); +NTSTATUS auth_get_challenge(struct auth4_context *auth_ctx, uint8_t chal[8]); NTSTATUS authsam_account_ok(TALLOC_CTX *mem_ctx, struct ldb_context *sam_ctx, uint32_t logon_parameters, @@ -193,17 +193,17 @@ NTSTATUS auth_context_create_methods(TALLOC_CTX *mem_ctx, const char **methods, struct imessaging_context *msg, struct loadparm_context *lp_ctx, struct ldb_context *sam_ctx, - struct auth_context **auth_ctx); + struct auth4_context **auth_ctx); const char **auth_methods_from_lp(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx); NTSTATUS auth_context_create(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct imessaging_context *msg, struct loadparm_context *lp_ctx, - struct auth_context **auth_ctx); -NTSTATUS auth_context_create_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, struct auth_context **auth_ctx); + struct auth4_context **auth_ctx); +NTSTATUS auth_context_create_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, struct auth4_context **auth_ctx); -NTSTATUS auth_check_password(struct auth_context *auth_ctx, +NTSTATUS auth_check_password(struct auth4_context *auth_ctx, TALLOC_CTX *mem_ctx, const struct auth_usersupplied_info *user_info, struct auth_user_info_dc **user_info_dc); @@ -222,17 +222,17 @@ NTSTATUS authenticate_username_pw(TALLOC_CTX *mem_ctx, struct tevent_req *auth_check_password_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - struct auth_context *auth_ctx, + struct auth4_context *auth_ctx, const struct auth_usersupplied_info *user_info); NTSTATUS auth_check_password_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, struct auth_user_info_dc **user_info_dc); -bool auth_challenge_may_be_modified(struct auth_context *auth_ctx); -NTSTATUS auth_context_set_challenge(struct auth_context *auth_ctx, const uint8_t chal[8], const char *set_by); +bool auth_challenge_may_be_modified(struct auth4_context *auth_ctx); +NTSTATUS auth_context_set_challenge(struct auth4_context *auth_ctx, const uint8_t chal[8], const char *set_by); NTSTATUS auth_get_user_info_dc_principal(TALLOC_CTX *mem_ctx, - struct auth_context *auth_ctx, + struct auth4_context *auth_ctx, const char *principal, struct ldb_dn *user_dn, struct auth_user_info_dc **user_info_dc); diff --git a/source4/auth/gensec/gensec.c b/source4/auth/gensec/gensec.c index e632aec2dc..9b0dbfffbc 100644 --- a/source4/auth/gensec/gensec.c +++ b/source4/auth/gensec/gensec.c @@ -514,7 +514,7 @@ const char **gensec_security_oids(struct gensec_security *gensec_security, static NTSTATUS gensec_start(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct gensec_settings *settings, - struct auth_context *auth_context, + struct auth4_context *auth_context, struct gensec_security **gensec_security) { if (ev == NULL) { @@ -604,7 +604,7 @@ _PUBLIC_ NTSTATUS gensec_client_start(TALLOC_CTX *mem_ctx, _PUBLIC_ NTSTATUS gensec_server_start(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct gensec_settings *settings, - struct auth_context *auth_context, + struct auth4_context *auth_context, struct gensec_security **gensec_security) { NTSTATUS status; diff --git a/source4/auth/gensec/gensec.h b/source4/auth/gensec/gensec.h index 48268c421e..28bed6c3b7 100644 --- a/source4/auth/gensec/gensec.h +++ b/source4/auth/gensec/gensec.h @@ -165,7 +165,7 @@ struct gensec_security { /* When we are a server, this may be filled in to provide an * NTLM authentication backend, and user lookup (such as if no * PAC is found) */ - struct auth_context *auth_context; + struct auth4_context *auth_context; }; /* this structure is used by backends to determine the size of some critical types */ @@ -179,7 +179,7 @@ struct gensec_critical_sizes { struct gensec_security; struct socket_context; -struct auth_context; +struct auth4_context; struct auth_user_info_dc; NTSTATUS gensec_socket_init(struct gensec_security *gensec_security, @@ -270,7 +270,7 @@ const char *gensec_get_name_by_authtype(struct gensec_security *gensec_security, NTSTATUS gensec_server_start(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct gensec_settings *settings, - struct auth_context *auth_context, + struct auth4_context *auth_context, struct gensec_security **gensec_security); NTSTATUS gensec_session_info(struct gensec_security *gensec_security, struct auth_session_info **session_info); diff --git a/source4/auth/gensec/pygensec.c b/source4/auth/gensec/pygensec.c index fd9726eb75..004cc4a76e 100644 --- a/source4/auth/gensec/pygensec.c +++ b/source4/auth/gensec/pygensec.c @@ -156,7 +156,7 @@ static PyObject *py_gensec_start_server(PyTypeObject *type, PyObject *args, PyOb PyObject *py_auth_context = Py_None; struct tevent_context *ev; struct gensec_security *gensec; - struct auth_context *auth_context = NULL; + struct auth4_context *auth_context = NULL; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OO", discard_const_p(char *, kwnames), &py_settings, &py_auth_context)) return NULL; @@ -201,7 +201,7 @@ static PyObject *py_gensec_start_server(PyTypeObject *type, PyObject *args, PyOb } if (py_auth_context != Py_None) { - auth_context = py_talloc_get_type(py_auth_context, struct auth_context); + auth_context = py_talloc_get_type(py_auth_context, struct auth4_context); if (!auth_context) { PyErr_Format(PyExc_TypeError, "Expected auth.AuthContext for auth_context argument, got %s", diff --git a/source4/auth/ntlm/auth.c b/source4/auth/ntlm/auth.c index 771474c803..72338ac3c9 100644 --- a/source4/auth/ntlm/auth.c +++ b/source4/auth/ntlm/auth.c @@ -31,7 +31,7 @@ /*************************************************************************** Set a fixed challenge ***************************************************************************/ -_PUBLIC_ NTSTATUS auth_context_set_challenge(struct auth_context *auth_ctx, const uint8_t chal[8], const char *set_by) +_PUBLIC_ NTSTATUS auth_context_set_challenge(struct auth4_context *auth_ctx, const uint8_t chal[8], const char *set_by) { auth_ctx->challenge.set_by = talloc_strdup(auth_ctx, set_by); NT_STATUS_HAVE_NO_MEMORY(auth_ctx->challenge.set_by); @@ -45,7 +45,7 @@ _PUBLIC_ NTSTATUS auth_context_set_challenge(struct auth_context *auth_ctx, cons /*************************************************************************** Set a fixed challenge ***************************************************************************/ -_PUBLIC_ bool auth_challenge_may_be_modified(struct auth_context *auth_ctx) +_PUBLIC_ bool auth_challenge_may_be_modified(struct auth4_context *auth_ctx) { return auth_ctx->challenge.may_be_modified; } @@ -54,7 +54,7 @@ _PUBLIC_ bool auth_challenge_may_be_modified(struct auth_context *auth_ctx) Try to get a challenge out of the various authentication modules. Returns a const char of length 8 bytes. ****************************************************************************/ -_PUBLIC_ NTSTATUS auth_get_challenge(struct auth_context *auth_ctx, uint8_t chal[8]) +_PUBLIC_ NTSTATUS auth_get_challenge(struct auth4_context *auth_ctx, uint8_t chal[8]) { NTSTATUS nt_status; struct auth_method_context *method; @@ -104,7 +104,7 @@ PAC isn't available, and for tokenGroups in the DSDB stack. Supply either a principal or a DN ****************************************************************************/ _PUBLIC_ NTSTATUS auth_get_user_info_dc_principal(TALLOC_CTX *mem_ctx, - struct auth_context *auth_ctx, + struct auth4_context *auth_ctx, const char *principal, struct ldb_dn *user_dn, struct auth_user_info_dc **user_info_dc) @@ -155,7 +155,7 @@ _PUBLIC_ NTSTATUS auth_get_user_info_dc_principal(TALLOC_CTX *mem_ctx, * **/ -_PUBLIC_ NTSTATUS auth_check_password(struct auth_context *auth_ctx, +_PUBLIC_ NTSTATUS auth_check_password(struct auth4_context *auth_ctx, TALLOC_CTX *mem_ctx, const struct auth_usersupplied_info *user_info, struct auth_user_info_dc **user_info_dc) @@ -188,7 +188,7 @@ _PUBLIC_ NTSTATUS auth_check_password(struct auth_context *auth_ctx, } struct auth_check_password_state { - struct auth_context *auth_ctx; + struct auth4_context *auth_ctx; const struct auth_usersupplied_info *user_info; struct auth_user_info_dc *user_info_dc; struct auth_method_context *method; @@ -225,7 +225,7 @@ static void auth_check_password_async_trigger(struct tevent_context *ev, _PUBLIC_ struct tevent_req *auth_check_password_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - struct auth_context *auth_ctx, + struct auth4_context *auth_ctx, const struct auth_usersupplied_info *user_info) { struct tevent_req *req; @@ -409,7 +409,7 @@ _PUBLIC_ NTSTATUS auth_check_password_recv(struct tevent_req *req, /* Wrapper because we don't want to expose all callers to needing to * know that session_info is generated from the main ldb */ static NTSTATUS auth_generate_session_info_wrapper(TALLOC_CTX *mem_ctx, - struct auth_context *auth_context, + struct auth4_context *auth_context, struct auth_user_info_dc *user_info_dc, uint32_t session_info_flags, struct auth_session_info **session_info) @@ -428,10 +428,10 @@ _PUBLIC_ NTSTATUS auth_context_create_methods(TALLOC_CTX *mem_ctx, const char ** struct imessaging_context *msg, struct loadparm_context *lp_ctx, struct ldb_context *sam_ctx, - struct auth_context **auth_ctx) + struct auth4_context **auth_ctx) { int i; - struct auth_context *ctx; + struct auth4_context *ctx; auth4_init(); @@ -440,7 +440,7 @@ _PUBLIC_ NTSTATUS auth_context_create_methods(TALLOC_CTX *mem_ctx, const char ** return NT_STATUS_INTERNAL_ERROR; } - ctx = talloc(mem_ctx, struct auth_context); + ctx = talloc(mem_ctx, struct auth4_context); NT_STATUS_HAVE_NO_MEMORY(ctx); ctx->challenge.set_by = NULL; ctx->challenge.may_be_modified = false; @@ -510,7 +510,7 @@ _PUBLIC_ NTSTATUS auth_context_create(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct imessaging_context *msg, struct loadparm_context *lp_ctx, - struct auth_context **auth_ctx) + struct auth4_context **auth_ctx) { NTSTATUS status; const char **auth_methods; @@ -533,7 +533,7 @@ _PUBLIC_ NTSTATUS auth_context_create(TALLOC_CTX *mem_ctx, This allows us not to re-open the LDB when we need to do a some authentication logic (such as tokenGroups) */ -NTSTATUS auth_context_create_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, struct auth_context **auth_ctx) +NTSTATUS auth_context_create_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, struct auth4_context **auth_ctx) { NTSTATUS status; const char **auth_methods; @@ -620,10 +620,10 @@ const struct auth_operations *auth_backend_byname(const char *name) const struct auth_critical_sizes *auth_interface_version(void) { static const struct auth_critical_sizes critical_sizes = { - AUTH_INTERFACE_VERSION, + AUTH4_INTERFACE_VERSION, sizeof(struct auth_operations), sizeof(struct auth_method_context), - sizeof(struct auth_context), + sizeof(struct auth4_context), sizeof(struct auth_usersupplied_info), sizeof(struct auth_user_info_dc) }; diff --git a/source4/auth/ntlm/auth_anonymous.c b/source4/auth/ntlm/auth_anonymous.c index 6b21225aad..4b0fff03cc 100644 --- a/source4/auth/ntlm/auth_anonymous.c +++ b/source4/auth/ntlm/auth_anonymous.c @@ -24,7 +24,7 @@ #include "auth/ntlm/auth_proto.h" #include "param/param.h" -_PUBLIC_ NTSTATUS auth_anonymous_init(void); +_PUBLIC_ NTSTATUS auth4_anonymous_init(void); /** * Return a anonymous logon for anonymous users (username = "") @@ -66,7 +66,7 @@ static const struct auth_operations anonymous_auth_ops = { .check_password = anonymous_check_password }; -_PUBLIC_ NTSTATUS auth_anonymous_init(void) +_PUBLIC_ NTSTATUS auth4_anonymous_init(void) { NTSTATUS ret; diff --git a/source4/auth/ntlm/auth_developer.c b/source4/auth/ntlm/auth_developer.c index da842c98ba..bc27f27fa2 100644 --- a/source4/auth/ntlm/auth_developer.c +++ b/source4/auth/ntlm/auth_developer.c @@ -24,7 +24,7 @@ #include "auth/ntlm/auth_proto.h" #include "libcli/security/security.h" -_PUBLIC_ NTSTATUS auth_developer_init(void); +_PUBLIC_ NTSTATUS auth4_developer_init(void); static NTSTATUS name_to_ntstatus_want_check(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, @@ -185,7 +185,7 @@ static const struct auth_operations fixed_challenge_auth_ops = { .check_password = fixed_challenge_check_password }; -_PUBLIC_ NTSTATUS auth_developer_init(void) +_PUBLIC_ NTSTATUS auth4_developer_init(void) { NTSTATUS ret; diff --git a/source4/auth/ntlm/auth_sam.c b/source4/auth/ntlm/auth_sam.c index f76057a6df..87a7d27559 100644 --- a/source4/auth/ntlm/auth_sam.c +++ b/source4/auth/ntlm/auth_sam.c @@ -72,7 +72,7 @@ static NTSTATUS authsam_search_account(TALLOC_CTX *mem_ctx, struct ldb_context * Do a specific test for an smb password being correct, given a smb_password and the lanman and NT responses. ****************************************************************************/ -static NTSTATUS authsam_password_ok(struct auth_context *auth_context, +static NTSTATUS authsam_password_ok(struct auth4_context *auth_context, TALLOC_CTX *mem_ctx, uint16_t acct_flags, const struct samr_Password *lm_pwd, @@ -142,7 +142,7 @@ static NTSTATUS authsam_password_ok(struct auth_context *auth_context, send a message to the drepl server telling it to initiate a REPL_SECRET getncchanges extended op to fetch the users secrets */ -static void auth_sam_trigger_repl_secret(TALLOC_CTX *mem_ctx, struct auth_context *auth_context, +static void auth_sam_trigger_repl_secret(TALLOC_CTX *mem_ctx, struct auth4_context *auth_context, struct ldb_dn *user_dn) { struct dcerpc_binding_handle *irpc_handle; @@ -170,7 +170,7 @@ static void auth_sam_trigger_repl_secret(TALLOC_CTX *mem_ctx, struct auth_contex } -static NTSTATUS authsam_authenticate(struct auth_context *auth_context, +static NTSTATUS authsam_authenticate(struct auth4_context *auth_context, TALLOC_CTX *mem_ctx, struct ldb_context *sam_ctx, struct ldb_dn *domain_dn, struct ldb_message *msg, @@ -357,7 +357,7 @@ static NTSTATUS authsam_want_check(struct auth_method_context *ctx, /* Wrapper for the auth subsystem pointer */ static NTSTATUS authsam_get_user_info_dc_principal_wrapper(TALLOC_CTX *mem_ctx, - struct auth_context *auth_context, + struct auth4_context *auth_context, const char *principal, struct ldb_dn *user_dn, struct auth_user_info_dc **user_info_dc) @@ -381,7 +381,7 @@ static const struct auth_operations sam_ops = { .get_user_info_dc_principal = authsam_get_user_info_dc_principal_wrapper }; -_PUBLIC_ NTSTATUS auth_sam_init(void) +_PUBLIC_ NTSTATUS auth4_sam_init(void) { NTSTATUS ret; diff --git a/source4/auth/ntlm/auth_server.c b/source4/auth/ntlm/auth_server.c index 7efeb9242a..9e1ceae0ca 100644 --- a/source4/auth/ntlm/auth_server.c +++ b/source4/auth/ntlm/auth_server.c @@ -27,7 +27,7 @@ #include "param/param.h" #include "libcli/resolve/resolve.h" -_PUBLIC_ NTSTATUS auth_server_init(void); +_PUBLIC_ NTSTATUS auth4_server_init(void); /* This version of 'security=server' rewirtten from scratch for Samba4 * libraries in 2008 */ @@ -223,7 +223,7 @@ static const struct auth_operations server_auth_ops = { .check_password = server_check_password }; -_PUBLIC_ NTSTATUS auth_server_init(void) +_PUBLIC_ NTSTATUS auth4_server_init(void) { NTSTATUS ret; diff --git a/source4/auth/ntlm/auth_simple.c b/source4/auth/ntlm/auth_simple.c index 5f86466db9..241906e281 100644 --- a/source4/auth/ntlm/auth_simple.c +++ b/source4/auth/ntlm/auth_simple.c @@ -38,7 +38,7 @@ _PUBLIC_ NTSTATUS authenticate_username_pw(TALLOC_CTX *mem_ctx, const uint32_t logon_parameters, struct auth_session_info **session_info) { - struct auth_context *auth_context; + struct auth4_context *auth_context; struct auth_usersupplied_info *user_info; struct auth_user_info_dc *user_info_dc; NTSTATUS nt_status; diff --git a/source4/auth/ntlm/auth_unix.c b/source4/auth/ntlm/auth_unix.c index 7fdb4b3ae0..9e92a04712 100644 --- a/source4/auth/ntlm/auth_unix.c +++ b/source4/auth/ntlm/auth_unix.c @@ -28,7 +28,7 @@ #include "../libcli/auth/pam_errors.h" #include "param/param.h" -_PUBLIC_ NTSTATUS auth_unix_init(void); +_PUBLIC_ NTSTATUS auth4_unix_init(void); /* TODO: look at how to best fill in parms retrieveing a struct passwd info * except in case USER_INFO_DONT_CHECK_UNIX_ACCOUNT is set @@ -804,7 +804,7 @@ static const struct auth_operations unix_ops = { .check_password = authunix_check_password }; -_PUBLIC_ NTSTATUS auth_unix_init(void) +_PUBLIC_ NTSTATUS auth4_unix_init(void) { NTSTATUS ret; diff --git a/source4/auth/ntlm/auth_util.c b/source4/auth/ntlm/auth_util.c index 17bfa32167..c19b5cfd42 100644 --- a/source4/auth/ntlm/auth_util.c +++ b/source4/auth/ntlm/auth_util.c @@ -99,7 +99,7 @@ NTSTATUS map_user_info(TALLOC_CTX *mem_ctx, Create an auth_usersupplied_data structure after appropriate mapping. ****************************************************************************/ -NTSTATUS encrypt_user_info(TALLOC_CTX *mem_ctx, struct auth_context *auth_context, +NTSTATUS encrypt_user_info(TALLOC_CTX *mem_ctx, struct auth4_context *auth_context, enum auth_password_state to_state, const struct auth_usersupplied_info *user_info_in, const struct auth_usersupplied_info **user_info_encrypted) diff --git a/source4/auth/ntlm/auth_winbind.c b/source4/auth/ntlm/auth_winbind.c index dfb8fce2a6..da152e718a 100644 --- a/source4/auth/ntlm/auth_winbind.c +++ b/source4/auth/ntlm/auth_winbind.c @@ -31,7 +31,7 @@ #include "nsswitch/libwbclient/wbclient.h" #include "libcli/security/security.h" -_PUBLIC_ NTSTATUS auth_winbind_init(void); +_PUBLIC_ NTSTATUS auth4_winbind_init(void); static NTSTATUS get_info3_from_wbcAuthUserInfo(TALLOC_CTX *mem_ctx, struct wbcAuthUserInfo *info, @@ -324,7 +324,7 @@ static const struct auth_operations winbind_wbclient_ops = { .check_password = winbind_check_password_wbclient }; -_PUBLIC_ NTSTATUS auth_winbind_init(void) +_PUBLIC_ NTSTATUS auth4_winbind_init(void) { NTSTATUS ret; diff --git a/source4/auth/ntlm/wscript_build b/source4/auth/ntlm/wscript_build index 2ac2773c85..d954ec0086 100644 --- a/source4/auth/ntlm/wscript_build +++ b/source4/auth/ntlm/wscript_build @@ -3,7 +3,7 @@ bld.SAMBA_MODULE('auth4_sam_module', source='auth_sam.c', subsystem='auth4', - init_function='auth_sam_init', + init_function='auth4_sam_init', deps='samdb auth4_sam NTLMSSP_COMMON samba-hostconfig' ) @@ -11,7 +11,7 @@ bld.SAMBA_MODULE('auth4_sam_module', bld.SAMBA_MODULE('auth4_anonymous', source='auth_anonymous.c', subsystem='auth4', - init_function='auth_anonymous_init', + init_function='auth4_anonymous_init', deps='talloc' ) @@ -19,7 +19,7 @@ bld.SAMBA_MODULE('auth4_anonymous', bld.SAMBA_MODULE('auth4_server', source='auth_server.c', subsystem='auth4', - init_function='auth_server_init', + init_function='auth4_server_init', deps='samba-util LIBCLI_SMB CREDENTIALS_NTLM' ) @@ -27,7 +27,7 @@ bld.SAMBA_MODULE('auth4_server', bld.SAMBA_MODULE('auth4_winbind', source='auth_winbind.c', subsystem='auth4', - init_function='auth_winbind_init', + init_function='auth4_winbind_init', deps='RPC_NDR_WINBIND MESSAGING wbclient' ) @@ -35,7 +35,7 @@ bld.SAMBA_MODULE('auth4_winbind', bld.SAMBA_MODULE('auth4_developer', source='auth_developer.c', subsystem='auth4', - init_function='auth_developer_init', + init_function='auth4_developer_init', deps='talloc' ) @@ -43,7 +43,7 @@ bld.SAMBA_MODULE('auth4_developer', bld.SAMBA_MODULE('auth4_unix', source='auth_unix.c', subsystem='auth4', - init_function='auth_unix_init', + init_function='auth4_unix_init', deps='pam PAM_ERRORS LIBTSOCKET' ) diff --git a/source4/auth/ntlmssp/ntlmssp.h b/source4/auth/ntlmssp/ntlmssp.h index ff30317f55..00439e68dd 100644 --- a/source4/auth/ntlmssp/ntlmssp.h +++ b/source4/auth/ntlmssp/ntlmssp.h @@ -26,7 +26,7 @@ struct gensec_ntlmssp_context { struct gensec_security *gensec_security; struct ntlmssp_state *ntlmssp_state; - struct auth_context *auth_context; + struct auth4_context *auth_context; struct auth_user_info_dc *user_info_dc; }; diff --git a/source4/auth/ntlmssp/ntlmssp_server.c b/source4/auth/ntlmssp/ntlmssp_server.c index cdae37262e..56315c5966 100644 --- a/source4/auth/ntlmssp/ntlmssp_server.c +++ b/source4/auth/ntlmssp/ntlmssp_server.c @@ -88,7 +88,7 @@ static NTSTATUS auth_ntlmssp_get_challenge(const struct ntlmssp_state *ntlmssp_s struct gensec_ntlmssp_context *gensec_ntlmssp = talloc_get_type_abort(ntlmssp_state->callback_private, struct gensec_ntlmssp_context); - struct auth_context *auth_context = gensec_ntlmssp->auth_context; + struct auth4_context *auth_context = gensec_ntlmssp->auth_context; NTSTATUS status; status = auth_context->get_challenge(auth_context, chal); @@ -111,7 +111,7 @@ static bool auth_ntlmssp_may_set_challenge(const struct ntlmssp_state *ntlmssp_s struct gensec_ntlmssp_context *gensec_ntlmssp = talloc_get_type_abort(ntlmssp_state->callback_private, struct gensec_ntlmssp_context); - struct auth_context *auth_context = gensec_ntlmssp->auth_context; + struct auth4_context *auth_context = gensec_ntlmssp->auth_context; return auth_context->challenge_may_be_modified(auth_context); } @@ -125,7 +125,7 @@ static NTSTATUS auth_ntlmssp_set_challenge(struct ntlmssp_state *ntlmssp_state, struct gensec_ntlmssp_context *gensec_ntlmssp = talloc_get_type_abort(ntlmssp_state->callback_private, struct gensec_ntlmssp_context); - struct auth_context *auth_context = gensec_ntlmssp->auth_context; + struct auth4_context *auth_context = gensec_ntlmssp->auth_context; NTSTATUS nt_status; const uint8_t *chal; @@ -155,7 +155,7 @@ static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state, struct gensec_ntlmssp_context *gensec_ntlmssp = talloc_get_type_abort(ntlmssp_state->callback_private, struct gensec_ntlmssp_context); - struct auth_context *auth_context = gensec_ntlmssp->auth_context; + struct auth4_context *auth_context = gensec_ntlmssp->auth_context; NTSTATUS nt_status; struct auth_usersupplied_info *user_info; diff --git a/source4/auth/pyauth.c b/source4/auth/pyauth.c index 6fd68d2070..6b3948970f 100644 --- a/source4/auth/pyauth.c +++ b/source4/auth/pyauth.c @@ -205,7 +205,7 @@ static const char **PyList_AsStringList(TALLOC_CTX *mem_ctx, PyObject *list, return ret; } -static PyObject *PyAuthContext_FromContext(struct auth_context *auth_context) +static PyObject *PyAuthContext_FromContext(struct auth4_context *auth_context) { return py_talloc_reference(&PyAuthContext, auth_context); } @@ -218,7 +218,7 @@ static PyObject *py_auth_context_new(PyTypeObject *type, PyObject *args, PyObjec PyObject *py_auth_context = Py_None; PyObject *py_methods = Py_None; TALLOC_CTX *mem_ctx; - struct auth_context *auth_context; + struct auth4_context *auth_context; struct imessaging_context *imessaging_context = NULL; struct loadparm_context *lp_ctx; struct tevent_context *ev; diff --git a/source4/auth/samba_server_gensec.c b/source4/auth/samba_server_gensec.c index b1b8687708..24b658ad32 100644 --- a/source4/auth/samba_server_gensec.c +++ b/source4/auth/samba_server_gensec.c @@ -37,7 +37,7 @@ NTSTATUS samba_server_gensec_start(TALLOC_CTX *mem_ctx, { NTSTATUS nt_status; struct gensec_security *gensec_ctx; - struct auth_context *auth_context; + struct auth4_context *auth_context; TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); if (!tmp_ctx) { -- cgit From c6836c8ede90a97a31c208a0057cffe78ed5a3d9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 25 Mar 2011 15:44:50 +0100 Subject: s4:gensec_gssapi: avoid delegation if s4u2self/proxy is used metze --- source4/auth/gensec/gensec_gssapi.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source4/auth') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 4bdd7f88dc..47f47745a5 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -302,6 +302,10 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi gensec_gssapi_state = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state); + if (cli_credentials_get_impersonate_principal(creds)) { + gensec_gssapi_state->want_flags &= ~(GSS_C_DELEG_FLAG|GSS_C_DELEG_POLICY_FLAG); + } + gensec_gssapi_state->target_principal = gensec_get_target_principal(gensec_security); if (gensec_gssapi_state->target_principal) { name_type = GSS_C_NULL_OID; -- cgit From a41efe6802da4e81a4af72aa231daa00f5012ab8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 22 Apr 2011 11:22:50 +0200 Subject: s4:auth/credentials: pass 'self_service' to cli_credentials_set_impersonate_principal() This also adds a cli_credentials_get_self_service() helper function. In order to support S4U2Proxy we need to be able to set the service principal for the S4U2Self step independent of the target principal. metze --- source4/auth/credentials/credentials.c | 1 + source4/auth/credentials/credentials.h | 6 +++++- source4/auth/credentials/credentials_krb5.c | 24 ++++++++++++++++++++---- source4/auth/kerberos/kerberos_util.c | 8 ++++++-- 4 files changed, 32 insertions(+), 7 deletions(-) (limited to 'source4/auth') diff --git a/source4/auth/credentials/credentials.c b/source4/auth/credentials/credentials.c index 015c549693..83e90344bf 100644 --- a/source4/auth/credentials/credentials.c +++ b/source4/auth/credentials/credentials.c @@ -64,6 +64,7 @@ _PUBLIC_ struct cli_credentials *cli_credentials_init(TALLOC_CTX *mem_ctx) cred->principal = NULL; cred->salt_principal = NULL; cred->impersonate_principal = NULL; + cred->self_service = NULL; cred->target_service = NULL; cred->bind_dn = NULL; diff --git a/source4/auth/credentials/credentials.h b/source4/auth/credentials/credentials.h index 0b0de59752..f8fa2f864b 100644 --- a/source4/auth/credentials/credentials.h +++ b/source4/auth/credentials/credentials.h @@ -84,6 +84,7 @@ struct cli_credentials { const char *principal; char *salt_principal; char *impersonate_principal; + char *self_service; char *target_service; const char *bind_dn; @@ -277,10 +278,13 @@ bool cli_credentials_parse_password_fd(struct cli_credentials *credentials, void cli_credentials_invalidate_ccache(struct cli_credentials *cred, enum credentials_obtained obtained); void cli_credentials_set_salt_principal(struct cli_credentials *cred, const char *principal); -void cli_credentials_set_impersonate_principal(struct cli_credentials *cred, const char *principal); +void cli_credentials_set_impersonate_principal(struct cli_credentials *cred, + const char *principal, + const char *self_service); void cli_credentials_set_target_service(struct cli_credentials *cred, const char *principal); const char *cli_credentials_get_salt_principal(struct cli_credentials *cred); const char *cli_credentials_get_impersonate_principal(struct cli_credentials *cred); +const char *cli_credentials_get_self_service(struct cli_credentials *cred); 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); diff --git a/source4/auth/credentials/credentials_krb5.c b/source4/auth/credentials/credentials_krb5.c index d3925a01f6..5883282c25 100644 --- a/source4/auth/credentials/credentials_krb5.c +++ b/source4/auth/credentials/credentials_krb5.c @@ -788,19 +788,35 @@ _PUBLIC_ void cli_credentials_set_salt_principal(struct cli_credentials *cred, c * member of the domain to get the groups of a user. This is also * known as S4U2Self */ -const char *cli_credentials_get_impersonate_principal(struct cli_credentials *cred) +_PUBLIC_ const char *cli_credentials_get_impersonate_principal(struct cli_credentials *cred) { return cred->impersonate_principal; } -_PUBLIC_ void cli_credentials_set_impersonate_principal(struct cli_credentials *cred, const char *principal) +/* + * The 'self_service' is the service principal that + * represents the same object (by its objectSid) + * as the client principal (typically our machine account). + * When trying to impersonate 'impersonate_principal' with + * S4U2Self. + */ +_PUBLIC_ const char *cli_credentials_get_self_service(struct cli_credentials *cred) +{ + return cred->self_service; +} + +_PUBLIC_ void cli_credentials_set_impersonate_principal(struct cli_credentials *cred, + const char *principal, + const char *self_service) { talloc_free(cred->impersonate_principal); cred->impersonate_principal = talloc_strdup(cred, principal); + talloc_free(cred->self_service); + cred->self_service = talloc_strdup(cred, self_service); } -/* when impersonating for S4U2Self we need to set the target principal - * to ourself, as otherwise we would need additional rights. +/* + * when impersonating for S4U2proxy we need to set the target principal. * Similarly, we may only be authorized to do general impersonation to * some particular services. * diff --git a/source4/auth/kerberos/kerberos_util.c b/source4/auth/kerberos/kerberos_util.c index 45b0b07e13..f05016b873 100644 --- a/source4/auth/kerberos/kerberos_util.c +++ b/source4/auth/kerberos/kerberos_util.c @@ -338,7 +338,9 @@ krb5_error_code principal_from_credentials(TALLOC_CTX *parent_ctx, const char **error_string) { krb5_error_code ret; - const char *password, *target_service; + const char *password; + const char *self_service; + const char *target_service; time_t kdc_time = 0; krb5_principal princ; krb5_principal impersonate_principal; @@ -363,6 +365,7 @@ krb5_error_code principal_from_credentials(TALLOC_CTX *parent_ctx, return ret; } + self_service = cli_credentials_get_self_service(credentials); target_service = cli_credentials_get_target_service(credentials); password = cli_credentials_get_password(credentials); @@ -403,7 +406,8 @@ krb5_error_code principal_from_credentials(TALLOC_CTX *parent_ctx, if (password) { ret = kerberos_kinit_password_cc(smb_krb5_context->krb5_context, ccache, princ, password, - impersonate_principal, target_service, + impersonate_principal, + self_service, krb_options, NULL, &kdc_time); } else if (impersonate_principal) { -- cgit From 053ef0f605e8e99bf10e784cf383f954a6940d0a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 28 Apr 2011 17:10:03 +0200 Subject: s4:auth/credentials: S4U2Self should force CRED_MUST_USE_KERBEROS Otherwise we would not impersonate the desired principal. This still doesn't work for plaintext auth, but should avoid ntlmssp. metze --- source4/auth/credentials/credentials_krb5.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/auth') diff --git a/source4/auth/credentials/credentials_krb5.c b/source4/auth/credentials/credentials_krb5.c index 5883282c25..bfba1679f7 100644 --- a/source4/auth/credentials/credentials_krb5.c +++ b/source4/auth/credentials/credentials_krb5.c @@ -813,6 +813,7 @@ _PUBLIC_ void cli_credentials_set_impersonate_principal(struct cli_credentials * cred->impersonate_principal = talloc_strdup(cred, principal); talloc_free(cred->self_service); cred->self_service = talloc_strdup(cred, self_service); + cli_credentials_set_kerberos_state(cred, CRED_MUST_USE_KERBEROS); } /* -- cgit From f44808fa1197c28137808f7e8560bbe3ed439cff Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Sat, 7 May 2011 10:37:24 +0200 Subject: s4:auth/ntlmssp/ntlmssp_server.c - add "const" in front of "dnsdomain" Signed-off-by: Metze --- source4/auth/ntlmssp/ntlmssp_server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/auth') diff --git a/source4/auth/ntlmssp/ntlmssp_server.c b/source4/auth/ntlmssp/ntlmssp_server.c index 56315c5966..240edbeaad 100644 --- a/source4/auth/ntlmssp/ntlmssp_server.c +++ b/source4/auth/ntlmssp/ntlmssp_server.c @@ -308,7 +308,7 @@ NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_security) ntlmssp_state->server.netbios_domain = lpcfg_workgroup(gensec_security->settings->lp_ctx); { - char *dnsdomain = lpcfg_dnsdomain(gensec_security->settings->lp_ctx); + const char *dnsdomain = lpcfg_dnsdomain(gensec_security->settings->lp_ctx); char *dnsname, *lower_netbiosname; lower_netbiosname = strlower_talloc(ntlmssp_state, ntlmssp_state->server.netbios_name); -- cgit From 907cdb5de7f16a2540299aeba211bf2a5ae6fafe Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 6 Jun 2011 14:58:28 +1000 Subject: s4-modules Remove lp_ctx from init functions that no longer need it Now that we don't allow the smb.conf to change the modules dir, many functions that simply load modules or initialise a subsytem that may load modules no longer need an lp_ctx. Andrew Bartlett --- source4/auth/gensec/gensec.c | 4 ++-- source4/auth/gensec/gensec.h | 2 +- source4/auth/gensec/pygensec.c | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'source4/auth') diff --git a/source4/auth/gensec/gensec.c b/source4/auth/gensec/gensec.c index 9b0dbfffbc..b91e790d3c 100644 --- a/source4/auth/gensec/gensec.c +++ b/source4/auth/gensec/gensec.c @@ -1406,7 +1406,7 @@ bool gensec_setting_bool(struct gensec_settings *settings, const char *mechanism /* initialise the GENSEC subsystem */ -_PUBLIC_ NTSTATUS gensec_init(struct loadparm_context *lp_ctx) +_PUBLIC_ NTSTATUS gensec_init(void) { static bool initialized = false; #define _MODULE_PROTO(init) extern NTSTATUS init(void); @@ -1417,7 +1417,7 @@ _PUBLIC_ NTSTATUS gensec_init(struct loadparm_context *lp_ctx) if (initialized) return NT_STATUS_OK; initialized = true; - shared_init = load_samba_modules(NULL, lp_ctx, "gensec"); + shared_init = load_samba_modules(NULL, "gensec"); run_init_functions(static_init); run_init_functions(shared_init); diff --git a/source4/auth/gensec/gensec.h b/source4/auth/gensec/gensec.h index 28bed6c3b7..e42b4aa5d2 100644 --- a/source4/auth/gensec/gensec.h +++ b/source4/auth/gensec/gensec.h @@ -242,7 +242,7 @@ NTSTATUS gensec_start_mech_by_oid(struct gensec_security *gensec_security, const char *mech_oid); const char *gensec_get_name_by_oid(struct gensec_security *gensec_security, const char *oid_string); struct cli_credentials *gensec_get_credentials(struct gensec_security *gensec_security); -NTSTATUS gensec_init(struct loadparm_context *lp_ctx); +NTSTATUS gensec_init(void); NTSTATUS gensec_unseal_packet(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx, uint8_t *data, size_t length, diff --git a/source4/auth/gensec/pygensec.c b/source4/auth/gensec/pygensec.c index 004cc4a76e..503974aaa3 100644 --- a/source4/auth/gensec/pygensec.c +++ b/source4/auth/gensec/pygensec.c @@ -127,7 +127,7 @@ static PyObject *py_gensec_start_client(PyTypeObject *type, PyObject *args, PyOb return NULL; } - status = gensec_init(settings->lp_ctx); + status = gensec_init(); if (!NT_STATUS_IS_OK(status)) { PyErr_SetNTSTATUS(status); PyObject_DEL(self); @@ -210,7 +210,7 @@ static PyObject *py_gensec_start_server(PyTypeObject *type, PyObject *args, PyOb } } - status = gensec_init(settings->lp_ctx); + status = gensec_init(); if (!NT_STATUS_IS_OK(status)) { PyErr_SetNTSTATUS(status); PyObject_DEL(self); -- cgit From 5197331fe5af0a53e02e642c9e006b19ae92ba19 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 7 Jun 2011 09:07:52 +1000 Subject: s4-auth Move default auth methods back into auth.c This changes auth_methods_from_lp to no longer use the parametric options, and to cope with ROLE_DOMAIN_BDC and ROLE_DOMAIN_PDC. This will assist in calling the source4 auth subsystem with a source3 derived lp_ctx. Andrew Bartlett --- source4/auth/ntlm/auth.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'source4/auth') diff --git a/source4/auth/ntlm/auth.c b/source4/auth/ntlm/auth.c index 72338ac3c9..2308b1594d 100644 --- a/source4/auth/ntlm/auth.c +++ b/source4/auth/ntlm/auth.c @@ -488,15 +488,17 @@ _PUBLIC_ NTSTATUS auth_context_create_methods(TALLOC_CTX *mem_ctx, const char ** const char **auth_methods_from_lp(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx) { const char **auth_methods = NULL; + switch (lpcfg_server_role(lp_ctx)) { case ROLE_STANDALONE: - auth_methods = lpcfg_parm_string_list(mem_ctx, lp_ctx, NULL, "auth methods", "standalone", NULL); + auth_methods = str_list_make(mem_ctx, "anonymous sam_ignoredomain", NULL); break; case ROLE_DOMAIN_MEMBER: - auth_methods = lpcfg_parm_string_list(mem_ctx, lp_ctx, NULL, "auth methods", "member server", NULL); + auth_methods = str_list_make(mem_ctx, "anonymous sam winbind", NULL); break; - case ROLE_DOMAIN_CONTROLLER: - auth_methods = lpcfg_parm_string_list(mem_ctx, lp_ctx, NULL, "auth methods", "domain controller", NULL); + case ROLE_DOMAIN_BDC: + case ROLE_DOMAIN_PDC: + auth_methods = str_list_make(mem_ctx, "anonymous sam_ignoredomain winbind", NULL); break; } return auth_methods; -- cgit From 8dbab93f28d8ddbce8f44116f45a107a05a59a15 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 8 Jun 2011 08:51:56 +1000 Subject: s4-credentials Allow use of file-based credentials caches for debugging. This means that we will leave a slew of file based credentials caches in /tmp, which should give some clues to the administrator or developer via klist as to what has gone wrong. Andrew Bartlett --- source4/auth/credentials/credentials_krb5.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'source4/auth') diff --git a/source4/auth/credentials/credentials_krb5.c b/source4/auth/credentials/credentials_krb5.c index bfba1679f7..aba010453d 100644 --- a/source4/auth/credentials/credentials_krb5.c +++ b/source4/auth/credentials/credentials_krb5.c @@ -235,9 +235,15 @@ static int cli_credentials_new_ccache(struct cli_credentials *cred, if (!ccache_name) { must_free_cc_name = true; - ccache_name = talloc_asprintf(ccc, "MEMORY:%p", - ccc); - + + if (lpcfg_parm_bool(lp_ctx, NULL, "credentials", "krb5_cc_file", false)) { + ccache_name = talloc_asprintf(ccc, "FILE:/tmp/krb5_cc_samba_%u_%p", + (unsigned int)getpid(), ccc); + } else { + ccache_name = talloc_asprintf(ccc, "MEMORY:%p", + ccc); + } + if (!ccache_name) { talloc_free(ccc); (*error_string) = strerror(ENOMEM); -- cgit From 9cf686f56fa50932a67f80a455c36025ca3470db Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 8 Jun 2011 08:53:16 +1000 Subject: s4-credentials Don't use expired Kerberos or GSSAPI credentials In a long-lived credentials cache situation, we may need to refetch the ticket after (say) 10 hours. This code should help that happen, by checking the lifetime before returning any credentials cache or GSSAPI credentials. Andrew Bartlett --- source4/auth/credentials/credentials_krb5.c | 61 +++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 4 deletions(-) (limited to 'source4/auth') diff --git a/source4/auth/credentials/credentials_krb5.c b/source4/auth/credentials/credentials_krb5.c index aba010453d..26fa8099ab 100644 --- a/source4/auth/credentials/credentials_krb5.c +++ b/source4/auth/credentials/credentials_krb5.c @@ -294,8 +294,38 @@ _PUBLIC_ int cli_credentials_get_named_ccache(struct cli_credentials *cred, if (cred->ccache_obtained >= cred->ccache_threshold && cred->ccache_obtained > CRED_UNINITIALISED) { - *ccc = cred->ccache; - return 0; + time_t lifetime; + bool expired = false; + ret = krb5_cc_get_lifetime(cred->ccache->smb_krb5_context->krb5_context, + cred->ccache->ccache, &lifetime); + if (ret == KRB5_CC_END) { + /* If we have a particular ccache set, without + * an initial ticket, then assume there is a + * good reason */ + } else if (ret == 0) { + if (lifetime == 0) { + DEBUG(3, ("Ticket in credentials cache for %s expired, will refresh\n", + cli_credentials_get_principal(cred, cred))); + expired = true; + } else if (lifetime < 300) { + DEBUG(3, ("Ticket in credentials cache for %s will shortly expire (%u secs), will refresh\n", + cli_credentials_get_principal(cred, cred), (unsigned int)lifetime)); + expired = true; + } + } else { + (*error_string) = talloc_asprintf(cred, "failed to get ccache lifetime: %s\n", + smb_get_krb5_error_message(cred->ccache->smb_krb5_context->krb5_context, + ret, cred)); + return ret; + } + + DEBUG(5, ("Ticket in credentials cache for %s will expire in %u secs\n", + cli_credentials_get_principal(cred, cred), (unsigned int)lifetime)); + + if (!expired) { + *ccc = cred->ccache; + return 0; + } } if (cli_credentials_is_anonymous(cred)) { (*error_string) = "Cannot get anonymous kerberos credentials"; @@ -422,8 +452,31 @@ _PUBLIC_ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred, if (cred->client_gss_creds_obtained >= cred->client_gss_creds_threshold && cred->client_gss_creds_obtained > CRED_UNINITIALISED) { - *_gcc = cred->client_gss_creds; - return 0; + bool expired = false; + OM_uint32 lifetime = 0; + gss_cred_usage_t usage = 0; + maj_stat = gss_inquire_cred(&min_stat, cred->client_gss_creds->creds, + NULL, &lifetime, &usage, NULL); + if (maj_stat == GSS_S_CREDENTIALS_EXPIRED) { + DEBUG(3, ("Credentials for %s expired, must refresh credentials cache\n", cli_credentials_get_principal(cred, cred))); + expired = true; + } else if (maj_stat == GSS_S_COMPLETE && lifetime < 300) { + DEBUG(3, ("Credentials for %s will expire shortly (%u sec), must refresh credentials cache\n", cli_credentials_get_principal(cred, cred), lifetime)); + expired = true; + } else if (maj_stat != GSS_S_COMPLETE) { + *error_string = talloc_asprintf(cred, "inquiry of credential lifefime via GSSAPI gss_inquire_cred failed: %s\n", + gssapi_error_string(cred, maj_stat, min_stat, NULL)); + return EINVAL; + } + if (expired) { + cli_credentials_unconditionally_invalidate_client_gss_creds(cred); + } else { + DEBUG(5, ("GSSAPI credentials for %s will expire in %u secs\n", + cli_credentials_get_principal(cred, cred), (unsigned int)lifetime)); + + *_gcc = cred->client_gss_creds; + return 0; + } } ret = cli_credentials_get_ccache(cred, event_ctx, lp_ctx, -- cgit From c79021382b3feda518440f7627a78959b96d0619 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 8 Jun 2011 08:55:19 +1000 Subject: s4-gensec bring GSS_S_CONTEXT_EXPIRED into it's own error handler This allows us to print much more debugging in this critical situation. Andrew Bartlett Autobuild-User: Andrew Bartlett Autobuild-Date: Wed Jun 8 04:19:58 CEST 2011 on sn-devel-104 --- source4/auth/gensec/gensec_gssapi.c | 59 +++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) (limited to 'source4/auth') diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 47f47745a5..72c6b3f991 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -523,6 +523,65 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security, gss_release_buffer(&min_stat2, &output_token); return NT_STATUS_MORE_PROCESSING_REQUIRED; + } else if (maj_stat == GSS_S_CONTEXT_EXPIRED) { + gss_cred_id_t creds; + gss_name_t name; + gss_buffer_desc buffer; + OM_uint32 lifetime = 0; + gss_cred_usage_t usage; + const char *role = NULL; + DEBUG(0, ("GSS %s Update(krb5)(%d) Update failed, credentials expired during GSSAPI handshake!\n", + role, + gensec_gssapi_state->gss_exchange_count)); + + + switch (gensec_security->gensec_role) { + case GENSEC_CLIENT: + creds = gensec_gssapi_state->client_cred->creds; + role = "client"; + case GENSEC_SERVER: + creds = gensec_gssapi_state->server_cred->creds; + role = "server"; + } + + maj_stat = gss_inquire_cred(&min_stat, + creds, + &name, &lifetime, &usage, NULL); + + if (maj_stat == GSS_S_COMPLETE) { + const char *usage_string; + switch (usage) { + case GSS_C_BOTH: + usage_string = "GSS_C_BOTH"; + break; + case GSS_C_ACCEPT: + usage_string = "GSS_C_ACCEPT"; + break; + case GSS_C_INITIATE: + usage_string = "GSS_C_INITIATE"; + break; + } + maj_stat = gss_display_name(&min_stat, name, &buffer, NULL); + if (maj_stat) { + buffer.value = NULL; + buffer.length = 0; + } + if (lifetime > 0) { + DEBUG(0, ("GSSAPI gss_inquire_cred indicates expiry of %*.*s in %u sec for %s\n", + (int)buffer.length, (int)buffer.length, (char *)buffer.value, + lifetime, usage_string)); + } else { + DEBUG(0, ("GSSAPI gss_inquire_cred indicates %*.*s has already expired for %s\n", + (int)buffer.length, (int)buffer.length, (char *)buffer.value, + usage_string)); + } + gss_release_buffer(&min_stat, &buffer); + gss_release_name(&min_stat, &name); + } else if (maj_stat != GSS_S_COMPLETE) { + DEBUG(0, ("inquiry of credential lifefime via GSSAPI gss_inquire_cred failed: %s\n", + gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); + } + return NT_STATUS_INVALID_PARAMETER; } else if (gss_oid_equal(gensec_gssapi_state->gss_oid, gss_mech_krb5)) { switch (min_stat) { case KRB5KRB_AP_ERR_TKT_NYV: -- cgit From 27f1779814accd82a5ec1330f8856192a69271f8 Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Wed, 8 Jun 2011 09:36:59 +0200 Subject: s4:auth/ntlm/auth.c - fix incompatible pointer type warning Reviewed-by: Tridge --- source4/auth/ntlm/auth.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/auth') diff --git a/source4/auth/ntlm/auth.c b/source4/auth/ntlm/auth.c index 2308b1594d..d2464c3cbf 100644 --- a/source4/auth/ntlm/auth.c +++ b/source4/auth/ntlm/auth.c @@ -487,7 +487,7 @@ _PUBLIC_ NTSTATUS auth_context_create_methods(TALLOC_CTX *mem_ctx, const char ** const char **auth_methods_from_lp(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx) { - const char **auth_methods = NULL; + char **auth_methods = NULL; switch (lpcfg_server_role(lp_ctx)) { case ROLE_STANDALONE: @@ -501,7 +501,7 @@ const char **auth_methods_from_lp(TALLOC_CTX *mem_ctx, struct loadparm_context * auth_methods = str_list_make(mem_ctx, "anonymous sam_ignoredomain winbind", NULL); break; } - return auth_methods; + return (const char **) auth_methods; } /*************************************************************************** -- cgit From cda2fa21eb007b57960ab8a7eb9ddd996887e5bf Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Sat, 11 Jun 2011 15:07:50 +0200 Subject: s4:auth/ntlm/auth_unix.c - remove unused variables Relicts from commit 323c7445713d17989452b99bbb541248bb2388eb Reviewed-by: Jelmer --- source4/auth/ntlm/auth_unix.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source4/auth') diff --git a/source4/auth/ntlm/auth_unix.c b/source4/auth/ntlm/auth_unix.c index 9e92a04712..d79ebc1772 100644 --- a/source4/auth/ntlm/auth_unix.c +++ b/source4/auth/ntlm/auth_unix.c @@ -607,12 +607,10 @@ static NTSTATUS check_unix_password(TALLOC_CTX *ctx, struct loadparm_context *lp { char *username; char *password; - char *pwcopy; char *salt; char *crypted; struct passwd *pws; NTSTATUS nt_status; - int level = lpcfg_passwordlevel(lp_ctx); *ret_passwd = NULL; -- cgit From e080ae0faa2556825189f82fa61a7ff5f249dbc5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 17 Jun 2011 13:47:14 +1000 Subject: s4-auth: quiet down the krb5 warnings when kerberos is not set to 'MUST' this prevents spurious error messages on client commands when when we will fallback to NTLM authentication Pair-Programmed-With: Andrew Bartlett --- source4/auth/credentials/credentials_krb5.c | 6 +++++- source4/auth/gensec/gensec.c | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'source4/auth') diff --git a/source4/auth/credentials/credentials_krb5.c b/source4/auth/credentials/credentials_krb5.c index 26fa8099ab..6670f434d9 100644 --- a/source4/auth/credentials/credentials_krb5.c +++ b/source4/auth/credentials/credentials_krb5.c @@ -482,7 +482,11 @@ _PUBLIC_ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred, ret = cli_credentials_get_ccache(cred, event_ctx, lp_ctx, &ccache, error_string); if (ret) { - DEBUG(1, ("Failed to get CCACHE for GSSAPI client: %s\n", error_message(ret))); + if (cli_credentials_get_kerberos_state(cred) == CRED_MUST_USE_KERBEROS) { + DEBUG(1, ("Failed to get kerberos credentials (kerberos required): %s\n", error_message(ret))); + } else { + DEBUG(4, ("Failed to get kerberos credentials: %s\n", error_message(ret))); + } return ret; } diff --git a/source4/auth/gensec/gensec.c b/source4/auth/gensec/gensec.c index b91e790d3c..7e6a83d51f 100644 --- a/source4/auth/gensec/gensec.c +++ b/source4/auth/gensec/gensec.c @@ -639,7 +639,7 @@ static NTSTATUS gensec_start_mech(struct gensec_security *gensec_security) if (gensec_security->ops->client_start) { status = gensec_security->ops->client_start(gensec_security); if (!NT_STATUS_IS_OK(status)) { - DEBUG(2, ("Failed to start GENSEC client mech %s: %s\n", + DEBUG(gensec_security->subcontext?4:2, ("Failed to start GENSEC client mech %s: %s\n", gensec_security->ops->name, nt_errstr(status))); } return status; -- cgit From 245b27774995b6ee8aef4b14bb3dc5518fc733d1 Mon Sep 17 00:00:00 2001 From: Matthieu Patou Date: Tue, 14 Jun 2011 00:27:07 +0400 Subject: s4: fix wrong index usage PRIMARY_USER_SID_INDEX when it should have been PRIMARY_GROUP_SID_INDEX The system account was instanciated with wrong user an group SIDs, group sid resulted being just the domain SID. Bug seems to date from fbe6d155bf177c610ee549cc534650b0f0700e8a. Andrew (B.) please check. --- source4/auth/system_session.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/auth') diff --git a/source4/auth/system_session.c b/source4/auth/system_session.c index 54b8f514cf..3b9edd779d 100644 --- a/source4/auth/system_session.c +++ b/source4/auth/system_session.c @@ -190,7 +190,7 @@ static NTSTATUS auth_domain_admin_user_info_dc(TALLOC_CTX *mem_ctx, sid_append_rid(&user_info_dc->sids[PRIMARY_USER_SID_INDEX], DOMAIN_RID_ADMINISTRATOR); user_info_dc->sids[PRIMARY_GROUP_SID_INDEX] = *domain_sid; - sid_append_rid(&user_info_dc->sids[PRIMARY_USER_SID_INDEX], DOMAIN_RID_USERS); + sid_append_rid(&user_info_dc->sids[PRIMARY_GROUP_SID_INDEX], DOMAIN_RID_USERS); user_info_dc->sids[2] = global_sid_Builtin_Administrators; -- cgit From 018f4a5889743f742a59e9ad72056b2ea09adfe9 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 20 Jun 2011 14:03:26 +1000 Subject: libcli/util Bring samba4 unix -> nt_status code in common. Due to library link orders, this is already the function that is being used. However we still need to sort out the duplicate symbol issues, probably by renaming things. Andrew Bartlett --- source4/auth/kerberos/wscript_build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/auth') diff --git a/source4/auth/kerberos/wscript_build b/source4/auth/kerberos/wscript_build index 586366d422..90e8560573 100644 --- a/source4/auth/kerberos/wscript_build +++ b/source4/auth/kerberos/wscript_build @@ -4,7 +4,7 @@ bld.SAMBA_LIBRARY('authkrb5', source='kerberos.c kerberos_heimdal.c kerberos_pac.c gssapi_parse.c krb5_init_context.c keytab_copy.c', autoproto='proto.h', public_deps='krb5 ndr-krb5pac samba_socket LIBCLI_RESOLVE com_err asn1', - deps='asn1util auth_sam_reply tevent LIBPACKET ndr ldb KRB5_WRAP', + deps='asn1util auth_sam_reply tevent LIBPACKET ndr ldb KRB5_WRAP errors', private_library=True ) -- cgit From a1f04e8abc761ef1ba211420ff1dbda50fcf527d Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 20 Jun 2011 14:55:32 +1000 Subject: libcli/util Rename common map_nt_error_from_unix to avoid duplicate symbol The two error tables need to be combined, but for now seperate the names. (As the common parts of the tree now use the _common function, errmap_unix.c must be included in the s3 autoconf build). Andrew Bartlett Autobuild-User: Andrew Bartlett Autobuild-Date: Mon Jun 20 08:12:03 CEST 2011 on sn-devel-104 --- source4/auth/kerberos/kerberos_pac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/auth') diff --git a/source4/auth/kerberos/kerberos_pac.c b/source4/auth/kerberos/kerberos_pac.c index 5bc80c9a58..8ce970e486 100644 --- a/source4/auth/kerberos/kerberos_pac.c +++ b/source4/auth/kerberos/kerberos_pac.c @@ -448,14 +448,14 @@ NTSTATUS kerberos_pac_blob_to_user_info_dc(TALLOC_CTX *mem_ctx, pac_blob.data, pac_blob.length, &pac); if (ret) { - return map_nt_error_from_unix(ret); + return map_nt_error_from_unix_common(ret); } ret = kerberos_pac_to_user_info_dc(mem_ctx, pac, context, user_info_dc, pac_srv_sig, pac_kdc_sig); krb5_pac_free(context, pac); if (ret) { - return map_nt_error_from_unix(ret); + return map_nt_error_from_unix_common(ret); } return NT_STATUS_OK; } -- cgit From c017cbfaa47f6cb7da38a7021427412fe2e62a8d Mon Sep 17 00:00:00 2001 From: Brad Hards Date: Fri, 17 Jun 2011 19:53:11 +1000 Subject: s4/auth: Trivial spelling fixes. Signed-off-by: Andrew Tridgell --- source4/auth/credentials/credentials_krb5.c | 6 +++--- source4/auth/kerberos/kerberos_util.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'source4/auth') diff --git a/source4/auth/credentials/credentials_krb5.c b/source4/auth/credentials/credentials_krb5.c index 6670f434d9..1643197004 100644 --- a/source4/auth/credentials/credentials_krb5.c +++ b/source4/auth/credentials/credentials_krb5.c @@ -387,7 +387,7 @@ void cli_credentials_invalidate_client_gss_creds(struct cli_credentials *cred, } /* Now that we know that the data is 'this specified', then * don't allow something less 'known' to be returned as a - * ccache. Ie, if the username is on the commmand line, we + * ccache. Ie, if the username is on the command line, we * don't want to later guess to use a file-based ccache */ if (obtained > cred->client_gss_creds_threshold) { cred->client_gss_creds_threshold = obtained; @@ -420,7 +420,7 @@ _PUBLIC_ void cli_credentials_invalidate_ccache(struct cli_credentials *cred, } /* Now that we know that the data is 'this specified', then * don't allow something less 'known' to be returned as a - * ccache. Ie, if the username is on the commmand line, we + * ccache. i.e, if the username is on the command line, we * don't want to later guess to use a file-based ccache */ if (obtained > cred->ccache_threshold) { cred->ccache_threshold = obtained; @@ -844,7 +844,7 @@ _PUBLIC_ void cli_credentials_set_salt_principal(struct cli_credentials *cred, c cred->salt_principal = talloc_strdup(cred, principal); } -/* The 'impersonate_principal' is used to allow on Kerberos principal +/* The 'impersonate_principal' is used to allow one Kerberos principal * (and it's associated keytab etc) to impersonate another. The * ability to do this is controlled by the KDC, but it is generally * permitted to impersonate anyone to yourself. This allows any diff --git a/source4/auth/kerberos/kerberos_util.c b/source4/auth/kerberos/kerberos_util.c index f05016b873..9cef977306 100644 --- a/source4/auth/kerberos/kerberos_util.c +++ b/source4/auth/kerberos/kerberos_util.c @@ -173,7 +173,7 @@ static krb5_error_code principals_from_msg(TALLOC_CTX *parent_ctx, return ret; } - /* This song-and-dance effectivly puts the principal + /* This song-and-dance effectively puts the principal * into talloc, so we can't loose it. */ talloc_set_destructor(principals[i], free_principal); i++; @@ -262,7 +262,7 @@ static krb5_error_code salt_principal_from_msg(TALLOC_CTX *parent_ctx, upper_realm, "host", salt_body, NULL); if (ret == 0) { - /* This song-and-dance effectivly puts the principal + /* This song-and-dance effectively puts the principal * into talloc, so we can't loose it. */ mem_ctx->smb_krb5_context = talloc_reference(mem_ctx, smb_krb5_context); mem_ctx->principal = *salt_princ; @@ -737,7 +737,7 @@ static krb5_error_code remove_old_entries(TALLOC_CTX *parent_ctx, /* Release the enumeration. We are going to * have to start this from the top again, * because deletes during enumeration may not - * always be consistant. + * always be consistent. * * Also, the enumeration locks a FILE: keytab */ -- cgit From 7cf38425b274c43144a2216accf5330d8ef1fe36 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 20 Jun 2011 17:41:52 +0200 Subject: s4:auth/kerberos: don't ignore return code in kerberos_kinit_password_cc() metze --- source4/auth/kerberos/kerberos.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/auth') diff --git a/source4/auth/kerberos/kerberos.c b/source4/auth/kerberos/kerberos.c index 0db0dd3ced..8824d748d2 100644 --- a/source4/auth/kerberos/kerberos.c +++ b/source4/auth/kerberos/kerberos.c @@ -159,6 +159,8 @@ code = krb5_cc_store_cred(ctx, cc, impersonate_creds); krb5_get_creds_opt_free(ctx, options); krb5_free_creds(ctx, impersonate_creds); + + return code; } return 0; -- cgit From b3d49620875d878e2ad39896a6fe9fddb039253e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 20 Jun 2011 18:01:49 +0200 Subject: s4:auth/kerberos: use better variable names in kerberos_kinit_password_cc() This will make the following changes easier to review. metze --- source4/auth/kerberos/kerberos.c | 68 ++++++++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 27 deletions(-) (limited to 'source4/auth') diff --git a/source4/auth/kerberos/kerberos.c b/source4/auth/kerberos/kerberos.c index 8824d748d2..5e38d878be 100644 --- a/source4/auth/kerberos/kerberos.c +++ b/source4/auth/kerberos/kerberos.c @@ -85,20 +85,24 @@ */ krb5_error_code kerberos_kinit_password_cc(krb5_context ctx, krb5_ccache cc, - krb5_principal principal, const char *password, - krb5_principal impersonate_principal, const char *target_service, + krb5_principal init_principal, + const char *init_password, + krb5_principal impersonate_principal, + const char *target_service, krb5_get_init_creds_opt *krb_options, time_t *expire_time, time_t *kdc_time) { krb5_error_code code = 0; - krb5_creds my_creds; - krb5_creds *impersonate_creds; + krb5_creds init_creds; krb5_get_creds_opt options; + const char *self_service = target_service; /* If we are not impersonating, then get this ticket for the * target service, otherwise a krbtgt, and get the next ticket * for the target */ - if ((code = krb5_get_init_creds_password(ctx, &my_creds, principal, password, + if ((code = krb5_get_init_creds_password(ctx, &init_creds, + init_principal, + init_password, NULL, NULL, 0, impersonate_principal ? NULL : target_service, @@ -106,59 +110,69 @@ return code; } - if ((code = krb5_cc_initialize(ctx, cc, principal))) { - krb5_free_cred_contents(ctx, &my_creds); + if ((code = krb5_cc_initialize(ctx, cc, init_principal))) { + krb5_free_cred_contents(ctx, &init_creds); return code; } - if ((code = krb5_cc_store_cred(ctx, cc, &my_creds))) { - krb5_free_cred_contents(ctx, &my_creds); + if ((code = krb5_cc_store_cred(ctx, cc, &init_creds))) { + krb5_free_cred_contents(ctx, &init_creds); return code; } if (expire_time) { - *expire_time = (time_t) my_creds.times.endtime; + *expire_time = (time_t) init_creds.times.endtime; } if (kdc_time) { - *kdc_time = (time_t) my_creds.times.starttime; + *kdc_time = (time_t) init_creds.times.starttime; } - krb5_free_cred_contents(ctx, &my_creds); - + krb5_free_cred_contents(ctx, &init_creds); + if (code == 0 && impersonate_principal) { - krb5_principal target_princ; - if ((code = krb5_get_creds_opt_alloc(ctx, &options))) { + krb5_creds *s4u2self_creds; + krb5_principal self_princ; + const char *self_realm; + + /* + * For S4U2Self we need our own service principal, + * which belongs to our own realm (available on + * our client principal. + */ + self_realm = krb5_principal_get_realm(ctx, init_principal); + + if ((code = krb5_parse_name(ctx, self_service, &self_princ))) { return code; } - if ((code = krb5_get_creds_opt_set_impersonate(ctx, options, impersonate_principal))) { - krb5_get_creds_opt_free(ctx, options); + if ((code = krb5_principal_set_realm(ctx, self_princ, self_realm))) { + krb5_free_principal(ctx, self_princ); return code; } - if ((code = krb5_parse_name(ctx, target_service, &target_princ))) { - krb5_get_creds_opt_free(ctx, options); + if ((code = krb5_get_creds_opt_alloc(ctx, &options))) { + krb5_free_principal(ctx, self_princ); return code; } - if ((code = krb5_principal_set_realm(ctx, target_princ, krb5_principal_get_realm(ctx, principal)))) { + if ((code = krb5_get_creds_opt_set_impersonate(ctx, options, impersonate_principal))) { krb5_get_creds_opt_free(ctx, options); - krb5_free_principal(ctx, target_princ); + krb5_free_principal(ctx, self_princ); return code; } - if ((code = krb5_get_creds(ctx, options, cc, target_princ, &impersonate_creds))) { - krb5_free_principal(ctx, target_princ); + if ((code = krb5_get_creds(ctx, options, cc, self_princ, &s4u2self_creds))) { krb5_get_creds_opt_free(ctx, options); + krb5_free_principal(ctx, self_princ); return code; } - krb5_free_principal(ctx, target_princ); - - code = krb5_cc_store_cred(ctx, cc, impersonate_creds); krb5_get_creds_opt_free(ctx, options); - krb5_free_creds(ctx, impersonate_creds); + krb5_free_principal(ctx, self_princ); + + code = krb5_cc_store_cred(ctx, cc, s4u2self_creds); + krb5_free_creds(ctx, s4u2self_creds); return code; } -- cgit From 9c56303f5a56697470ea9f2ee1a428aed2367d75 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 20 Jun 2011 15:27:58 +0200 Subject: s4:auth/kerberos: don't mix s4u2self creds with machine account creds It's important that we don't store the tgt for the machine account in the same krb5_ccache as the ticket for the impersonated principal. We may pass it to some krb5/gssapi functions and they may use them in the wrong way, which would grant machine account privileges to the client. metze --- source4/auth/kerberos/kerberos.c | 100 +++++++++++++++++++++++++++++---------- 1 file changed, 76 insertions(+), 24 deletions(-) (limited to 'source4/auth') diff --git a/source4/auth/kerberos/kerberos.c b/source4/auth/kerberos/kerberos.c index 5e38d878be..5feb3e6221 100644 --- a/source4/auth/kerberos/kerberos.c +++ b/source4/auth/kerberos/kerberos.c @@ -84,7 +84,7 @@ The target_service defaults to the krbtgt if NULL, but could be kpasswd/realm or the local service (if we are doing s4u2self) */ - krb5_error_code kerberos_kinit_password_cc(krb5_context ctx, krb5_ccache cc, + krb5_error_code kerberos_kinit_password_cc(krb5_context ctx, krb5_ccache store_cc, krb5_principal init_principal, const char *init_password, krb5_principal impersonate_principal, @@ -93,14 +93,15 @@ time_t *expire_time, time_t *kdc_time) { krb5_error_code code = 0; - krb5_creds init_creds; krb5_get_creds_opt options; + krb5_principal store_principal; + krb5_creds store_creds; const char *self_service = target_service; /* If we are not impersonating, then get this ticket for the * target service, otherwise a krbtgt, and get the next ticket * for the target */ - if ((code = krb5_get_init_creds_password(ctx, &init_creds, + if ((code = krb5_get_init_creds_password(ctx, &store_creds, init_principal, init_password, NULL, NULL, @@ -110,31 +111,43 @@ return code; } - if ((code = krb5_cc_initialize(ctx, cc, init_principal))) { - krb5_free_cred_contents(ctx, &init_creds); - return code; - } - - if ((code = krb5_cc_store_cred(ctx, cc, &init_creds))) { - krb5_free_cred_contents(ctx, &init_creds); - return code; - } - - if (expire_time) { - *expire_time = (time_t) init_creds.times.endtime; - } - - if (kdc_time) { - *kdc_time = (time_t) init_creds.times.starttime; - } - - krb5_free_cred_contents(ctx, &init_creds); + store_principal = init_principal; if (code == 0 && impersonate_principal) { + krb5_ccache tmp_cc; krb5_creds *s4u2self_creds; krb5_principal self_princ; const char *self_realm; + /* + * As we do not want to expose our TGT in the + * krb5_ccache, which is also holds the impersonated creds. + * + * Some low level krb5/gssapi function might use the TGT + * identity and let the client act as our machine account. + * + * We need to avoid that and use a temporary krb5_ccache + * in order to pass our TGT to the krb5_get_creds() function. + */ + if ((code = krb5_cc_new_unique(ctx, NULL, NULL, &tmp_cc))) { + krb5_free_cred_contents(ctx, &store_creds); + return code; + } + + if ((code = krb5_cc_initialize(ctx, tmp_cc, store_creds.client))) { + krb5_cc_destroy(ctx, tmp_cc); + krb5_free_cred_contents(ctx, &store_creds); + return code; + } + + if ((code = krb5_cc_store_cred(ctx, tmp_cc, &store_creds))) { + krb5_cc_destroy(ctx, tmp_cc); + krb5_free_cred_contents(ctx, &store_creds); + return code; + } + + krb5_free_cred_contents(ctx, &store_creds); + /* * For S4U2Self we need our own service principal, * which belongs to our own realm (available on @@ -143,40 +156,79 @@ self_realm = krb5_principal_get_realm(ctx, init_principal); if ((code = krb5_parse_name(ctx, self_service, &self_princ))) { + krb5_cc_destroy(ctx, tmp_cc); return code; } if ((code = krb5_principal_set_realm(ctx, self_princ, self_realm))) { krb5_free_principal(ctx, self_princ); + krb5_cc_destroy(ctx, tmp_cc); return code; } if ((code = krb5_get_creds_opt_alloc(ctx, &options))) { krb5_free_principal(ctx, self_princ); + krb5_cc_destroy(ctx, tmp_cc); return code; } if ((code = krb5_get_creds_opt_set_impersonate(ctx, options, impersonate_principal))) { krb5_get_creds_opt_free(ctx, options); krb5_free_principal(ctx, self_princ); + krb5_cc_destroy(ctx, tmp_cc); return code; } - if ((code = krb5_get_creds(ctx, options, cc, self_princ, &s4u2self_creds))) { + if ((code = krb5_get_creds(ctx, options, tmp_cc, self_princ, &s4u2self_creds))) { krb5_get_creds_opt_free(ctx, options); krb5_free_principal(ctx, self_princ); + krb5_cc_destroy(ctx, tmp_cc); return code; } krb5_get_creds_opt_free(ctx, options); krb5_free_principal(ctx, self_princ); + krb5_cc_destroy(ctx, tmp_cc); - code = krb5_cc_store_cred(ctx, cc, s4u2self_creds); + /* + * Now make sure we store the impersonated principal + * and creds instead of the TGT related stuff + * in the krb5_ccache of the caller. + */ + if ((code = krb5_copy_creds_contents(ctx, s4u2self_creds, &store_creds))) { + krb5_free_creds(ctx, s4u2self_creds); + return code; + } krb5_free_creds(ctx, s4u2self_creds); + /* + * It's important to store the principal the KDC + * returned, as otherwise the caller would not find + * the S4U2Self ticket in the krb5_ccache lookup. + */ + store_principal = store_creds.client; + } + + if ((code = krb5_cc_initialize(ctx, store_cc, store_principal))) { + krb5_free_cred_contents(ctx, &store_creds); return code; } + if ((code = krb5_cc_store_cred(ctx, store_cc, &store_creds))) { + krb5_free_cred_contents(ctx, &store_creds); + return code; + } + + if (expire_time) { + *expire_time = (time_t) store_creds.times.endtime; + } + + if (kdc_time) { + *kdc_time = (time_t) store_creds.times.starttime; + } + + krb5_free_cred_contents(ctx, &store_creds); + return 0; } -- cgit From b98428e630cc5a1bbc18bf4260030a24322fdf9e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 20 Jun 2011 21:09:13 +0200 Subject: s4:auth/kerberos: reformat kerberos_kinit_password_cc() In order to make the following changes easier to review. metze --- source4/auth/kerberos/kerberos.c | 73 ++++++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 32 deletions(-) (limited to 'source4/auth') diff --git a/source4/auth/kerberos/kerberos.c b/source4/auth/kerberos/kerberos.c index 5feb3e6221..1ba6952e2b 100644 --- a/source4/auth/kerberos/kerberos.c +++ b/source4/auth/kerberos/kerberos.c @@ -98,22 +98,25 @@ krb5_creds store_creds; const char *self_service = target_service; - /* If we are not impersonating, then get this ticket for the + /* + * If we are not impersonating, then get this ticket for the * target service, otherwise a krbtgt, and get the next ticket - * for the target */ - if ((code = krb5_get_init_creds_password(ctx, &store_creds, - init_principal, - init_password, - NULL, NULL, - 0, - impersonate_principal ? NULL : target_service, - krb_options))) { + * for the target + */ + code = krb5_get_init_creds_password(ctx, &store_creds, + init_principal, + init_password, + NULL, NULL, + 0, + impersonate_principal ? NULL : target_service, + krb_options); + if (code != 0) { return code; } store_principal = init_principal; - if (code == 0 && impersonate_principal) { + if (impersonate_principal) { krb5_ccache tmp_cc; krb5_creds *s4u2self_creds; krb5_principal self_princ; @@ -129,25 +132,26 @@ * We need to avoid that and use a temporary krb5_ccache * in order to pass our TGT to the krb5_get_creds() function. */ - if ((code = krb5_cc_new_unique(ctx, NULL, NULL, &tmp_cc))) { + code = krb5_cc_new_unique(ctx, NULL, NULL, &tmp_cc); + if (code != 0) { krb5_free_cred_contents(ctx, &store_creds); return code; } - if ((code = krb5_cc_initialize(ctx, tmp_cc, store_creds.client))) { + code = krb5_cc_initialize(ctx, tmp_cc, store_creds.client); + if (code != 0) { krb5_cc_destroy(ctx, tmp_cc); krb5_free_cred_contents(ctx, &store_creds); return code; } - if ((code = krb5_cc_store_cred(ctx, tmp_cc, &store_creds))) { + code = krb5_cc_store_cred(ctx, tmp_cc, &store_creds); + krb5_free_cred_contents(ctx, &store_creds); + if (code != 0) { krb5_cc_destroy(ctx, tmp_cc); - krb5_free_cred_contents(ctx, &store_creds); return code; } - krb5_free_cred_contents(ctx, &store_creds); - /* * For S4U2Self we need our own service principal, * which belongs to our own realm (available on @@ -155,51 +159,54 @@ */ self_realm = krb5_principal_get_realm(ctx, init_principal); - if ((code = krb5_parse_name(ctx, self_service, &self_princ))) { - krb5_cc_destroy(ctx, tmp_cc); - return code; - } - - if ((code = krb5_principal_set_realm(ctx, self_princ, self_realm))) { - krb5_free_principal(ctx, self_princ); + code = krb5_parse_name(ctx, self_service, &self_princ); + if (code != 0) { krb5_cc_destroy(ctx, tmp_cc); return code; } - if ((code = krb5_get_creds_opt_alloc(ctx, &options))) { + code = krb5_principal_set_realm(ctx, self_princ, self_realm); + if (code != 0) { krb5_free_principal(ctx, self_princ); krb5_cc_destroy(ctx, tmp_cc); return code; } - if ((code = krb5_get_creds_opt_set_impersonate(ctx, options, impersonate_principal))) { - krb5_get_creds_opt_free(ctx, options); + code = krb5_get_creds_opt_alloc(ctx, &options); + if (code != 0) { krb5_free_principal(ctx, self_princ); krb5_cc_destroy(ctx, tmp_cc); return code; } - if ((code = krb5_get_creds(ctx, options, tmp_cc, self_princ, &s4u2self_creds))) { + code = krb5_get_creds_opt_set_impersonate(ctx, options, + impersonate_principal); + if (code != 0) { krb5_get_creds_opt_free(ctx, options); krb5_free_principal(ctx, self_princ); krb5_cc_destroy(ctx, tmp_cc); return code; } + code = krb5_get_creds(ctx, options, tmp_cc, + self_princ, &s4u2self_creds); krb5_get_creds_opt_free(ctx, options); krb5_free_principal(ctx, self_princ); krb5_cc_destroy(ctx, tmp_cc); + if (code != 0) { + return code; + } /* * Now make sure we store the impersonated principal * and creds instead of the TGT related stuff * in the krb5_ccache of the caller. */ - if ((code = krb5_copy_creds_contents(ctx, s4u2self_creds, &store_creds))) { - krb5_free_creds(ctx, s4u2self_creds); + code = krb5_copy_creds_contents(ctx, s4u2self_creds, &store_creds); + krb5_free_creds(ctx, s4u2self_creds); + if (code != 0) { return code; } - krb5_free_creds(ctx, s4u2self_creds); /* * It's important to store the principal the KDC @@ -209,12 +216,14 @@ store_principal = store_creds.client; } - if ((code = krb5_cc_initialize(ctx, store_cc, store_principal))) { + code = krb5_cc_initialize(ctx, store_cc, store_principal); + if (code != 0) { krb5_free_cred_contents(ctx, &store_creds); return code; } - if ((code = krb5_cc_store_cred(ctx, store_cc, &store_creds))) { + code = krb5_cc_store_cred(ctx, store_cc, &store_creds); + if (code != 0) { krb5_free_cred_contents(ctx, &store_creds); return code; } -- cgit From e5378e600e507241dd64c1ea7345676076dc8755 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 20 Jun 2011 21:23:45 +0200 Subject: s4:auth/kerberos: remove one indentation level in kerberos_kinit_password_cc() This will make the following changes easier to review. metze --- source4/auth/kerberos/kerberos.c | 193 ++++++++++++++++++++------------------- 1 file changed, 99 insertions(+), 94 deletions(-) (limited to 'source4/auth') diff --git a/source4/auth/kerberos/kerberos.c b/source4/auth/kerberos/kerberos.c index 1ba6952e2b..4acb54fb33 100644 --- a/source4/auth/kerberos/kerberos.c +++ b/source4/auth/kerberos/kerberos.c @@ -97,6 +97,10 @@ krb5_principal store_principal; krb5_creds store_creds; const char *self_service = target_service; + krb5_creds *s4u2self_creds; + krb5_principal self_princ; + krb5_ccache tmp_cc; + const char *self_realm; /* * If we are not impersonating, then get this ticket for the @@ -116,106 +120,107 @@ store_principal = init_principal; - if (impersonate_principal) { - krb5_ccache tmp_cc; - krb5_creds *s4u2self_creds; - krb5_principal self_princ; - const char *self_realm; - - /* - * As we do not want to expose our TGT in the - * krb5_ccache, which is also holds the impersonated creds. - * - * Some low level krb5/gssapi function might use the TGT - * identity and let the client act as our machine account. - * - * We need to avoid that and use a temporary krb5_ccache - * in order to pass our TGT to the krb5_get_creds() function. - */ - code = krb5_cc_new_unique(ctx, NULL, NULL, &tmp_cc); - if (code != 0) { - krb5_free_cred_contents(ctx, &store_creds); - return code; - } - - code = krb5_cc_initialize(ctx, tmp_cc, store_creds.client); - if (code != 0) { - krb5_cc_destroy(ctx, tmp_cc); - krb5_free_cred_contents(ctx, &store_creds); - return code; - } - - code = krb5_cc_store_cred(ctx, tmp_cc, &store_creds); + if (impersonate_principal == NULL) { + goto store; + } + + /* + * We are trying S4U2Self now: + * + * As we do not want to expose our TGT in the + * krb5_ccache, which is also holds the impersonated creds. + * + * Some low level krb5/gssapi function might use the TGT + * identity and let the client act as our machine account. + * + * We need to avoid that and use a temporary krb5_ccache + * in order to pass our TGT to the krb5_get_creds() function. + */ + code = krb5_cc_new_unique(ctx, NULL, NULL, &tmp_cc); + if (code != 0) { + krb5_free_cred_contents(ctx, &store_creds); + return code; + } + + code = krb5_cc_initialize(ctx, tmp_cc, store_creds.client); + if (code != 0) { + krb5_cc_destroy(ctx, tmp_cc); krb5_free_cred_contents(ctx, &store_creds); - if (code != 0) { - krb5_cc_destroy(ctx, tmp_cc); - return code; - } - - /* - * For S4U2Self we need our own service principal, - * which belongs to our own realm (available on - * our client principal. - */ - self_realm = krb5_principal_get_realm(ctx, init_principal); - - code = krb5_parse_name(ctx, self_service, &self_princ); - if (code != 0) { - krb5_cc_destroy(ctx, tmp_cc); - return code; - } - - code = krb5_principal_set_realm(ctx, self_princ, self_realm); - if (code != 0) { - krb5_free_principal(ctx, self_princ); - krb5_cc_destroy(ctx, tmp_cc); - return code; - } - - code = krb5_get_creds_opt_alloc(ctx, &options); - if (code != 0) { - krb5_free_principal(ctx, self_princ); - krb5_cc_destroy(ctx, tmp_cc); - return code; - } - - code = krb5_get_creds_opt_set_impersonate(ctx, options, - impersonate_principal); - if (code != 0) { - krb5_get_creds_opt_free(ctx, options); - krb5_free_principal(ctx, self_princ); - krb5_cc_destroy(ctx, tmp_cc); - return code; - } - - code = krb5_get_creds(ctx, options, tmp_cc, - self_princ, &s4u2self_creds); + return code; + } + + code = krb5_cc_store_cred(ctx, tmp_cc, &store_creds); + krb5_free_cred_contents(ctx, &store_creds); + if (code != 0) { + krb5_cc_destroy(ctx, tmp_cc); + return code; + } + + /* + * For S4U2Self we need our own service principal, + * which belongs to our own realm (available on + * our client principal). + */ + self_realm = krb5_principal_get_realm(ctx, init_principal); + + code = krb5_parse_name(ctx, self_service, &self_princ); + if (code != 0) { + krb5_cc_destroy(ctx, tmp_cc); + return code; + } + + code = krb5_principal_set_realm(ctx, self_princ, self_realm); + if (code != 0) { + krb5_free_principal(ctx, self_princ); + krb5_cc_destroy(ctx, tmp_cc); + return code; + } + + code = krb5_get_creds_opt_alloc(ctx, &options); + if (code != 0) { + krb5_free_principal(ctx, self_princ); + krb5_cc_destroy(ctx, tmp_cc); + return code; + } + + code = krb5_get_creds_opt_set_impersonate(ctx, options, + impersonate_principal); + if (code != 0) { krb5_get_creds_opt_free(ctx, options); krb5_free_principal(ctx, self_princ); krb5_cc_destroy(ctx, tmp_cc); - if (code != 0) { - return code; - } - - /* - * Now make sure we store the impersonated principal - * and creds instead of the TGT related stuff - * in the krb5_ccache of the caller. - */ - code = krb5_copy_creds_contents(ctx, s4u2self_creds, &store_creds); - krb5_free_creds(ctx, s4u2self_creds); - if (code != 0) { - return code; - } - - /* - * It's important to store the principal the KDC - * returned, as otherwise the caller would not find - * the S4U2Self ticket in the krb5_ccache lookup. - */ - store_principal = store_creds.client; + return code; } + code = krb5_get_creds(ctx, options, tmp_cc, + self_princ, &s4u2self_creds); + krb5_get_creds_opt_free(ctx, options); + krb5_free_principal(ctx, self_princ); + krb5_cc_destroy(ctx, tmp_cc); + if (code != 0) { + return code; + } + + /* + * Now make sure we store the impersonated principal + * and creds instead of the TGT related stuff + * in the krb5_ccache of the caller. + */ + code = krb5_copy_creds_contents(ctx, s4u2self_creds, + &store_creds); + krb5_free_creds(ctx, s4u2self_creds); + if (code != 0) { + return code; + } + + /* + * It's important to store the principal the KDC + * returned, as otherwise the caller would not find + * the S4U2Self ticket in the krb5_ccache lookup. + */ + store_principal = store_creds.client; + + store: code = krb5_cc_initialize(ctx, store_cc, store_principal); if (code != 0) { krb5_free_cred_contents(ctx, &store_creds); -- cgit From ede3046b8b9b0576a35626026cb28c31b42da46d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 21 Jun 2011 01:39:58 +0200 Subject: s4:auth/kerberos: protect kerberos_kinit_password_cc() against old KDCs Old KDCs may not support S4U2Self (or S4U2Proxy) and return tickets which belongs to the client principal of the TGT. metze Autobuild-User: Stefan Metzmacher Autobuild-Date: Wed Jun 22 09:10:55 CEST 2011 on sn-devel-104 --- source4/auth/kerberos/kerberos.c | 48 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) (limited to 'source4/auth') diff --git a/source4/auth/kerberos/kerberos.c b/source4/auth/kerberos/kerberos.c index 4acb54fb33..fa8c64b93e 100644 --- a/source4/auth/kerberos/kerberos.c +++ b/source4/auth/kerberos/kerberos.c @@ -101,6 +101,7 @@ krb5_principal self_princ; krb5_ccache tmp_cc; const char *self_realm; + krb5_principal blacklist_principal = NULL; /* * If we are not impersonating, then get this ticket for the @@ -150,12 +151,22 @@ } code = krb5_cc_store_cred(ctx, tmp_cc, &store_creds); - krb5_free_cred_contents(ctx, &store_creds); if (code != 0) { + krb5_free_cred_contents(ctx, &store_creds); krb5_cc_destroy(ctx, tmp_cc); return code; } + /* + * we need to remember the client principal of our + * TGT and make sure the KDC does not return this + * in the impersonated tickets. This can happen + * if the KDC does not support S4U2Self and S4U2Proxy. + */ + blacklist_principal = store_creds.client; + store_creds.client = NULL; + krb5_free_cred_contents(ctx, &store_creds); + /* * For S4U2Self we need our own service principal, * which belongs to our own realm (available on @@ -165,12 +176,14 @@ code = krb5_parse_name(ctx, self_service, &self_princ); if (code != 0) { + krb5_free_principal(ctx, blacklist_principal); krb5_cc_destroy(ctx, tmp_cc); return code; } code = krb5_principal_set_realm(ctx, self_princ, self_realm); if (code != 0) { + krb5_free_principal(ctx, blacklist_principal); krb5_free_principal(ctx, self_princ); krb5_cc_destroy(ctx, tmp_cc); return code; @@ -178,6 +191,7 @@ code = krb5_get_creds_opt_alloc(ctx, &options); if (code != 0) { + krb5_free_principal(ctx, blacklist_principal); krb5_free_principal(ctx, self_princ); krb5_cc_destroy(ctx, tmp_cc); return code; @@ -187,6 +201,7 @@ impersonate_principal); if (code != 0) { krb5_get_creds_opt_free(ctx, options); + krb5_free_principal(ctx, blacklist_principal); krb5_free_principal(ctx, self_princ); krb5_cc_destroy(ctx, tmp_cc); return code; @@ -198,6 +213,7 @@ krb5_free_principal(ctx, self_princ); krb5_cc_destroy(ctx, tmp_cc); if (code != 0) { + krb5_free_principal(ctx, blacklist_principal); return code; } @@ -210,6 +226,7 @@ &store_creds); krb5_free_creds(ctx, s4u2self_creds); if (code != 0) { + krb5_free_principal(ctx, blacklist_principal); return code; } @@ -221,6 +238,35 @@ store_principal = store_creds.client; store: + if (blacklist_principal && + krb5_principal_compare(ctx, store_creds.client, blacklist_principal)) { + char *sp = NULL; + char *ip = NULL; + + code = krb5_unparse_name(ctx, blacklist_principal, &sp); + if (code != 0) { + sp = NULL; + } + code = krb5_unparse_name(ctx, impersonate_principal, &ip); + if (code != 0) { + ip = NULL; + } + DEBUG(1, ("kerberos_kinit_password_cc: " + "KDC returned self principal[%s] while impersonating [%s]\n", + sp?sp:"", + ip?ip:"")); + + SAFE_FREE(sp); + SAFE_FREE(ip); + + krb5_free_principal(ctx, blacklist_principal); + krb5_free_cred_contents(ctx, &store_creds); + return KRB5_FWD_BAD_PRINCIPAL; + } + if (blacklist_principal) { + krb5_free_principal(ctx, blacklist_principal); + } + code = krb5_cc_initialize(ctx, store_cc, store_principal); if (code != 0) { krb5_free_cred_contents(ctx, &store_creds); -- cgit From b9e095fdfb684005f9bb5c1d943b2a0705308500 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 20 Jun 2011 20:28:44 +0200 Subject: s4:auth/kerberos: add S4U2Proxy support to kerberos_kinit_password_cc() For S4U2Proxy we need to use the ticket from the S4U2Self stage and ask the kdc for the delegated ticket for the target service. metze --- source4/auth/kerberos/kerberos.c | 134 +++++++++++++++++++++++++++++++++- source4/auth/kerberos/kerberos.h | 4 +- source4/auth/kerberos/kerberos_util.c | 1 + 3 files changed, 134 insertions(+), 5 deletions(-) (limited to 'source4/auth') diff --git a/source4/auth/kerberos/kerberos.c b/source4/auth/kerberos/kerberos.c index fa8c64b93e..d32559ed81 100644 --- a/source4/auth/kerberos/kerberos.c +++ b/source4/auth/kerberos/kerberos.c @@ -81,13 +81,16 @@ The impersonate_principal is the principal if NULL, or the principal to impersonate - The target_service defaults to the krbtgt if NULL, but could be kpasswd/realm or the local service (if we are doing s4u2self) + The self_service, should be the local service (for S4U2Self if impersonate_principal is given). + + The target_service defaults to the krbtgt if NULL, but could be kpasswd/realm or a remote service (for S4U2Proxy) */ krb5_error_code kerberos_kinit_password_cc(krb5_context ctx, krb5_ccache store_cc, krb5_principal init_principal, const char *init_password, krb5_principal impersonate_principal, + const char *self_service, const char *target_service, krb5_get_init_creds_opt *krb_options, time_t *expire_time, time_t *kdc_time) @@ -96,13 +99,21 @@ krb5_get_creds_opt options; krb5_principal store_principal; krb5_creds store_creds; - const char *self_service = target_service; krb5_creds *s4u2self_creds; + Ticket s4u2self_ticket; + size_t s4u2self_ticketlen; + krb5_creds *s4u2proxy_creds; krb5_principal self_princ; + bool s4u2proxy; + krb5_principal target_princ; krb5_ccache tmp_cc; const char *self_realm; krb5_principal blacklist_principal = NULL; + if (impersonate_principal && self_service == NULL) { + return EINVAL; + } + /* * If we are not impersonating, then get this ticket for the * target service, otherwise a krbtgt, and get the next ticket @@ -167,6 +178,18 @@ store_creds.client = NULL; krb5_free_cred_contents(ctx, &store_creds); + /* + * Check if we also need S4U2Proxy or if S4U2Self is + * enough in order to get a ticket for the target. + */ + if (target_service == NULL) { + s4u2proxy = false; + } else if (strcmp(target_service, self_service) == 0) { + s4u2proxy = false; + } else { + s4u2proxy = true; + } + /* * For S4U2Self we need our own service principal, * which belongs to our own realm (available on @@ -197,6 +220,14 @@ return code; } + if (s4u2proxy) { + /* + * If we want S4U2Proxy, we need the forwardable flag + * on the S4U2Self ticket. + */ + krb5_get_creds_opt_set_options(ctx, options, KRB5_GC_FORWARDABLE); + } + code = krb5_get_creds_opt_set_impersonate(ctx, options, impersonate_principal); if (code != 0) { @@ -211,6 +242,101 @@ self_princ, &s4u2self_creds); krb5_get_creds_opt_free(ctx, options); krb5_free_principal(ctx, self_princ); + if (code != 0) { + krb5_free_principal(ctx, blacklist_principal); + krb5_cc_destroy(ctx, tmp_cc); + return code; + } + + if (!s4u2proxy) { + krb5_cc_destroy(ctx, tmp_cc); + + /* + * Now make sure we store the impersonated principal + * and creds instead of the TGT related stuff + * in the krb5_ccache of the caller. + */ + code = krb5_copy_creds_contents(ctx, s4u2self_creds, + &store_creds); + krb5_free_creds(ctx, s4u2self_creds); + if (code != 0) { + return code; + } + + /* + * It's important to store the principal the KDC + * returned, as otherwise the caller would not find + * the S4U2Self ticket in the krb5_ccache lookup. + */ + store_principal = store_creds.client; + goto store; + } + + /* + * We are trying S4U2Proxy: + * + * We need the ticket from the S4U2Self step + * and our TGT in order to get the delegated ticket. + */ + code = decode_Ticket((const uint8_t *)s4u2self_creds->ticket.data, + s4u2self_creds->ticket.length, + &s4u2self_ticket, + &s4u2self_ticketlen); + krb5_free_creds(ctx, s4u2self_creds); + if (code != 0) { + krb5_free_principal(ctx, blacklist_principal); + krb5_cc_destroy(ctx, tmp_cc); + return code; + } + + /* + * For S4U2Proxy we also got a target service principal, + * which also belongs to our own realm (available on + * our client principal). + */ + code = krb5_parse_name(ctx, target_service, &target_princ); + if (code != 0) { + free_Ticket(&s4u2self_ticket); + krb5_free_principal(ctx, blacklist_principal); + krb5_cc_destroy(ctx, tmp_cc); + return code; + } + + code = krb5_principal_set_realm(ctx, target_princ, self_realm); + if (code != 0) { + free_Ticket(&s4u2self_ticket); + krb5_free_principal(ctx, target_princ); + krb5_free_principal(ctx, blacklist_principal); + krb5_cc_destroy(ctx, tmp_cc); + return code; + } + + code = krb5_get_creds_opt_alloc(ctx, &options); + if (code != 0) { + free_Ticket(&s4u2self_ticket); + krb5_free_principal(ctx, target_princ); + krb5_free_principal(ctx, blacklist_principal); + krb5_cc_destroy(ctx, tmp_cc); + return code; + } + + krb5_get_creds_opt_set_options(ctx, options, KRB5_GC_FORWARDABLE); + krb5_get_creds_opt_set_options(ctx, options, KRB5_GC_CONSTRAINED_DELEGATION); + + code = krb5_get_creds_opt_set_ticket(ctx, options, &s4u2self_ticket); + free_Ticket(&s4u2self_ticket); + if (code != 0) { + krb5_get_creds_opt_free(ctx, options); + krb5_free_principal(ctx, target_princ); + krb5_free_principal(ctx, blacklist_principal); + krb5_cc_destroy(ctx, tmp_cc); + return code; + } + + code = krb5_get_creds(ctx, options, tmp_cc, + target_princ, &s4u2proxy_creds); + krb5_get_creds_opt_free(ctx, options); + krb5_free_principal(ctx, target_princ); krb5_cc_destroy(ctx, tmp_cc); if (code != 0) { krb5_free_principal(ctx, blacklist_principal); @@ -222,9 +348,9 @@ * and creds instead of the TGT related stuff * in the krb5_ccache of the caller. */ - code = krb5_copy_creds_contents(ctx, s4u2self_creds, + code = krb5_copy_creds_contents(ctx, s4u2proxy_creds, &store_creds); - krb5_free_creds(ctx, s4u2self_creds); + krb5_free_creds(ctx, s4u2proxy_creds); if (code != 0) { krb5_free_principal(ctx, blacklist_principal); return code; diff --git a/source4/auth/kerberos/kerberos.h b/source4/auth/kerberos/kerberos.h index c712569e5d..31794b8e03 100644 --- a/source4/auth/kerberos/kerberos.h +++ b/source4/auth/kerberos/kerberos.h @@ -97,7 +97,9 @@ krb5_error_code ads_krb5_mk_req(krb5_context context, bool get_auth_data_from_tkt(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, krb5_ticket *tkt); krb5_error_code kerberos_kinit_password_cc(krb5_context ctx, krb5_ccache cc, krb5_principal principal, const char *password, - krb5_principal impersonate_principal, const char *target_service, + krb5_principal impersonate_principal, + const char *self_service, + const char *target_service, krb5_get_init_creds_opt *krb_options, time_t *expire_time, time_t *kdc_time); krb5_error_code kerberos_kinit_keyblock_cc(krb5_context ctx, krb5_ccache cc, diff --git a/source4/auth/kerberos/kerberos_util.c b/source4/auth/kerberos/kerberos_util.c index 9cef977306..9a48e95c6d 100644 --- a/source4/auth/kerberos/kerberos_util.c +++ b/source4/auth/kerberos/kerberos_util.c @@ -408,6 +408,7 @@ krb5_error_code principal_from_credentials(TALLOC_CTX *parent_ctx, princ, password, impersonate_principal, self_service, + target_service, krb_options, NULL, &kdc_time); } else if (impersonate_principal) { -- cgit From 033f3376a834c1078b377647069b7e30aef59667 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 21 Jun 2011 11:05:15 +0200 Subject: s4:auth/kerberos: protect kerberos_kinit_password_cc() against old KDCs If the KDC does not support S4U2Proxy, it might return a ticket for the TGT client principal. metze --- source4/auth/kerberos/kerberos.c | 49 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) (limited to 'source4/auth') diff --git a/source4/auth/kerberos/kerberos.c b/source4/auth/kerberos/kerberos.c index d32559ed81..0fc9d143ab 100644 --- a/source4/auth/kerberos/kerberos.c +++ b/source4/auth/kerberos/kerberos.c @@ -109,6 +109,7 @@ krb5_ccache tmp_cc; const char *self_realm; krb5_principal blacklist_principal = NULL; + krb5_principal whitelist_principal = NULL; if (impersonate_principal && self_service == NULL) { return EINVAL; @@ -282,13 +283,23 @@ s4u2self_creds->ticket.length, &s4u2self_ticket, &s4u2self_ticketlen); - krb5_free_creds(ctx, s4u2self_creds); if (code != 0) { + krb5_free_creds(ctx, s4u2self_creds); krb5_free_principal(ctx, blacklist_principal); krb5_cc_destroy(ctx, tmp_cc); return code; } + /* + * we need to remember the client principal of the + * S4U2Self stage and as it needs to match the one we + * will get for the S4U2Proxy stage. We need this + * in order to detect KDCs which does not support S4U2Proxy. + */ + whitelist_principal = s4u2self_creds->client; + s4u2self_creds->client = NULL; + krb5_free_creds(ctx, s4u2self_creds); + /* * For S4U2Proxy we also got a target service principal, * which also belongs to our own realm (available on @@ -297,6 +308,7 @@ code = krb5_parse_name(ctx, target_service, &target_princ); if (code != 0) { free_Ticket(&s4u2self_ticket); + krb5_free_principal(ctx, whitelist_principal); krb5_free_principal(ctx, blacklist_principal); krb5_cc_destroy(ctx, tmp_cc); return code; @@ -306,6 +318,7 @@ if (code != 0) { free_Ticket(&s4u2self_ticket); krb5_free_principal(ctx, target_princ); + krb5_free_principal(ctx, whitelist_principal); krb5_free_principal(ctx, blacklist_principal); krb5_cc_destroy(ctx, tmp_cc); return code; @@ -315,6 +328,7 @@ if (code != 0) { free_Ticket(&s4u2self_ticket); krb5_free_principal(ctx, target_princ); + krb5_free_principal(ctx, whitelist_principal); krb5_free_principal(ctx, blacklist_principal); krb5_cc_destroy(ctx, tmp_cc); return code; @@ -328,6 +342,7 @@ if (code != 0) { krb5_get_creds_opt_free(ctx, options); krb5_free_principal(ctx, target_princ); + krb5_free_principal(ctx, whitelist_principal); krb5_free_principal(ctx, blacklist_principal); krb5_cc_destroy(ctx, tmp_cc); return code; @@ -339,6 +354,7 @@ krb5_free_principal(ctx, target_princ); krb5_cc_destroy(ctx, tmp_cc); if (code != 0) { + krb5_free_principal(ctx, whitelist_principal); krb5_free_principal(ctx, blacklist_principal); return code; } @@ -352,6 +368,7 @@ &store_creds); krb5_free_creds(ctx, s4u2proxy_creds); if (code != 0) { + krb5_free_principal(ctx, whitelist_principal); krb5_free_principal(ctx, blacklist_principal); return code; } @@ -385,6 +402,7 @@ SAFE_FREE(sp); SAFE_FREE(ip); + krb5_free_principal(ctx, whitelist_principal); krb5_free_principal(ctx, blacklist_principal); krb5_free_cred_contents(ctx, &store_creds); return KRB5_FWD_BAD_PRINCIPAL; @@ -393,6 +411,35 @@ krb5_free_principal(ctx, blacklist_principal); } + if (whitelist_principal && + !krb5_principal_compare(ctx, store_creds.client, whitelist_principal)) { + char *sp = NULL; + char *ep = NULL; + + code = krb5_unparse_name(ctx, store_creds.client, &sp); + if (code != 0) { + sp = NULL; + } + code = krb5_unparse_name(ctx, whitelist_principal, &ep); + if (code != 0) { + ep = NULL; + } + DEBUG(1, ("kerberos_kinit_password_cc: " + "KDC returned wrong principal[%s] we expected [%s]\n", + sp?sp:"", + ep?ep:"")); + + SAFE_FREE(sp); + SAFE_FREE(ep); + + krb5_free_principal(ctx, whitelist_principal); + krb5_free_cred_contents(ctx, &store_creds); + return KRB5_FWD_BAD_PRINCIPAL; + } + if (whitelist_principal) { + krb5_free_principal(ctx, whitelist_principal); + } + code = krb5_cc_initialize(ctx, store_cc, store_principal); if (code != 0) { krb5_free_cred_contents(ctx, &store_creds); -- cgit