From 33cce5fac0e2f818a19a6c4e6a797ef44f3b5c75 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 30 Oct 1997 01:05:13 +0000 Subject: 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. --- source/client/ntclient.c | 2 +- source/include/proto.h | 2 + source/include/smb.h | 3 +- source/lsaparse.c | 5 ++ source/ntclientpipe.c | 2 +- source/smbd/ipc.c | 15 ++--- source/smbd/pipes.c | 171 +++++++++++++++++++++++++++-------------------- source/smbd/reply.c | 5 ++ 8 files changed, 122 insertions(+), 83 deletions(-) diff --git a/source/client/ntclient.c b/source/client/ntclient.c index 89775cd3aac..38d96f440c5 100644 --- a/source/client/ntclient.c +++ b/source/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/source/include/proto.h b/source/include/proto.h index ee7bd41dbdc..00c95587ba5 100644 --- a/source/include/proto.h +++ b/source/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/source/include/smb.h b/source/include/smb.h index 9b54385eeee..8f0bd31bf4d 100644 --- a/source/include/smb.h +++ b/source/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/source/lsaparse.c b/source/lsaparse.c index 1da67da6155..6da21ba5d2a 100644 --- a/source/lsaparse.c +++ b/source/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/source/ntclientpipe.c b/source/ntclientpipe.c index 80991cea517..213087bc1ff 100644 --- a/source/ntclientpipe.c +++ b/source/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/source/smbd/ipc.c b/source/smbd/ipc.c index 0d57b1ecfee..b525f06046e 100644 --- a/source/smbd/ipc.c +++ b/source/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/source/smbd/pipes.c b/source/smbd/pipes.c index 901d7e682ab..990b25cb0ae 100644 --- a/source/smbd/pipes.c +++ b/source/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,79 +159,66 @@ 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 diff --git a/source/smbd/reply.c b/source/smbd/reply.c index 9484f3b85fe..46425861d42 100644 --- a/source/smbd/reply.c +++ b/source/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)) { -- cgit