2 Unix SMB/Netbios implementation.
4 Pipe SMB reply routines
5 Copyright (C) Andrew Tridgell 1992-1995
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 This file handles reply_ calls on named pipes that the server
23 makes to handle specific protocols
30 #define PIPE "\\PIPE\\"
31 #define PIPELEN strlen(PIPE)
33 #define REALLOC(ptr,size) Realloc(ptr,MAX((size),4*1024))
35 /* look in server.c for some explanation of these variables */
37 extern int DEBUGLEVEL;
38 extern int chain_size;
40 extern int chain_fnum;
41 extern char magic_char;
42 extern connection_struct Connections[];
43 extern files_struct Files[];
44 extern BOOL case_sensitive;
45 extern pstring sesssetup_user;
48 /* this macro should always be used to extract an fnum (smb_fid) from
49 a packet to ensure chaining works correctly */
50 #define GETFNUM(buf,where) (chain_fnum!= -1?chain_fnum:SVAL(buf,where))
52 char * known_pipes [] =
58 /****************************************************************************
59 reply to an open and X on a named pipe
61 In fact what we do is to open a regular file with the same name in
62 /tmp. This can then be closed as normal. Reading and writing won't
63 make much sense, but will do *something*. The real reason for this
64 support is to be able to do transactions on them (well, on lsarpc
65 for domain login purposes...).
67 This code is basically stolen from reply_open_and_X with some
68 wrinkles to handle pipes.
69 ****************************************************************************/
70 int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize)
73 int cnum = SVAL(inbuf,smb_tid);
76 int smb_com2 = CVAL(inbuf,smb_vwv0);
77 int smb_off2 = SVAL(inbuf,smb_vwv1);
78 int smb_mode = SVAL(inbuf,smb_vwv3);
79 int smb_attr = SVAL(inbuf,smb_vwv5);
81 int open_flags = SVAL(inbuf,smb_vwv2);
82 int smb_sattr = SVAL(inbuf,smb_vwv4);
83 uint32 smb_time = make_unix_date3(inbuf+smb_vwv6);
85 int smb_ofun = SVAL(inbuf,smb_vwv8);
87 int size=0,fmode=0,mtime=0,rmode=0;
92 /* XXXX we need to handle passed times, sattr and flags */
93 strcpy(fname,smb_buf(inbuf));
95 /* If the name doesn't start \PIPE\ then this is directed */
96 /* at a mailslot or something we really, really don't understand, */
97 /* not just something we really don't understand. */
98 if ( strncmp(fname,PIPE,PIPELEN) != 0 )
99 return(ERROR(ERRSRV,ERRaccess));
101 DEBUG(4,("Opening pipe %s.\n", fname));
103 /* Strip \PIPE\ off the name. */
104 strcpy(fname,smb_buf(inbuf) + PIPELEN);
106 /* See if it is one we want to handle. */
107 for( i = 0; known_pipes[i] ; i++ )
108 if( strcmp(fname,known_pipes[i]) == 0 )
111 if ( known_pipes[i] == NULL )
112 return(ERROR(ERRSRV,ERRaccess));
114 /* Known pipes arrive with DIR attribs. Remove it so a regular file */
115 /* can be opened and add it in after the open. */
116 DEBUG(3,("Known pipe %s opening.\n",fname));
118 Connections[cnum].read_only = 0;
119 smb_ofun |= 0x10; /* Add Create it not exists flag */
121 unix_convert(fname,cnum);
123 fnum = find_free_file();
125 return(ERROR(ERRSRV,ERRnofids));
127 if (!check_name(fname,cnum))
128 return(UNIXERROR(ERRDOS,ERRnoaccess));
130 unixmode = unix_mode(cnum,smb_attr);
132 open_file_shared(fnum,cnum,fname,smb_mode,smb_ofun,unixmode,
135 if (!Files[fnum].open)
136 return(UNIXERROR(ERRDOS,ERRnoaccess));
138 if (fstat(Files[fnum].fd,&sbuf) != 0) {
140 return(ERROR(ERRDOS,ERRnoaccess));
144 fmode = dos_mode(cnum,fname,&sbuf);
145 mtime = sbuf.st_mtime;
148 return(ERROR(ERRDOS,ERRnoaccess));
151 /* Prepare the reply */
152 outsize = set_message(outbuf,15,0,True);
153 CVAL(outbuf,smb_vwv0) = smb_com2;
155 /* Put things back the way they were. */
156 Connections[cnum].read_only = 1;
158 /* Mark the opened file as an existing named pipe in message mode. */
159 SSVAL(outbuf,smb_vwv9,2);
160 SSVAL(outbuf,smb_vwv10,0xc700);
163 DEBUG(4,("Resetting open result to open from create.\n"));
167 SSVAL(outbuf,smb_vwv1,(chain_size+outsize)-4);
168 SSVAL(outbuf,smb_vwv2,fnum);
169 SSVAL(outbuf,smb_vwv3,fmode);
170 put_dos_date3(outbuf,smb_vwv4,mtime);
171 SIVAL(outbuf,smb_vwv6,size);
172 SSVAL(outbuf,smb_vwv8,rmode);
173 SSVAL(outbuf,smb_vwv11,smb_action);
177 if (smb_com2 != 0xFF)
178 outsize += chain_reply(smb_com2,inbuf,inbuf+smb_off2+4,
179 outbuf,outbuf+outsize,
184 DEBUG(4,("Opened pipe %s with handle %d, saved name %s.\n",
185 fname, fnum, Files[fnum].name));
191 /****************************************************************************
194 SetNamedPipeHandleState on \PIPE\lsarpc. We can't really do much here,
195 so just blithely return True. This is really only for NT domain stuff,
196 we we're only handling that - don't assume Samba now does complete
198 ****************************************************************************/
199 BOOL api_LsarpcSNPHS(int cnum,int uid, char *param,char *data,
200 int mdrcnt,int mprcnt,
201 char **rdata,char **rparam,
202 int *rdata_len,int *rparam_len)
206 id = param[0] + (param[1] << 8);
207 DEBUG(4,("lsarpc SetNamedPipeHandleState to code %x\n",id));
212 /****************************************************************************
215 TransactNamedPipe on \PIPE\lsarpc.
216 ****************************************************************************/
217 static void LsarpcTNP1(char *data,char **rdata, int *rdata_len)
219 uint32 dword1, dword2;
220 char pname[] = "\\PIPE\\lsass";
222 /* All kinds of mysterious numbers here */
224 *rdata = REALLOC(*rdata,*rdata_len);
226 dword1 = IVAL(data,0xC);
227 dword2 = IVAL(data,0x10);
229 SIVAL(*rdata,0,0xc0005);
230 SIVAL(*rdata,4,0x10);
231 SIVAL(*rdata,8,0x44);
232 SIVAL(*rdata,0xC,dword1);
234 SIVAL(*rdata,0x10,dword2);
235 SIVAL(*rdata,0x14,0x15);
236 SSVAL(*rdata,0x18,sizeof(pname));
237 strcpy(*rdata + 0x1a,pname);
238 SIVAL(*rdata,0x28,1);
239 memcpy(*rdata + 0x30, data + 0x34, 0x14);
242 static void LsarpcTNP2(char *data,char **rdata, int *rdata_len)
246 /* All kinds of mysterious numbers here */
248 *rdata = REALLOC(*rdata,*rdata_len);
250 dword1 = IVAL(data,0xC);
252 SIVAL(*rdata,0,0x03020005);
253 SIVAL(*rdata,4,0x10);
254 SIVAL(*rdata,8,0x30);
255 SIVAL(*rdata,0xC,dword1);
256 SIVAL(*rdata,0x10,0x18);
257 SIVAL(*rdata,0x1c,0x44332211);
258 SIVAL(*rdata,0x20,0x88776655);
259 SIVAL(*rdata,0x24,0xCCBBAA99);
260 SIVAL(*rdata,0x28,0x11FFEEDD);
263 static void LsarpcTNP3(char *data,char **rdata, int *rdata_len)
267 char * workgroup = lp_workgroup();
268 int wglen = strlen(workgroup);
271 /* All kinds of mysterious numbers here */
272 *rdata_len = 90 + 2 * wglen;
273 *rdata = REALLOC(*rdata,*rdata_len);
275 dword1 = IVAL(data,0xC);
276 word1 = SVAL(data,0x2C);
278 SIVAL(*rdata,0,0x03020005);
279 SIVAL(*rdata,4,0x10);
280 SIVAL(*rdata,8,0x60);
281 SIVAL(*rdata,0xC,dword1);
282 SIVAL(*rdata,0x10,0x48);
283 SSVAL(*rdata,0x18,0x5988); /* This changes */
284 SSVAL(*rdata,0x1A,0x15);
285 SSVAL(*rdata,0x1C,word1);
286 SSVAL(*rdata,0x20,6);
287 SSVAL(*rdata,0x22,8);
288 SSVAL(*rdata,0x24,0x8E8); /* So does this */
289 SSVAL(*rdata,0x26,0x15);
290 SSVAL(*rdata,0x28,0x4D48); /* And this */
291 SSVAL(*rdata,0x2A,0x15);
292 SIVAL(*rdata,0x2C,4);
293 SIVAL(*rdata,0x34,wglen);
294 for ( i = 0 ; i < wglen ; i++ )
295 (*rdata)[0x38 + i * 2] = workgroup[i];
297 /* Now fill in the rest */
298 i = 0x38 + wglen * 2;
299 SSVAL(*rdata,i,0x648);
301 SIVAL(*rdata,i+6,0x401);
302 SSVAL(*rdata,i+0xC,0x500);
303 SIVAL(*rdata,i+0xE,0x15);
304 SIVAL(*rdata,i+0x12,0x2372FE1);
305 SIVAL(*rdata,i+0x16,0x7E831BEF);
306 SIVAL(*rdata,i+0x1A,0x4B454B2);
309 static void LsarpcTNP4(char *data,char **rdata, int *rdata_len)
313 /* All kinds of mysterious numbers here */
315 *rdata = REALLOC(*rdata,*rdata_len);
317 dword1 = IVAL(data,0xC);
319 SIVAL(*rdata,0,0x03020005);
320 SIVAL(*rdata,4,0x10);
321 SIVAL(*rdata,8,0x30);
322 SIVAL(*rdata,0xC,dword1);
323 SIVAL(*rdata,0x10,0x18);
327 BOOL api_LsarpcTNP(int cnum,int uid, char *param,char *data,
328 int mdrcnt,int mprcnt,
329 char **rdata,char **rparam,
330 int *rdata_len,int *rparam_len)
336 DEBUG(4,("lsarpc TransactNamedPipe id %lx\n",id));
340 LsarpcTNP1(data,rdata,rdata_len);
345 DEBUG(4,("\t- Suboperation %lx\n",id2));
349 LsarpcTNP2(data,rdata,rdata_len);
353 LsarpcTNP4(data,rdata,rdata_len);
357 LsarpcTNP3(data,rdata,rdata_len);