summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorAndreas Schneider <asn@samba.org>2010-06-03 22:01:46 +0200
committerSimo Sorce <idra@samba.org>2010-06-04 12:12:43 -0400
commit3344adc3404df47f02f6eb3096cb623ae94850b8 (patch)
tree1bf594f859de7bcd64618cf469d7ec3f59b3753a /source3
parent9097bdddd03f81579699e0d0ce725a7453a3a158 (diff)
downloadsamba-3344adc3404df47f02f6eb3096cb623ae94850b8.tar.gz
samba-3344adc3404df47f02f6eb3096cb623ae94850b8.tar.bz2
samba-3344adc3404df47f02f6eb3096cb623ae94850b8.zip
s3-rpc: Seperate rpc_srv_register for plain connection.
This will make it possible to create plain rpc named pipe connnections. Reviewed-by: Simo Sorce <idra@samba.org>
Diffstat (limited to 'source3')
-rw-r--r--source3/Makefile.in3
-rw-r--r--source3/rpc_server/srv_pipe.c157
-rw-r--r--source3/rpc_server/srv_pipe_internal.h42
-rw-r--r--source3/rpc_server/srv_pipe_register.c200
-rw-r--r--source3/wscript_build3
5 files changed, 276 insertions, 129 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in
index 91e1518e13..19bee48ab9 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -653,8 +653,7 @@ RPC_EVENTLOG_OBJ = rpc_server/srv_eventlog_nt.o \
NPA_TSTREAM_OBJ = ../libcli/named_pipe_auth/npa_tstream.o
-RPC_PIPE_OBJ = rpc_server/srv_pipe_hnd.o \
- rpc_server/srv_pipe.o rpc_server/srv_lsa_hnd.o
+RPC_PIPE_OBJ = rpc_server/srv_pipe.o rpc_server/srv_pipe_hnd.o rpc_server/srv_pipe_register.c
RPC_ECHO_OBJ = rpc_server/srv_echo_nt.o librpc/gen_ndr/srv_echo.o
diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c
index 50914acfbd..fccc41c33a 100644
--- a/source3/rpc_server/srv_pipe.c
+++ b/source3/rpc_server/srv_pipe.c
@@ -28,6 +28,7 @@
*/
#include "includes.h"
+#include "srv_pipe_internal.h"
#include "../librpc/gen_ndr/ndr_schannel.h"
#include "../libcli/auth/schannel.h"
#include "../libcli/auth/spnego.h"
@@ -742,23 +743,6 @@ static bool pipe_ntlmssp_verify_final(pipes_struct *p, DATA_BLOB *p_resp_blob)
}
/*******************************************************************
- The switch table for the pipe names and the functions to handle them.
-*******************************************************************/
-
-struct rpc_table {
- struct {
- const char *clnt;
- const char *srv;
- } pipe;
- struct ndr_syntax_id rpc_interface;
- const struct api_struct *cmds;
- int n_cmds;
-};
-
-static struct rpc_table *rpc_lookup;
-static int rpc_lookup_size;
-
-/*******************************************************************
This is the "stage3" NTLMSSP response after a bind request and reply.
*******************************************************************/
@@ -1044,25 +1028,18 @@ static bool check_bind_req(struct pipes_struct *p,
struct ndr_syntax_id* transfer,
uint32 context_id)
{
- int i=0;
struct pipe_rpc_fns *context_fns;
DEBUG(3,("check_bind_req for %s\n",
get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
/* we have to check all now since win2k introduced a new UUID on the lsaprpc pipe */
-
- for (i=0; i<rpc_lookup_size; i++) {
- DEBUGADD(10, ("checking %s\n", rpc_lookup[i].pipe.clnt));
- if (ndr_syntax_id_equal(
- abstract, &rpc_lookup[i].rpc_interface)
- && ndr_syntax_id_equal(
- transfer, &ndr_transfer_syntax)) {
- break;
- }
- }
-
- if (i == rpc_lookup_size) {
+ if (rpc_srv_pipe_exists_by_id(abstract) &&
+ ndr_syntax_id_equal(transfer, &ndr_transfer_syntax)) {
+ DEBUG(3, ("check_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
+ rpc_srv_get_pipe_cli_name(abstract),
+ rpc_srv_get_pipe_srv_name(abstract)));
+ } else {
return false;
}
@@ -1072,8 +1049,8 @@ static bool check_bind_req(struct pipes_struct *p,
return False;
}
- context_fns->cmds = rpc_lookup[i].cmds;
- context_fns->n_cmds = rpc_lookup[i].n_cmds;
+ context_fns->n_cmds = rpc_srv_get_pipe_num_cmds(abstract);
+ context_fns->cmds = rpc_srv_get_pipe_cmds(abstract);
context_fns->context_id = context_id;
/* add to the list of open contexts */
@@ -1083,59 +1060,6 @@ static bool check_bind_req(struct pipes_struct *p,
return True;
}
-/*******************************************************************
- Register commands to an RPC pipe
-*******************************************************************/
-
-NTSTATUS rpc_srv_register(int version, const char *clnt, const char *srv,
- const struct ndr_interface_table *iface,
- const struct api_struct *cmds, int size)
-{
- struct rpc_table *rpc_entry;
-
- if (!clnt || !srv || !cmds) {
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- if (version != SMB_RPC_INTERFACE_VERSION) {
- DEBUG(0,("Can't register rpc commands!\n"
- "You tried to register a rpc module with SMB_RPC_INTERFACE_VERSION %d"
- ", while this version of samba uses version %d!\n",
- version,SMB_RPC_INTERFACE_VERSION));
- return NT_STATUS_OBJECT_TYPE_MISMATCH;
- }
-
- /* TODO:
- *
- * we still need to make sure that don't register the same commands twice!!!
- *
- * --metze
- */
-
- /* We use a temporary variable because this call can fail and
- rpc_lookup will still be valid afterwards. It could then succeed if
- called again later */
- rpc_lookup_size++;
- rpc_entry = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(rpc_lookup, struct rpc_table, rpc_lookup_size);
- if (NULL == rpc_entry) {
- rpc_lookup_size--;
- DEBUG(0, ("rpc_pipe_register_commands: memory allocation failed\n"));
- return NT_STATUS_NO_MEMORY;
- } else {
- rpc_lookup = rpc_entry;
- }
-
- rpc_entry = rpc_lookup + (rpc_lookup_size - 1);
- ZERO_STRUCTP(rpc_entry);
- rpc_entry->pipe.clnt = SMB_STRDUP(clnt);
- rpc_entry->pipe.srv = SMB_STRDUP(srv);
- rpc_entry->rpc_interface = iface->syntax_id;
- rpc_entry->cmds = cmds;
- rpc_entry->n_cmds = size;
-
- return NT_STATUS_OK;
-}
-
/**
* Is a named pipe known?
* @param[in] cli_filename The pipe name requested by the client
@@ -1144,7 +1068,6 @@ NTSTATUS rpc_srv_register(int version, const char *clnt, const char *srv,
bool is_known_pipename(const char *cli_filename, struct ndr_syntax_id *syntax)
{
const char *pipename = cli_filename;
- int i;
NTSTATUS status;
if (strnequal(pipename, "\\PIPE\\", 6)) {
@@ -1160,11 +1083,8 @@ bool is_known_pipename(const char *cli_filename, struct ndr_syntax_id *syntax)
return false;
}
- for (i=0; i<rpc_lookup_size; i++) {
- if (strequal(pipename, rpc_lookup[i].pipe.clnt)) {
- *syntax = rpc_lookup[i].rpc_interface;
- return true;
- }
+ if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
+ return true;
}
status = smb_probe_module("rpc", pipename);
@@ -1177,12 +1097,8 @@ bool is_known_pipename(const char *cli_filename, struct ndr_syntax_id *syntax)
/*
* Scan the list again for the interface id
*/
-
- for (i=0; i<rpc_lookup_size; i++) {
- if (strequal(pipename, rpc_lookup[i].pipe.clnt)) {
- *syntax = rpc_lookup[i].rpc_interface;
- return true;
- }
+ if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
+ return true;
}
DEBUG(10, ("is_known_pipename: pipe %s did not register itself!\n",
@@ -1664,10 +1580,11 @@ bool api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p)
fstring ack_pipe_name;
prs_struct out_hdr_ba;
prs_struct out_auth;
- int i = 0;
int auth_len = 0;
unsigned int auth_type = DCERPC_AUTH_TYPE_NONE;
uint32_t ss_padding_len = 0;
+ NTSTATUS status;
+ struct ndr_syntax_id id;
/* No rebinds on a bound pipe - use alter context. */
if (p->pipe_bound) {
@@ -1724,19 +1641,12 @@ bool api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p)
* Try and find the correct pipe name to ensure
* that this is a pipe name we support.
*/
-
- for (i = 0; i < rpc_lookup_size; i++) {
- if (ndr_syntax_id_equal(&rpc_lookup[i].rpc_interface,
- &hdr_rb.rpc_context[0].abstract)) {
- DEBUG(3, ("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
- rpc_lookup[i].pipe.clnt, rpc_lookup[i].pipe.srv));
- break;
- }
- }
-
- if (i == rpc_lookup_size) {
- NTSTATUS status;
-
+ id = hdr_rb.rpc_context[0].abstract;
+ if (rpc_srv_pipe_exists_by_id(&id)) {
+ DEBUG(3, ("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
+ rpc_srv_get_pipe_cli_name(&id),
+ rpc_srv_get_pipe_srv_name(&id)));
+ } else {
status = smb_probe_module(
"rpc", get_pipe_name_from_syntax(
talloc_tos(),
@@ -1752,19 +1662,16 @@ bool api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p)
prs_mem_free(&out_auth);
return setup_bind_nak(p);
- }
-
- for (i = 0; i < rpc_lookup_size; i++) {
- if (strequal(rpc_lookup[i].pipe.clnt,
- get_pipe_name_from_syntax(talloc_tos(),
- &p->syntax))) {
- DEBUG(3, ("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
- rpc_lookup[i].pipe.clnt, rpc_lookup[i].pipe.srv));
- break;
- }
- }
-
- if (i == rpc_lookup_size) {
+ }
+
+ if (rpc_srv_get_pipe_interface_by_cli_name(
+ get_pipe_name_from_syntax(talloc_tos(),
+ &p->syntax),
+ &id)) {
+ DEBUG(3, ("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
+ rpc_srv_get_pipe_cli_name(&id),
+ rpc_srv_get_pipe_srv_name(&id)));
+ } else {
DEBUG(0, ("module %s doesn't provide functions for "
"pipe %s!\n",
get_pipe_name_from_syntax(talloc_tos(),
@@ -1777,7 +1684,7 @@ bool api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p)
/* name has to be \PIPE\xxxxx */
fstrcpy(ack_pipe_name, "\\PIPE\\");
- fstrcat(ack_pipe_name, rpc_lookup[i].pipe.srv);
+ fstrcat(ack_pipe_name, rpc_srv_get_pipe_srv_name(&id));
DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__));
diff --git a/source3/rpc_server/srv_pipe_internal.h b/source3/rpc_server/srv_pipe_internal.h
new file mode 100644
index 0000000000..f84c6aad4d
--- /dev/null
+++ b/source3/rpc_server/srv_pipe_internal.h
@@ -0,0 +1,42 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * RPC Pipe client / server routines
+ * Almost completely rewritten by (C) Jeremy Allison 2005 - 2010
+ *
+ * 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/>.
+ */
+
+#ifndef _RPC_PIPE_INTERNAL_H_
+#define _RPC_PIPE_INTERNAL_H_
+
+#include "includes.h"
+
+bool rpc_srv_pipe_exists_by_id(const struct ndr_syntax_id *id);
+
+bool rpc_srv_pipe_exists_by_cli_name(const char *cli_name);
+
+bool rpc_srv_pipe_exists_by_srv_name(const char *srv_name);
+
+const char *rpc_srv_get_pipe_cli_name(const struct ndr_syntax_id *id);
+
+const char *rpc_srv_get_pipe_srv_name(const struct ndr_syntax_id *id);
+
+uint32_t rpc_srv_get_pipe_num_cmds(const struct ndr_syntax_id *id);
+
+const struct api_struct *rpc_srv_get_pipe_cmds(const struct ndr_syntax_id *id);
+
+bool rpc_srv_get_pipe_interface_by_cli_name(const char *cli_name,
+ struct ndr_syntax_id *id);
+
+#endif /* _RPC_PIPE_INTERNAL_H_ */
diff --git a/source3/rpc_server/srv_pipe_register.c b/source3/rpc_server/srv_pipe_register.c
new file mode 100644
index 0000000000..757e4fbe72
--- /dev/null
+++ b/source3/rpc_server/srv_pipe_register.c
@@ -0,0 +1,200 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * RPC Pipe client / server routines
+ * Almost completely rewritten by (C) Jeremy Allison 2005 - 2010
+ *
+ * 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 "srv_pipe_internal.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_RPC_SRV
+
+struct rpc_table {
+ struct {
+ const char *clnt;
+ const char *srv;
+ } pipe;
+ struct ndr_syntax_id rpc_interface;
+ const struct api_struct *cmds;
+ uint32_t n_cmds;
+};
+
+static struct rpc_table *rpc_lookup;
+static uint32_t rpc_lookup_size;
+
+bool rpc_srv_pipe_exists_by_id(const struct ndr_syntax_id *id)
+{
+ uint32_t i;
+
+ for (i = 0; i < rpc_lookup_size; i++) {
+ if (ndr_syntax_id_equal(&rpc_lookup[i].rpc_interface, id)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool rpc_srv_pipe_exists_by_cli_name(const char *cli_name)
+{
+ uint32_t i;
+
+ for (i = 0; i < rpc_lookup_size; i++) {
+ if (strequal(rpc_lookup[i].pipe.clnt, cli_name)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool rpc_srv_pipe_exists_by_srv_name(const char *srv_name)
+{
+ uint32_t i;
+
+ for (i = 0; i < rpc_lookup_size; i++) {
+ if (strequal(rpc_lookup[i].pipe.srv, srv_name)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+const char *rpc_srv_get_pipe_cli_name(const struct ndr_syntax_id *id)
+{
+ uint32_t i;
+
+ for (i = 0; i < rpc_lookup_size; i++) {
+ if (ndr_syntax_id_equal(&rpc_lookup[i].rpc_interface, id)) {
+ return rpc_lookup[i].pipe.clnt;
+ }
+ }
+
+ return NULL;
+}
+
+const char *rpc_srv_get_pipe_srv_name(const struct ndr_syntax_id *id)
+{
+ uint32_t i;
+
+ for (i = 0; i < rpc_lookup_size; i++) {
+ if (ndr_syntax_id_equal(&rpc_lookup[i].rpc_interface, id)) {
+ return rpc_lookup[i].pipe.srv;
+ }
+ }
+
+ return NULL;
+}
+
+uint32_t rpc_srv_get_pipe_num_cmds(const struct ndr_syntax_id *id)
+{
+ uint32_t i;
+
+ for (i = 0; i < rpc_lookup_size; i++) {
+ if (ndr_syntax_id_equal(&rpc_lookup[i].rpc_interface, id)) {
+ return rpc_lookup[i].n_cmds;
+ }
+ }
+
+ return 0;
+}
+
+const struct api_struct *rpc_srv_get_pipe_cmds(const struct ndr_syntax_id *id)
+{
+ uint32_t i;
+
+ for (i = 0; i < rpc_lookup_size; i++) {
+ if (ndr_syntax_id_equal(&rpc_lookup[i].rpc_interface, id)) {
+ return rpc_lookup[i].cmds;
+ }
+ }
+
+ return NULL;
+}
+
+bool rpc_srv_get_pipe_interface_by_cli_name(const char *cli_name,
+ struct ndr_syntax_id *id)
+{
+ uint32_t i;
+
+ for (i = 0; i < rpc_lookup_size; i++) {
+ if (strequal(rpc_lookup[i].pipe.clnt, cli_name)) {
+ if (id) {
+ *id = rpc_lookup[i].rpc_interface;
+ }
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/*******************************************************************
+ Register commands to an RPC pipe
+*******************************************************************/
+
+NTSTATUS rpc_srv_register(int version, const char *clnt, const char *srv,
+ const struct ndr_interface_table *iface,
+ const struct api_struct *cmds, int size)
+{
+ struct rpc_table *rpc_entry;
+
+ if (!clnt || !srv || !cmds) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ if (version != SMB_RPC_INTERFACE_VERSION) {
+ DEBUG(0,("Can't register rpc commands!\n"
+ "You tried to register a rpc module with SMB_RPC_INTERFACE_VERSION %d"
+ ", while this version of samba uses version %d!\n",
+ version,SMB_RPC_INTERFACE_VERSION));
+ return NT_STATUS_OBJECT_TYPE_MISMATCH;
+ }
+
+ /* TODO:
+ *
+ * we still need to make sure that don't register the same commands twice!!!
+ *
+ * --metze
+ */
+
+ /*
+ * We use a temporary variable because this call can fail and
+ * rpc_lookup will still be valid afterwards. It could then succeed if
+ * called again later
+ */
+ rpc_lookup_size++;
+ rpc_entry = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(rpc_lookup, struct rpc_table, rpc_lookup_size);
+ if (NULL == rpc_entry) {
+ rpc_lookup_size--;
+ DEBUG(0, ("rpc_pipe_register_commands: memory allocation failed\n"));
+ return NT_STATUS_NO_MEMORY;
+ } else {
+ rpc_lookup = rpc_entry;
+ }
+
+ rpc_entry = rpc_lookup + (rpc_lookup_size - 1);
+ ZERO_STRUCTP(rpc_entry);
+ rpc_entry->pipe.clnt = SMB_STRDUP(clnt);
+ rpc_entry->pipe.srv = SMB_STRDUP(srv);
+ rpc_entry->rpc_interface = iface->syntax_id;
+ rpc_entry->cmds = cmds;
+ rpc_entry->n_cmds = size;
+
+ return NT_STATUS_OK;
+}
diff --git a/source3/wscript_build b/source3/wscript_build
index 3ce63adb69..2077661722 100644
--- a/source3/wscript_build
+++ b/source3/wscript_build
@@ -396,8 +396,7 @@ RPC_EVENTLOG_SRC = '''rpc_server/srv_eventlog_nt.c
NPA_TSTREAM_SRC = '''../libcli/named_pipe_auth/npa_tstream.c'''
-RPC_PIPE_SRC = '''rpc_server/srv_pipe_hnd.c
- rpc_server/srv_pipe.c rpc_server/srv_lsa_hnd.c'''
+RPC_PIPE_SRC = '''rpc_server/srv_pipe_hnd.c rpc_server/srv_pipe.c rpc_server/srv_pipe_register.c'''
RPC_ECHO_SRC = '''rpc_server/srv_echo_nt.c ../librpc/gen_ndr/srv_echo.c'''