summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Leighton <lkcl@samba.org>1997-10-30 01:05:13 +0000
committerLuke Leighton <lkcl@samba.org>1997-10-30 01:05:13 +0000
commita275e5d4e16142a9924f8b97980f364a80df3b64 (patch)
tree037c7e130d66a1c9b34593b6aa2ad51294e02dad
parentcbafcc4d03d960749fdeed111d0f78dadc399095 (diff)
downloadsamba-a275e5d4e16142a9924f8b97980f364a80df3b64.tar.gz
samba-a275e5d4e16142a9924f8b97980f364a80df3b64.tar.bz2
samba-a275e5d4e16142a9924f8b97980f364a80df3b64.zip
removed mechanism that created actual files NETLOGON, lsarpc and the like,
which are pipes on the IPC$ connection. created mechanism to record pipe names in a separate pipes_struct. it is planned to expand this, to return sensible things like interface structures, and policy handles (RPC_IFACE and LSA_POL_HND). and the like. (This used to be commit 33cce5fac0e2f818a19a6c4e6a797ef44f3b5c75)
-rw-r--r--source3/client/ntclient.c2
-rw-r--r--source3/include/proto.h2
-rw-r--r--source3/include/smb.h3
-rw-r--r--source3/lsaparse.c5
-rw-r--r--source3/ntclientpipe.c2
-rw-r--r--source3/smbd/ipc.c15
-rw-r--r--source3/smbd/pipes.c171
-rw-r--r--source3/smbd/reply.c5
8 files changed, 122 insertions, 83 deletions
diff --git a/source3/client/ntclient.c b/source3/client/ntclient.c
index 89775cd3aa..38d96f440c 100644
--- a/source3/client/ntclient.c
+++ b/source3/client/ntclient.c
@@ -110,7 +110,7 @@ BOOL do_nt_login(char *desthost, char *myhostname,
/* create and send a MSRPC command with api LSA_OPENPOLICY */
- DEBUG(4,("LSA RPC Bind[%d]\n", fnum));
+ DEBUG(4,("LSA RPC Bind[%x]\n", fnum));
for (i = 0; i < sizeof(trn_data); i++)
{
diff --git a/source3/include/proto.h b/source3/include/proto.h
index ee7bd41dbd..00c95587ba 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -746,7 +746,9 @@ BOOL api_ntLsarpcTNP(int cnum,int uid, char *param,char *data,
/*The following definitions come from pipes.c */
+char *get_pipe_name(int pnum);
int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize);
+int reply_pipe_close(char *inbuf,char *outbuf);
BOOL api_LsarpcSNPHS(int cnum,int uid, char *param,char *data,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
diff --git a/source3/include/smb.h b/source3/include/smb.h
index 9b54385eee..8f0bd31bf4 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -297,6 +297,7 @@ enum RPC_PKT_TYPE
#define LSA_REQCHAL 0x04
#define LSA_SRVPWSET 0x06
#define LSA_SAMLOGON 0x02
+#define LSA_SAMLOGOFF 0x03
#define LSA_AUTH2 0x0f
#define LSA_CLOSE 0x00
@@ -304,7 +305,6 @@ enum RPC_PKT_TYPE
#define LSA_OPENSECRET 0xFF
#define LSA_LOOKUPSIDS 0xFE
#define LSA_LOOKUPNAMES 0xFD
-#define LSA_SAMLOGOFF 0xFC
/* srvsvc pipe */
#define NETSERVERGETINFO 0x15
@@ -678,6 +678,7 @@ typedef struct object_attributes_info
/* LSA_Q_OPEN_POL - LSA Query Open Policy */
typedef struct lsa_q_open_pol_info
{
+ uint32 ptr; /* undocumented buffer pointer */
UNISTR2 uni_server_name; /* server name, starting with two '\'s */
LSA_OBJ_ATTR attr ; /* object attributes */
diff --git a/source3/lsaparse.c b/source3/lsaparse.c
index 1da67da615..6da21ba5d2 100644
--- a/source3/lsaparse.c
+++ b/source3/lsaparse.c
@@ -35,6 +35,8 @@ void make_q_open_pol(LSA_Q_OPEN_POL *r_q, char *server_name,
DEBUG(5,("make_open_pol\n"));
+ r_q->ptr = 1; /* undocumented pointer */
+
make_unistr2 (&(r_q->uni_server_name), server_name, strlen(server_name));
make_obj_attr(&(r_q->attr ), attributes, sec_qos);
@@ -51,6 +53,8 @@ char* lsa_io_q_open_pol(BOOL io, LSA_Q_OPEN_POL *r_q, char *q, char *base, int a
DEBUG(5,("%s%04x lsa_io_q_open_pol\n", tab_depth(depth), PTR_DIFF(q, base)));
depth++;
+ DBG_RW_IVAL("ptr ", depth, base, io, q, r_q->ptr ); q += 4;
+
q = smb_io_unistr2 (io, &(r_q->uni_server_name), q, base, align, depth);
q = smb_io_obj_attr(io, &(r_q->attr ), q, base, align, depth);
@@ -69,6 +73,7 @@ char* lsa_io_r_open_pol(BOOL io, LSA_R_OPEN_POL *r_p, char *q, char *base, int a
DEBUG(5,("%s%04x lsa_io_r_open_pol\n", tab_depth(depth), PTR_DIFF(q, base)));
depth++;
+
q = smb_io_pol_hnd(io, &(r_p->pol), q, base, align, depth);
DBG_RW_IVAL("status", depth, base, io, q, r_p->status); q += 4;
diff --git a/source3/ntclientpipe.c b/source3/ntclientpipe.c
index 80991cea51..213087bc1f 100644
--- a/source3/ntclientpipe.c
+++ b/source3/ntclientpipe.c
@@ -118,7 +118,7 @@ BOOL bind_rpc_pipe(char *pipe_name, uint16 fnum, uint32 call_id,
if (pipe_name == NULL || abstract == NULL || transfer == NULL) return False;
- DEBUG(5,("Bind RPC Pipe[%d]: %s\n", fnum, pipe_name));
+ DEBUG(5,("Bind RPC Pipe[%x]: %s\n", fnum, pipe_name));
/* create the request RPC_HDR_RB */
make_rpc_hdr_rb(&hdr_rb,
diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c
index 0d57b1ecfe..b525f06046 100644
--- a/source3/smbd/ipc.c
+++ b/source3/smbd/ipc.c
@@ -2903,7 +2903,7 @@ static int api_fd_reply(int cnum,uint16 vuid,char *outbuf,
int i;
int fd;
int subcommand;
- pstring pipe_name;
+ char *pipe_name;
DEBUG(5,("api_fd_reply\n"));
/* First find out the name of this file. */
@@ -2916,14 +2916,11 @@ static int api_fd_reply(int cnum,uint16 vuid,char *outbuf,
/* Get the file handle and hence the file name. */
fd = setup[1];
subcommand = setup[0];
- if (fd >= 0 && fd < MAX_OPEN_FILES)
- {
- pstrcpy(pipe_name, Files[fd].name);
- }
- else
+ pipe_name = get_pipe_name(fd);
+
+ if (pipe_name == NULL)
{
- pipe_name[0] = 0;
- DEBUG(1,("api_fd_reply: INVALID FILE HANDLE: %x\n", fd));
+ DEBUG(1,("api_fd_reply: INVALID PIPE HANDLE: %x\n", fd));
}
DEBUG(3,("Got API command %d on pipe %s (fd %x)",
@@ -2946,7 +2943,7 @@ static int api_fd_reply(int cnum,uint16 vuid,char *outbuf,
rparam = (char *)malloc(1024); if (rparam) bzero(rparam,1024);
#ifdef NTDOMAIN
- if (data != NULL && api_fd_commands[i].subcommand != -1)
+ if (data != NULL && api_fd_commands[i].subcommand == 0x26)
{
RPC_HDR hdr;
diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c
index 901d7e682a..990b25cb0a 100644
--- a/source3/smbd/pipes.c
+++ b/source3/smbd/pipes.c
@@ -37,18 +37,34 @@
/* look in server.c for some explanation of these variables */
extern int Protocol;
extern int DEBUGLEVEL;
-extern int chain_fnum;
extern char magic_char;
-extern connection_struct Connections[];
-extern files_struct Files[];
+static int chain_pnum = -1;
extern BOOL case_sensitive;
extern pstring sesssetup_user;
extern int Client;
extern fstring myworkgroup;
-/* this macro should always be used to extract an fnum (smb_fid) from
-a packet to ensure chaining works correctly */
-#define GETFNUM(buf,where) (chain_fnum!= -1?chain_fnum:SVAL(buf,where))
+#ifndef MAX_OPEN_PIPES
+#define MAX_OPEN_PIPES 50
+#endif
+
+static struct
+{
+ int cnum;
+ BOOL open;
+ fstring name;
+
+} Pipes[MAX_OPEN_PIPES];
+
+#define VALID_PNUM(pnum) (((pnum) >= 0) && ((pnum) < MAX_OPEN_PIPES))
+#define OPEN_PNUM(pnum) (VALID_PNUM(pnum) && Pipes[pnum].open)
+#define PNUM_OK(pnum,c) (OPEN_PNUM(pnum) && (c)==Pipes[pnum].cnum)
+
+#define CHECK_PNUM(pnum,c) if (!PNUM_OK(pnum,c)) \
+ return(ERROR(ERRDOS,ERRbadfid))
+/* this macro should always be used to extract an pnum (smb_fid) from
+ a packet to ensure chaining works correctly */
+#define GETPNUM(buf,where) (chain_pnum!= -1?chain_pnum:SVAL(buf,where))
char * known_pipes [] =
{
@@ -61,13 +77,50 @@ char * known_pipes [] =
};
/****************************************************************************
- reply to an open and X on a named pipe
+ find first available file slot
+****************************************************************************/
+static int find_free_pipe(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++)
+ if (!Pipes[i].open)
+ return(i);
- In fact what we do is to open a regular file with the same name in
- /tmp. This can then be closed as normal. Reading and writing won't
- make much sense, but will do *something*. The real reason for this
- support is to be able to do transactions on them (well, on lsarpc
- for domain login purposes...).
+ DEBUG(1,("ERROR! Out of pipe structures - perhaps increase MAX_OPEN_PIPES?\n"));
+
+ return(-1);
+}
+
+/****************************************************************************
+ gets the name of a pipe
+****************************************************************************/
+char *get_pipe_name(int pnum)
+{
+ DEBUG(6,("get_pipe_name: "));
+
+ if (VALID_PNUM(pnum - 0x800))
+ {
+ DEBUG(6,("name: %s cnum: %d open: %s ",
+ Pipes[pnum - 0x800].name,
+ Pipes[pnum - 0x800].cnum,
+ BOOLSTR(Pipes[pnum - 0x800].open)));
+ }
+ if (OPEN_PNUM(pnum - 0x800))
+ {
+ DEBUG(6,("OK\n"));
+ return Pipes[pnum - 0x800].name;
+ }
+ else
+ {
+ DEBUG(6,("NOT\n"));
+ return NULL;
+ }
+}
+
+/****************************************************************************
+ reply to an open and X on a named pipe
This code is basically stolen from reply_open_and_X with some
wrinkles to handle pipes.
@@ -76,21 +129,10 @@ int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize)
{
pstring fname;
int cnum = SVAL(inbuf,smb_tid);
- int fnum = -1;
- int smb_mode = SVAL(inbuf,smb_vwv3);
- int smb_attr = SVAL(inbuf,smb_vwv5);
-#if 0
- int open_flags = SVAL(inbuf,smb_vwv2);
- int smb_sattr = SVAL(inbuf,smb_vwv4);
- uint32 smb_time = make_unix_date3(inbuf+smb_vwv6);
-#endif
+ int pnum = -1;
int smb_ofun = SVAL(inbuf,smb_vwv8);
- int unixmode;
int size=0,fmode=0,mtime=0,rmode=0;
- struct stat sbuf;
- int smb_action = 0;
int i;
- BOOL bad_path = False;
/* XXXX we need to handle passed times, sattr and flags */
pstrcpy(fname,smb_buf(inbuf));
@@ -117,80 +159,67 @@ int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize)
/* Known pipes arrive with DIR attribs. Remove it so a regular file */
/* can be opened and add it in after the open. */
DEBUG(3,("Known pipe %s opening.\n",fname));
- smb_attr &= ~aDIR;
- Connections[cnum].read_only = 0;
smb_ofun |= 0x10; /* Add Create it not exists flag */
- unix_convert(fname,cnum,0,&bad_path);
-
- fnum = find_free_file();
- if (fnum < 0)
- return(ERROR(ERRSRV,ERRnofids));
-
- if (!check_name(fname,cnum))
- return(UNIXERROR(ERRDOS,ERRnoaccess));
-
- unixmode = unix_mode(cnum,smb_attr);
-
- open_file_shared(fnum,cnum,fname,smb_mode,smb_ofun,unixmode,
- 0, &rmode,&smb_action);
-
- if (!Files[fnum].open)
- {
- /* Change the error code if bad_path was set. */
- if((errno == ENOENT) && bad_path)
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
-
- if (fstat(Files[fnum].fd_ptr->fd,&sbuf) != 0) {
- close_file(fnum,False);
- return(ERROR(ERRDOS,ERRnoaccess));
- }
+ pnum = find_free_pipe();
+ if (pnum < 0) return(ERROR(ERRSRV,ERRnofids));
- size = sbuf.st_size;
- fmode = dos_mode(cnum,fname,&sbuf);
- mtime = sbuf.st_mtime;
- if (fmode & aDIR) {
- close_file(fnum,False);
- return(ERROR(ERRDOS,ERRnoaccess));
- }
+ Pipes[pnum].open = True;
+ Pipes[pnum].cnum = cnum;
+ fstrcpy(Pipes[pnum].name, fname);
/* Prepare the reply */
set_message(outbuf,15,0,True);
- /* Put things back the way they were. */
- Connections[cnum].read_only = 1;
-
/* Mark the opened file as an existing named pipe in message mode. */
SSVAL(outbuf,smb_vwv9,2);
SSVAL(outbuf,smb_vwv10,0xc700);
+
if (rmode == 2)
{
DEBUG(4,("Resetting open result to open from create.\n"));
rmode = 1;
}
- SSVAL(outbuf,smb_vwv2,fnum);
+ SSVAL(outbuf,smb_vwv2, pnum + 0x800); /* mark file handle up into high range */
SSVAL(outbuf,smb_vwv3,fmode);
put_dos_date3(outbuf,smb_vwv4,mtime);
SIVAL(outbuf,smb_vwv6,size);
SSVAL(outbuf,smb_vwv8,rmode);
- SSVAL(outbuf,smb_vwv11,smb_action);
-
- chain_fnum = fnum;
+ SSVAL(outbuf,smb_vwv11,0);
- DEBUG(4,("Opened pipe %s with handle %d, saved name %s.\n",
- fname, fnum, Files[fnum].name));
+ DEBUG(4,("Opened pipe %s with handle %x name %s.\n",
+ fname, pnum + 0x800, Pipes[pnum].name));
+ chain_pnum = pnum;
+
return chain_reply(inbuf,outbuf,length,bufsize);
}
/****************************************************************************
+ reply to a close
+****************************************************************************/
+int reply_pipe_close(char *inbuf,char *outbuf)
+{
+ int pnum = GETPNUM(inbuf,smb_vwv0);
+ int cnum = SVAL(inbuf,smb_tid);
+ int outsize = set_message(outbuf,0,0,True);
+
+ /* mapping is 0x800 up... */
+
+ CHECK_PNUM(pnum-0x800,cnum);
+
+ DEBUG(3,("%s Closed pipe name %s pnum=%d cnum=%d\n",
+ timestring(),Pipes[pnum-0x800].name, pnum,cnum));
+
+ Pipes[pnum-0x800].open = False;
+
+ return(outsize);
+}
+
+
+/****************************************************************************
api_LsarpcSNPHS
SetNamedPipeHandleState on \PIPE\lsarpc. We can't really do much here,
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 9484f3b85f..46425861d4 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -2283,7 +2283,12 @@ int reply_close(char *inbuf,char *outbuf)
cnum = SVAL(inbuf,smb_tid);
+ /* If it's an IPC, pass off to the pipe handler. */
+ if (IS_IPC(cnum))
+ return reply_pipe_close(inbuf,outbuf);
+
fnum = GETFNUM(inbuf,smb_vwv0);
+
CHECK_FNUM(fnum,cnum);
if(HAS_CACHED_ERROR(fnum)) {