summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/Makefile.in15
-rw-r--r--source3/configure.in5
-rw-r--r--source3/include/ntdomain.h2
-rw-r--r--source3/include/rpc_echo.h74
-rw-r--r--source3/include/smb.h4
-rw-r--r--source3/lib/util.c44
-rw-r--r--source3/rpc_client/cli_echo.c187
-rw-r--r--source3/rpc_parse/parse_echo.c166
-rw-r--r--source3/rpc_parse/parse_rpc.c10
-rw-r--r--source3/rpc_server/srv_echo.c137
-rw-r--r--source3/rpc_server/srv_echo_nt.c78
-rw-r--r--source3/rpcclient/cmd_echo.c157
-rw-r--r--source3/rpcclient/rpcclient.c7
-rw-r--r--source3/smbd/nttrans.c1
14 files changed, 837 insertions, 50 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in
index 99e557b7a74..641294790d9 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -226,7 +226,7 @@ LIBMSRPC_OBJ = rpc_client/cli_lsarpc.o rpc_client/cli_samr.o \
rpc_client/cli_wkssvc.o rpc_client/cli_dfs.o \
rpc_client/cli_reg.o rpc_client/cli_pipe.o \
rpc_client/cli_spoolss.o rpc_client/cli_spoolss_notify.o \
- rpc_client/cli_ds.o libsmb/namequery_dc.o
+ rpc_client/cli_ds.o rpc_client/cli_echo.o libsmb/namequery_dc.o
LIBMSRPC_SERVER_OBJ = libsmb/trusts_util.o
@@ -253,6 +253,8 @@ RPC_SPOOLSS_OBJ = rpc_server/srv_spoolss.o rpc_server/srv_spoolss_nt.o
RPC_PIPE_OBJ = rpc_server/srv_pipe_hnd.o rpc_server/srv_util.o \
rpc_server/srv_pipe.o rpc_server/srv_lsa_hnd.o
+RPC_ECHO_OBJ = rpc_server/srv_echo.o rpc_server/srv_echo_nt.o
+
RPC_SERVER_OBJ = @RPC_STATIC@ $(RPC_PIPE_OBJ)
# this includes only the low level parse code, not stuff
@@ -265,6 +267,7 @@ RPC_PARSE_OBJ = rpc_parse/parse_lsa.o rpc_parse/parse_net.o \
rpc_parse/parse_samr.o rpc_parse/parse_srv.o \
rpc_parse/parse_wks.o rpc_parse/parse_ds.o \
rpc_parse/parse_spoolss.o rpc_parse/parse_dfs.o \
+ rpc_parse/parse_echo.o \
$(REGOBJS_OBJ)
@@ -424,7 +427,8 @@ RPCCLIENT_OBJ1 = rpcclient/rpcclient.o rpcclient/cmd_lsarpc.o \
rpcclient/cmd_samr.o rpcclient/cmd_spoolss.o \
rpcclient/cmd_netlogon.o rpcclient/cmd_srvsvc.o \
rpcclient/cmd_dfs.o rpcclient/cmd_reg.o \
- rpcclient/display_sec.o rpcclient/cmd_ds.o
+ rpcclient/display_sec.o rpcclient/cmd_ds.o \
+ rpcclient/cmd_echo.o
RPCCLIENT_OBJ = $(RPCCLIENT_OBJ1) \
$(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) \
@@ -557,7 +561,7 @@ PROTO_OBJ = $(SMBD_OBJ_MAIN) \
$(LIB_SMBD_OBJ) $(SAM_OBJ) $(REGISTRY_OBJ) $(POPT_LIB_OBJ) \
$(RPC_LSA_OBJ) $(RPC_NETLOG_OBJ) $(RPC_SAMR_OBJ) $(RPC_REG_OBJ) \
$(RPC_SVC_OBJ) $(RPC_WKS_OBJ) $(RPC_DFS_OBJ) $(RPC_SPOOLSS_OBJ) \
- $(IDMAP_OBJ)
+ $(IDMAP_OBJ) $(RPC_ECHO_OBJ)
NSS_OBJ_0 = nsswitch/wins.o $(PARAM_OBJ) $(UBIQX_OBJ) $(LIBSMB_OBJ) \
$(LIB_OBJ) $(NSSWINS_OBJ)
@@ -943,6 +947,11 @@ bin/librpc_netdfs.@SHLIBEXT@: $(RPC_DFS_OBJ)
@$(SHLD) $(LDSHFLAGS) -o $@ $(RPC_DFS_OBJ) -lc \
@SONAMEFLAG@`basename $@`
+bin/librpc_echo.@SHLIBEXT@: $(RPC_ECHO_OBJ)
+ @echo "Linking $@"
+ @$(SHLD) $(LDSHFLAGS) -o $@ $(RPC_ECHO_OBJ) -lc \
+ @SONAMEFLAG@`basename $@`
+
nsswitch/libnss_wins.@SHLIBEXT@: $(NSS_OBJ)
@echo "Linking $@"
@$(SHLD) $(LDSHFLAGS) -o $@ $(NSS_OBJ) -lc \
diff --git a/source3/configure.in b/source3/configure.in
index c2b7ae27654..ce53358d09b 100644
--- a/source3/configure.in
+++ b/source3/configure.in
@@ -247,6 +247,10 @@ dnl Add modules that have to be built by default here
dnl These have to be built static:
default_static_modules="pdb_smbpasswd pdb_tdbsam pdb_unix rpc_lsa rpc_samr rpc_reg rpc_wks rpc_net rpc_dfs rpc_srv rpc_spoolss auth_rhosts auth_sam auth_unix auth_winbind auth_server auth_domain auth_builtin idmap_winbind"
+if test "x$enable_developer" = xyes; then
+ default_static_modules="$default_static_modules rpc_echo"
+fi
+
dnl These are preferably build shared, and static if dlopen() is not available
default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_fake_perms vfs_netatalk"
@@ -3460,6 +3464,7 @@ SMB_MODULE(rpc_dfs, \$(RPC_DFS_OBJ), "bin/librpc_netdfs.$SHLIBEXT", RPC)
SMB_MODULE(rpc_srv, \$(RPC_SVC_OBJ), "bin/librpc_srvsvc.$SHLIBEXT", RPC)
SMB_MODULE(rpc_spoolss, \$(RPC_SPOOLSS_OBJ), "bin/librpc_spoolss.$SHLIBEXT", RPC)
SMB_MODULE(rpc_samr, \$(RPC_SAMR_OBJ), "bin/librpc_samr.$SHLIBEXT", RPC)
+SMB_MODULE(rpc_echo, \$(RPC_ECHO_OBJ), "bin/librpc_echo.$SHLIBEXT", RPC)
SMB_SUBSYSTEM(RPC)
SMB_MODULE(charset_weird, modules/developer.o, "bin/developer.$SHLIBEXT", CHARSET)
diff --git a/source3/include/ntdomain.h b/source3/include/ntdomain.h
index 9216640c039..b6ab4fd0c50 100644
--- a/source3/include/ntdomain.h
+++ b/source3/include/ntdomain.h
@@ -385,4 +385,6 @@ struct acct_info
#include "rpc_spoolss.h"
#include "rpc_dfs.h"
#include "rpc_ds.h"
+#include "rpc_echo.h"
+
#endif /* _NT_DOMAIN_H */
diff --git a/source3/include/rpc_echo.h b/source3/include/rpc_echo.h
new file mode 100644
index 00000000000..8fa389cf569
--- /dev/null
+++ b/source3/include/rpc_echo.h
@@ -0,0 +1,74 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Samba rpcecho definitions.
+
+ Copyright (C) Tim Potter 2003
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _RPC_ECHO_H
+#define _RPC_ECHO_H
+
+#define ECHO_ADD_ONE 0x00
+#define ECHO_DATA 0x01
+#define ECHO_SINK_DATA 0x02
+#define ECHO_SOURCE_DATA 0x03
+
+typedef struct echo_q_add_one
+{
+ uint32 request;
+} ECHO_Q_ADD_ONE;
+
+typedef struct echo_r_add_one
+{
+ uint32 response;
+} ECHO_R_ADD_ONE;
+
+typedef struct echo_q_echo_data
+{
+ uint32 size;
+ char *data;
+} ECHO_Q_ECHO_DATA;
+
+typedef struct echo_r_echo_data
+{
+ uint32 size;
+ char *data;
+} ECHO_R_ECHO_DATA;
+
+typedef struct echo_q_source_data
+{
+ uint32 size;
+} ECHO_Q_SOURCE_DATA;
+
+typedef struct echo_r_source_data
+{
+ uint32 size;
+ char *data;
+} ECHO_R_SOURCE_DATA;
+
+typedef struct echo_q_sink_data
+{
+ uint32 size;
+ char *data;
+} ECHO_Q_SINK_DATA;
+
+typedef struct echo_r_sink_data
+{
+} ECHO_R_SINK_DATA;
+
+#endif
diff --git a/source3/include/smb.h b/source3/include/smb.h
index 78690cd5244..02b5b9435ee 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -187,6 +187,7 @@ typedef smb_ucs2_t wfstring[FSTRING_LEN];
#define PIPE_LSARPC "\\PIPE\\lsarpc"
#define PIPE_SPOOLSS "\\PIPE\\spoolss"
#define PIPE_NETDFS "\\PIPE\\netdfs"
+#define PIPE_ECHO "\\PIPE\\rpcecho"
#define PIPE_NETLOGON_PLAIN "\\NETLOGON"
@@ -199,7 +200,8 @@ typedef smb_ucs2_t wfstring[FSTRING_LEN];
#define PI_WINREG 6
#define PI_SPOOLSS 7
#define PI_NETDFS 8
-#define PI_MAX_PIPES 9
+#define PI_ECHO 9
+#define PI_MAX_PIPES 10
/* 64 bit time (100usec) since ????? - cifs6.txt, section 3.5, page 30 */
typedef struct nttime_info
diff --git a/source3/lib/util.c b/source3/lib/util.c
index 3ecfc925526..ddc20e492c2 100644
--- a/source3/lib/util.c
+++ b/source3/lib/util.c
@@ -1840,50 +1840,6 @@ enum remote_arch_types get_remote_arch(void)
return ra_type;
}
-
-void out_ascii(FILE *f, unsigned char *buf,int len)
-{
- int i;
- for (i=0;i<len;i++)
- fprintf(f, "%c", isprint(buf[i])?buf[i]:'.');
-}
-
-void out_data(FILE *f,char *buf1,int len, int per_line)
-{
- unsigned char *buf = (unsigned char *)buf1;
- int i=0;
- if (len<=0) {
- return;
- }
-
- fprintf(f, "[%03X] ",i);
- for (i=0;i<len;) {
- fprintf(f, "%02X ",(int)buf[i]);
- i++;
- if (i%(per_line/2) == 0) fprintf(f, " ");
- if (i%per_line == 0) {
- out_ascii(f,&buf[i-per_line ],per_line/2); fprintf(f, " ");
- out_ascii(f,&buf[i-per_line/2],per_line/2); fprintf(f, "\n");
- if (i<len) fprintf(f, "[%03X] ",i);
- }
- }
- if ((i%per_line) != 0) {
- int n;
-
- n = per_line - (i%per_line);
- fprintf(f, " ");
- if (n>(per_line/2)) fprintf(f, " ");
- while (n--) {
- fprintf(f, " ");
- }
- n = MIN(per_line/2,i%per_line);
- out_ascii(f,&buf[i-(i%per_line)],n); fprintf(f, " ");
- n = (i%per_line) - n;
- if (n>0) out_ascii(f,&buf[i-n],n);
- fprintf(f, "\n");
- }
-}
-
void print_asc(int level, const unsigned char *buf,int len)
{
int i;
diff --git a/source3/rpc_client/cli_echo.c b/source3/rpc_client/cli_echo.c
new file mode 100644
index 00000000000..03a4ab36ee0
--- /dev/null
+++ b/source3/rpc_client/cli_echo.c
@@ -0,0 +1,187 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ RPC pipe client
+
+ Copyright (C) Tim Potter 2003
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+NTSTATUS cli_echo_add_one(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ uint32 request, uint32 *response)
+{
+ prs_struct qbuf, rbuf;
+ ECHO_Q_ADD_ONE q;
+ ECHO_R_ADD_ONE r;
+ BOOL result = False;
+
+ ZERO_STRUCT(q);
+ ZERO_STRUCT(r);
+
+ /* Initialise parse structures */
+
+ prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+ /* Marshall data and send request */
+
+ init_echo_q_add_one(&q, request);
+
+ if (!echo_io_q_add_one("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, ECHO_ADD_ONE, &qbuf, &rbuf))
+ goto done;
+
+ /* Unmarshall response */
+
+ if (!echo_io_r_add_one("", &r, &rbuf, 0))
+ goto done;
+
+ if (response)
+ *response = r.response;
+
+ result = True;
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
+}
+
+NTSTATUS cli_echo_data(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ uint32 size, char *in_data, char **out_data)
+{
+ prs_struct qbuf, rbuf;
+ ECHO_Q_ECHO_DATA q;
+ ECHO_R_ECHO_DATA r;
+ BOOL result = False;
+
+ ZERO_STRUCT(q);
+ ZERO_STRUCT(r);
+
+ /* Initialise parse structures */
+
+ prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+ /* Marshall data and send request */
+
+ init_echo_q_echo_data(&q, size, in_data);
+
+ if (!echo_io_q_echo_data("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, ECHO_DATA, &qbuf, &rbuf))
+ goto done;
+
+ /* Unmarshall response */
+
+ if (!echo_io_r_echo_data("", &r, &rbuf, 0))
+ goto done;
+
+ result = True;
+
+ if (out_data) {
+ *out_data = talloc(mem_ctx, size);
+ memcpy(*out_data, r.data, size);
+ }
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
+}
+
+NTSTATUS cli_echo_sink_data(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ uint32 size, char *in_data)
+{
+ prs_struct qbuf, rbuf;
+ ECHO_Q_SINK_DATA q;
+ ECHO_R_SINK_DATA r;
+ BOOL result = False;
+
+ ZERO_STRUCT(q);
+ ZERO_STRUCT(r);
+
+ /* Initialise parse structures */
+
+ prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+ /* Marshall data and send request */
+
+ init_echo_q_sink_data(&q, size, in_data);
+
+ if (!echo_io_q_sink_data("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, ECHO_SINK_DATA, &qbuf, &rbuf)) {
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ if (!echo_io_r_sink_data("", &r, &rbuf, 0)) {
+ goto done;
+ }
+
+ result = True;
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
+}
+
+NTSTATUS cli_echo_source_data(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ uint32 size, char **out_data)
+{
+ prs_struct qbuf, rbuf;
+ ECHO_Q_SOURCE_DATA q;
+ ECHO_R_SOURCE_DATA r;
+ BOOL result = False;
+
+ ZERO_STRUCT(q);
+ ZERO_STRUCT(r);
+
+ /* Initialise parse structures */
+
+ prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+ /* Marshall data and send request */
+
+ init_echo_q_source_data(&q, size);
+
+ if (!echo_io_q_source_data("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, ECHO_SOURCE_DATA, &qbuf, &rbuf)) {
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ if (!echo_io_r_source_data("", &r, &rbuf, 0)) {
+ goto done;
+ }
+
+ result = True;
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
+}
diff --git a/source3/rpc_parse/parse_echo.c b/source3/rpc_parse/parse_echo.c
new file mode 100644
index 00000000000..67f9ad772ee
--- /dev/null
+++ b/source3/rpc_parse/parse_echo.c
@@ -0,0 +1,166 @@
+/*
+ * Unix SMB/CIFS implementation.
+ *
+ * RPC Pipe client / server routines
+ *
+ * Copyright (C) Tim Potter 2003
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "includes.h"
+#include "nterr.h"
+#include "rpc_parse.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_RPC_PARSE
+
+void init_echo_q_add_one(ECHO_Q_ADD_ONE *q_d, uint32 request)
+{
+ q_d->request = request;
+}
+
+BOOL echo_io_q_add_one(const char *desc, ECHO_Q_ADD_ONE *q_d,
+ prs_struct *ps, int depth)
+{
+ if (!prs_uint32("request", ps, 0, &q_d->request))
+ return False;
+
+ return True;
+}
+
+BOOL echo_io_r_add_one(const char *desc, ECHO_R_ADD_ONE *q_d,
+ prs_struct *ps, int depth)
+{
+ if (!prs_uint32("response", ps, 0, &q_d->response))
+ return False;
+
+ return True;
+}
+
+
+void init_echo_q_echo_data(ECHO_Q_ECHO_DATA *q_d, uint32 size, char *data)
+{
+ q_d->size = size;
+ q_d->data = data;
+}
+
+BOOL echo_io_q_echo_data(const char *desc, ECHO_Q_ECHO_DATA *q_d,
+ prs_struct *ps, int depth)
+{
+ if (!prs_uint32("size", ps, depth, &q_d->size))
+ return False;
+
+ if (!prs_uint32("size", ps, depth, &q_d->size))
+ return False;
+
+ if (UNMARSHALLING(ps)) {
+ q_d->data = prs_alloc_mem(ps, q_d->size);
+
+ if (!q_d->data)
+ return False;
+ }
+
+ if (!prs_uint8s(False, "data", ps, depth, q_d->data, q_d->size))
+ return False;
+
+ return True;
+}
+
+BOOL echo_io_r_echo_data(const char *desc, ECHO_R_ECHO_DATA *q_d,
+ prs_struct *ps, int depth)
+{
+ if (!prs_uint32("size", ps, 0, &q_d->size))
+ return False;
+
+ if (UNMARSHALLING(ps)) {
+ q_d->data = prs_alloc_mem(ps, q_d->size);
+
+ if (!q_d->data)
+ return False;
+ }
+
+ if (!prs_uint8s(False, "data", ps, depth, q_d->data, q_d->size))
+ return False;
+
+ return True;
+}
+
+void init_echo_q_sink_data(ECHO_Q_SINK_DATA *q_d, uint32 size, char *data)
+{
+ q_d->size = size;
+ q_d->data = data;
+}
+
+BOOL echo_io_q_sink_data(const char *desc, ECHO_Q_SINK_DATA *q_d,
+ prs_struct *ps, int depth)
+{
+ if (!prs_uint32("size", ps, depth, &q_d->size))
+ return False;
+
+ if (!prs_uint32("size", ps, depth, &q_d->size))
+ return False;
+
+ if (UNMARSHALLING(ps)) {
+ q_d->data = prs_alloc_mem(ps, q_d->size);
+
+ if (!q_d->data)
+ return False;
+ }
+
+ if (!prs_uint8s(False, "data", ps, depth, q_d->data, q_d->size))
+ return False;
+
+ return True;
+}
+
+BOOL echo_io_r_sink_data(const char *desc, ECHO_R_SINK_DATA *q_d,
+ prs_struct *ps, int depth)
+{
+ return True;
+}
+
+void init_echo_q_source_data(ECHO_Q_SOURCE_DATA *q_d, uint32 size)
+{
+ q_d->size = size;
+}
+
+BOOL echo_io_q_source_data(const char *desc, ECHO_Q_SOURCE_DATA *q_d,
+ prs_struct *ps, int depth)
+{
+ if (!prs_uint32("size", ps, depth, &q_d->size))
+ return False;
+
+ return True;
+}
+
+BOOL echo_io_r_source_data(const char *desc, ECHO_R_SOURCE_DATA *q_d,
+ prs_struct *ps, int depth)
+{
+ if (!prs_uint32("size", ps, 0, &q_d->size))
+ return False;
+
+ if (UNMARSHALLING(ps)) {
+ q_d->data = prs_alloc_mem(ps, q_d->size);
+
+ if (!q_d->data)
+ return False;
+ }
+
+ if (!prs_uint8s(False, "data", ps, depth, q_d->data, q_d->size))
+ return False;
+
+ return True;
+}
diff --git a/source3/rpc_parse/parse_rpc.c b/source3/rpc_parse/parse_rpc.c
index 656082e05ae..30909c69105 100644
--- a/source3/rpc_parse/parse_rpc.c
+++ b/source3/rpc_parse/parse_rpc.c
@@ -138,6 +138,15 @@ interface/version dce/rpc pipe identification
}, 0x03 \
}
+#define SYNT_ECHO_V1 \
+{ \
+ { \
+ 0x60a15ec5, 0x4de8, 0x11d7, \
+ { 0xa6, 0x37, 0x00, 0x50, \
+ 0x56, 0xa2, 0x01, 0x82 } \
+ }, 0x01 \
+}
+
/*
* IMPORTANT!! If you update this structure, make sure to
* update the index #defines in smb.h.
@@ -155,6 +164,7 @@ const struct pipe_id_info pipe_names [] =
{ PIPE_WINREG , SYNT_WINREG_V1 , PIPE_WINREG , TRANS_SYNT_V2 },
{ PIPE_SPOOLSS , SYNT_SPOOLSS_V1 , PIPE_SPOOLSS , TRANS_SYNT_V2 },
{ PIPE_NETDFS , SYNT_NETDFS_V3 , PIPE_NETDFS , TRANS_SYNT_V2 },
+ { PIPE_ECHO , SYNT_ECHO_V1 , PIPE_ECHO , TRANS_SYNT_V2 },
{ NULL , SYNT_NONE_V0 , NULL , SYNT_NONE_V0 }
};
diff --git a/source3/rpc_server/srv_echo.c b/source3/rpc_server/srv_echo.c
new file mode 100644
index 00000000000..dcd8dd0c53b
--- /dev/null
+++ b/source3/rpc_server/srv_echo.c
@@ -0,0 +1,137 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * RPC Pipe client / server routines for rpcecho
+ * Copyright (C) Tim Potter 2003.
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* This is the interface to the rpcecho pipe. */
+
+#include "includes.h"
+#include "nterr.h"
+
+#ifdef DEVELOPER
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_RPC_SRV
+
+static BOOL api_add_one(pipes_struct *p)
+{
+ ECHO_Q_ADD_ONE q_u;
+ ECHO_R_ADD_ONE r_u;
+
+ prs_struct *data = &p->in_data.data;
+ prs_struct *rdata = &p->out_data.rdata;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ if(!echo_io_q_add_one("", &q_u, data, 0))
+ return False;
+
+ _echo_add_one(p, &q_u, &r_u);
+
+ if(!echo_io_r_add_one("", &r_u, rdata, 0))
+ return False;
+
+ return True;
+}
+
+static BOOL api_echo_data(pipes_struct *p)
+{
+ ECHO_Q_ECHO_DATA q_u;
+ ECHO_R_ECHO_DATA r_u;
+
+ prs_struct *data = &p->in_data.data;
+ prs_struct *rdata = &p->out_data.rdata;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ if(!echo_io_q_echo_data("", &q_u, data, 0))
+ return False;
+
+ _echo_data(p, &q_u, &r_u);
+
+ if(!echo_io_r_echo_data("", &r_u, rdata, 0))
+ return False;
+
+ return True;
+}
+
+static BOOL api_source_data(pipes_struct *p)
+{
+ ECHO_Q_SOURCE_DATA q_u;
+ ECHO_R_SOURCE_DATA r_u;
+
+ prs_struct *data = &p->in_data.data;
+ prs_struct *rdata = &p->out_data.rdata;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ if(!echo_io_q_source_data("", &q_u, data, 0))
+ return False;
+
+ _source_data(p, &q_u, &r_u);
+
+ if(!echo_io_r_source_data("", &r_u, rdata, 0))
+ return False;
+
+ return True;
+}
+
+static BOOL api_sink_data(pipes_struct *p)
+{
+ ECHO_Q_SINK_DATA q_u;
+ ECHO_R_SINK_DATA r_u;
+
+ prs_struct *data = &p->in_data.data;
+ prs_struct *rdata = &p->out_data.rdata;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ if(!echo_io_q_sink_data("", &q_u, data, 0))
+ return False;
+
+ _sink_data(p, &q_u, &r_u);
+
+ if(!echo_io_r_sink_data("", &r_u, rdata, 0))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+\pipe\rpcecho commands
+********************************************************************/
+
+int rpc_echo_init(void)
+{
+ struct api_struct api_echo_cmds[] = {
+ {"ADD_ONE", ECHO_ADD_ONE, api_add_one },
+ {"ECHO_DATA", ECHO_DATA, api_echo_data },
+ {"SOURCE_DATA", ECHO_SOURCE_DATA, api_source_data },
+ {"SINK_DATA", ECHO_SINK_DATA, api_sink_data },
+ };
+
+ return rpc_pipe_register_commands(
+ "rpcecho", "rpcecho", api_echo_cmds,
+ sizeof(api_echo_cmds) / sizeof(struct api_struct));
+}
+
+#endif /* DEVELOPER */
diff --git a/source3/rpc_server/srv_echo_nt.c b/source3/rpc_server/srv_echo_nt.c
new file mode 100644
index 00000000000..ddb76b3a21e
--- /dev/null
+++ b/source3/rpc_server/srv_echo_nt.c
@@ -0,0 +1,78 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * RPC Pipe client / server routines for rpcecho
+ * Copyright (C) Tim Potter 2003.
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* This is the interface to the rpcecho pipe. */
+
+#include "includes.h"
+#include "nterr.h"
+
+#ifdef DEVELOPER
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_RPC_SRV
+
+/* Add one to the input and return it */
+
+void _echo_add_one(pipes_struct *p, ECHO_Q_ADD_ONE *q_u, ECHO_R_ADD_ONE *r_u)
+{
+ DEBUG(10, ("_echo_add_one\n"));
+
+ r_u->response = q_u->request + 1;
+}
+
+/* Echo back an array of data */
+
+void _echo_data(pipes_struct *p, ECHO_Q_ECHO_DATA *q_u,
+ ECHO_R_ECHO_DATA *r_u)
+{
+ DEBUG(10, ("_echo_data\n"));
+
+ r_u->data = talloc(p->mem_ctx, q_u->size);
+ r_u->size = q_u->size;
+ memcpy(r_u->data, q_u->data, q_u->size);
+}
+
+/* Sink an array of data */
+
+void _sink_data(pipes_struct *p, ECHO_Q_SINK_DATA *q_u,
+ ECHO_R_SINK_DATA *r_u)
+{
+ DEBUG(10, ("_sink_data\n"));
+
+ /* My that was some yummy data! */
+}
+
+/* Source an array of data */
+
+void _source_data(pipes_struct *p, ECHO_Q_SOURCE_DATA *q_u,
+ ECHO_R_SOURCE_DATA *r_u)
+{
+ uint32 i;
+
+ DEBUG(10, ("_source_data\n"));
+
+ r_u->data = talloc(p->mem_ctx, q_u->size);
+ r_u->size = q_u->size;
+
+ for (i = 0; i < r_u->size; i++)
+ r_u->data[i] = i & 0xff;
+}
+
+#endif /* DEVELOPER */
diff --git a/source3/rpcclient/cmd_echo.c b/source3/rpcclient/cmd_echo.c
new file mode 100644
index 00000000000..79ba744a55a
--- /dev/null
+++ b/source3/rpcclient/cmd_echo.c
@@ -0,0 +1,157 @@
+/*
+ Unix SMB/CIFS implementation.
+ RPC pipe client
+
+ Copyright (C) Tim Potter 2003
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "rpcclient.h"
+
+static NTSTATUS cmd_echo_add_one(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ int argc, const char **argv)
+{
+ uint32 request = 1, response;
+ NTSTATUS result;
+
+ if (argc > 2) {
+ printf("Usage: %s [num]\n", argv[0]);
+ return NT_STATUS_OK;
+ }
+
+ if (argc == 2)
+ request = atoi(argv[1]);
+
+ result = cli_echo_add_one(cli, mem_ctx, request, &response);
+
+ if (!NT_STATUS_IS_OK(result))
+ goto done;
+
+ printf("%d + 1 = %d\n", request, response);
+
+done:
+ return result;
+}
+
+static NTSTATUS cmd_echo_data(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ int argc, const char **argv)
+{
+ uint32 size, i;
+ NTSTATUS result;
+ char *in_data = NULL, *out_data = NULL;
+
+ if (argc != 2) {
+ printf("Usage: %s num\n", argv[0]);
+ return NT_STATUS_OK;
+ }
+
+ size = atoi(argv[1]);
+ in_data = malloc(size);
+
+ for (i = 0; i < size; i++)
+ in_data[i] = i & 0xff;
+
+ result = cli_echo_data(cli, mem_ctx, size, in_data, &out_data);
+
+ if (!NT_STATUS_IS_OK(result))
+ goto done;
+
+ for (i = 0; i < size; i++) {
+ if (in_data[i] != out_data[i]) {
+ printf("mismatch at offset %d, %d != %d\n",
+ i, in_data[i], out_data[i]);
+ }
+ }
+
+done:
+ SAFE_FREE(in_data);
+
+ return result;
+}
+
+static NTSTATUS cmd_echo_source_data(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx, int argc,
+ const char **argv)
+{
+ uint32 size, i;
+ NTSTATUS result;
+ char *out_data = NULL;
+
+ if (argc != 2) {
+ printf("Usage: %s num\n", argv[0]);
+ return NT_STATUS_OK;
+ }
+
+ size = atoi(argv[1]);
+
+ result = cli_echo_source_data(cli, mem_ctx, size, &out_data);
+
+ if (!NT_STATUS_IS_OK(result))
+ goto done;
+
+ for (i = 0; i < size; i++) {
+ if (out_data && out_data[i] != (i & 0xff)) {
+ printf("mismatch at offset %d, %d != %d\n",
+ i, out_data[i], i & 0xff);
+ }
+ }
+
+done:
+ return result;
+}
+
+static NTSTATUS cmd_echo_sink_data(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ int argc, const char **argv)
+{
+ uint32 size, i;
+ NTSTATUS result;
+ char *in_data = NULL;
+
+ if (argc != 2) {
+ printf("Usage: %s num\n", argv[0]);
+ return NT_STATUS_OK;
+ }
+
+ size = atoi(argv[1]);
+ in_data = malloc(size);
+
+ for (i = 0; i < size; i++)
+ in_data[i] = i & 0xff;
+
+ result = cli_echo_sink_data(cli, mem_ctx, size, in_data);
+
+ if (!NT_STATUS_IS_OK(result))
+ goto done;
+
+done:
+ SAFE_FREE(in_data);
+
+ return result;
+}
+
+/* List of commands exported by this module */
+
+struct cmd_set echo_commands[] = {
+
+ { "ECHO" },
+
+ { "echoaddone", RPC_RTYPE_NTSTATUS, cmd_echo_add_one, NULL, PI_ECHO, "Add one to a number", "" },
+ { "echodata", RPC_RTYPE_NTSTATUS, cmd_echo_data, NULL, PI_ECHO, "Echo data", "" },
+ { "sinkdata", RPC_RTYPE_NTSTATUS, cmd_echo_sink_data, NULL, PI_ECHO, "Sink data", "" },
+ { "sourcedata", RPC_RTYPE_NTSTATUS, cmd_echo_source_data, NULL, PI_ECHO, "Source data", "" },
+ { NULL }
+};
diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c
index 1de181f77c9..efc883ff9ff 100644
--- a/source3/rpcclient/rpcclient.c
+++ b/source3/rpcclient/rpcclient.c
@@ -336,6 +336,7 @@ extern struct cmd_set srvsvc_commands[];
extern struct cmd_set dfs_commands[];
extern struct cmd_set reg_commands[];
extern struct cmd_set ds_commands[];
+extern struct cmd_set echo_commands[];
static struct cmd_set *rpcclient_command_list[] = {
rpcclient_commands,
@@ -347,6 +348,7 @@ static struct cmd_set *rpcclient_command_list[] = {
srvsvc_commands,
dfs_commands,
reg_commands,
+ echo_commands,
NULL
};
@@ -400,13 +402,14 @@ static NTSTATUS do_cmd(struct cli_state *cli,
if (!cli_nt_open_netlogon(cli, trust_password,
SEC_CHAN_WKSTA)) {
- DEBUG(0, ("Could not initialize NETLOGON pipe\n"));
+ DEBUG(0, ("Could not initialise NETLOGON pipe\n"));
return NT_STATUS_UNSUCCESSFUL;
}
} else {
if (cmd_entry->pipe_idx != -1) {
if (!cli_nt_session_open(cli, cmd_entry->pipe_idx)) {
- DEBUG(0, ("Could not initialize pipe\n"));
+ DEBUG(0, ("Could not initialise %s\n",
+ get_pipe_name_from_index(cmd_entry->pipe_idx)));
return NT_STATUS_UNSUCCESSFUL;
}
}
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index 6d9c6490459..9f7fabb75e4 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -40,6 +40,7 @@ static const char *known_nt_pipes[] = {
"\\winreg",
"\\spoolss",
"\\netdfs",
+ "\\rpcecho",
NULL
};