From 4ace291278d9a44f5c577bdd3b282c1231e543df Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 28 Jul 2006 22:42:39 +0000 Subject: [PATCH] r17293: After the results from the cluster tests in Germany, fix the messaging code to call the efficient calls : save_re_uid() set_effective_uid(0); messaging_op restore_re_uid(); instead of using heavyweight become_root()/unbecome_root() pairs around all messaging code. Fixup the messaging code to ensure sec_init() is called (only once) so that non-root processes still work when sending messages. This is a lighter weight solution to become_root()/unbecome_root() (which swaps all the supplemental groups) and should be more efficient. I will migrate all server code over to using this (a similar technique should be used in the passdb backend where needed). Jeremy. --- source/lib/messages.c | 28 ++++++++++++++++++++++++---- source/lib/tallocmsg.c | 2 -- source/lib/util_sec.c | 10 ++++++++-- source/locking/brlock.c | 6 ------ source/locking/locking.c | 2 -- source/printing/printing.c | 2 -- source/rpc_server/srv_srvsvc_nt.c | 9 --------- source/smbd/blocking.c | 3 --- source/smbd/close.c | 2 -- source/smbd/open.c | 2 -- source/smbd/oplock.c | 11 ----------- 11 files changed, 32 insertions(+), 45 deletions(-) diff --git a/source/lib/messages.c b/source/lib/messages.c index 57e4514b588..bae40529645 100644 --- a/source/lib/messages.c +++ b/source/lib/messages.c @@ -117,7 +117,10 @@ static void ping_message(int msg_type, struct process_id src, BOOL message_init(void) { - if (tdb) return True; + sec_init(); + + if (tdb) + return True; tdb = tdb_open_log(lock_path("messages.tdb"), 0, TDB_CLEAR_IF_FIRST|TDB_DEFAULT, @@ -164,6 +167,10 @@ static TDB_DATA message_key_pid(struct process_id pid) static BOOL message_notify(struct process_id procid) { pid_t pid = procid.pid; + int saved_errno; + int ret; + uid_t euid = geteuid(); + /* * Doing kill with a non-positive pid causes messages to be * sent to places we don't want. @@ -171,15 +178,28 @@ static BOOL message_notify(struct process_id procid) SMB_ASSERT(pid > 0); - if (kill(pid, SIGUSR1) == -1) { - if (errno == ESRCH) { + if (euid != 0) { + save_re_uid(); + set_effective_uid(0); + } + + ret = kill(pid, SIGUSR1); + saved_errno = errno; + + if (euid != 0) { + restore_re_uid(); + } + + if (ret == -1) { + if (saved_errno == ESRCH) { DEBUG(2,("pid %d doesn't exist - deleting messages record\n", (int)pid)); tdb_delete(tdb, message_key_pid(procid)); } else { - DEBUG(2,("message to process %d failed - %s\n", (int)pid, strerror(errno))); + DEBUG(2,("message to process %d failed - %s\n", (int)pid, strerror(saved_errno))); } return False; } + return True; } diff --git a/source/lib/tallocmsg.c b/source/lib/tallocmsg.c index b515093cd69..e4364f1ff72 100644 --- a/source/lib/tallocmsg.c +++ b/source/lib/tallocmsg.c @@ -44,10 +44,8 @@ void msg_pool_usage(int msg_type, struct process_id src_pid, return; } - become_root(); message_send_pid(src_pid, MSG_POOL_USAGE, reply, strlen(reply)+1, True); - unbecome_root(); SAFE_FREE(reply); } diff --git a/source/lib/util_sec.c b/source/lib/util_sec.c index 26be27ea515..c13b20ec927 100644 --- a/source/lib/util_sec.c +++ b/source/lib/util_sec.c @@ -52,10 +52,16 @@ static gid_t initial_gid; remember what uid we got started as - this allows us to run correctly as non-root while catching trapdoor systems ****************************************************************************/ + void sec_init(void) { - initial_uid = geteuid(); - initial_gid = getegid(); + static int initialized; + + if (!initialized) { + initial_uid = geteuid(); + initial_gid = getegid(); + initialized = 1; + } } /**************************************************************************** diff --git a/source/locking/brlock.c b/source/locking/brlock.c index 031836ecdfa..4a36d938add 100644 --- a/source/locking/brlock.c +++ b/source/locking/brlock.c @@ -816,11 +816,9 @@ static BOOL brl_unlock_windows(struct byte_range_lock *br_lck, const struct lock DEBUG(10,("brl_unlock: sending unlock message to pid %s\n", procid_str_static(&pend_lock->context.pid ))); - become_root(); message_send_pid(pend_lock->context.pid, MSG_SMB_UNLOCK, NULL, 0, True); - unbecome_root(); } } @@ -985,11 +983,9 @@ static BOOL brl_unlock_posix(struct byte_range_lock *br_lck, const struct lock_s DEBUG(10,("brl_unlock: sending unlock message to pid %s\n", procid_str_static(&pend_lock->context.pid ))); - become_root(); message_send_pid(pend_lock->context.pid, MSG_SMB_UNLOCK, NULL, 0, True); - unbecome_root(); } } @@ -1306,11 +1302,9 @@ void brl_close_fnum(struct byte_range_lock *br_lck) /* We could send specific lock info here... */ if (brl_pending_overlap(lock, pend_lock)) { - become_root(); message_send_pid(pend_lock->context.pid, MSG_SMB_UNLOCK, NULL, 0, True); - unbecome_root(); } } diff --git a/source/locking/locking.c b/source/locking/locking.c index 3cbf318007a..3879d40cbab 100644 --- a/source/locking/locking.c +++ b/source/locking/locking.c @@ -851,10 +851,8 @@ BOOL rename_share_filename(struct share_mode_lock *lck, (unsigned int)lck->dev, (double)lck->ino, lck->servicepath, lck->filename )); - become_root(); message_send_pid(se->pid, MSG_SMB_FILE_RENAME, frm, msg_len, True); - unbecome_root(); } return True; diff --git a/source/printing/printing.c b/source/printing/printing.c index bb756c88707..fbb81665650 100644 --- a/source/printing/printing.c +++ b/source/printing/printing.c @@ -1535,10 +1535,8 @@ static void print_queue_update(int snum, BOOL force) /* finally send the message */ - become_root(); message_send_pid(pid_to_procid(background_lpq_updater_pid), MSG_PRINTER_UPDATE, buffer, len, False); - unbecome_root(); SAFE_FREE( buffer ); diff --git a/source/rpc_server/srv_srvsvc_nt.c b/source/rpc_server/srv_srvsvc_nt.c index e4e5bde2157..de3148aae89 100644 --- a/source/rpc_server/srv_srvsvc_nt.c +++ b/source/rpc_server/srv_srvsvc_nt.c @@ -1303,7 +1303,6 @@ WERROR _srv_net_sess_del(pipes_struct *p, SRV_Q_NET_SESS_DEL *q_u, SRV_R_NET_SES int num_sessions, snum; fstring username; fstring machine; - BOOL not_root = False; rpcstr_pull_unistr2_fstring(username, &q_u->uni_user_name); rpcstr_pull_unistr2_fstring(machine, &q_u->uni_cli_name); @@ -1332,16 +1331,8 @@ WERROR _srv_net_sess_del(pipes_struct *p, SRV_Q_NET_SESS_DEL *q_u, SRV_R_NET_SES if ((strequal(session_list[snum].username, username) || username[0] == '\0' ) && strequal(session_list[snum].remote_machine, machine)) { - if (p->pipe_user.ut.uid != sec_initial_uid()) { - not_root = True; - become_root(); - } - if (message_send_pid(pid_to_procid(session_list[snum].pid), MSG_SHUTDOWN, NULL, 0, False)) r_u->status = WERR_OK; - - if (not_root) - unbecome_root(); } } diff --git a/source/smbd/blocking.c b/source/smbd/blocking.c index a0b93f50320..ed57c9f6216 100644 --- a/source/smbd/blocking.c +++ b/source/smbd/blocking.c @@ -837,9 +837,6 @@ BOOL blocking_lock_cancel(files_struct *fsp, memcpy(msg, &blr, sizeof(blr)); memcpy(&msg[sizeof(blr)], &err, sizeof(NTSTATUS)); - /* Don't need to be root here as we're only ever - sending to ourselves. */ - message_send_pid(pid_to_procid(sys_getpid()), MSG_SMB_BLOCKING_LOCK_CANCEL, &msg, sizeof(msg), True); diff --git a/source/smbd/close.c b/source/smbd/close.c index 08e4a24a562..a3ddcae11d0 100644 --- a/source/smbd/close.c +++ b/source/smbd/close.c @@ -134,10 +134,8 @@ static void notify_deferred_opens(struct share_mode_lock *lck) share_mode_entry_to_message(msg, e); - become_root(); message_send_pid(e->pid, MSG_SMB_OPEN_RETRY, msg, MSG_SMB_SHARE_MODE_ENTRY_SIZE, True); - unbecome_root(); } } } diff --git a/source/smbd/open.c b/source/smbd/open.c index ef59da64473..5c10c590549 100644 --- a/source/smbd/open.c +++ b/source/smbd/open.c @@ -713,10 +713,8 @@ static BOOL delay_for_oplocks(struct share_mode_lock *lck, SSVAL(msg,6,exclusive->op_type | FORCE_OPLOCK_BREAK_TO_NONE); } - become_root(); ret = message_send_pid(exclusive->pid, MSG_SMB_BREAK_REQUEST, msg, MSG_SMB_SHARE_MODE_ENTRY_SIZE, True); - unbecome_root(); if (!ret) { DEBUG(3, ("Could not send oplock break message\n")); } diff --git a/source/smbd/oplock.c b/source/smbd/oplock.c index 99ce79296fd..d9850ee051c 100644 --- a/source/smbd/oplock.c +++ b/source/smbd/oplock.c @@ -504,13 +504,10 @@ static void process_oplock_break_message(int msg_type, struct process_id src, * get to process this message, we have closed the file. Reply * with 'ok, oplock broken' */ DEBUG(3, ("Did not find fsp\n")); - become_root(); /* We just send the same message back. */ message_send_pid(src, MSG_SMB_BREAK_RESPONSE, buf, MSG_SMB_SHARE_MODE_ENTRY_SIZE, True); - - unbecome_root(); return; } @@ -529,13 +526,9 @@ static void process_oplock_break_message(int msg_type, struct process_id src, DEBUG(3, ("Already downgraded oplock on 0x%x/%.0f: %s\n", (unsigned int)fsp->dev, (double)fsp->inode, fsp->fsp_name)); - become_root(); - /* We just send the same message back. */ message_send_pid(src, MSG_SMB_BREAK_RESPONSE, buf, MSG_SMB_SHARE_MODE_ENTRY_SIZE, True); - - unbecome_root(); return; } @@ -656,7 +649,6 @@ void reply_to_oplock_break_requests(files_struct *fsp) { int i; - become_root(); for (i=0; inum_pending_break_messages; i++) { struct share_mode_entry *e = &fsp->pending_break_messages[i]; char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE]; @@ -666,7 +658,6 @@ void reply_to_oplock_break_requests(files_struct *fsp) message_send_pid(e->pid, MSG_SMB_BREAK_RESPONSE, msg, MSG_SMB_SHARE_MODE_ENTRY_SIZE, True); } - unbecome_root(); SAFE_FREE(fsp->pending_break_messages); fsp->num_pending_break_messages = 0; @@ -801,10 +792,8 @@ void release_level_2_oplocks_on_change(files_struct *fsp) share_mode_entry_to_message(msg, share_entry); - become_root(); message_send_pid(share_entry->pid, MSG_SMB_ASYNC_LEVEL2_BREAK, msg, MSG_SMB_SHARE_MODE_ENTRY_SIZE, True); - unbecome_root(); } /* We let the message receivers handle removing the oplock state