TODO: s3-libads: Pass cli_credentials to ads_sasl_spnego_gensec_bind()
authorAndreas Schneider <asn@samba.org>
Thu, 15 Sep 2016 08:48:19 +0000 (10:48 +0200)
committerStefan Metzmacher <metze@samba.org>
Mon, 18 Feb 2019 12:46:10 +0000 (13:46 +0100)
Signed-off-by: Andreas Schneider <asn@samba.org>
source3/libads/sasl.c

index 0dc7597e8e175a8a73ea998a8860610c8b36cea8..841f24c6487106e4de33620309c8ec3d86a89a6f 100644 (file)
 #include "ads.h"
 #include "smb_krb5.h"
 #include "system/gssapi.h"
-#include "lib/param/loadparm.h"
+#include "lib/param/param.h"
 #include "krb5_env.h"
 
+static struct cli_credentials *ads_sasl_creds_init(TALLOC_CTX *mem_ctx,
+                                                  const char *username,
+                                                  const char *password,
+                                                  const char *domain,
+                                                  const char *realm,
+                                                  enum credentials_use_kerberos krb5_state)
+{
+       struct loadparm_context *lp_ctx;
+       struct cli_credentials *creds;
+       bool ok;
+
+       creds = cli_credentials_init(mem_ctx);
+       if (creds == NULL) {
+               return NULL;
+       }
+
+       lp_ctx = loadparm_init_s3(creds, loadparm_s3_helpers());
+       if (lp_ctx == NULL) {
+               goto fail;
+       }
+       cli_credentials_set_conf(creds, lp_ctx);
+
+       if (username != NULL) {
+               ok = cli_credentials_set_username(creds,
+                                                 username,
+                                                 CRED_SPECIFIED);
+               if (!ok) {
+                       goto fail;
+               }
+       }
+
+       if (password != NULL) {
+               ok = cli_credentials_set_password(creds,
+                                                 password,
+                                                 CRED_SPECIFIED);
+               if (!ok) {
+                       goto fail;
+               }
+       }
+
+       if (domain != NULL) {
+               ok = cli_credentials_set_domain(creds,
+                                               domain,
+                                               CRED_SPECIFIED);
+               if (!ok) {
+                       goto fail;
+               }
+       }
+
+       if (realm != NULL) {
+               ok = cli_credentials_set_realm(creds,
+                                              realm,
+                                              CRED_SPECIFIED);
+               if (!ok) {
+                       goto fail;
+               }
+       }
+
+       cli_credentials_set_kerberos_state(creds, krb5_state);
+
+       return creds;
+fail:
+       TALLOC_FREE(creds);
+       return NULL;
+}
+
 #ifdef HAVE_LDAP
 
 static ADS_STATUS ads_sasl_gensec_wrap(struct ads_saslwrap *wrap,
@@ -123,7 +189,7 @@ static const struct ads_saslwrap_ops ads_sasl_gensec_ops = {
 */
 static ADS_STATUS ads_sasl_spnego_gensec_bind(ADS_STRUCT *ads,
                                const char *sasl,
-                               enum credentials_use_kerberos krb5_state,
+                               struct cli_credentials *creds,
                                const char *target_service,
                                const char *target_hostname,
                                const DATA_BLOB server_blob)
@@ -136,6 +202,7 @@ static ADS_STATUS ads_sasl_spnego_gensec_bind(ADS_STRUCT *ads,
        struct auth_generic_state *auth_generic_state;
        bool use_spnego_principal = lp_client_use_spnego_principal();
        const char *sasl_list[] = { sasl, NULL };
+       enum credentials_use_kerberos krb5_state;
        NTTIME end_nt_time;
        struct ads_saslwrap *wrap = &ads->ldap_wrap_data;
 
@@ -144,13 +211,8 @@ static ADS_STATUS ads_sasl_spnego_gensec_bind(ADS_STRUCT *ads,
                return ADS_ERROR_NT(nt_status);
        }
 
-       if (!NT_STATUS_IS_OK(nt_status = auth_generic_set_username(auth_generic_state, ads->auth.user_name))) {
-               return ADS_ERROR_NT(nt_status);
-       }
-       if (!NT_STATUS_IS_OK(nt_status = auth_generic_set_domain(auth_generic_state, ads->auth.realm))) {
-               return ADS_ERROR_NT(nt_status);
-       }
-       if (!NT_STATUS_IS_OK(nt_status = auth_generic_set_password(auth_generic_state, ads->auth.password))) {
+       nt_status = auth_generic_set_creds(auth_generic_state, creds);
+       if (!NT_STATUS_IS_OK(nt_status)) {
                return ADS_ERROR_NT(nt_status);
        }
 
@@ -158,13 +220,11 @@ static ADS_STATUS ads_sasl_spnego_gensec_bind(ADS_STRUCT *ads,
                use_spnego_principal = false;
        }
 
+       krb5_state = cli_credentials_get_kerberos_state(creds);
        if (krb5_state == CRED_DONT_USE_KERBEROS) {
                use_spnego_principal = false;
        }
 
-       cli_credentials_set_kerberos_state(auth_generic_state->credentials,
-                                          krb5_state);
-
        if (target_service != NULL) {
                nt_status = gensec_set_target_service(
                                        auth_generic_state->gensec_security,
@@ -534,6 +594,7 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads)
        struct ads_service_principal p = {0};
        ADS_STATUS status;
        enum credentials_use_kerberos krb5_state;
+       struct cli_credentials *creds;
 
        if (ads->auth.flags & ADS_AUTH_DISABLE_KERBEROS) {
                krb5_state = CRED_DONT_USE_KERBEROS;
@@ -548,51 +609,24 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads)
                goto done;
        }
 
-       if (krb5_state == CRED_DONT_USE_KERBEROS) {
-               goto do_ntlmssp;
-       }
-
-       if (ads->auth.password == NULL ||
-           ads->auth.password[0] == '\0')
-       {
-               status = ads_sasl_spnego_gensec_bind(ads,
-                                                    "GSS-SPNEGO",
-                                                    krb5_state,
-                                                    p.service,
-                                                    p.hostname,
-                                                    data_blob_null);
-               if (ADS_ERR_OK(status)) {
-                       goto done;
-               }
-
-               DEBUG(10,("ads_sasl_spnego_gensec_bind(GSS-SPNEGO): "
-                         "failed with: %s, calling kinit\n",
-                         ads_errstr(status)));
+       creds = ads_sasl_creds_init(frame,
+                                   ads->auth.user_name,
+                                   ads->auth.password,
+                                   ads->auth.realm,
+                                   ads->auth.realm,
+                                   krb5_state);
+       if (creds == NULL) {
+               status = ADS_ERROR_SYSTEM(ENOMEM);
+               goto done;
        }
 
-       status = ADS_ERROR_KRB5(ads_kinit_password(ads));
+       status = ads_sasl_spnego_gensec_bind(ads,
+                                            "GSS-SPNEGO",
+                                            creds,
+                                            p.service,
+                                            p.hostname,
+                                            data_blob_null);
 
- do_ntlmssp:
-       if (ADS_ERR_OK(status)) {
-               status = ads_sasl_spnego_gensec_bind(ads,
-                                                    "GSS-SPNEGO",
-                                                    krb5_state,
-                                                    p.service,
-                                                    p.hostname,
-                                                    data_blob_null);
-               if (!ADS_ERR_OK(status)) {
-                       DEBUG(0,("kinit succeeded but "
-                               "ads_sasl_spnego_gensec_bind() failed: %s\n",
-                               ads_errstr(status)));
-               }
-
-               DEBUG(1,("ads_sasl_spnego_gensec_bind(GSS-SPNEGO) failed "
-                        "for %s/%s with user[%s] realm[%s]: %s\n",
-                        p.service, p.hostname,
-                        ads->auth.user_name,
-                        ads->auth.realm,
-                        ads_errstr(status)));
-       }
 done:
        if (!ADS_ERR_OK(status)) {
                DEBUG(1,("ads_sasl_spnego_gensec_bind(GSS-SPNEGO) failed "
@@ -611,44 +645,37 @@ done:
 
 static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads)
 {
+       TALLOC_CTX *frame = talloc_stackframe();
        ADS_STATUS status;
        struct ads_service_principal p;
+       struct cli_credentials *creds;
 
        status = ads_generate_service_principal(ads, &p);
        if (!ADS_ERR_OK(status)) {
-               return status;
+               goto done;
        }
 
-       if (ads->auth.password == NULL ||
-           ads->auth.password[0] == '\0') {
-               status = ads_sasl_spnego_gensec_bind(ads,
-                                                    "GSSAPI",
-                                                    CRED_MUST_USE_KERBEROS,
-                                                    p.service,
-                                                    p.hostname,
-                                                    data_blob_null);
-               if (ADS_ERR_OK(status)) {
-                       ads_free_service_principal(&p);
-                       return status;
-               }
-
-               DEBUG(10,("ads_sasl_spnego_gensec_bind(KRB5) failed with: %s, "
-                         "calling kinit\n", ads_errstr(status)));
+       creds = ads_sasl_creds_init(frame,
+                                   ads->auth.user_name,
+                                   ads->auth.password,
+                                   ads->auth.realm,
+                                   ads->auth.realm,
+                                   CRED_MUST_USE_KERBEROS);
+       if (creds == NULL) {
+               status = ADS_ERROR_SYSTEM(ENOMEM);
+               goto done;
        }
 
-       status = ADS_ERROR_KRB5(ads_kinit_password(ads));
-
-       if (ADS_ERR_OK(status)) {
-               status = ads_sasl_spnego_gensec_bind(ads,
-                                                    "GSSAPI",
-                                                    CRED_MUST_USE_KERBEROS,
-                                                    p.service,
-                                                    p.hostname,
-                                                    data_blob_null);
-       }
+       status = ads_sasl_spnego_gensec_bind(ads,
+                                            "GSSAPI",
+                                            creds,
+                                            p.service,
+                                            p.hostname,
+                                            data_blob_null);
 
+done:
        ads_free_service_principal(&p);
-
+       TALLOC_FREE(frame);
        return status;
 }