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 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;
47 extern fstring myworkgroup;
49 /* this macro should always be used to extract an fnum (smb_fid) from
50 a packet to ensure chaining works correctly */
51 #define GETFNUM(buf,where) (chain_fnum!= -1?chain_fnum:SVAL(buf,where))
53 char * known_pipes [] =
62 /****************************************************************************
63 reply to an open and X on a named pipe
65 In fact what we do is to open a regular file with the same name in
66 /tmp. This can then be closed as normal. Reading and writing won't
67 make much sense, but will do *something*. The real reason for this
68 support is to be able to do transactions on them (well, on lsarpc
69 for domain login purposes...).
71 This code is basically stolen from reply_open_and_X with some
72 wrinkles to handle pipes.
73 ****************************************************************************/
74 int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize)
77 int cnum = SVAL(inbuf,smb_tid);
79 int smb_mode = SVAL(inbuf,smb_vwv3);
80 int smb_attr = SVAL(inbuf,smb_vwv5);
82 int open_flags = SVAL(inbuf,smb_vwv2);
83 int smb_sattr = SVAL(inbuf,smb_vwv4);
84 uint32 smb_time = make_unix_date3(inbuf+smb_vwv6);
86 int smb_ofun = SVAL(inbuf,smb_vwv8);
88 int size=0,fmode=0,mtime=0,rmode=0;
92 BOOL bad_path = False;
94 /* XXXX we need to handle passed times, sattr and flags */
95 pstrcpy(fname,smb_buf(inbuf));
97 /* If the name doesn't start \PIPE\ then this is directed */
98 /* at a mailslot or something we really, really don't understand, */
99 /* not just something we really don't understand. */
100 if ( strncmp(fname,PIPE,PIPELEN) != 0 )
101 return(ERROR(ERRSRV,ERRaccess));
103 DEBUG(4,("Opening pipe %s.\n", fname));
105 /* Strip \PIPE\ off the name. */
106 pstrcpy(fname,smb_buf(inbuf) + PIPELEN);
108 /* See if it is one we want to handle. */
109 for( i = 0; known_pipes[i] ; i++ )
110 if( strcmp(fname,known_pipes[i]) == 0 )
113 if ( known_pipes[i] == NULL )
114 return(ERROR(ERRSRV,ERRaccess));
116 /* Known pipes arrive with DIR attribs. Remove it so a regular file */
117 /* can be opened and add it in after the open. */
118 DEBUG(3,("Known pipe %s opening.\n",fname));
120 Connections[cnum].read_only = 0;
121 smb_ofun |= 0x10; /* Add Create it not exists flag */
123 unix_convert(fname,cnum,0,&bad_path);
125 fnum = find_free_file();
127 return(ERROR(ERRSRV,ERRnofids));
129 if (!check_name(fname,cnum))
130 return(UNIXERROR(ERRDOS,ERRnoaccess));
132 unixmode = unix_mode(cnum,smb_attr);
134 open_file_shared(fnum,cnum,fname,smb_mode,smb_ofun,unixmode,
135 0, &rmode,&smb_action);
137 if (!Files[fnum].open)
139 /* Change the error code if bad_path was set. */
140 if((errno == ENOENT) && bad_path)
142 unix_ERR_class = ERRDOS;
143 unix_ERR_code = ERRbadpath;
145 return(UNIXERROR(ERRDOS,ERRnoaccess));
148 if (fstat(Files[fnum].fd_ptr->fd,&sbuf) != 0) {
150 return(ERROR(ERRDOS,ERRnoaccess));
154 fmode = dos_mode(cnum,fname,&sbuf);
155 mtime = sbuf.st_mtime;
158 return(ERROR(ERRDOS,ERRnoaccess));
161 /* Prepare the reply */
162 set_message(outbuf,15,0,True);
164 /* Put things back the way they were. */
165 Connections[cnum].read_only = 1;
167 /* Mark the opened file as an existing named pipe in message mode. */
168 SSVAL(outbuf,smb_vwv9,2);
169 SSVAL(outbuf,smb_vwv10,0xc700);
172 DEBUG(4,("Resetting open result to open from create.\n"));
176 SSVAL(outbuf,smb_vwv2,fnum);
177 SSVAL(outbuf,smb_vwv3,fmode);
178 put_dos_date3(outbuf,smb_vwv4,mtime);
179 SIVAL(outbuf,smb_vwv6,size);
180 SSVAL(outbuf,smb_vwv8,rmode);
181 SSVAL(outbuf,smb_vwv11,smb_action);
185 DEBUG(4,("Opened pipe %s with handle %d, saved name %s.\n",
186 fname, fnum, Files[fnum].name));
188 return chain_reply(inbuf,outbuf,length,bufsize);
192 /****************************************************************************
195 SetNamedPipeHandleState on \PIPE\lsarpc. We can't really do much here,
196 so just blithely return True. This is really only for NT domain stuff,
197 we we're only handling that - don't assume Samba now does complete
199 ****************************************************************************/
200 BOOL api_LsarpcSNPHS(int cnum,int uid, char *param,char *data,
201 int mdrcnt,int mprcnt,
202 char **rdata,char **rparam,
203 int *rdata_len,int *rparam_len)
207 id = param[0] + (param[1] << 8);
208 DEBUG(4,("lsarpc SetNamedPipeHandleState to code %x\n",id));
213 /****************************************************************************
216 TransactNamedPipe on \PIPE\lsarpc.
217 ****************************************************************************/
218 void LsarpcTNP1(char *data,char **rdata, int *rdata_len)
220 uint32 dword1, dword2;
221 char pname[] = "\\PIPE\\lsass";
223 /* All kinds of mysterious numbers here */
225 *rdata = REALLOC(*rdata,*rdata_len);
227 dword1 = IVAL(data,0xC);
228 dword2 = IVAL(data,0x10);
230 SIVAL(*rdata,0,0xc0005);
231 SIVAL(*rdata,4,0x10);
232 SIVAL(*rdata,8,0x44);
233 SIVAL(*rdata,0xC,dword1);
235 SIVAL(*rdata,0x10,dword2);
236 SIVAL(*rdata,0x14,0x15);
237 SSVAL(*rdata,0x18,sizeof(pname));
238 strcpy(*rdata + 0x1a,pname);
239 SIVAL(*rdata,0x28,1);
240 memcpy(*rdata + 0x30, data + 0x34, 0x14);
243 static void LsarpcTNP2(char *data,char **rdata, int *rdata_len)
247 /* All kinds of mysterious numbers here */
249 *rdata = REALLOC(*rdata,*rdata_len);
251 dword1 = IVAL(data,0xC);
253 SIVAL(*rdata,0,0x03020005);
254 SIVAL(*rdata,4,0x10);
255 SIVAL(*rdata,8,0x30);
256 SIVAL(*rdata,0xC,dword1);
257 SIVAL(*rdata,0x10,0x18);
258 SIVAL(*rdata,0x1c,0x44332211);
259 SIVAL(*rdata,0x20,0x88776655);
260 SIVAL(*rdata,0x24,0xCCBBAA99);
261 SIVAL(*rdata,0x28,0x11FFEEDD);
264 static void LsarpcTNP3(char *data,char **rdata, int *rdata_len)
268 char * workgroup = myworkgroup;
269 int wglen = strlen(workgroup);
272 /* All kinds of mysterious numbers here */
273 *rdata_len = 90 + 2 * wglen;
274 *rdata = REALLOC(*rdata,*rdata_len);
276 dword1 = IVAL(data,0xC);
277 word1 = SVAL(data,0x2C);
279 SIVAL(*rdata,0,0x03020005);
280 SIVAL(*rdata,4,0x10);
281 SIVAL(*rdata,8,0x60);
282 SIVAL(*rdata,0xC,dword1);
283 SIVAL(*rdata,0x10,0x48);
284 SSVAL(*rdata,0x18,0x5988); /* This changes */
285 SSVAL(*rdata,0x1A,0x15);
286 SSVAL(*rdata,0x1C,word1);
287 SSVAL(*rdata,0x20,6);
288 SSVAL(*rdata,0x22,8);
289 SSVAL(*rdata,0x24,0x8E8); /* So does this */
290 SSVAL(*rdata,0x26,0x15);
291 SSVAL(*rdata,0x28,0x4D48); /* And this */
292 SSVAL(*rdata,0x2A,0x15);
293 SIVAL(*rdata,0x2C,4);
294 SIVAL(*rdata,0x34,wglen);
295 for ( i = 0 ; i < wglen ; i++ )
296 (*rdata)[0x38 + i * 2] = workgroup[i];
298 /* Now fill in the rest */
299 i = 0x38 + wglen * 2;
300 SSVAL(*rdata,i,0x648);
302 SIVAL(*rdata,i+6,0x401);
303 SSVAL(*rdata,i+0xC,0x500);
304 SIVAL(*rdata,i+0xE,0x15);
305 SIVAL(*rdata,i+0x12,0x2372FE1);
306 SIVAL(*rdata,i+0x16,0x7E831BEF);
307 SIVAL(*rdata,i+0x1A,0x4B454B2);
310 static void LsarpcTNP4(char *data,char **rdata, int *rdata_len)
314 /* All kinds of mysterious numbers here */
316 *rdata = REALLOC(*rdata,*rdata_len);
318 dword1 = IVAL(data,0xC);
320 SIVAL(*rdata,0,0x03020005);
321 SIVAL(*rdata,4,0x10);
322 SIVAL(*rdata,8,0x30);
323 SIVAL(*rdata,0xC,dword1);
324 SIVAL(*rdata,0x10,0x18);
328 BOOL api_LsarpcTNP(int cnum,int uid, char *param,char *data,
329 int mdrcnt,int mprcnt,
330 char **rdata,char **rparam,
331 int *rdata_len,int *rparam_len)
337 DEBUG(4,("lsarpc TransactNamedPipe id %lx\n",id));
341 LsarpcTNP1(data,rdata,rdata_len);
346 DEBUG(4,("\t- Suboperation %lx\n",id2));
350 LsarpcTNP2(data,rdata,rdata_len);
354 LsarpcTNP4(data,rdata,rdata_len);
358 LsarpcTNP3(data,rdata,rdata_len);