From a834a73e341059be154426390304a42e4a011f72 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 25 Sep 2002 15:19:00 +0000 Subject: sync'ing up for 3.0alpha20 release (This used to be commit 65e7b5273bb58802bf0c389b77f7fcae0a1f6139) --- source3/smbd/process.c | 288 +++++++++++++++++++++++++------------------------ 1 file changed, 147 insertions(+), 141 deletions(-) (limited to 'source3/smbd/process.c') diff --git a/source3/smbd/process.c b/source3/smbd/process.c index 55234ec896..0f7cfd0e9c 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -42,8 +42,8 @@ extern int last_message; extern int global_oplock_break; extern userdom_struct current_user_info; extern int smb_read_error; -SIG_ATOMIC_T reload_after_sighup; -SIG_ATOMIC_T got_sig_term; +SIG_ATOMIC_T reload_after_sighup = 0; +SIG_ATOMIC_T got_sig_term = 0; extern BOOL global_machine_password_needs_changing; extern fstring global_myworkgroup; extern pstring global_myname; @@ -609,8 +609,9 @@ const static struct smb_message_struct }; /******************************************************************* -dump a prs to a file - ********************************************************************/ + Dump a packet to a file. +********************************************************************/ + static void smb_dump(const char *name, int type, char *data, ssize_t len) { int fd, i; @@ -635,178 +636,171 @@ static void smb_dump(const char *name, int type, char *data, ssize_t len) /**************************************************************************** -do a switch on the message type, and return the response size + Do a switch on the message type, and return the response size ****************************************************************************/ + static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize) { - static pid_t pid= (pid_t)-1; - int outsize = 0; - extern uint16 global_smbpid; - - type &= 0xff; + static pid_t pid= (pid_t)-1; + int outsize = 0; + extern uint16 global_smbpid; - if (pid == (pid_t)-1) - pid = sys_getpid(); + type &= 0xff; - errno = 0; - last_message = type; - - /* make sure this is an SMB packet */ - if (strncmp(smb_base(inbuf),"\377SMB",4) != 0) - { - DEBUG(2,("Non-SMB packet of length %d\n",smb_len(inbuf))); - return(-1); - } + if (pid == (pid_t)-1) + pid = sys_getpid(); - /* yuck! this is an interim measure before we get rid of our - current inbuf/outbuf system */ - global_smbpid = SVAL(inbuf,smb_pid); + errno = 0; + last_message = type; - if (smb_messages[type].fn == NULL) - { - DEBUG(0,("Unknown message type %d!\n",type)); - smb_dump("Unknown", 1, inbuf, size); - outsize = reply_unknown(inbuf,outbuf); - } - else - { - int flags = smb_messages[type].flags; - static uint16 last_session_tag = UID_FIELD_INVALID; - /* In share mode security we must ignore the vuid. */ - uint16 session_tag = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID : SVAL(inbuf,smb_uid); - connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); + /* Make sure this is an SMB packet. smb_size contains NetBIOS header so subtract 4 from it. */ + if ((strncmp(smb_base(inbuf),"\377SMB",4) != 0) || (size < (smb_size - 4))) { + DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",smb_len(inbuf))); + exit_server("Non-SMB packet"); + return(-1); + } - DEBUG(3,("switch message %s (pid %d)\n",smb_fn_name(type),(int)pid)); + /* yuck! this is an interim measure before we get rid of our + current inbuf/outbuf system */ + global_smbpid = SVAL(inbuf,smb_pid); + + if (smb_messages[type].fn == NULL) { + DEBUG(0,("Unknown message type %d!\n",type)); + smb_dump("Unknown", 1, inbuf, size); + outsize = reply_unknown(inbuf,outbuf); + } else { + int flags = smb_messages[type].flags; + static uint16 last_session_tag = UID_FIELD_INVALID; + /* In share mode security we must ignore the vuid. */ + uint16 session_tag = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID : SVAL(inbuf,smb_uid); + connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); + + DEBUG(3,("switch message %s (pid %d)\n",smb_fn_name(type),(int)pid)); + + smb_dump(smb_fn_name(type), 1, inbuf, size); + if(global_oplock_break) { + if(flags & QUEUE_IN_OPLOCK) { + /* + * Queue this message as we are the process of an oplock break. + */ + + DEBUG( 2, ( "switch_message: queueing message due to being in " ) ); + DEBUGADD( 2, ( "oplock break state.\n" ) ); + + push_oplock_pending_smb_message( inbuf, size ); + return -1; + } + } - smb_dump(smb_fn_name(type), 1, inbuf, size); - if(global_oplock_break) - { - if(flags & QUEUE_IN_OPLOCK) - { - /* - * Queue this message as we are the process of an oplock break. - */ - - DEBUG( 2, ( "switch_message: queueing message due to being in " ) ); - DEBUGADD( 2, ( "oplock break state.\n" ) ); - - push_oplock_pending_smb_message( inbuf, size ); - return -1; - } - } + /* Ensure this value is replaced in the incoming packet. */ + SSVAL(inbuf,smb_uid,session_tag); - /* Ensure this value is replaced in the incoming packet. */ - SSVAL(inbuf,smb_uid,session_tag); + /* + * Ensure the correct username is in current_user_info. + * This is a really ugly bugfix for problems with + * multiple session_setup_and_X's being done and + * allowing %U and %G substitutions to work correctly. + * There is a reason this code is done here, don't + * move it unless you know what you're doing... :-). + * JRA. + */ - /* - * Ensure the correct username is in current_user_info. - * This is a really ugly bugfix for problems with - * multiple session_setup_and_X's being done and - * allowing %U and %G substitutions to work correctly. - * There is a reason this code is done here, don't - * move it unless you know what you're doing... :-). - * JRA. - */ + if (session_tag != last_session_tag) { + user_struct *vuser = NULL; - if (session_tag != last_session_tag) { - user_struct *vuser = NULL; + last_session_tag = session_tag; + if(session_tag != UID_FIELD_INVALID) + vuser = get_valid_user_struct(session_tag); + if(vuser != NULL) + current_user_info = vuser->user; + } - last_session_tag = session_tag; - if(session_tag != UID_FIELD_INVALID) - vuser = get_valid_user_struct(session_tag); - if(vuser != NULL) - current_user_info = vuser->user; - } + /* does this protocol need to be run as root? */ + if (!(flags & AS_USER)) + change_to_root_user(); - /* does this protocol need to be run as root? */ - if (!(flags & AS_USER)) - change_to_root_user(); + /* does this protocol need a valid tree connection? */ + if ((flags & AS_USER) && !conn) + return ERROR_DOS(ERRSRV, ERRinvnid); - /* does this protocol need a valid tree connection? */ - if ((flags & AS_USER) && !conn) { - return ERROR_DOS(ERRSRV, ERRinvnid); - } + /* does this protocol need to be run as the connected user? */ + if ((flags & AS_USER) && !change_to_user(conn,session_tag)) { + if (flags & AS_GUEST) + flags &= ~AS_USER; + else + return(ERROR_DOS(ERRSRV,ERRaccess)); + } - /* does this protocol need to be run as the connected user? */ - if ((flags & AS_USER) && !change_to_user(conn,session_tag)) { - if (flags & AS_GUEST) - flags &= ~AS_USER; - else - return(ERROR_DOS(ERRSRV,ERRaccess)); - } - - /* this code is to work around a bug is MS client 3 without - introducing a security hole - it needs to be able to do - print queue checks as guest if it isn't logged in properly */ - if (flags & AS_USER) - flags &= ~AS_GUEST; + /* this code is to work around a bug is MS client 3 without + introducing a security hole - it needs to be able to do + print queue checks as guest if it isn't logged in properly */ + if (flags & AS_USER) + flags &= ~AS_GUEST; - /* does it need write permission? */ - if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) - return(ERROR_DOS(ERRSRV,ERRaccess)); + /* does it need write permission? */ + if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) + return(ERROR_DOS(ERRSRV,ERRaccess)); - /* ipc services are limited */ - if (IS_IPC(conn) && (flags & AS_USER) && !(flags & CAN_IPC)) { - return(ERROR_DOS(ERRSRV,ERRaccess)); - } + /* ipc services are limited */ + if (IS_IPC(conn) && (flags & AS_USER) && !(flags & CAN_IPC)) + return(ERROR_DOS(ERRSRV,ERRaccess)); - /* load service specific parameters */ - if (conn && !set_current_service(conn,(flags & AS_USER)?True:False)) { - return(ERROR_DOS(ERRSRV,ERRaccess)); - } + /* load service specific parameters */ + if (conn && !set_current_service(conn,(flags & AS_USER)?True:False)) + return(ERROR_DOS(ERRSRV,ERRaccess)); - /* does this protocol need to be run as guest? */ - if ((flags & AS_GUEST) && - (!change_to_guest() || - !check_access(smbd_server_fd(), lp_hostsallow(-1), lp_hostsdeny(-1)))) { - return(ERROR_DOS(ERRSRV,ERRaccess)); - } + /* does this protocol need to be run as guest? */ + if ((flags & AS_GUEST) && (!change_to_guest() || + !check_access(smbd_server_fd(), lp_hostsallow(-1), lp_hostsdeny(-1)))) + return(ERROR_DOS(ERRSRV,ERRaccess)); - last_inbuf = inbuf; + last_inbuf = inbuf; - outsize = smb_messages[type].fn(conn, inbuf,outbuf,size,bufsize); - } + outsize = smb_messages[type].fn(conn, inbuf,outbuf,size,bufsize); + } - smb_dump(smb_fn_name(type), 0, outbuf, outsize); + smb_dump(smb_fn_name(type), 0, outbuf, outsize); - return(outsize); + return(outsize); } /**************************************************************************** - construct a reply to the incoming packet + Construct a reply to the incoming packet. ****************************************************************************/ + static int construct_reply(char *inbuf,char *outbuf,int size,int bufsize) { - int type = CVAL(inbuf,smb_com); - int outsize = 0; - int msg_type = CVAL(inbuf,0); + int type = CVAL(inbuf,smb_com); + int outsize = 0; + int msg_type = CVAL(inbuf,0); - GetTimeOfDay(&smb_last_time); + GetTimeOfDay(&smb_last_time); - chain_size = 0; - file_chain_reset(); - reset_chain_p(); + chain_size = 0; + file_chain_reset(); + reset_chain_p(); - if (msg_type != 0) - return(reply_special(inbuf,outbuf)); + if (msg_type != 0) + return(reply_special(inbuf,outbuf)); - construct_reply_common(inbuf, outbuf); + construct_reply_common(inbuf, outbuf); - outsize = switch_message(type,inbuf,outbuf,size,bufsize); + outsize = switch_message(type,inbuf,outbuf,size,bufsize); - outsize += chain_size; + outsize += chain_size; - if(outsize > 4) - smb_setlen(outbuf,outsize - 4); - return(outsize); + if(outsize > 4) + smb_setlen(outbuf,outsize - 4); + return(outsize); } /**************************************************************************** - Keep track of the number of running smbd's. This functionality is used to - 'hard' limit Samba overhead on resource constrained systems. + Keep track of the number of running smbd's. This functionality is used to + 'hard' limit Samba overhead on resource constrained systems. ****************************************************************************/ + static BOOL smbd_process_limit(void) { int32 total_smbds; @@ -1032,16 +1026,15 @@ static int setup_select_timeout(void) int select_timeout; int t; - /* - * Increase the select timeout back to SMBD_SELECT_TIMEOUT if we - * have removed any blocking locks. JRA. - */ - - select_timeout = blocking_locks_pending() ? SMBD_SELECT_TIMEOUT_WITH_PENDING_LOCKS*1000 : - SMBD_SELECT_TIMEOUT*1000; + select_timeout = blocking_locks_timeout(SMBD_SELECT_TIMEOUT); + select_timeout *= 1000; t = change_notify_timeout(); - if (t != -1) select_timeout = MIN(select_timeout, t*1000); + if (t != -1) + select_timeout = MIN(select_timeout, t*1000); + + if (print_notify_messages_pending()) + select_timeout = MIN(select_timeout, 1000); return select_timeout; } @@ -1161,9 +1154,16 @@ static BOOL timeout_processing(int deadtime, int *select_timeout, time_t *last_t * First, open the machine password file with an exclusive lock. */ + if (secrets_lock_trust_account_password(global_myworkgroup, True) == False) { + DEBUG(0,("process: unable to lock the machine account password for \ +machine %s in domain %s.\n", global_myname, global_myworkgroup )); + return True; + } + if(!secrets_fetch_trust_account_password(global_myworkgroup, trust_passwd_hash, &lct)) { DEBUG(0,("process: unable to read the machine account password for \ machine %s in domain %s.\n", global_myname, global_myworkgroup )); + secrets_lock_trust_account_password(global_myworkgroup, False); return True; } @@ -1173,6 +1173,7 @@ machine %s in domain %s.\n", global_myname, global_myworkgroup )); if(t < lct + lp_machine_password_timeout()) { global_machine_password_needs_changing = False; + secrets_lock_trust_account_password(global_myworkgroup, False); return True; } @@ -1180,6 +1181,7 @@ machine %s in domain %s.\n", global_myname, global_myworkgroup )); change_trust_account_password( global_myworkgroup, remote_machine_list); global_machine_password_needs_changing = False; + secrets_lock_trust_account_password(global_myworkgroup, False); } /* @@ -1201,6 +1203,10 @@ machine %s in domain %s.\n", global_myname, global_myworkgroup )); force_check_log_size(); check_log_size(); + /* Send any queued printer notify message to interested smbd's. */ + + print_notify_send_messages(); + /* * Modify the select timeout depending upon * what we have remaining in our queues. -- cgit