smbd/process.c

ソースコードを見る。

データ構造

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_listget_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_eventadd_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_contextnegprot_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_listdeferred_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   ) 

process.c56 行で定義されています。

参照先 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]

process.c73 行で定義されています。

参照先 pending_message_list::bufdata_blob_::datadata_blob_talloc()deferred_open_queuepending_message_list::end_timepending_message_list::private_datapending_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  ) 

process.c119 行で定義されています。

参照先 pending_message_list::bufdata_blob_::datadeferred_open_queuedata_blob_::lengthpending_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  ) 

process.c141 行で定義されています。

参照先 pending_message_list::bufdata_blob_::datadeferred_open_queuepending_message_list::end_timepending_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  ) 

process.c168 行で定義されています。

参照先 pending_message_list::bufdata_blob_::datadeferred_open_queuepending_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  ) 

process.c184 行で定義されています。

参照先 pending_message_list::bufdata_blob_::datadeferred_open_queuepending_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 
)

process.c201 行で定義されています。

参照先 current_inbufpush_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]

process.c228 行で定義されています。

参照先 event_add_timed()idle_event::handleridle_event::intervalidle_event::private_datasmbd_event_context()idle_event::tetimeval_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 
)

process.c253 行で定義されています。

参照先 event_add_timed()idle_event_handler()resultsmbd_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]

process.c290 行で定義されています。

参照先 change_to_root_user()exit_server_cleanly()got_sig_termprocess_aio_queue()process_kernel_oplocks()reload_after_sighupreload_services().

参照元 receive_message_or_smb().

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]

process.c320 行で定義されています。

参照元 receive_message_or_smb().

00321 {
00322         if (fd != -1) {
00323                 FD_SET(fd, fds);
00324                 maxfd = MAX(maxfd, fd);
00325         }
00326 
00327         return maxfd;
00328 }

static BOOL receive_message_or_smb ( char *  buffer,
int  buffer_len,
int  timeout 
) [static]

process.c351 行で定義されています。

参照先 async_processing()pending_message_list::bufdata_blob_::datadeferred_open_queuepending_message_list::end_timeerrnoevent_add_to_select_args()GetTimeOfDay()data_blob_::lengthmessage_dispatch()oplock_message_waiting()oplock_notify_fd()receive_smb()run_events()select_on_fd()smb_read_errorsmbd_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 
)

process.c533 行で定義されています。

参照先 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   ) 

process.c558 行で定義されています。

参照先 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]

process.c864 行で定義されています。

参照先 DEBUGLEVELerrnofd.

参照元 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]

process.c891 行で定義されています。

参照先 change_to_guest()change_to_root_user()change_to_user()check_access()conn_find()current_inbuferrnoexit_server_cleanly()smb_message_struct::flagsflagssmb_message_struct::fnfnget_valid_user_struct()global_smbpidlast_messagereply_unknown()SEC_SHAREset_current_service()set_current_user_info()smb_dump()smb_fn_name()smb_messagessmbd_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]

process.c1016 行で定義されています。

参照先 chain_sizeconstruct_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]

process.c1044 行で定義されています。

参照先 bufcheck_access()client_addr()construct_reply()exit_server_cleanly()lenmax_sendsend_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  ) 

process.c1096 行で定義されています。

参照先 namesmb_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  ) 

process.c1112 行で定義されています。

参照元 reply_nt1().

01113 {
01114         common_flags2 |= v;
01115 }

void remove_from_common_flags2 ( uint32  v  ) 

process.c1117 行で定義されています。

参照元 reply_sesssetup_and_X()reply_sesssetup_and_X_spnego().

01118 {
01119         common_flags2 &= ~v;
01120 }

void construct_reply_common ( const char *  inbuf,
char *  outbuf 
)

process.c1122 行で定義されています。

参照先 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 
)

process.c1144 行で定義されています。

参照先 chain_sizeconstruct_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]

process.c1251 行で定義されています。

参照先 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  ) 

process.c1268 行で定義されています。

参照先 mypidreload_after_sighupreload_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]

process.c1321 行で定義されています。

参照先 auth_context::challenge_set_methodchange_to_root_user()change_trust_account_password()check_log_size()check_reload()conn_idle_all()conn_num_open()errnoforce_check_log_size()global_machine_password_needs_changingglobal_mynamekeepalivelp_workgroup()negprot_global_auth_contextprint_notify_send_messages()auth_methods::private_dataprocess_blocking_lock_queue()SEC_DOMAINsecrets_fetch_trust_account_password()secrets_lock_trust_account_password()auth_methods::send_keepalivesend_keepalive()setup_select_timeout()smb_read_errorsmb_run_idle_events()smbd_server_fd()strerror()tupdate_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   ) 

process.c1479 行で定義されています。

参照先 InBuffer.

参照元 exit_server_common().

01480 {
01481         return InBuffer;
01482 }

char* get_OutBuffer ( void   ) 

process.c1484 行で定義されています。

参照先 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]

process.c1495 行で定義されています。

参照先 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]

process.c1515 行で定義されています。

参照先 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   ) 

process.c1535 行で定義されています。

参照先 change_to_root_user()check_log_size()clobber_region()errnoInBufferlp_TALLOC_FREE()main_loop_TALLOC_FREE()max_recvneed_to_check_log_size()NewInBuffer()NewOutBuffer()OutBufferprocess_smb()receive_message_or_smb()run_events()setup_select_timeout()smb_echo_countsmbd_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

process.c24 行で定義されています。

参照元 fcb_or_dos_open()open_directory()open_file()open_file_stat()switch_message().

int keepalive

loadparm.c82 行で定義されています。

参照元 timeout_processing().

struct auth_context* negprot_global_auth_context

negprot.c29 行で定義されています。

int smb_echo_count

reply.c33 行で定義されています。

参照元 reply_echo()smbd_process().

char* InBuffer = NULL [static]

process.c29 行で定義されています。

参照元 get_current_mid()get_InBuffer()NewInBuffer()smbd_process().

char* OutBuffer = NULL [static]

process.c30 行で定義されています。

参照元 get_OutBuffer()NewOutBuffer()smbd_process().

char* current_inbuf = NULL [static]

process.c31 行で定義されています。

参照元 push_deferred_smb_message()switch_message().

int max_send = BUFFER_SIZE

process.c38 行で定義されています。

int max_recv = BUFFER_SIZE

process.c43 行で定義されています。

int last_message

server.c30 行で定義されています。

参照元 switch_message().

int smb_read_error

util_sock.c117 行で定義されています。

SIG_ATOMIC_T reload_after_sighup = 0

process.c47 行で定義されています。

SIG_ATOMIC_T got_sig_term = 0

process.c48 行で定義されています。

BOOL global_machine_password_needs_changing

secrets.c34 行で定義されています。

int max_send

process.c38 行で定義されています。

struct pending_message_list* deferred_open_queue [static]

process.c66 行で定義されています。

参照元 get_open_deferred_message()open_was_deferred()push_queued_message()receive_message_or_smb()remove_deferred_open_smb_message()schedule_deferred_open_smb_message().

struct smb_message_struct smb_messages[256] [static]

参照元 smb_fn_name()switch_message().

uint32 common_flags2 = FLAGS2_LONG_PATH_COMPONENTS|FLAGS2_32_BIT_ERROR_CODES [static]

process.c1110 行で定義されています。

const int total_buffer_size = (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE + SAFETY_MARGIN)

process.c1489 行で定義されています。


Sambaに対してSat Aug 29 21:24:28 2009に生成されました。  doxygen 1.4.7