diff options
-rw-r--r-- | source3/Makefile.in | 15 | ||||
-rw-r--r-- | source3/configure.in | 5 | ||||
-rw-r--r-- | source3/include/ntdomain.h | 2 | ||||
-rw-r--r-- | source3/include/rpc_echo.h | 74 | ||||
-rw-r--r-- | source3/include/smb.h | 4 | ||||
-rw-r--r-- | source3/lib/util.c | 44 | ||||
-rw-r--r-- | source3/rpc_client/cli_echo.c | 187 | ||||
-rw-r--r-- | source3/rpc_parse/parse_echo.c | 166 | ||||
-rw-r--r-- | source3/rpc_parse/parse_rpc.c | 10 | ||||
-rw-r--r-- | source3/rpc_server/srv_echo.c | 137 | ||||
-rw-r--r-- | source3/rpc_server/srv_echo_nt.c | 78 | ||||
-rw-r--r-- | source3/rpcclient/cmd_echo.c | 157 | ||||
-rw-r--r-- | source3/rpcclient/rpcclient.c | 7 | ||||
-rw-r--r-- | source3/smbd/nttrans.c | 1 |
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 }; |