From 3f464ca1f5672491edf5daf15389cf7f2dc68e2b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 16 Sep 2013 09:38:09 -0700 Subject: auth/credentials: Add cli_credentials_{set,get}_forced_sasl_mech() This will allow us to force the use of only DIGEST-MD5, for example, which is useful to avoid hitting GSSAPI, SPNEGO or NTLM when talking to OpenLDAP and Cyrus-SASL. Andrew Bartlett Signed-off-by: Andrew Bartlett Reviewed-by: Nadezhda Ivanova --- auth/credentials/credentials.c | 14 ++++++++++++++ auth/credentials/credentials.h | 3 +++ auth/credentials/credentials_internal.h | 3 +++ auth/credentials/pycredentials.c | 26 ++++++++++++++++++++++++++ auth/gensec/gensec_start.c | 14 ++++++++++++++ 5 files changed, 60 insertions(+) (limited to 'auth') diff --git a/auth/credentials/credentials.c b/auth/credentials/credentials.c index 57a7c0b80d..e98dfbdae4 100644 --- a/auth/credentials/credentials.c +++ b/auth/credentials/credentials.c @@ -112,6 +112,8 @@ _PUBLIC_ struct cli_credentials *cli_credentials_init(TALLOC_CTX *mem_ctx) cli_credentials_set_gensec_features(cred, 0); cli_credentials_set_krb_forwardable(cred, CRED_AUTO_KRB_FORWARDABLE); + cred->forced_sasl_mech = NULL; + return cred; } @@ -161,6 +163,13 @@ _PUBLIC_ void cli_credentials_set_kerberos_state(struct cli_credentials *creds, creds->use_kerberos = use_kerberos; } +_PUBLIC_ void cli_credentials_set_forced_sasl_mech(struct cli_credentials *creds, + const char *sasl_mech) +{ + TALLOC_FREE(creds->forced_sasl_mech); + creds->forced_sasl_mech = talloc_strdup(creds, sasl_mech); +} + _PUBLIC_ void cli_credentials_set_krb_forwardable(struct cli_credentials *creds, enum credentials_krb_forwardable krb_forwardable) { @@ -172,6 +181,11 @@ _PUBLIC_ enum credentials_use_kerberos cli_credentials_get_kerberos_state(struct return creds->use_kerberos; } +_PUBLIC_ const char *cli_credentials_get_forced_sasl_mech(struct cli_credentials *creds) +{ + return creds->forced_sasl_mech; +} + _PUBLIC_ enum credentials_krb_forwardable cli_credentials_get_krb_forwardable(struct cli_credentials *creds) { return creds->krb_forwardable; diff --git a/auth/credentials/credentials.h b/auth/credentials/credentials.h index 766a513cca..fdd35bbd42 100644 --- a/auth/credentials/credentials.h +++ b/auth/credentials/credentials.h @@ -118,6 +118,8 @@ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred, struct loadparm_context *lp_ctx, struct gssapi_creds_container **_gcc, const char **error_string); +void cli_credentials_set_forced_sasl_mech(struct cli_credentials *creds, + const char *sasl_mech); void cli_credentials_set_kerberos_state(struct cli_credentials *creds, enum credentials_use_kerberos use_kerberos); void cli_credentials_set_krb_forwardable(struct cli_credentials *creds, @@ -206,6 +208,7 @@ const char *cli_credentials_get_impersonate_principal(struct cli_credentials *cr 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); +const char *cli_credentials_get_forced_sasl_mech(struct cli_credentials *cred); enum credentials_krb_forwardable cli_credentials_get_krb_forwardable(struct cli_credentials *creds); NTSTATUS cli_credentials_set_secrets(struct cli_credentials *cred, struct loadparm_context *lp_ctx, diff --git a/auth/credentials/credentials_internal.h b/auth/credentials/credentials_internal.h index f2f79b9f77..d05d1532cb 100644 --- a/auth/credentials/credentials_internal.h +++ b/auth/credentials/credentials_internal.h @@ -101,6 +101,9 @@ struct cli_credentials { /* Should we get a forwardable ticket? */ enum credentials_krb_forwardable krb_forwardable; + /* Forced SASL mechansim */ + char *forced_sasl_mech; + /* gensec features which should be used for connections */ uint32_t gensec_features; diff --git a/auth/credentials/pycredentials.c b/auth/credentials/pycredentials.c index 14fd5e01ba..e32d9a93d0 100644 --- a/auth/credentials/pycredentials.c +++ b/auth/credentials/pycredentials.c @@ -229,6 +229,27 @@ static PyObject *py_creds_set_krb_forwardable(pytalloc_Object *self, PyObject *a Py_RETURN_NONE; } + +static PyObject *py_creds_get_forced_sasl_mech(pytalloc_Object *self) +{ + return PyString_FromStringOrNULL(cli_credentials_get_forced_sasl_mech(PyCredentials_AsCliCredentials(self))); +} + +static PyObject *py_creds_set_forced_sasl_mech(pytalloc_Object *self, PyObject *args) +{ + char *newval; + enum credentials_obtained obt = CRED_SPECIFIED; + int _obt = obt; + + if (!PyArg_ParseTuple(args, "s", &newval)) { + return NULL; + } + obt = _obt; + + cli_credentials_set_forced_sasl_mech(PyCredentials_AsCliCredentials(self), newval); + Py_RETURN_NONE; +} + static PyObject *py_creds_guess(pytalloc_Object *self, PyObject *args) { PyObject *py_lp_ctx = Py_None; @@ -440,6 +461,11 @@ static PyMethodDef py_creds_methods[] = { { "get_named_ccache", (PyCFunction)py_creds_get_named_ccache, METH_VARARGS, NULL }, { "set_gensec_features", (PyCFunction)py_creds_set_gensec_features, METH_VARARGS, NULL }, { "get_gensec_features", (PyCFunction)py_creds_get_gensec_features, METH_NOARGS, NULL }, + { "get_forced_sasl_mech", (PyCFunction)py_creds_get_forced_sasl_mech, METH_NOARGS, + "S.get_forced_sasl_mech() -> SASL mechanism\nObtain forced SASL mechanism." }, + { "set_forced_sasl_mech", (PyCFunction)py_creds_set_forced_sasl_mech, METH_VARARGS, + "S.set_forced_sasl_mech(name) -> None\n" + "Set forced SASL mechanism." }, { NULL } }; diff --git a/auth/gensec/gensec_start.c b/auth/gensec/gensec_start.c index 3ae64d5683..81b6abc2a4 100644 --- a/auth/gensec/gensec_start.c +++ b/auth/gensec/gensec_start.c @@ -668,6 +668,20 @@ _PUBLIC_ NTSTATUS gensec_server_start(TALLOC_CTX *mem_ctx, NTSTATUS gensec_start_mech(struct gensec_security *gensec_security) { NTSTATUS status; + + if (gensec_security->credentials) { + const char *forced_mech = cli_credentials_get_forced_sasl_mech(gensec_security->credentials); + if (forced_mech && + (gensec_security->ops->sasl_name == NULL || + strcasecmp(forced_mech, gensec_security->ops->sasl_name) != 0)) { + DEBUG(5, ("GENSEC mechanism %s (%s) skipped, as it " + "did not match forced mechanism %s\n", + gensec_security->ops->name, + gensec_security->ops->sasl_name, + forced_mech)); + return NT_STATUS_INVALID_PARAMETER; + } + } DEBUG(5, ("Starting GENSEC %smechanism %s\n", gensec_security->subcontext ? "sub" : "", gensec_security->ops->name)); -- cgit