Makefile: Added cleandir target.
[Samba.git] / source / smbd / pipes.c
blobefa6a68b9d736eaad7406b704b7d4b1e8502df9a
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
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
27 #include "includes.h"
28 #include "trans2.h"
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 */
36 extern int Protocol;
37 extern int DEBUGLEVEL;
38 extern int maxxmit;
39 extern int chain_fnum;
40 extern char magic_char;
41 extern connection_struct Connections[];
42 extern files_struct Files[];
43 extern BOOL case_sensitive;
44 extern pstring sesssetup_user;
45 extern int Client;
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 [] =
53 "lsarpc",
54 NULL
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)
71 pstring fname;
72 int cnum = SVAL(inbuf,smb_tid);
73 int fnum = -1;
74 int smb_mode = SVAL(inbuf,smb_vwv3);
75 int smb_attr = SVAL(inbuf,smb_vwv5);
76 #if 0
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);
80 #endif
81 int smb_ofun = SVAL(inbuf,smb_vwv8);
82 int unixmode;
83 int size=0,fmode=0,mtime=0,rmode=0;
84 struct stat sbuf;
85 int smb_action = 0;
86 int i;
88 /* XXXX we need to handle passed times, sattr and flags */
89 strcpy(fname,smb_buf(inbuf));
91 /* If the name doesn't start \PIPE\ then this is directed */
92 /* at a mailslot or something we really, really don't understand, */
93 /* not just something we really don't understand. */
94 if ( strncmp(fname,PIPE,PIPELEN) != 0 )
95 return(ERROR(ERRSRV,ERRaccess));
97 DEBUG(4,("Opening pipe %s.\n", fname));
99 /* Strip \PIPE\ off the name. */
100 strcpy(fname,smb_buf(inbuf) + PIPELEN);
102 /* See if it is one we want to handle. */
103 for( i = 0; known_pipes[i] ; i++ )
104 if( strcmp(fname,known_pipes[i]) == 0 )
105 break;
107 if ( known_pipes[i] == NULL )
108 return(ERROR(ERRSRV,ERRaccess));
110 /* Known pipes arrive with DIR attribs. Remove it so a regular file */
111 /* can be opened and add it in after the open. */
112 DEBUG(3,("Known pipe %s opening.\n",fname));
113 smb_attr &= ~aDIR;
114 Connections[cnum].read_only = 0;
115 smb_ofun |= 0x10; /* Add Create it not exists flag */
117 unix_convert(fname,cnum,0);
119 fnum = find_free_file();
120 if (fnum < 0)
121 return(ERROR(ERRSRV,ERRnofids));
123 if (!check_name(fname,cnum))
124 return(UNIXERROR(ERRDOS,ERRnoaccess));
126 unixmode = unix_mode(cnum,smb_attr);
128 open_file_shared(fnum,cnum,fname,smb_mode,smb_ofun,unixmode,
129 &rmode,&smb_action);
131 if (!Files[fnum].open)
132 return(UNIXERROR(ERRDOS,ERRnoaccess));
134 if (fstat(Files[fnum].fd_ptr->fd,&sbuf) != 0) {
135 close_file(fnum);
136 return(ERROR(ERRDOS,ERRnoaccess));
139 size = sbuf.st_size;
140 fmode = dos_mode(cnum,fname,&sbuf);
141 mtime = sbuf.st_mtime;
142 if (fmode & aDIR) {
143 close_file(fnum);
144 return(ERROR(ERRDOS,ERRnoaccess));
147 /* Prepare the reply */
148 set_message(outbuf,15,0,True);
150 /* Put things back the way they were. */
151 Connections[cnum].read_only = 1;
153 /* Mark the opened file as an existing named pipe in message mode. */
154 SSVAL(outbuf,smb_vwv9,2);
155 SSVAL(outbuf,smb_vwv10,0xc700);
156 if (rmode == 2)
158 DEBUG(4,("Resetting open result to open from create.\n"));
159 rmode = 1;
162 SSVAL(outbuf,smb_vwv2,fnum);
163 SSVAL(outbuf,smb_vwv3,fmode);
164 put_dos_date3(outbuf,smb_vwv4,mtime);
165 SIVAL(outbuf,smb_vwv6,size);
166 SSVAL(outbuf,smb_vwv8,rmode);
167 SSVAL(outbuf,smb_vwv11,smb_action);
169 chain_fnum = fnum;
171 DEBUG(4,("Opened pipe %s with handle %d, saved name %s.\n",
172 fname, fnum, Files[fnum].name));
174 return chain_reply(inbuf,outbuf,length,bufsize);
178 /****************************************************************************
179 api_LsarpcSNPHS
181 SetNamedPipeHandleState on \PIPE\lsarpc. We can't really do much here,
182 so just blithely return True. This is really only for NT domain stuff,
183 we we're only handling that - don't assume Samba now does complete
184 named pipe handling.
185 ****************************************************************************/
186 BOOL api_LsarpcSNPHS(int cnum,int uid, char *param,char *data,
187 int mdrcnt,int mprcnt,
188 char **rdata,char **rparam,
189 int *rdata_len,int *rparam_len)
191 uint16 id;
193 id = param[0] + (param[1] << 8);
194 DEBUG(4,("lsarpc SetNamedPipeHandleState to code %x\n",id));
195 return(True);
199 /****************************************************************************
200 api_LsarpcTNP
202 TransactNamedPipe on \PIPE\lsarpc.
203 ****************************************************************************/
204 static void LsarpcTNP1(char *data,char **rdata, int *rdata_len)
206 uint32 dword1, dword2;
207 char pname[] = "\\PIPE\\lsass";
209 /* All kinds of mysterious numbers here */
210 *rdata_len = 68;
211 *rdata = REALLOC(*rdata,*rdata_len);
213 dword1 = IVAL(data,0xC);
214 dword2 = IVAL(data,0x10);
216 SIVAL(*rdata,0,0xc0005);
217 SIVAL(*rdata,4,0x10);
218 SIVAL(*rdata,8,0x44);
219 SIVAL(*rdata,0xC,dword1);
221 SIVAL(*rdata,0x10,dword2);
222 SIVAL(*rdata,0x14,0x15);
223 SSVAL(*rdata,0x18,sizeof(pname));
224 strcpy(*rdata + 0x1a,pname);
225 SIVAL(*rdata,0x28,1);
226 memcpy(*rdata + 0x30, data + 0x34, 0x14);
229 static void LsarpcTNP2(char *data,char **rdata, int *rdata_len)
231 uint32 dword1;
233 /* All kinds of mysterious numbers here */
234 *rdata_len = 48;
235 *rdata = REALLOC(*rdata,*rdata_len);
237 dword1 = IVAL(data,0xC);
239 SIVAL(*rdata,0,0x03020005);
240 SIVAL(*rdata,4,0x10);
241 SIVAL(*rdata,8,0x30);
242 SIVAL(*rdata,0xC,dword1);
243 SIVAL(*rdata,0x10,0x18);
244 SIVAL(*rdata,0x1c,0x44332211);
245 SIVAL(*rdata,0x20,0x88776655);
246 SIVAL(*rdata,0x24,0xCCBBAA99);
247 SIVAL(*rdata,0x28,0x11FFEEDD);
250 static void LsarpcTNP3(char *data,char **rdata, int *rdata_len)
252 uint32 dword1;
253 uint16 word1;
254 char * workgroup = lp_workgroup();
255 int wglen = strlen(workgroup);
256 int i;
258 /* All kinds of mysterious numbers here */
259 *rdata_len = 90 + 2 * wglen;
260 *rdata = REALLOC(*rdata,*rdata_len);
262 dword1 = IVAL(data,0xC);
263 word1 = SVAL(data,0x2C);
265 SIVAL(*rdata,0,0x03020005);
266 SIVAL(*rdata,4,0x10);
267 SIVAL(*rdata,8,0x60);
268 SIVAL(*rdata,0xC,dword1);
269 SIVAL(*rdata,0x10,0x48);
270 SSVAL(*rdata,0x18,0x5988); /* This changes */
271 SSVAL(*rdata,0x1A,0x15);
272 SSVAL(*rdata,0x1C,word1);
273 SSVAL(*rdata,0x20,6);
274 SSVAL(*rdata,0x22,8);
275 SSVAL(*rdata,0x24,0x8E8); /* So does this */
276 SSVAL(*rdata,0x26,0x15);
277 SSVAL(*rdata,0x28,0x4D48); /* And this */
278 SSVAL(*rdata,0x2A,0x15);
279 SIVAL(*rdata,0x2C,4);
280 SIVAL(*rdata,0x34,wglen);
281 for ( i = 0 ; i < wglen ; i++ )
282 (*rdata)[0x38 + i * 2] = workgroup[i];
284 /* Now fill in the rest */
285 i = 0x38 + wglen * 2;
286 SSVAL(*rdata,i,0x648);
287 SIVAL(*rdata,i+2,4);
288 SIVAL(*rdata,i+6,0x401);
289 SSVAL(*rdata,i+0xC,0x500);
290 SIVAL(*rdata,i+0xE,0x15);
291 SIVAL(*rdata,i+0x12,0x2372FE1);
292 SIVAL(*rdata,i+0x16,0x7E831BEF);
293 SIVAL(*rdata,i+0x1A,0x4B454B2);
296 static void LsarpcTNP4(char *data,char **rdata, int *rdata_len)
298 uint32 dword1;
300 /* All kinds of mysterious numbers here */
301 *rdata_len = 48;
302 *rdata = REALLOC(*rdata,*rdata_len);
304 dword1 = IVAL(data,0xC);
306 SIVAL(*rdata,0,0x03020005);
307 SIVAL(*rdata,4,0x10);
308 SIVAL(*rdata,8,0x30);
309 SIVAL(*rdata,0xC,dword1);
310 SIVAL(*rdata,0x10,0x18);
314 BOOL api_LsarpcTNP(int cnum,int uid, char *param,char *data,
315 int mdrcnt,int mprcnt,
316 char **rdata,char **rparam,
317 int *rdata_len,int *rparam_len)
319 uint32 id,id2;
321 id = IVAL(data,0);
323 DEBUG(4,("lsarpc TransactNamedPipe id %lx\n",id));
324 switch (id)
326 case 0xb0005:
327 LsarpcTNP1(data,rdata,rdata_len);
328 break;
330 case 0x03000005:
331 id2 = IVAL(data,8);
332 DEBUG(4,("\t- Suboperation %lx\n",id2));
333 switch (id2 & 0xF)
335 case 8:
336 LsarpcTNP2(data,rdata,rdata_len);
337 break;
339 case 0xC:
340 LsarpcTNP4(data,rdata,rdata_len);
341 break;
343 case 0xE:
344 LsarpcTNP3(data,rdata,rdata_len);
345 break;
347 break;
349 return(True);