summaryrefslogtreecommitdiff
path: root/source3/rpc_server/srv_pipe_hnd.c
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>1998-03-11 21:11:04 +0000
committerJeremy Allison <jra@samba.org>1998-03-11 21:11:04 +0000
commitfdeea341ed1bae670382e45eb731db1b5838ad21 (patch)
treebdbc5138a9340bdbd5c12cee243e6acfb2e64daf /source3/rpc_server/srv_pipe_hnd.c
parent4c6230afd2f144322c07c7e4c46147d3e5d2ddde (diff)
downloadsamba-fdeea341ed1bae670382e45eb731db1b5838ad21.tar.gz
samba-fdeea341ed1bae670382e45eb731db1b5838ad21.tar.bz2
samba-fdeea341ed1bae670382e45eb731db1b5838ad21.zip
"For I have laboured mightily on Luke's code, and hath broken
all I saw" - the book of Jeremy, chapter 1 :-). So here is the mega-merge of the NTDOM branch server code. It doesn't include the new client side pieces, we'll look at that later. This should give the same functionality, server wise, as the NTDOM branch does, only merged into the main branch. Any fixes to domain controler functionality should be added to the main branch, not the NTDOM branch. This code compiles without warnings on gcc2.8, but will need further testing before we are sure all the working functionality of the NTDOM server branch has been correctly carried over. I hereby declare the server side of the NTDOM branch dead (and all who sail in her :-). Jeremy. (This used to be commit 118ba4d77a33248e762a2cf843fb7cbc906ee6e7)
Diffstat (limited to 'source3/rpc_server/srv_pipe_hnd.c')
-rw-r--r--source3/rpc_server/srv_pipe_hnd.c315
1 files changed, 315 insertions, 0 deletions
diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c
new file mode 100644
index 0000000000..e4893fee89
--- /dev/null
+++ b/source3/rpc_server/srv_pipe_hnd.c
@@ -0,0 +1,315 @@
+
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-1997,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
+ *
+ * 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"
+
+
+#define PIPE "\\PIPE\\"
+#define PIPELEN strlen(PIPE)
+
+extern int DEBUGLEVEL;
+static int chain_pnum = -1;
+
+#ifndef MAX_OPEN_PIPES
+#define MAX_OPEN_PIPES 50
+#endif
+
+#define PIPE_HANDLE_OFFSET 0x800
+
+pipes_struct Pipes[MAX_OPEN_PIPES];
+
+#define P_OPEN(p) ((p)->open)
+#define P_OK(p,c) (P_OPEN(p) && (c)==((p)->cnum))
+#define VALID_PNUM(pnum) (((pnum) >= 0) && ((pnum) < MAX_OPEN_PIPES))
+#define OPEN_PNUM(pnum) (VALID_PNUM(pnum) && P_OPEN(&(Pipes[pnum])))
+#define PNUM_OK(pnum,c) (OPEN_PNUM(pnum) && (c)==Pipes[pnum].cnum)
+
+
+/****************************************************************************
+ reset pipe chain handle number
+****************************************************************************/
+void reset_chain_pnum(void)
+{
+ chain_pnum = -1;
+}
+
+/****************************************************************************
+ sets chain pipe-file handle
+****************************************************************************/
+void set_chain_pnum(int new_pnum)
+{
+ chain_pnum = new_pnum;
+}
+
+/****************************************************************************
+ initialise pipe handle states...
+****************************************************************************/
+void init_rpc_pipe_hnd(void)
+{
+ int i;
+ /* we start at 1 here for an obscure reason I can't now remember,
+ but I think is important :-) */
+ for (i = 1; i < MAX_OPEN_PIPES; i++)
+ {
+ Pipes[i].open = False;
+ Pipes[i].name[0] = 0;
+ Pipes[i].pipe_srv_name[0] = 0;
+
+ Pipes[i].rhdr.data = NULL;
+ Pipes[i].rdata.data = NULL;
+ Pipes[i].rhdr.offset = 0;
+ Pipes[i].rdata.offset = 0;
+
+ Pipes[i].max_rdata_len = 0;
+ Pipes[i].hdr_offsets = 0;
+ }
+
+ return;
+}
+
+/****************************************************************************
+ find first available file slot
+****************************************************************************/
+int open_rpc_pipe_hnd(char *pipe_name, int cnum, uint16 vuid)
+{
+ int i;
+ /* we start at 1 here for an obscure reason I can't now remember,
+ but I think is important :-) */
+ for (i = 1; i < MAX_OPEN_PIPES; i++)
+ {
+ if (!Pipes[i].open)
+ {
+ Pipes[i].open = True;
+ Pipes[i].device_state = 0;
+ Pipes[i].cnum = cnum;
+ Pipes[i].uid = vuid;
+
+ Pipes[i].rhdr.data = NULL;
+ Pipes[i].rdata.data = NULL;
+ Pipes[i].rhdr.offset = 0;
+ Pipes[i].rdata.offset = 0;
+
+ Pipes[i].max_rdata_len = 0;
+ Pipes[i].hdr_offsets = 0;
+
+ fstrcpy(Pipes[i].name, pipe_name);
+
+ DEBUG(4,("Opened pipe %s with handle %x\n",
+ pipe_name, i + PIPE_HANDLE_OFFSET));
+
+ set_chain_pnum(i);
+
+ return(i);
+ }
+ }
+
+ DEBUG(1,("ERROR! Out of pipe structures - perhaps increase MAX_OPEN_PIPES?\n"));
+
+ return(-1);
+}
+
+/****************************************************************************
+ reads data from a pipe.
+
+ headers are interspersed with the data at regular intervals. by the time
+ this function is called, the start of the data could possibly have been
+ read by an SMBtrans (max_rdata_len != 0).
+
+ calling create_rpc_request() here is a fudge. the data should already
+ have been prepared into arrays of headers + data stream sections.
+
+ ****************************************************************************/
+int read_pipe(uint16 pnum, char *data, uint32 pos, int n)
+{
+ int data_pos = pos;
+ pipes_struct *p = &Pipes[pnum - PIPE_HANDLE_OFFSET];
+ DEBUG(6,("read_pipe: %x", pnum));
+
+ if (VALID_PNUM(pnum - PIPE_HANDLE_OFFSET))
+ {
+ DEBUG(6,("name: %s cnum: %d open: %s data_pos: %lx len: %lx",
+ p->name,
+ p->cnum,
+ BOOLSTR(p->open),
+ data_pos, n));
+ }
+
+ if (OPEN_PNUM(pnum - PIPE_HANDLE_OFFSET))
+ {
+ int num;
+ int len;
+ uint32 rpc_frag_pos;
+
+ DEBUG(6,("OK\n"));
+
+ if (p->rhdr.data == NULL || p->rhdr.data->data == NULL ||
+ p->rhdr.data->data_used == 0)
+ {
+ return 0;
+ }
+
+ /* the read request starts from where the SMBtrans2 left off. */
+ data_pos += p->max_rdata_len;
+
+ /* headers accumulate an offset */
+ data_pos -= p->hdr_offsets;
+
+ len = mem_buf_len(p->rhdr.data);
+ num = len - (int)data_pos;
+
+ if (num > n) num = n;
+
+ if (!IS_BITS_SET_ALL(p->hdr.flags, RPC_FLG_LAST))
+ {
+ rpc_frag_pos = data_pos % p->hdr.frag_len;
+
+ if (rpc_frag_pos == 0)
+ {
+ /* create and copy in a new header. */
+ create_rpc_reply(p, data_pos, p->rdata.offset);
+ mem_buf_copy(data, p->rhdr.data, 0, 0x18);
+
+ /* make room in data stream for header */
+ p->hdr_offsets += 0x18;
+ }
+ }
+
+ if (num > 0)
+ {
+ mem_buf_copy(data, p->rhdr.data, data_pos, num);
+ return num;
+ }
+
+ return 0;
+
+ }
+ else
+ {
+ DEBUG(6,("NOT\n"));
+ return -1;
+ }
+}
+
+/****************************************************************************
+ gets the name of a pipe
+****************************************************************************/
+BOOL get_rpc_pipe(int pnum, pipes_struct **p)
+{
+ DEBUG(6,("get_rpc_pipe: "));
+
+ /* mapping is PIPE_HANDLE_OFFSET up... */
+
+ if (VALID_PNUM(pnum - PIPE_HANDLE_OFFSET))
+ {
+ DEBUG(6,("name: %s cnum: %d open: %s ",
+ Pipes[pnum - PIPE_HANDLE_OFFSET].name,
+ Pipes[pnum - PIPE_HANDLE_OFFSET].cnum,
+ BOOLSTR(Pipes[pnum - PIPE_HANDLE_OFFSET].open)));
+ }
+ if (OPEN_PNUM(pnum - PIPE_HANDLE_OFFSET))
+ {
+ DEBUG(6,("OK\n"));
+ (*p) = &(Pipes[pnum - PIPE_HANDLE_OFFSET]);
+ return True;
+ }
+ else
+ {
+ DEBUG(6,("NOT\n"));
+ return False;
+ }
+}
+
+/****************************************************************************
+ gets the name of a pipe
+****************************************************************************/
+char *get_rpc_pipe_hnd_name(int pnum)
+{
+ pipes_struct *p = NULL;
+ get_rpc_pipe(pnum, &p);
+ return p != NULL ? p->name : NULL;
+}
+
+/****************************************************************************
+ set device state on a pipe. exactly what this is for is unknown...
+****************************************************************************/
+BOOL set_rpc_pipe_hnd_state(pipes_struct *p, uint16 device_state)
+{
+ if (p == NULL) return False;
+
+ if (P_OPEN(p))
+ {
+ DEBUG(3,("%s Setting pipe device state=%x on pipe (name=%s cnum=%d)\n",
+ timestring(), device_state, p->name, p->cnum));
+
+ p->device_state = device_state;
+
+ return True;
+ }
+ else
+ {
+ DEBUG(3,("%s Error setting pipe device state=%x (name=%s cnum=%d)\n",
+ timestring(), device_state, p->name, p->cnum));
+ return False;
+ }
+}
+
+/****************************************************************************
+ close an rpc pipe
+****************************************************************************/
+BOOL close_rpc_pipe_hnd(int pnum, int cnum)
+{
+ pipes_struct *p = NULL;
+ get_rpc_pipe(pnum, &p);
+ /* mapping is PIPE_HANDLE_OFFSET up... */
+
+ if (p != NULL && P_OK(p, cnum))
+ {
+ DEBUG(3,("%s Closed pipe name %s pnum=%x cnum=%d\n",
+ timestring(),Pipes[pnum-PIPE_HANDLE_OFFSET].name, pnum,cnum));
+
+ p->open = False;
+
+ p->rdata.offset = 0;
+ p->rhdr.offset = 0;
+ mem_buf_free(&(p->rdata.data));
+ mem_buf_free(&(p->rhdr .data));
+
+ return True;
+ }
+ else
+ {
+ DEBUG(3,("%s Error closing pipe pnum=%x cnum=%d\n",
+ timestring(),pnum, cnum));
+ return False;
+ }
+}
+
+/****************************************************************************
+ close an rpc pipe
+****************************************************************************/
+int get_rpc_pipe_num(char *buf, int where)
+{
+ return (chain_pnum != -1 ? chain_pnum : SVAL(buf,where));
+}
+