The branch, master has been updated via 175b8e1 s4:rpc_server: remember the hdr_signing negotiation result in dcesrv_auth via c4726e4 s4:rpc_server: use talloc_zero for struct dcesrv_connection via 79996cd s4:rpc_server: remove unused DCESRV_CALL_STATE_FLAG_HEADER_SIGNING via 410c30f ndrdump: dump verification trailer via 0f3848a librpc/ndr: add ndr_pop_dcerpc_sec_verification_trailer() via b7a5380 librpc/rpc: simplify tevent_req_nterror() usage in binding_handle.c via 0e62f32 libcli/auth: fix usage of an uninitialized variable in netlogon_creds_cli_check_caps() from f8363dd crypto: fix build on OS X
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 175b8e1475c45a6a829941127f018197baec3909 Author: Stefan Metzmacher <me...@samba.org> Date: Wed Jan 8 10:57:44 2014 +0100 s4:rpc_server: remember the hdr_signing negotiation result in dcesrv_auth Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> Autobuild-User(master): Stefan Metzmacher <me...@samba.org> Autobuild-Date(master): Wed Jan 8 18:37:22 CET 2014 on sn-devel-104 commit c4726e414de13060bca29882f900d6df6d008792 Author: Stefan Metzmacher <me...@samba.org> Date: Wed Jan 8 10:57:19 2014 +0100 s4:rpc_server: use talloc_zero for struct dcesrv_connection Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit 79996cd1eb4855fbb780c10ff96cfab1c5e7c312 Author: Stefan Metzmacher <me...@samba.org> Date: Wed Jan 8 10:52:51 2014 +0100 s4:rpc_server: remove unused DCESRV_CALL_STATE_FLAG_HEADER_SIGNING Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit 410c30f12374b13854378f1d0fecaed9b5112bbb Author: Gregor Beck <gb...@sernet.de> Date: Mon Jan 6 11:19:04 2014 +0100 ndrdump: dump verification trailer Pair-Programmed-With: Stefan Metzmacher <me...@samba.org> Signed-off-by: Gregor Beck <gb...@sernet.de> Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit 0f3848a8632d6f6c113d128e71171dc49f4f74b9 Author: Gregor Beck <gb...@sernet.de> Date: Thu Jan 2 15:30:52 2014 +0100 librpc/ndr: add ndr_pop_dcerpc_sec_verification_trailer() This extracts the dcerpc_sec_verification_trailer from the end of an ndr_pull structure, it found it reduces ndr->data_size. NDR_ERR_ALLOC is the only possible error, all other errors are ignored and a trailer with command count = 0 is returned. Pair-Programmed-With: Gregor Beck <gb...@sernet.de> Signed-off-by: Gregor Beck <gb...@sernet.de> Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit b7a53803f3e5596329688ad8186bb0287705821f Author: Stefan Metzmacher <me...@samba.org> Date: Fri Aug 30 09:48:06 2013 +0200 librpc/rpc: simplify tevent_req_nterror() usage in binding_handle.c Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit 0e62f3279525ea864590f713f334f4dc5f5d3a32 Author: Stefan Metzmacher <me...@samba.org> Date: Wed Jan 8 12:04:22 2014 +0100 libcli/auth: fix usage of an uninitialized variable in netlogon_creds_cli_check_caps() If status is RPC_PROCNUM_OUT_OF_RANGE, result might be uninitialized. Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> Reviewed-by: Günther Deschner <g...@samba.org> ----------------------------------------------------------------------- Summary of changes: libcli/auth/netlogon_creds_cli.c | 4 +- librpc/idl/dcerpc.idl | 3 + librpc/ndr/ndr_dcerpc.c | 121 +++++++++++++++++++++ libcli/auth/schannel.h => librpc/ndr/ndr_dcerpc.h | 12 +- librpc/rpc/binding_handle.c | 9 +- librpc/tools/ndrdump.c | 21 ++++ librpc/tools/wscript_build | 2 +- librpc/wscript_build | 4 +- source4/rpc_server/dcerpc_server.c | 14 +--- source4/rpc_server/dcerpc_server.h | 3 +- source4/rpc_server/dcesrv_auth.c | 5 +- 11 files changed, 165 insertions(+), 33 deletions(-) copy libcli/auth/schannel.h => librpc/ndr/ndr_dcerpc.h (70%) Changeset truncated at 500 lines: diff --git a/libcli/auth/netlogon_creds_cli.c b/libcli/auth/netlogon_creds_cli.c index 1724064..51b30a1 100644 --- a/libcli/auth/netlogon_creds_cli.c +++ b/libcli/auth/netlogon_creds_cli.c @@ -1390,7 +1390,7 @@ struct netlogon_creds_cli_check_state { }; static void netlogon_creds_cli_check_cleanup(struct tevent_req *req, - NTSTATUS status); + NTSTATUS status); static void netlogon_creds_cli_check_locked(struct tevent_req *subreq); struct tevent_req *netlogon_creds_cli_check_send(TALLOC_CTX *mem_ctx, @@ -1582,7 +1582,7 @@ static void netlogon_creds_cli_check_caps(struct tevent_req *subreq) * with the next request as the sequence number processing * gets out of sync. */ - netlogon_creds_cli_check_cleanup(req, result); + netlogon_creds_cli_check_cleanup(req, status); tevent_req_done(req); return; } diff --git a/librpc/idl/dcerpc.idl b/librpc/idl/dcerpc.idl index 276ddd8..32f9514 100644 --- a/librpc/idl/dcerpc.idl +++ b/librpc/idl/dcerpc.idl @@ -21,6 +21,9 @@ import "misc.idl"; cpp_quote("extern const uint8_t DCERPC_SEC_VT_MAGIC[8];") +[ + helper("../librpc/ndr/ndr_dcerpc.h") +] interface dcerpc { typedef struct { diff --git a/librpc/ndr/ndr_dcerpc.c b/librpc/ndr/ndr_dcerpc.c index 88a7f38..3cbcef0 100644 --- a/librpc/ndr/ndr_dcerpc.c +++ b/librpc/ndr/ndr_dcerpc.c @@ -24,6 +24,7 @@ #include "bin/default/librpc/gen_ndr/ndr_dcerpc.h" #include "librpc/gen_ndr/ndr_misc.h" +#include "lib/util/bitmap.h" const uint8_t DCERPC_SEC_VT_MAGIC[] = {0x8a,0xe3,0x13,0x71,0x02,0xf4,0x36,0x71}; @@ -64,3 +65,123 @@ _PUBLIC_ enum ndr_err_code ndr_pull_dcerpc_sec_vt_count(struct ndr_pull *ndr, in ndr->offset = _saved_ofs; return NDR_ERR_SUCCESS; } + +_PUBLIC_ enum ndr_err_code ndr_pop_dcerpc_sec_verification_trailer( + struct ndr_pull *ndr, TALLOC_CTX *mem_ctx, + struct dcerpc_sec_verification_trailer **_r) +{ + enum ndr_err_code ndr_err; + uint32_t ofs; + uint32_t min_ofs = 0; + struct dcerpc_sec_verification_trailer *r; + DATA_BLOB sub_blob = data_blob_null; + struct ndr_pull *sub_ndr = NULL; + uint32_t remaining; + + *_r = NULL; + + r = talloc_zero(mem_ctx, struct dcerpc_sec_verification_trailer); + if (r == NULL) { + return NDR_ERR_ALLOC; + } + + if (ndr->data_size < sizeof(DCERPC_SEC_VT_MAGIC)) { + /* + * we return with r->count = 0 + */ + *_r = r; + return NDR_ERR_SUCCESS; + } + + ofs = ndr->data_size - sizeof(DCERPC_SEC_VT_MAGIC); + /* the magic is 4 byte aligned */ + ofs &= ~3; + + if (ofs > DCERPC_SEC_VT_MAX_SIZE) { + /* + * We just scan the last 1024 bytes. + */ + min_ofs = ofs - DCERPC_SEC_VT_MAX_SIZE; + } else { + min_ofs = 0; + } + + while (true) { + int ret; + + ret = memcmp(&ndr->data[ofs], + DCERPC_SEC_VT_MAGIC, + sizeof(DCERPC_SEC_VT_MAGIC)); + if (ret == 0) { + sub_blob = data_blob_const(&ndr->data[ofs], + ndr->data_size - ofs); + break; + } + + if (ofs <= min_ofs) { + break; + } + + ofs -= 4; + } + + if (sub_blob.length == 0) { + /* + * we return with r->count = 0 + */ + *_r = r; + return NDR_ERR_SUCCESS; + } + + sub_ndr = ndr_pull_init_blob(&sub_blob, r); + if (sub_ndr == NULL) { + TALLOC_FREE(r); + return NDR_ERR_ALLOC; + } + + ndr_err = ndr_pull_dcerpc_sec_verification_trailer(sub_ndr, + NDR_SCALARS | NDR_BUFFERS, + r); + if (ndr_err == NDR_ERR_ALLOC) { + TALLOC_FREE(r); + return NDR_ERR_ALLOC; + } + + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + goto ignore_error; + } + + remaining = sub_ndr->data_size - sub_ndr->offset; + if (remaining > 16) { + /* + * we expect not more than 16 byte of additional + * padding after the verification trailer. + */ + goto ignore_error; + } + + /* + * We assume that we got a real verification trailer. + * + * We remove it from the available stub data. + */ + ndr->data_size = ofs; + + TALLOC_FREE(sub_ndr); + + *_r = r; + return NDR_ERR_SUCCESS; + +ignore_error: + TALLOC_FREE(sub_ndr); + /* + * just ignore the error, it's likely + * that the magic we found belongs to + * the stub data. + * + * we return with r->count = 0 + */ + ZERO_STRUCTP(r); + *_r = r; + return NDR_ERR_SUCCESS; +} diff --git a/libcli/auth/schannel.h b/librpc/ndr/ndr_dcerpc.h similarity index 70% copy from libcli/auth/schannel.h copy to librpc/ndr/ndr_dcerpc.h index c53d68e..f544fb1 100644 --- a/libcli/auth/schannel.h +++ b/librpc/ndr/ndr_dcerpc.h @@ -1,10 +1,10 @@ /* Unix SMB/CIFS implementation. - dcerpc schannel operations + Manually parsed structures found in the DCERPC protocol - Copyright (C) Andrew Tridgell 2004 - Copyright (C) Andrew Bartlett <abart...@samba.org> 2004-2005 + Copyright (C) Stefan Metzmacher 2014 + Copyright (C) Gregor Beck 2014 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 @@ -20,6 +20,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "libcli/auth/libcli_auth.h" -#include "libcli/auth/schannel_state.h" -#include "libcli/auth/schannel_proto.h" +enum ndr_err_code ndr_pop_dcerpc_sec_verification_trailer( + struct ndr_pull *ndr, TALLOC_CTX *mem_ctx, + struct dcerpc_sec_verification_trailer **_r); diff --git a/librpc/rpc/binding_handle.c b/librpc/rpc/binding_handle.c index 1e11b04..ef2b7bd 100644 --- a/librpc/rpc/binding_handle.c +++ b/librpc/rpc/binding_handle.c @@ -180,8 +180,7 @@ static void dcerpc_binding_handle_raw_call_done(struct tevent_req *subreq) &state->out_length, &state->out_flags); TALLOC_FREE(subreq); - if (!NT_STATUS_IS_OK(error)) { - tevent_req_nterror(req, error); + if (tevent_req_nterror(req, error)) { return; } @@ -313,8 +312,7 @@ static void dcerpc_binding_handle_disconnect_done(struct tevent_req *subreq) error = state->ops->disconnect_recv(subreq); TALLOC_FREE(subreq); - if (!NT_STATUS_IS_OK(error)) { - tevent_req_nterror(req, error); + if (tevent_req_nterror(req, error)) { return; } @@ -466,8 +464,7 @@ static void dcerpc_binding_handle_call_done(struct tevent_req *subreq) &state->response.length, &out_flags); TALLOC_FREE(subreq); - if (!NT_STATUS_IS_OK(error)) { - tevent_req_nterror(req, error); + if (tevent_req_nterror(req, error)) { return; } diff --git a/librpc/tools/ndrdump.c b/librpc/tools/ndrdump.c index 02cc47a..f7aac4e 100644 --- a/librpc/tools/ndrdump.c +++ b/librpc/tools/ndrdump.c @@ -23,6 +23,7 @@ #include "system/locale.h" #include "librpc/ndr/libndr.h" #include "librpc/ndr/ndr_table.h" +#include "librpc/gen_ndr/ndr_dcerpc.h" #include "lib/cmdline/popt_common.h" #include "param/param.h" @@ -221,6 +222,7 @@ static NTSTATUS ndrdump_pull_and_print_pipes(const char *function, const struct ndr_interface_call_pipes *in_pipes = NULL; const struct ndr_interface_call_pipes *out_pipes = NULL; uint32_t highest_ofs; + struct dcerpc_sec_verification_trailer *sec_vt = NULL; ndr_table_init(); @@ -400,6 +402,25 @@ static NTSTATUS ndrdump_pull_and_print_pipes(const char *function, ndr_print->print = ndr_print_printf_helper; ndr_print->depth = 1; + ndr_err = ndr_pop_dcerpc_sec_verification_trailer(ndr_pull, mem_ctx, &sec_vt); + status = ndr_map_error2ntstatus(ndr_err); + if (!NT_STATUS_IS_OK(status)) { + printf("ndr_pop_dcerpc_sec_verification_trailer returned %s\n", + nt_errstr(status)); + } + + if (sec_vt != NULL && sec_vt->count.count > 0) { + printf("SEC_VT: consumed %d bytes\n", + (int)(blob.length - ndr_pull->data_size)); + if (dumpdata) { + ndrdump_data(blob.data + ndr_pull->data_size, + blob.length - ndr_pull->data_size, + dumpdata); + } + ndr_print_dcerpc_sec_verification_trailer(ndr_print, "SEC_VT", sec_vt); + } + TALLOC_FREE(sec_vt); + if (out_pipes) { status = ndrdump_pull_and_print_pipes(function, ndr_pull, ndr_print, out_pipes); if (!NT_STATUS_IS_OK(status)) { diff --git a/librpc/tools/wscript_build b/librpc/tools/wscript_build index d1f0a26..a7463a9 100644 --- a/librpc/tools/wscript_build +++ b/librpc/tools/wscript_build @@ -3,5 +3,5 @@ bld.SAMBA_BINARY('ndrdump', source='ndrdump.c', manpages='ndrdump.1', - deps='samba-hostconfig samba-util popt POPT_SAMBA ndr-table errors' + deps='samba-hostconfig samba-util popt POPT_SAMBA ndr-table errors NDR_DCERPC' ) diff --git a/librpc/wscript_build b/librpc/wscript_build index a5cf687..b99ec9e 100644 --- a/librpc/wscript_build +++ b/librpc/wscript_build @@ -303,8 +303,8 @@ bld.SAMBA_SUBSYSTEM('NDR_FSRVP', bld.SAMBA_SUBSYSTEM('NDR_DCERPC', source='gen_ndr/ndr_dcerpc.c ndr/ndr_dcerpc.c', public_deps='ndr', - public_headers='gen_ndr/ndr_dcerpc.h gen_ndr/dcerpc.h', - header_path= [ ('*gen_ndr*', 'gen_ndr') ], + public_headers='gen_ndr/ndr_dcerpc.h gen_ndr/dcerpc.h ndr/ndr_dcerpc.h', + header_path=[ ('gen_ndr*', 'gen_ndr'), ('ndr*', 'ndr')] ) bld.SAMBA_SUBSYSTEM('NDR_DRSUAPI', diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 5ce7339..d82ef9c 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -378,7 +378,7 @@ _PUBLIC_ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, return NT_STATUS_ACCESS_DENIED; } - p = talloc(mem_ctx, struct dcesrv_connection); + p = talloc_zero(mem_ctx, struct dcesrv_connection); NT_STATUS_HAVE_NO_MEMORY(p); if (!talloc_reference(p, session_info)) { @@ -386,27 +386,15 @@ _PUBLIC_ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, return NT_STATUS_NO_MEMORY; } - p->prev = NULL; - p->next = NULL; p->dce_ctx = dce_ctx; p->endpoint = ep; - p->contexts = NULL; - p->call_list = NULL; p->packet_log_dir = lpcfg_lockdir(dce_ctx->lp_ctx); - p->incoming_fragmented_call_list = NULL; - p->pending_call_list = NULL; - p->cli_max_recv_frag = 0; - p->partial_input = data_blob(NULL, 0); - p->auth_state.auth_info = NULL; - p->auth_state.gensec_security = NULL; p->auth_state.session_info = session_info; p->auth_state.session_key = dcesrv_generic_session_key; p->event_ctx = event_ctx; p->msg_ctx = msg_ctx; p->server_id = server_id; - p->terminate = NULL; p->state_flags = state_flags; - ZERO_STRUCT(p->transport); *_p = p; return NT_STATUS_OK; diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index 66fe51e..c5d8632 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -101,7 +101,6 @@ struct dcesrv_call_state { */ #define DCESRV_CALL_STATE_FLAG_ASYNC (1<<0) #define DCESRV_CALL_STATE_FLAG_MAY_ASYNC (1<<1) -#define DCESRV_CALL_STATE_FLAG_HEADER_SIGNING (1<<2) uint32_t state_flags; /* the time the request arrived in the server */ @@ -149,6 +148,8 @@ struct dcesrv_auth { struct gensec_security *gensec_security; struct auth_session_info *session_info; NTSTATUS (*session_key)(struct dcesrv_connection *, DATA_BLOB *session_key); + bool client_hdr_signing; + bool hdr_signing; }; struct dcesrv_connection_context { diff --git a/source4/rpc_server/dcesrv_auth.c b/source4/rpc_server/dcesrv_auth.c index 152715b..7ec0d43 100644 --- a/source4/rpc_server/dcesrv_auth.c +++ b/source4/rpc_server/dcesrv_auth.c @@ -110,6 +110,7 @@ NTSTATUS dcesrv_auth_bind_ack(struct dcesrv_call_state *call, struct ncacn_packe } if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN) { + dce_conn->auth_state.client_hdr_signing = true; want_header_signing = true; } @@ -140,7 +141,7 @@ NTSTATUS dcesrv_auth_bind_ack(struct dcesrv_call_state *call, struct ncacn_packe if (want_header_signing) { gensec_want_feature(dce_conn->auth_state.gensec_security, GENSEC_FEATURE_SIGN_PKT_HEADER); - call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_HEADER_SIGNING; + dce_conn->auth_state.hdr_signing = true; pkt->pfc_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN; } @@ -160,7 +161,7 @@ NTSTATUS dcesrv_auth_bind_ack(struct dcesrv_call_state *call, struct ncacn_packe if (want_header_signing) { gensec_want_feature(dce_conn->auth_state.gensec_security, GENSEC_FEATURE_SIGN_PKT_HEADER); - call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_HEADER_SIGNING; + dce_conn->auth_state.hdr_signing = true; pkt->pfc_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN; } -- Samba Shared Repository