s3-auth: Fix a possible null pointer dereference
[kai/samba.git] / source3 / auth / auth_ntlmssp.c
index 027666fb0a368a9414af9d63cd6aff56d6a3858d..a0e49027af999f92dac1fcd68fc27c42ee754871 100644 (file)
 
 #include "includes.h"
 #include "auth.h"
-#include "../auth/ntlmssp/ntlmssp.h"
-#include "../auth/ntlmssp/ntlmssp_private.h"
-#include "../librpc/gen_ndr/netlogon.h"
-#include "../librpc/gen_ndr/dcerpc.h"
-#include "../lib/tsocket/tsocket.h"
-#include "auth/gensec/gensec.h"
-#include "librpc/rpc/dcerpc.h"
-#include "lib/param/param.h"
-
-NTSTATUS auth3_generate_session_info(TALLOC_CTX *mem_ctx,
-                                    struct auth4_context *auth_context,
+#include "libcli/security/security.h"
+
+NTSTATUS auth3_generate_session_info(struct auth4_context *auth_context,
+                                    TALLOC_CTX *mem_ctx,
                                     void *server_returned_info,
                                     const char *original_user_name,
                                     uint32_t session_info_flags,
                                     struct auth_session_info **session_info)
 {
-       struct auth_serversupplied_info *server_info = talloc_get_type_abort(server_returned_info,
-                                                                            struct auth_serversupplied_info);
+       struct auth_user_info_dc *user_info = NULL;
+       struct auth_serversupplied_info *server_info = NULL;
        NTSTATUS nt_status;
 
+       /*
+        * This is a hack, some callers...
+        *
+        * Some callers pass auth_user_info_dc, the SCHANNEL and
+        * NCALRPC_AS_SYSTEM gensec modules.
+        *
+        * While the reset passes auth3_check_password() returned.
+        */
+       user_info = talloc_get_type(server_returned_info,
+                                   struct auth_user_info_dc);
+       if (user_info != NULL) {
+               const struct dom_sid *sid;
+               int cmp;
+
+               /*
+                * This should only be called from SCHANNEL or NCALRPC_AS_SYSTEM
+                */
+               if (user_info->num_sids != 1) {
+                       return NT_STATUS_INTERNAL_ERROR;
+               }
+               sid = &user_info->sids[PRIMARY_USER_SID_INDEX];
+
+               cmp = dom_sid_compare(sid, &global_sid_System);
+               if (cmp == 0) {
+                       return make_session_info_system(mem_ctx, session_info);
+               }
+
+               cmp = dom_sid_compare(sid, &global_sid_Anonymous);
+               if (cmp == 0) {
+                       /*
+                        * TODO: use auth_anonymous_session_info() here?
+                        */
+                       return make_session_info_guest(mem_ctx, session_info);
+               }
+
+               return NT_STATUS_INTERNAL_ERROR;
+       }
+
+       server_info = talloc_get_type_abort(server_returned_info,
+                                           struct auth_serversupplied_info);
        nt_status = create_local_token(mem_ctx,
                                       server_info,
                                       NULL,
@@ -67,22 +100,10 @@ NTSTATUS auth3_get_challenge(struct auth4_context *auth4_context,
 {
        struct auth_context *auth_context = talloc_get_type_abort(auth4_context->private_data,
                                                                  struct auth_context);
-       auth_context->get_ntlm_challenge(auth_context, chal);
+       auth_get_ntlm_challenge(auth_context, chal);
        return NT_STATUS_OK;
 }
 
-/**
- * Some authentication methods 'fix' the challenge, so we may not be able to set it
- *
- * @return If the effective challenge used by the auth subsystem may be modified
- */
-bool auth3_may_set_challenge(struct auth4_context *auth4_context)
-{
-       struct auth_context *auth_context = talloc_get_type_abort(auth4_context->private_data,
-                                                                 struct auth_context);
-       return auth_context->challenge_may_be_modified;
-}
-
 /**
  * NTLM2 authentication modifies the effective challenge, 
  * @param challenge The new challenge value
@@ -134,9 +155,10 @@ NTSTATUS auth3_check_password(struct auth4_context *auth4_context,
        /* sub_set_smb_name checks for weird internally */
        sub_set_smb_name(user_info->client.account_name);
 
-       lp_load(get_dyn_CONFIGFILE(), false, false, true, true);
+       lp_load_with_shares(get_dyn_CONFIGFILE());
 
-       nt_status = make_user_info_map(&mapped_user_info,
+       nt_status = make_user_info_map(talloc_tos(),
+                                       &mapped_user_info,
                                       user_info->client.account_name,
                                       user_info->client.domain_name,
                                       user_info->workstation_name,
@@ -154,8 +176,10 @@ NTSTATUS auth3_check_password(struct auth4_context *auth4_context,
 
        mapped_user_info->flags = user_info->flags;
 
-       nt_status = auth_context->check_ntlm_password(auth_context,
-                                                     mapped_user_info, &server_info);
+       nt_status = auth_check_ntlm_password(mem_ctx,
+                                            auth_context,
+                                            mapped_user_info,
+                                            &server_info);
 
        if (!NT_STATUS_IS_OK(nt_status)) {
                DEBUG(5,("Checking NTLMSSP password for %s\\%s failed: %s\n",
@@ -166,14 +190,17 @@ NTSTATUS auth3_check_password(struct auth4_context *auth4_context,
 
        username_was_mapped = mapped_user_info->was_mapped;
 
-       free_user_info(&mapped_user_info);
+       TALLOC_FREE(mapped_user_info);
 
        if (!NT_STATUS_IS_OK(nt_status)) {
-               nt_status = do_map_to_guest_server_info(nt_status,
-                                                       &server_info,
+               nt_status = do_map_to_guest_server_info(mem_ctx,
+                                                       nt_status,
                                                        user_info->client.account_name,
-                                                       user_info->client.domain_name);
-               *server_returned_info = talloc_steal(mem_ctx, server_info);
+                                                       user_info->client.domain_name,
+                                                       &server_info);
+               if (NT_STATUS_IS_OK(nt_status)) {
+                       *server_returned_info = talloc_steal(mem_ctx, server_info);
+               }
                return nt_status;
        }
 
@@ -201,95 +228,3 @@ NTSTATUS auth3_check_password(struct auth4_context *auth4_context,
        *server_returned_info = talloc_steal(mem_ctx, server_info);
        return nt_status;
 }
-
-static NTSTATUS gensec_ntlmssp3_server_start(struct gensec_security *gensec_security)
-{
-       NTSTATUS nt_status;
-       bool is_standalone;
-       const char *netbios_name;
-       const char *netbios_domain;
-       const char *dns_name;
-       char *dns_domain;
-       struct gensec_ntlmssp_context *gensec_ntlmssp;
-
-       if ((enum server_role)lp_server_role() == ROLE_STANDALONE) {
-               is_standalone = true;
-       } else {
-               is_standalone = false;
-       }
-
-       netbios_name = lp_netbios_name();
-       netbios_domain = lp_workgroup();
-       /* This should be a 'netbios domain -> DNS domain' mapping */
-       dns_domain = get_mydnsdomname(talloc_tos());
-       if (dns_domain) {
-               strlower_m(dns_domain);
-       }
-       dns_name = get_mydnsfullname();
-
-       nt_status = gensec_ntlmssp_start(gensec_security);
-       NT_STATUS_NOT_OK_RETURN(nt_status);
-
-       gensec_ntlmssp =
-               talloc_get_type_abort(gensec_security->private_data,
-                                     struct gensec_ntlmssp_context);
-
-       nt_status = ntlmssp_server_start(gensec_ntlmssp,
-                                        is_standalone,
-                                        netbios_name,
-                                        netbios_domain,
-                                        dns_name,
-                                        dns_domain,
-                                        &gensec_ntlmssp->ntlmssp_state);
-       if (!NT_STATUS_IS_OK(nt_status)) {
-               return nt_status;
-       }
-
-       gensec_ntlmssp->ntlmssp_state->callback_private = gensec_ntlmssp;
-
-       gensec_ntlmssp->ntlmssp_state->get_challenge = auth_ntlmssp_get_challenge;
-       gensec_ntlmssp->ntlmssp_state->may_set_challenge = auth_ntlmssp_may_set_challenge;
-       gensec_ntlmssp->ntlmssp_state->set_challenge = auth_ntlmssp_set_challenge;
-       gensec_ntlmssp->ntlmssp_state->check_password = auth_ntlmssp_check_password;
-
-       if (gensec_ntlmssp->gensec_security->want_features & GENSEC_FEATURE_SESSION_KEY) {
-               gensec_ntlmssp->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
-       }
-       if (gensec_ntlmssp->gensec_security->want_features & GENSEC_FEATURE_SIGN) {
-               gensec_ntlmssp->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
-       }
-       if (gensec_ntlmssp->gensec_security->want_features & GENSEC_FEATURE_SEAL) {
-               gensec_ntlmssp->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
-               gensec_ntlmssp->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
-       }
-
-       return NT_STATUS_OK;
-}
-
-static const char *gensec_ntlmssp3_server_oids[] = {
-       GENSEC_OID_NTLMSSP,
-       NULL
-};
-
-const struct gensec_security_ops gensec_ntlmssp3_server_ops = {
-       .name           = "ntlmssp3_server",
-       .sasl_name      = GENSEC_SASL_NAME_NTLMSSP, /* "NTLM" */
-       .auth_type      = DCERPC_AUTH_TYPE_NTLMSSP,
-       .oid            = gensec_ntlmssp3_server_oids,
-       .server_start   = gensec_ntlmssp3_server_start,
-       .magic          = gensec_ntlmssp_magic,
-       .update         = gensec_ntlmssp_update,
-       .sig_size       = gensec_ntlmssp_sig_size,
-       .sign_packet    = gensec_ntlmssp_sign_packet,
-       .check_packet   = gensec_ntlmssp_check_packet,
-       .seal_packet    = gensec_ntlmssp_seal_packet,
-       .unseal_packet  = gensec_ntlmssp_unseal_packet,
-       .wrap           = gensec_ntlmssp_wrap,
-       .unwrap         = gensec_ntlmssp_unwrap,
-       .session_key    = gensec_ntlmssp_session_key,
-       .session_info   = gensec_ntlmssp_session_info,
-       .have_feature   = gensec_ntlmssp_have_feature,
-       .enabled        = true,
-       .priority       = GENSEC_NTLMSSP
-};
-