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;
28 char *InBuffer = NULL;
29 char *OutBuffer = NULL;
30 char *last_inbuf = NULL;
33 * Size of data we can send to client. Set
34 * by the client for all protocols above CORE.
35 * Set by us for CORE protocol.
37 int max_send = BUFFER_SIZE;
39 * Size of the data we can receive. Set by us.
40 * Can be modified by the max xmit parameter.
42 int max_recv = BUFFER_SIZE;
44 extern int last_message;
45 extern int global_oplock_break;
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;
52 extern BOOL global_machine_password_needs_changing;
53 extern fstring global_myworkgroup;
54 extern pstring global_myname;
57 /****************************************************************************
58 structure to hold a linked list of queued messages.
60 ****************************************************************************/
66 } pending_message_list;
68 static ubi_slList smb_oplock_queue = { NULL, (ubi_slNodePtr)&smb_oplock_queue, 0};
70 /****************************************************************************
71 Function to push a message onto the tail of a linked list of smb messages ready
73 ****************************************************************************/
75 static BOOL push_message(ubi_slList *list_head, char *buf, int msg_len)
77 pending_message_list *msg = (pending_message_list *)
78 malloc(sizeof(pending_message_list));
82 DEBUG(0,("push_message: malloc fail (1)\n"));
86 msg->msg_buf = (char *)malloc(msg_len);
87 if(msg->msg_buf == NULL)
89 DEBUG(0,("push_message: malloc fail (2)\n"));
94 memcpy(msg->msg_buf, buf, msg_len);
95 msg->msg_len = msg_len;
97 ubi_slAddTail( list_head, msg);
102 /****************************************************************************
103 Function to push a smb message onto a linked list of local smb messages ready
105 ****************************************************************************/
107 BOOL push_oplock_pending_smb_message(char *buf, int msg_len)
109 return push_message(&smb_oplock_queue, buf, msg_len);
112 /****************************************************************************
113 Do a select on an two fd's - with timeout.
115 If a local udp message has been pushed onto the
116 queue (this can only happen during oplock break
117 processing) return this first.
119 If a pending smb message has been pushed onto the
120 queue (this can only happen during oplock break
121 processing) return this next.
123 If the first smbfd is ready then read an smb from it.
124 if the second (loopback UDP) fd is ready then read a message
125 from it and setup the buffer header to identify the length
127 Returns False on timeout or error.
130 The timeout is in milli seconds
131 ****************************************************************************/
133 static BOOL receive_message_or_smb(char *buffer, int buffer_len,
134 int timeout, BOOL *got_smb)
147 * Check to see if we already have a message on the smb queue.
148 * If so - copy and return it.
151 if(ubi_slCount(&smb_oplock_queue) != 0)
153 pending_message_list *msg = (pending_message_list *)ubi_slRemHead(&smb_oplock_queue);
154 memcpy(buffer, msg->msg_buf, MIN(buffer_len, msg->msg_len));
156 /* Free the message we just copied. */
157 free((char *)msg->msg_buf);
161 DEBUG(5,("receive_message_or_smb: returning queued smb message.\n"));
166 * Setup the select read fd set.
171 maxfd = setup_oplock_select_set(&fds);
173 to.tv_sec = timeout / 1000;
174 to.tv_usec = (timeout % 1000) * 1000;
176 selrtn = sys_select(MAX(maxfd,Client)+1,&fds,timeout>0?&to:NULL);
180 /* something is wrong. Maybe the socket is dead? */
181 smb_read_error = READ_ERROR;
185 /* Did we timeout ? */
187 smb_read_error = READ_TIMEOUT;
191 if (FD_ISSET(Client,&fds))
194 return receive_smb(Client, buffer, 0);
198 return receive_local_message(&fds, buffer, buffer_len, 0);
202 /****************************************************************************
203 Get the next SMB packet, doing the local message processing automatically.
204 ****************************************************************************/
206 BOOL receive_next_smb(char *inbuf, int bufsize, int timeout)
208 BOOL got_smb = False;
213 ret = receive_message_or_smb(inbuf,bufsize,timeout,&got_smb);
217 /* Deal with oplock break requests from other smbd's. */
218 process_local_message(inbuf, bufsize);
222 if(ret && (CVAL(inbuf,0) == 0x85))
224 /* Keepalive packet. */
229 while(ret && !got_smb);
236 These flags determine some of the permissions required to do an operation
238 Note that I don't set NEED_WRITE on some write operations because they
239 are used by some brain-dead clients when printing, and I don't want to
240 force write permissions on print services.
242 #define AS_USER (1<<0)
243 #define NEED_WRITE (1<<1)
244 #define TIME_INIT (1<<2)
245 #define CAN_IPC (1<<3)
246 #define AS_GUEST (1<<5)
247 #define QUEUE_IN_OPLOCK (1<<6)
250 define a list of possible SMB messages and their corresponding
251 functions. Any message that has a NULL function is unimplemented -
252 please feel free to contribute implementations!
254 struct smb_message_struct
258 int (*fn)(connection_struct *conn, char *, char *, int, int);
265 {SMBnegprot,"SMBnegprot",reply_negprot,0},
266 {SMBtcon,"SMBtcon",reply_tcon,0},
267 {SMBtdis,"SMBtdis",reply_tdis,0},
268 {SMBexit,"SMBexit",reply_exit,0},
269 {SMBioctl,"SMBioctl",reply_ioctl,0},
270 {SMBecho,"SMBecho",reply_echo,0},
271 {SMBsesssetupX,"SMBsesssetupX",reply_sesssetup_and_X,0},
272 {SMBtconX,"SMBtconX",reply_tcon_and_X,0},
273 {SMBulogoffX, "SMBulogoffX", reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
274 {SMBgetatr,"SMBgetatr",reply_getatr,AS_USER},
275 {SMBsetatr,"SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
276 {SMBchkpth,"SMBchkpth",reply_chkpth,AS_USER},
277 {SMBsearch,"SMBsearch",reply_search,AS_USER},
278 {SMBopen,"SMBopen",reply_open,AS_USER | QUEUE_IN_OPLOCK },
280 /* note that SMBmknew and SMBcreate are deliberately overloaded */
281 {SMBcreate,"SMBcreate",reply_mknew,AS_USER},
282 {SMBmknew,"SMBmknew",reply_mknew,AS_USER},
284 {SMBunlink,"SMBunlink",reply_unlink,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK},
285 {SMBread,"SMBread",reply_read,AS_USER},
286 {SMBwrite,"SMBwrite",reply_write,AS_USER},
287 {SMBclose,"SMBclose",reply_close,AS_USER | CAN_IPC},
288 {SMBmkdir,"SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
289 {SMBrmdir,"SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
290 {SMBdskattr,"SMBdskattr",reply_dskattr,AS_USER},
291 {SMBmv,"SMBmv",reply_mv,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK},
293 /* this is a Pathworks specific call, allowing the
294 changing of the root path */
295 {pSETDIR,"pSETDIR",reply_setdir,AS_USER},
297 {SMBlseek,"SMBlseek",reply_lseek,AS_USER},
298 {SMBflush,"SMBflush",reply_flush,AS_USER},
299 {SMBctemp,"SMBctemp",reply_ctemp,AS_USER | QUEUE_IN_OPLOCK },
300 {SMBsplopen,"SMBsplopen",reply_printopen,AS_USER | QUEUE_IN_OPLOCK },
301 {SMBsplclose,"SMBsplclose",reply_printclose,AS_USER},
302 {SMBsplretq,"SMBsplretq",reply_printqueue,AS_USER},
303 {SMBsplwr,"SMBsplwr",reply_printwrite,AS_USER},
304 {SMBlock,"SMBlock",reply_lock,AS_USER},
305 {SMBunlock,"SMBunlock",reply_unlock,AS_USER},
307 /* CORE+ PROTOCOL FOLLOWS */
309 {SMBreadbraw,"SMBreadbraw",reply_readbraw,AS_USER},
310 {SMBwritebraw,"SMBwritebraw",reply_writebraw,AS_USER},
311 {SMBwriteclose,"SMBwriteclose",reply_writeclose,AS_USER},
312 {SMBlockread,"SMBlockread",reply_lockread,AS_USER},
313 {SMBwriteunlock,"SMBwriteunlock",reply_writeunlock,AS_USER},
315 /* LANMAN1.0 PROTOCOL FOLLOWS */
317 {SMBreadBmpx,"SMBreadBmpx",reply_readbmpx,AS_USER},
318 {SMBreadBs,"SMBreadBs",NULL,AS_USER},
319 {SMBwriteBmpx,"SMBwriteBmpx",reply_writebmpx,AS_USER},
320 {SMBwriteBs,"SMBwriteBs",reply_writebs,AS_USER},
321 {SMBwritec,"SMBwritec",NULL,AS_USER},
322 {SMBsetattrE,"SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE},
323 {SMBgetattrE,"SMBgetattrE",reply_getattrE,AS_USER},
324 {SMBtrans,"SMBtrans",reply_trans,AS_USER | CAN_IPC},
325 {SMBtranss,"SMBtranss",NULL,AS_USER | CAN_IPC},
326 {SMBioctls,"SMBioctls",NULL,AS_USER},
327 {SMBcopy,"SMBcopy",reply_copy,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK },
328 {SMBmove,"SMBmove",NULL,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK },
330 {SMBopenX,"SMBopenX",reply_open_and_X,AS_USER | CAN_IPC | QUEUE_IN_OPLOCK },
331 {SMBreadX,"SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
332 {SMBwriteX,"SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
333 {SMBlockingX,"SMBlockingX",reply_lockingX,AS_USER},
335 {SMBffirst,"SMBffirst",reply_search,AS_USER},
336 {SMBfunique,"SMBfunique",reply_search,AS_USER},
337 {SMBfclose,"SMBfclose",reply_fclose,AS_USER},
339 /* LANMAN2.0 PROTOCOL FOLLOWS */
340 {SMBfindnclose, "SMBfindnclose", reply_findnclose, AS_USER},
341 {SMBfindclose, "SMBfindclose", reply_findclose,AS_USER},
342 {SMBtrans2, "SMBtrans2", reply_trans2, AS_USER | CAN_IPC},
343 {SMBtranss2, "SMBtranss2", reply_transs2, AS_USER},
345 /* NT PROTOCOL FOLLOWS */
346 {SMBntcreateX, "SMBntcreateX", reply_ntcreate_and_X, AS_USER | CAN_IPC | QUEUE_IN_OPLOCK },
347 {SMBnttrans, "SMBnttrans", reply_nttrans, AS_USER | CAN_IPC },
348 {SMBnttranss, "SMBnttranss", reply_nttranss, AS_USER | CAN_IPC },
349 {SMBntcancel, "SMBntcancel", reply_ntcancel, AS_USER },
351 /* messaging routines */
352 {SMBsends,"SMBsends",reply_sends,AS_GUEST},
353 {SMBsendstrt,"SMBsendstrt",reply_sendstrt,AS_GUEST},
354 {SMBsendend,"SMBsendend",reply_sendend,AS_GUEST},
355 {SMBsendtxt,"SMBsendtxt",reply_sendtxt,AS_GUEST},
357 /* NON-IMPLEMENTED PARTS OF THE CORE PROTOCOL */
359 {SMBsendb,"SMBsendb",NULL,AS_GUEST},
360 {SMBfwdname,"SMBfwdname",NULL,AS_GUEST},
361 {SMBcancelf,"SMBcancelf",NULL,AS_GUEST},
362 {SMBgetmac,"SMBgetmac",NULL,AS_GUEST}
366 /****************************************************************************
367 do a switch on the message type, and return the response size
368 ****************************************************************************/
369 static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize)
373 static int num_smb_messages =
374 sizeof(smb_messages) / sizeof(struct smb_message_struct);
384 /* make sure this is an SMB packet */
385 if (strncmp(smb_base(inbuf),"\377SMB",4) != 0)
387 DEBUG(2,("Non-SMB packet of length %d\n",smb_len(inbuf)));
391 for (match=0;match<num_smb_messages;match++)
392 if (smb_messages[match].code == type)
395 if (match == num_smb_messages)
397 DEBUG(0,("Unknown message type %d!\n",type));
398 outsize = reply_unknown(inbuf,outbuf);
402 DEBUG(3,("switch message %s (pid %d)\n",smb_messages[match].name,pid));
404 if(global_oplock_break && (smb_messages[match].flags & QUEUE_IN_OPLOCK))
407 * Queue this message as we are the process of an oplock break.
410 DEBUG( 2, ( "switch_message: queueing message due to being in " ) );
411 DEBUGADD( 2, ( "oplock break state.\n" ) );
413 push_oplock_pending_smb_message( inbuf, size );
417 if (smb_messages[match].fn)
419 int flags = smb_messages[match].flags;
420 static uint16 last_session_tag = UID_FIELD_INVALID;
421 /* In share mode security we must ignore the vuid. */
422 uint16 session_tag = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID : SVAL(inbuf,smb_uid);
423 connection_struct *conn = conn_find(SVAL(inbuf,smb_tid));
426 /* Ensure this value is replaced in the incoming packet. */
427 SSVAL(inbuf,smb_uid,session_tag);
430 * Ensure the correct username is in sesssetup_user.
431 * This is a really ugly bugfix for problems with
432 * multiple session_setup_and_X's being done and
433 * allowing %U and %G substitutions to work correctly.
434 * There is a reason this code is done here, don't
435 * move it unless you know what you're doing... :-).
438 if (session_tag != last_session_tag) {
439 user_struct *vuser = NULL;
441 last_session_tag = session_tag;
442 if(session_tag != UID_FIELD_INVALID)
443 vuser = get_valid_user_struct(session_tag);
445 pstrcpy( sesssetup_user, vuser->requested_name);
448 /* does this protocol need to be run as root? */
449 if (!(flags & AS_USER))
452 /* does this protocol need to be run as the connected user? */
453 if ((flags & AS_USER) && !become_user(conn,session_tag)) {
454 if (flags & AS_GUEST)
457 return(ERROR(ERRSRV,ERRinvnid));
459 /* this code is to work around a bug is MS client 3 without
460 introducing a security hole - it needs to be able to do
461 print queue checks as guest if it isn't logged in properly */
465 /* does it need write permission? */
466 if ((flags & NEED_WRITE) && !CAN_WRITE(conn))
467 return(ERROR(ERRSRV,ERRaccess));
469 /* ipc services are limited */
470 if (IS_IPC(conn) && (flags & AS_USER) && !(flags & CAN_IPC)) {
471 return(ERROR(ERRSRV,ERRaccess));
474 /* load service specific parameters */
476 !become_service(conn,(flags & AS_USER)?True:False)) {
477 return(ERROR(ERRSRV,ERRaccess));
480 /* does this protocol need to be run as guest? */
481 if ((flags & AS_GUEST) &&
483 !check_access(Client, lp_hostsallow(-1), lp_hostsdeny(-1)))) {
484 return(ERROR(ERRSRV,ERRaccess));
489 outsize = smb_messages[match].fn(conn, inbuf,outbuf,size,bufsize);
493 outsize = reply_unknown(inbuf,outbuf);
501 /****************************************************************************
502 construct a reply to the incoming packet
503 ****************************************************************************/
504 static int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
506 int type = CVAL(inbuf,smb_com);
508 int msg_type = CVAL(inbuf,0);
509 extern int chain_size;
511 smb_last_time = time(NULL);
518 return(reply_special(inbuf,outbuf));
520 construct_reply_common(inbuf, outbuf);
522 outsize = switch_message(type,inbuf,outbuf,size,bufsize);
524 outsize += chain_size;
527 smb_setlen(outbuf,outsize - 4);
532 /****************************************************************************
533 process an smb from the client - split out from the process() code so
534 it can be used by the oplock break code.
535 ****************************************************************************/
536 void process_smb(char *inbuf, char *outbuf)
540 extern BOOL sslEnabled; /* don't use function for performance reasons */
541 static int sslConnected = 0;
542 #endif /* WITH_SSL */
543 static int trans_num;
544 int msg_type = CVAL(inbuf,0);
545 int32 len = smb_len(inbuf);
549 profile_p->smb_count++;
552 if (trans_num == 0) {
553 /* on the first packet, check the global hosts allow/ hosts
554 deny parameters before doing any parsing of the packet
555 passed to us by the client. This prevents attacks on our
556 parsing code from hosts not in the hosts allow list */
557 if (!check_access(Client, lp_hostsallow(-1), lp_hostsdeny(-1))) {
558 /* send a negative session response "not listining on calling
560 static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
561 DEBUG( 1, ( "Connection denied from %s\n",
562 client_addr(Client) ) );
563 send_smb(Client,(char *)buf);
564 exit_server("connection denied");
568 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type, len ) );
569 DEBUG( 3, ( "Transaction %d of length %d\n", trans_num, nread ) );
572 if(sslEnabled && !sslConnected){
573 sslConnected = sslutil_negotiate_ssl(Client, msg_type);
574 if(sslConnected < 0){ /* an error occured */
575 exit_server("SSL negotiation failed");
576 }else if(sslConnected){
581 #endif /* WITH_SSL */
584 if(trans_num == 1 && VT_Check(inbuf))
593 else if(msg_type == 0x85)
594 return; /* Keepalive packet. */
596 nread = construct_reply(inbuf,outbuf,nread,max_send);
600 if (CVAL(outbuf,0) == 0)
603 if (nread != smb_len(outbuf) + 4)
605 DEBUG(0,("ERROR: Invalid message response size! %d %d\n",
606 nread, smb_len(outbuf)));
609 send_smb(Client,outbuf);
616 /****************************************************************************
617 return a string containing the function name of a SMB command
618 ****************************************************************************/
619 char *smb_fn_name(int type)
621 static char *unknown_name = "SMBunknown";
622 static int num_smb_messages =
623 sizeof(smb_messages) / sizeof(struct smb_message_struct);
626 for (match=0;match<num_smb_messages;match++)
627 if (smb_messages[match].code == type)
630 if (match == num_smb_messages)
631 return(unknown_name);
633 return(smb_messages[match].name);
637 /****************************************************************************
638 Helper function for contruct_reply.
639 ****************************************************************************/
641 void construct_reply_common(char *inbuf,char *outbuf)
643 bzero(outbuf,smb_size);
645 set_message(outbuf,0,0,True);
646 CVAL(outbuf,smb_com) = CVAL(inbuf,smb_com);
648 memcpy(outbuf+4,inbuf+4,4);
649 CVAL(outbuf,smb_rcls) = SMB_SUCCESS;
650 CVAL(outbuf,smb_reh) = 0;
651 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES)); /* bit 7 set
653 SSVAL(outbuf,smb_flg2,FLAGS2_LONG_PATH_COMPONENTS); /* say we support long filenames */
654 SSVAL(outbuf,smb_err,SMB_SUCCESS);
655 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
656 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
657 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
658 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
661 /****************************************************************************
662 construct a chained reply and add it to the already made reply
663 **************************************************************************/
664 int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
666 static char *orig_inbuf;
667 static char *orig_outbuf;
668 int smb_com1, smb_com2 = CVAL(inbuf,smb_vwv0);
669 unsigned smb_off2 = SVAL(inbuf,smb_vwv1);
670 char *inbuf2, *outbuf2;
672 char inbuf_saved[smb_wct];
673 char outbuf_saved[smb_wct];
674 extern int chain_size;
675 int wct = CVAL(outbuf,smb_wct);
676 int outsize = smb_size + 2*wct + SVAL(outbuf,smb_vwv0+2*wct);
678 /* maybe its not chained */
679 if (smb_com2 == 0xFF) {
680 CVAL(outbuf,smb_vwv0) = 0xFF;
684 if (chain_size == 0) {
685 /* this is the first part of the chain */
687 orig_outbuf = outbuf;
690 /* we need to tell the client where the next part of the reply will be */
691 SSVAL(outbuf,smb_vwv1,smb_offset(outbuf+outsize,outbuf));
692 CVAL(outbuf,smb_vwv0) = smb_com2;
694 /* remember how much the caller added to the chain, only counting stuff
695 after the parameter words */
696 chain_size += outsize - smb_wct;
698 /* work out pointers into the original packets. The
699 headers on these need to be filled in */
700 inbuf2 = orig_inbuf + smb_off2 + 4 - smb_wct;
701 outbuf2 = orig_outbuf + SVAL(outbuf,smb_vwv1) + 4 - smb_wct;
703 /* remember the original command type */
704 smb_com1 = CVAL(orig_inbuf,smb_com);
706 /* save the data which will be overwritten by the new headers */
707 memcpy(inbuf_saved,inbuf2,smb_wct);
708 memcpy(outbuf_saved,outbuf2,smb_wct);
710 /* give the new packet the same header as the last part of the SMB */
711 memmove(inbuf2,inbuf,smb_wct);
713 /* create the in buffer */
714 CVAL(inbuf2,smb_com) = smb_com2;
716 /* create the out buffer */
717 construct_reply_common(inbuf2, outbuf2);
719 DEBUG(3,("Chained message\n"));
722 /* process the request */
723 outsize2 = switch_message(smb_com2,inbuf2,outbuf2,size-chain_size,
726 /* copy the new reply and request headers over the old ones, but
727 preserve the smb_com field */
728 memmove(orig_outbuf,outbuf2,smb_wct);
729 CVAL(orig_outbuf,smb_com) = smb_com1;
731 /* restore the saved data, being careful not to overwrite any
732 data from the reply header */
733 memcpy(inbuf2,inbuf_saved,smb_wct);
735 int ofs = smb_wct - PTR_DIFF(outbuf2,orig_outbuf);
736 if (ofs < 0) ofs = 0;
737 memmove(outbuf2+ofs,outbuf_saved+ofs,smb_wct-ofs);
743 /****************************************************************************
744 process commands from the client
745 ****************************************************************************/
746 void smbd_process(void)
750 InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
751 OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
752 if ((InBuffer == NULL) || (OutBuffer == NULL))
755 InBuffer += SMB_ALIGNMENT;
756 OutBuffer += SMB_ALIGNMENT;
759 DEBUG(3,("priming nmbd\n"));
762 ip = *interpret_addr2("localhost");
763 if (zero_ip(ip)) ip = *interpret_addr2("127.0.0.1");
765 send_one_packet(OutBuffer,1,ip,NMB_PORT,SOCK_DGRAM);
770 max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
772 /* re-initialise the timezone */
777 int deadtime = lp_deadtime()*60;
779 int last_keepalive=0;
780 int service_load_counter = 0;
781 BOOL got_smb = False;
784 deadtime = DEFAULT_SMBD_TIMEOUT;
786 #if USE_READ_PREDICTION
787 if (lp_readprediction())
788 do_read_prediction();
793 for (counter=SMBD_SELECT_LOOP;
794 !receive_message_or_smb(InBuffer,BUFFER_SIZE,
795 SMBD_SELECT_LOOP*1000,&got_smb);
796 counter += SMBD_SELECT_LOOP)
800 extern int keepalive;
802 if (counter > 365 * 3600) /* big number of seconds. */
805 service_load_counter = 0;
808 if (smb_read_error == READ_EOF)
810 DEBUG(3,("end of file from client\n"));
814 if (smb_read_error == READ_ERROR)
816 DEBUG(3,("receive_smb error (%s) exiting\n",
823 /* become root again if waiting */
826 /* check for smb.conf reload */
827 if (counter >= service_load_counter + SMBD_RELOAD_CHECK)
829 service_load_counter = counter;
831 /* reload services, if files have changed. */
832 reload_services(True);
836 * If reload_after_sighup == True then we got a SIGHUP
837 * and are being asked to reload. Fix from <branko.cibej@hermes.si>
840 if (reload_after_sighup)
842 DEBUG(0,("Reloading services after SIGHUP\n"));
843 reload_services(False);
844 reload_after_sighup = False;
846 * Use this as an excuse to print some stats.
848 print_stat_cache_statistics();
851 /* automatic timeout if all connections are closed */
852 if (conn_num_open()==0 && counter >= IDLE_CLOSED_TIMEOUT)
854 DEBUG( 2, ( "Closing idle connection\n" ) );
858 if (keepalive && (counter-last_keepalive)>keepalive)
860 struct cli_state *cli = server_client();
861 if (!send_keepalive(Client)) {
862 DEBUG( 2, ( "Keepalive failed - exiting.\n" ) );
865 /* also send a keepalive to the password server if its still
867 if (cli && cli->initialised)
868 send_keepalive(cli->fd);
869 last_keepalive = counter;
872 /* check for connection timeouts */
873 allidle = conn_idle_all(t, deadtime);
875 if (allidle && conn_num_open()>0) {
876 DEBUG(2,("Closing idle connection 2.\n"));
880 if(global_machine_password_needs_changing)
882 unsigned char trust_passwd_hash[16];
884 pstring remote_machine_list;
885 int sec_chan = SEC_CHAN_WKSTA;
888 * We're in domain level security, and the code that
889 * read the machine password flagged that the machine
890 * password needs changing.
894 * First, open the machine password file with an exclusive lock.
897 if(!trust_password_lock( global_myworkgroup, global_myname, True)) {
898 DEBUG(0,("process: unable to open the machine account password file for \
899 machine %s in domain %s.\n", global_myname, global_myworkgroup ));
903 if(!get_trust_account_password( trust_passwd_hash, &lct)) {
904 DEBUG(0,("process: unable to read the machine account password for \
905 machine %s in domain %s.\n", global_myname, global_myworkgroup ));
906 trust_password_unlock();
911 * Make sure someone else hasn't already done this.
914 if(t < lct + lp_machine_password_timeout()) {
915 trust_password_unlock();
916 global_machine_password_needs_changing = False;
920 pstrcpy(remote_machine_list, lp_passwordserver());
921 if (lp_server_role() == ROLE_DOMAIN_BDC)
922 sec_chan = SEC_CHAN_BDC;
924 change_trust_account_password(global_myworkgroup, remote_machine_list,
926 trust_password_unlock();
927 global_machine_password_needs_changing = False;
931 * Check to see if we have any blocking locks
932 * outstanding on the queue.
934 process_blocking_lock_queue(t);
937 * Check to see if we have any change notifies
938 * outstanding on the queue.
940 process_pending_change_notify_queue(t);
944 process_smb(InBuffer, OutBuffer);
946 process_local_message(InBuffer, BUFFER_SIZE);