auth: Always supply both the remote and local address to the auth subsystem
authorAndrew Bartlett <abartlet@samba.org>
Thu, 23 Feb 2017 01:31:52 +0000 (14:31 +1300)
committerAndrew Bartlett <abartlet@samba.org>
Wed, 29 Mar 2017 00:37:26 +0000 (02:37 +0200)
This ensures that gensec, and then the NTLM auth subsystem under it, always gets the
remote and local address pointers for potential logging.

The local address allows us to know which interface an authentication is on

Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Pair-Programmed-by: Gary Lockyer <gary@catalyst.net.nz>
Signed-off-by: Gary Lockyer <gary@catalyst.net.nz>
12 files changed:
auth/ntlmssp/ntlmssp_server.c
source3/auth/auth_generic.c
source3/auth/proto.h
source3/rpc_server/dcesrv_auth_generic.c
source3/rpc_server/dcesrv_auth_generic.h
source3/rpc_server/srv_pipe.c
source3/smbd/negprot.c
source3/smbd/seal.c
source3/smbd/sesssetup.c
source3/smbd/smb2_sesssetup.c
source4/smb_server/smb/sesssetup.c
source4/smb_server/smb2/sesssetup.c

index c17e173b0737af0c9405e95c37be24eab752cd9b..1bfd4ccdc242dc19370b170211bec24e0783a183 100644 (file)
@@ -718,6 +718,7 @@ static NTSTATUS ntlmssp_server_check_password(struct gensec_security *gensec_sec
        user_info->client.domain_name = ntlmssp_state->domain;
        user_info->workstation_name = ntlmssp_state->client.netbios_name;
        user_info->remote_host = gensec_get_remote_address(gensec_security);
+       user_info->local_host = gensec_get_local_address(gensec_security);
        user_info->service_description
                = gensec_get_target_service_description(gensec_security);
        user_info->auth_description = "NTLMSSP";
index 70eb5145932633c540db26fe9b39bba2ce331b28..7c57e18e1aafe8185e8c5078f398c7499c3454b8 100644 (file)
@@ -233,6 +233,7 @@ NTSTATUS make_auth4_context(TALLOC_CTX *mem_ctx, struct auth4_context **auth4_co
 
 NTSTATUS auth_generic_prepare(TALLOC_CTX *mem_ctx,
                              const struct tsocket_address *remote_address,
+                             const struct tsocket_address *local_address,
                              const char *service_description,
                              struct gensec_security **gensec_security_out)
 {
@@ -378,6 +379,13 @@ NTSTATUS auth_generic_prepare(TALLOC_CTX *mem_ctx,
                return nt_status;
        }
 
+       nt_status = gensec_set_local_address(gensec_security,
+                                            local_address);
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               TALLOC_FREE(tmp_ctx);
+               return nt_status;
+       }
+
        nt_status = gensec_set_target_service_description(gensec_security,
                                                          service_description);
 
index b64ebed4e07ee9307e290ff782d3fe58d27f0124..400875f05914563553118b63901fa211c4a7770e 100644 (file)
@@ -105,7 +105,9 @@ NTSTATUS auth_domain_init(void);
 /* The following definitions come from auth/auth_generic.c  */
 
 NTSTATUS make_auth4_context(TALLOC_CTX *mem_ctx, struct auth4_context **auth4_context_out);
-NTSTATUS auth_generic_prepare(TALLOC_CTX *mem_ctx, const struct tsocket_address *remote_address,
+NTSTATUS auth_generic_prepare(TALLOC_CTX *mem_ctx,
+                             const struct tsocket_address *remote_address,
+                             const struct tsocket_address *local_address,
                              const char *service_description,
                              struct gensec_security **gensec_security_out);
 
index 7bdfdeeed94023474f184763472c818c4171bac4..1092cd3317f2b680c020ab8d07e27869bd6cb668 100644 (file)
@@ -29,13 +29,16 @@ static NTSTATUS auth_generic_server_authtype_start_as_root(TALLOC_CTX *mem_ctx,
                                                           DATA_BLOB *token_in,
                                                           DATA_BLOB *token_out,
                                                           const struct tsocket_address *remote_address,
+                                                          const struct tsocket_address *local_address,
                                                           const char *service_description,
                                                           struct gensec_security **ctx)
 {
        struct gensec_security *gensec_security = NULL;
        NTSTATUS status;
 
-       status = auth_generic_prepare(talloc_tos(), remote_address,
+       status = auth_generic_prepare(talloc_tos(),
+                                     remote_address,
+                                     local_address,
                                      service_description,
                                      &gensec_security);
        if (!NT_STATUS_IS_OK(status)) {
@@ -70,6 +73,7 @@ NTSTATUS auth_generic_server_authtype_start(TALLOC_CTX *mem_ctx,
                                            DATA_BLOB *token_in,
                                            DATA_BLOB *token_out,
                                            const struct tsocket_address *remote_address,
+                                           const struct tsocket_address *local_address,
                                            const char *service_description,
                                            struct gensec_security **ctx)
 {
@@ -82,6 +86,7 @@ NTSTATUS auth_generic_server_authtype_start(TALLOC_CTX *mem_ctx,
                                                            token_in,
                                                            token_out,
                                                            remote_address,
+                                                           local_address,
                                                            service_description,
                                                            ctx);
        unbecome_root();
index 36e1a83e07729fc91b533ab43737badc4ca543dc..4e86eabc95324ebadbcb5ee0dc638893ba7664ec 100644 (file)
@@ -27,6 +27,7 @@ NTSTATUS auth_generic_server_authtype_start(TALLOC_CTX *mem_ctx,
                                            DATA_BLOB *token_in,
                                            DATA_BLOB *token_out,
                                            const struct tsocket_address *remote_address,
+                                           const struct tsocket_address *local_address,
                                            const char *service_description,
                                            struct gensec_security **ctx);
 
index 4a63dd734aaf733500db806c31d5f229e85620e4..446679f39d4945c10058077d4f3fc2fdeed7327e 100644 (file)
@@ -530,6 +530,7 @@ static bool pipe_auth_generic_bind(struct pipes_struct *p,
                                                    &auth_info->credentials,
                                                    response,
                                                    p->remote_address,
+                                                   p->local_address,
                                                    service_description,
                                                    &gensec_security);
        if (!NT_STATUS_IS_OK(status) &&
index b53210112017006b5fa95cfdf820e23ba0632c90..d3f4776076fd43308fc79ca9d1e1283757d36850 100644 (file)
@@ -171,13 +171,14 @@ DATA_BLOB negprot_spnego(TALLOC_CTX *ctx, struct smbXsrv_connection *xconn)
        /* See if we can get an SPNEGO blob */
        status = auth_generic_prepare(talloc_tos(),
                                      xconn->remote_address,
+                                     xconn->local_address,
                                      "SMB",
                                      &gensec_security);
 
        /*
-        * There is no need to set a remote address or similar as we
-        * are just interested in the SPNEGO blob, we never keep this
-        * context.
+        * Despite including it above, there is no need to set a
+        * remote address or similar as we are just interested in the
+        * SPNEGO blob, we never keep this context.
         */
 
        if (NT_STATUS_IS_OK(status)) {
index f406c43b0af340c5ed2dc42df1a62a56ecf5eeb6..8a0dbeb2bf4468ce03c6d731f810d0ff729c9f56 100644 (file)
@@ -72,11 +72,13 @@ bool is_encrypted_packet(const uint8_t *inbuf)
 ******************************************************************************/
 
 static NTSTATUS make_auth_gensec(const struct tsocket_address *remote_address,
+                                const struct tsocket_address *local_address,
                                 struct smb_trans_enc_state *es)
 {
        NTSTATUS status;
 
        status = auth_generic_prepare(es, remote_address,
+                                     local_address,
                                      "SMB encryption",
                                      &es->gensec_security);
        if (!NT_STATUS_IS_OK(status)) {
@@ -107,6 +109,7 @@ static NTSTATUS make_auth_gensec(const struct tsocket_address *remote_address,
 ******************************************************************************/
 
 static NTSTATUS make_srv_encryption_context(const struct tsocket_address *remote_address,
+                                           const struct tsocket_address *local_address,
                                            struct smb_trans_enc_state **pp_es)
 {
        NTSTATUS status;
@@ -120,6 +123,7 @@ static NTSTATUS make_srv_encryption_context(const struct tsocket_address *remote
                return NT_STATUS_NO_MEMORY;
        }
        status = make_auth_gensec(remote_address,
+                                 local_address,
                                  es);
        if (!NT_STATUS_IS_OK(status)) {
                TALLOC_FREE(es);
@@ -208,6 +212,7 @@ NTSTATUS srv_request_encryption_setup(connection_struct *conn,
        if (!partial_srv_trans_enc_ctx) {
                /* This is the initial step. */
                status = make_srv_encryption_context(conn->sconn->remote_address,
+                                                    conn->sconn->local_address,
                                        &partial_srv_trans_enc_ctx);
                if (!NT_STATUS_IS_OK(status)) {
                        return status;
index 68c0efd5082fe3ed61e44573d39cc0e670e89215..3a283b9d575ad9360c429b2baa023156bec4a39c 100644 (file)
@@ -249,7 +249,9 @@ static void reply_sesssetup_and_X_spnego(struct smb_request *req)
        }
 
        if (auth->gensec == NULL) {
-               status = auth_generic_prepare(session, xconn->remote_address,
+               status = auth_generic_prepare(session,
+                                             xconn->remote_address,
+                                             xconn->local_address,
                                              "SMB",
                                              &auth->gensec);
                if (!NT_STATUS_IS_OK(status)) {
index 7e3102b0c2bc6b8ab7ab5ed78c9225b1593fe425..52462882771df7135498ff2f86388641a1a3b900 100644 (file)
@@ -855,6 +855,7 @@ auth:
        if (state->auth->gensec == NULL) {
                status = auth_generic_prepare(state->auth,
                                              state->smb2req->xconn->remote_address,
+                                             state->smb2req->xconn->local_address,
                                              "SMB2",
                                              &state->auth->gensec);
                if (tevent_req_nterror(req, status)) {
index 054400e900bf33d5a5c95d4b0c10532101f83ddb..4dee6d0c026fdb2684a8e20b700410481e6576e3 100644 (file)
@@ -119,7 +119,7 @@ failed:
 static void sesssetup_old(struct smbsrv_request *req, union smb_sesssetup *sess)
 {
        struct auth_usersupplied_info *user_info = NULL;
-       struct tsocket_address *remote_address;
+       struct tsocket_address *remote_address, *local_address;
        const char *remote_machine = NULL;
        struct tevent_req *subreq;
        struct sesssetup_context *state;
@@ -148,6 +148,9 @@ static void sesssetup_old(struct smbsrv_request *req, union smb_sesssetup *sess)
                if (!remote_machine) goto nomem;
        }
 
+       local_address = socket_get_local_addr(req->smb_conn->connection->socket, req);
+       if (!local_address) goto nomem;
+
        user_info = talloc_zero(req, struct auth_usersupplied_info);
        if (!user_info) goto nomem;
 
@@ -159,7 +162,9 @@ static void sesssetup_old(struct smbsrv_request *req, union smb_sesssetup *sess)
        user_info->client.account_name = sess->old.in.user;
        user_info->client.domain_name = sess->old.in.domain;
        user_info->workstation_name = remote_machine;
+
        user_info->remote_host = talloc_steal(user_info, remote_address);
+       user_info->local_host = talloc_steal(user_info, local_address);
        
        user_info->password_state = AUTH_PASSWORD_RESPONSE;
        user_info->password.response.lanman = sess->old.in.password;
@@ -264,7 +269,7 @@ static void sesssetup_nt1(struct smbsrv_request *req, union smb_sesssetup *sess)
 {
        NTSTATUS status;
        struct auth_usersupplied_info *user_info = NULL;
-       struct tsocket_address *remote_address;
+       struct tsocket_address *remote_address, *local_address;
        const char *remote_machine = NULL;
        struct tevent_req *subreq;
        struct sesssetup_context *state;
@@ -327,6 +332,9 @@ static void sesssetup_nt1(struct smbsrv_request *req, union smb_sesssetup *sess)
                if (!remote_machine) goto nomem;
        }
 
+       local_address = socket_get_local_addr(req->smb_conn->connection->socket, req);
+       if (!local_address) goto nomem;
+
        user_info = talloc_zero(req, struct auth_usersupplied_info);
        if (!user_info) goto nomem;
 
@@ -339,6 +347,7 @@ static void sesssetup_nt1(struct smbsrv_request *req, union smb_sesssetup *sess)
        user_info->client.domain_name = sess->nt1.in.domain;
        user_info->workstation_name = remote_machine;
        user_info->remote_host = talloc_steal(user_info, remote_address);
+       user_info->local_host = talloc_steal(user_info, local_address);
        
        user_info->password_state = AUTH_PASSWORD_RESPONSE;
        user_info->password.response.lanman = sess->nt1.in.password1;
@@ -455,7 +464,7 @@ static void sesssetup_spnego(struct smbsrv_request *req, union smb_sesssetup *se
        /* lookup an existing session */
        if (vuid == 0) {
                struct gensec_security *gensec_ctx;
-
+               struct tsocket_address *remote_address, *local_address;
                status = samba_server_gensec_start(req,
                                                   req->smb_conn->connection->event.ctx,
                                                   req->smb_conn->connection->msg_ctx,
@@ -470,6 +479,44 @@ static void sesssetup_spnego(struct smbsrv_request *req, union smb_sesssetup *se
 
                gensec_want_feature(gensec_ctx, GENSEC_FEATURE_SESSION_KEY);
 
+               remote_address = socket_get_remote_addr(req->smb_conn->connection->socket,
+                                                       req);
+               if (!remote_address) {
+                       status = NT_STATUS_INTERNAL_ERROR;
+                       DBG_ERR("Failed to obtain remote address");
+                       goto failed;
+               }
+
+               status = gensec_set_remote_address(gensec_ctx,
+                                                  remote_address);
+               if (!NT_STATUS_IS_OK(status)) {
+                       DBG_ERR("Failed to set remote address");
+                       goto failed;
+               }
+
+               local_address = socket_get_local_addr(req->smb_conn->connection->socket,
+                                                       req);
+               if (!local_address) {
+                       status = NT_STATUS_INTERNAL_ERROR;
+                       DBG_ERR("Failed to obtain local address");
+                       goto failed;
+               }
+
+               status = gensec_set_local_address(gensec_ctx,
+                                                  local_address);
+               if (!NT_STATUS_IS_OK(status)) {
+                       DBG_ERR("Failed to set local address");
+                       goto failed;
+               }
+
+               status = gensec_set_target_service_description(gensec_ctx,
+                                                              "SMB");
+
+               if (!NT_STATUS_IS_OK(status)) {
+                       DBG_ERR("Failed to set service description");
+                       goto failed;
+               }
+
                status = gensec_start_mech_by_oid(gensec_ctx, req->smb_conn->negotiate.oid);
                if (!NT_STATUS_IS_OK(status)) {
                        DEBUG(1, ("Failed to start GENSEC %s server code: %s\n", 
index 5e261a20e40ca3c5f9b5c4f7f5244bb3703d2603..0a66f46856dff497f1f34a5632cd4ec4ded10d9a 100644 (file)
@@ -130,6 +130,7 @@ static void smb2srv_sesssetup_backend(struct smb2srv_request *req, union smb_ses
         */
        if (vuid == 0) {
                struct gensec_security *gensec_ctx;
+               struct tsocket_address *remote_address, *local_address;
 
                status = samba_server_gensec_start(req,
                                                   req->smb_conn->connection->event.ctx,
@@ -145,6 +146,44 @@ static void smb2srv_sesssetup_backend(struct smb2srv_request *req, union smb_ses
 
                gensec_want_feature(gensec_ctx, GENSEC_FEATURE_SESSION_KEY);
 
+               remote_address = socket_get_remote_addr(req->smb_conn->connection->socket,
+                                                       req);
+               if (!remote_address) {
+                       status = NT_STATUS_INTERNAL_ERROR;
+                       DBG_ERR("Failed to obtain remote address");
+                       goto failed;
+               }
+
+               status = gensec_set_remote_address(gensec_ctx,
+                                                  remote_address);
+               if (!NT_STATUS_IS_OK(status)) {
+                       DBG_ERR("Failed to set remote address");
+                       goto failed;
+               }
+
+               local_address = socket_get_local_addr(req->smb_conn->connection->socket,
+                                                     req);
+               if (!local_address) {
+                       status = NT_STATUS_INTERNAL_ERROR;
+                       DBG_ERR("Failed to obtain local address");
+                       goto failed;
+               }
+
+               status = gensec_set_local_address(gensec_ctx,
+                                                 local_address);
+               if (!NT_STATUS_IS_OK(status)) {
+                       DBG_ERR("Failed to set local address");
+                       goto failed;
+               }
+
+               status = gensec_set_target_service_description(gensec_ctx,
+                                                              "SMB2");
+
+               if (!NT_STATUS_IS_OK(status)) {
+                       DBG_ERR("Failed to set service description");
+                       goto failed;
+               }
+
                status = gensec_start_mech_by_oid(gensec_ctx, GENSEC_OID_SPNEGO);
                if (!NT_STATUS_IS_OK(status)) {
                        DEBUG(1, ("Failed to start GENSEC SPNEGO server code: %s\n", nt_errstr(status)));