00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "includes.h"
00023
00024 uint16 global_smbpid;
00025 extern int keepalive;
00026 extern struct auth_context *negprot_global_auth_context;
00027 extern int smb_echo_count;
00028
00029 static char *InBuffer = NULL;
00030 static char *OutBuffer = NULL;
00031 static char *current_inbuf = NULL;
00032
00033
00034
00035
00036
00037
00038 int max_send = BUFFER_SIZE;
00039
00040
00041
00042
00043 int max_recv = BUFFER_SIZE;
00044
00045 extern int last_message;
00046 extern int smb_read_error;
00047 SIG_ATOMIC_T reload_after_sighup = 0;
00048 SIG_ATOMIC_T got_sig_term = 0;
00049 extern BOOL global_machine_password_needs_changing;
00050 extern int max_send;
00051
00052
00053
00054
00055
00056 uint16 get_current_mid(void)
00057 {
00058 return SVAL(InBuffer,smb_mid);
00059 }
00060
00061
00062
00063
00064
00065
00066 static struct pending_message_list *deferred_open_queue;
00067
00068
00069
00070
00071
00072
00073 static BOOL push_queued_message(char *buf, int msg_len,
00074 struct timeval request_time,
00075 struct timeval end_time,
00076 char *private_data, size_t private_len)
00077 {
00078 struct pending_message_list *msg;
00079
00080 msg = TALLOC_ZERO_P(NULL, struct pending_message_list);
00081
00082 if(msg == NULL) {
00083 DEBUG(0,("push_message: malloc fail (1)\n"));
00084 return False;
00085 }
00086
00087 msg->buf = data_blob_talloc(msg, buf, msg_len);
00088 if(msg->buf.data == NULL) {
00089 DEBUG(0,("push_message: malloc fail (2)\n"));
00090 TALLOC_FREE(msg);
00091 return False;
00092 }
00093
00094 msg->request_time = request_time;
00095 msg->end_time = end_time;
00096
00097 if (private_data) {
00098 msg->private_data = data_blob_talloc(msg, private_data,
00099 private_len);
00100 if (msg->private_data.data == NULL) {
00101 DEBUG(0,("push_message: malloc fail (3)\n"));
00102 TALLOC_FREE(msg);
00103 return False;
00104 }
00105 }
00106
00107 DLIST_ADD_END(deferred_open_queue, msg, struct pending_message_list *);
00108
00109 DEBUG(10,("push_message: pushed message length %u on "
00110 "deferred_open_queue\n", (unsigned int)msg_len));
00111
00112 return True;
00113 }
00114
00115
00116
00117
00118
00119 void remove_deferred_open_smb_message(uint16 mid)
00120 {
00121 struct pending_message_list *pml;
00122
00123 for (pml = deferred_open_queue; pml; pml = pml->next) {
00124 if (mid == SVAL(pml->buf.data,smb_mid)) {
00125 DEBUG(10,("remove_sharing_violation_open_smb_message: "
00126 "deleting mid %u len %u\n",
00127 (unsigned int)mid,
00128 (unsigned int)pml->buf.length ));
00129 DLIST_REMOVE(deferred_open_queue, pml);
00130 TALLOC_FREE(pml);
00131 return;
00132 }
00133 }
00134 }
00135
00136
00137
00138
00139
00140
00141 void schedule_deferred_open_smb_message(uint16 mid)
00142 {
00143 struct pending_message_list *pml;
00144 int i = 0;
00145
00146 for (pml = deferred_open_queue; pml; pml = pml->next) {
00147 uint16 msg_mid = SVAL(pml->buf.data,smb_mid);
00148 DEBUG(10,("schedule_deferred_open_smb_message: [%d] msg_mid = %u\n", i++,
00149 (unsigned int)msg_mid ));
00150 if (mid == msg_mid) {
00151 DEBUG(10,("schedule_deferred_open_smb_message: scheduling mid %u\n",
00152 mid ));
00153 pml->end_time.tv_sec = 0;
00154 pml->end_time.tv_usec = 0;
00155 DLIST_PROMOTE(deferred_open_queue, pml);
00156 return;
00157 }
00158 }
00159
00160 DEBUG(10,("schedule_deferred_open_smb_message: failed to find message mid %u\n",
00161 mid ));
00162 }
00163
00164
00165
00166
00167
00168 BOOL open_was_deferred(uint16 mid)
00169 {
00170 struct pending_message_list *pml;
00171
00172 for (pml = deferred_open_queue; pml; pml = pml->next) {
00173 if (SVAL(pml->buf.data,smb_mid) == mid) {
00174 return True;
00175 }
00176 }
00177 return False;
00178 }
00179
00180
00181
00182
00183
00184 struct pending_message_list *get_open_deferred_message(uint16 mid)
00185 {
00186 struct pending_message_list *pml;
00187
00188 for (pml = deferred_open_queue; pml; pml = pml->next) {
00189 if (SVAL(pml->buf.data,smb_mid) == mid) {
00190 return pml;
00191 }
00192 }
00193 return NULL;
00194 }
00195
00196
00197
00198
00199
00200
00201 BOOL push_deferred_smb_message(uint16 mid,
00202 struct timeval request_time,
00203 struct timeval timeout,
00204 char *private_data, size_t priv_len)
00205 {
00206 struct timeval end_time;
00207
00208 end_time = timeval_sum(&request_time, &timeout);
00209
00210 DEBUG(10,("push_deferred_open_smb_message: pushing message len %u mid %u "
00211 "timeout time [%u.%06u]\n",
00212 (unsigned int) smb_len(current_inbuf)+4, (unsigned int)mid,
00213 (unsigned int)end_time.tv_sec,
00214 (unsigned int)end_time.tv_usec));
00215
00216 return push_queued_message(current_inbuf, smb_len(current_inbuf)+4,
00217 request_time, end_time,
00218 private_data, priv_len);
00219 }
00220
00221 struct idle_event {
00222 struct timed_event *te;
00223 struct timeval interval;
00224 BOOL (*handler)(const struct timeval *now, void *private_data);
00225 void *private_data;
00226 };
00227
00228 static void idle_event_handler(struct event_context *ctx,
00229 struct timed_event *te,
00230 const struct timeval *now,
00231 void *private_data)
00232 {
00233 struct idle_event *event =
00234 talloc_get_type_abort(private_data, struct idle_event);
00235
00236 TALLOC_FREE(event->te);
00237
00238 if (!event->handler(now, event->private_data)) {
00239
00240 TALLOC_FREE(event);
00241 return;
00242 }
00243
00244 event->te = event_add_timed(smbd_event_context(), event,
00245 timeval_sum(now, &event->interval),
00246 "idle_event_handler",
00247 idle_event_handler, event);
00248
00249
00250 SMB_ASSERT(event->te != NULL);
00251 }
00252
00253 struct idle_event *add_idle_event(TALLOC_CTX *mem_ctx,
00254 struct timeval interval,
00255 BOOL (*handler)(const struct timeval *now,
00256 void *private_data),
00257 void *private_data)
00258 {
00259 struct idle_event *result;
00260 struct timeval now = timeval_current();
00261
00262 result = TALLOC_P(mem_ctx, struct idle_event);
00263 if (result == NULL) {
00264 DEBUG(0, ("talloc failed\n"));
00265 return NULL;
00266 }
00267
00268 result->interval = interval;
00269 result->handler = handler;
00270 result->private_data = private_data;
00271
00272 result->te = event_add_timed(smbd_event_context(), result,
00273 timeval_sum(&now, &interval),
00274 "idle_event_handler",
00275 idle_event_handler, result);
00276 if (result->te == NULL) {
00277 DEBUG(0, ("event_add_timed failed\n"));
00278 TALLOC_FREE(result);
00279 return NULL;
00280 }
00281
00282 return result;
00283 }
00284
00285
00286
00287
00288
00289
00290 static void async_processing(fd_set *pfds)
00291 {
00292 DEBUG(10,("async_processing: Doing async processing.\n"));
00293
00294 process_aio_queue();
00295
00296 process_kernel_oplocks(pfds);
00297
00298
00299
00300
00301 process_aio_queue();
00302
00303 if (got_sig_term) {
00304 exit_server_cleanly("termination signal");
00305 }
00306
00307
00308 if (reload_after_sighup) {
00309 change_to_root_user();
00310 DEBUG(1,("Reloading services after SIGHUP\n"));
00311 reload_services(False);
00312 reload_after_sighup = 0;
00313 }
00314 }
00315
00316
00317
00318
00319
00320 static int select_on_fd(int fd, int maxfd, fd_set *fds)
00321 {
00322 if (fd != -1) {
00323 FD_SET(fd, fds);
00324 maxfd = MAX(maxfd, fd);
00325 }
00326
00327 return maxfd;
00328 }
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351 static BOOL receive_message_or_smb(char *buffer, int buffer_len, int timeout)
00352 {
00353 fd_set r_fds, w_fds;
00354 int selrtn;
00355 struct timeval to;
00356 int maxfd = 0;
00357
00358 smb_read_error = 0;
00359
00360 again:
00361
00362 if (timeout >= 0) {
00363 to.tv_sec = timeout / 1000;
00364 to.tv_usec = (timeout % 1000) * 1000;
00365 } else {
00366 to.tv_sec = SMBD_SELECT_TIMEOUT;
00367 to.tv_usec = 0;
00368 }
00369
00370
00371
00372
00373
00374
00375 message_dispatch();
00376
00377
00378
00379
00380
00381 if(deferred_open_queue != NULL) {
00382 BOOL pop_message = False;
00383 struct pending_message_list *msg = deferred_open_queue;
00384
00385 if (timeval_is_zero(&msg->end_time)) {
00386 pop_message = True;
00387 } else {
00388 struct timeval tv;
00389 SMB_BIG_INT tdif;
00390
00391 GetTimeOfDay(&tv);
00392 tdif = usec_time_diff(&msg->end_time, &tv);
00393 if (tdif <= 0) {
00394
00395 pop_message = True;
00396 DEBUG(10,("receive_message_or_smb: queued message timed out.\n"));
00397 } else {
00398
00399 to.tv_sec = tdif / 1000000;
00400 to.tv_usec = tdif % 1000000;
00401 DEBUG(10,("receive_message_or_smb: select with timeout of [%u.%06u]\n",
00402 (unsigned int)to.tv_sec, (unsigned int)to.tv_usec ));
00403 }
00404 }
00405
00406 if (pop_message) {
00407 memcpy(buffer, msg->buf.data, MIN(buffer_len, msg->buf.length));
00408
00409
00410
00411 DEBUG(5,("receive_message_or_smb: returning deferred open smb message.\n"));
00412 return True;
00413 }
00414 }
00415
00416
00417
00418
00419
00420 FD_ZERO(&r_fds);
00421 FD_ZERO(&w_fds);
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432 if (oplock_message_waiting(&r_fds)) {
00433 DEBUG(10,("receive_message_or_smb: oplock_message is waiting.\n"));
00434 async_processing(&r_fds);
00435
00436
00437
00438
00439
00440 goto again;
00441 }
00442
00443
00444
00445
00446
00447
00448 {
00449 struct timeval now;
00450 GetTimeOfDay(&now);
00451
00452 event_add_to_select_args(smbd_event_context(), &now,
00453 &r_fds, &w_fds, &to, &maxfd);
00454 }
00455
00456 if (timeval_is_zero(&to)) {
00457
00458 if (run_events(smbd_event_context(), 0, NULL, NULL)) {
00459 goto again;
00460 }
00461 }
00462
00463 {
00464 int sav;
00465 START_PROFILE(smbd_idle);
00466
00467 maxfd = select_on_fd(smbd_server_fd(), maxfd, &r_fds);
00468 maxfd = select_on_fd(oplock_notify_fd(), maxfd, &r_fds);
00469
00470 selrtn = sys_select(maxfd+1,&r_fds,&w_fds,NULL,&to);
00471 sav = errno;
00472
00473 END_PROFILE(smbd_idle);
00474 errno = sav;
00475 }
00476
00477 if (run_events(smbd_event_context(), selrtn, &r_fds, &w_fds)) {
00478 goto again;
00479 }
00480
00481
00482
00483
00484
00485 if (selrtn == -1 && errno == EINTR) {
00486 async_processing(&r_fds);
00487
00488
00489
00490
00491
00492 goto again;
00493 }
00494
00495
00496 if (selrtn == -1) {
00497
00498 smb_read_error = READ_ERROR;
00499 return False;
00500 }
00501
00502
00503 if (selrtn == 0) {
00504 smb_read_error = READ_TIMEOUT;
00505 return False;
00506 }
00507
00508
00509
00510
00511
00512
00513
00514 if (oplock_message_waiting(&r_fds)) {
00515 async_processing(&r_fds);
00516
00517
00518
00519
00520
00521 goto again;
00522 }
00523
00524 return receive_smb(smbd_server_fd(), buffer,
00525 BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE, 0);
00526 }
00527
00528
00529
00530
00531
00532
00533 NTSTATUS allow_new_trans(struct trans_state *list, int mid)
00534 {
00535 int count = 0;
00536 for (; list != NULL; list = list->next) {
00537
00538 if (list->mid == mid) {
00539 return NT_STATUS_INVALID_PARAMETER;
00540 }
00541
00542 count += 1;
00543 }
00544 if (count > 5) {
00545 return NT_STATUS_INSUFFICIENT_RESOURCES;
00546 }
00547
00548 return NT_STATUS_OK;
00549 }
00550
00551
00552
00553
00554
00555
00556
00557
00558 void respond_to_all_remaining_local_messages(void)
00559 {
00560
00561
00562
00563
00564 if(get_number_of_exclusive_open_oplocks()) {
00565 DEBUG(0,("respond_to_all_remaining_local_messages: PANIC : we have %d exclusive oplocks.\n",
00566 get_number_of_exclusive_open_oplocks() ));
00567 return;
00568 }
00569
00570 process_kernel_oplocks(NULL);
00571
00572 return;
00573 }
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583 #define AS_USER (1<<0)
00584 #define NEED_WRITE (1<<1)
00585 #define TIME_INIT (1<<2)
00586 #define CAN_IPC (1<<3)
00587 #define AS_GUEST (1<<5)
00588 #define DO_CHDIR (1<<6)
00589
00590
00591
00592
00593
00594
00595 static const struct smb_message_struct {
00596 const char *name;
00597 int (*fn)(connection_struct *conn, char *, char *, int, int);
00598 int flags;
00599 } smb_messages[256] = {
00600
00601 { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
00602 { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
00603 { "SMBopen",reply_open,AS_USER },
00604 { "SMBcreate",reply_mknew,AS_USER},
00605 { "SMBclose",reply_close,AS_USER | CAN_IPC },
00606 { "SMBflush",reply_flush,AS_USER},
00607 { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
00608 { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
00609 { "SMBgetatr",reply_getatr,AS_USER},
00610 { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
00611 { "SMBread",reply_read,AS_USER},
00612 { "SMBwrite",reply_write,AS_USER | CAN_IPC },
00613 { "SMBlock",reply_lock,AS_USER},
00614 { "SMBunlock",reply_unlock,AS_USER},
00615 { "SMBctemp",reply_ctemp,AS_USER },
00616 { "SMBmknew",reply_mknew,AS_USER},
00617 { "SMBcheckpath",reply_checkpath,AS_USER},
00618 { "SMBexit",reply_exit,DO_CHDIR},
00619 { "SMBlseek",reply_lseek,AS_USER},
00620 { "SMBlockread",reply_lockread,AS_USER},
00621 { "SMBwriteunlock",reply_writeunlock,AS_USER},
00622 { NULL, NULL, 0 },
00623 { NULL, NULL, 0 },
00624 { NULL, NULL, 0 },
00625 { NULL, NULL, 0 },
00626 { NULL, NULL, 0 },
00627 { "SMBreadbraw",reply_readbraw,AS_USER},
00628 { "SMBreadBmpx",reply_readbmpx,AS_USER},
00629 { "SMBreadBs",NULL,0 },
00630 { "SMBwritebraw",reply_writebraw,AS_USER},
00631 { "SMBwriteBmpx",reply_writebmpx,AS_USER},
00632 { "SMBwriteBs",reply_writebs,AS_USER},
00633 { "SMBwritec",NULL,0},
00634 { NULL, NULL, 0 },
00635 { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
00636 { "SMBgetattrE",reply_getattrE,AS_USER },
00637 { "SMBlockingX",reply_lockingX,AS_USER },
00638 { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
00639 { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
00640 { "SMBioctl",reply_ioctl,0},
00641 { "SMBioctls",NULL,AS_USER},
00642 { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
00643 { "SMBmove",NULL,AS_USER | NEED_WRITE },
00644 { "SMBecho",reply_echo,0},
00645 { "SMBwriteclose",reply_writeclose,AS_USER},
00646 { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
00647 { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
00648 { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
00649 { NULL, NULL, 0 },
00650 { NULL, NULL, 0 },
00651 { "SMBtrans2", reply_trans2, AS_USER | CAN_IPC },
00652 { "SMBtranss2", reply_transs2, AS_USER},
00653 { "SMBfindclose", reply_findclose,AS_USER},
00654 { "SMBfindnclose", reply_findnclose, AS_USER},
00655 { NULL, NULL, 0 },
00656 { NULL, NULL, 0 },
00657 { NULL, NULL, 0 },
00658 { NULL, NULL, 0 },
00659 { NULL, NULL, 0 },
00660 { NULL, NULL, 0 },
00661 { NULL, NULL, 0 },
00662 { NULL, NULL, 0 },
00663 { NULL, NULL, 0 },
00664 { NULL, NULL, 0 },
00665 { NULL, NULL, 0 },
00666 { NULL, NULL, 0 },
00667 { NULL, NULL, 0 },
00668 { NULL, NULL, 0 },
00669 { NULL, NULL, 0 },
00670 { NULL, NULL, 0 },
00671 { NULL, NULL, 0 },
00672 { NULL, NULL, 0 },
00673 { NULL, NULL, 0 },
00674 { NULL, NULL, 0 },
00675 { NULL, NULL, 0 },
00676 { NULL, NULL, 0 },
00677 { NULL, NULL, 0 },
00678 { NULL, NULL, 0 },
00679 { NULL, NULL, 0 },
00680 { NULL, NULL, 0 },
00681 { NULL, NULL, 0 },
00682 { NULL, NULL, 0 },
00683 { NULL, NULL, 0 },
00684 { NULL, NULL, 0 },
00685 { NULL, NULL, 0 },
00686 { NULL, NULL, 0 },
00687 { NULL, NULL, 0 },
00688 { NULL, NULL, 0 },
00689 { NULL, NULL, 0 },
00690 { NULL, NULL, 0 },
00691 { NULL, NULL, 0 },
00692 { NULL, NULL, 0 },
00693 { NULL, NULL, 0 },
00694 { NULL, NULL, 0 },
00695 { NULL, NULL, 0 },
00696 { NULL, NULL, 0 },
00697 { NULL, NULL, 0 },
00698 { NULL, NULL, 0 },
00699 { NULL, NULL, 0 },
00700 { NULL, NULL, 0 },
00701 { NULL, NULL, 0 },
00702 { NULL, NULL, 0 },
00703 { NULL, NULL, 0 },
00704 { NULL, NULL, 0 },
00705 { NULL, NULL, 0 },
00706 { NULL, NULL, 0 },
00707 { NULL, NULL, 0 },
00708 { NULL, NULL, 0 },
00709 { NULL, NULL, 0 },
00710 { NULL, NULL, 0 },
00711 { NULL, NULL, 0 },
00712 { NULL, NULL, 0 },
00713 { "SMBtcon",reply_tcon,0},
00714 { "SMBtdis",reply_tdis,DO_CHDIR},
00715 { "SMBnegprot",reply_negprot,0},
00716 { "SMBsesssetupX",reply_sesssetup_and_X,0},
00717 { "SMBulogoffX", reply_ulogoffX, 0},
00718 { "SMBtconX",reply_tcon_and_X,0},
00719 { NULL, NULL, 0 },
00720 { NULL, NULL, 0 },
00721 { NULL, NULL, 0 },
00722 { NULL, NULL, 0 },
00723 { NULL, NULL, 0 },
00724 { NULL, NULL, 0 },
00725 { NULL, NULL, 0 },
00726 { NULL, NULL, 0 },
00727 { NULL, NULL, 0 },
00728 { NULL, NULL, 0 },
00729 { "SMBdskattr",reply_dskattr,AS_USER},
00730 { "SMBsearch",reply_search,AS_USER},
00731 { "SMBffirst",reply_search,AS_USER},
00732 { "SMBfunique",reply_search,AS_USER},
00733 { "SMBfclose",reply_fclose,AS_USER},
00734 { NULL, NULL, 0 },
00735 { NULL, NULL, 0 },
00736 { NULL, NULL, 0 },
00737 { NULL, NULL, 0 },
00738 { NULL, NULL, 0 },
00739 { NULL, NULL, 0 },
00740 { NULL, NULL, 0 },
00741 { NULL, NULL, 0 },
00742 { NULL, NULL, 0 },
00743 { NULL, NULL, 0 },
00744 { NULL, NULL, 0 },
00745 { NULL, NULL, 0 },
00746 { NULL, NULL, 0 },
00747 { NULL, NULL, 0 },
00748 { NULL, NULL, 0 },
00749 { NULL, NULL, 0 },
00750 { NULL, NULL, 0 },
00751 { NULL, NULL, 0 },
00752 { NULL, NULL, 0 },
00753 { NULL, NULL, 0 },
00754 { NULL, NULL, 0 },
00755 { NULL, NULL, 0 },
00756 { NULL, NULL, 0 },
00757 { NULL, NULL, 0 },
00758 { NULL, NULL, 0 },
00759 { NULL, NULL, 0 },
00760 { NULL, NULL, 0 },
00761 { "SMBnttrans", reply_nttrans, AS_USER | CAN_IPC },
00762 { "SMBnttranss", reply_nttranss, AS_USER | CAN_IPC },
00763 { "SMBntcreateX", reply_ntcreate_and_X, AS_USER | CAN_IPC },
00764 { NULL, NULL, 0 },
00765 { "SMBntcancel", reply_ntcancel, 0 },
00766 { "SMBntrename", reply_ntrename, AS_USER | NEED_WRITE },
00767 { NULL, NULL, 0 },
00768 { NULL, NULL, 0 },
00769 { NULL, NULL, 0 },
00770 { NULL, NULL, 0 },
00771 { NULL, NULL, 0 },
00772 { NULL, NULL, 0 },
00773 { NULL, NULL, 0 },
00774 { NULL, NULL, 0 },
00775 { NULL, NULL, 0 },
00776 { NULL, NULL, 0 },
00777 { NULL, NULL, 0 },
00778 { NULL, NULL, 0 },
00779 { NULL, NULL, 0 },
00780 { NULL, NULL, 0 },
00781 { NULL, NULL, 0 },
00782 { NULL, NULL, 0 },
00783 { NULL, NULL, 0 },
00784 { NULL, NULL, 0 },
00785 { NULL, NULL, 0 },
00786 { NULL, NULL, 0 },
00787 { NULL, NULL, 0 },
00788 { NULL, NULL, 0 },
00789 { NULL, NULL, 0 },
00790 { NULL, NULL, 0 },
00791 { NULL, NULL, 0 },
00792 { NULL, NULL, 0 },
00793 { "SMBsplopen",reply_printopen,AS_USER},
00794 { "SMBsplwr",reply_printwrite,AS_USER},
00795 { "SMBsplclose",reply_printclose,AS_USER},
00796 { "SMBsplretq",reply_printqueue,AS_USER},
00797 { NULL, NULL, 0 },
00798 { NULL, NULL, 0 },
00799 { NULL, NULL, 0 },
00800 { NULL, NULL, 0 },
00801 { NULL, NULL, 0 },
00802 { NULL, NULL, 0 },
00803 { NULL, NULL, 0 },
00804 { NULL, NULL, 0 },
00805 { NULL, NULL, 0 },
00806 { NULL, NULL, 0 },
00807 { NULL, NULL, 0 },
00808 { NULL, NULL, 0 },
00809 { "SMBsends",reply_sends,AS_GUEST},
00810 { "SMBsendb",NULL,AS_GUEST},
00811 { "SMBfwdname",NULL,AS_GUEST},
00812 { "SMBcancelf",NULL,AS_GUEST},
00813 { "SMBgetmac",NULL,AS_GUEST},
00814 { "SMBsendstrt",reply_sendstrt,AS_GUEST},
00815 { "SMBsendend",reply_sendend,AS_GUEST},
00816 { "SMBsendtxt",reply_sendtxt,AS_GUEST},
00817 { NULL, NULL, 0 },
00818 { NULL, NULL, 0 },
00819 { NULL, NULL, 0 },
00820 { NULL, NULL, 0 },
00821 { NULL, NULL, 0 },
00822 { NULL, NULL, 0 },
00823 { NULL, NULL, 0 },
00824 { NULL, NULL, 0 },
00825 { NULL, NULL, 0 },
00826 { NULL, NULL, 0 },
00827 { NULL, NULL, 0 },
00828 { NULL, NULL, 0 },
00829 { NULL, NULL, 0 },
00830 { NULL, NULL, 0 },
00831 { NULL, NULL, 0 },
00832 { NULL, NULL, 0 },
00833 { NULL, NULL, 0 },
00834 { NULL, NULL, 0 },
00835 { NULL, NULL, 0 },
00836 { NULL, NULL, 0 },
00837 { NULL, NULL, 0 },
00838 { NULL, NULL, 0 },
00839 { NULL, NULL, 0 },
00840 { NULL, NULL, 0 },
00841 { NULL, NULL, 0 },
00842 { NULL, NULL, 0 },
00843 { NULL, NULL, 0 },
00844 { NULL, NULL, 0 },
00845 { NULL, NULL, 0 },
00846 { NULL, NULL, 0 },
00847 { NULL, NULL, 0 },
00848 { NULL, NULL, 0 },
00849 { NULL, NULL, 0 },
00850 { NULL, NULL, 0 },
00851 { NULL, NULL, 0 },
00852 { NULL, NULL, 0 },
00853 { NULL, NULL, 0 },
00854 { NULL, NULL, 0 },
00855 { NULL, NULL, 0 },
00856 { NULL, NULL, 0 }
00857
00858 };
00859
00860
00861
00862
00863
00864 static void smb_dump(const char *name, int type, char *data, ssize_t len)
00865 {
00866 int fd, i;
00867 pstring fname;
00868 if (DEBUGLEVEL < 50) return;
00869
00870 if (len < 4) len = smb_len(data)+4;
00871 for (i=1;i<100;i++) {
00872 slprintf(fname,sizeof(fname)-1, "/tmp/%s.%d.%s", name, i,
00873 type ? "req" : "resp");
00874 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
00875 if (fd != -1 || errno != EEXIST) break;
00876 }
00877 if (fd != -1) {
00878 ssize_t ret = write(fd, data, len);
00879 if (ret != len)
00880 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
00881 close(fd);
00882 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
00883 }
00884 }
00885
00886
00887
00888
00889
00890
00891 static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize)
00892 {
00893 static pid_t pid= (pid_t)-1;
00894 int outsize = 0;
00895
00896 type &= 0xff;
00897
00898 if (pid == (pid_t)-1)
00899 pid = sys_getpid();
00900
00901 errno = 0;
00902
00903 last_message = type;
00904
00905
00906 if ((strncmp(smb_base(inbuf),"\377SMB",4) != 0) || (size < (smb_size - 4))) {
00907 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",smb_len(inbuf)));
00908 exit_server_cleanly("Non-SMB packet");
00909 return(-1);
00910 }
00911
00912
00913
00914 global_smbpid = SVAL(inbuf,smb_pid);
00915
00916 if (smb_messages[type].fn == NULL) {
00917 DEBUG(0,("Unknown message type %d!\n",type));
00918 smb_dump("Unknown", 1, inbuf, size);
00919 outsize = reply_unknown(inbuf,outbuf);
00920 } else {
00921 int flags = smb_messages[type].flags;
00922 static uint16 last_session_tag = UID_FIELD_INVALID;
00923
00924 uint16 session_tag = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID : SVAL(inbuf,smb_uid);
00925 connection_struct *conn = conn_find(SVAL(inbuf,smb_tid));
00926
00927 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n",smb_fn_name(type),(int)pid,(unsigned long)conn));
00928
00929 smb_dump(smb_fn_name(type), 1, inbuf, size);
00930
00931
00932 SSVAL(inbuf,smb_uid,session_tag);
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944 if (session_tag != last_session_tag) {
00945 user_struct *vuser = NULL;
00946
00947 last_session_tag = session_tag;
00948 if(session_tag != UID_FIELD_INVALID) {
00949 vuser = get_valid_user_struct(session_tag);
00950 if (vuser) {
00951 set_current_user_info(&vuser->user);
00952 }
00953 }
00954 }
00955
00956
00957 if (flags & AS_USER) {
00958
00959
00960 if (!conn) {
00961
00962 if (type == SMBntcreateX) {
00963 return ERROR_NT(NT_STATUS_INVALID_HANDLE);
00964 } else {
00965 return ERROR_DOS(ERRSRV, ERRinvnid);
00966 }
00967 }
00968
00969 if (!change_to_user(conn,session_tag)) {
00970 return(ERROR_NT(NT_STATUS_DOS(ERRSRV,ERRbaduid)));
00971 }
00972
00973
00974
00975
00976 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
00977 return ERROR_NT(NT_STATUS_MEDIA_WRITE_PROTECTED);
00978 }
00979
00980
00981 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
00982 return(ERROR_DOS(ERRSRV,ERRaccess));
00983 }
00984 } else {
00985
00986 change_to_root_user();
00987 }
00988
00989
00990 if (conn) {
00991 if (!set_current_service(conn,SVAL(inbuf,smb_flg),(flags & (AS_USER|DO_CHDIR)?True:False))) {
00992 return(ERROR_DOS(ERRSRV,ERRaccess));
00993 }
00994 conn->num_smb_operations++;
00995 }
00996
00997
00998 if ((flags & AS_GUEST) && (!change_to_guest() ||
00999 !check_access(smbd_server_fd(), lp_hostsallow(-1), lp_hostsdeny(-1)))) {
01000 return(ERROR_DOS(ERRSRV,ERRaccess));
01001 }
01002
01003 current_inbuf = inbuf;
01004 outsize = smb_messages[type].fn(conn, inbuf,outbuf,size,bufsize);
01005 }
01006
01007 smb_dump(smb_fn_name(type), 0, outbuf, outsize);
01008
01009 return(outsize);
01010 }
01011
01012
01013
01014
01015
01016 static int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
01017 {
01018 int type = CVAL(inbuf,smb_com);
01019 int outsize = 0;
01020 int msg_type = CVAL(inbuf,0);
01021
01022 chain_size = 0;
01023 file_chain_reset();
01024 reset_chain_p();
01025
01026 if (msg_type != 0)
01027 return(reply_special(inbuf,outbuf));
01028
01029 construct_reply_common(inbuf, outbuf);
01030
01031 outsize = switch_message(type,inbuf,outbuf,size,bufsize);
01032
01033 outsize += chain_size;
01034
01035 if(outsize > 4)
01036 smb_setlen(outbuf,outsize - 4);
01037 return(outsize);
01038 }
01039
01040
01041
01042
01043
01044 static void process_smb(char *inbuf, char *outbuf)
01045 {
01046 static int trans_num;
01047 int msg_type = CVAL(inbuf,0);
01048 int32 len = smb_len(inbuf);
01049 int nread = len + 4;
01050
01051 DO_PROFILE_INC(smb_count);
01052
01053 if (trans_num == 0) {
01054
01055
01056
01057
01058 if (!check_access(smbd_server_fd(), lp_hostsallow(-1),
01059 lp_hostsdeny(-1))) {
01060
01061 static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
01062 DEBUG( 1, ( "Connection denied from %s\n", client_addr() ) );
01063 (void)send_smb(smbd_server_fd(),(char *)buf);
01064 exit_server_cleanly("connection denied");
01065 }
01066 }
01067
01068 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type, len ) );
01069 DEBUG( 3, ( "Transaction %d of length %d\n", trans_num, nread ) );
01070
01071 if (msg_type == 0)
01072 show_msg(inbuf);
01073 else if(msg_type == SMBkeepalive)
01074 return;
01075
01076 nread = construct_reply(inbuf,outbuf,nread,max_send);
01077
01078 if(nread > 0) {
01079 if (CVAL(outbuf,0) == 0)
01080 show_msg(outbuf);
01081
01082 if (nread != smb_len(outbuf) + 4) {
01083 DEBUG(0,("ERROR: Invalid message response size! %d %d\n",
01084 nread, smb_len(outbuf)));
01085 } else if (!send_smb(smbd_server_fd(),outbuf)) {
01086 exit_server_cleanly("process_smb: send_smb failed.");
01087 }
01088 }
01089 trans_num++;
01090 }
01091
01092
01093
01094
01095
01096 const char *smb_fn_name(int type)
01097 {
01098 const char *unknown_name = "SMBunknown";
01099
01100 if (smb_messages[type].name == NULL)
01101 return(unknown_name);
01102
01103 return(smb_messages[type].name);
01104 }
01105
01106
01107
01108
01109
01110 static uint32 common_flags2 = FLAGS2_LONG_PATH_COMPONENTS|FLAGS2_32_BIT_ERROR_CODES;
01111
01112 void add_to_common_flags2(uint32 v)
01113 {
01114 common_flags2 |= v;
01115 }
01116
01117 void remove_from_common_flags2(uint32 v)
01118 {
01119 common_flags2 &= ~v;
01120 }
01121
01122 void construct_reply_common(const char *inbuf, char *outbuf)
01123 {
01124 set_message(outbuf,0,0,False);
01125
01126 SCVAL(outbuf,smb_com,CVAL(inbuf,smb_com));
01127 SIVAL(outbuf,smb_rcls,0);
01128 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
01129 SSVAL(outbuf,smb_flg2,
01130 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
01131 common_flags2);
01132 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
01133
01134 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
01135 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
01136 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
01137 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
01138 }
01139
01140
01141
01142
01143
01144 int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
01145 {
01146 static char *orig_inbuf;
01147 static char *orig_outbuf;
01148 int smb_com1, smb_com2 = CVAL(inbuf,smb_vwv0);
01149 unsigned smb_off2 = SVAL(inbuf,smb_vwv1);
01150 char *inbuf2, *outbuf2;
01151 int outsize2;
01152 int new_size;
01153 char inbuf_saved[smb_wct];
01154 char outbuf_saved[smb_wct];
01155 int outsize = smb_len(outbuf) + 4;
01156
01157
01158 if (smb_com2 == 0xFF || SVAL(outbuf,smb_rcls) != 0) {
01159 SCVAL(outbuf,smb_vwv0,0xFF);
01160 return outsize;
01161 }
01162
01163 if (chain_size == 0) {
01164
01165 orig_inbuf = inbuf;
01166 orig_outbuf = outbuf;
01167 }
01168
01169
01170
01171
01172
01173
01174
01175 outsize = (outsize + 3) & ~3;
01176
01177
01178 SSVAL(outbuf,smb_vwv1,smb_offset(outbuf+outsize,outbuf));
01179 SCVAL(outbuf,smb_vwv0,smb_com2);
01180
01181
01182
01183 chain_size += outsize - smb_wct;
01184
01185
01186
01187 inbuf2 = orig_inbuf + smb_off2 + 4 - smb_wct;
01188 outbuf2 = orig_outbuf + SVAL(outbuf,smb_vwv1) + 4 - smb_wct;
01189
01190
01191 smb_com1 = CVAL(orig_inbuf,smb_com);
01192
01193
01194 memcpy(inbuf_saved,inbuf2,smb_wct);
01195 memcpy(outbuf_saved,outbuf2,smb_wct);
01196
01197
01198 memmove(inbuf2,inbuf,smb_wct);
01199
01200
01201 SCVAL(inbuf2,smb_com,smb_com2);
01202
01203
01204 new_size = size - (inbuf2 - inbuf);
01205 if (new_size < 0) {
01206 DEBUG(0,("chain_reply: chain packet size incorrect (orig size = %d, "
01207 "offset = %d)\n",
01208 size,
01209 (inbuf2 - inbuf) ));
01210 exit_server_cleanly("Bad chained packet");
01211 return(-1);
01212 }
01213
01214
01215 smb_setlen(inbuf2, new_size);
01216
01217
01218 construct_reply_common(inbuf2, outbuf2);
01219
01220 DEBUG(3,("Chained message\n"));
01221 show_msg(inbuf2);
01222
01223
01224 outsize2 = switch_message(smb_com2,inbuf2,outbuf2,new_size,
01225 bufsize-chain_size);
01226
01227
01228
01229 memmove(orig_outbuf,outbuf2,smb_wct);
01230 SCVAL(orig_outbuf,smb_com,smb_com1);
01231
01232
01233
01234 memcpy(inbuf2,inbuf_saved,smb_wct);
01235
01236 {
01237 int ofs = smb_wct - PTR_DIFF(outbuf2,orig_outbuf);
01238 if (ofs < 0) {
01239 ofs = 0;
01240 }
01241 memmove(outbuf2+ofs,outbuf_saved+ofs,smb_wct-ofs);
01242 }
01243
01244 return outsize2;
01245 }
01246
01247
01248
01249
01250
01251 static int setup_select_timeout(void)
01252 {
01253 int select_timeout;
01254
01255 select_timeout = blocking_locks_timeout_ms(SMBD_SELECT_TIMEOUT*1000);
01256
01257 if (print_notify_messages_pending()) {
01258 select_timeout = MIN(select_timeout, 1000);
01259 }
01260
01261 return select_timeout;
01262 }
01263
01264
01265
01266
01267
01268 void check_reload(time_t t)
01269 {
01270 static pid_t mypid = 0;
01271 static time_t last_smb_conf_reload_time = 0;
01272 static time_t last_printer_reload_time = 0;
01273 time_t printcap_cache_time = (time_t)lp_printcap_cache_time();
01274
01275 if(last_smb_conf_reload_time == 0) {
01276 last_smb_conf_reload_time = t;
01277
01278
01279
01280 if ( printcap_cache_time > 60 )
01281 last_printer_reload_time = t - printcap_cache_time + 60;
01282 else
01283 last_printer_reload_time = t;
01284 }
01285
01286 if (mypid != getpid()) {
01287
01288
01289 int time_range = 60;
01290
01291 last_printer_reload_time += random() % time_range;
01292 mypid = getpid();
01293 }
01294
01295 if (reload_after_sighup || (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK)) {
01296 reload_services(True);
01297 reload_after_sighup = False;
01298 last_smb_conf_reload_time = t;
01299 }
01300
01301
01302
01303 if ( printcap_cache_time != 0 )
01304 {
01305
01306
01307 if ( (t >= last_printer_reload_time+printcap_cache_time)
01308 || (t-last_printer_reload_time < 0) )
01309 {
01310 DEBUG( 3,( "Printcap cache time expired.\n"));
01311 reload_printers();
01312 last_printer_reload_time = t;
01313 }
01314 }
01315 }
01316
01317
01318
01319
01320
01321 static BOOL timeout_processing(int deadtime, int *select_timeout, time_t *last_timeout_processing_time)
01322 {
01323 static time_t last_keepalive_sent_time = 0;
01324 static time_t last_idle_closed_check = 0;
01325 time_t t;
01326 BOOL allidle = True;
01327
01328 if (smb_read_error == READ_EOF) {
01329 DEBUG(3,("timeout_processing: End of file from client (client has disconnected).\n"));
01330 return False;
01331 }
01332
01333 if (smb_read_error == READ_ERROR) {
01334 DEBUG(3,("timeout_processing: receive_smb error (%s) Exiting\n",
01335 strerror(errno)));
01336 return False;
01337 }
01338
01339 if (smb_read_error == READ_BAD_SIG) {
01340 DEBUG(3,("timeout_processing: receive_smb error bad smb signature. Exiting\n"));
01341 return False;
01342 }
01343
01344 *last_timeout_processing_time = t = time(NULL);
01345
01346 if(last_keepalive_sent_time == 0)
01347 last_keepalive_sent_time = t;
01348
01349 if(last_idle_closed_check == 0)
01350 last_idle_closed_check = t;
01351
01352
01353 change_to_root_user();
01354
01355
01356 smb_run_idle_events(t);
01357
01358
01359 check_reload(t);
01360
01361
01362 if (conn_num_open()==0 && (t - last_idle_closed_check) >= IDLE_CLOSED_TIMEOUT) {
01363 DEBUG( 2, ( "Closing idle connection\n" ) );
01364 return False;
01365 } else {
01366 last_idle_closed_check = t;
01367 }
01368
01369 if (keepalive && (t - last_keepalive_sent_time)>keepalive) {
01370 if (!send_keepalive(smbd_server_fd())) {
01371 DEBUG( 2, ( "Keepalive failed - exiting.\n" ) );
01372 return False;
01373 }
01374
01375
01376
01377
01378 if (negprot_global_auth_context && negprot_global_auth_context->challenge_set_method
01379 && negprot_global_auth_context->challenge_set_method->send_keepalive) {
01380
01381 negprot_global_auth_context->challenge_set_method->send_keepalive
01382 (&negprot_global_auth_context->challenge_set_method->private_data);
01383 }
01384
01385 last_keepalive_sent_time = t;
01386 }
01387
01388
01389 allidle = conn_idle_all(t, deadtime);
01390
01391 if (allidle && conn_num_open()>0) {
01392 DEBUG(2,("Closing idle connection 2.\n"));
01393 return False;
01394 }
01395
01396 if(global_machine_password_needs_changing &&
01397
01398
01399 lp_security() == SEC_DOMAIN) {
01400
01401 unsigned char trust_passwd_hash[16];
01402 time_t lct;
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414 if (secrets_lock_trust_account_password(lp_workgroup(), True) == False) {
01415 DEBUG(0,("process: unable to lock the machine account password for \
01416 machine %s in domain %s.\n", global_myname(), lp_workgroup() ));
01417 return True;
01418 }
01419
01420 if(!secrets_fetch_trust_account_password(lp_workgroup(), trust_passwd_hash, &lct, NULL)) {
01421 DEBUG(0,("process: unable to read the machine account password for \
01422 machine %s in domain %s.\n", global_myname(), lp_workgroup()));
01423 secrets_lock_trust_account_password(lp_workgroup(), False);
01424 return True;
01425 }
01426
01427
01428
01429
01430
01431 if(t < lct + lp_machine_password_timeout()) {
01432 global_machine_password_needs_changing = False;
01433 secrets_lock_trust_account_password(lp_workgroup(), False);
01434 return True;
01435 }
01436
01437
01438
01439 change_trust_account_password( lp_workgroup(), NULL);
01440 global_machine_password_needs_changing = False;
01441 secrets_lock_trust_account_password(lp_workgroup(), False);
01442 }
01443
01444
01445
01446
01447
01448 process_blocking_lock_queue();
01449
01450
01451
01452 update_monitored_printq_cache();
01453
01454
01455
01456
01457
01458 force_check_log_size();
01459 check_log_size();
01460
01461
01462
01463 print_notify_send_messages(0);
01464
01465
01466
01467
01468
01469
01470 *select_timeout = setup_select_timeout();
01471
01472 return True;
01473 }
01474
01475
01476
01477
01478
01479 char *get_InBuffer(void)
01480 {
01481 return InBuffer;
01482 }
01483
01484 char *get_OutBuffer(void)
01485 {
01486 return OutBuffer;
01487 }
01488
01489 const int total_buffer_size = (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE + SAFETY_MARGIN);
01490
01491
01492
01493
01494
01495 static char *NewInBuffer(char **old_inbuf)
01496 {
01497 char *new_inbuf = (char *)SMB_MALLOC(total_buffer_size);
01498 if (!new_inbuf) {
01499 return NULL;
01500 }
01501 if (old_inbuf) {
01502 *old_inbuf = InBuffer;
01503 }
01504 InBuffer = new_inbuf;
01505 #if defined(DEVELOPER)
01506 clobber_region(SAFE_STRING_FUNCTION_NAME, SAFE_STRING_LINE, InBuffer, total_buffer_size);
01507 #endif
01508 return InBuffer;
01509 }
01510
01511
01512
01513
01514
01515 static char *NewOutBuffer(char **old_outbuf)
01516 {
01517 char *new_outbuf = (char *)SMB_MALLOC(total_buffer_size);
01518 if (!new_outbuf) {
01519 return NULL;
01520 }
01521 if (old_outbuf) {
01522 *old_outbuf = OutBuffer;
01523 }
01524 OutBuffer = new_outbuf;
01525 #if defined(DEVELOPER)
01526 clobber_region(SAFE_STRING_FUNCTION_NAME, SAFE_STRING_LINE, OutBuffer, total_buffer_size);
01527 #endif
01528 return OutBuffer;
01529 }
01530
01531
01532
01533
01534
01535 void smbd_process(void)
01536 {
01537 time_t last_timeout_processing_time = time(NULL);
01538 unsigned int num_smbs = 0;
01539
01540
01541
01542 if ((NewInBuffer(NULL) == NULL) || (NewOutBuffer(NULL) == NULL))
01543 return;
01544
01545 max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
01546
01547 while (True) {
01548 int deadtime = lp_deadtime()*60;
01549 int select_timeout = setup_select_timeout();
01550 int num_echos;
01551
01552 if (deadtime <= 0)
01553 deadtime = DEFAULT_SMBD_TIMEOUT;
01554
01555 errno = 0;
01556
01557
01558 lp_TALLOC_FREE();
01559 main_loop_TALLOC_FREE();
01560
01561
01562 if (select_timeout == 0) {
01563 if(!timeout_processing( deadtime, &select_timeout, &last_timeout_processing_time))
01564 return;
01565 num_smbs = 0;
01566 }
01567
01568 run_events(smbd_event_context(), 0, NULL, NULL);
01569
01570 #if defined(DEVELOPER)
01571 clobber_region(SAFE_STRING_FUNCTION_NAME, SAFE_STRING_LINE, InBuffer, total_buffer_size);
01572 #endif
01573
01574 while (!receive_message_or_smb(InBuffer,BUFFER_SIZE+LARGE_WRITEX_HDR_SIZE,select_timeout)) {
01575 if(!timeout_processing( deadtime, &select_timeout, &last_timeout_processing_time))
01576 return;
01577 num_smbs = 0;
01578 }
01579
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589 num_echos = smb_echo_count;
01590
01591 clobber_region(SAFE_STRING_FUNCTION_NAME, SAFE_STRING_LINE, OutBuffer, total_buffer_size);
01592
01593 process_smb(InBuffer, OutBuffer);
01594
01595 if (smb_echo_count != num_echos) {
01596 if(!timeout_processing( deadtime, &select_timeout, &last_timeout_processing_time))
01597 return;
01598 num_smbs = 0;
01599 }
01600
01601 num_smbs++;
01602
01603
01604
01605
01606
01607
01608
01609
01610 if ((num_smbs % 200) == 0) {
01611 time_t new_check_time = time(NULL);
01612 if(new_check_time - last_timeout_processing_time >= (select_timeout/1000)) {
01613 if(!timeout_processing( deadtime, &select_timeout, &last_timeout_processing_time))
01614 return;
01615 num_smbs = 0;
01616 last_timeout_processing_time = new_check_time;
01617 }
01618 }
01619
01620
01621
01622
01623
01624
01625
01626
01627 if ((num_smbs % 50) == 0 && need_to_check_log_size()) {
01628 change_to_root_user();
01629 check_log_size();
01630 }
01631 }
01632 }