2 Unix SMB/Netbios implementation.
4 Pipe SMB reply routines
5 Copyright (C) Andrew Tridgell 1992-1997,
6 Copyright (C) Luke Kenneth Casson Leighton 1996-1997.
7 Copyright (C) Paul Ashton 1997.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 This file handles reply_ calls on named pipes that the server
25 makes to handle specific protocols
32 #define PIPE "\\PIPE\\"
33 #define PIPELEN strlen(PIPE)
35 #define REALLOC(ptr,size) Realloc(ptr,MAX((size),4*1024))
37 /* look in server.c for some explanation of these variables */
39 extern int DEBUGLEVEL;
40 extern char magic_char;
41 extern BOOL case_sensitive;
42 extern pstring sesssetup_user;
44 extern fstring myworkgroup;
46 #define VALID_PNUM(pnum) (((pnum) >= 0) && ((pnum) < MAX_OPEN_PIPES))
47 #define OPEN_PNUM(pnum) (VALID_PNUM(pnum) && Pipes[pnum].open)
48 #define PNUM_OK(pnum,c) (OPEN_PNUM(pnum) && (c)==Pipes[pnum].cnum)
50 /* this macro should always be used to extract an pnum (smb_fid) from
51 a packet to ensure chaining works correctly */
52 #define GETPNUM(buf,where) (chain_pnum!= -1?chain_pnum:SVAL(buf,where))
54 char * known_pipes [] =
66 /****************************************************************************
67 reply to an open and X on a named pipe
69 This code is basically stolen from reply_open_and_X with some
70 wrinkles to handle pipes.
71 ****************************************************************************/
72 int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize)
75 int cnum = SVAL(inbuf,smb_tid);
77 int smb_ofun = SVAL(inbuf,smb_vwv8);
78 int size=0,fmode=0,mtime=0,rmode=0;
81 /* XXXX we need to handle passed times, sattr and flags */
82 pstrcpy(fname,smb_buf(inbuf));
84 /* If the name doesn't start \PIPE\ then this is directed */
85 /* at a mailslot or something we really, really don't understand, */
86 /* not just something we really don't understand. */
87 if ( strncmp(fname,PIPE,PIPELEN) != 0 )
88 return(ERROR(ERRSRV,ERRaccess));
90 DEBUG(4,("Opening pipe %s.\n", fname));
92 /* Strip \PIPE\ off the name. */
93 pstrcpy(fname,smb_buf(inbuf) + PIPELEN);
95 /* See if it is one we want to handle. */
96 for( i = 0; known_pipes[i] ; i++ )
97 if( strcmp(fname,known_pipes[i]) == 0 )
100 if ( known_pipes[i] == NULL )
101 return(ERROR(ERRSRV,ERRaccess));
103 /* Known pipes arrive with DIR attribs. Remove it so a regular file */
104 /* can be opened and add it in after the open. */
105 DEBUG(3,("Known pipe %s opening.\n",fname));
106 smb_ofun |= 0x10; /* Add Create it not exists flag */
108 pnum = open_rpc_pipe_hnd(fname, cnum);
109 if (pnum < 0) return(ERROR(ERRSRV,ERRnofids));
111 /* Prepare the reply */
112 set_message(outbuf,15,0,True);
114 /* Mark the opened file as an existing named pipe in message mode. */
115 SSVAL(outbuf,smb_vwv9,2);
116 SSVAL(outbuf,smb_vwv10,0xc700);
120 DEBUG(4,("Resetting open result to open from create.\n"));
124 SSVAL(outbuf,smb_vwv2, pnum + 0x800); /* mark file handle up into high range */
125 SSVAL(outbuf,smb_vwv3,fmode);
126 put_dos_date3(outbuf,smb_vwv4,mtime);
127 SIVAL(outbuf,smb_vwv6,size);
128 SSVAL(outbuf,smb_vwv8,rmode);
129 SSVAL(outbuf,smb_vwv11,0);
131 return chain_reply(inbuf,outbuf,length,bufsize);
135 /****************************************************************************
137 ****************************************************************************/
138 int reply_pipe_close(char *inbuf,char *outbuf)
140 int pnum = get_rpc_pipe_num(inbuf,smb_vwv0);
141 int cnum = SVAL(inbuf,smb_tid);
142 int outsize = set_message(outbuf,0,0,True);
144 DEBUG(5,("reply_pipe_close: pnum:%x cnum:%x\n", pnum, cnum));
146 if (!close_rpc_pipe_hnd(pnum, cnum)) return(ERROR(ERRDOS,ERRbadfid));
152 /****************************************************************************
155 SetNamedPipeHandleState on \PIPE\lsarpc.
156 ****************************************************************************/
157 BOOL api_LsarpcSNPHS(int pnum, int cnum, char *param)
161 if (!param) return False;
163 id = param[0] + (param[1] << 8);
164 DEBUG(4,("lsarpc SetNamedPipeHandleState to code %x\n",id));
166 return set_rpc_pipe_hnd_state(pnum, cnum, id);
170 /****************************************************************************
173 TransactNamedPipe on \PIPE\lsarpc.
174 ****************************************************************************/
175 static void LsarpcTNP1(char *data,char **rdata, int *rdata_len)
177 uint32 dword1, dword2;
178 char pname[] = "\\PIPE\\lsass";
180 /* All kinds of mysterious numbers here */
182 *rdata = REALLOC(*rdata,*rdata_len);
184 dword1 = IVAL(data,0xC);
185 dword2 = IVAL(data,0x10);
187 SIVAL(*rdata,0,0xc0005);
188 SIVAL(*rdata,4,0x10);
189 SIVAL(*rdata,8,0x44);
190 SIVAL(*rdata,0xC,dword1);
192 SIVAL(*rdata,0x10,dword2);
193 SIVAL(*rdata,0x14,0x15);
194 SSVAL(*rdata,0x18,sizeof(pname));
195 strcpy(*rdata + 0x1a,pname);
196 SIVAL(*rdata,0x28,1);
197 memcpy(*rdata + 0x30, data + 0x34, 0x14);
200 static void LsarpcTNP2(char *data,char **rdata, int *rdata_len)
204 /* All kinds of mysterious numbers here */
206 *rdata = REALLOC(*rdata,*rdata_len);
208 dword1 = IVAL(data,0xC);
210 SIVAL(*rdata,0,0x03020005);
211 SIVAL(*rdata,4,0x10);
212 SIVAL(*rdata,8,0x30);
213 SIVAL(*rdata,0xC,dword1);
214 SIVAL(*rdata,0x10,0x18);
215 SIVAL(*rdata,0x1c,0x44332211);
216 SIVAL(*rdata,0x20,0x88776655);
217 SIVAL(*rdata,0x24,0xCCBBAA99);
218 SIVAL(*rdata,0x28,0x11FFEEDD);
221 static void LsarpcTNP3(char *data,char **rdata, int *rdata_len)
225 char * workgroup = myworkgroup;
226 int wglen = strlen(workgroup);
229 /* All kinds of mysterious numbers here */
230 *rdata_len = 90 + 2 * wglen;
231 *rdata = REALLOC(*rdata,*rdata_len);
233 dword1 = IVAL(data,0xC);
234 word1 = SVAL(data,0x2C);
236 SIVAL(*rdata,0,0x03020005);
237 SIVAL(*rdata,4,0x10);
238 SIVAL(*rdata,8,0x60);
239 SIVAL(*rdata,0xC,dword1);
240 SIVAL(*rdata,0x10,0x48);
241 SSVAL(*rdata,0x18,0x5988); /* This changes */
242 SSVAL(*rdata,0x1A,0x15);
243 SSVAL(*rdata,0x1C,word1);
244 SSVAL(*rdata,0x20,6);
245 SSVAL(*rdata,0x22,8);
246 SSVAL(*rdata,0x24,0x8E8); /* So does this */
247 SSVAL(*rdata,0x26,0x15);
248 SSVAL(*rdata,0x28,0x4D48); /* And this */
249 SSVAL(*rdata,0x2A,0x15);
250 SIVAL(*rdata,0x2C,4);
251 SIVAL(*rdata,0x34,wglen);
252 for ( i = 0 ; i < wglen ; i++ )
253 (*rdata)[0x38 + i * 2] = workgroup[i];
255 /* Now fill in the rest */
256 i = 0x38 + wglen * 2;
257 SSVAL(*rdata,i,0x648);
259 SIVAL(*rdata,i+6,0x401);
260 SSVAL(*rdata,i+0xC,0x500);
261 SIVAL(*rdata,i+0xE,0x15);
262 SIVAL(*rdata,i+0x12,0x2372FE1);
263 SIVAL(*rdata,i+0x16,0x7E831BEF);
264 SIVAL(*rdata,i+0x1A,0x4B454B2);
267 static void LsarpcTNP4(char *data,char **rdata, int *rdata_len)
271 /* All kinds of mysterious numbers here */
273 *rdata = REALLOC(*rdata,*rdata_len);
275 dword1 = IVAL(data,0xC);
277 SIVAL(*rdata,0,0x03020005);
278 SIVAL(*rdata,4,0x10);
279 SIVAL(*rdata,8,0x30);
280 SIVAL(*rdata,0xC,dword1);
281 SIVAL(*rdata,0x10,0x18);
285 BOOL api_LsarpcTNP(int cnum,int uid, char *param,char *data,
286 int mdrcnt,int mprcnt,
287 char **rdata,char **rparam,
288 int *rdata_len,int *rparam_len)
294 DEBUG(4,("lsarpc TransactNamedPipe id %lx\n",id));
298 LsarpcTNP1(data,rdata,rdata_len);
303 DEBUG(4,("\t- Suboperation %lx\n",id2));
307 LsarpcTNP2(data,rdata,rdata_len);
311 LsarpcTNP4(data,rdata,rdata_len);
315 LsarpcTNP3(data,rdata,rdata_len);