#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
struct dcesrv_context;
struct dcesrv_interface;
struct dcesrv_connection;
+struct dcesrv_connection_context;
struct dcesrv_endpoint;
struct dcesrv_call_state;
struct dcesrv_auth;
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)
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
*/
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) {
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;
}
(*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;
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) {
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;
}
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 = "";
}
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;
}
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;
}
/* 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);
}
}
/* 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);
}
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);
}
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;
}
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);
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.
*/
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;
/* 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 */
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 {
/* 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;
/* 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 */
#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
*/
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);
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;
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);
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;
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;
}
#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 &&
};
-/*
- 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
*/
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);
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;
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;
return status;
}
- dce_call->conn->private = state;
+ dce_call->context->private = state;
return NT_STATUS_OK;
}
*/
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 &&
}
/* 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
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);
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;
}
*r->out.credentials = pipe_state->server_challenge;
- dce_call->conn->private = pipe_state;
+ dce_call->context->private = pipe_state;
return NT_STATUS_OK;
}
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;
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;
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;
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;
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) {
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 };
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);
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;
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;
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 */
#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
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;
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);
}
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;
}
/* 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;
}
/* 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 */
}
/* 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;
}
/* 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;
}
/* 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;
}
/* 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;
}
-/*
- 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
*/
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);
{
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;
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;
};
struct registry_context *ctx;
reg_open_local(&ctx);
- dce_call->conn->private = ctx;
+ dce_call->context->private = ctx;
return NT_STATUS_OK;
}
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)) {
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;
}
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;
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);
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;
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);
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;
{
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);
}
{
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;
}
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;
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);
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;
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;