/* * 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 . */ #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; icount; 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; isyntax_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; isyntax_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; }