r4640: first stage in the server side support for multiple context_ids on one pipe
authorAndrew Tridgell <tridge@samba.org>
Mon, 10 Jan 2005 12:15:26 +0000 (12:15 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:08:38 +0000 (13:08 -0500)
this stage does the following:

 - simplifies the dcerpc_handle handling, and all the callers of it

 - split out the context_id depenent state into a linked list of established contexts

 - fixed some talloc handling in several rpc servers that i noticed while doing the above
(This used to be commit fde042b3fc609c94e2c7eedcdd72ecdf489cf63b)

15 files changed:
source4/build/pidl/server.pm
source4/include/structs.h
source4/rpc_server/common/common.h
source4/rpc_server/dcerpc_server.c
source4/rpc_server/dcerpc_server.h
source4/rpc_server/drsuapi/dcesrv_drsuapi.c
source4/rpc_server/epmapper/rpc_epmapper.c
source4/rpc_server/handles.c
source4/rpc_server/lsa/dcesrv_lsa.c
source4/rpc_server/netlogon/dcerpc_netlogon.c
source4/rpc_server/remote/dcesrv_remote.c
source4/rpc_server/samr/dcesrv_samr.c
source4/rpc_server/spoolss/dcesrv_spoolss.c
source4/rpc_server/spoolss/dcesrv_spoolss.h
source4/rpc_server/winreg/rpc_winreg.c

index c035b7e6bbf9e29773ec8b9d910af576e6187eb0..5c70adf2af138afc16ec5835df2791123abbaa67 100644 (file)
@@ -69,10 +69,10 @@ static NTSTATUS $name\__op_bind(struct dcesrv_call_state *dce_call, const struct
 #endif
 }
 
-static void $name\__op_unbind(struct dcesrv_connection *dce_conn, const struct dcesrv_interface *iface)
+static void $name\__op_unbind(struct dcesrv_connection_context *context, const struct dcesrv_interface *iface)
 {
 #ifdef DCESRV_INTERFACE_$uname\_UNBIND
-       DCESRV_INTERFACE_$uname\_UNBIND(dce_conn,iface);
+       DCESRV_INTERFACE_$uname\_UNBIND(context, iface);
 #else
        return;
 #endif
index 9572bfe03859d3b7e40e1a4278e44a9bc32b7bfd..006446b4b15e2295b1377fbc851ee6bcd1bb8dd4 100644 (file)
@@ -97,6 +97,7 @@ struct pvfs_file_handle;
 struct dcesrv_context;
 struct dcesrv_interface;
 struct dcesrv_connection;
+struct dcesrv_connection_context;
 struct dcesrv_endpoint;
 struct dcesrv_call_state;
 struct dcesrv_auth;
index a45f183ca6925e19d256946f682d1b4535a2b2d2..67c758a698982d45976958087fa67c518b9cf91d 100644 (file)
    invalid handle or retval if the handle is of the
    wrong type */
 #define DCESRV_PULL_HANDLE_RETVAL(h, inhandle, t, retval) do { \
-       (h) = dcesrv_handle_fetch(dce_call->conn, (inhandle), DCESRV_HANDLE_ANY); \
+       (h) = dcesrv_handle_fetch(dce_call->context, (inhandle), DCESRV_HANDLE_ANY); \
        DCESRV_CHECK_HANDLE(h); \
        if ((t) != DCESRV_HANDLE_ANY && (h)->wire_handle.handle_type != (t)) { \
                return retval; \
        } \
 } while (0)
 
+/* this checks for a valid policy handle and gives a dcerpc fault 
+   if its the wrong type of handle */
+#define DCESRV_PULL_HANDLE_FAULT(h, inhandle, t) do { \
+       (h) = dcesrv_handle_fetch(dce_call->context, (inhandle), t); \
+       DCESRV_CHECK_HANDLE(h); \
+} while (0)
+
 #define DCESRV_PULL_HANDLE(h, inhandle, t) DCESRV_PULL_HANDLE_RETVAL(h, inhandle, t, NT_STATUS_INVALID_HANDLE)
 #define DCESRV_PULL_HANDLE_WERR(h, inhandle, t) DCESRV_PULL_HANDLE_RETVAL(h, inhandle, t, WERR_BADFID)
index e4f581882695c42ae171551bdb8599d42bbfea1b..808cad94d9c35da905e00c47b497e6e45ac2b5d8 100644 (file)
@@ -63,6 +63,19 @@ static struct dcesrv_endpoint *find_endpoint(struct dcesrv_context *dce_ctx,
        return NULL;
 }
 
+/*
+  find a registered context_id from a bind or alter_context
+*/
+static struct dcesrv_connection_context *dcesrv_find_context(struct dcesrv_connection *conn, 
+                                                                  uint32_t context_id)
+{
+       struct dcesrv_connection_context *c;
+       for (c=conn->contexts;c;c=c->next) {
+               if (c->context_id == context_id) return c;
+       }
+       return NULL;
+}
+
 /*
   see if a uuid and if_version match to an interface
 */
@@ -84,7 +97,7 @@ static BOOL interface_match(const struct dcesrv_interface *if1,
   find the interface operations on an endpoint
 */
 static const struct dcesrv_interface *find_interface(const struct dcesrv_endpoint *endpoint,
-                                                      const struct dcesrv_interface *iface)
+                                                    const struct dcesrv_interface *iface)
 {
        struct dcesrv_if_list *ifl;
        for (ifl=endpoint->interface_list; ifl; ifl=ifl->next) {
@@ -264,15 +277,19 @@ NTSTATUS dcesrv_fetch_session_key(struct dcesrv_connection *p,
 static int dcesrv_endpoint_destructor(void *ptr)
 {
        struct dcesrv_connection *p = ptr;
-       if (p->iface) {
-               p->iface->unbind(p, p->iface);
-       }
 
-       /* destroy any handles */
-       while (p->handles) {
-               dcesrv_handle_destroy(p, p->handles);
+       while (p->contexts) {
+               struct dcesrv_connection_context *c = p->contexts;
+
+               DLIST_REMOVE(p->contexts, c);
+
+               if (c->iface) {
+                       c->iface->unbind(c, c->iface);
+               }
+               talloc_free(c);
        }
 
+
        return 0;
 }
 
@@ -291,11 +308,9 @@ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx,
 
        (*p)->dce_ctx = dce_ctx;
        (*p)->endpoint = ep;
-       (*p)->iface = NULL;
-       (*p)->private = NULL;
+       (*p)->contexts = NULL;
        (*p)->call_list = NULL;
        (*p)->cli_max_recv_frag = 0;
-       (*p)->handles = NULL;
        (*p)->partial_input = data_blob(NULL, 0);
        (*p)->auth_state.auth_info = NULL;
        (*p)->auth_state.gensec_security = NULL;
@@ -443,12 +458,21 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
        struct dcesrv_call_reply *rep;
        NTSTATUS status;
        uint32_t result=0, reason=0;
+       uint32_t context_id;
+       const struct dcesrv_interface *iface;
 
        if (call->pkt.u.bind.num_contexts != 1 ||
            call->pkt.u.bind.ctx_list[0].num_transfer_syntaxes < 1) {
                return dcesrv_bind_nak(call, 0);
        }
 
+       context_id = call->pkt.u.bind.ctx_list[0].context_id;
+
+       /* you can't bind twice on one context */
+       if (dcesrv_find_context(call->conn, context_id) != NULL) {
+               return dcesrv_bind_nak(call, 0);
+       }
+
        if_version = call->pkt.u.bind.ctx_list[0].abstract_syntax.if_version;
        uuid = GUID_string(call, &call->pkt.u.bind.ctx_list[0].abstract_syntax.uuid);
        if (!uuid) {
@@ -465,14 +489,30 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
                return dcesrv_bind_nak(call, 0);
        }
 
-       call->conn->iface = find_interface_by_uuid(call->conn->endpoint, uuid, if_version);
-       if (!call->conn->iface) {
+       iface = find_interface_by_uuid(call->conn->endpoint, uuid, if_version);
+       if (iface == NULL) {
                DEBUG(2,("Request for unknown dcerpc interface %s/%d\n", uuid, if_version));
                /* we don't know about that interface */
                result = DCERPC_BIND_PROVIDER_REJECT;
                reason = DCERPC_BIND_REASON_ASYNTAX;            
        }
 
+       if (iface) {
+               /* add this context to the list of available context_ids */
+               struct dcesrv_connection_context *context = talloc(call->conn, 
+                                                                  struct dcesrv_connection_context);
+               if (context == NULL) {
+                       return dcesrv_bind_nak(call, 0);
+               }
+               context->conn = call->conn;
+               context->iface = iface;
+               context->context_id = context_id;
+               context->private = NULL;
+               context->handles = NULL;
+               DLIST_ADD(call->conn->contexts, context);
+               call->context = context;
+       }
+
        if (call->conn->cli_max_recv_frag == 0) {
                call->conn->cli_max_recv_frag = call->pkt.u.bind.max_recv_frag;
        }
@@ -492,10 +532,9 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
        pkt.u.bind_ack.max_xmit_frag = 0x2000;
        pkt.u.bind_ack.max_recv_frag = 0x2000;
        pkt.u.bind_ack.assoc_group_id = call->pkt.u.bind.assoc_group_id;
-       if (call->conn->iface) {
+       if (iface) {
                /* FIXME: Use pipe name as specified by endpoint instead of interface name */
-               pkt.u.bind_ack.secondary_address = talloc_asprintf(call, "\\PIPE\\%s", 
-                                                                  call->conn->iface->name);
+               pkt.u.bind_ack.secondary_address = talloc_asprintf(call, "\\PIPE\\%s", iface->name);
        } else {
                pkt.u.bind_ack.secondary_address = "";
        }
@@ -514,15 +553,16 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
                return dcesrv_bind_nak(call, 0);
        }
 
-       if (call->conn->iface) {
-               status = call->conn->iface->bind(call, call->conn->iface);
+       if (iface) {
+               status = iface->bind(call, iface);
                if (!NT_STATUS_IS_OK(status)) {
-                       DEBUG(2,("Request for dcerpc interface %s/%d rejected: %s\n", uuid, if_version, nt_errstr(status)));
+                       DEBUG(2,("Request for dcerpc interface %s/%d rejected: %s\n", 
+                                uuid, if_version, nt_errstr(status)));
                        return dcesrv_bind_nak(call, 0);
                }
        }
 
-       rep = talloc_p(call, struct dcesrv_call_reply);
+       rep = talloc(call, struct dcesrv_call_reply);
        if (!rep) {
                return NT_STATUS_NO_MEMORY;
        }
@@ -630,13 +670,17 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
        NTSTATUS status;
        DATA_BLOB stub;
        uint32_t total_length;
+       struct dcesrv_connection_context *context;
 
        call->fault_code = 0;
 
-       if (!call->conn->iface) {
+       context = dcesrv_find_context(call->conn, call->pkt.u.request.context_id);
+       if (context == NULL) {
                return dcesrv_fault(call, DCERPC_FAULT_UNK_IF);
        }
 
+       call->context = context;
+
        pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call);
        if (!pull) {
                return NT_STATUS_NO_MEMORY;
@@ -651,7 +695,7 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
        }
 
        /* unravel the NDR for the packet */
-       status = call->conn->iface->ndr_pull(call, call, pull, &r);
+       status = context->iface->ndr_pull(call, call, pull, &r);
        if (!NT_STATUS_IS_OK(status)) {
                return dcesrv_fault(call, call->fault_code);
        }
@@ -663,7 +707,7 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
        }
 
        /* call the dispatch function */
-       status = call->conn->iface->dispatch(call, call, r);
+       status = context->iface->dispatch(call, call, r);
        if (!NT_STATUS_IS_OK(status)) {
                return dcesrv_fault(call, call->fault_code);
        }
@@ -683,7 +727,7 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
                push->flags |= LIBNDR_FLAG_BIGENDIAN;
        }
 
-       status = call->conn->iface->ndr_push(call, call, push, r);
+       status = context->iface->ndr_push(call, call, push, r);
        if (!NT_STATUS_IS_OK(status)) {
                return dcesrv_fault(call, call->fault_code);
        }
@@ -697,7 +741,7 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
                struct dcesrv_call_reply *rep;
                struct dcerpc_packet pkt;
 
-               rep = talloc_p(call, struct dcesrv_call_reply);
+               rep = talloc(call, struct dcesrv_call_reply);
                if (!rep) {
                        return NT_STATUS_NO_MEMORY;
                }
@@ -787,13 +831,14 @@ NTSTATUS dcesrv_input_process(struct dcesrv_connection *dce_conn)
        struct dcesrv_call_state *call;
        DATA_BLOB blob;
 
-       call = talloc_p(dce_conn, struct dcesrv_call_state);
+       call = talloc(dce_conn, struct dcesrv_call_state);
        if (!call) {
                talloc_free(dce_conn->partial_input.data);
                return NT_STATUS_NO_MEMORY;
        }
        call->conn = dce_conn;
        call->replies = NULL;
+       call->context = NULL;
 
        blob = dce_conn->partial_input;
        blob.length = dcerpc_get_frag_length(&blob);
index c919476d1bdcecdfe61df62a9b82811fd2cf07bf..49fbd4477b2ded611aa7f58f6bde57e23bdf52d4 100644 (file)
@@ -44,8 +44,7 @@ struct dcesrv_interface {
        NTSTATUS (*bind)(struct dcesrv_call_state *, const struct dcesrv_interface *);
 
        /* this function is called when the client disconnects the endpoint */
-       void (*unbind)(struct dcesrv_connection *, const struct dcesrv_interface *);
-
+       void (*unbind)(struct dcesrv_connection_context *, const struct dcesrv_interface *);
 
        /* the ndr_pull function for the chosen interface.
         */
@@ -67,6 +66,7 @@ struct dcesrv_interface {
 struct dcesrv_call_state {
        struct dcesrv_call_state *next, *prev;
        struct dcesrv_connection *conn;
+       struct dcesrv_connection_context *context;
        struct dcerpc_packet pkt;
 
        DATA_BLOB input;
@@ -85,9 +85,10 @@ struct dcesrv_call_state {
 /* a dcerpc handle in internal format */
 struct dcesrv_handle {
        struct dcesrv_handle *next, *prev;
+       struct dcesrv_connection_context *context;
        struct policy_handle wire_handle;
        void *data;
-       void (*destroy)(struct dcesrv_connection *, struct dcesrv_handle *);
+       void (*destroy)(struct dcesrv_connection_context *, struct dcesrv_handle *);
 };
 
 /* hold the authentication state information */
@@ -98,6 +99,24 @@ struct dcesrv_auth {
        NTSTATUS (*session_key)(struct dcesrv_connection *, DATA_BLOB *session_key);
 };
 
+struct dcesrv_connection_context {
+       struct dcesrv_connection_context *next, *prev;
+       uint32_t context_id;
+
+       /* the connection this is on */
+       struct dcesrv_connection *conn;
+
+       /* the ndr function table for the chosen interface */
+       const struct dcesrv_interface *iface;
+
+       /* private data for the interface implementation */
+       void *private;
+
+       /* current rpc handles - this is really the wrong scope for
+          them, but it will do for now */
+       struct dcesrv_handle *handles;
+};
+
 
 /* the state associated with a dcerpc server connection */
 struct dcesrv_connection {
@@ -107,8 +126,8 @@ struct dcesrv_connection {
        /* the endpoint that was opened */
        const struct dcesrv_endpoint *endpoint;
 
-       /* the ndr function table for the chosen interface */
-       const struct dcesrv_interface *iface;
+       /* a list of established context_ids */
+       struct dcesrv_connection_context *contexts;
 
        /* the state of the current calls */
        struct dcesrv_call_state *call_list;
@@ -116,13 +135,6 @@ struct dcesrv_connection {
        /* the maximum size the client wants to receive */
        uint32_t cli_max_recv_frag;
 
-       /* private data for the interface implementation */
-       void *private;
-
-       /* current rpc handles - this is really the wrong scope for
-          them, but it will do for now */
-       struct dcesrv_handle *handles;
-
        DATA_BLOB partial_input;
 
        /* the current authentication state */
index 5539c9117f36079469414e4b6c2023f112921269..508a2dec5e20f3d0eeb6cf075a5a20ad7a0be1c7 100644 (file)
 #include "rpc_server/common/common.h"
 #include "rpc_server/drsuapi/dcesrv_drsuapi.h"
 
-/*
-  destroy a general handle. 
-*/
-static void drsuapi_handle_destroy(struct dcesrv_connection *conn, struct dcesrv_handle *h)
-{
-       talloc_free(h->data);
-}
-
 /* 
   drsuapi_DsBind 
 */
@@ -57,14 +49,13 @@ static WERROR drsuapi_DsBind(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem
                return WERR_FOOBAR;
        }
 
-       handle = dcesrv_handle_new(dce_call->conn, DRSUAPI_BIND_HANDLE);
+       handle = dcesrv_handle_new(dce_call->context, DRSUAPI_BIND_HANDLE);
        if (!handle) {
                talloc_free(b_state);
                return WERR_NOMEM;
        }
 
-       handle->data = b_state;
-       handle->destroy = drsuapi_handle_destroy;
+       handle->data = talloc_steal(handle, b_state);
 
        bind_info = talloc_p(mem_ctx, struct drsuapi_DsBindInfoCtr);
        WERR_TALLOC_CHECK(bind_info);
@@ -88,7 +79,7 @@ static WERROR drsuapi_DsBind(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem
   drsuapi_DsUnbind 
 */
 static WERROR drsuapi_DsUnbind(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
-                      struct drsuapi_DsUnbind *r)
+                              struct drsuapi_DsUnbind *r)
 {
        struct dcesrv_handle *h;
 
@@ -96,10 +87,7 @@ static WERROR drsuapi_DsUnbind(struct dcesrv_call_state *dce_call, TALLOC_CTX *m
 
        DCESRV_PULL_HANDLE_WERR(h, r->in.bind_handle, DRSUAPI_BIND_HANDLE);
 
-       /* this causes the callback drsuapi_handle_destroy() to be called by
-          the handle destroy code which destroys the state associated
-          with the handle */
-       dcesrv_handle_destroy(dce_call->conn, h);
+       talloc_free(h);
 
        ZERO_STRUCTP(r->out.bind_handle);
 
index 85adb5390953561b0dfac76971a6e9c0db869dce..98992de74aebe027bc32c18436031d12efa83131 100644 (file)
@@ -121,8 +121,7 @@ static error_status_t epm_Lookup(struct dcesrv_call_state *dce_call, TALLOC_CTX
        uint32_t num_ents;
        int i;
 
-       h = dcesrv_handle_fetch(dce_call->conn, r->in.entry_handle, HTYPE_LOOKUP);
-       DCESRV_CHECK_HANDLE(h);
+       DCESRV_PULL_HANDLE_FAULT(h, r->in.entry_handle, HTYPE_LOOKUP);
 
        eps = h->data;
 
@@ -150,7 +149,7 @@ static error_status_t epm_Lookup(struct dcesrv_call_state *dce_call, TALLOC_CTX
        if (num_ents == 0) {
                r->out.entries = NULL;
                ZERO_STRUCTP(r->out.entry_handle);
-               dcesrv_handle_destroy(dce_call->conn, h);
+               talloc_free(h);
                return EPMAPPER_STATUS_NO_MORE_ENTRIES;
        }
 
index 41169aa25dd36e57d4ada187b194c993bbbe6d02..df9213bfd3ad8e59baf9aafa4f1c2632565f641e 100644 (file)
 #include "dlinklist.h"
 #include "rpc_server/dcerpc_server.h"
 
+/*
+  destroy a rpc handle
+*/
+static int dcesrv_handle_destructor(void *ptr)
+{
+       struct dcesrv_handle *h = ptr;
+       if (h->destroy) {
+               h->destroy(h->context, h);
+       }
+       DLIST_REMOVE(h->context->handles, h);
+       talloc_free(h);
+       return 0;
+}
+
+
 /*
   allocate a new rpc handle
 */
-struct dcesrv_handle *dcesrv_handle_new(struct dcesrv_connection *dce_conn
+struct dcesrv_handle *dcesrv_handle_new(struct dcesrv_connection_context *context
                                        uint8_t handle_type)
 {
        struct dcesrv_handle *h;
 
-       h = talloc_p(dce_conn, struct dcesrv_handle);
+       h = talloc_p(context, struct dcesrv_handle);
        if (!h) {
                return NULL;
        }
        h->data = NULL;
        h->destroy = NULL;
+       h->context = context;
 
        h->wire_handle.handle_type = handle_type;
        h->wire_handle.uuid = GUID_random();
        
-       DLIST_ADD(dce_conn->handles, h);
+       DLIST_ADD(context->handles, h);
 
-       return h;
-}
+       talloc_set_destructor(h, dcesrv_handle_destructor);
 
-/*
-  destroy a rpc handle
-*/
-void dcesrv_handle_destroy(struct dcesrv_connection *dce_conn, 
-                          struct dcesrv_handle *h)
-{
-       if (h->destroy) {
-               h->destroy(dce_conn, h);
-       }
-       DLIST_REMOVE(dce_conn->handles, h);
-       talloc_free(h);
+       return h;
 }
 
-
 /*
   find an internal handle given a wire handle. If the wire handle is NULL then
   allocate a new handle
 */
-struct dcesrv_handle *dcesrv_handle_fetch(struct dcesrv_connection *dce_conn
+struct dcesrv_handle *dcesrv_handle_fetch(struct dcesrv_connection_context *context
                                          struct policy_handle *p,
                                          uint8_t handle_type)
 {
        struct dcesrv_handle *h;
 
        if (policy_handle_empty(p)) {
-               return dcesrv_handle_new(dce_conn, handle_type);
+               return dcesrv_handle_new(context, handle_type);
        }
 
-       for (h=dce_conn->handles; h; h=h->next) {
+       for (h=context->handles; h; h=h->next) {
                if (h->wire_handle.handle_type == p->handle_type &&
                    GUID_equal(&p->uuid, &h->wire_handle.uuid)) {
                        if (handle_type != DCESRV_HANDLE_ANY &&
index dd22834c01c5be29c3340c1583a3f2e18d7228bb..752795b65b4cd5c3a9442d88a17a08ac1cfb83d4 100644 (file)
@@ -65,24 +65,6 @@ struct lsa_account_state {
 };
 
 
-/*
-  destroy an open policy. This closes the database connection
-*/
-static void lsa_Policy_destroy(struct dcesrv_connection *conn, struct dcesrv_handle *h)
-{
-       struct lsa_policy_state *state = h->data;
-       talloc_free(state);
-}
-
-/*
-  destroy an open account.
-*/
-static void lsa_Account_destroy(struct dcesrv_connection *conn, struct dcesrv_handle *h)
-{
-       struct lsa_account_state *astate = h->data;
-       talloc_free(astate);
-}
-
 /* 
   lsa_Close 
 */
@@ -95,10 +77,7 @@ static NTSTATUS lsa_Close(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ct
 
        DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
 
-       /* this causes the callback samr_XXX_destroy() to be called by
-          the handle destroy code which destroys the state associated
-          with the handle */
-       dcesrv_handle_destroy(dce_call->conn, h);
+       talloc_free(h);
 
        ZERO_STRUCTP(r->out.handle);
 
@@ -278,13 +257,12 @@ static NTSTATUS lsa_OpenPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *
                return status;
        }
 
-       handle = dcesrv_handle_new(dce_call->conn, LSA_HANDLE_POLICY);
+       handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_POLICY);
        if (!handle) {
                return NT_STATUS_NO_MEMORY;
        }
 
-       handle->data = talloc_reference(handle, state);
-       handle->destroy = lsa_Policy_destroy;
+       handle->data = talloc_steal(handle, state);
 
        state->access_mask = r->in.access_mask;
        state->handle = handle;
@@ -858,14 +836,13 @@ static NTSTATUS lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *
        astate->policy = talloc_reference(astate, state);
        astate->access_mask = r->in.access_mask;
 
-       ah = dcesrv_handle_new(dce_call->conn, LSA_HANDLE_ACCOUNT);
+       ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
        if (!ah) {
                talloc_free(astate);
                return NT_STATUS_NO_MEMORY;
        }
 
-       ah->data = astate;
-       ah->destroy = lsa_Account_destroy;
+       ah->data = talloc_steal(ah, astate);
 
        *r->out.acct_handle = ah->wire_handle;
 
index 259f43895b03272c99bb2dd343329627dea7401f..afb066f4ee41d492834936aef0d47411f7d09eae 100644 (file)
@@ -73,7 +73,7 @@ static NTSTATUS netlogon_schannel_setup(struct dcesrv_call_state *dce_call)
                return status;
        }
        
-       dce_call->conn->private = state;
+       dce_call->context->private = state;
 
        return NT_STATUS_OK;
 }
@@ -83,7 +83,7 @@ static NTSTATUS netlogon_schannel_setup(struct dcesrv_call_state *dce_call)
 */
 static NTSTATUS netlogon_bind(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *di) 
 {
-       dce_call->conn->private = NULL;
+       dce_call->context->private = NULL;
 
        /* if this is a schannel bind then we need to reconstruct the pipe state */
        if (dce_call->conn->auth_state.auth_info &&
@@ -103,15 +103,11 @@ static NTSTATUS netlogon_bind(struct dcesrv_call_state *dce_call, const struct d
 }
 
 /* this function is called when the client disconnects the endpoint */
-static void netlogon_unbind(struct dcesrv_connection *conn, const struct dcesrv_interface *di) 
+static void netlogon_unbind(struct dcesrv_connection_context *context, const struct dcesrv_interface *di) 
 {
-       struct server_pipe_state *pipe_state = conn->private;
-
-       if (pipe_state) {
-               talloc_free(pipe_state);
-       }
-
-       conn->private = NULL;
+       struct server_pipe_state *pipe_state = context->private;
+       talloc_free(pipe_state);
+       context->private = NULL;
 }
 
 #define DCESRV_INTERFACE_NETLOGON_BIND netlogon_bind
@@ -120,7 +116,7 @@ static void netlogon_unbind(struct dcesrv_connection *conn, const struct dcesrv_
 static NTSTATUS netr_ServerReqChallenge(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                                        struct netr_ServerReqChallenge *r)
 {
-       struct server_pipe_state *pipe_state = dce_call->conn->private;
+       struct server_pipe_state *pipe_state = dce_call->context->private;
 
        ZERO_STRUCTP(r->out.credentials);
 
@@ -128,10 +124,10 @@ static NTSTATUS netr_ServerReqChallenge(struct dcesrv_call_state *dce_call, TALL
 
        if (pipe_state) {
                talloc_free(pipe_state);
-               dce_call->conn->private = NULL;
+               dce_call->context->private = NULL;
        }
        
-       pipe_state = talloc_p(dce_call->conn, struct server_pipe_state);
+       pipe_state = talloc_p(dce_call->context, struct server_pipe_state);
        if (!pipe_state) {
                return NT_STATUS_NO_MEMORY;
        }
@@ -148,7 +144,7 @@ static NTSTATUS netr_ServerReqChallenge(struct dcesrv_call_state *dce_call, TALL
 
        *r->out.credentials = pipe_state->server_challenge;
 
-       dce_call->conn->private = pipe_state;
+       dce_call->context->private = pipe_state;
 
        return NT_STATUS_OK;
 }
@@ -156,7 +152,7 @@ static NTSTATUS netr_ServerReqChallenge(struct dcesrv_call_state *dce_call, TALL
 static NTSTATUS netr_ServerAuthenticate3(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                                         struct netr_ServerAuthenticate3 *r)
 {
-       struct server_pipe_state *pipe_state = dce_call->conn->private;
+       struct server_pipe_state *pipe_state = dce_call->context->private;
        void *sam_ctx;
        struct samr_Password *mach_pwd;
        uint16_t acct_flags;
@@ -339,7 +335,7 @@ static NTSTATUS netr_creds_server_step_check(struct server_pipe_state *pipe_stat
 static NTSTATUS netr_ServerPasswordSet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                                       struct netr_ServerPasswordSet *r)
 {
-       struct server_pipe_state *pipe_state = dce_call->conn->private;
+       struct server_pipe_state *pipe_state = dce_call->context->private;
 
        void *sam_ctx;
        int num_records;
@@ -468,7 +464,7 @@ static WERROR netr_LogonUasLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX
 static NTSTATUS netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                                     struct netr_LogonSamLogonEx *r)
 {
-       struct server_pipe_state *pipe_state = dce_call->conn->private;
+       struct server_pipe_state *pipe_state = dce_call->context->private;
 
        struct auth_context *auth_context;
        struct auth_usersupplied_info *user_info;
@@ -539,7 +535,7 @@ static NTSTATUS netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_
        nt_status = auth_check_password(auth_context, mem_ctx, user_info, &server_info);
        NT_STATUS_NOT_OK_RETURN(nt_status);
 
-       sam = talloc_p(mem_ctx, struct netr_SamBaseInfo);
+       sam = talloc_zero(mem_ctx, struct netr_SamBaseInfo);
        NT_STATUS_HAVE_NO_MEMORY(sam);
 
        sam->last_logon = server_info->last_logon;
@@ -660,7 +656,7 @@ static NTSTATUS netr_LogonSamLogonWithFlags(struct dcesrv_call_state *dce_call,
        NTSTATUS nt_status;
        struct netr_LogonSamLogonEx r2;
 
-       struct server_pipe_state *pipe_state = dce_call->conn->private;
+       struct server_pipe_state *pipe_state = dce_call->context->private;
 
        r->out.return_authenticator = talloc_p(mem_ctx, struct netr_Authenticator);
        if (!r->out.return_authenticator) {
@@ -963,7 +959,7 @@ static NTSTATUS fill_domain_trust_info(TALLOC_CTX *mem_ctx, struct ldb_message *
 static NTSTATUS netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                                        struct netr_LogonGetDomainInfo *r)
 {
-       struct server_pipe_state *pipe_state = dce_call->conn->private;
+       struct server_pipe_state *pipe_state = dce_call->context->private;
        const char * const attrs[] = { "name", "dnsDomain", "objectSid", 
                                       "objectGUID", "flatName", "securityIdentifier",
                                       NULL };
index 83c550974d9a9d5b865759b93f12f66c95782568..1464ef03079cb0462fd69606a79990c95b3f0d8d 100644 (file)
@@ -50,14 +50,14 @@ static NTSTATUS remote_op_bind(struct dcesrv_call_state *dce_call, const struct
                return status;
        }
 
-       dce_call->conn->private = private;
+       dce_call->context->private = private;
 
        return NT_STATUS_OK;    
 }
 
-static void remote_op_unbind(struct dcesrv_connection *dce_conn, const struct dcesrv_interface *iface)
+static void remote_op_unbind(struct dcesrv_connection_context *context, const struct dcesrv_interface *iface)
 {
-       struct dcesrv_remote_private *private = dce_conn->private;
+       struct dcesrv_remote_private *private = context->private;
 
        dcerpc_pipe_close(private->c_pipe);
 
@@ -67,7 +67,7 @@ static void remote_op_unbind(struct dcesrv_connection *dce_conn, const struct dc
 static NTSTATUS remote_op_ndr_pull(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ndr_pull *pull, void **r)
 {
        NTSTATUS status;
-       const struct dcerpc_interface_table *table = dce_call->conn->iface->private;
+       const struct dcerpc_interface_table *table = dce_call->context->iface->private;
        uint16_t opnum = dce_call->pkt.u.request.opnum;
 
        dce_call->fault_code = 0;
@@ -96,9 +96,9 @@ static NTSTATUS remote_op_ndr_pull(struct dcesrv_call_state *dce_call, TALLOC_CT
 
 static NTSTATUS remote_op_dispatch(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r)
 {
-       struct dcesrv_remote_private *private = dce_call->conn->private;
+       struct dcesrv_remote_private *private = dce_call->context->private;
        uint16_t opnum = dce_call->pkt.u.request.opnum;
-       const struct dcerpc_interface_table *table = dce_call->conn->iface->private;
+       const struct dcerpc_interface_table *table = dce_call->context->iface->private;
        const struct dcerpc_interface_call *call;
        const char *name;
 
@@ -129,7 +129,7 @@ static NTSTATUS remote_op_dispatch(struct dcesrv_call_state *dce_call, TALLOC_CT
 static NTSTATUS remote_op_ndr_push(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ndr_push *push, void *r)
 {
        NTSTATUS status;
-       const struct dcerpc_interface_table *table = dce_call->conn->iface->private;
+       const struct dcerpc_interface_table *table = dce_call->context->iface->private;
        uint16_t opnum = dce_call->pkt.u.request.opnum;
 
         /* unravel the NDR for the packet */
index 92de6fe402393b464d6fa72fc1045c2d6c274bc2..9f0b8d4801c22cba8dbf17f93e6fe4b40948754c 100644 (file)
 #include "lib/ldb/include/ldb.h"
 
 
-/*
-  destroy a general handle. 
-*/
-static void samr_handle_destroy(struct dcesrv_connection *conn, struct dcesrv_handle *h)
-{
-       talloc_free(h->data);
-}
-
 /*
   This is a bad temporary hack until we have at least some kind of schema
   support
@@ -72,14 +64,13 @@ static NTSTATUS samr_Connect(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem
                return NT_STATUS_INVALID_SYSTEM_SERVICE;
        }
 
-       handle = dcesrv_handle_new(dce_call->conn, SAMR_HANDLE_CONNECT);
+       handle = dcesrv_handle_new(dce_call->context, SAMR_HANDLE_CONNECT);
        if (!handle) {
                talloc_free(c_state);
                return NT_STATUS_NO_MEMORY;
        }
 
-       handle->data = c_state;
-       handle->destroy = samr_handle_destroy;
+       handle->data = talloc_steal(handle, c_state);
 
        c_state->access_mask = r->in.access_mask;
        *r->out.connect_handle = handle->wire_handle;
@@ -100,10 +91,7 @@ static NTSTATUS samr_Close(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_c
 
        DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
 
-       /* this causes the parameters samr_XXX_destroy() to be called by
-          the handle destroy code which destroys the state associated
-          with the handle */
-       dcesrv_handle_destroy(dce_call->conn, h);
+       talloc_free(h);
 
        ZERO_STRUCTP(r->out.handle);
 
@@ -327,14 +315,14 @@ static NTSTATUS samr_OpenDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *
        }
        d_state->access_mask = r->in.access_mask;
 
-       h_domain = dcesrv_handle_new(dce_call->conn, SAMR_HANDLE_DOMAIN);
+       h_domain = dcesrv_handle_new(dce_call->context, SAMR_HANDLE_DOMAIN);
        if (!h_domain) {
                talloc_free(d_state);
                return NT_STATUS_NO_MEMORY;
        }
        
-       h_domain->data = d_state;
-       h_domain->destroy = samr_handle_destroy;
+       h_domain->data = talloc_steal(h_domain, d_state);
+
        *r->out.domain_handle = h_domain->wire_handle;
 
        return NT_STATUS_OK;
@@ -579,13 +567,12 @@ static NTSTATUS samr_CreateDomainGroup(struct dcesrv_call_state *dce_call, TALLO
        }
 
        /* create the policy handle */
-       g_handle = dcesrv_handle_new(dce_call->conn, SAMR_HANDLE_GROUP);
+       g_handle = dcesrv_handle_new(dce_call->context, SAMR_HANDLE_GROUP);
        if (!g_handle) {
                return NT_STATUS_NO_MEMORY;
        }
 
-       g_handle->data = a_state;
-       g_handle->destroy = samr_handle_destroy;
+       g_handle->data = talloc_steal(g_handle, a_state);
 
        *r->out.group_handle = g_handle->wire_handle;
        *r->out.rid = rid;      
@@ -862,16 +849,12 @@ static NTSTATUS samr_CreateUser2(struct dcesrv_call_state *dce_call, TALLOC_CTX
        }
 
        /* create the policy handle */
-       u_handle = dcesrv_handle_new(dce_call->conn, SAMR_HANDLE_USER);
+       u_handle = dcesrv_handle_new(dce_call->context, SAMR_HANDLE_USER);
        if (!u_handle) {
                return NT_STATUS_NO_MEMORY;
        }
 
-       u_handle->data = a_state;
-       u_handle->destroy = samr_handle_destroy;
-
-       /* the domain state is in use one more time */
-       
+       u_handle->data = talloc_steal(u_handle, a_state);
 
        *r->out.user_handle = u_handle->wire_handle;
        *r->out.access_granted = 0xf07ff; /* TODO: fix access mask calculations */
@@ -1095,12 +1078,11 @@ static NTSTATUS samr_CreateDomAlias(struct dcesrv_call_state *dce_call, TALLOC_C
        }
 
        /* create the policy handle */
-       a_handle = dcesrv_handle_new(dce_call->conn, SAMR_HANDLE_ALIAS);
+       a_handle = dcesrv_handle_new(dce_call->context, SAMR_HANDLE_ALIAS);
        if (a_handle == NULL)
                return NT_STATUS_NO_MEMORY;
 
-       a_handle->data = a_state;
-       a_handle->destroy = samr_handle_destroy;
+       a_handle->data = talloc_steal(a_handle, a_state);
 
        *r->out.alias_handle = a_handle->wire_handle;
        *r->out.rid = rid;
@@ -1518,13 +1500,12 @@ static NTSTATUS samr_OpenGroup(struct dcesrv_call_state *dce_call, TALLOC_CTX *m
        }
 
        /* create the policy handle */
-       g_handle = dcesrv_handle_new(dce_call->conn, SAMR_HANDLE_GROUP);
+       g_handle = dcesrv_handle_new(dce_call->context, SAMR_HANDLE_GROUP);
        if (!g_handle) {
                return NT_STATUS_NO_MEMORY;
        }
 
-       g_handle->data = a_state;
-       g_handle->destroy = samr_handle_destroy;
+       g_handle->data = talloc_steal(g_handle, a_state);
 
        *r->out.group_handle = g_handle->wire_handle;
 
@@ -1993,13 +1974,12 @@ static NTSTATUS samr_OpenAlias(struct dcesrv_call_state *dce_call, TALLOC_CTX *m
        }
 
        /* create the policy handle */
-       g_handle = dcesrv_handle_new(dce_call->conn, SAMR_HANDLE_ALIAS);
+       g_handle = dcesrv_handle_new(dce_call->context, SAMR_HANDLE_ALIAS);
        if (!g_handle) {
                return NT_STATUS_NO_MEMORY;
        }
 
-       g_handle->data = a_state;
-       g_handle->destroy = samr_handle_destroy;
+       g_handle->data = talloc_steal(g_handle, a_state);
 
        *r->out.alias_handle = g_handle->wire_handle;
 
@@ -2426,13 +2406,12 @@ static NTSTATUS samr_OpenUser(struct dcesrv_call_state *dce_call, TALLOC_CTX *me
        }
 
        /* create the policy handle */
-       u_handle = dcesrv_handle_new(dce_call->conn, SAMR_HANDLE_USER);
+       u_handle = dcesrv_handle_new(dce_call->context, SAMR_HANDLE_USER);
        if (!u_handle) {
                return NT_STATUS_NO_MEMORY;
        }
 
-       u_handle->data = a_state;
-       u_handle->destroy = samr_handle_destroy;
+       u_handle->data = talloc_steal(u_handle, a_state);
 
        *r->out.user_handle = u_handle->wire_handle;
 
index 25210913feffe81cd07225175ad59f7a5131ad37..ff0a5641b7e322e8037c59859f5dd19681d5e45a 100644 (file)
@@ -186,26 +186,6 @@ static WERROR spoolss_EnumPrinters(struct dcesrv_call_state *dce_call, TALLOC_CT
 }
 
 
-/*
-  destroy connection state
-*/
-static void spoolss_OpenPrinter_close(struct spoolss_openprinter_state *c_state)
-{
-       c_state->reference_count--;
-       if (c_state->reference_count == 0) {
-               talloc_destroy(c_state->mem_ctx);
-       }
-}
-
-/*
-  destroy an open connection. This closes the database connection
-*/
-static void spoolss_OpenPrinter_destroy(struct dcesrv_connection *conn, struct dcesrv_handle *h)
-{
-       struct spoolss_openprinter_state *c_state = h->data;
-       spoolss_OpenPrinter_close(c_state);
-}
-
 /* 
   spoolss_OpenPrinter 
 */
@@ -498,10 +478,7 @@ static WERROR spoolss_ClosePrinter(struct dcesrv_call_state *dce_call, TALLOC_CT
 
        DCESRV_PULL_HANDLE_WERR(h, r->in.handle, DCESRV_HANDLE_ANY);
 
-       /* this causes the callback s_XXX_destroy() to be called by
-          the handle destroy code which destroys the state associated
-          with the handle */
-       dcesrv_handle_destroy(dce_call->conn, h);
+       talloc_free(h);
 
        ZERO_STRUCTP(r->out.handle);
 
@@ -905,34 +882,24 @@ static WERROR spoolss_OpenPrinterEx_server(struct dcesrv_call_state *dce_call,
 {
        struct spoolss_openprinter_state *state;
        struct dcesrv_handle *handle;
-       TALLOC_CTX *op_mem_ctx;
 
        /* Check printername is our name */
 
        if (!strequal(r->in.printername + 2, lp_netbios_name()))
                return WERR_INVALID_PRINTER_NAME;
 
-       op_mem_ctx = talloc_init("spoolss_OpenPrinter");
-       if (!op_mem_ctx) {
-               return WERR_OK;
+       handle = dcesrv_handle_new(dce_call->context, SPOOLSS_HANDLE_SERVER);
+       if (!handle) {
+               return WERR_NOMEM;
        }
 
-       state = talloc_p(op_mem_ctx, struct spoolss_openprinter_state);
+       state = talloc_p(handle, struct spoolss_openprinter_state);
        if (!state) {
                return WERR_OK;
        }
-       state->mem_ctx = op_mem_ctx;
-
-       handle = dcesrv_handle_new(dce_call->conn, SPOOLSS_HANDLE_SERVER);
-       if (!handle) {
-               talloc_destroy(state->mem_ctx);
-               return WERR_NOMEM;
-       }
 
        handle->data = state;
-       handle->destroy = spoolss_OpenPrinter_destroy;
 
-       state->reference_count = 1;
        state->access_mask = r->in.access_mask;
        *r->out.handle = handle->wire_handle;
 
index 950c765a72d6350cb4c5749b1fc0f431fc3849da..aef13dd6d6f22552fb80a3a8c30d03d5e499cbc4 100644 (file)
@@ -32,8 +32,6 @@ enum spoolss_handle {
   state asscoiated with a spoolss_OpenPrinter{,Ex}() operation
 */
 struct spoolss_openprinter_state {
-       int reference_count;
        void *openprinter_ctx;
-       TALLOC_CTX *mem_ctx;
        uint32_t access_mask;
 };
index 56e5c427cc675a9512d621cc8209d4be6d306019..58bee5e18b41b2b696fda0dfb7d7022a8f9f41ce 100644 (file)
@@ -33,7 +33,7 @@ static NTSTATUS dcerpc_winreg_bind(struct dcesrv_call_state *dce_call, const str
        struct registry_context *ctx;
        reg_open_local(&ctx);
 
-       dce_call->conn->private = ctx;
+       dce_call->context->private = ctx;
 
        return NT_STATUS_OK;
 }
@@ -42,11 +42,11 @@ static NTSTATUS dcerpc_winreg_bind(struct dcesrv_call_state *dce_call, const str
 
 static WERROR winreg_openhive (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, uint32_t hkey, struct policy_handle **outh)
 {
-       struct registry_context *ctx = dce_call->conn->private;
+       struct registry_context *ctx = dce_call->context->private;
        struct dcesrv_handle *h; 
        WERROR error;
 
-       h = dcesrv_handle_new(dce_call->conn, HTYPE_REGKEY); 
+       h = dcesrv_handle_new(dce_call->context, HTYPE_REGKEY); 
 
        error = reg_get_predefined_key(ctx, hkey, (struct registry_key **)&h->data);
        if (!W_ERROR_IS_OK(error)) {
@@ -77,14 +77,13 @@ func_winreg_OpenHive(HKPN,HKEY_PERFORMANCE_NLSTEXT)
   winreg_CloseKey 
 */
 static WERROR winreg_CloseKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
-                      struct winreg_CloseKey *r)
+                             struct winreg_CloseKey *r)
 {
        struct dcesrv_handle *h; 
 
-       h = dcesrv_handle_fetch(dce_call->conn, r->in.handle, HTYPE_REGKEY);
-       DCESRV_CHECK_HANDLE(h);
+       DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
 
-       dcesrv_handle_destroy(dce_call->conn, h);
+       talloc_free(h);
 
        return WERR_OK;
 }
@@ -94,25 +93,23 @@ static WERROR winreg_CloseKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *me
   winreg_CreateKey 
 */
 static WERROR winreg_CreateKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
-                      struct winreg_CreateKey *r)
+                              struct winreg_CreateKey *r)
 {
        struct dcesrv_handle *h, *newh;
        WERROR error;
 
-       h = dcesrv_handle_fetch(dce_call->conn, r->in.handle, HTYPE_REGKEY);
-       DCESRV_CHECK_HANDLE(h);
+       DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
        
-       newh = dcesrv_handle_new(dce_call->conn, HTYPE_REGKEY);
+       newh = dcesrv_handle_new(dce_call->context, HTYPE_REGKEY);
 
        error = reg_key_add_name(newh, (struct registry_key *)h->data, r->in.key.name, 
-                                                        r->in.access_mask, 
-                                                        r->in.sec_desc?r->in.sec_desc->sd:NULL, 
-                                                        (struct registry_key **)&newh->data);
-
-       if(W_ERROR_IS_OK(error)) {
+                                r->in.access_mask, 
+                                r->in.sec_desc?r->in.sec_desc->sd:NULL, 
+                                (struct registry_key **)&newh->data);
+       if (W_ERROR_IS_OK(error)) {
                r->out.handle = &newh->wire_handle;
        } else {
-               dcesrv_handle_destroy(dce_call->conn, newh);
+               talloc_free(newh);
        }
 
        return error;
@@ -128,8 +125,7 @@ static WERROR winreg_DeleteKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *m
        struct dcesrv_handle *h;
        WERROR result;
 
-       h = dcesrv_handle_fetch(dce_call->conn, r->in.handle, HTYPE_REGKEY);
-       DCESRV_CHECK_HANDLE(h);
+       DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
 
        if (W_ERROR_IS_OK(result)) {
                return reg_key_del((struct registry_key *)h->data, r->in.key.name);
@@ -148,8 +144,7 @@ static WERROR winreg_DeleteValue(struct dcesrv_call_state *dce_call, TALLOC_CTX
        struct dcesrv_handle *h;
        struct registry_key *key;
 
-       h = dcesrv_handle_fetch(dce_call->conn, r->in.handle, HTYPE_REGKEY);
-       DCESRV_CHECK_HANDLE(h);
+       DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
 
        key = h->data;
        
@@ -166,8 +161,7 @@ static WERROR winreg_EnumKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem
        struct dcesrv_handle *h;
        struct registry_key *key;
 
-       h = dcesrv_handle_fetch(dce_call->conn, r->in.handle, HTYPE_REGKEY);
-       DCESRV_CHECK_HANDLE(h);
+       DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
 
        r->out.result = reg_key_get_subkey_by_index(mem_ctx, (struct registry_key *)h->data, r->in.enum_index, &key);
 
@@ -194,8 +188,7 @@ static WERROR winreg_EnumValue(struct dcesrv_call_state *dce_call, TALLOC_CTX *m
        struct registry_value *value;
        WERROR result;
 
-       h = dcesrv_handle_fetch(dce_call->conn, r->in.handle, HTYPE_REGKEY);
-       DCESRV_CHECK_HANDLE(h);
+       DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
 
        key = h->data;
 
@@ -224,8 +217,7 @@ static WERROR winreg_FlushKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *me
 {
        struct dcesrv_handle *h;
 
-       h = dcesrv_handle_fetch(dce_call->conn, r->in.handle, HTYPE_REGKEY);
-       DCESRV_CHECK_HANDLE(h);
+       DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
 
        return reg_key_flush(h->data);
 }
@@ -239,8 +231,7 @@ static WERROR winreg_GetKeySecurity(struct dcesrv_call_state *dce_call, TALLOC_C
 {
        struct dcesrv_handle *h;
 
-       h = dcesrv_handle_fetch(dce_call->conn, r->in.handle, HTYPE_REGKEY);
-       DCESRV_CHECK_HANDLE(h);
+       DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
 
        return WERR_NOT_SUPPORTED;
 }
@@ -275,18 +266,17 @@ static WERROR winreg_OpenKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem
        struct dcesrv_handle *h, *newh;
        WERROR result;
 
-       h = dcesrv_handle_fetch(dce_call->conn, r->in.handle, HTYPE_REGKEY);
-       DCESRV_CHECK_HANDLE(h);
+       DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
 
-       newh = dcesrv_handle_new(dce_call->conn, HTYPE_REGKEY);
+       newh = dcesrv_handle_new(dce_call->context, HTYPE_REGKEY);
 
        result = reg_open_key(newh, (struct registry_key *)h->data, 
-                               r->in.keyname.name, (struct registry_key **)&newh->data);
+                             r->in.keyname.name, (struct registry_key **)&newh->data);
 
        if (W_ERROR_IS_OK(result)) {
                r->out.handle = &newh->wire_handle; 
        } else {
-               dcesrv_handle_destroy(dce_call->conn, newh);
+               talloc_free(newh);
        }
        
        return result;
@@ -303,8 +293,8 @@ static WERROR winreg_QueryInfoKey(struct dcesrv_call_state *dce_call, TALLOC_CTX
        struct registry_key *k;
        WERROR ret;
 
-       h = dcesrv_handle_fetch(dce_call->conn, r->in.handle, HTYPE_REGKEY);
-       DCESRV_CHECK_HANDLE(h);
+       DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
+
        k = h->data;
 
        ret = reg_key_num_subkeys(k, &r->out.num_subkeys);
@@ -349,8 +339,7 @@ static WERROR winreg_QueryValue(struct dcesrv_call_state *dce_call, TALLOC_CTX *
        struct registry_value *val;
        WERROR result;
 
-       h = dcesrv_handle_fetch(dce_call->conn, r->in.handle, HTYPE_REGKEY);
-       DCESRV_CHECK_HANDLE(h);
+       DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
 
        key = h->data;
        
@@ -425,8 +414,7 @@ static WERROR winreg_SetValue(struct dcesrv_call_state *dce_call, TALLOC_CTX *me
        struct registry_key *key;
        WERROR result;
 
-       h = dcesrv_handle_fetch(dce_call->conn, r->in.handle, HTYPE_REGKEY);
-       DCESRV_CHECK_HANDLE(h);
+       DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
 
        key = h->data;