libcli/named_pipe_auth Change from 'info3' to auth_session_info_transport
authorAndrew Bartlett <abartlet@samba.org>
Wed, 9 Feb 2011 03:22:16 +0000 (14:22 +1100)
committerAndrew Tridgell <tridge@samba.org>
Thu, 10 Feb 2011 05:51:06 +0000 (06:51 +0100)
This changes the structure being used to convey the current user state
from the netlogon-derived 'netr_SamInfo3' structure to a purpose-built
structure that matches the internals of the Samba auth subsystem and
contains the final group list, as well as the final privilege set and
session key.

These previously had to be re-created on the server side of the pipe
each time.

Andrew Bartlett

Signed-off-by: Andrew Tridgell <tridge@samba.org>
libcli/named_pipe_auth/npa_tstream.c
libcli/named_pipe_auth/npa_tstream.h
librpc/idl/named_pipe_auth.idl
librpc/wscript_build
source3/Makefile.in
source3/rpc_server/rpc_ncacn_np.c
source3/rpc_server/rpc_server.c
source4/auth/session.c
source4/auth/session.h
source4/ntvfs/ipc/vfs_ipc.c
source4/smbd/service_named_pipe.c

index ace90d666480b5bf49164e5a2bb6056fd5dc8e06..2aeea5b0d363b81997282af9996e0e94ab23a9a3 100644 (file)
@@ -59,16 +59,14 @@ struct tstream_npa_connect_state {
 static void tstream_npa_connect_unix_done(struct tevent_req *subreq);
 
 struct tevent_req *tstream_npa_connect_send(TALLOC_CTX *mem_ctx,
-                                       struct tevent_context *ev,
-                                       const char *directory,
-                                       const char *npipe,
-                                       const struct tsocket_address *client,
-                                       const char *client_name_in,
-                                       const struct tsocket_address *server,
-                                       const char *server_name,
-                                       const struct netr_SamInfo3 *sam_info3,
-                                       DATA_BLOB session_key,
-                                       DATA_BLOB delegated_creds)
+                                           struct tevent_context *ev,
+                                           const char *directory,
+                                           const char *npipe,
+                                           const struct tsocket_address *client,
+                                           const char *client_name_in,
+                                           const struct tsocket_address *server,
+                                           const char *server_name,
+                                           const struct auth_session_info_transport *session_info)
 {
        struct tevent_req *req;
        struct tstream_npa_connect_state *state;
@@ -76,7 +74,7 @@ struct tevent_req *tstream_npa_connect_send(TALLOC_CTX *mem_ctx,
        int ret;
        enum ndr_err_code ndr_err;
        char *lower_case_npipe;
-       struct named_pipe_auth_req_info3 *info3;
+       struct named_pipe_auth_req_info4 *info4;
 
        req = tevent_req_create(mem_ctx, &state,
                                struct tstream_npa_connect_state);
@@ -122,37 +120,33 @@ struct tevent_req *tstream_npa_connect_send(TALLOC_CTX *mem_ctx,
                goto post;
        }
 
-       state->auth_req.level = 3;
-       info3 = &state->auth_req.info.info3;
+       state->auth_req.level = 4;
+       info4 = &state->auth_req.info.info4;
 
-       info3->client_name = client_name_in;
-       info3->client_addr = tsocket_address_inet_addr_string(client, state);
-       if (!info3->client_addr) {
+       info4->client_name = client_name_in;
+       info4->client_addr = tsocket_address_inet_addr_string(client, state);
+       if (!info4->client_addr) {
                /* errno might be EINVAL */
                tevent_req_error(req, errno);
                goto post;
        }
-       info3->client_port = tsocket_address_inet_port(client);
-       if (!info3->client_name) {
-               info3->client_name = info3->client_addr;
+       info4->client_port = tsocket_address_inet_port(client);
+       if (!info4->client_name) {
+               info4->client_name = info4->client_addr;
        }
 
-       info3->server_addr = tsocket_address_inet_addr_string(server, state);
-       if (!info3->server_addr) {
+       info4->server_addr = tsocket_address_inet_addr_string(server, state);
+       if (!info4->server_addr) {
                /* errno might be EINVAL */
                tevent_req_error(req, errno);
                goto post;
        }
-       info3->server_port = tsocket_address_inet_port(server);
-       if (!info3->server_name) {
-               info3->server_name = info3->server_addr;
+       info4->server_port = tsocket_address_inet_port(server);
+       if (!info4->server_name) {
+               info4->server_name = info4->server_addr;
        }
 
-       info3->sam_info3 = discard_const_p(struct netr_SamInfo3, sam_info3);
-       info3->session_key_length = session_key.length;
-       info3->session_key = session_key.data;
-       info3->gssapi_delegated_creds_length = delegated_creds.length;
-       info3->gssapi_delegated_creds = delegated_creds.data;
+       info4->session_info = discard_const_p(struct auth_session_info_transport, session_info);
 
        if (DEBUGLVL(10)) {
                NDR_PRINT_DEBUG(named_pipe_auth_req, &state->auth_req);
@@ -422,10 +416,10 @@ int _tstream_npa_connect_recv(struct tevent_req *req,
 
        npas->unix_stream = talloc_move(stream, &state->unix_stream);
        switch (state->auth_rep.level) {
-       case 3:
-               npas->file_type = state->auth_rep.info.info3.file_type;
-               device_state = state->auth_rep.info.info3.device_state;
-               allocation_size = state->auth_rep.info.info3.allocation_size;
+       case 4:
+               npas->file_type = state->auth_rep.info.info4.file_type;
+               device_state = state->auth_rep.info.info4.device_state;
+               allocation_size = state->auth_rep.info.info4.allocation_size;
                break;
        }
 
@@ -1086,9 +1080,7 @@ struct tstream_npa_accept_state {
        char *client_name;
        struct tsocket_address *server;
        char *server_name;
-       struct netr_SamInfo3 *info3;
-       DATA_BLOB session_key;
-       DATA_BLOB delegated_creds;
+       struct auth_session_info_transport *session_info;
 };
 
 static int tstream_npa_accept_next_vector(struct tstream_context *unix_stream,
@@ -1238,7 +1230,7 @@ static void tstream_npa_accept_existing_reply(struct tevent_req *subreq)
                        tevent_req_data(req, struct tstream_npa_accept_state);
        struct named_pipe_auth_req *pipe_request;
        struct named_pipe_auth_rep pipe_reply;
-       struct named_pipe_auth_req_info3 i3;
+       struct named_pipe_auth_req_info4 i4;
        enum ndr_err_code ndr_err;
        DATA_BLOB out;
        int sys_errno;
@@ -1283,70 +1275,62 @@ static void tstream_npa_accept_existing_reply(struct tevent_req *subreq)
                NDR_PRINT_DEBUG(named_pipe_auth_req, pipe_request);
        }
 
-       ZERO_STRUCT(i3);
+       ZERO_STRUCT(i4);
 
-       if (pipe_request->level != 3) {
+       if (pipe_request->level != 4) {
                DEBUG(0, ("Unknown level %u\n", pipe_request->level));
                pipe_reply.level = 0;
                pipe_reply.status = NT_STATUS_INVALID_LEVEL;
                goto reply;
        }
 
-       pipe_reply.level = 3;
+       pipe_reply.level = 4;
        pipe_reply.status = NT_STATUS_OK;
-       pipe_reply.info.info3.file_type = state->file_type;
-       pipe_reply.info.info3.device_state = state->device_state;
-       pipe_reply.info.info3.allocation_size = state->alloc_size;
+       pipe_reply.info.info4.file_type = state->file_type;
+       pipe_reply.info.info4.device_state = state->device_state;
+       pipe_reply.info.info4.allocation_size = state->alloc_size;
 
-       i3 = pipe_request->info.info3;
-       if (i3.server_addr == NULL) {
+       i4 = pipe_request->info.info4;
+       if (i4.server_addr == NULL) {
                pipe_reply.status = NT_STATUS_INVALID_ADDRESS;
                DEBUG(2, ("Missing server address\n"));
                goto reply;
        }
-       if (i3.client_addr == NULL) {
+       if (i4.client_addr == NULL) {
                pipe_reply.status = NT_STATUS_INVALID_ADDRESS;
                DEBUG(2, ("Missing client address\n"));
                goto reply;
        }
 
        state->server_name = discard_const_p(char,
-                                            talloc_move(state, &i3.server_name));
+                                            talloc_move(state, &i4.server_name));
        ret = tsocket_address_inet_from_strings(state, "ip",
-                                               i3.server_addr,
-                                               i3.server_port,
+                                               i4.server_addr,
+                                               i4.server_port,
                                                &state->server);
        if (ret != 0) {
                DEBUG(2, ("Invalid server address[%s:%u] - %s\n",
-                         i3.server_addr, i3.server_port,
+                         i4.server_addr, i4.server_port,
                          strerror(errno)));
                pipe_reply.status = NT_STATUS_INVALID_ADDRESS;
                goto reply;
        }
 
        state->client_name = discard_const_p(char,
-                                            talloc_move(state, &i3.client_name));
+                                            talloc_move(state, &i4.client_name));
        ret = tsocket_address_inet_from_strings(state, "ip",
-                                               i3.client_addr,
-                                               i3.client_port,
+                                               i4.client_addr,
+                                               i4.client_port,
                                                &state->client);
        if (ret != 0) {
                DEBUG(2, ("Invalid server address[%s:%u] - %s\n",
-                         i3.client_addr, i3.client_port,
+                         i4.client_addr, i4.client_port,
                          strerror(errno)));
                pipe_reply.status = NT_STATUS_INVALID_ADDRESS;
                goto reply;
        }
 
-       state->info3 = talloc_move(state, &i3.sam_info3);
-       state->session_key.data = talloc_move(state, &i3.session_key);
-       state->session_key.length = i3.session_key_length;
-
-       state->delegated_creds.data =
-               talloc_move(state, &i3.gssapi_delegated_creds);
-       state->delegated_creds.length =
-               i3.gssapi_delegated_creds_length;
-
+       state->session_info = talloc_move(state, &i4.session_info);
 reply:
        /* create the output */
        ndr_err = ndr_push_struct_blob(&out, state, &pipe_reply,
@@ -1406,9 +1390,7 @@ int _tstream_npa_accept_existing_recv(struct tevent_req *req,
                                      char **_client_name,
                                      struct tsocket_address **server,
                                      char **server_name,
-                                     struct netr_SamInfo3 **info3,
-                                     DATA_BLOB *session_key,
-                                     DATA_BLOB *delegated_creds,
+                                     struct auth_session_info_transport **session_info,
                                      const char *location)
 {
        struct tstream_npa_accept_state *state =
@@ -1457,11 +1439,7 @@ int _tstream_npa_accept_existing_recv(struct tevent_req *req,
        *_client_name = talloc_move(mem_ctx, &state->client_name);
        *server = talloc_move(mem_ctx, &state->server);
        *server_name = talloc_move(mem_ctx, &state->server_name);
-       *info3 = talloc_move(mem_ctx, &state->info3);
-       *session_key = state->session_key;
-       talloc_steal(mem_ctx, state->session_key.data);
-       *delegated_creds = state->delegated_creds;
-       talloc_steal(mem_ctx, state->delegated_creds.data);
+       *session_info = talloc_move(mem_ctx, &state->session_info);
 
        tevent_req_received(req);
        return 0;
index 63845bed6a28ea0c290058a50f2db09687d3f9b8..f2223170f0cc307e2fb5ac8d5479dc816f130bf6 100644 (file)
 
 struct tevent_req;
 struct tevent_context;
-struct netr_SamInfo3;
+struct auth_session_info_transport;
 
 struct tevent_req *tstream_npa_connect_send(TALLOC_CTX *mem_ctx,
-                                       struct tevent_context *ev,
-                                       const char *directory,
-                                       const char *npipe,
-                                       const struct tsocket_address *client,
-                                       const char *client_name_in,
-                                       const struct tsocket_address *server,
-                                       const char *server_name,
-                                       const struct netr_SamInfo3 *info3,
-                                       DATA_BLOB session_key,
-                                       DATA_BLOB delegated_creds);
+                                           struct tevent_context *ev,
+                                           const char *directory,
+                                           const char *npipe,
+                                           const struct tsocket_address *client,
+                                           const char *client_name_in,
+                                           const struct tsocket_address *server,
+                                           const char *server_name,
+                                           const struct auth_session_info_transport *session_info);
 int _tstream_npa_connect_recv(struct tevent_req *req,
                              int *perrno,
                              TALLOC_CTX *mem_ctx,
@@ -101,25 +99,21 @@ int _tstream_npa_accept_existing_recv(struct tevent_req *req,
                                      TALLOC_CTX *mem_ctx,
                                      struct tstream_context **stream,
                                      struct tsocket_address **client,
-                                     char **client_name,
+                                     char **_client_name,
                                      struct tsocket_address **server,
                                      char **server_name,
-                                     struct netr_SamInfo3 **info3,
-                                     DATA_BLOB *session_key,
-                                     DATA_BLOB *delegated_creds,
+                                     struct auth_session_info_transport **session_info,
                                      const char *location);
 #define tstream_npa_accept_existing_recv(req, perrno, \
                                         mem_ctx, stream, \
                                         client, client_name, \
                                         server, server_name, \
-                                        info3, session_key, \
-                                        delegated_creds) \
+                                        session_info) \
        _tstream_npa_accept_existing_recv(req, perrno, \
                                          mem_ctx, stream, \
                                          client, client_name, \
                                          server, server_name, \
-                                         info3, session_key, \
-                                         delegated_creds, \
+                                         session_info, \
                                          __location__)
 
 #endif /* NPA_TSTREAM_H */
index de89588664ac4efbf92a7fa5c98c0758d1d71661..721667eef985079792361e048a33e9cb60a36d69 100644 (file)
@@ -3,7 +3,7 @@
   miscellaneous IDL structures
 */
 
-import "netlogon.idl";
+import "netlogon.idl", "security.idl", "auth.idl";
 
 [
        pointer_default(unique)
@@ -19,16 +19,11 @@ interface named_pipe_auth
                [charset(UTF8),string] uint8 *server_name;
                [charset(DOS),string] uint8 *server_addr;
                uint16 server_port;
-               netr_SamInfo3 *sam_info3;
-               uint32 session_key_length;
-               [size_is(session_key_length)] uint8 *session_key;
-               uint32 gssapi_delegated_creds_length;
-               [size_is(gssapi_delegated_creds_length)]
-                       uint8 *gssapi_delegated_creds;
-       } named_pipe_auth_req_info3;
+               auth_session_info_transport *session_info;
+       } named_pipe_auth_req_info4;
 
        typedef [switch_type(uint32)] union {
-               [case(3)] named_pipe_auth_req_info3 info3;
+               [case(4)] named_pipe_auth_req_info4 info4;
        } named_pipe_auth_req_info;
 
        typedef [public,gensize] struct {
@@ -44,10 +39,10 @@ interface named_pipe_auth
                uint16 file_type;
                uint16 device_state;
                hyper allocation_size;
-       } named_pipe_auth_rep_info3;
+       } named_pipe_auth_rep_info4;
 
        typedef [switch_type(uint32)] union {
-               [case(3)] named_pipe_auth_rep_info3 info3;
+               [case(4)] named_pipe_auth_rep_info4 info4;
        } named_pipe_auth_rep_info;
 
        typedef [public,gensize] struct {
index d15e8b225d9c88b0b2c61bded2b54179a4be89b0..706977c45df8d02e02503f443547aa33c8c60eff 100644 (file)
@@ -8,9 +8,14 @@ bld.SAMBA_SUBSYSTEM('NDR_AUDIOSRV',
        public_deps='ndr'
        )
 
+bld.SAMBA_SUBSYSTEM('NDR_AUTH',
+       source='gen_ndr/ndr_auth.c',
+       public_deps='ndr NDR_SECURITY'
+       )
+
 bld.SAMBA_SUBSYSTEM('NDR_NAMED_PIPE_AUTH',
        source='gen_ndr/ndr_named_pipe_auth.c',
-       public_deps='ndr'
+       public_deps='ndr NDR_AUTH'
        )
 
 bld.SAMBA_SUBSYSTEM('NDR_DNSSERVER',
index 15d854eb15a8a08308776836e3e43a5c7905177b..3012caa7d33620ab226076e4f3fd48c2a9efa1f3 100644 (file)
@@ -709,7 +709,8 @@ RPC_EVENTLOG_OBJ = rpc_server/srv_eventlog_nt.o \
                   $(LIB_EVENTLOG_OBJ) librpc/gen_ndr/srv_eventlog.o
 
 NPA_TSTREAM_OBJ = ../libcli/named_pipe_auth/npa_tstream.o \
-                 librpc/gen_ndr/ndr_named_pipe_auth.o
+                 librpc/gen_ndr/ndr_named_pipe_auth.o \
+                 ../auth/auth_sam_reply.o librpc/gen_ndr/ndr_auth.o
 
 RPC_NCACN_NP = rpc_server/srv_pipe_register.o rpc_server/rpc_ncacn_np.o \
               rpc_server/rpc_handles.o
index af21ec2aad236d512ebf17ee1faa2a1c942d1e52..c35fa847ad41e5a5b0aff4ac3746187100d4dc86 100644 (file)
@@ -26,6 +26,8 @@
 #include "../libcli/named_pipe_auth/npa_tstream.h"
 #include "rpc_server/rpc_ncacn_np.h"
 #include "librpc/gen_ndr/netlogon.h"
+#include "librpc/gen_ndr/auth.h"
+#include "../auth/auth_sam_reply.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_RPC_SRV
@@ -594,7 +596,9 @@ struct np_proxy_state *make_external_rpc_pipe_p(TALLOC_CTX *mem_ctx,
        const char *socket_dir;
        struct tevent_context *ev;
        struct tevent_req *subreq;
-       struct netr_SamInfo3 *info3;
+       struct auth_session_info_transport *session_info;
+       struct auth_user_info_dc *user_info_dc;
+       union netr_Validation val;
        NTSTATUS status;
        bool ok;
        int ret;
@@ -637,20 +641,31 @@ struct np_proxy_state *make_external_rpc_pipe_p(TALLOC_CTX *mem_ctx,
                goto fail;
        }
 
-       info3 = talloc_zero(talloc_tos(), struct netr_SamInfo3);
-       if (info3 == NULL) {
+       session_info = talloc_zero(talloc_tos(), struct auth_session_info_transport);
+       if (session_info == NULL) {
                DEBUG(0, ("talloc failed\n"));
                goto fail;
        }
 
-       status = serverinfo_to_SamInfo3(server_info, NULL, 0, info3);
+       /* Send the named_pipe_auth server the user's full token */
+       session_info->security_token = server_info->ptok;
+       session_info->session_key = server_info->user_session_key;
+
+       val.sam3 = server_info->info3;
+
+       /* Convert into something we can build a struct
+        * auth_session_info_transport from.  Most of the work here
+        * will be to convert the SIDS, which we will then ignore, but
+        * this is the easier way to handle it */
+       status = make_user_info_dc_netlogon_validation(talloc_tos(), "", 3, &val, &user_info_dc);
        if (!NT_STATUS_IS_OK(status)) {
-               TALLOC_FREE(info3);
-               DEBUG(0, ("serverinfo_to_SamInfo3 failed: %s\n",
-                         nt_errstr(status)));
+               DEBUG(0, ("conversion of info3 into user_info_dc failed!\n"));
                goto fail;
        }
 
+       session_info->info = talloc_move(session_info, &user_info_dc->info);
+       talloc_free(user_info_dc);
+
        become_root();
        subreq = tstream_npa_connect_send(talloc_tos(), ev,
                                          socket_np_dir,
@@ -659,15 +674,13 @@ struct np_proxy_state *make_external_rpc_pipe_p(TALLOC_CTX *mem_ctx,
                                          NULL, /* client_name */
                                          local_address, /* server_addr */
                                          NULL, /* server_name */
-                                         info3,
-                                         server_info->user_session_key,
-                                         data_blob_null /* delegated_creds */);
+                                         session_info);
        if (subreq == NULL) {
                unbecome_root();
                DEBUG(0, ("tstream_npa_connect_send to %s for pipe %s and "
                          "user %s\\%s failed\n",
-                         socket_np_dir, pipe_name, info3->base.domain.string,
-                         info3->base.account_name.string));
+                         socket_np_dir, pipe_name, session_info->info->domain_name,
+                         session_info->info->account_name));
                goto fail;
        }
        ok = tevent_req_poll(subreq, ev);
@@ -675,8 +688,8 @@ struct np_proxy_state *make_external_rpc_pipe_p(TALLOC_CTX *mem_ctx,
        if (!ok) {
                DEBUG(0, ("tevent_req_poll to %s for pipe %s and user %s\\%s "
                          "failed for tstream_npa_connect: %s\n",
-                         socket_np_dir, pipe_name, info3->base.domain.string,
-                         info3->base.account_name.string,
+                         socket_np_dir, pipe_name, session_info->info->domain_name,
+                         session_info->info->account_name,
                          strerror(errno)));
                goto fail;
 
@@ -691,8 +704,8 @@ struct np_proxy_state *make_external_rpc_pipe_p(TALLOC_CTX *mem_ctx,
        if (ret != 0) {
                DEBUG(0, ("tstream_npa_connect_recv  to %s for pipe %s and "
                          "user %s\\%s failed: %s\n",
-                         socket_np_dir, pipe_name, info3->base.domain.string,
-                         info3->base.account_name.string,
+                         socket_np_dir, pipe_name, session_info->info->domain_name,
+                         session_info->info->account_name,
                          strerror(sys_errno)));
                goto fail;
        }
index 229096e463728f7b11a3375c071d3be3fa280a6c..a0da354fd30aec1c3bd2835266ba3e2e001d5418 100644 (file)
 #include "rpc_server/rpc_server.h"
 #include "rpc_dce.h"
 #include "librpc/gen_ndr/netlogon.h"
+#include "librpc/gen_ndr/auth.h"
 #include "registry/reg_parse_prs.h"
 #include "lib/tsocket/tsocket.h"
 #include "libcli/named_pipe_auth/npa_tstream.h"
+#include "../auth/auth_sam_reply.h"
 
 /* Creates a pipes_struct and initializes it with the information
  * sent from the client */
@@ -31,10 +33,12 @@ static int make_server_pipes_struct(TALLOC_CTX *mem_ctx,
                                    const char *pipe_name,
                                    const struct ndr_syntax_id id,
                                    const char *client_address,
-                                   struct netr_SamInfo3 *info3,
+                                   struct auth_session_info_transport *session_info,
                                    struct pipes_struct **_p,
                                    int *perrno)
 {
+       struct netr_SamInfo3 *info3;
+       struct auth_user_info_dc *auth_user_info_dc;
        struct pipes_struct *p;
        NTSTATUS status;
        bool ok;
@@ -67,6 +71,30 @@ static int make_server_pipes_struct(TALLOC_CTX *mem_ctx,
 
        p->endian = RPC_LITTLE_ENDIAN;
 
+       /* Fake up an auth_user_info_dc for now, to make an info3, to make the server_info structure */
+       auth_user_info_dc = talloc_zero(p, struct auth_user_info_dc);
+       if (!auth_user_info_dc) {
+               TALLOC_FREE(p);
+               *perrno = ENOMEM;
+               return -1;
+       }
+
+       auth_user_info_dc->num_sids = session_info->security_token->num_sids;
+       auth_user_info_dc->sids = session_info->security_token->sids;
+       auth_user_info_dc->info = session_info->info;
+       auth_user_info_dc->user_session_key = session_info->session_key;
+
+       /* This creates the input structure that make_server_info_info3 is looking for */
+       status = auth_convert_user_info_dc_saminfo3(p, auth_user_info_dc,
+                                                   &info3);
+
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(1, ("Failed to convert auth_user_info_dc into netr_SamInfo3\n"));
+               TALLOC_FREE(p);
+               *perrno = EINVAL;
+               return -1;
+       }
+
        status = make_server_info_info3(p,
                                        info3->base.account_name.string,
                                        info3->base.domain.string,
@@ -90,6 +118,15 @@ static int make_server_pipes_struct(TALLOC_CTX *mem_ctx,
                return -1;
        }
 
+       /* Now override the server_info->ptok with the exact
+        * security_token we were given from the other side,
+        * regardless of what we just calculated */
+       p->server_info->ptok = talloc_move(p->server_info, &session_info->security_token);
+
+       /* Also set the session key to the correct value */
+       p->server_info->user_session_key = session_info->session_key;
+       p->server_info->user_session_key.data = talloc_move(p->server_info, &session_info->session_key.data);
+
        p->client_id = talloc_zero(p, struct client_address);
        if (!p->client_id) {
                TALLOC_FREE(p);
@@ -318,9 +355,7 @@ struct named_pipe_client {
        char *client_name;
        struct tsocket_address *server;
        char *server_name;
-       struct netr_SamInfo3 *info3;
-       DATA_BLOB session_key;
-       DATA_BLOB delegated_creds;
+       struct auth_session_info_transport *session_info;
 
        struct pipes_struct *p;
 
@@ -410,9 +445,7 @@ static void named_pipe_accept_done(struct tevent_req *subreq)
                                                &npc->client_name,
                                                &npc->server,
                                                &npc->server_name,
-                                               &npc->info3,
-                                               &npc->session_key,
-                                               &npc->delegated_creds);
+                                               &npc->session_info);
        TALLOC_FREE(subreq);
        if (ret != 0) {
                DEBUG(2, ("Failed to accept named pipe connection! (%s)\n",
@@ -434,7 +467,7 @@ static void named_pipe_accept_done(struct tevent_req *subreq)
 
        ret = make_server_pipes_struct(npc,
                                        npc->pipe_name, npc->pipe_id,
-                                       cli_addr, npc->info3,
+                                       cli_addr, npc->session_info,
                                        &npc->p, &error);
        if (ret != 0) {
                DEBUG(2, ("Failed to create pipes_struct! (%s)\n",
index a6b8b2688ce5080afda53b88bd00c75ca24b2a6c..cf5514cbf7fa139e88d8e5721a778bb0c4e955e1 100644 (file)
 #include "includes.h"
 #include "auth/auth.h"
 #include "auth/auth_sam.h"
+#include "auth/credentials/credentials.h"
+#include "auth/credentials/credentials_krb5.h"
 #include "libcli/security/security.h"
 #include "libcli/auth/libcli_auth.h"
 #include "dsdb/samdb/samdb.h"
 #include "auth/session_proto.h"
+#include "system/kerberos.h"
+#include <gssapi/gssapi.h>
 
 _PUBLIC_ struct auth_session_info *anonymous_session(TALLOC_CTX *mem_ctx, 
                                            struct loadparm_context *lp_ctx)
@@ -151,6 +155,149 @@ _PUBLIC_ NTSTATUS auth_generate_session_info(TALLOC_CTX *mem_ctx,
        return NT_STATUS_OK;
 }
 
+/* Create a session_info structure from the
+ * auth_session_info_transport we were forwarded over named pipe
+ * forwarding.
+ *
+ * NOTE: The stucture members of session_info_transport are stolen
+ * with talloc_move() into auth_session_info for long term use
+ */
+struct auth_session_info *auth_session_info_from_transport(TALLOC_CTX *mem_ctx,
+                                                          struct auth_session_info_transport *session_info_transport,
+                                                          struct loadparm_context *lp_ctx,
+                                                          const char **reason)
+{
+       struct auth_session_info *session_info;
+       session_info = talloc_zero(mem_ctx, struct auth_session_info);
+       if (!session_info) {
+               *reason = "failed to allocate session_info";
+               return NULL;
+       }
+
+       session_info->security_token = talloc_move(session_info, &session_info_transport->security_token);
+       session_info->info = talloc_move(session_info, &session_info_transport->info);
+       session_info->session_key = session_info_transport->session_key;
+       session_info->session_key.data = talloc_move(session_info, &session_info_transport->session_key.data);
+
+       if (session_info_transport->exported_gssapi_credentials.length) {
+               struct cli_credentials *creds;
+               OM_uint32 minor_status;
+               gss_buffer_desc cred_token;
+               gss_cred_id_t cred_handle;
+               const char *error_string;
+               int ret;
+
+               DEBUG(10, ("Delegated credentials supplied by client\n"));
+
+               cred_token.value = session_info_transport->exported_gssapi_credentials.data;
+               cred_token.length = session_info_transport->exported_gssapi_credentials.length;
+
+               ret = gss_import_cred(&minor_status,
+                                     &cred_token,
+                                     &cred_handle);
+               if (ret != GSS_S_COMPLETE) {
+                       *reason = "Internal error in gss_import_cred()";
+                       return NULL;
+               }
+
+               creds = cli_credentials_init(session_info);
+               if (!creds) {
+                       *reason = "Out of memory in cli_credentials_init()";
+                       return NULL;
+               }
+               session_info->credentials = creds;
+
+               cli_credentials_set_conf(creds, lp_ctx);
+               /* Just so we don't segfault trying to get at a username */
+               cli_credentials_set_anonymous(creds);
+
+               ret = cli_credentials_set_client_gss_creds(creds,
+                                                          lp_ctx,
+                                                          cred_handle,
+                                                          CRED_SPECIFIED,
+                                                          &error_string);
+               if (ret) {
+                       *reason = talloc_asprintf(mem_ctx,
+                                                 "Failed to set pipe forwarded"
+                                                 "creds: %s\n", error_string);
+                       return NULL;
+               }
+
+               /* This credential handle isn't useful for password
+                * authentication, so ensure nobody tries to do that */
+               cli_credentials_set_kerberos_state(creds,
+                                                  CRED_MUST_USE_KERBEROS);
+
+       }
+
+       return session_info;
+}
+
+
+/* Create a auth_session_info_transport from an auth_session_info.
+ *
+ * NOTE: Members of the auth_session_info_transport structure are not talloc_referenced, but simply assigned.  They are only valid for the lifetime of the struct auth_session_info
+ *
+ * This isn't normally an issue, as the auth_session_info has a very long typical life
+ */
+NTSTATUS auth_session_info_transport_from_session(TALLOC_CTX *mem_ctx,
+                                                 struct auth_session_info *session_info,
+                                                 struct tevent_context *event_ctx,
+                                                 struct loadparm_context *lp_ctx,
+                                                 struct auth_session_info_transport **transport_out)
+{
+
+       struct auth_session_info_transport *session_info_transport = talloc_zero(mem_ctx, struct auth_session_info_transport);
+       session_info_transport->security_token = talloc_reference(session_info, session_info->security_token);
+       NT_STATUS_HAVE_NO_MEMORY(session_info_transport->security_token);
+
+       session_info_transport->info = talloc_reference(session_info, session_info->info);
+       NT_STATUS_HAVE_NO_MEMORY(session_info_transport->info);
+
+       session_info_transport->session_key = session_info->session_key;
+       session_info_transport->session_key.data = talloc_reference(session_info, session_info->session_key.data);
+       if (!session_info_transport->session_key.data && session_info->session_key.length) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       if (session_info->credentials) {
+               struct gssapi_creds_container *gcc;
+               OM_uint32 gret;
+               OM_uint32 minor_status;
+               gss_buffer_desc cred_token;
+               const char *error_string;
+               int ret;
+
+               ret = cli_credentials_get_client_gss_creds(session_info->credentials,
+                                                          event_ctx,
+                                                          lp_ctx,
+                                                          &gcc, &error_string);
+               if (ret != 0) {
+                       *transport_out = session_info_transport;
+                       return NT_STATUS_OK;
+               }
+
+               gret = gss_export_cred(&minor_status,
+                                      gcc->creds,
+                                      &cred_token);
+               if (gret != GSS_S_COMPLETE) {
+                       return NT_STATUS_INTERNAL_ERROR;
+               }
+
+               if (cred_token.length) {
+                       session_info_transport->exported_gssapi_credentials
+                               = data_blob_talloc(session_info_transport,
+                                                  cred_token.value,
+                                                  cred_token.length);
+                       gss_release_buffer(&minor_status, &cred_token);
+                       NT_STATUS_HAVE_NO_MEMORY(session_info_transport->exported_gssapi_credentials.data);
+               }
+       }
+       *transport_out = session_info_transport;
+       return NT_STATUS_OK;
+}
+
+
 /* Produce a session_info for an arbitary DN or principal in the local
  * DB, assuming the local DB holds all the groups
  *
index d8c00a39a4d533bb949d28e59241c829fe08a6ca..795497ea8fe761d8a329ae7beec8099c62552242 100644 (file)
@@ -52,6 +52,16 @@ NTSTATUS auth_generate_session_info(TALLOC_CTX *mem_ctx,
 NTSTATUS auth_anonymous_session_info(TALLOC_CTX *parent_ctx, 
                                     struct loadparm_context *lp_ctx,
                                     struct auth_session_info **session_info);
+struct auth_session_info *auth_session_info_from_transport(TALLOC_CTX *mem_ctx,
+                                                          struct auth_session_info_transport *session_info_transport,
+                                                          struct loadparm_context *lp_ctx,
+                                                          const char **reason);
+NTSTATUS auth_session_info_transport_from_session(TALLOC_CTX *mem_ctx,
+                                                 struct auth_session_info *session_info,
+                                                 struct tevent_context *event_ctx,
+                                                 struct loadparm_context *lp_ctx,
+                                                 struct auth_session_info_transport **transport_out);
+
 /* Produce a session_info for an arbitary DN or principal in the local
  * DB, assuming the local DB holds all the groups
  *
index 19127a29bcec15368409bb81f3695dd9094c111e..185e72cfb0fe6fdd903fdf50ecefee8b15696754 100644 (file)
@@ -217,7 +217,7 @@ struct ipc_open_state {
        struct pipe_state *p;
        struct ntvfs_request *req;
        union smb_open *oi;
-       struct netr_SamInfo3 *info3;
+       struct auth_session_info_transport *session_info_transport;
 };
 
 static void ipc_open_done(struct tevent_req *subreq);
@@ -253,9 +253,6 @@ static NTSTATUS ipc_open(struct ntvfs_module_context *ntvfs,
        const char *directory;
        const struct tsocket_address *client_addr;
        const struct tsocket_address *server_addr;
-       int ret;
-       DATA_BLOB delegated_creds = data_blob_null;
-       struct auth_user_info_dc user_info_dc;
 
        switch (oi->generic.level) {
        case RAW_OPEN_NTCREATEX:
@@ -310,54 +307,17 @@ static NTSTATUS ipc_open(struct ntvfs_module_context *ntvfs,
        state->req = req;
        state->oi = oi;
 
-       /* Disgusting hack to recreate the user_info_dc that should
-        * not be used that this layer in this way */
-       ZERO_STRUCT(user_info_dc);
-       user_info_dc.info = req->session_info->info;
-       user_info_dc.num_sids = req->session_info->torture->num_dc_sids;
-       user_info_dc.sids = req->session_info->torture->dc_sids;
+       status = auth_session_info_transport_from_session(state,
+                                                         req->session_info,
+                                                         ipriv->ntvfs->ctx->event_ctx,
+                                                         ipriv->ntvfs->ctx->lp_ctx,
+                                                         &state->session_info_transport);
 
-       status = auth_convert_user_info_dc_saminfo3(state,
-                                                   &user_info_dc,
-                                                   &state->info3);
        NT_STATUS_NOT_OK_RETURN(status);
 
        client_addr = ntvfs_get_local_address(ipriv->ntvfs);
        server_addr = ntvfs_get_remote_address(ipriv->ntvfs);
 
-       if (req->session_info->credentials) {
-               struct gssapi_creds_container *gcc;
-               OM_uint32 gret;
-               OM_uint32 minor_status;
-               gss_buffer_desc cred_token;
-               const char *error_string;
-
-               ret = cli_credentials_get_client_gss_creds(req->session_info->credentials,
-                                                          ipriv->ntvfs->ctx->event_ctx,
-                                                          ipriv->ntvfs->ctx->lp_ctx,
-                                                          &gcc, &error_string);
-               if (ret) {
-                       goto skip;
-               }
-
-               gret = gss_export_cred(&minor_status,
-                                      gcc->creds,
-                                      &cred_token);
-               if (gret != GSS_S_COMPLETE) {
-                       return NT_STATUS_INTERNAL_ERROR;
-               }
-
-               if (cred_token.length) {
-                       delegated_creds = data_blob_talloc(req,
-                                                          cred_token.value,
-                                                          cred_token.length);
-                       gss_release_buffer(&minor_status, &cred_token);
-                       NT_STATUS_HAVE_NO_MEMORY(delegated_creds.data);
-               }
-       }
-
-skip:
-
        subreq = tstream_npa_connect_send(p,
                                          ipriv->ntvfs->ctx->event_ctx,
                                          directory,
@@ -366,9 +326,7 @@ skip:
                                          NULL,
                                          server_addr,
                                          NULL,
-                                         state->info3,
-                                         req->session_info->session_key,
-                                         delegated_creds);
+                                         state->session_info_transport);
        NT_STATUS_HAVE_NO_MEMORY(subreq);
        tevent_req_set_callback(subreq, ipc_open_done, state);
 
index 148d4fdf80f7357d63808b0c2b7049f8c3992993..086a037b69dc9dffa832ea03706566c9a8df223e 100644 (file)
@@ -33,8 +33,7 @@
 #include "system/passwd.h"
 #include "system/network.h"
 #include "libcli/raw/smb.h"
-#include "auth/credentials/credentials.h"
-#include "auth/credentials/credentials_krb5.h"
+#include "auth/session.h"
 #include "libcli/security/security.h"
 #include "libcli/named_pipe_auth/npa_tstream.h"
 
@@ -93,18 +92,9 @@ static void named_pipe_accept_done(struct tevent_req *subreq)
        char *client_name;
        struct tsocket_address *server;
        char *server_name;
-       struct netr_SamInfo3 *info3;
-       DATA_BLOB session_key;
-       DATA_BLOB delegated_creds;
-
-       union netr_Validation val;
-       struct auth_user_info_dc *user_info_dc;
-       struct auth_context *auth_context;
-       uint32_t session_flags = 0;
-       struct dom_sid *anonymous_sid;
+       struct auth_session_info_transport *session_info_transport;
        const char *reason = NULL;
        TALLOC_CTX *tmp_ctx;
-       NTSTATUS status;
        int error;
        int ret;
 
@@ -115,14 +105,12 @@ static void named_pipe_accept_done(struct tevent_req *subreq)
        }
 
        ret = tstream_npa_accept_existing_recv(subreq, &error, tmp_ctx,
-                                               &conn->tstream,
-                                               &client,
-                                               &client_name,
-                                               &server,
-                                               &server_name,
-                                               &info3,
-                                               &session_key,
-                                               &delegated_creds);
+                                              &conn->tstream,
+                                              &client,
+                                              &client_name,
+                                              &server,
+                                              &server_name,
+                                              &session_info_transport);
        TALLOC_FREE(subreq);
        if (ret != 0) {
                reason = talloc_asprintf(conn,
@@ -137,111 +125,11 @@ static void named_pipe_accept_done(struct tevent_req *subreq)
                   client_name, tsocket_address_string(client, tmp_ctx),
                   server_name, tsocket_address_string(server, tmp_ctx)));
 
-       if (info3) {
-               val.sam3 = info3;
-
-               status = make_user_info_dc_netlogon_validation(conn,
-                                       val.sam3->base.account_name.string,
-                                       3, &val, &user_info_dc);
-               if (!NT_STATUS_IS_OK(status)) {
-                       reason = talloc_asprintf(conn,
-                                       "make_user_info_dc_netlogon_validation "
-                                       "returned: %s", nt_errstr(status));
-                       goto out;
-               }
-
-               status = auth_context_create(conn, conn->event.ctx,
-                                            conn->msg_ctx, conn->lp_ctx,
-                                            &auth_context);
-               if (!NT_STATUS_IS_OK(status)) {
-                       reason = talloc_asprintf(conn,
-                                       "auth_context_create returned: %s",
-                                       nt_errstr(status));
-                       goto out;
-               }
-
-               anonymous_sid = dom_sid_parse_talloc(auth_context,
-                                                    SID_NT_ANONYMOUS);
-               if (anonymous_sid == NULL) {
-                       talloc_free(auth_context);
-                       reason = "Failed to parse Anonymous SID ";
-                       goto out;
-               }
-
-               session_flags = AUTH_SESSION_INFO_DEFAULT_GROUPS;
-               if (user_info_dc->num_sids > 1 && !dom_sid_equal(anonymous_sid, &user_info_dc->sids[0])) {
-                       session_flags |= AUTH_SESSION_INFO_AUTHENTICATED;
-               }
-
-
-               /* setup the session_info on the connection */
-               status = auth_context->generate_session_info(conn,
-                                                            auth_context,
-                                                            user_info_dc,
-                                                            session_flags,
-                                                            &conn->session_info);
-               talloc_free(auth_context);
-               if (!NT_STATUS_IS_OK(status)) {
-                       reason = talloc_asprintf(conn,
-                                       "auth_generate_session_info "
-                                       "returned: %s", nt_errstr(status));
-                       goto out;
-               }
-       }
-
-       if (session_key.length) {
-               conn->session_info->session_key = session_key;
-               talloc_steal(conn->session_info, session_key.data);
-       }
-
-       if (delegated_creds.length) {
-               struct cli_credentials *creds;
-               OM_uint32 minor_status;
-               gss_buffer_desc cred_token;
-               gss_cred_id_t cred_handle;
-               const char *error_string;
-
-               DEBUG(10, ("Delegated credentials supplied by client\n"));
-
-               cred_token.value = delegated_creds.data;
-               cred_token.length = delegated_creds.length;
-
-               ret = gss_import_cred(&minor_status,
-                                     &cred_token,
-                                     &cred_handle);
-               if (ret != GSS_S_COMPLETE) {
-                       reason = "Internal error in gss_import_cred()";
-                       goto out;
-               }
-
-               creds = cli_credentials_init(conn->session_info);
-               if (!creds) {
-                       reason = "Out of memory in cli_credentials_init()";
-                       goto out;
-               }
-               conn->session_info->credentials = creds;
-
-               cli_credentials_set_conf(creds, conn->lp_ctx);
-               /* Just so we don't segfault trying to get at a username */
-               cli_credentials_set_anonymous(creds);
-
-               ret = cli_credentials_set_client_gss_creds(creds,
-                                                          conn->lp_ctx,
-                                                          cred_handle,
-                                                          CRED_SPECIFIED,
-                                                          &error_string);
-               if (ret) {
-                       reason = talloc_asprintf(conn,
-                                                "Failed to set pipe forwarded"
-                                                "creds: %s\n", error_string);
-                       goto out;
-               }
-
-               /* This credential handle isn't useful for password
-                * authentication, so ensure nobody tries to do that */
-               cli_credentials_set_kerberos_state(creds,
-                                                  CRED_MUST_USE_KERBEROS);
-
+       conn->session_info = auth_session_info_from_transport(conn, session_info_transport,
+                                                             conn->lp_ctx,
+                                                             &reason);
+       if (!conn->session_info) {
+               goto out;
        }
 
        /*