diff options
author | Andrew Bartlett <abartlet@samba.org> | 2011-06-24 16:26:23 +1000 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2011-06-24 16:26:23 +1000 |
commit | 6da26870e0ae5acd6ff49a30ec2f6886b44d095e (patch) | |
tree | 850c71039563c16a5d563c47e7ba2ab645baf198 /source4/auth/gensec | |
parent | 6925a799d04c6fa59dd2ddef1f5510f9bb7d17d1 (diff) | |
parent | 2610c05b5b95cc7036b3d6dfb894c6cfbdb68483 (diff) | |
download | samba-6da26870e0ae5acd6ff49a30ec2f6886b44d095e.tar.gz samba-6da26870e0ae5acd6ff49a30ec2f6886b44d095e.tar.bz2 samba-6da26870e0ae5acd6ff49a30ec2f6886b44d095e.zip |
Merge 2610c05b5b95cc7036b3d6dfb894c6cfbdb68483 as Samba-4.0alpha16
Diffstat (limited to 'source4/auth/gensec')
-rw-r--r-- | source4/auth/gensec/cyrus_sasl.c | 4 | ||||
-rw-r--r-- | source4/auth/gensec/gensec.c | 10 | ||||
-rw-r--r-- | source4/auth/gensec/gensec.h | 8 | ||||
-rw-r--r-- | source4/auth/gensec/gensec_gssapi.c | 120 | ||||
-rw-r--r-- | source4/auth/gensec/pygensec.c | 8 |
5 files changed, 82 insertions, 68 deletions
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; } diff --git a/source4/auth/gensec/gensec.c b/source4/auth/gensec/gensec.c index e632aec2dc..7e6a83d51f 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; @@ -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; @@ -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 48268c421e..e42b4aa5d2 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, @@ -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, @@ -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/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index 59029e6fc9..72c6b3f991 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; @@ -340,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; @@ -557,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: @@ -1262,7 +1287,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; @@ -1277,25 +1301,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); diff --git a/source4/auth/gensec/pygensec.c b/source4/auth/gensec/pygensec.c index fd9726eb75..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); @@ -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", @@ -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); |