*/
#include "includes.h"
-#include "../libcli/auth/libcli_auth.h"
#include "librpc/gen_ndr/cli_epmapper.h"
#include "../librpc/gen_ndr/ndr_schannel.h"
#include "../libcli/auth/schannel.h"
-#include "../libcli/auth/schannel_proto.h"
#include "../libcli/auth/spnego.h"
+#include "smb_krb5.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_RPC_CLI
-/*******************************************************************
-interface/version dce/rpc pipe identification
-********************************************************************/
-
-#define PIPE_SRVSVC "\\PIPE\\srvsvc"
-#define PIPE_SAMR "\\PIPE\\samr"
-#define PIPE_WINREG "\\PIPE\\winreg"
-#define PIPE_WKSSVC "\\PIPE\\wkssvc"
-#define PIPE_NETLOGON "\\PIPE\\NETLOGON"
-#define PIPE_NTLSA "\\PIPE\\ntlsa"
-#define PIPE_NTSVCS "\\PIPE\\ntsvcs"
-#define PIPE_LSASS "\\PIPE\\lsass"
-#define PIPE_LSARPC "\\PIPE\\lsarpc"
-#define PIPE_SPOOLSS "\\PIPE\\spoolss"
-#define PIPE_NETDFS "\\PIPE\\netdfs"
-#define PIPE_ECHO "\\PIPE\\rpcecho"
-#define PIPE_SHUTDOWN "\\PIPE\\initshutdown"
-#define PIPE_EPM "\\PIPE\\epmapper"
-#define PIPE_SVCCTL "\\PIPE\\svcctl"
-#define PIPE_EVENTLOG "\\PIPE\\eventlog"
-#define PIPE_EPMAPPER "\\PIPE\\epmapper"
-#define PIPE_DRSUAPI "\\PIPE\\drsuapi"
+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;
-/*
- * IMPORTANT!! If you update this structure, make sure to
- * update the index #defines in smb.h.
- */
+ for (i=0; i<ep->count; i++) {
+ if (strncmp(ep->names[i], "ncacn_np:[\\pipe\\", 16) == 0) {
+ break;
+ }
+ }
+ if (i == ep->count) {
+ return NULL;
+ }
-static const struct pipe_id_info {
- /* the names appear not to matter: the syntaxes _do_ matter */
+ /*
+ * 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;
- const char *client_pipe;
- const struct ndr_syntax_id *abstr_syntax; /* this one is the abstract syntax id */
-} pipe_names [] =
+bool smb_register_ndr_interface(const struct ndr_interface_table *interface)
{
- { PIPE_LSARPC, &ndr_table_lsarpc.syntax_id },
- { PIPE_LSARPC, &ndr_table_dssetup.syntax_id },
- { PIPE_SAMR, &ndr_table_samr.syntax_id },
- { PIPE_NETLOGON, &ndr_table_netlogon.syntax_id },
- { PIPE_SRVSVC, &ndr_table_srvsvc.syntax_id },
- { PIPE_WKSSVC, &ndr_table_wkssvc.syntax_id },
- { PIPE_WINREG, &ndr_table_winreg.syntax_id },
- { PIPE_SPOOLSS, &ndr_table_spoolss.syntax_id },
- { PIPE_NETDFS, &ndr_table_netdfs.syntax_id },
- { PIPE_ECHO, &ndr_table_rpcecho.syntax_id },
- { PIPE_SHUTDOWN, &ndr_table_initshutdown.syntax_id },
- { PIPE_SVCCTL, &ndr_table_svcctl.syntax_id },
- { PIPE_EVENTLOG, &ndr_table_eventlog.syntax_id },
- { PIPE_NTSVCS, &ndr_table_ntsvcs.syntax_id },
- { PIPE_EPMAPPER, &ndr_table_epmapper.syntax_id },
- { PIPE_DRSUAPI, &ndr_table_drsuapi.syntax_id },
- { NULL, NULL }
-};
+ 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_iface(const struct ndr_syntax_id *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;
- int i;
- for (i = 0; pipe_names[i].client_pipe; i++) {
- if (ndr_syntax_id_equal(pipe_names[i].abstr_syntax,
- interface)) {
- return &pipe_names[i].client_pipe[5];
+
+ interface = get_iface_from_syntax(syntax);
+ if (interface != NULL) {
+ result = get_pipe_name_from_iface(mem_ctx, interface);
+ if (result != NULL) {
+ return result;
}
}
* interested in the known pipes mentioned in pipe_names[]
*/
- guid_str = GUID_string(talloc_tos(), &interface->uuid);
+ guid_str = GUID_string(talloc_tos(), &syntax->uuid);
if (guid_str == NULL) {
return NULL;
}
- result = talloc_asprintf(talloc_tos(), "Interface %s.%d", guid_str,
- (int)interface->if_version);
+ result = talloc_asprintf(mem_ctx, "Interface %s.%d", guid_str,
+ (int)syntax->if_version);
TALLOC_FREE(guid_str);
if (result == NULL) {
return 0;
}
-NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
+static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
enum pipe_auth_type auth_type,
enum dcerpc_AuthLevel auth_level,
const char *domain,
}
#endif
-NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
+static NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
enum dcerpc_AuthLevel auth_level,
const char *service_princ,
const char *username,
NTSTATUS status;
uint16_t port = 0;
- *presult = NULL;
-
status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
if (!NT_STATUS_IS_OK(status)) {
- goto done;
+ return status;
}
- status = rpc_pipe_open_tcp_port(mem_ctx, host, port,
+ return rpc_pipe_open_tcp_port(mem_ctx, host, port,
abstract_syntax, presult);
-
-done:
- return status;
}
/********************************************************************
}
DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
"%s failed with error %s\n",
- get_pipe_name_from_iface(interface),
+ get_pipe_name_from_syntax(talloc_tos(), interface),
nt_errstr(status) ));
TALLOC_FREE(result);
return status;
DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
"%s and bound anonymously.\n",
- get_pipe_name_from_iface(interface), cli->desthost));
+ get_pipe_name_from_syntax(talloc_tos(), interface),
+ cli->desthost));
*presult = result;
return NT_STATUS_OK;
DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
"machine %s and bound NTLMSSP as user %s\\%s.\n",
- get_pipe_name_from_iface(interface), cli->desthost, domain,
- username ));
+ get_pipe_name_from_syntax(talloc_tos(), interface),
+ cli->desthost, domain, username ));
*presult = result;
return NT_STATUS_OK;
DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
"for domain %s and bound using schannel.\n",
- get_pipe_name_from_iface(interface),
+ get_pipe_name_from_syntax(talloc_tos(), interface),
cli->desthost, domain ));
*presult = result;
*presult = result;
}
- return NT_STATUS_OK;
+ return status;
}
/****************************************************************************