auth/credentials: Add cli_credentials_{set,get}_forced_sasl_mech()
authorAndrew Bartlett <abartlet@samba.org>
Mon, 16 Sep 2013 16:38:09 +0000 (09:38 -0700)
committerNadezhda Ivanova <nivanova@symas.com>
Mon, 16 Sep 2013 21:44:28 +0000 (14:44 -0700)
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 <abartlet@samba.org>
Reviewed-by: Nadezhda Ivanova <nivanova@symas.com>
auth/credentials/credentials.c
auth/credentials/credentials.h
auth/credentials/credentials_internal.h
auth/credentials/pycredentials.c
auth/gensec/gensec_start.c

index 57a7c0b80d068e5039e92cf33f5a322532990d62..e98dfbdae4e49187b3f315be59672959c91b1507 100644 (file)
@@ -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;
index 766a513cca939c77a7e3072dd4290280c6ce5c58..fdd35bbd42506480032ec066d5fac6fa1f988c65 100644 (file)
@@ -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,
index f2f79b9f774e064c2733bb98db73fcfca3ab4d89..d05d1532cb0c1033244d1a5498ad6c5dc9c96890 100644 (file)
@@ -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;
 
index 14fd5e01ba92e97f2100151c9aedd485bea8a861..e32d9a93d04e4113238560f15df1bc7bf9ceda07 100644 (file)
@@ -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 }
 };
 
index 3ae64d5683fd86270c5a58d8f61854c7b9c0e57b..81b6abc2a48b012b1ffa7e7dd59578d608ccea3d 100644 (file)
@@ -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));