s3: Add sync cli_notify
[ab/samba.git/.git] / source3 / auth / auth_generic.c
index e73c27b5ebe96fe08643e6665f6959724cb1dce0..f99d390edd118ece4ac26261d6b9ebe3890d9733 100644 (file)
@@ -29,6 +29,8 @@
 #ifdef HAVE_KRB5
 #include "libcli/auth/krb5_wrap.h"
 #endif
+#include "librpc/crypto/gse.h"
+#include "auth/credentials/credentials.h"
 
 static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx,
                                                TALLOC_CTX *mem_ctx,
@@ -125,6 +127,12 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx,
                netsamlogon_cache_store(ntuser, &logon_info->info3);
        }
 
+       /* setup the string used by %U */
+       sub_set_smb_name(username);
+
+       /* reload services so that the new %U is taken into account */
+       lp_load(get_dyn_CONFIGFILE(), false, false, true, true);
+
        status = make_session_info_krb5(mem_ctx,
                                        ntuser, ntdomain, username, pw,
                                        logon_info, is_guest, is_mapped, NULL /* No session key for now, caller will sort it out */,
@@ -146,6 +154,54 @@ done:
        return status;
 }
 
+static struct auth4_context *make_auth4_context_s3(TALLOC_CTX *mem_ctx, struct auth_context *auth_context)
+{
+       struct auth4_context *auth4_context = talloc_zero(mem_ctx, struct auth4_context);
+       if (auth4_context == NULL) {
+               DEBUG(10, ("failed to allocate auth4_context failed\n"));
+               return NULL;
+       }
+       auth4_context->generate_session_info_pac = auth3_generate_session_info_pac;
+       auth4_context->generate_session_info = auth3_generate_session_info;
+       auth4_context->get_ntlm_challenge = auth3_get_challenge;
+       auth4_context->set_ntlm_challenge = auth3_set_challenge;
+       auth4_context->challenge_may_be_modified = auth3_may_set_challenge;
+       auth4_context->check_ntlm_password = auth3_check_password;
+       auth4_context->private_data = talloc_steal(auth4_context, auth_context);
+       return auth4_context;
+}
+
+NTSTATUS make_auth4_context(TALLOC_CTX *mem_ctx, struct auth4_context **auth4_context_out)
+{
+       struct auth_context *auth_context;
+       NTSTATUS nt_status;
+
+       TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
+       NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
+
+       nt_status = make_auth_context_subsystem(tmp_ctx, &auth_context);
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               TALLOC_FREE(tmp_ctx);
+               return nt_status;
+       }
+
+       if (auth_context->make_auth4_context) {
+               nt_status = auth_context->make_auth4_context(mem_ctx, auth4_context_out);
+               TALLOC_FREE(tmp_ctx);
+               return nt_status;
+
+       } else {
+               struct auth4_context *auth4_context = make_auth4_context_s3(tmp_ctx, auth_context);
+               if (auth4_context == NULL) {
+                       TALLOC_FREE(tmp_ctx);
+                       return NT_STATUS_NO_MEMORY;
+               }
+               *auth4_context_out = talloc_steal(mem_ctx, auth4_context);
+               TALLOC_FREE(tmp_ctx);
+               return NT_STATUS_OK;
+       }
+}
+
 NTSTATUS auth_generic_prepare(TALLOC_CTX *mem_ctx,
                              const struct tsocket_address *remote_address,
                              struct gensec_security **gensec_security_out)
@@ -173,14 +229,15 @@ NTSTATUS auth_generic_prepare(TALLOC_CTX *mem_ctx,
        } else {
                struct gensec_settings *gensec_settings;
                struct loadparm_context *lp_ctx;
-
-               struct auth4_context *auth4_context = talloc_zero(tmp_ctx, struct auth4_context);
+               size_t idx = 0;
+               struct cli_credentials *server_credentials;
+               const char *dns_name;
+               const char *dns_domain;
+               struct auth4_context *auth4_context = make_auth4_context_s3(tmp_ctx, auth_context);
                if (auth4_context == NULL) {
-                       DEBUG(10, ("failed to allocate auth4_context failed\n"));
                        TALLOC_FREE(tmp_ctx);
                        return NT_STATUS_NO_MEMORY;
                }
-               auth4_context->generate_session_info_pac = auth3_generate_session_info_pac;
 
                lp_ctx = loadparm_init_s3(tmp_ctx, loadparm_s3_context());
                if (lp_ctx == NULL) {
@@ -196,13 +253,71 @@ NTSTATUS auth_generic_prepare(TALLOC_CTX *mem_ctx,
                        return NT_STATUS_NO_MEMORY;
                }
 
-               gensec_settings->backends = talloc_zero_array(gensec_settings, struct gensec_security_ops *, 2);
+               /*
+                * This should be a 'netbios domain -> DNS domain'
+                * mapping, and can currently validly return NULL on
+                * poorly configured systems.
+                *
+                * This is used for the NTLMSSP server
+                *
+                */
+               dns_name = get_mydnsfullname();
+               if (dns_name == NULL) {
+                       dns_name = "";
+               }
+
+               dns_domain = get_mydnsdomname(tmp_ctx);
+               if (dns_domain == NULL) {
+                       dns_domain = "";
+               }
+
+               gensec_settings->server_dns_name = strlower_talloc(gensec_settings, dns_name);
+               if (gensec_settings->server_dns_name == NULL) {
+                       TALLOC_FREE(tmp_ctx);
+                       return NT_STATUS_NO_MEMORY;
+               }
+
+               gensec_settings->server_dns_domain = strlower_talloc(gensec_settings, dns_domain);
+               if (gensec_settings->server_dns_domain == NULL) {
+                       TALLOC_FREE(tmp_ctx);
+                       return NT_STATUS_NO_MEMORY;
+               }
+
+               gensec_settings->backends = talloc_zero_array(gensec_settings,
+                                               struct gensec_security_ops *, 4);
                if (gensec_settings->backends == NULL) {
                        TALLOC_FREE(tmp_ctx);
                        return NT_STATUS_NO_MEMORY;
                }
 
-               gensec_settings->backends[0] = &gensec_ntlmssp3_server_ops;
+               gensec_init();
+
+               gensec_settings->backends[idx++] = gensec_security_by_oid(NULL, GENSEC_OID_NTLMSSP);
+
+#if defined(HAVE_KRB5)
+               gensec_settings->backends[idx++] = &gensec_gse_krb5_security_ops;
+#endif
+
+               gensec_settings->backends[idx++] = gensec_security_by_oid(NULL,
+                                                       GENSEC_OID_SPNEGO);
+
+               /*
+                * This is anonymous for now, because we just use it
+                * to set the kerberos state at the moment
+                */
+               server_credentials = cli_credentials_init_anon(tmp_ctx);
+               if (!server_credentials) {
+                       DEBUG(0, ("auth_generic_prepare: Failed to init server credentials\n"));
+                       return NT_STATUS_NO_MEMORY;
+               }
+
+               cli_credentials_set_conf(server_credentials, lp_ctx);
+
+               if (lp_security() == SEC_ADS || USE_KERBEROS_KEYTAB) {
+                       cli_credentials_set_kerberos_state(server_credentials, CRED_AUTO_USE_KERBEROS);
+               } else {
+                       cli_credentials_set_kerberos_state(server_credentials, CRED_DONT_USE_KERBEROS);
+               }
 
                nt_status = gensec_server_start(tmp_ctx, gensec_settings,
                                                auth4_context, &gensec_security);
@@ -211,7 +326,11 @@ NTSTATUS auth_generic_prepare(TALLOC_CTX *mem_ctx,
                        TALLOC_FREE(tmp_ctx);
                        return nt_status;
                }
+
+               gensec_set_credentials(gensec_security, server_credentials);
+
                talloc_unlink(tmp_ctx, lp_ctx);
+               talloc_unlink(tmp_ctx, server_credentials);
                talloc_unlink(tmp_ctx, gensec_settings);
                talloc_unlink(tmp_ctx, auth4_context);
        }
@@ -227,3 +346,29 @@ NTSTATUS auth_generic_prepare(TALLOC_CTX *mem_ctx,
        TALLOC_FREE(tmp_ctx);
        return NT_STATUS_OK;
 }
+
+NTSTATUS auth_check_password_session_info(struct auth4_context *auth_context,
+                                         TALLOC_CTX *mem_ctx,
+                                         struct auth_usersupplied_info *user_info,
+                                         struct auth_session_info **session_info)
+{
+       NTSTATUS nt_status;
+       void *server_info;
+
+       nt_status = auth_context->check_ntlm_password(auth_context,
+                                                     talloc_tos(),
+                                                     user_info,
+                                                     &server_info, NULL, NULL);
+
+       if (NT_STATUS_IS_OK(nt_status)) {
+               nt_status = auth_context->generate_session_info(auth_context,
+                                                               mem_ctx,
+                                                               server_info,
+                                                               user_info->client.account_name,
+                                                               AUTH_SESSION_INFO_UNIX_TOKEN |
+                                                               AUTH_SESSION_INFO_DEFAULT_GROUPS,
+                                                               session_info);
+               TALLOC_FREE(server_info);
+       }
+       return nt_status;
+}