2 Unix SMB/Netbios implementation.
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.
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.
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.
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.
24 This file handles reply_ calls on named pipes that the server
25 makes to handle specific protocols
32 #define PIPE "\\PIPE\\"
33 #define PIPELEN strlen(PIPE)
35 #define REALLOC(ptr,size) Realloc(ptr,MAX((size),4*1024))
37 /* look in server.c for some explanation of these variables */
39 extern int DEBUGLEVEL;
40 extern char magic_char;
41 extern BOOL case_sensitive;
42 extern pstring sesssetup_user;
44 extern fstring myworkgroup;
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)
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))
54 char * known_pipes [] =
64 /****************************************************************************
65 reply to an open and X on a named pipe
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)
73 int cnum = SVAL(inbuf,smb_tid);
75 int smb_ofun = SVAL(inbuf,smb_vwv8);
76 int size=0,fmode=0,mtime=0,rmode=0;
79 /* XXXX we need to handle passed times, sattr and flags */
80 pstrcpy(fname,smb_buf(inbuf));
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));
88 DEBUG(4,("Opening pipe %s.\n", fname));
90 /* Strip \PIPE\ off the name. */
91 pstrcpy(fname,smb_buf(inbuf) + PIPELEN);
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 )
98 if ( known_pipes[i] == NULL )
99 return(ERROR(ERRSRV,ERRaccess));
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 */
106 pnum = open_rpc_pipe_hnd(fname, cnum);
107 if (pnum < 0) return(ERROR(ERRSRV,ERRnofids));
109 /* Prepare the reply */
110 set_message(outbuf,15,0,True);
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);
118 DEBUG(4,("Resetting open result to open from create.\n"));
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);
129 return chain_reply(inbuf,outbuf,length,bufsize);
133 /****************************************************************************
135 ****************************************************************************/
136 int reply_pipe_close(char *inbuf,char *outbuf)
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);
142 if (!close_rpc_pipe_hnd(pnum, cnum)) return(ERROR(ERRDOS,ERRbadfid));
148 /****************************************************************************
151 SetNamedPipeHandleState on \PIPE\lsarpc.
152 ****************************************************************************/
153 BOOL api_LsarpcSNPHS(int pnum, int cnum, char *param)
157 if (!param) return False;
159 id = param[0] + (param[1] << 8);
160 DEBUG(4,("lsarpc SetNamedPipeHandleState to code %x\n",id));
162 return set_rpc_pipe_hnd_state(pnum, cnum, id);
166 /****************************************************************************
169 TransactNamedPipe on \PIPE\lsarpc.
170 ****************************************************************************/
171 static void LsarpcTNP1(char *data,char **rdata, int *rdata_len)
173 uint32 dword1, dword2;
174 char pname[] = "\\PIPE\\lsass";
176 /* All kinds of mysterious numbers here */
178 *rdata = REALLOC(*rdata,*rdata_len);
180 dword1 = IVAL(data,0xC);
181 dword2 = IVAL(data,0x10);
183 SIVAL(*rdata,0,0xc0005);
184 SIVAL(*rdata,4,0x10);
185 SIVAL(*rdata,8,0x44);
186 SIVAL(*rdata,0xC,dword1);
188 SIVAL(*rdata,0x10,dword2);
189 SIVAL(*rdata,0x14,0x15);
190 SSVAL(*rdata,0x18,sizeof(pname));
191 strcpy(*rdata + 0x1a,pname);
192 SIVAL(*rdata,0x28,1);
193 memcpy(*rdata + 0x30, data + 0x34, 0x14);
196 static void LsarpcTNP2(char *data,char **rdata, int *rdata_len)
200 /* All kinds of mysterious numbers here */
202 *rdata = REALLOC(*rdata,*rdata_len);
204 dword1 = IVAL(data,0xC);
206 SIVAL(*rdata,0,0x03020005);
207 SIVAL(*rdata,4,0x10);
208 SIVAL(*rdata,8,0x30);
209 SIVAL(*rdata,0xC,dword1);
210 SIVAL(*rdata,0x10,0x18);
211 SIVAL(*rdata,0x1c,0x44332211);
212 SIVAL(*rdata,0x20,0x88776655);
213 SIVAL(*rdata,0x24,0xCCBBAA99);
214 SIVAL(*rdata,0x28,0x11FFEEDD);
217 static void LsarpcTNP3(char *data,char **rdata, int *rdata_len)
221 char * workgroup = myworkgroup;
222 int wglen = strlen(workgroup);
225 /* All kinds of mysterious numbers here */
226 *rdata_len = 90 + 2 * wglen;
227 *rdata = REALLOC(*rdata,*rdata_len);
229 dword1 = IVAL(data,0xC);
230 word1 = SVAL(data,0x2C);
232 SIVAL(*rdata,0,0x03020005);
233 SIVAL(*rdata,4,0x10);
234 SIVAL(*rdata,8,0x60);
235 SIVAL(*rdata,0xC,dword1);
236 SIVAL(*rdata,0x10,0x48);
237 SSVAL(*rdata,0x18,0x5988); /* This changes */
238 SSVAL(*rdata,0x1A,0x15);
239 SSVAL(*rdata,0x1C,word1);
240 SSVAL(*rdata,0x20,6);
241 SSVAL(*rdata,0x22,8);
242 SSVAL(*rdata,0x24,0x8E8); /* So does this */
243 SSVAL(*rdata,0x26,0x15);
244 SSVAL(*rdata,0x28,0x4D48); /* And this */
245 SSVAL(*rdata,0x2A,0x15);
246 SIVAL(*rdata,0x2C,4);
247 SIVAL(*rdata,0x34,wglen);
248 for ( i = 0 ; i < wglen ; i++ )
249 (*rdata)[0x38 + i * 2] = workgroup[i];
251 /* Now fill in the rest */
252 i = 0x38 + wglen * 2;
253 SSVAL(*rdata,i,0x648);
255 SIVAL(*rdata,i+6,0x401);
256 SSVAL(*rdata,i+0xC,0x500);
257 SIVAL(*rdata,i+0xE,0x15);
258 SIVAL(*rdata,i+0x12,0x2372FE1);
259 SIVAL(*rdata,i+0x16,0x7E831BEF);
260 SIVAL(*rdata,i+0x1A,0x4B454B2);
263 static void LsarpcTNP4(char *data,char **rdata, int *rdata_len)
267 /* All kinds of mysterious numbers here */
269 *rdata = REALLOC(*rdata,*rdata_len);
271 dword1 = IVAL(data,0xC);
273 SIVAL(*rdata,0,0x03020005);
274 SIVAL(*rdata,4,0x10);
275 SIVAL(*rdata,8,0x30);
276 SIVAL(*rdata,0xC,dword1);
277 SIVAL(*rdata,0x10,0x18);
281 BOOL api_LsarpcTNP(int cnum,int uid, char *param,char *data,
282 int mdrcnt,int mprcnt,
283 char **rdata,char **rparam,
284 int *rdata_len,int *rparam_len)
290 DEBUG(4,("lsarpc TransactNamedPipe id %lx\n",id));
294 LsarpcTNP1(data,rdata,rdata_len);
299 DEBUG(4,("\t- Suboperation %lx\n",id2));
303 LsarpcTNP2(data,rdata,rdata_len);
307 LsarpcTNP4(data,rdata,rdata_len);
311 LsarpcTNP3(data,rdata,rdata_len);