s3-rpc_server read and write the unix_token and unix_info across named_pipe_auth
authorAndrew Bartlett <abartlet@samba.org>
Mon, 18 Jul 2011 02:23:04 +0000 (12:23 +1000)
committerAndrew Bartlett <abartlet@samba.org>
Tue, 19 Jul 2011 23:17:13 +0000 (09:17 +1000)
This ensures that the exact same token is used on both sides of the
pipe, when a full token is passed (ie, source3 to source3, but not yet
source4 to to source3 as the unix info isn't calculated there yet).

If we do not have unix_token, we fall back to the old behaviour and go
via create_local_token().  (However, in this case the security_token
is now overwritten, as it is better to have it match the rest of the
session_info create_local_token() builds).

Andrew Bartlett

Signed-off-by: Andrew Tridgell <tridge@samba.org>
source3/rpc_server/rpc_ncacn_np.c
source3/rpc_server/rpc_server.c

index 0fa8e83329500d82fe39767ed760ac7b7158d0c1..f43d0b81bc4e433571f55e152c0e778f0f867ec8 100644 (file)
@@ -682,6 +682,8 @@ struct np_proxy_state *make_external_rpc_pipe_p(TALLOC_CTX *mem_ctx,
        /* Send the named_pipe_auth server the user's full token */
        session_info_npa->security_token = session_info->security_token;
        session_info_npa->session_key = session_info->session_key;
+       session_info_npa->unix_token = session_info->unix_token;
+       session_info_npa->unix_info = session_info->unix_info;
 
        val.sam3 = session_info->info3;
 
index 7733b3819fc7df534020dc2d4d96c3bf3ce0303e..7e383e84c191fc420175cbe600ec24c630ed0fb6 100644 (file)
@@ -91,7 +91,6 @@ static int make_server_pipes_struct(TALLOC_CTX *mem_ctx,
        struct netr_SamInfo3 *info3;
        struct auth_user_info_dc *auth_user_info_dc;
        struct pipes_struct *p;
-       struct auth_serversupplied_info *server_info;
        NTSTATUS status;
 
        p = talloc_zero(mem_ctx, struct pipes_struct);
@@ -139,34 +138,48 @@ static int make_server_pipes_struct(TALLOC_CTX *mem_ctx,
                return -1;
        }
 
-       status = make_server_info_info3(p,
-                                       info3->base.account_name.string,
-                                       info3->base.domain.string,
-                                       &server_info, info3);
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(1, ("Failed to init server info\n"));
-               TALLOC_FREE(p);
-               *perrno = EINVAL;
-               return -1;
-       }
+       if (session_info->unix_token && session_info->unix_info && session_info->security_token) {
+               /* Don't call create_local_token(), we already have the full details here */
+               p->session_info = talloc_zero(p, struct auth3_session_info);
+               if (p->session_info == NULL) {
+                       TALLOC_FREE(p);
+                       *perrno = ENOMEM;
+                       return -1;
+               }
+               p->session_info->security_token = talloc_move(p->session_info, &session_info->security_token);
+               p->session_info->unix_token = talloc_move(p->session_info, &session_info->unix_token);
+               p->session_info->unix_info = talloc_move(p->session_info, &session_info->unix_info);
+               p->session_info->info3 = talloc_move(p->session_info, &info3);
+               p->session_info->session_key = session_info->session_key;
+               p->session_info->session_key.data = talloc_move(p->session_info, &session_info->session_key.data);
 
-       /*
-        * Some internal functions need a local token to determine access to
-        * resoutrces.
-        */
-       status = create_local_token(p, server_info, &session_info->session_key, &p->session_info);
-       talloc_free(server_info);
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(1, ("Failed to init local auth token\n"));
-               TALLOC_FREE(p);
-               *perrno = EINVAL;
-               return -1;
-       }
+       } else {
+               struct auth_serversupplied_info *server_info;
 
-       /* Now override the session_info->security_token with the exact
-        * security_token we were given from the other side,
-        * regardless of what we just calculated */
-       p->session_info->security_token = talloc_move(p->session_info, &session_info->security_token);
+               status = make_server_info_info3(p,
+                                               info3->base.account_name.string,
+                                               info3->base.domain.string,
+                                               &server_info, info3);
+               if (!NT_STATUS_IS_OK(status)) {
+                       DEBUG(1, ("Failed to init server info\n"));
+                       TALLOC_FREE(p);
+                       *perrno = EINVAL;
+                       return -1;
+               }
+
+               /*
+                * Some internal functions need a local token to determine access to
+                * resources.
+                */
+               status = create_local_token(p, server_info, &session_info->session_key, &p->session_info);
+               talloc_free(server_info);
+               if (!NT_STATUS_IS_OK(status)) {
+                       DEBUG(1, ("Failed to init local auth token\n"));
+                       TALLOC_FREE(p);
+                       *perrno = EINVAL;
+                       return -1;
+               }
+       }
 
        p->remote_address = tsocket_address_copy(remote_address, p);
        if (p->remote_address == NULL) {