From 6f12e4ace1609fbf00d42226134b1dbb259f38bc Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 16 Dec 2003 09:50:49 +0000 Subject: it turns out that a wire policy handle isn't a blob either, its a uint32 followed by a GUID. I needed to fix this to support running in mixed-mode rpc (where smbtorture is bigendian and w2k3 is little-endian). Otherwise when you send back a policy handle the server doesn't recognise it. (This used to be commit 9b1c76a8e9e953e051072441f8938ee17a674d35) --- source4/lib/util_uuid.c | 26 ++++++++++++++++++++++++++ source4/librpc/idl/misc.idl | 6 +++--- source4/rpc_server/dcerpc_server.c | 1 - source4/rpc_server/dcerpc_server.h | 1 - source4/rpc_server/handles.c | 20 ++++++++++---------- 5 files changed, 39 insertions(+), 15 deletions(-) diff --git a/source4/lib/util_uuid.c b/source4/lib/util_uuid.c index 0c607fb823..c7858aae72 100644 --- a/source4/lib/util_uuid.c +++ b/source4/lib/util_uuid.c @@ -28,3 +28,29 @@ void uuid_generate_random(struct GUID *out) out->clock_seq[0] = (out->clock_seq[0] & 0x3F) | 0x80; out->time_hi_and_version = (out->time_hi_and_version & 0x0FFF) | 0x4000; } + +BOOL uuid_all_zero(const struct GUID *u) +{ + if (u->time_low != 0 || + u->time_mid != 0 || + u->time_hi_and_version != 0 || + u->clock_seq[0] != 0 || + u->clock_seq[1] != 0 || + !all_zero(u->node, 6)) { + return False; + } + return True; +} + +BOOL uuid_equal(const struct GUID *u1, const struct GUID *u2) +{ + if (u1->time_low != u2->time_low || + u1->time_mid != u2->time_mid || + u1->time_hi_and_version != u2->time_hi_and_version || + u1->clock_seq[0] != u2->clock_seq[0] || + u1->clock_seq[1] != u2->clock_seq[1] || + memcmp(u1->node, u2->node, 6) != 0) { + return False; + } + return True; +} diff --git a/source4/librpc/idl/misc.idl b/source4/librpc/idl/misc.idl index a1f8549eaa..e6b1772284 100644 --- a/source4/librpc/idl/misc.idl +++ b/source4/librpc/idl/misc.idl @@ -58,11 +58,11 @@ interface misc [relative] security_acl *dacl; /* user (discretionary) ACL */ } security_descriptor; - typedef [public, flag(NDR_PAHEX)] struct { - uint8 data[20]; + typedef [public] struct { + uint32 handle_type; + GUID uuid; } policy_handle; - /* a 4 byte aligned 64-bit integer */ typedef [public] struct { uint32 low; diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 5780de0c30..081b5b1d5a 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -128,7 +128,6 @@ NTSTATUS dcesrv_endpoint_connect_ops(struct dcesrv_context *dce, (*p)->ndr = NULL; (*p)->dispatch = NULL; (*p)->handles = NULL; - (*p)->next_handle = 0; (*p)->partial_input = data_blob(NULL, 0); (*p)->auth_state.ntlmssp_state = NULL; (*p)->auth_state.auth_info = NULL; diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index e731a5719c..8481372d55 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -108,7 +108,6 @@ struct dcesrv_state { /* current rpc handles - this is really the wrong scope for them, but it will do for now */ - uint32 next_handle; struct dcesrv_handle *handles; DATA_BLOB partial_input; diff --git a/source4/rpc_server/handles.c b/source4/rpc_server/handles.c index 6b7d422267..df7745f6da 100644 --- a/source4/rpc_server/handles.c +++ b/source4/rpc_server/handles.c @@ -43,15 +43,9 @@ struct dcesrv_handle *dcesrv_handle_new(struct dcesrv_state *dce, h->mem_ctx = mem_ctx; h->data = NULL; - memset(h->wire_handle.data, 'H', sizeof(h->wire_handle.data)); - strncpy(h->wire_handle.data, dce->ndr->name, 11); - h->wire_handle.data[11] = handle_type; + h->wire_handle.handle_type = handle_type; + uuid_generate_random(&h->wire_handle.uuid); - /* TODO: check for wraparound here */ - SIVAL(&h->wire_handle.data, 12, random()); - dce->next_handle++; - SIVAL(&h->wire_handle.data, 16, dce->next_handle); - DLIST_ADD(dce->handles, h); return h; @@ -78,12 +72,18 @@ struct dcesrv_handle *dcesrv_handle_fetch(struct dcesrv_state *dce, { struct dcesrv_handle *h; - if (all_zero(p->data, sizeof(p->data))) { + if (p->handle_type == 0 && uuid_all_zero(&p->uuid)) { return dcesrv_handle_new(dce, handle_type); } for (h=dce->handles; h; h=h->next) { - if (memcmp(h->wire_handle.data, p->data, sizeof(p->data)) == 0) { + if (h->wire_handle.handle_type == p->handle_type && + uuid_equal(&p->uuid, &h->wire_handle.uuid)) { + if (p->handle_type != handle_type) { + DEBUG(0,("client gave us the wrong handle type (%d should be %d)\n", + p->handle_type, handle_type)); + return NULL; + } return h; } } -- cgit