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 static int chain_pnum = -1;
42 extern BOOL case_sensitive;
43 extern pstring sesssetup_user;
45 extern fstring myworkgroup;
47 #ifndef MAX_OPEN_PIPES
48 #define MAX_OPEN_PIPES 50
57 } Pipes[MAX_OPEN_PIPES];
59 #define VALID_PNUM(pnum) (((pnum) >= 0) && ((pnum) < MAX_OPEN_PIPES))
60 #define OPEN_PNUM(pnum) (VALID_PNUM(pnum) && Pipes[pnum].open)
61 #define PNUM_OK(pnum,c) (OPEN_PNUM(pnum) && (c)==Pipes[pnum].cnum)
63 #define CHECK_PNUM(pnum,c) if (!PNUM_OK(pnum,c)) \
64 return(ERROR(ERRDOS,ERRbadfid))
65 /* this macro should always be used to extract an pnum (smb_fid) from
66 a packet to ensure chaining works correctly */
67 #define GETPNUM(buf,where) (chain_pnum!= -1?chain_pnum:SVAL(buf,where))
69 char * known_pipes [] =
79 /****************************************************************************
80 find first available file slot
81 ****************************************************************************/
82 static int find_free_pipe(void )
85 /* we start at 1 here for an obscure reason I can't now remember,
86 but I think is important :-) */
87 for (i = 1; i < MAX_OPEN_PIPES; i++)
91 DEBUG(1,("ERROR! Out of pipe structures - perhaps increase MAX_OPEN_PIPES?\n"));
96 /****************************************************************************
97 gets the name of a pipe
98 ****************************************************************************/
99 char *get_pipe_name(int pnum)
101 DEBUG(6,("get_pipe_name: "));
103 if (VALID_PNUM(pnum - 0x800))
105 DEBUG(6,("name: %s cnum: %d open: %s ",
106 Pipes[pnum - 0x800].name,
107 Pipes[pnum - 0x800].cnum,
108 BOOLSTR(Pipes[pnum - 0x800].open)));
110 if (OPEN_PNUM(pnum - 0x800))
113 return Pipes[pnum - 0x800].name;
122 /****************************************************************************
123 reply to an open and X on a named pipe
125 This code is basically stolen from reply_open_and_X with some
126 wrinkles to handle pipes.
127 ****************************************************************************/
128 int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize)
131 int cnum = SVAL(inbuf,smb_tid);
133 int smb_ofun = SVAL(inbuf,smb_vwv8);
134 int size=0,fmode=0,mtime=0,rmode=0;
137 /* XXXX we need to handle passed times, sattr and flags */
138 pstrcpy(fname,smb_buf(inbuf));
140 /* If the name doesn't start \PIPE\ then this is directed */
141 /* at a mailslot or something we really, really don't understand, */
142 /* not just something we really don't understand. */
143 if ( strncmp(fname,PIPE,PIPELEN) != 0 )
144 return(ERROR(ERRSRV,ERRaccess));
146 DEBUG(4,("Opening pipe %s.\n", fname));
148 /* Strip \PIPE\ off the name. */
149 pstrcpy(fname,smb_buf(inbuf) + PIPELEN);
151 /* See if it is one we want to handle. */
152 for( i = 0; known_pipes[i] ; i++ )
153 if( strcmp(fname,known_pipes[i]) == 0 )
156 if ( known_pipes[i] == NULL )
157 return(ERROR(ERRSRV,ERRaccess));
159 /* Known pipes arrive with DIR attribs. Remove it so a regular file */
160 /* can be opened and add it in after the open. */
161 DEBUG(3,("Known pipe %s opening.\n",fname));
162 smb_ofun |= 0x10; /* Add Create it not exists flag */
164 pnum = find_free_pipe();
165 if (pnum < 0) return(ERROR(ERRSRV,ERRnofids));
167 Pipes[pnum].open = True;
168 Pipes[pnum].cnum = cnum;
169 fstrcpy(Pipes[pnum].name, fname);
171 /* Prepare the reply */
172 set_message(outbuf,15,0,True);
174 /* Mark the opened file as an existing named pipe in message mode. */
175 SSVAL(outbuf,smb_vwv9,2);
176 SSVAL(outbuf,smb_vwv10,0xc700);
180 DEBUG(4,("Resetting open result to open from create.\n"));
184 SSVAL(outbuf,smb_vwv2, pnum + 0x800); /* mark file handle up into high range */
185 SSVAL(outbuf,smb_vwv3,fmode);
186 put_dos_date3(outbuf,smb_vwv4,mtime);
187 SIVAL(outbuf,smb_vwv6,size);
188 SSVAL(outbuf,smb_vwv8,rmode);
189 SSVAL(outbuf,smb_vwv11,0);
191 DEBUG(4,("Opened pipe %s with handle %x name %s.\n",
192 fname, pnum + 0x800, Pipes[pnum].name));
196 return chain_reply(inbuf,outbuf,length,bufsize);
200 /****************************************************************************
202 ****************************************************************************/
203 int reply_pipe_close(char *inbuf,char *outbuf)
205 int pnum = GETPNUM(inbuf,smb_vwv0);
206 int cnum = SVAL(inbuf,smb_tid);
207 int outsize = set_message(outbuf,0,0,True);
209 /* mapping is 0x800 up... */
211 CHECK_PNUM(pnum-0x800,cnum);
213 DEBUG(3,("%s Closed pipe name %s pnum=%d cnum=%d\n",
214 timestring(),Pipes[pnum-0x800].name, pnum,cnum));
216 Pipes[pnum-0x800].open = False;
222 /****************************************************************************
225 SetNamedPipeHandleState on \PIPE\lsarpc. We can't really do much here,
226 so just blithely return True. This is really only for NT domain stuff,
227 we we're only handling that - don't assume Samba now does complete
229 ****************************************************************************/
230 BOOL api_LsarpcSNPHS(int cnum,int uid, char *param,char *data,
231 int mdrcnt,int mprcnt,
232 char **rdata,char **rparam,
233 int *rdata_len,int *rparam_len)
237 id = param[0] + (param[1] << 8);
238 DEBUG(4,("lsarpc SetNamedPipeHandleState to code %x\n",id));
243 /****************************************************************************
246 TransactNamedPipe on \PIPE\lsarpc.
247 ****************************************************************************/
248 static void LsarpcTNP1(char *data,char **rdata, int *rdata_len)
250 uint32 dword1, dword2;
251 char pname[] = "\\PIPE\\lsass";
253 /* All kinds of mysterious numbers here */
255 *rdata = REALLOC(*rdata,*rdata_len);
257 dword1 = IVAL(data,0xC);
258 dword2 = IVAL(data,0x10);
260 SIVAL(*rdata,0,0xc0005);
261 SIVAL(*rdata,4,0x10);
262 SIVAL(*rdata,8,0x44);
263 SIVAL(*rdata,0xC,dword1);
265 SIVAL(*rdata,0x10,dword2);
266 SIVAL(*rdata,0x14,0x15);
267 SSVAL(*rdata,0x18,sizeof(pname));
268 strcpy(*rdata + 0x1a,pname);
269 SIVAL(*rdata,0x28,1);
270 memcpy(*rdata + 0x30, data + 0x34, 0x14);
273 static void LsarpcTNP2(char *data,char **rdata, int *rdata_len)
277 /* All kinds of mysterious numbers here */
279 *rdata = REALLOC(*rdata,*rdata_len);
281 dword1 = IVAL(data,0xC);
283 SIVAL(*rdata,0,0x03020005);
284 SIVAL(*rdata,4,0x10);
285 SIVAL(*rdata,8,0x30);
286 SIVAL(*rdata,0xC,dword1);
287 SIVAL(*rdata,0x10,0x18);
288 SIVAL(*rdata,0x1c,0x44332211);
289 SIVAL(*rdata,0x20,0x88776655);
290 SIVAL(*rdata,0x24,0xCCBBAA99);
291 SIVAL(*rdata,0x28,0x11FFEEDD);
294 static void LsarpcTNP3(char *data,char **rdata, int *rdata_len)
298 char * workgroup = myworkgroup;
299 int wglen = strlen(workgroup);
302 /* All kinds of mysterious numbers here */
303 *rdata_len = 90 + 2 * wglen;
304 *rdata = REALLOC(*rdata,*rdata_len);
306 dword1 = IVAL(data,0xC);
307 word1 = SVAL(data,0x2C);
309 SIVAL(*rdata,0,0x03020005);
310 SIVAL(*rdata,4,0x10);
311 SIVAL(*rdata,8,0x60);
312 SIVAL(*rdata,0xC,dword1);
313 SIVAL(*rdata,0x10,0x48);
314 SSVAL(*rdata,0x18,0x5988); /* This changes */
315 SSVAL(*rdata,0x1A,0x15);
316 SSVAL(*rdata,0x1C,word1);
317 SSVAL(*rdata,0x20,6);
318 SSVAL(*rdata,0x22,8);
319 SSVAL(*rdata,0x24,0x8E8); /* So does this */
320 SSVAL(*rdata,0x26,0x15);
321 SSVAL(*rdata,0x28,0x4D48); /* And this */
322 SSVAL(*rdata,0x2A,0x15);
323 SIVAL(*rdata,0x2C,4);
324 SIVAL(*rdata,0x34,wglen);
325 for ( i = 0 ; i < wglen ; i++ )
326 (*rdata)[0x38 + i * 2] = workgroup[i];
328 /* Now fill in the rest */
329 i = 0x38 + wglen * 2;
330 SSVAL(*rdata,i,0x648);
332 SIVAL(*rdata,i+6,0x401);
333 SSVAL(*rdata,i+0xC,0x500);
334 SIVAL(*rdata,i+0xE,0x15);
335 SIVAL(*rdata,i+0x12,0x2372FE1);
336 SIVAL(*rdata,i+0x16,0x7E831BEF);
337 SIVAL(*rdata,i+0x1A,0x4B454B2);
340 static void LsarpcTNP4(char *data,char **rdata, int *rdata_len)
344 /* All kinds of mysterious numbers here */
346 *rdata = REALLOC(*rdata,*rdata_len);
348 dword1 = IVAL(data,0xC);
350 SIVAL(*rdata,0,0x03020005);
351 SIVAL(*rdata,4,0x10);
352 SIVAL(*rdata,8,0x30);
353 SIVAL(*rdata,0xC,dword1);
354 SIVAL(*rdata,0x10,0x18);
358 BOOL api_LsarpcTNP(int cnum,int uid, char *param,char *data,
359 int mdrcnt,int mprcnt,
360 char **rdata,char **rparam,
361 int *rdata_len,int *rparam_len)
367 DEBUG(4,("lsarpc TransactNamedPipe id %lx\n",id));
371 LsarpcTNP1(data,rdata,rdata_len);
376 DEBUG(4,("\t- Suboperation %lx\n",id2));
380 LsarpcTNP2(data,rdata,rdata_len);
384 LsarpcTNP4(data,rdata,rdata_len);
388 LsarpcTNP3(data,rdata,rdata_len);