process.c

来自「samba-3.0.22.tar.gz 编译smb服务器的源码」· C语言 代码 · 共 1,793 行 · 第 1/4 页

C
1,793
字号
	memcpy(inbuf2,inbuf_saved,smb_wct);	{		int ofs = smb_wct - PTR_DIFF(outbuf2,orig_outbuf);		if (ofs < 0) ofs = 0;			memmove(outbuf2+ofs,outbuf_saved+ofs,smb_wct-ofs);	}	return outsize2;}/**************************************************************************** Setup the needed select timeout.****************************************************************************/static int setup_select_timeout(void){	int select_timeout;	int t;	select_timeout = blocking_locks_timeout(SMBD_SELECT_TIMEOUT);	select_timeout *= 1000;	t = change_notify_timeout();	DEBUG(10, ("change_notify_timeout: %d\n", t));	if (t != -1)		select_timeout = MIN(select_timeout, t*1000);	if (print_notify_messages_pending())		select_timeout = MIN(select_timeout, 1000);	return select_timeout;}/**************************************************************************** Check if services need reloading.****************************************************************************/void check_reload(time_t t){	static pid_t mypid = 0;	static time_t last_smb_conf_reload_time = 0;	static time_t last_printer_reload_time = 0;	time_t printcap_cache_time = (time_t)lp_printcap_cache_time();	if(last_smb_conf_reload_time == 0) {		last_smb_conf_reload_time = t;		/* Our printing subsystem might not be ready at smbd start up.		   Then no printer is available till the first printers check		   is performed.  A lower initial interval circumvents this. */		if ( printcap_cache_time > 60 )			last_printer_reload_time = t - printcap_cache_time + 60;		else			last_printer_reload_time = t;	}	if (mypid != getpid()) { /* First time or fork happened meanwhile */		/* randomize over 60 second the printcap reload to avoid all		 * process hitting cupsd at the same time */		int time_range = 60;		last_printer_reload_time += random() % time_range;		mypid = getpid();	}	if (reload_after_sighup || (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK)) {		reload_services(True);		reload_after_sighup = False;		last_smb_conf_reload_time = t;	}	/* 'printcap cache time = 0' disable the feature */		if ( printcap_cache_time != 0 )	{ 		/* see if it's time to reload or if the clock has been set back */				if ( (t >= last_printer_reload_time+printcap_cache_time) 			|| (t-last_printer_reload_time  < 0) ) 		{			DEBUG( 3,( "Printcap cache time expired.\n"));			reload_printers();			last_printer_reload_time = t;		}	}}/**************************************************************************** Process any timeout housekeeping. Return False if the caller should exit.****************************************************************************/static BOOL timeout_processing(int deadtime, int *select_timeout, time_t *last_timeout_processing_time){	static time_t last_keepalive_sent_time = 0;	static time_t last_idle_closed_check = 0;	time_t t;	BOOL allidle = True;	if (smb_read_error == READ_EOF) {		DEBUG(3,("timeout_processing: End of file from client (client has disconnected).\n"));		return False;	}	if (smb_read_error == READ_ERROR) {		DEBUG(3,("timeout_processing: receive_smb error (%s) Exiting\n",			strerror(errno)));		return False;	}	if (smb_read_error == READ_BAD_SIG) {		DEBUG(3,("timeout_processing: receive_smb error bad smb signature. Exiting\n"));		return False;	}	*last_timeout_processing_time = t = time(NULL);	if(last_keepalive_sent_time == 0)		last_keepalive_sent_time = t;	if(last_idle_closed_check == 0)		last_idle_closed_check = t;	/* become root again if waiting */	change_to_root_user();	/* run all registered idle events */	smb_run_idle_events(t);	/* check if we need to reload services */	check_reload(t);	/* automatic timeout if all connections are closed */      	if (conn_num_open()==0 && (t - last_idle_closed_check) >= IDLE_CLOSED_TIMEOUT) {		DEBUG( 2, ( "Closing idle connection\n" ) );		return False;	} else {		last_idle_closed_check = t;	}	if (keepalive && (t - last_keepalive_sent_time)>keepalive) {		if (!send_keepalive(smbd_server_fd())) {			DEBUG( 2, ( "Keepalive failed - exiting.\n" ) );			return False;		}		/* send a keepalive for a password server or the like.			This is attached to the auth_info created in the		negprot */		if (negprot_global_auth_context && negprot_global_auth_context->challenge_set_method 				&& negprot_global_auth_context->challenge_set_method->send_keepalive) {			negprot_global_auth_context->challenge_set_method->send_keepalive			(&negprot_global_auth_context->challenge_set_method->private_data);		}		last_keepalive_sent_time = t;	}	/* check for connection timeouts */	allidle = conn_idle_all(t, deadtime);	if (allidle && conn_num_open()>0) {		DEBUG(2,("Closing idle connection 2.\n"));		return False;	}	if(global_machine_password_needs_changing && 			/* for ADS we need to do a regular ADS password change, not a domain					password change */			lp_security() == SEC_DOMAIN) {		unsigned char trust_passwd_hash[16];		time_t lct;		/*		 * We're in domain level security, and the code that		 * read the machine password flagged that the machine		 * password needs changing.		 */		/*		 * First, open the machine password file with an exclusive lock.		 */		if (secrets_lock_trust_account_password(lp_workgroup(), True) == False) {			DEBUG(0,("process: unable to lock the machine account password for \machine %s in domain %s.\n", global_myname(), lp_workgroup() ));			return True;		}		if(!secrets_fetch_trust_account_password(lp_workgroup(), trust_passwd_hash, &lct, NULL)) {			DEBUG(0,("process: unable to read the machine account password for \machine %s in domain %s.\n", global_myname(), lp_workgroup()));			secrets_lock_trust_account_password(lp_workgroup(), False);			return True;		}		/*		 * Make sure someone else hasn't already done this.		 */		if(t < lct + lp_machine_password_timeout()) {			global_machine_password_needs_changing = False;			secrets_lock_trust_account_password(lp_workgroup(), False);			return True;		}		/* always just contact the PDC here */    		change_trust_account_password( lp_workgroup(), NULL);		global_machine_password_needs_changing = False;		secrets_lock_trust_account_password(lp_workgroup(), False);	}	/*	 * Check to see if we have any blocking locks	 * outstanding on the queue.	 */	process_blocking_lock_queue(t);	/* update printer queue caches if necessary */  	update_monitored_printq_cache();  	/*	 * Check to see if we have any change notifies 	 * outstanding on the queue.	 */	process_pending_change_notify_queue(t);	/*	 * Now we are root, check if the log files need pruning.	 * Force a log file check.	 */	force_check_log_size();	check_log_size();	/* Send any queued printer notify message to interested smbd's. */	print_notify_send_messages(0);	/*	 * Modify the select timeout depending upon	 * what we have remaining in our queues.	 */	*select_timeout = setup_select_timeout();	return True;}/**************************************************************************** Accessor functions for InBuffer, OutBuffer.****************************************************************************/char *get_InBuffer(void){	return InBuffer;}void set_InBuffer(char *new_inbuf){	InBuffer = new_inbuf;	current_inbuf = InBuffer;}char *get_OutBuffer(void){	return OutBuffer;}void set_OutBuffer(char *new_outbuf){	OutBuffer = new_outbuf;}/**************************************************************************** Free an InBuffer. Checks if not in use by aio system. Must have been allocated by NewInBuffer.****************************************************************************/void free_InBuffer(char *inbuf){	if (!aio_inbuffer_in_use(inbuf)) {		if (current_inbuf == inbuf) {			current_inbuf = NULL;		}		SAFE_FREE(inbuf);	}}/**************************************************************************** Free an OutBuffer. No outbuffers currently stolen by aio system. Must have been allocated by NewInBuffer.****************************************************************************/void free_OutBuffer(char *outbuf){	SAFE_FREE(outbuf);}const int total_buffer_size = (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE + SAFETY_MARGIN);/**************************************************************************** Allocate a new InBuffer. Returns the new and old ones.****************************************************************************/char *NewInBuffer(char **old_inbuf){	char *new_inbuf = (char *)SMB_MALLOC(total_buffer_size);	if (!new_inbuf) {		return NULL;	}	if (old_inbuf) {		*old_inbuf = InBuffer;	}	InBuffer = new_inbuf;#if defined(DEVELOPER)	clobber_region(SAFE_STRING_FUNCTION_NAME, SAFE_STRING_LINE, InBuffer, total_buffer_size);#endif	return InBuffer;}/**************************************************************************** Allocate a new OutBuffer. Returns the new and old ones.****************************************************************************/char *NewOutBuffer(char **old_outbuf){	char *new_outbuf = (char *)SMB_MALLOC(total_buffer_size);	if (!new_outbuf) {		return NULL;	}	if (old_outbuf) {		*old_outbuf = OutBuffer;	}	OutBuffer = new_outbuf;#if defined(DEVELOPER)	clobber_region(SAFE_STRING_FUNCTION_NAME, SAFE_STRING_LINE, OutBuffer, total_buffer_size);#endif	return OutBuffer;}/**************************************************************************** Process commands from the client****************************************************************************/void smbd_process(void){	time_t last_timeout_processing_time = time(NULL);	unsigned int num_smbs = 0;	/* Allocate the primary Inbut/Output buffers. */	if ((NewInBuffer(NULL) == NULL) || (NewOutBuffer(NULL) == NULL)) 		return;	max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);	while (True) {		int deadtime = lp_deadtime()*60;		int select_timeout = setup_select_timeout();		int num_echos;		if (deadtime <= 0)			deadtime = DEFAULT_SMBD_TIMEOUT;		errno = 0;      				/* free up temporary memory */		lp_talloc_free();		main_loop_talloc_free();		/* Did someone ask for immediate checks on things like blocking locks ? */		if (select_timeout == 0) {			if(!timeout_processing( deadtime, &select_timeout, &last_timeout_processing_time))				return;			num_smbs = 0; /* Reset smb counter. */		}		run_events();#if defined(DEVELOPER)		clobber_region(SAFE_STRING_FUNCTION_NAME, SAFE_STRING_LINE, InBuffer, total_buffer_size);#endif		while (!receive_message_or_smb(InBuffer,BUFFER_SIZE+LARGE_WRITEX_HDR_SIZE,select_timeout)) {			if(!timeout_processing( deadtime, &select_timeout, &last_timeout_processing_time))				return;			num_smbs = 0; /* Reset smb counter. */		}		/*		 * Ensure we do timeout processing if the SMB we just got was		 * only an echo request. This allows us to set the select		 * timeout in 'receive_message_or_smb()' to any value we like		 * without worrying that the client will send echo requests		 * faster than the select timeout, thus starving out the		 * essential processing (change notify, blocking locks) that		 * the timeout code does. JRA.		 */ 		num_echos = smb_echo_count;		clobber_region(SAFE_STRING_FUNCTION_NAME, SAFE_STRING_LINE, OutBuffer, total_buffer_size);		process_smb(InBuffer, OutBuffer);		if (smb_echo_count != num_echos) {			if(!timeout_processing( deadtime, &select_timeout, &last_timeout_processing_time))				return;			num_smbs = 0; /* Reset smb counter. */		}		num_smbs++;		/*		 * If we are getting smb requests in a constant stream		 * with no echos, make sure we attempt timeout processing		 * every select_timeout milliseconds - but only check for this		 * every 200 smb requests.		 */				if ((num_smbs % 200) == 0) {			time_t new_check_time = time(NULL);			if(new_check_time - last_timeout_processing_time >= (select_timeout/1000)) {				if(!timeout_processing( deadtime, &select_timeout, &last_timeout_processing_time))					return;				num_smbs = 0; /* Reset smb counter. */				last_timeout_processing_time = new_check_time; /* Reset time. */			}		}		/* The timeout_processing function isn't run nearly		   often enough to implement 'max log size' without		   overrunning the size of the file by many megabytes.		   This is especially true if we are running at debug		   level 10.  Checking every 50 SMBs is a nice		   tradeoff of performance vs log file size overrun. */		if ((num_smbs % 50) == 0 && need_to_check_log_size()) {			change_to_root_user();			check_log_size();		}	}}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?