s4:rpc_server Record the remote connections association group ID
authorAndrew Bartlett <abartlet@samba.org>
Fri, 19 Feb 2010 04:53:31 +0000 (15:53 +1100)
committerAndrew Bartlett <abartlet@samba.org>
Fri, 19 Feb 2010 05:32:49 +0000 (16:32 +1100)
By recording the association group the remote server assigned to our
proxied RPC connection, we can ensure we use the same value when the
client wishes to use it.

This isn't stored in a private pointer, as mapiproxy will want to use
this feature too.

Andrew Bartlett

source4/rpc_server/dcerpc_server.h
source4/rpc_server/remote/dcesrv_remote.c

index d273f6eca996fdf632c2fd04c819afeaee4110d0..3a9c8feb75f151ab0c9f3d35415ca19358b7aace 100644 (file)
@@ -260,6 +260,9 @@ struct dcesrv_assoc_group {
 
        /* parent context */
        struct dcesrv_context *dce_ctx;
+
+       /* Remote association group ID (if proxied) */
+       uint32_t proxied_id;
 };
 
 /* server-wide context information for the dcerpc server */
index e20e87b326ae90a34333a43f091bd297591cf332..9c4174be96bfe53d9ef29fdfea5e9f6469f19bb7 100644 (file)
@@ -3,7 +3,9 @@
    remote dcerpc operations
 
    Copyright (C) Stefan (metze) Metzmacher 2004
-   
+   Copyright (C) Julien Kerihuel 2008-2009
+   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2010
+
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
@@ -43,7 +45,10 @@ static NTSTATUS remote_op_bind(struct dcesrv_call_state *dce_call, const struct
        const char *binding = lp_parm_string(dce_call->conn->dce_ctx->lp_ctx, NULL, "dcerpc_remote", "binding");
        const char *user, *pass, *domain;
        struct cli_credentials *credentials;
+       bool must_free_credentials = true;
        bool machine_account;
+       struct dcerpc_binding           *b;
+       struct composite_context        *pipe_conn_req;
 
        machine_account = lp_parm_bool(dce_call->conn->dce_ctx->lp_ctx, NULL, "dcerpc_remote", "use_machine_account", false);
 
@@ -96,17 +101,42 @@ static NTSTATUS remote_op_bind(struct dcesrv_call_state *dce_call, const struct
        } else if (dce_call->conn->auth_state.session_info->credentials) {
                DEBUG(5, ("dcerpc_remote: RPC Proxy: Using delegated credentials\n"));
                credentials = dce_call->conn->auth_state.session_info->credentials;
+               must_free_credentials = false;
        } else {
                DEBUG(1,("dcerpc_remote: RPC Proxy: You must supply binding, user and password or have delegated credentials\n"));
                return NT_STATUS_INVALID_PARAMETER;
        }
 
-       status = dcerpc_pipe_connect(priv,
-                                    &(priv->c_pipe), binding, table,
-                                    credentials, dce_call->event_ctx,
-                                    dce_call->conn->dce_ctx->lp_ctx);
+       /* parse binding string to the structure */
+       status = dcerpc_parse_binding(dce_call->context, binding, &b);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(0, ("Failed to parse dcerpc binding '%s'\n", binding));
+               return status;
+       }
+       
+       DEBUG(3, ("Using binding %s\n", dcerpc_binding_string(dce_call->context, b)));
+       
+       /* If we already have a remote association group ID, then use that */
+       if (dce_call->context->assoc_group->proxied_id != 0) {
+               b->assoc_group_id = dce_call->context->assoc_group->proxied_id;
+       }
+
+       pipe_conn_req = dcerpc_pipe_connect_b_send(dce_call->context, b, table,
+                                                  credentials, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx);
+       status = dcerpc_pipe_connect_b_recv(pipe_conn_req, dce_call->context, &(priv->c_pipe));
+       
+       if (must_free_credentials) {
+               talloc_free(credentials);
+       }
+
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       if (dce_call->context->assoc_group->proxied_id == 0) {
+               dce_call->context->assoc_group->proxied_id = priv->c_pipe->assoc_group_id;
+       }
 
-       talloc_free(credentials);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }