mirror of
https://github.com/samba-team/samba.git
synced 2025-03-27 22:50:26 +03:00
Simply our main loop processing. A lot :-). Correctly use events for all the previous "special" cases.
A step on the way to adding signals to the events and being able to merge the S3 event system with the S4 one. Jeremy.
This commit is contained in:
parent
4b9cc7d478
commit
f6c883b4b0
@ -26,6 +26,71 @@
|
||||
extern bool global_machine_password_needs_changing;
|
||||
static struct named_mutex *mutex;
|
||||
|
||||
/*
|
||||
* Change machine password (called from main loop
|
||||
* idle timeout. Must be done as root.
|
||||
*/
|
||||
|
||||
void attempt_machine_password_change(void)
|
||||
{
|
||||
unsigned char trust_passwd_hash[16];
|
||||
time_t lct;
|
||||
void *lock;
|
||||
|
||||
if (!global_machine_password_needs_changing) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (lp_security() != SEC_DOMAIN) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
lock = secrets_get_trust_account_lock(NULL, lp_workgroup());
|
||||
|
||||
if (lock == NULL) {
|
||||
DEBUG(0,("attempt_machine_password_change: unable to lock "
|
||||
"the machine account password for machine %s in "
|
||||
"domain %s.\n",
|
||||
global_myname(), lp_workgroup() ));
|
||||
return;
|
||||
}
|
||||
|
||||
if(!secrets_fetch_trust_account_password(lp_workgroup(),
|
||||
trust_passwd_hash, &lct, NULL)) {
|
||||
DEBUG(0,("attempt_machine_password_change: unable to read the "
|
||||
"machine account password for %s in domain %s.\n",
|
||||
global_myname(), lp_workgroup()));
|
||||
TALLOC_FREE(lock);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure someone else hasn't already done this.
|
||||
*/
|
||||
|
||||
if(time(NULL) < lct + lp_machine_password_timeout()) {
|
||||
global_machine_password_needs_changing = false;
|
||||
TALLOC_FREE(lock);
|
||||
return;
|
||||
}
|
||||
|
||||
/* always just contact the PDC here */
|
||||
|
||||
change_trust_account_password( lp_workgroup(), NULL);
|
||||
global_machine_password_needs_changing = false;
|
||||
TALLOC_FREE(lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to a remote server for (inter)domain security authenticaion.
|
||||
*
|
||||
|
@ -43,7 +43,8 @@ bool password_ok(const char *smb_name, DATA_BLOB password_blob);
|
||||
|
||||
/* The following definitions come from auth/auth_domain.c */
|
||||
|
||||
NTSTATUS auth_domain_init(void) ;
|
||||
void attempt_machine_password_change(void);
|
||||
NTSTATUS auth_domain_init(void);
|
||||
|
||||
/* The following definitions come from auth/auth_ntlmssp.c */
|
||||
|
||||
|
@ -51,3 +51,18 @@ NTSTATUS can_delete_directory(struct connection_struct *conn,
|
||||
{
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
bool change_to_root_user(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
struct event_context *smbd_event_context(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct messaging_context *smbd_messaging_context(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ static struct notify_queue {
|
||||
size_t buflen;
|
||||
} *notify_queue_head = NULL;
|
||||
|
||||
static struct timed_event *notify_event;
|
||||
|
||||
static bool create_send_ctx(void)
|
||||
{
|
||||
@ -214,6 +215,22 @@ void print_notify_send_messages(struct messaging_context *msg_ctx,
|
||||
num_messages = 0;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Event handler to send the messages.
|
||||
*******************************************************************/
|
||||
|
||||
static void print_notify_event_send_messages(struct event_context *event_ctx,
|
||||
struct timed_event *te,
|
||||
const struct timeval *now,
|
||||
void *private_data)
|
||||
{
|
||||
/* Remove this timed event handler. */
|
||||
TALLOC_FREE(notify_event);
|
||||
|
||||
change_to_root_user();
|
||||
print_notify_send_messages(smbd_messaging_context(), 0);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
deep copy a SPOOLSS_NOTIFY_MSG structure using a TALLOC_CTX
|
||||
*********************************************************************/
|
||||
@ -304,6 +321,15 @@ to notify_queue_head\n", msg->type, msg->field, msg->printer));
|
||||
|
||||
DLIST_ADD_END(notify_queue_head, pnqueue, struct notify_queue *);
|
||||
num_messages++;
|
||||
|
||||
if (smbd_event_context()) {
|
||||
/* Add an event for 1 second's time to send this queue. */
|
||||
notify_event = event_add_timed(smbd_event_context(), NULL,
|
||||
timeval_current_ofs(1,0),
|
||||
"print_notify",
|
||||
print_notify_event_send_messages, NULL);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void send_notify_field_values(const char *sharename, uint32 type,
|
||||
|
@ -706,7 +706,7 @@ The timeout is in milliseconds
|
||||
****************************************************************************/
|
||||
|
||||
static NTSTATUS receive_message_or_smb(TALLOC_CTX *mem_ctx, char **buffer,
|
||||
size_t *buffer_len, int timeout,
|
||||
size_t *buffer_len,
|
||||
size_t *p_unread, bool *p_encrypted)
|
||||
{
|
||||
fd_set r_fds, w_fds;
|
||||
@ -720,13 +720,8 @@ static NTSTATUS receive_message_or_smb(TALLOC_CTX *mem_ctx, char **buffer,
|
||||
|
||||
again:
|
||||
|
||||
if (timeout >= 0) {
|
||||
to.tv_sec = timeout / 1000;
|
||||
to.tv_usec = (timeout % 1000) * 1000;
|
||||
} else {
|
||||
to.tv_sec = SMBD_SELECT_TIMEOUT;
|
||||
to.tv_usec = 0;
|
||||
}
|
||||
to.tv_sec = SMBD_SELECT_TIMEOUT;
|
||||
to.tv_usec = 0;
|
||||
|
||||
/*
|
||||
* Note that this call must be before processing any SMB
|
||||
@ -869,7 +864,7 @@ static NTSTATUS receive_message_or_smb(TALLOC_CTX *mem_ctx, char **buffer,
|
||||
|
||||
/* Did we timeout ? */
|
||||
if (selrtn == 0) {
|
||||
return NT_STATUS_IO_TIMEOUT;
|
||||
goto again;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1836,23 +1831,6 @@ void chain_reply(struct smb_request *req)
|
||||
return;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Setup the needed select timeout in milliseconds.
|
||||
****************************************************************************/
|
||||
|
||||
static int setup_select_timeout(void)
|
||||
{
|
||||
int select_timeout;
|
||||
|
||||
select_timeout = SMBD_SELECT_TIMEOUT*1000;
|
||||
|
||||
if (print_notify_messages_pending()) {
|
||||
select_timeout = MIN(select_timeout, 1000);
|
||||
}
|
||||
|
||||
return select_timeout;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Check if services need reloading.
|
||||
****************************************************************************/
|
||||
@ -1906,114 +1884,19 @@ void check_reload(time_t t)
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Process any timeout housekeeping. Return False if the caller should exit.
|
||||
****************************************************************************/
|
||||
|
||||
static void timeout_processing(int *select_timeout,
|
||||
time_t *last_timeout_processing_time)
|
||||
{
|
||||
time_t t;
|
||||
|
||||
*last_timeout_processing_time = t = time(NULL);
|
||||
|
||||
/* become root again if waiting */
|
||||
change_to_root_user();
|
||||
|
||||
/* check if we need to reload services */
|
||||
check_reload(t);
|
||||
|
||||
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;
|
||||
void *lock;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
lock = secrets_get_trust_account_lock(NULL, lp_workgroup());
|
||||
|
||||
if (lock == NULL) {
|
||||
DEBUG(0,("process: unable to lock the machine account password for \
|
||||
machine %s in domain %s.\n", global_myname(), lp_workgroup() ));
|
||||
return;
|
||||
}
|
||||
|
||||
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()));
|
||||
TALLOC_FREE(lock);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure someone else hasn't already done this.
|
||||
*/
|
||||
|
||||
if(t < lct + lp_machine_password_timeout()) {
|
||||
global_machine_password_needs_changing = False;
|
||||
TALLOC_FREE(lock);
|
||||
return;
|
||||
}
|
||||
|
||||
/* always just contact the PDC here */
|
||||
|
||||
change_trust_account_password( lp_workgroup(), NULL);
|
||||
global_machine_password_needs_changing = False;
|
||||
TALLOC_FREE(lock);
|
||||
}
|
||||
|
||||
/* update printer queue caches if necessary */
|
||||
|
||||
update_monitored_printq_cache();
|
||||
|
||||
/*
|
||||
* 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(smbd_messaging_context(), 0);
|
||||
|
||||
/*
|
||||
* Modify the select timeout depending upon
|
||||
* what we have remaining in our queues.
|
||||
*/
|
||||
|
||||
*select_timeout = setup_select_timeout();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Process commands from the client
|
||||
****************************************************************************/
|
||||
|
||||
void smbd_process(void)
|
||||
{
|
||||
time_t last_timeout_processing_time = time(NULL);
|
||||
unsigned int num_smbs = 0;
|
||||
size_t unread_bytes = 0;
|
||||
|
||||
max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
|
||||
|
||||
while (True) {
|
||||
int select_timeout = setup_select_timeout();
|
||||
int num_echos;
|
||||
NTSTATUS status;
|
||||
char *inbuf = NULL;
|
||||
size_t inbuf_len = 0;
|
||||
bool encrypted = false;
|
||||
@ -2021,82 +1904,24 @@ void smbd_process(void)
|
||||
|
||||
errno = 0;
|
||||
|
||||
/* Did someone ask for immediate checks on things like blocking locks ? */
|
||||
if (select_timeout == 0) {
|
||||
timeout_processing(&select_timeout,
|
||||
&last_timeout_processing_time);
|
||||
num_smbs = 0; /* Reset smb counter. */
|
||||
}
|
||||
|
||||
run_events(smbd_event_context(), 0, NULL, NULL);
|
||||
|
||||
while (True) {
|
||||
NTSTATUS status;
|
||||
|
||||
status = receive_message_or_smb(
|
||||
talloc_tos(), &inbuf, &inbuf_len,
|
||||
select_timeout, &unread_bytes, &encrypted);
|
||||
|
||||
if (NT_STATUS_IS_OK(status)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
|
||||
timeout_processing(
|
||||
&select_timeout,
|
||||
&last_timeout_processing_time);
|
||||
continue;
|
||||
}
|
||||
status = receive_message_or_smb(
|
||||
talloc_tos(), &inbuf, &inbuf_len,
|
||||
&unread_bytes, &encrypted);
|
||||
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
DEBUG(3, ("receive_message_or_smb failed: %s, "
|
||||
"exiting\n", nt_errstr(status)));
|
||||
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;
|
||||
|
||||
process_smb(inbuf, inbuf_len, unread_bytes, encrypted);
|
||||
|
||||
TALLOC_FREE(inbuf);
|
||||
|
||||
if (smb_echo_count != num_echos) {
|
||||
timeout_processing(&select_timeout,
|
||||
&last_timeout_processing_time);
|
||||
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)) {
|
||||
timeout_processing(
|
||||
&select_timeout,
|
||||
&last_timeout_processing_time);
|
||||
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.
|
||||
|
@ -29,7 +29,6 @@
|
||||
/* look in server.c for some explanation of these variables */
|
||||
extern enum protocol_types Protocol;
|
||||
extern int max_recv;
|
||||
unsigned int smb_echo_count = 0;
|
||||
extern uint32 global_client_caps;
|
||||
|
||||
extern bool global_encrypted_passwords_negotiated;
|
||||
@ -4611,8 +4610,6 @@ void reply_echo(struct smb_request *req)
|
||||
|
||||
TALLOC_FREE(req->outbuf);
|
||||
|
||||
smb_echo_count++;
|
||||
|
||||
END_PROFILE(SMBecho);
|
||||
return;
|
||||
}
|
||||
|
@ -1067,6 +1067,30 @@ static bool deadtime_fn(const struct timeval *now, void *private_data)
|
||||
return True;
|
||||
}
|
||||
|
||||
/*
|
||||
* Do the recurring log file and smb.conf reload checks.
|
||||
*/
|
||||
|
||||
static bool housekeeping_fn(const struct timeval *now, void *private_data)
|
||||
{
|
||||
change_to_root_user();
|
||||
|
||||
/* update printer queue caches if necessary */
|
||||
update_monitored_printq_cache();
|
||||
|
||||
/* check if we need to reload services */
|
||||
check_reload(time(NULL));
|
||||
|
||||
/* Change machine password if neccessary. */
|
||||
attempt_machine_password_change();
|
||||
|
||||
/*
|
||||
* Force a log file check.
|
||||
*/
|
||||
force_check_log_size();
|
||||
check_log_size();
|
||||
return true;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
main program.
|
||||
@ -1426,6 +1450,13 @@ extern void build_options(bool screen);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!(event_add_idle(smbd_event_context(), NULL,
|
||||
timeval_set(SMBD_SELECT_TIMEOUT, 0),
|
||||
"housekeeping", housekeeping_fn, NULL))) {
|
||||
DEBUG(0, ("Could not add housekeeping event\n"));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#ifdef CLUSTER_SUPPORT
|
||||
|
||||
if (lp_clustering()) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user