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;
46 /* this macro should always be used to extract an fnum (smb_fid) from
47 a packet to ensure chaining works correctly */
48 #define GETFNUM(buf,where) (chain_fnum!= -1?chain_fnum:SVAL(buf,where))
50 char * known_pipes [] =
56 /****************************************************************************
57 reply to an open and X on a named pipe
59 In fact what we do is to open a regular file with the same name in
60 /tmp. This can then be closed as normal. Reading and writing won't
61 make much sense, but will do *something*. The real reason for this
62 support is to be able to do transactions on them (well, on lsarpc
63 for domain login purposes...).
65 This code is basically stolen from reply_open_and_X with some
66 wrinkles to handle pipes.
67 ****************************************************************************/
68 int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize)
71 int cnum = SVAL(inbuf,smb_tid);
73 int smb_mode = SVAL(inbuf,smb_vwv3);
74 int smb_attr = SVAL(inbuf,smb_vwv5);
76 int open_flags = SVAL(inbuf,smb_vwv2);
77 int smb_sattr = SVAL(inbuf,smb_vwv4);
78 uint32 smb_time = make_unix_date3(inbuf+smb_vwv6);
80 int smb_ofun = SVAL(inbuf,smb_vwv8);
82 int size=0,fmode=0,mtime=0,rmode=0;
87 /* XXXX we need to handle passed times, sattr and flags */
88 strcpy(fname,smb_buf(inbuf));
90 /* If the name doesn't start \PIPE\ then this is directed */
91 /* at a mailslot or something we really, really don't understand, */
92 /* not just something we really don't understand. */
93 if ( strncmp(fname,PIPE,PIPELEN) != 0 )
94 return(ERROR(ERRSRV,ERRaccess));
96 DEBUG(4,("Opening pipe %s.\n", fname));
98 /* Strip \PIPE\ off the name. */
99 strcpy(fname,smb_buf(inbuf) + PIPELEN);
101 /* See if it is one we want to handle. */
102 for( i = 0; known_pipes[i] ; i++ )
103 if( strcmp(fname,known_pipes[i]) == 0 )
106 if ( known_pipes[i] == NULL )
107 return(ERROR(ERRSRV,ERRaccess));
109 /* Known pipes arrive with DIR attribs. Remove it so a regular file */
110 /* can be opened and add it in after the open. */
111 DEBUG(3,("Known pipe %s opening.\n",fname));
113 Connections[cnum].read_only = 0;
114 smb_ofun |= 0x10; /* Add Create it not exists flag */
116 unix_convert(fname,cnum,0);
118 fnum = find_free_file();
120 return(ERROR(ERRSRV,ERRnofids));
122 if (!check_name(fname,cnum))
123 return(UNIXERROR(ERRDOS,ERRnoaccess));
125 unixmode = unix_mode(cnum,smb_attr);
127 open_file_shared(fnum,cnum,fname,smb_mode,smb_ofun,unixmode,
130 if (!Files[fnum].open)
131 return(UNIXERROR(ERRDOS,ERRnoaccess));
133 if (fstat(Files[fnum].fd_ptr->fd,&sbuf) != 0) {
135 return(ERROR(ERRDOS,ERRnoaccess));
139 fmode = dos_mode(cnum,fname,&sbuf);
140 mtime = sbuf.st_mtime;
143 return(ERROR(ERRDOS,ERRnoaccess));
146 /* Prepare the reply */
147 set_message(outbuf,15,0,True);
149 /* Put things back the way they were. */
150 Connections[cnum].read_only = 1;
152 /* Mark the opened file as an existing named pipe in message mode. */
153 SSVAL(outbuf,smb_vwv9,2);
154 SSVAL(outbuf,smb_vwv10,0xc700);
157 DEBUG(4,("Resetting open result to open from create.\n"));
161 SSVAL(outbuf,smb_vwv2,fnum);
162 SSVAL(outbuf,smb_vwv3,fmode);
163 put_dos_date3(outbuf,smb_vwv4,mtime);
164 SIVAL(outbuf,smb_vwv6,size);
165 SSVAL(outbuf,smb_vwv8,rmode);
166 SSVAL(outbuf,smb_vwv11,smb_action);
170 DEBUG(4,("Opened pipe %s with handle %d, saved name %s.\n",
171 fname, fnum, Files[fnum].name));
173 return chain_reply(inbuf,outbuf,length,bufsize);
177 /****************************************************************************
180 SetNamedPipeHandleState on \PIPE\lsarpc. We can't really do much here,
181 so just blithely return True. This is really only for NT domain stuff,
182 we we're only handling that - don't assume Samba now does complete
184 ****************************************************************************/
185 BOOL api_LsarpcSNPHS(int cnum,int uid, char *param,char *data,
186 int mdrcnt,int mprcnt,
187 char **rdata,char **rparam,
188 int *rdata_len,int *rparam_len)
192 id = param[0] + (param[1] << 8);
193 DEBUG(4,("lsarpc SetNamedPipeHandleState to code %x\n",id));
198 /****************************************************************************
201 TransactNamedPipe on \PIPE\lsarpc.
202 ****************************************************************************/
203 static void LsarpcTNP1(char *data,char **rdata, int *rdata_len)
205 uint32 dword1, dword2;
206 char pname[] = "\\PIPE\\lsass";
208 /* All kinds of mysterious numbers here */
210 *rdata = REALLOC(*rdata,*rdata_len);
212 dword1 = IVAL(data,0xC);
213 dword2 = IVAL(data,0x10);
215 SIVAL(*rdata,0,0xc0005);
216 SIVAL(*rdata,4,0x10);
217 SIVAL(*rdata,8,0x44);
218 SIVAL(*rdata,0xC,dword1);
220 SIVAL(*rdata,0x10,dword2);
221 SIVAL(*rdata,0x14,0x15);
222 SSVAL(*rdata,0x18,sizeof(pname));
223 strcpy(*rdata + 0x1a,pname);
224 SIVAL(*rdata,0x28,1);
225 memcpy(*rdata + 0x30, data + 0x34, 0x14);
228 static void LsarpcTNP2(char *data,char **rdata, int *rdata_len)
232 /* All kinds of mysterious numbers here */
234 *rdata = REALLOC(*rdata,*rdata_len);
236 dword1 = IVAL(data,0xC);
238 SIVAL(*rdata,0,0x03020005);
239 SIVAL(*rdata,4,0x10);
240 SIVAL(*rdata,8,0x30);
241 SIVAL(*rdata,0xC,dword1);
242 SIVAL(*rdata,0x10,0x18);
243 SIVAL(*rdata,0x1c,0x44332211);
244 SIVAL(*rdata,0x20,0x88776655);
245 SIVAL(*rdata,0x24,0xCCBBAA99);
246 SIVAL(*rdata,0x28,0x11FFEEDD);
249 static void LsarpcTNP3(char *data,char **rdata, int *rdata_len)
253 char * workgroup = lp_workgroup();
254 int wglen = strlen(workgroup);
257 /* All kinds of mysterious numbers here */
258 *rdata_len = 90 + 2 * wglen;
259 *rdata = REALLOC(*rdata,*rdata_len);
261 dword1 = IVAL(data,0xC);
262 word1 = SVAL(data,0x2C);
264 SIVAL(*rdata,0,0x03020005);
265 SIVAL(*rdata,4,0x10);
266 SIVAL(*rdata,8,0x60);
267 SIVAL(*rdata,0xC,dword1);
268 SIVAL(*rdata,0x10,0x48);
269 SSVAL(*rdata,0x18,0x5988); /* This changes */
270 SSVAL(*rdata,0x1A,0x15);
271 SSVAL(*rdata,0x1C,word1);
272 SSVAL(*rdata,0x20,6);
273 SSVAL(*rdata,0x22,8);
274 SSVAL(*rdata,0x24,0x8E8); /* So does this */
275 SSVAL(*rdata,0x26,0x15);
276 SSVAL(*rdata,0x28,0x4D48); /* And this */
277 SSVAL(*rdata,0x2A,0x15);
278 SIVAL(*rdata,0x2C,4);
279 SIVAL(*rdata,0x34,wglen);
280 for ( i = 0 ; i < wglen ; i++ )
281 (*rdata)[0x38 + i * 2] = workgroup[i];
283 /* Now fill in the rest */
284 i = 0x38 + wglen * 2;
285 SSVAL(*rdata,i,0x648);
287 SIVAL(*rdata,i+6,0x401);
288 SSVAL(*rdata,i+0xC,0x500);
289 SIVAL(*rdata,i+0xE,0x15);
290 SIVAL(*rdata,i+0x12,0x2372FE1);
291 SIVAL(*rdata,i+0x16,0x7E831BEF);
292 SIVAL(*rdata,i+0x1A,0x4B454B2);
295 static void LsarpcTNP4(char *data,char **rdata, int *rdata_len)
299 /* All kinds of mysterious numbers here */
301 *rdata = REALLOC(*rdata,*rdata_len);
303 dword1 = IVAL(data,0xC);
305 SIVAL(*rdata,0,0x03020005);
306 SIVAL(*rdata,4,0x10);
307 SIVAL(*rdata,8,0x30);
308 SIVAL(*rdata,0xC,dword1);
309 SIVAL(*rdata,0x10,0x18);
313 BOOL api_LsarpcTNP(int cnum,int uid, char *param,char *data,
314 int mdrcnt,int mprcnt,
315 char **rdata,char **rparam,
316 int *rdata_len,int *rparam_len)
322 DEBUG(4,("lsarpc TransactNamedPipe id %lx\n",id));
326 LsarpcTNP1(data,rdata,rdata_len);
331 DEBUG(4,("\t- Suboperation %lx\n",id2));
335 LsarpcTNP2(data,rdata,rdata_len);
339 LsarpcTNP4(data,rdata,rdata_len);
343 LsarpcTNP3(data,rdata,rdata_len);