Split maxxmit parameter into two : max_send (auto configured by the
[sfrench/samba-autobuild/.git] / source3 / smbd / pipes.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    Pipe SMB reply routines
5    Copyright (C) Andrew Tridgell 1992-1995
6    
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.
11    
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.
16    
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.
20 */
21 /*
22    This file handles reply_ calls on named pipes that the server
23    makes to handle specific protocols
24 */
25
26
27 #include "includes.h"
28 #include "trans2.h"
29
30 #define PIPE            "\\PIPE\\"
31 #define PIPELEN         strlen(PIPE)
32
33 #define REALLOC(ptr,size) Realloc(ptr,MAX((size),4*1024))
34
35 /* look in server.c for some explanation of these variables */
36 extern int Protocol;
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;
44 extern int Client;
45
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))
49
50 char * known_pipes [] =
51 {
52   "lsarpc",
53   NULL
54 };
55
56 /****************************************************************************
57   reply to an open and X on a named pipe
58
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...).
64
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)
69 {
70   pstring fname;
71   int cnum = SVAL(inbuf,smb_tid);
72   int fnum = -1;
73   int smb_mode = SVAL(inbuf,smb_vwv3);
74   int smb_attr = SVAL(inbuf,smb_vwv5);
75 #if 0
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);
79 #endif
80   int smb_ofun = SVAL(inbuf,smb_vwv8);
81   int unixmode;
82   int size=0,fmode=0,mtime=0,rmode=0;
83   struct stat sbuf;
84   int smb_action = 0;
85   int i;
86
87   /* XXXX we need to handle passed times, sattr and flags */
88   strcpy(fname,smb_buf(inbuf));
89
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));
95
96   DEBUG(4,("Opening pipe %s.\n", fname));
97
98   /* Strip \PIPE\ off the name. */
99   strcpy(fname,smb_buf(inbuf) + PIPELEN);
100
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 )
104       break;
105
106   if ( known_pipes[i] == NULL )
107     return(ERROR(ERRSRV,ERRaccess));
108
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));
112   smb_attr &= ~aDIR;
113   Connections[cnum].read_only = 0;
114   smb_ofun |= 0x10;             /* Add Create it not exists flag */
115
116   unix_convert(fname,cnum,0);
117     
118   fnum = find_free_file();
119   if (fnum < 0)
120     return(ERROR(ERRSRV,ERRnofids));
121
122   if (!check_name(fname,cnum))
123     return(UNIXERROR(ERRDOS,ERRnoaccess));
124
125   unixmode = unix_mode(cnum,smb_attr);
126       
127   open_file_shared(fnum,cnum,fname,smb_mode,smb_ofun,unixmode,
128                    &rmode,&smb_action);
129       
130   if (!Files[fnum].open)
131     return(UNIXERROR(ERRDOS,ERRnoaccess));
132
133   if (fstat(Files[fnum].fd_ptr->fd,&sbuf) != 0) {
134     close_file(fnum);
135     return(ERROR(ERRDOS,ERRnoaccess));
136   }
137
138   size = sbuf.st_size;
139   fmode = dos_mode(cnum,fname,&sbuf);
140   mtime = sbuf.st_mtime;
141   if (fmode & aDIR) {
142     close_file(fnum);
143     return(ERROR(ERRDOS,ERRnoaccess));
144   }
145
146   /* Prepare the reply */
147   set_message(outbuf,15,0,True);
148
149   /* Put things back the way they were. */
150   Connections[cnum].read_only = 1;
151
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);
155   if (rmode == 2)
156   {
157     DEBUG(4,("Resetting open result to open from create.\n"));
158     rmode = 1;
159   }
160
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);
167
168   chain_fnum = fnum;
169
170   DEBUG(4,("Opened pipe %s with handle %d, saved name %s.\n",
171            fname, fnum, Files[fnum].name));
172   
173   return chain_reply(inbuf,outbuf,length,bufsize);
174 }
175
176
177 /****************************************************************************
178  api_LsarpcSNPHS
179
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
183  named pipe handling.
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)
189 {
190   uint16 id;
191
192   id = param[0] + (param[1] << 8);
193   DEBUG(4,("lsarpc SetNamedPipeHandleState to code %x\n",id));
194   return(True);
195 }
196
197
198 /****************************************************************************
199  api_LsarpcTNP
200
201  TransactNamedPipe on \PIPE\lsarpc.
202 ****************************************************************************/
203 static void LsarpcTNP1(char *data,char **rdata, int *rdata_len)
204 {
205   uint32 dword1, dword2;
206   char pname[] = "\\PIPE\\lsass";
207
208   /* All kinds of mysterious numbers here */
209   *rdata_len = 68;
210   *rdata = REALLOC(*rdata,*rdata_len);
211
212   dword1 = IVAL(data,0xC);
213   dword2 = IVAL(data,0x10);
214
215   SIVAL(*rdata,0,0xc0005);
216   SIVAL(*rdata,4,0x10);
217   SIVAL(*rdata,8,0x44);
218   SIVAL(*rdata,0xC,dword1);
219   
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);
226 }
227
228 static void LsarpcTNP2(char *data,char **rdata, int *rdata_len)
229 {
230   uint32 dword1;
231
232   /* All kinds of mysterious numbers here */
233   *rdata_len = 48;
234   *rdata = REALLOC(*rdata,*rdata_len);
235
236   dword1 = IVAL(data,0xC);
237
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);
247 }
248
249 static void LsarpcTNP3(char *data,char **rdata, int *rdata_len)
250 {
251   uint32 dword1;
252   uint16 word1;
253   char * workgroup = lp_workgroup();
254   int wglen = strlen(workgroup);
255   int i;
256
257   /* All kinds of mysterious numbers here */
258   *rdata_len = 90 + 2 * wglen;
259   *rdata = REALLOC(*rdata,*rdata_len);
260
261   dword1 = IVAL(data,0xC);
262   word1 = SVAL(data,0x2C);
263
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];
282    
283   /* Now fill in the rest */
284   i = 0x38 + wglen * 2;
285   SSVAL(*rdata,i,0x648);
286   SIVAL(*rdata,i+2,4);
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);
293 }
294
295 static void LsarpcTNP4(char *data,char **rdata, int *rdata_len)
296 {
297   uint32 dword1;
298
299   /* All kinds of mysterious numbers here */
300   *rdata_len = 48;
301   *rdata = REALLOC(*rdata,*rdata_len);
302
303   dword1 = IVAL(data,0xC);
304
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);
310 }
311
312
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)
317 {
318   uint32 id,id2;
319
320   id = IVAL(data,0);
321
322   DEBUG(4,("lsarpc TransactNamedPipe id %lx\n",id));
323   switch (id)
324   {
325     case 0xb0005:
326       LsarpcTNP1(data,rdata,rdata_len);
327       break;
328
329     case 0x03000005:
330       id2 = IVAL(data,8);
331       DEBUG(4,("\t- Suboperation %lx\n",id2));
332       switch (id2 & 0xF)
333       {
334         case 8:
335           LsarpcTNP2(data,rdata,rdata_len);
336           break;
337
338         case 0xC:
339           LsarpcTNP4(data,rdata,rdata_len);
340           break;
341
342         case 0xE:
343           LsarpcTNP3(data,rdata,rdata_len);
344           break;
345       }
346       break;
347   }
348   return(True);
349 }