2 Unix SMB/Netbios implementation.
4 Pipe SMB reply routines
5 Copyright (C) Andrew Tridgell 1992-1997
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_fnum;
39 extern char magic_char;
40 extern connection_struct Connections[];
41 extern files_struct Files[];
42 extern BOOL case_sensitive;
43 extern pstring sesssetup_user;
45 extern fstring myworkgroup;
47 /* this macro should always be used to extract an fnum (smb_fid) from
48 a packet to ensure chaining works correctly */
49 #define GETFNUM(buf,where) (chain_fnum!= -1?chain_fnum:SVAL(buf,where))
51 char * known_pipes [] =
57 /****************************************************************************
58 reply to an open and X on a named pipe
60 In fact what we do is to open a regular file with the same name in
61 /tmp. This can then be closed as normal. Reading and writing won't
62 make much sense, but will do *something*. The real reason for this
63 support is to be able to do transactions on them (well, on lsarpc
64 for domain login purposes...).
66 This code is basically stolen from reply_open_and_X with some
67 wrinkles to handle pipes.
68 ****************************************************************************/
69 int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize)
72 int cnum = SVAL(inbuf,smb_tid);
74 int smb_mode = SVAL(inbuf,smb_vwv3);
75 int smb_attr = SVAL(inbuf,smb_vwv5);
77 int open_flags = SVAL(inbuf,smb_vwv2);
78 int smb_sattr = SVAL(inbuf,smb_vwv4);
79 uint32 smb_time = make_unix_date3(inbuf+smb_vwv6);
81 int smb_ofun = SVAL(inbuf,smb_vwv8);
83 int size=0,fmode=0,mtime=0,rmode=0;
87 BOOL bad_path = False;
89 /* XXXX we need to handle passed times, sattr and flags */
90 pstrcpy(fname,smb_buf(inbuf));
92 /* If the name doesn't start \PIPE\ then this is directed */
93 /* at a mailslot or something we really, really don't understand, */
94 /* not just something we really don't understand. */
95 if ( strncmp(fname,PIPE,PIPELEN) != 0 )
96 return(ERROR(ERRSRV,ERRaccess));
98 DEBUG(4,("Opening pipe %s.\n", fname));
100 /* Strip \PIPE\ off the name. */
101 pstrcpy(fname,smb_buf(inbuf) + PIPELEN);
103 /* See if it is one we want to handle. */
104 for( i = 0; known_pipes[i] ; i++ )
105 if( strcmp(fname,known_pipes[i]) == 0 )
108 if ( known_pipes[i] == NULL )
109 return(ERROR(ERRSRV,ERRaccess));
111 /* Known pipes arrive with DIR attribs. Remove it so a regular file */
112 /* can be opened and add it in after the open. */
113 DEBUG(3,("Known pipe %s opening.\n",fname));
115 Connections[cnum].read_only = 0;
116 smb_ofun |= 0x10; /* Add Create it not exists flag */
118 unix_convert(fname,cnum,0,&bad_path);
120 fnum = find_free_file();
122 return(ERROR(ERRSRV,ERRnofids));
124 if (!check_name(fname,cnum))
125 return(UNIXERROR(ERRDOS,ERRnoaccess));
127 unixmode = unix_mode(cnum,smb_attr);
129 open_file_shared(fnum,cnum,fname,smb_mode,smb_ofun,unixmode,
132 if (!Files[fnum].open)
134 /* Change the error code if bad_path was set. */
135 if((errno == ENOENT) && bad_path)
137 unix_ERR_class = ERRDOS;
138 unix_ERR_code = ERRbadpath;
140 return(UNIXERROR(ERRDOS,ERRnoaccess));
143 if (fstat(Files[fnum].fd_ptr->fd,&sbuf) != 0) {
145 return(ERROR(ERRDOS,ERRnoaccess));
149 fmode = dos_mode(cnum,fname,&sbuf);
150 mtime = sbuf.st_mtime;
153 return(ERROR(ERRDOS,ERRnoaccess));
156 /* Prepare the reply */
157 set_message(outbuf,15,0,True);
159 /* Put things back the way they were. */
160 Connections[cnum].read_only = 1;
162 /* Mark the opened file as an existing named pipe in message mode. */
163 SSVAL(outbuf,smb_vwv9,2);
164 SSVAL(outbuf,smb_vwv10,0xc700);
167 DEBUG(4,("Resetting open result to open from create.\n"));
171 SSVAL(outbuf,smb_vwv2,fnum);
172 SSVAL(outbuf,smb_vwv3,fmode);
173 put_dos_date3(outbuf,smb_vwv4,mtime);
174 SIVAL(outbuf,smb_vwv6,size);
175 SSVAL(outbuf,smb_vwv8,rmode);
176 SSVAL(outbuf,smb_vwv11,smb_action);
180 DEBUG(4,("Opened pipe %s with handle %d, saved name %s.\n",
181 fname, fnum, Files[fnum].name));
183 return chain_reply(inbuf,outbuf,length,bufsize);
187 /****************************************************************************
190 SetNamedPipeHandleState on \PIPE\lsarpc. We can't really do much here,
191 so just blithely return True. This is really only for NT domain stuff,
192 we we're only handling that - don't assume Samba now does complete
194 ****************************************************************************/
195 BOOL api_LsarpcSNPHS(int cnum,int uid, char *param,char *data,
196 int mdrcnt,int mprcnt,
197 char **rdata,char **rparam,
198 int *rdata_len,int *rparam_len)
202 id = param[0] + (param[1] << 8);
203 DEBUG(4,("lsarpc SetNamedPipeHandleState to code %x\n",id));
208 /****************************************************************************
211 TransactNamedPipe on \PIPE\lsarpc.
212 ****************************************************************************/
213 static void LsarpcTNP1(char *data,char **rdata, int *rdata_len)
215 uint32 dword1, dword2;
216 char pname[] = "\\PIPE\\lsass";
218 /* All kinds of mysterious numbers here */
220 *rdata = REALLOC(*rdata,*rdata_len);
222 dword1 = IVAL(data,0xC);
223 dword2 = IVAL(data,0x10);
225 SIVAL(*rdata,0,0xc0005);
226 SIVAL(*rdata,4,0x10);
227 SIVAL(*rdata,8,0x44);
228 SIVAL(*rdata,0xC,dword1);
230 SIVAL(*rdata,0x10,dword2);
231 SIVAL(*rdata,0x14,0x15);
232 SSVAL(*rdata,0x18,sizeof(pname));
233 strcpy(*rdata + 0x1a,pname);
234 SIVAL(*rdata,0x28,1);
235 memcpy(*rdata + 0x30, data + 0x34, 0x14);
238 static void LsarpcTNP2(char *data,char **rdata, int *rdata_len)
242 /* All kinds of mysterious numbers here */
244 *rdata = REALLOC(*rdata,*rdata_len);
246 dword1 = IVAL(data,0xC);
248 SIVAL(*rdata,0,0x03020005);
249 SIVAL(*rdata,4,0x10);
250 SIVAL(*rdata,8,0x30);
251 SIVAL(*rdata,0xC,dword1);
252 SIVAL(*rdata,0x10,0x18);
253 SIVAL(*rdata,0x1c,0x44332211);
254 SIVAL(*rdata,0x20,0x88776655);
255 SIVAL(*rdata,0x24,0xCCBBAA99);
256 SIVAL(*rdata,0x28,0x11FFEEDD);
259 static void LsarpcTNP3(char *data,char **rdata, int *rdata_len)
263 char * workgroup = myworkgroup;
264 int wglen = strlen(workgroup);
267 /* All kinds of mysterious numbers here */
268 *rdata_len = 90 + 2 * wglen;
269 *rdata = REALLOC(*rdata,*rdata_len);
271 dword1 = IVAL(data,0xC);
272 word1 = SVAL(data,0x2C);
274 SIVAL(*rdata,0,0x03020005);
275 SIVAL(*rdata,4,0x10);
276 SIVAL(*rdata,8,0x60);
277 SIVAL(*rdata,0xC,dword1);
278 SIVAL(*rdata,0x10,0x48);
279 SSVAL(*rdata,0x18,0x5988); /* This changes */
280 SSVAL(*rdata,0x1A,0x15);
281 SSVAL(*rdata,0x1C,word1);
282 SSVAL(*rdata,0x20,6);
283 SSVAL(*rdata,0x22,8);
284 SSVAL(*rdata,0x24,0x8E8); /* So does this */
285 SSVAL(*rdata,0x26,0x15);
286 SSVAL(*rdata,0x28,0x4D48); /* And this */
287 SSVAL(*rdata,0x2A,0x15);
288 SIVAL(*rdata,0x2C,4);
289 SIVAL(*rdata,0x34,wglen);
290 for ( i = 0 ; i < wglen ; i++ )
291 (*rdata)[0x38 + i * 2] = workgroup[i];
293 /* Now fill in the rest */
294 i = 0x38 + wglen * 2;
295 SSVAL(*rdata,i,0x648);
297 SIVAL(*rdata,i+6,0x401);
298 SSVAL(*rdata,i+0xC,0x500);
299 SIVAL(*rdata,i+0xE,0x15);
300 SIVAL(*rdata,i+0x12,0x2372FE1);
301 SIVAL(*rdata,i+0x16,0x7E831BEF);
302 SIVAL(*rdata,i+0x1A,0x4B454B2);
305 static void LsarpcTNP4(char *data,char **rdata, int *rdata_len)
309 /* All kinds of mysterious numbers here */
311 *rdata = REALLOC(*rdata,*rdata_len);
313 dword1 = IVAL(data,0xC);
315 SIVAL(*rdata,0,0x03020005);
316 SIVAL(*rdata,4,0x10);
317 SIVAL(*rdata,8,0x30);
318 SIVAL(*rdata,0xC,dword1);
319 SIVAL(*rdata,0x10,0x18);
323 BOOL api_LsarpcTNP(int cnum,int uid, char *param,char *data,
324 int mdrcnt,int mprcnt,
325 char **rdata,char **rparam,
326 int *rdata_len,int *rparam_len)
332 DEBUG(4,("lsarpc TransactNamedPipe id %lx\n",id));
336 LsarpcTNP1(data,rdata,rdata_len);
341 DEBUG(4,("\t- Suboperation %lx\n",id2));
345 LsarpcTNP2(data,rdata,rdata_len);
349 LsarpcTNP4(data,rdata,rdata_len);
353 LsarpcTNP3(data,rdata,rdata_len);