データ構造 | |
| struct | idle_event |
| struct | smb_message_struct |
関数 | |
| uint16 | get_current_mid (void) |
| static BOOL | push_queued_message (char *buf, int msg_len, struct timeval request_time, struct timeval end_time, char *private_data, size_t private_len) |
| void | remove_deferred_open_smb_message (uint16 mid) |
| void | schedule_deferred_open_smb_message (uint16 mid) |
| BOOL | open_was_deferred (uint16 mid) |
| pending_message_list * | get_open_deferred_message (uint16 mid) |
| BOOL | push_deferred_smb_message (uint16 mid, struct timeval request_time, struct timeval timeout, char *private_data, size_t priv_len) |
| static void | idle_event_handler (struct event_context *ctx, struct timed_event *te, const struct timeval *now, void *private_data) |
| idle_event * | add_idle_event (TALLOC_CTX *mem_ctx, struct timeval interval, BOOL(*handler)(const struct timeval *now, void *private_data), void *private_data) |
| static void | async_processing (fd_set *pfds) |
| static int | select_on_fd (int fd, int maxfd, fd_set *fds) |
| static BOOL | receive_message_or_smb (char *buffer, int buffer_len, int timeout) |
| NTSTATUS | allow_new_trans (struct trans_state *list, int mid) |
| void | respond_to_all_remaining_local_messages (void) |
| static void | smb_dump (const char *name, int type, char *data, ssize_t len) |
| static int | switch_message (int type, char *inbuf, char *outbuf, int size, int bufsize) |
| static int | construct_reply (char *inbuf, char *outbuf, int size, int bufsize) |
| static void | process_smb (char *inbuf, char *outbuf) |
| const char * | smb_fn_name (int type) |
| void | add_to_common_flags2 (uint32 v) |
| void | remove_from_common_flags2 (uint32 v) |
| void | construct_reply_common (const char *inbuf, char *outbuf) |
| int | chain_reply (char *inbuf, char *outbuf, int size, int bufsize) |
| static int | setup_select_timeout (void) |
| void | check_reload (time_t t) |
| static BOOL | timeout_processing (int deadtime, int *select_timeout, time_t *last_timeout_processing_time) |
| char * | get_InBuffer (void) |
| char * | get_OutBuffer (void) |
| static char * | NewInBuffer (char **old_inbuf) |
| static char * | NewOutBuffer (char **old_outbuf) |
| void | smbd_process (void) |
変数 | |
| uint16 | global_smbpid |
| int | keepalive |
| auth_context * | negprot_global_auth_context |
| int | smb_echo_count |
| static char * | InBuffer = NULL |
| static char * | OutBuffer = NULL |
| static char * | current_inbuf = NULL |
| int | max_send = BUFFER_SIZE |
| int | max_recv = BUFFER_SIZE |
| int | last_message |
| int | smb_read_error |
| SIG_ATOMIC_T | reload_after_sighup = 0 |
| SIG_ATOMIC_T | got_sig_term = 0 |
| BOOL | global_machine_password_needs_changing |
| int | max_send |
| static struct pending_message_list * | deferred_open_queue |
| static struct smb_message_struct | smb_messages [256] |
| static uint32 | common_flags2 = FLAGS2_LONG_PATH_COMPONENTS|FLAGS2_32_BIT_ERROR_CODES |
| const int | total_buffer_size = (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE + SAFETY_MARGIN) |
| uint16 get_current_mid | ( | void | ) |
参照先 InBuffer.
参照元 defer_open()・open_file_ntcreate().
00057 { 00058 return SVAL(InBuffer,smb_mid); 00059 }
| static BOOL push_queued_message | ( | char * | buf, | |
| int | msg_len, | |||
| struct timeval | request_time, | |||
| struct timeval | end_time, | |||
| char * | private_data, | |||
| size_t | private_len | |||
| ) | [static] |
参照先 pending_message_list::buf・data_blob_::data・data_blob_talloc()・deferred_open_queue・pending_message_list::end_time・pending_message_list::private_data・pending_message_list::request_time.
参照元 push_deferred_smb_message().
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 }
| void remove_deferred_open_smb_message | ( | uint16 | mid | ) |
参照先 pending_message_list::buf・data_blob_::data・deferred_open_queue・data_blob_::length・pending_message_list::next.
参照元 open_file_ntcreate().
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 }
| void schedule_deferred_open_smb_message | ( | uint16 | mid | ) |
参照先 pending_message_list::buf・data_blob_::data・deferred_open_queue・pending_message_list::end_time・pending_message_list::next.
参照元 notify_deferred_opens()・process_open_retry_message()・process_oplock_break_response().
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 }
| BOOL open_was_deferred | ( | uint16 | mid | ) |
参照先 pending_message_list::buf・data_blob_::data・deferred_open_queue・pending_message_list::next.
参照元 call_nt_transact_create()・call_nt_transact_rename()・call_trans2open()・call_trans2setfilepathinfo()・reply_ctemp()・reply_mknew()・reply_mv()・reply_ntcreate_and_X()・reply_ntrename()・reply_open()・reply_open_and_X()・reply_unlink()・validate_my_share_entries().
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 }
| struct pending_message_list* get_open_deferred_message | ( | uint16 | mid | ) |
参照先 pending_message_list::buf・data_blob_::data・deferred_open_queue・pending_message_list::next.
参照元 open_file_ntcreate().
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 }
| BOOL push_deferred_smb_message | ( | uint16 | mid, | |
| struct timeval | request_time, | |||
| struct timeval | timeout, | |||
| char * | private_data, | |||
| size_t | priv_len | |||
| ) |
参照先 current_inbuf・push_queued_message()・timeval_sum().
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 }
| static void idle_event_handler | ( | struct event_context * | ctx, | |
| struct timed_event * | te, | |||
| const struct timeval * | now, | |||
| void * | private_data | |||
| ) | [static] |
参照先 event_add_timed()・idle_event::handler・idle_event::interval・idle_event::private_data・smbd_event_context()・idle_event::te・timeval_sum().
参照元 add_idle_event().
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 /* Don't repeat, delete ourselves */ 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 /* We can't do much but fail here. */ 00250 SMB_ASSERT(event->te != NULL); 00251 }
| struct idle_event* add_idle_event | ( | TALLOC_CTX * | mem_ctx, | |
| struct timeval | interval, | |||
| BOOL(*)(const struct timeval *now, void *private_data) | handler, | |||
| void * | private_data | |||
| ) |
参照先 event_add_timed()・idle_event_handler()・result・smbd_event_context()・timeval_current()・timeval_sum().
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 }
| static void async_processing | ( | fd_set * | pfds | ) | [static] |
参照先 change_to_root_user()・exit_server_cleanly()・got_sig_term・process_aio_queue()・process_kernel_oplocks()・reload_after_sighup・reload_services().
00291 { 00292 DEBUG(10,("async_processing: Doing async processing.\n")); 00293 00294 process_aio_queue(); 00295 00296 process_kernel_oplocks(pfds); 00297 00298 /* Do the aio check again after receive_local_message as it does a 00299 select and may have eaten our signal. */ 00300 /* Is this till true? -- vl */ 00301 process_aio_queue(); 00302 00303 if (got_sig_term) { 00304 exit_server_cleanly("termination signal"); 00305 } 00306 00307 /* check for sighup processing */ 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 }
| static int select_on_fd | ( | int | fd, | |
| int | maxfd, | |||
| fd_set * | fds | |||
| ) | [static] |
| static BOOL receive_message_or_smb | ( | char * | buffer, | |
| int | buffer_len, | |||
| int | timeout | |||
| ) | [static] |
参照先 async_processing()・pending_message_list::buf・data_blob_::data・deferred_open_queue・pending_message_list::end_time・errno・event_add_to_select_args()・GetTimeOfDay()・data_blob_::length・message_dispatch()・oplock_message_waiting()・oplock_notify_fd()・receive_smb()・run_events()・select_on_fd()・smb_read_error・smbd_event_context()・smbd_server_fd()・sys_select()・timeval_is_zero()・usec_time_diff().
参照元 smbd_process().
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 * Note that this call must be before processing any SMB 00372 * messages as we need to synchronously process any messages 00373 * we may have sent to ourselves from the previous SMB. 00374 */ 00375 message_dispatch(); 00376 00377 /* 00378 * Check to see if we already have a message on the deferred open queue 00379 * and it's time to schedule. 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 /* Timed out. Schedule...*/ 00395 pop_message = True; 00396 DEBUG(10,("receive_message_or_smb: queued message timed out.\n")); 00397 } else { 00398 /* Make a more accurate select timeout. */ 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 /* We leave this message on the queue so the open code can 00410 know this is a retry. */ 00411 DEBUG(5,("receive_message_or_smb: returning deferred open smb message.\n")); 00412 return True; 00413 } 00414 } 00415 00416 /* 00417 * Setup the select fd sets. 00418 */ 00419 00420 FD_ZERO(&r_fds); 00421 FD_ZERO(&w_fds); 00422 00423 /* 00424 * Ensure we process oplock break messages by preference. 00425 * We have to do this before the select, after the select 00426 * and if the select returns EINTR. This is due to the fact 00427 * that the selects called from async_processing can eat an EINTR 00428 * caused by a signal (we can't take the break message there). 00429 * This is hideously complex - *MUST* be simplified for 3.0 ! JRA. 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 * After async processing we must go and do the select again, as 00437 * the state of the flag in fds for the server file descriptor is 00438 * indeterminate - we may have done I/O on it in the oplock processing. JRA. 00439 */ 00440 goto again; 00441 } 00442 00443 /* 00444 * Are there any timed events waiting ? If so, ensure we don't 00445 * select for longer than it would take to wait for them. 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 /* Process a timed event now... */ 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 /* if we get EINTR then maybe we have received an oplock 00482 signal - treat this as select returning 1. This is ugly, but 00483 is the best we can do until the oplock code knows more about 00484 signals */ 00485 if (selrtn == -1 && errno == EINTR) { 00486 async_processing(&r_fds); 00487 /* 00488 * After async processing we must go and do the select again, as 00489 * the state of the flag in fds for the server file descriptor is 00490 * indeterminate - we may have done I/O on it in the oplock processing. JRA. 00491 */ 00492 goto again; 00493 } 00494 00495 /* Check if error */ 00496 if (selrtn == -1) { 00497 /* something is wrong. Maybe the socket is dead? */ 00498 smb_read_error = READ_ERROR; 00499 return False; 00500 } 00501 00502 /* Did we timeout ? */ 00503 if (selrtn == 0) { 00504 smb_read_error = READ_TIMEOUT; 00505 return False; 00506 } 00507 00508 /* 00509 * Ensure we process oplock break messages by preference. 00510 * This is IMPORTANT ! Otherwise we can starve other processes 00511 * sending us an oplock break message. JRA. 00512 */ 00513 00514 if (oplock_message_waiting(&r_fds)) { 00515 async_processing(&r_fds); 00516 /* 00517 * After async processing we must go and do the select again, as 00518 * the state of the flag in fds for the server file descriptor is 00519 * indeterminate - we may have done I/O on it in the oplock processing. JRA. 00520 */ 00521 goto again; 00522 } 00523 00524 return receive_smb(smbd_server_fd(), buffer, 00525 BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE, 0); 00526 }
| NTSTATUS allow_new_trans | ( | struct trans_state * | list, | |
| int | mid | |||
| ) |
参照先 list().
参照元 reply_nttrans()・reply_trans()・reply_trans2().
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 }
| void respond_to_all_remaining_local_messages | ( | void | ) |
参照先 get_number_of_exclusive_open_oplocks()・process_kernel_oplocks().
参照元 exit_server_common().
00559 { 00560 /* 00561 * Assert we have no exclusive open oplocks. 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 }
| static void smb_dump | ( | const char * | name, | |
| int | type, | |||
| char * | data, | |||
| ssize_t | len | |||
| ) | [static] |
参照先 DEBUGLEVEL・errno・fd.
参照元 switch_message().
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 }
| static int switch_message | ( | int | type, | |
| char * | inbuf, | |||
| char * | outbuf, | |||
| int | size, | |||
| int | bufsize | |||
| ) | [static] |
参照先 change_to_guest()・change_to_root_user()・change_to_user()・check_access()・conn_find()・current_inbuf・errno・exit_server_cleanly()・smb_message_struct::flags・flags・smb_message_struct::fn・fn・get_valid_user_struct()・global_smbpid・last_message・reply_unknown()・SEC_SHARE・set_current_service()・set_current_user_info()・smb_dump()・smb_fn_name()・smb_messages・smbd_server_fd()・sys_getpid()・user_struct::user.
参照元 chain_reply()・construct_reply().
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 /* Make sure this is an SMB packet. smb_size contains NetBIOS header so subtract 4 from it. */ 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 /* yuck! this is an interim measure before we get rid of our 00913 current inbuf/outbuf system */ 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 /* In share mode security we must ignore the vuid. */ 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 /* Ensure this value is replaced in the incoming packet. */ 00932 SSVAL(inbuf,smb_uid,session_tag); 00933 00934 /* 00935 * Ensure the correct username is in current_user_info. 00936 * This is a really ugly bugfix for problems with 00937 * multiple session_setup_and_X's being done and 00938 * allowing %U and %G substitutions to work correctly. 00939 * There is a reason this code is done here, don't 00940 * move it unless you know what you're doing... :-). 00941 * JRA. 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 /* Does this call need to be run as the connected user? */ 00957 if (flags & AS_USER) { 00958 00959 /* Does this call need a valid tree connection? */ 00960 if (!conn) { 00961 /* Amazingly, the error code depends on the command (from Samba4). */ 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 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */ 00974 00975 /* Does it need write permission? */ 00976 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) { 00977 return ERROR_NT(NT_STATUS_MEDIA_WRITE_PROTECTED); 00978 } 00979 00980 /* IPC services are limited */ 00981 if (IS_IPC(conn) && !(flags & CAN_IPC)) { 00982 return(ERROR_DOS(ERRSRV,ERRaccess)); 00983 } 00984 } else { 00985 /* This call needs to be run as root */ 00986 change_to_root_user(); 00987 } 00988 00989 /* load service specific parameters */ 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 /* does this protocol need to be run as guest? */ 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; /* In case we need to defer this message in open... */ 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 }
| static int construct_reply | ( | char * | inbuf, | |
| char * | outbuf, | |||
| int | size, | |||
| int | bufsize | |||
| ) | [static] |
参照先 chain_size・construct_reply_common()・file_chain_reset()・reply_special()・reset_chain_p()・smb_setlen()・switch_message()・type.
参照元 process_smb().
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 }
| static void process_smb | ( | char * | inbuf, | |
| char * | outbuf | |||
| ) | [static] |
参照先 buf・check_access()・client_addr()・construct_reply()・exit_server_cleanly()・len・max_send・send_smb()・show_msg()・smbd_server_fd()・trans_num.
参照元 smbd_process().
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 /* on the first packet, check the global hosts allow/ hosts 01055 deny parameters before doing any parsing of the packet 01056 passed to us by the client. This prevents attacks on our 01057 parsing code from hosts not in the hosts allow list */ 01058 if (!check_access(smbd_server_fd(), lp_hostsallow(-1), 01059 lp_hostsdeny(-1))) { 01060 /* send a negative session response "not listening on calling name" */ 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; /* Keepalive packet. */ 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 }
| const char* smb_fn_name | ( | int | type | ) |
参照先 name・smb_messages.
参照元 call_trans2findfirst()・call_trans2findnext()・call_trans2qfsinfo()・error_packet_set()・reply_search()・reply_unknown()・switch_message().
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 }
| void add_to_common_flags2 | ( | uint32 | v | ) |
| void remove_from_common_flags2 | ( | uint32 | v | ) |
参照元 reply_sesssetup_and_X()・reply_sesssetup_and_X_spnego().
01118 { 01119 common_flags2 &= ~v; 01120 }
| void construct_reply_common | ( | const char * | inbuf, | |
| char * | outbuf | |||
| ) |
参照先 set_message().
参照元 blocking_lock_reply_error()・chain_reply()・change_notify_reply()・change_notify_reply_packet()・construct_reply()・generic_blocking_lock_error()・process_trans2()・reply_lockingX_success().
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 }
| int chain_reply | ( | char * | inbuf, | |
| char * | outbuf, | |||
| int | size, | |||
| int | bufsize | |||
| ) |
参照先 chain_size・construct_reply_common()・exit_server_cleanly()・show_msg()・smb_setlen()・switch_message().
参照元 do_ntcreate_pipe_open()・reply_lockingX()・reply_lockingX_success()・reply_ntcreate_and_X()・reply_ntcreate_and_X_quota()・reply_open_and_X()・reply_open_pipe_and_X()・reply_pipe_read_and_X()・reply_pipe_write_and_X()・reply_read_and_X()・reply_sesssetup_and_X()・reply_tcon_and_X()・reply_ulogoffX()・reply_write_and_X().
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 /* Maybe its not chained, or it's an error packet. */ 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 /* this is the first part of the chain */ 01165 orig_inbuf = inbuf; 01166 orig_outbuf = outbuf; 01167 } 01168 01169 /* 01170 * The original Win95 redirector dies on a reply to 01171 * a lockingX and read chain unless the chain reply is 01172 * 4 byte aligned. JRA. 01173 */ 01174 01175 outsize = (outsize + 3) & ~3; 01176 01177 /* we need to tell the client where the next part of the reply will be */ 01178 SSVAL(outbuf,smb_vwv1,smb_offset(outbuf+outsize,outbuf)); 01179 SCVAL(outbuf,smb_vwv0,smb_com2); 01180 01181 /* remember how much the caller added to the chain, only counting stuff 01182 after the parameter words */ 01183 chain_size += outsize - smb_wct; 01184 01185 /* work out pointers into the original packets. The 01186 headers on these need to be filled in */ 01187 inbuf2 = orig_inbuf + smb_off2 + 4 - smb_wct; 01188 outbuf2 = orig_outbuf + SVAL(outbuf,smb_vwv1) + 4 - smb_wct; 01189 01190 /* remember the original command type */ 01191 smb_com1 = CVAL(orig_inbuf,smb_com); 01192 01193 /* save the data which will be overwritten by the new headers */ 01194 memcpy(inbuf_saved,inbuf2,smb_wct); 01195 memcpy(outbuf_saved,outbuf2,smb_wct); 01196 01197 /* give the new packet the same header as the last part of the SMB */ 01198 memmove(inbuf2,inbuf,smb_wct); 01199 01200 /* create the in buffer */ 01201 SCVAL(inbuf2,smb_com,smb_com2); 01202 01203 /* work out the new size for the in buffer. */ 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 /* And set it in the header. */ 01215 smb_setlen(inbuf2, new_size); 01216 01217 /* create the out buffer */ 01218 construct_reply_common(inbuf2, outbuf2); 01219 01220 DEBUG(3,("Chained message\n")); 01221 show_msg(inbuf2); 01222 01223 /* process the request */ 01224 outsize2 = switch_message(smb_com2,inbuf2,outbuf2,new_size, 01225 bufsize-chain_size); 01226 01227 /* copy the new reply and request headers over the old ones, but 01228 preserve the smb_com field */ 01229 memmove(orig_outbuf,outbuf2,smb_wct); 01230 SCVAL(orig_outbuf,smb_com,smb_com1); 01231 01232 /* restore the saved data, being careful not to overwrite any 01233 data from the reply header */ 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 }
| static int setup_select_timeout | ( | void | ) | [static] |
参照先 blocking_locks_timeout_ms()・print_notify_messages_pending().
参照元 smbd_process()・timeout_processing().
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 }
| void check_reload | ( | time_t | t | ) |
参照先 mypid・reload_after_sighup・reload_printers()・reload_services().
参照元 open_sockets_smbd()・timeout_processing().
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 /* Our printing subsystem might not be ready at smbd start up. 01278 Then no printer is available till the first printers check 01279 is performed. A lower initial interval circumvents this. */ 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()) { /* First time or fork happened meanwhile */ 01287 /* randomize over 60 second the printcap reload to avoid all 01288 * process hitting cupsd at the same time */ 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 /* 'printcap cache time = 0' disable the feature */ 01302 01303 if ( printcap_cache_time != 0 ) 01304 { 01305 /* see if it's time to reload or if the clock has been set back */ 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 }
| static BOOL timeout_processing | ( | int | deadtime, | |
| int * | select_timeout, | |||
| time_t * | last_timeout_processing_time | |||
| ) | [static] |
参照先 auth_context::challenge_set_method・change_to_root_user()・change_trust_account_password()・check_log_size()・check_reload()・conn_idle_all()・conn_num_open()・errno・force_check_log_size()・global_machine_password_needs_changing・global_myname・keepalive・lp_workgroup()・negprot_global_auth_context・print_notify_send_messages()・auth_methods::private_data・process_blocking_lock_queue()・SEC_DOMAIN・secrets_fetch_trust_account_password()・secrets_lock_trust_account_password()・auth_methods::send_keepalive・send_keepalive()・setup_select_timeout()・smb_read_error・smb_run_idle_events()・smbd_server_fd()・strerror()・t・update_monitored_printq_cache().
参照元 smbd_process().
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 /* become root again if waiting */ 01353 change_to_root_user(); 01354 01355 /* run all registered idle events */ 01356 smb_run_idle_events(t); 01357 01358 /* check if we need to reload services */ 01359 check_reload(t); 01360 01361 /* automatic timeout if all connections are closed */ 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 /* send a keepalive for a password server or the like. 01376 This is attached to the auth_info created in the 01377 negprot */ 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 /* check for connection timeouts */ 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 /* for ADS we need to do a regular ADS password change, not a domain 01398 password change */ 01399 lp_security() == SEC_DOMAIN) { 01400 01401 unsigned char trust_passwd_hash[16]; 01402 time_t lct; 01403 01404 /* 01405 * We're in domain level security, and the code that 01406 * read the machine password flagged that the machine 01407 * password needs changing. 01408 */ 01409 01410 /* 01411 * First, open the machine password file with an exclusive lock. 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 * Make sure someone else hasn't already done this. 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 /* always just contact the PDC here */ 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 * Check to see if we have any blocking locks 01446 * outstanding on the queue. 01447 */ 01448 process_blocking_lock_queue(); 01449 01450 /* update printer queue caches if necessary */ 01451 01452 update_monitored_printq_cache(); 01453 01454 /* 01455 * Now we are root, check if the log files need pruning. 01456 * Force a log file check. 01457 */ 01458 force_check_log_size(); 01459 check_log_size(); 01460 01461 /* Send any queued printer notify message to interested smbd's. */ 01462 01463 print_notify_send_messages(0); 01464 01465 /* 01466 * Modify the select timeout depending upon 01467 * what we have remaining in our queues. 01468 */ 01469 01470 *select_timeout = setup_select_timeout(); 01471 01472 return True; 01473 }
| char* get_InBuffer | ( | void | ) |
| char* get_OutBuffer | ( | void | ) |
参照先 OutBuffer.
参照元 blocking_lock_reply_error()・generic_blocking_lock_error()・process_trans2()・reply_lockingX_success().
01485 { 01486 return OutBuffer; 01487 }
| static char* NewInBuffer | ( | char ** | old_inbuf | ) | [static] |
参照先 clobber_region()・InBuffer.
参照元 smbd_process().
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 }
| static char* NewOutBuffer | ( | char ** | old_outbuf | ) | [static] |
参照先 clobber_region()・OutBuffer.
参照元 smbd_process().
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 }
| void smbd_process | ( | void | ) |
参照先 change_to_root_user()・check_log_size()・clobber_region()・errno・InBuffer・lp_TALLOC_FREE()・main_loop_TALLOC_FREE()・max_recv・need_to_check_log_size()・NewInBuffer()・NewOutBuffer()・OutBuffer・process_smb()・receive_message_or_smb()・run_events()・setup_select_timeout()・smb_echo_count・smbd_event_context()・timeout_processing().
参照元 main().
01536 { 01537 time_t last_timeout_processing_time = time(NULL); 01538 unsigned int num_smbs = 0; 01539 01540 /* Allocate the primary Inbut/Output buffers. */ 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 /* free up temporary memory */ 01558 lp_TALLOC_FREE(); 01559 main_loop_TALLOC_FREE(); 01560 01561 /* Did someone ask for immediate checks on things like blocking locks ? */ 01562 if (select_timeout == 0) { 01563 if(!timeout_processing( deadtime, &select_timeout, &last_timeout_processing_time)) 01564 return; 01565 num_smbs = 0; /* Reset smb counter. */ 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; /* Reset smb counter. */ 01578 } 01579 01580 /* 01581 * Ensure we do timeout processing if the SMB we just got was 01582 * only an echo request. This allows us to set the select 01583 * timeout in 'receive_message_or_smb()' to any value we like 01584 * without worrying that the client will send echo requests 01585 * faster than the select timeout, thus starving out the 01586 * essential processing (change notify, blocking locks) that 01587 * the timeout code does. JRA. 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; /* Reset smb counter. */ 01599 } 01600 01601 num_smbs++; 01602 01603 /* 01604 * If we are getting smb requests in a constant stream 01605 * with no echos, make sure we attempt timeout processing 01606 * every select_timeout milliseconds - but only check for this 01607 * every 200 smb requests. 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; /* Reset smb counter. */ 01616 last_timeout_processing_time = new_check_time; /* Reset time. */ 01617 } 01618 } 01619 01620 /* The timeout_processing function isn't run nearly 01621 often enough to implement 'max log size' without 01622 overrunning the size of the file by many megabytes. 01623 This is especially true if we are running at debug 01624 level 10. Checking every 50 SMBs is a nice 01625 tradeoff of performance vs log file size overrun. */ 01626 01627 if ((num_smbs % 50) == 0 && need_to_check_log_size()) { 01628 change_to_root_user(); 01629 check_log_size(); 01630 } 01631 } 01632 }
| uint16 global_smbpid |
| int keepalive |
| int smb_echo_count |
char* InBuffer = NULL [static] |
char* OutBuffer = NULL [static] |
char* current_inbuf = NULL [static] |
| int last_message |
| int smb_read_error |
util_sock.c の 117 行で定義されています。
| SIG_ATOMIC_T reload_after_sighup = 0 |
| SIG_ATOMIC_T got_sig_term = 0 |
struct pending_message_list* deferred_open_queue [static] |
struct smb_message_struct smb_messages[256] [static] |
uint32 common_flags2 = FLAGS2_LONG_PATH_COMPONENTS|FLAGS2_32_BIT_ERROR_CODES [static] |
| const int total_buffer_size = (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE + SAFETY_MARGIN) |
1.4.7