diff options
Diffstat (limited to 'source3/librpc/rpc')
-rw-r--r-- | source3/librpc/rpc/dcerpc.h | 6 | ||||
-rw-r--r-- | source3/librpc/rpc/dcerpc_helpers.c | 36 | ||||
-rw-r--r-- | source3/librpc/rpc/rpc_common.c | 238 |
3 files changed, 272 insertions, 8 deletions
diff --git a/source3/librpc/rpc/dcerpc.h b/source3/librpc/rpc/dcerpc.h index d18920ca0d..bb7bd34de8 100644 --- a/source3/librpc/rpc/dcerpc.h +++ b/source3/librpc/rpc/dcerpc.h @@ -123,7 +123,8 @@ NTSTATUS dcerpc_push_ncacn_packet(TALLOC_CTX *mem_ctx, DATA_BLOB *blob); NTSTATUS dcerpc_pull_ncacn_packet(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, - struct ncacn_packet *r); + struct ncacn_packet *r, + bool bigendian); NTSTATUS dcerpc_push_schannel_bind(TALLOC_CTX *mem_ctx, struct NL_AUTH_MESSAGE *r, DATA_BLOB *blob); @@ -136,6 +137,7 @@ NTSTATUS dcerpc_push_dcerpc_auth(TALLOC_CTX *mem_ctx, DATA_BLOB *blob); NTSTATUS dcerpc_pull_dcerpc_auth(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, - struct dcerpc_auth *r); + struct dcerpc_auth *r, + bool bigendian); #endif /* __DCERPC_H__ */ diff --git a/source3/librpc/rpc/dcerpc_helpers.c b/source3/librpc/rpc/dcerpc_helpers.c index ce48a691ac..5c92a792e9 100644 --- a/source3/librpc/rpc/dcerpc_helpers.c +++ b/source3/librpc/rpc/dcerpc_helpers.c @@ -92,15 +92,27 @@ NTSTATUS dcerpc_push_ncacn_packet(TALLOC_CTX *mem_ctx, */ NTSTATUS dcerpc_pull_ncacn_packet(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, - struct ncacn_packet *r) + struct ncacn_packet *r, + bool bigendian) { enum ndr_err_code ndr_err; + struct ndr_pull *ndr; + + ndr = ndr_pull_init_blob(blob, mem_ctx); + if (!ndr) { + return NT_STATUS_NO_MEMORY; + } + if (bigendian) { + ndr->flags |= LIBNDR_FLAG_BIGENDIAN; + } + + ndr_err = ndr_pull_ncacn_packet(ndr, NDR_SCALARS|NDR_BUFFERS, r); - ndr_err = ndr_pull_struct_blob(blob, mem_ctx, r, - (ndr_pull_flags_fn_t)ndr_pull_ncacn_packet); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(ndr); return ndr_map_error2ntstatus(ndr_err); } + talloc_free(ndr); if (DEBUGLEVEL >= 10) { NDR_PRINT_DEBUG(ncacn_packet, r); @@ -194,15 +206,27 @@ NTSTATUS dcerpc_push_dcerpc_auth(TALLOC_CTX *mem_ctx, */ NTSTATUS dcerpc_pull_dcerpc_auth(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, - struct dcerpc_auth *r) + struct dcerpc_auth *r, + bool bigendian) { enum ndr_err_code ndr_err; + struct ndr_pull *ndr; + + ndr = ndr_pull_init_blob(blob, mem_ctx); + if (!ndr) { + return NT_STATUS_NO_MEMORY; + } + if (bigendian) { + ndr->flags |= LIBNDR_FLAG_BIGENDIAN; + } + + ndr_err = ndr_pull_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, r); - ndr_err = ndr_pull_struct_blob(blob, mem_ctx, r, - (ndr_pull_flags_fn_t)ndr_pull_dcerpc_auth); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(ndr); return ndr_map_error2ntstatus(ndr_err); } + talloc_free(ndr); if (DEBUGLEVEL >= 10) { NDR_PRINT_DEBUG(dcerpc_auth, r); diff --git a/source3/librpc/rpc/rpc_common.c b/source3/librpc/rpc/rpc_common.c new file mode 100644 index 0000000000..78b88f7e33 --- /dev/null +++ b/source3/librpc/rpc/rpc_common.c @@ -0,0 +1,238 @@ +/* + * Unix SMB/CIFS implementation. + * RPC Pipe client / server routines + * Largely rewritten by Jeremy Allison 2005. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include "includes.h" +#include "../librpc/gen_ndr/ndr_schannel.h" +#include "../librpc/gen_ndr/ndr_lsa.h" +#include "../librpc/gen_ndr/ndr_dssetup.h" +#include "../librpc/gen_ndr/ndr_samr.h" +#include "../librpc/gen_ndr/ndr_netlogon.h" +#include "../librpc/gen_ndr/ndr_srvsvc.h" +#include "../librpc/gen_ndr/ndr_wkssvc.h" +#include "../librpc/gen_ndr/ndr_winreg.h" +#include "../librpc/gen_ndr/ndr_spoolss.h" +#include "../librpc/gen_ndr/ndr_dfs.h" +#include "../librpc/gen_ndr/ndr_echo.h" +#include "../librpc/gen_ndr/ndr_initshutdown.h" +#include "../librpc/gen_ndr/ndr_svcctl.h" +#include "../librpc/gen_ndr/ndr_eventlog.h" +#include "../librpc/gen_ndr/ndr_ntsvcs.h" +#include "../librpc/gen_ndr/ndr_epmapper.h" +#include "../librpc/gen_ndr/ndr_drsuapi.h" + +static const char *get_pipe_name_from_iface( + TALLOC_CTX *mem_ctx, const struct ndr_interface_table *interface) +{ + int i; + const struct ndr_interface_string_array *ep = interface->endpoints; + char *p; + + for (i=0; i<ep->count; i++) { + if (strncmp(ep->names[i], "ncacn_np:[\\pipe\\", 16) == 0) { + break; + } + } + if (i == ep->count) { + return NULL; + } + + /* + * extract the pipe name without \\pipe from for example + * ncacn_np:[\\pipe\\epmapper] + */ + p = strchr(ep->names[i]+15, ']'); + if (p == NULL) { + return "PIPE"; + } + return talloc_strndup(mem_ctx, ep->names[i]+15, p - ep->names[i] - 15); +} + +static const struct ndr_interface_table **interfaces; + +bool smb_register_ndr_interface(const struct ndr_interface_table *interface) +{ + int num_interfaces = talloc_array_length(interfaces); + const struct ndr_interface_table **tmp; + int i; + + for (i=0; i<num_interfaces; i++) { + if (ndr_syntax_id_equal(&interfaces[i]->syntax_id, + &interface->syntax_id)) { + return true; + } + } + + tmp = talloc_realloc(NULL, interfaces, + const struct ndr_interface_table *, + num_interfaces + 1); + if (tmp == NULL) { + DEBUG(1, ("smb_register_ndr_interface: talloc failed\n")); + return false; + } + interfaces = tmp; + interfaces[num_interfaces] = interface; + return true; +} + +static bool initialize_interfaces(void) +{ + if (!smb_register_ndr_interface(&ndr_table_lsarpc)) { + return false; + } + if (!smb_register_ndr_interface(&ndr_table_dssetup)) { + return false; + } + if (!smb_register_ndr_interface(&ndr_table_samr)) { + return false; + } + if (!smb_register_ndr_interface(&ndr_table_netlogon)) { + return false; + } + if (!smb_register_ndr_interface(&ndr_table_srvsvc)) { + return false; + } + if (!smb_register_ndr_interface(&ndr_table_wkssvc)) { + return false; + } + if (!smb_register_ndr_interface(&ndr_table_winreg)) { + return false; + } + if (!smb_register_ndr_interface(&ndr_table_spoolss)) { + return false; + } + if (!smb_register_ndr_interface(&ndr_table_netdfs)) { + return false; + } + if (!smb_register_ndr_interface(&ndr_table_rpcecho)) { + return false; + } + if (!smb_register_ndr_interface(&ndr_table_initshutdown)) { + return false; + } + if (!smb_register_ndr_interface(&ndr_table_svcctl)) { + return false; + } + if (!smb_register_ndr_interface(&ndr_table_eventlog)) { + return false; + } + if (!smb_register_ndr_interface(&ndr_table_ntsvcs)) { + return false; + } + if (!smb_register_ndr_interface(&ndr_table_epmapper)) { + return false; + } + if (!smb_register_ndr_interface(&ndr_table_drsuapi)) { + return false; + } + return true; +} + +const struct ndr_interface_table *get_iface_from_syntax( + const struct ndr_syntax_id *syntax) +{ + int num_interfaces; + int i; + + if (interfaces == NULL) { + if (!initialize_interfaces()) { + return NULL; + } + } + num_interfaces = talloc_array_length(interfaces); + + for (i=0; i<num_interfaces; i++) { + if (ndr_syntax_id_equal(&interfaces[i]->syntax_id, syntax)) { + return interfaces[i]; + } + } + + return NULL; +} + +/**************************************************************************** + Return the pipe name from the interface. + ****************************************************************************/ + +const char *get_pipe_name_from_syntax(TALLOC_CTX *mem_ctx, + const struct ndr_syntax_id *syntax) +{ + const struct ndr_interface_table *interface; + char *guid_str; + const char *result; + + interface = get_iface_from_syntax(syntax); + if (interface != NULL) { + result = get_pipe_name_from_iface(mem_ctx, interface); + if (result != NULL) { + return result; + } + } + + /* + * Here we should ask \\epmapper, but for now our code is only + * interested in the known pipes mentioned in pipe_names[] + */ + + guid_str = GUID_string(talloc_tos(), &syntax->uuid); + if (guid_str == NULL) { + return NULL; + } + result = talloc_asprintf(mem_ctx, "Interface %s.%d", guid_str, + (int)syntax->if_version); + TALLOC_FREE(guid_str); + + if (result == NULL) { + return "PIPE"; + } + return result; +} + +/******************************************************************** + Map internal value to wire value. + ********************************************************************/ + +enum dcerpc_AuthType map_pipe_auth_type_to_rpc_auth_type(enum pipe_auth_type auth_type) +{ + switch (auth_type) { + + case PIPE_AUTH_TYPE_NONE: + return DCERPC_AUTH_TYPE_NONE; + + case PIPE_AUTH_TYPE_NTLMSSP: + return DCERPC_AUTH_TYPE_NTLMSSP; + + case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP: + case PIPE_AUTH_TYPE_SPNEGO_KRB5: + return DCERPC_AUTH_TYPE_SPNEGO; + + case PIPE_AUTH_TYPE_SCHANNEL: + return DCERPC_AUTH_TYPE_SCHANNEL; + + case PIPE_AUTH_TYPE_KRB5: + return DCERPC_AUTH_TYPE_KRB5; + + default: + DEBUG(0,("map_pipe_auth_type_to_rpc_type: unknown pipe " + "auth type %u\n", + (unsigned int)auth_type )); + break; + } + return -1; +} + |