Makefile:
[samba.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-1997,
6    Copyright (C) Luke Kenneth Casson Leighton 1996-1997.
7    Copyright (C) Paul Ashton  1997.
8    
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.
13    
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.
18    
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.
22 */
23 /*
24    This file handles reply_ calls on named pipes that the server
25    makes to handle specific protocols
26 */
27
28
29 #include "includes.h"
30 #include "trans2.h"
31
32 #define PIPE            "\\PIPE\\"
33 #define PIPELEN         strlen(PIPE)
34
35 #define REALLOC(ptr,size) Realloc(ptr,MAX((size),4*1024))
36
37 /* look in server.c for some explanation of these variables */
38 extern int Protocol;
39 extern int DEBUGLEVEL;
40 extern char magic_char;
41 extern BOOL case_sensitive;
42 extern pstring sesssetup_user;
43 extern int Client;
44 extern fstring myworkgroup;
45
46 #define VALID_PNUM(pnum)   (((pnum) >= 0) && ((pnum) < MAX_OPEN_PIPES))
47 #define OPEN_PNUM(pnum)    (VALID_PNUM(pnum) && Pipes[pnum].open)
48 #define PNUM_OK(pnum,c) (OPEN_PNUM(pnum) && (c)==Pipes[pnum].cnum)
49
50 /* this macro should always be used to extract an pnum (smb_fid) from
51    a packet to ensure chaining works correctly */
52 #define GETPNUM(buf,where) (chain_pnum!= -1?chain_pnum:SVAL(buf,where))
53
54 char * known_pipes [] =
55 {
56   "lsarpc",
57 #if NTDOMAIN
58   "NETLOGON",
59   "srvsvc",
60 #endif
61   NULL
62 };
63
64 /****************************************************************************
65   reply to an open and X on a named pipe
66
67   This code is basically stolen from reply_open_and_X with some
68   wrinkles to handle pipes.
69 ****************************************************************************/
70 int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize)
71 {
72   pstring fname;
73   int cnum = SVAL(inbuf,smb_tid);
74   int pnum = -1;
75   int smb_ofun = SVAL(inbuf,smb_vwv8);
76   int size=0,fmode=0,mtime=0,rmode=0;
77   int i;
78
79   /* XXXX we need to handle passed times, sattr and flags */
80   pstrcpy(fname,smb_buf(inbuf));
81
82   /* If the name doesn't start \PIPE\ then this is directed */
83   /* at a mailslot or something we really, really don't understand, */
84   /* not just something we really don't understand. */
85   if ( strncmp(fname,PIPE,PIPELEN) != 0 )
86     return(ERROR(ERRSRV,ERRaccess));
87
88   DEBUG(4,("Opening pipe %s.\n", fname));
89
90   /* Strip \PIPE\ off the name. */
91   pstrcpy(fname,smb_buf(inbuf) + PIPELEN);
92
93   /* See if it is one we want to handle. */
94   for( i = 0; known_pipes[i] ; i++ )
95     if( strcmp(fname,known_pipes[i]) == 0 )
96       break;
97
98   if ( known_pipes[i] == NULL )
99     return(ERROR(ERRSRV,ERRaccess));
100
101   /* Known pipes arrive with DIR attribs. Remove it so a regular file */
102   /* can be opened and add it in after the open. */
103   DEBUG(3,("Known pipe %s opening.\n",fname));
104   smb_ofun |= 0x10;             /* Add Create it not exists flag */
105
106   pnum = open_rpc_pipe_hnd(fname, cnum);
107   if (pnum < 0) return(ERROR(ERRSRV,ERRnofids));
108
109   /* Prepare the reply */
110   set_message(outbuf,15,0,True);
111
112   /* Mark the opened file as an existing named pipe in message mode. */
113   SSVAL(outbuf,smb_vwv9,2);
114   SSVAL(outbuf,smb_vwv10,0xc700);
115
116   if (rmode == 2)
117   {
118     DEBUG(4,("Resetting open result to open from create.\n"));
119     rmode = 1;
120   }
121
122   SSVAL(outbuf,smb_vwv2, pnum + 0x800); /* mark file handle up into high range */
123   SSVAL(outbuf,smb_vwv3,fmode);
124   put_dos_date3(outbuf,smb_vwv4,mtime);
125   SIVAL(outbuf,smb_vwv6,size);
126   SSVAL(outbuf,smb_vwv8,rmode);
127   SSVAL(outbuf,smb_vwv11,0);
128
129   return chain_reply(inbuf,outbuf,length,bufsize);
130 }
131
132
133 /****************************************************************************
134   reply to a close
135 ****************************************************************************/
136 int reply_pipe_close(char *inbuf,char *outbuf)
137 {
138   int pnum = get_rpc_pipe_num(inbuf,smb_vwv0);
139   int cnum = SVAL(inbuf,smb_tid);
140   int outsize = set_message(outbuf,0,0,True);
141
142   if (!close_rpc_pipe_hnd(pnum, cnum)) return(ERROR(ERRDOS,ERRbadfid));
143
144   return(outsize);
145 }
146
147
148 /****************************************************************************
149  api_LsarpcSNPHS
150
151  SetNamedPipeHandleState on \PIPE\lsarpc. We can't really do much here,
152  so just blithely return True. This is really only for NT domain stuff,
153  we we're only handling that - don't assume Samba now does complete
154  named pipe handling.
155 ****************************************************************************/
156 BOOL api_LsarpcSNPHS(int cnum,int uid, char *param,char *data,
157                      int mdrcnt,int mprcnt,
158                      char **rdata,char **rparam,
159                      int *rdata_len,int *rparam_len)
160 {
161   uint16 id;
162
163   id = param[0] + (param[1] << 8);
164   DEBUG(4,("lsarpc SetNamedPipeHandleState to code %x\n",id));
165   return(True);
166 }
167
168
169 /****************************************************************************
170  api_LsarpcTNP
171
172  TransactNamedPipe on \PIPE\lsarpc.
173 ****************************************************************************/
174 static void LsarpcTNP1(char *data,char **rdata, int *rdata_len)
175 {
176   uint32 dword1, dword2;
177   char pname[] = "\\PIPE\\lsass";
178
179   /* All kinds of mysterious numbers here */
180   *rdata_len = 68;
181   *rdata = REALLOC(*rdata,*rdata_len);
182
183   dword1 = IVAL(data,0xC);
184   dword2 = IVAL(data,0x10);
185
186   SIVAL(*rdata,0,0xc0005);
187   SIVAL(*rdata,4,0x10);
188   SIVAL(*rdata,8,0x44);
189   SIVAL(*rdata,0xC,dword1);
190   
191   SIVAL(*rdata,0x10,dword2);
192   SIVAL(*rdata,0x14,0x15);
193   SSVAL(*rdata,0x18,sizeof(pname));
194   strcpy(*rdata + 0x1a,pname);
195   SIVAL(*rdata,0x28,1);
196   memcpy(*rdata + 0x30, data + 0x34, 0x14);
197 }
198
199 static void LsarpcTNP2(char *data,char **rdata, int *rdata_len)
200 {
201   uint32 dword1;
202
203   /* All kinds of mysterious numbers here */
204   *rdata_len = 48;
205   *rdata = REALLOC(*rdata,*rdata_len);
206
207   dword1 = IVAL(data,0xC);
208
209   SIVAL(*rdata,0,0x03020005);
210   SIVAL(*rdata,4,0x10);
211   SIVAL(*rdata,8,0x30);
212   SIVAL(*rdata,0xC,dword1);
213   SIVAL(*rdata,0x10,0x18);
214   SIVAL(*rdata,0x1c,0x44332211);
215   SIVAL(*rdata,0x20,0x88776655);
216   SIVAL(*rdata,0x24,0xCCBBAA99);
217   SIVAL(*rdata,0x28,0x11FFEEDD);
218 }
219
220 static void LsarpcTNP3(char *data,char **rdata, int *rdata_len)
221 {
222   uint32 dword1;
223   uint16 word1;
224   char * workgroup = myworkgroup;
225   int wglen = strlen(workgroup);
226   int i;
227
228   /* All kinds of mysterious numbers here */
229   *rdata_len = 90 + 2 * wglen;
230   *rdata = REALLOC(*rdata,*rdata_len);
231
232   dword1 = IVAL(data,0xC);
233   word1 = SVAL(data,0x2C);
234
235   SIVAL(*rdata,0,0x03020005);
236   SIVAL(*rdata,4,0x10);
237   SIVAL(*rdata,8,0x60);
238   SIVAL(*rdata,0xC,dword1);
239   SIVAL(*rdata,0x10,0x48);
240   SSVAL(*rdata,0x18,0x5988);    /* This changes */
241   SSVAL(*rdata,0x1A,0x15);
242   SSVAL(*rdata,0x1C,word1);
243   SSVAL(*rdata,0x20,6);
244   SSVAL(*rdata,0x22,8);
245   SSVAL(*rdata,0x24,0x8E8);     /* So does this */
246   SSVAL(*rdata,0x26,0x15);
247   SSVAL(*rdata,0x28,0x4D48);    /* And this */
248   SSVAL(*rdata,0x2A,0x15);
249   SIVAL(*rdata,0x2C,4);
250   SIVAL(*rdata,0x34,wglen);
251   for ( i = 0 ; i < wglen ; i++ )
252     (*rdata)[0x38 + i * 2] = workgroup[i];
253    
254   /* Now fill in the rest */
255   i = 0x38 + wglen * 2;
256   SSVAL(*rdata,i,0x648);
257   SIVAL(*rdata,i+2,4);
258   SIVAL(*rdata,i+6,0x401);
259   SSVAL(*rdata,i+0xC,0x500);
260   SIVAL(*rdata,i+0xE,0x15);
261   SIVAL(*rdata,i+0x12,0x2372FE1);
262   SIVAL(*rdata,i+0x16,0x7E831BEF);
263   SIVAL(*rdata,i+0x1A,0x4B454B2);
264 }
265
266 static void LsarpcTNP4(char *data,char **rdata, int *rdata_len)
267 {
268   uint32 dword1;
269
270   /* All kinds of mysterious numbers here */
271   *rdata_len = 48;
272   *rdata = REALLOC(*rdata,*rdata_len);
273
274   dword1 = IVAL(data,0xC);
275
276   SIVAL(*rdata,0,0x03020005);
277   SIVAL(*rdata,4,0x10);
278   SIVAL(*rdata,8,0x30);
279   SIVAL(*rdata,0xC,dword1);
280   SIVAL(*rdata,0x10,0x18);
281 }
282
283
284 BOOL api_LsarpcTNP(int cnum,int uid, char *param,char *data,
285                      int mdrcnt,int mprcnt,
286                      char **rdata,char **rparam,
287                      int *rdata_len,int *rparam_len)
288 {
289   uint32 id,id2;
290
291   id = IVAL(data,0);
292
293   DEBUG(4,("lsarpc TransactNamedPipe id %lx\n",id));
294   switch (id)
295   {
296     case 0xb0005:
297       LsarpcTNP1(data,rdata,rdata_len);
298       break;
299
300     case 0x03000005:
301       id2 = IVAL(data,8);
302       DEBUG(4,("\t- Suboperation %lx\n",id2));
303       switch (id2 & 0xF)
304       {
305         case 8:
306           LsarpcTNP2(data,rdata,rdata_len);
307           break;
308
309         case 0xC:
310           LsarpcTNP4(data,rdata,rdata_len);
311           break;
312
313         case 0xE:
314           LsarpcTNP3(data,rdata,rdata_len);
315           break;
316       }
317       break;
318   }
319   return(True);
320 }
321