2 Unix SMB/Netbios implementation.
4 process incoming packets - main loop
5 Copyright (C) Andrew Tridgell 1992-1998
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.
24 extern int DEBUGLEVEL;
26 time_t smb_last_time=(time_t)0;
27 static struct pipes_struct static_pipe;
29 char *InBuffer = NULL;
30 char *OutBuffer = NULL;
31 char *last_inbuf = NULL;
34 * Size of data we can send to client. Set
35 * by the client for all protocols above CORE.
36 * Set by us for CORE protocol.
38 int max_send = BUFFER_SIZE;
40 * Size of the data we can receive. Set by us.
41 * Can be modified by the max xmit parameter.
43 int max_recv = BUFFER_SIZE;
45 extern int last_message;
46 extern pstring sesssetup_user;
47 extern char *last_inbuf;
48 extern char *InBuffer;
49 extern char *OutBuffer;
50 extern int smb_read_error;
51 extern BOOL reload_after_sighup;
55 /****************************************************************************
56 Do a select on an two fd's - with timeout.
58 If a local udp message has been pushed onto the
59 queue (this can only happen during oplock break
60 processing) return this first.
62 If a pending smb message has been pushed onto the
63 queue (this can only happen during oplock break
64 processing) return this next.
66 If the first smbfd is ready then read an smb from it.
67 if the second (loopback UDP) fd is ready then read a message
68 from it and setup the buffer header to identify the length
70 Returns False on timeout or error.
73 The timeout is in milli seconds
74 ****************************************************************************/
76 static BOOL receive_message_or_smb(char *buffer, int buffer_len,
77 int timeout, BOOL *got_smb)
90 * Check to see if we already have a message on the smb queue.
91 * If so - copy and return it.
95 * Setup the select read fd set.
102 to.tv_sec = timeout / 1000;
103 to.tv_usec = (timeout % 1000) * 1000;
105 selrtn = sys_select(MAX(maxfd,Client)+1,&fds,NULL, timeout>0?&to:NULL);
109 /* something is wrong. Maybe the socket is dead? */
110 smb_read_error = READ_ERROR;
114 /* Did we timeout ? */
116 smb_read_error = READ_TIMEOUT;
120 if (FD_ISSET(Client,&fds))
123 return receive_smb(Client, buffer, 0);
128 /****************************************************************************
129 Get the next SMB packet, doing the local message processing automatically.
130 ****************************************************************************/
132 BOOL receive_next_smb(char *inbuf, int bufsize, int timeout)
134 BOOL got_smb = False;
139 ret = receive_message_or_smb(inbuf,bufsize,timeout,&got_smb);
146 if(ret && (CVAL(inbuf,0) == 0x85))
148 /* Keepalive packet. */
153 while(ret && !got_smb);
160 These flags determine some of the permissions required to do an operation
162 Note that I don't set NEED_WRITE on some write operations because they
163 are used by some brain-dead clients when printing, and I don't want to
164 force write permissions on print services.
166 #define AS_USER (1<<0)
167 #define NEED_WRITE (1<<1)
168 #define TIME_INIT (1<<2)
169 #define CAN_IPC (1<<3)
170 #define AS_GUEST (1<<5)
171 #define QUEUE_IN_OPLOCK (1<<6)
174 define a list of possible SMB messages and their corresponding
175 functions. Any message that has a NULL function is unimplemented -
176 please feel free to contribute implementations!
179 /****************************************************************************
180 do a switch on the message type, and return the response size
181 ****************************************************************************/
182 static int do_message(char *inbuf,char *outbuf,int size,int bufsize)
186 pipes_struct *p = &static_pipe;
190 /* make a static data parsing structure from the api_fd_reply data */
191 prs_init(&pd, 0, 4, 0, True);
192 mem_create(pd.data, smb_base(inbuf), 0, smb_len(inbuf), 0, False);
197 /* dce/rpc command */
198 if (rpc_to_smb(p, smb_base(inbuf), smb_len(inbuf)))
200 char *copy_into = smb_base(outbuf);
201 outsize = mem_buf_len(p->rsmb_pdu.data);
202 if (!mem_buf_copy(copy_into, p->rsmb_pdu.data, 0, outsize))
206 mem_free_data(p->rsmb_pdu.data);
213 /****************************************************************************
214 construct a reply to the incoming packet
215 ****************************************************************************/
216 static int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
219 smb_last_time = time(NULL);
221 outsize = do_message(inbuf,outbuf,size,bufsize) + 4;
224 _smb_setlen(outbuf,outsize - 4);
229 /****************************************************************************
230 process an smb from the client - split out from the process() code so
231 it can be used by the oplock break code.
232 ****************************************************************************/
233 void process_smb(char *inbuf, char *outbuf)
236 static int trans_num;
237 int32 len = smb_len(inbuf);
240 if (trans_num == 0) {
241 /* on the first packet, check the global hosts allow/ hosts
242 deny parameters before doing any parsing of the packet
243 passed to us by the client. This prevents attacks on our
244 parsing code from hosts not in the hosts allow list */
245 if (!check_access(Client, lp_hostsallow(-1), lp_hostsdeny(-1))) {
246 /* send a negative session response "not listining on calling
248 DEBUG( 1, ( "Connection denied from %s\n",
249 client_addr(Client) ) );
250 exit_server("connection denied");
254 DEBUG( 6, ( "got message of len 0x%x\n", len ) );
255 DEBUG( 3, ( "Transaction %d of length %d\n", trans_num, nread ) );
257 dump_data(10, inbuf, len);
260 if(trans_num == 1 && VT_Check(inbuf))
267 nread = construct_reply(inbuf,outbuf,nread,max_send);
271 dump_data(10, outbuf, nread);
273 if (nread != smb_len(outbuf) + 4)
275 DEBUG(0,("ERROR: Invalid message response size! %d %d\n",
276 nread, smb_len(outbuf)));
279 send_smb(Client,outbuf);
285 BOOL get_user_creds(struct user_creds *usr)
290 BOOL new_con = False;
301 DEBUG(10,("get_user_creds: first request\n"));
303 rl = read(Client, &buf, sizeof(len));
305 if (rl != sizeof(len))
307 DEBUG(0,("Unable to read length\n"));
308 dump_data(0, buf, sizeof(len));
314 if (len > sizeof(buf))
316 DEBUG(0,("length %d too long\n", len));
320 rl = read(Client, buf, len);
324 DEBUG(0,("Unable to read from connection\n"));
328 #ifdef DEBUG_PASSWORD
329 dump_data(100, buf, rl);
332 /* make a static data parsing structure from the api_fd_reply data */
333 prs_init(&ps, 0, 4, 0, True);
334 mem_create(ps.data, buf, 0, len, 0, False);
336 if (!creds_io_cmd("creds", &cmd, &ps, 0))
338 DEBUG(0,("Unable to parse credentials\n"));
339 mem_free_data(ps.data);
343 mem_free_data(ps.data);
347 DEBUG(0,("Buffer size %d %d!\n", ps.offset, rl));
354 case AGENT_CMD_CON_ANON:
359 case AGENT_CMD_CON_REUSE:
366 DEBUG(0,("unknown command %d\n", cmd.command));
371 status = new_con ? 0x0 : 0x1;
373 if (write(Client, &status, sizeof(status)) !=
382 /****************************************************************************
383 process commands from the client
384 ****************************************************************************/
385 void lsarpcd_process(void)
387 struct user_creds usr;
388 gid_t *groups = NULL;
390 ZERO_STRUCT(static_pipe);
392 fstrcpy(static_pipe.name, "lsarpc");
394 if (!get_user_creds(&usr))
396 DEBUG(0,("authentication failed\n"));
397 free_user_creds(&usr);
401 if (usr.uxs.num_grps != 0)
404 groups = malloc(usr.uxs.num_grps * sizeof(groups[0]));
409 for (i = 0; i < usr.uxs.num_grps; i++)
411 groups[i] = (gid_t)usr.uxs.grps[i];
415 static_pipe.vuid = create_vuid(usr.uxs.uid, usr.uxs.gid,
416 usr.uxs.num_grps, groups,
418 usr.uxc.requested_name,
421 usr.ntc.pwd.sess_key);
423 if (static_pipe.vuid == UID_FIELD_INVALID)
428 free_user_creds(&usr);
430 become_vuser(static_pipe.vuid);
432 static_pipe.l = malloc(sizeof(*static_pipe.l));
433 if (static_pipe.l == NULL)
438 ZERO_STRUCTP(static_pipe.l);
440 InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
441 OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
442 if ((InBuffer == NULL) || (OutBuffer == NULL))
445 InBuffer += SMB_ALIGNMENT;
446 OutBuffer += SMB_ALIGNMENT;
448 max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
450 /* re-initialise the timezone */
456 int service_load_counter = 0;
457 BOOL got_smb = False;
461 for (counter=SMBD_SELECT_LOOP;
462 !receive_message_or_smb(InBuffer,BUFFER_SIZE,
463 SMBD_SELECT_LOOP*1000,&got_smb);
464 counter += SMBD_SELECT_LOOP)
468 if (counter > 365 * 3600) /* big number of seconds. */
471 service_load_counter = 0;
474 if (smb_read_error == READ_EOF)
476 DEBUG(3,("end of file from client\n"));
480 if (smb_read_error == READ_ERROR)
482 DEBUG(3,("receive_smb error (%s) exiting\n",
489 /* become root again if waiting */
492 /* check for smb.conf reload */
493 if (counter >= service_load_counter + SMBD_RELOAD_CHECK)
495 service_load_counter = counter;
497 /* reload services, if files have changed. */
498 reload_services(True);
502 * If reload_after_sighup == True then we got a SIGHUP
503 * and are being asked to reload. Fix from <branko.cibej@hermes.si>
506 if (reload_after_sighup)
508 DEBUG(0,("Reloading services after SIGHUP\n"));
509 reload_services(False);
510 reload_after_sighup = False;
512 * Use this as an excuse to print some stats.
516 /* automatic timeout if all connections are closed */
517 if (counter >= IDLE_CLOSED_TIMEOUT)
519 DEBUG( 2, ( "Closing idle connection\n" ) );
526 process_smb(InBuffer, OutBuffer);