From: Stefan Metzmacher Date: Fri, 11 May 2012 13:51:42 +0000 (+0200) Subject: smbd: implement smbd_impersonate_{conn_vuid,conn_sess,root,guest}_create() wrappers X-Git-Tag: ldb-1.5.0~341 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1b804f7ae23f54a6c1004e5ff17b9df1376b5adb;p=thirdparty%2Fsamba.git smbd: implement smbd_impersonate_{conn_vuid,conn_sess,root,guest}_create() wrappers This makes sure we're doing the correct impersonation for async requests, which is a requirement to start adding path based async SMB_VFS calls. Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme --- diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 9799f8b59dd..fcc4d51a698 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -974,52 +974,961 @@ uint64_t get_current_vuid(connection_struct *conn) return current_user.vuid; } +struct smbd_impersonate_conn_vuid_state { + struct connection_struct *conn; + uint64_t vuid; +}; + +static bool smbd_impersonate_conn_vuid_before_use( + struct tevent_context *wrap_ev, + void *private_data, + struct tevent_context *main_ev, + const char *location) +{ + struct smbd_impersonate_conn_vuid_state *state = + talloc_get_type_abort(private_data, + struct smbd_impersonate_conn_vuid_state); + bool ok; + + DEBUG(11,("%s: wrap_ev[%p] main_ev[%p] location[%s]" + "old uid[%ju] old gid[%ju] vuid[%ju] cwd[%s]\n", + __func__, wrap_ev, main_ev, location, + (uintmax_t)geteuid(), (uintmax_t)getegid(), + (uintmax_t)state->vuid, state->conn->cwd_fname->base_name)); + + ok = become_user(state->conn, state->vuid); + if (!ok) { + smb_panic("smbd_impersonate_conn_vuid_before_use() - failed"); + return false; + } + + DEBUG(11,("%s: impersonated user[%s] uid[%ju] gid[%ju] cwd[%s]\n", + __func__, state->conn->session_info->unix_info->unix_name, + (uintmax_t)geteuid(), (uintmax_t)getegid(), + state->conn->cwd_fname->base_name)); + + return true; +} + +static void smbd_impersonate_conn_vuid_after_use( + struct tevent_context *wrap_ev, + void *private_data, + struct tevent_context *main_ev, + const char *location) +{ + struct smbd_impersonate_conn_vuid_state *state = + talloc_get_type_abort(private_data, + struct smbd_impersonate_conn_vuid_state); + bool ok; + + DEBUG(11,("%s: deimpersonating[%s] uid[%ju] gid[%ju] cwd[%s] " + "location[%s]\n", + __func__, state->conn->session_info->unix_info->unix_name, + (uintmax_t)geteuid(), (uintmax_t)getegid(), + state->conn->cwd_fname->base_name, location)); + + ok = unbecome_user(); + if (!ok) { + smb_panic("smbd_impersonate_conn_vuid_after_use() - failed"); + return; + } + + DEBUG(11,("%s: impersonated user[%s] uid[%ju] gid[%ju] cwd[%s]\n", + __func__, state->conn->session_info->unix_info->unix_name, + (uintmax_t)geteuid(), (uintmax_t)getegid(), + state->conn->cwd_fname->base_name)); +} + +static void smbd_impersonate_conn_vuid_before_fd_handler( + struct tevent_context *wrap_ev, + void *private_data, + struct tevent_context *main_ev, + struct tevent_fd *fde, + uint16_t flags, + const char *handler_name, + const char *location) +{ + struct smbd_impersonate_conn_vuid_state *state = talloc_get_type_abort( + private_data, struct smbd_impersonate_conn_vuid_state); + bool ok; + + DEBUG(11,("%s: fde[%p] flags[%ju] handler_name[%s] location[%s]\n", + __func__, fde, (uintmax_t)flags, handler_name, location)); + + ok = change_to_user(state->conn, state->vuid); + if (!ok) { + smb_panic("smbd_impersonate_conn_vuid_before_use() - failed"); + return; + } + + DEBUG(11,("%s: impersonated user[%s] uid[%ju] gid[%ju] cwd[%s]\n", + __func__, state->conn->session_info->unix_info->unix_name, + (uintmax_t)geteuid(), (uintmax_t)getegid(), + state->conn->cwd_fname->base_name)); +} + +static void smbd_impersonate_conn_vuid_after_fd_handler( + struct tevent_context *wrap_ev, + void *private_data, + struct tevent_context *main_ev, + struct tevent_fd *fde, + uint16_t flags, + const char *handler_name, + const char *location) +{ + DEBUG(11,("%s: fde[%p] handler_name[%s] location[%s]\n", + __func__, fde, handler_name, location)); + + /* be lazy and defer change_to_root_user() */ +} + +static void smbd_impersonate_conn_vuid_before_timer_handler( + struct tevent_context *wrap_ev, + void *private_data, + struct tevent_context *main_ev, + struct tevent_timer *te, + struct timeval requested_time, + struct timeval trigger_time, + const char *handler_name, + const char *location) +{ + struct smbd_impersonate_conn_vuid_state *state = talloc_get_type_abort( + private_data, struct smbd_impersonate_conn_vuid_state); + struct timeval_buf requested_buf; + struct timeval_buf trigger_buf; + bool ok; + + DEBUG(11,("%s: te[%p] requested_time[%s] trigger_time[%s] " + "handler_name[%s] location[%s]\n", + __func__, te, + timeval_str_buf(&requested_time, true, true, &requested_buf), + timeval_str_buf(&trigger_time, true, true, &trigger_buf), + handler_name, location)); + + ok = change_to_user(state->conn, state->vuid); + if (!ok) { + smb_panic("smbd_impersonate_conn_vuid_before_use() - failed"); + return; + } + + DEBUG(11,("%s: impersonated user[%s] uid[%ju] gid[%ju] cwd[%s]\n", + __func__, state->conn->session_info->unix_info->unix_name, + (uintmax_t)geteuid(), (uintmax_t)getegid(), + state->conn->cwd_fname->base_name)); +} + +static void smbd_impersonate_conn_vuid_after_timer_handler( + struct tevent_context *wrap_ev, + void *private_data, + struct tevent_context *main_ev, + struct tevent_timer *te, + struct timeval requested_time, + struct timeval trigger_time, + const char *handler_name, + const char *location) +{ + DEBUG(11,("%s: te[%p] handler_name[%s] location[%s]\n", + __func__, te, handler_name, location)); + + /* be lazy and defer change_to_root_user() */ +} + +static void smbd_impersonate_conn_vuid_before_immediate_handler( + struct tevent_context *wrap_ev, + void *private_data, + struct tevent_context *main_ev, + struct tevent_immediate *im, + const char *handler_name, + const char *location) +{ + struct smbd_impersonate_conn_vuid_state *state = talloc_get_type_abort( + private_data, struct smbd_impersonate_conn_vuid_state); + bool ok; + + DEBUG(11,("%s: im[%p] handler_name[%s] location[%s]\n", + __func__, im, handler_name, location)); + + ok = change_to_user(state->conn, state->vuid); + if (!ok) { + smb_panic("smbd_impersonate_conn_vuid_before_use() - failed"); + return; + } + + DEBUG(11,("%s: impersonated user[%s] uid[%ju] gid[%ju] cwd[%s]\n", + __func__, state->conn->session_info->unix_info->unix_name, + (uintmax_t)geteuid(), (uintmax_t)getegid(), + state->conn->cwd_fname->base_name)); +} + +static void smbd_impersonate_conn_vuid_after_immediate_handler( + struct tevent_context *wrap_ev, + void *private_data, + struct tevent_context *main_ev, + struct tevent_immediate *im, + const char *handler_name, + const char *location) +{ + DEBUG(11,("%s: im[%p] handler_name[%s] location[%s]\n", + __func__, im, handler_name, location)); + + /* be lazy and defer unbecome_user() */ +} + +static void smbd_impersonate_conn_vuid_before_signal_handler( + struct tevent_context *wrap_ev, + void *private_data, + struct tevent_context *main_ev, + struct tevent_signal *se, + int signum, + int count, + void *siginfo, + const char *handler_name, + const char *location) +{ + struct smbd_impersonate_conn_vuid_state *state = talloc_get_type_abort( + private_data, struct smbd_impersonate_conn_vuid_state); + bool ok; + + DEBUG(11,("%s: se[%p] signum[%d] count[%d] siginfo[%p] " + "handler_name[%s] location[%s]\n", + __func__, se, signum, count, siginfo, handler_name, location)); + + ok = change_to_user(state->conn, state->vuid); + if (!ok) { + smb_panic("smbd_impersonate_conn_vuid_before_use() - failed"); + return; + } + + DEBUG(11,("%s: impersonated user[%s] uid[%ju] gid[%ju] cwd[%s]\n", + __func__, state->conn->session_info->unix_info->unix_name, + (uintmax_t)geteuid(), (uintmax_t)getegid(), + state->conn->cwd_fname->base_name)); +} + +static void smbd_impersonate_conn_vuid_after_signal_handler( + struct tevent_context *wrap_ev, + void *private_data, + struct tevent_context *main_ev, + struct tevent_signal *se, + int signum, + int count, + void *siginfo, + const char *handler_name, + const char *location) +{ + DEBUG(11,("%s: se[%p] handler_name[%s] location[%s]\n", + __func__, se, handler_name, location)); + + /* be lazy and defer change_to_root_user() */ +} + +static const struct tevent_wrapper_ops smbd_impersonate_conn_vuid_ops = { + .name = "smbd_impersonate_conn_vuid", + .before_use = smbd_impersonate_conn_vuid_before_use, + .after_use = smbd_impersonate_conn_vuid_after_use, + .before_fd_handler = smbd_impersonate_conn_vuid_before_fd_handler, + .after_fd_handler = smbd_impersonate_conn_vuid_after_fd_handler, + .before_timer_handler = smbd_impersonate_conn_vuid_before_timer_handler, + .after_timer_handler = smbd_impersonate_conn_vuid_after_timer_handler, + .before_immediate_handler = smbd_impersonate_conn_vuid_before_immediate_handler, + .after_immediate_handler = smbd_impersonate_conn_vuid_after_immediate_handler, + .before_signal_handler = smbd_impersonate_conn_vuid_before_signal_handler, + .after_signal_handler = smbd_impersonate_conn_vuid_after_signal_handler, +}; + struct tevent_context *smbd_impersonate_conn_vuid_create( struct tevent_context *main_ev, struct connection_struct *conn, uint64_t vuid) { - struct tevent_context *wrap_ev = NULL; + struct tevent_context *ev = NULL; + struct smbd_impersonate_conn_vuid_state *state = NULL; + + ev = tevent_context_wrapper_create(main_ev, + conn, + &smbd_impersonate_conn_vuid_ops, + &state, + struct smbd_impersonate_conn_vuid_state); + if (ev == NULL) { + return NULL; + } + state->conn = conn; + state->vuid = vuid; - wrap_ev = smbd_impersonate_debug_create(main_ev, - "conn_vuid", - DBGLVL_DEBUG); + return ev; +} - return wrap_ev; +struct smbd_impersonate_conn_sess_state { + struct connection_struct *conn; + struct auth_session_info *session_info; +}; + +static bool smbd_impersonate_conn_sess_before_use(struct tevent_context *wrap_ev, + void *private_data, + struct tevent_context *main_ev, + const char *location) +{ + struct smbd_impersonate_conn_sess_state *state = talloc_get_type_abort( + private_data, struct smbd_impersonate_conn_sess_state); + bool ok; + + DEBUG(11,("%s: impersonating user[%s] wrap_ev[%p] main_ev[%p] " + "location[%s] old uid[%ju] old gid[%ju] cwd[%s]\n", + __func__, state->session_info->unix_info->unix_name, + wrap_ev, main_ev, location, + (uintmax_t)geteuid(), (uintmax_t)getegid(), + state->conn->cwd_fname->base_name)); + + ok = become_user_by_session(state->conn, state->session_info); + if (!ok) { + return false; + } + + DEBUG(11,("%s: impersonated user[%s] uid[%ju] gid[%ju] cwd[%s]\n", + __func__, state->conn->session_info->unix_info->unix_name, + (uintmax_t)geteuid(), (uintmax_t)getegid(), + state->conn->cwd_fname->base_name)); + + return true; +} + +static void smbd_impersonate_conn_sess_after_use(struct tevent_context *wrap_ev, + void *private_data, + struct tevent_context *main_ev, + const char *location) +{ + struct smbd_impersonate_conn_sess_state *state = talloc_get_type_abort( + private_data, struct smbd_impersonate_conn_sess_state); + bool ok; + + DEBUG(11,("%s: deimpersonating[%s] uid[%ju] gid[%ju] cwd[%s] " + "location[%s]\n", + __func__, state->session_info->unix_info->unix_name, + (uintmax_t)geteuid(), (uintmax_t)getegid(), + state->conn->cwd_fname->base_name, location)); + + ok = unbecome_user(); + if (!ok) { + smb_panic("smbd_impersonate_conn_sess_after_use() - failed"); + return; + } + + DEBUG(11,("%s: deimpersonated user[%s] uid[%ju] gid[%ju] cwd[%s]\n", + __func__, state->conn->session_info->unix_info->unix_name, + (uintmax_t)geteuid(), (uintmax_t)getegid(), + state->conn->cwd_fname->base_name)); +} + +static void smbd_impersonate_conn_sess_before_fd_handler( + struct tevent_context *wrap_ev, + void *private_data, + struct tevent_context *main_ev, + struct tevent_fd *fde, + uint16_t flags, + const char *handler_name, + const char *location) +{ + struct smbd_impersonate_conn_sess_state *state = talloc_get_type_abort( + private_data, struct smbd_impersonate_conn_sess_state); + bool ok; + + DEBUG(11,("%s: fde[%p] flags[%ju] handler_name[%s] location[%s]\n", + __func__, fde, (uintmax_t)flags, handler_name, location)); + + ok = change_to_user_by_session(state->conn, state->session_info); + if (!ok) { + smb_panic("smbd_impersonate_conn_sess_before_fd_handler failed"); + return; + } + + DEBUG(11,("%s: impersonated user[%s] uid[%ju] gid[%ju] cwd[%s]\n", + __func__, state->conn->session_info->unix_info->unix_name, + (uintmax_t)geteuid(), (uintmax_t)getegid(), + state->conn->cwd_fname->base_name)); +} + +static void smbd_impersonate_conn_sess_after_fd_handler(struct tevent_context *wrap_ev, + void *private_data, + struct tevent_context *main_ev, + struct tevent_fd *fde, + uint16_t flags, + const char *handler_name, + const char *location) +{ + DEBUG(11,("%s: fde[%p] handler_name[%s] location[%s]\n", + __func__, fde, handler_name, location)); + + /* be lazy and defer change_to_root_user() */ +} + +static void smbd_impersonate_conn_sess_before_timer_handler( + struct tevent_context *wrap_ev, + void *private_data, + struct tevent_context *main_ev, + struct tevent_timer *te, + struct timeval requested_time, + struct timeval trigger_time, + const char *handler_name, + const char *location) +{ + struct smbd_impersonate_conn_sess_state *state = talloc_get_type_abort( + private_data, struct smbd_impersonate_conn_sess_state); + struct timeval_buf requested_buf; + struct timeval_buf trigger_buf; + bool ok; + + DEBUG(11,("%s: te[%p] requested_time[%s] trigger_time[%s] " + "handler_name[%s] location[%s]\n", + __func__, te, + timeval_str_buf(&requested_time, true, true, &requested_buf), + timeval_str_buf(&trigger_time, true, true, &trigger_buf), + handler_name, location)); + + ok = change_to_user_by_session(state->conn, state->session_info); + if (!ok) { + smb_panic("smbd_impersonate_conn_sess_before_tm_handler failed"); + return; + } + + DEBUG(11,("%s: impersonated user[%s] uid[%ju] gid[%ju] cwd[%s]\n", + __func__, state->conn->session_info->unix_info->unix_name, + (uintmax_t)geteuid(), (uintmax_t)getegid(), + state->conn->cwd_fname->base_name)); } +static void smbd_impersonate_conn_sess_after_timer_handler( + struct tevent_context *wrap_ev, + void *private_data, + struct tevent_context *main_ev, + struct tevent_timer *te, + struct timeval requested_time, + struct timeval trigger_time, + const char *handler_name, + const char *location) +{ + DEBUG(11,("%s: te[%p] handler_name[%s] location[%s]\n", + __func__, te, handler_name, location)); + + /* be lazy and defer change_to_root_user() */ +} + +static void smbd_impersonate_conn_sess_before_immediate_handler( + struct tevent_context *wrap_ev, + void *private_data, + struct tevent_context *main_ev, + struct tevent_immediate *im, + const char *handler_name, + const char *location) +{ + struct smbd_impersonate_conn_sess_state *state = talloc_get_type_abort( + private_data, struct smbd_impersonate_conn_sess_state); + bool ok; + + DEBUG(11,("%s: im[%p] handler_name[%s] location[%s]\n", + __func__, im, handler_name, location)); + + ok = change_to_user_by_session(state->conn, state->session_info); + if (!ok) { + smb_panic("smbd_impersonate_conn_sess_before_im_handler failed"); + return; + } + + DEBUG(11,("%s: impersonated user[%s] uid[%ju] gid[%ju] cwd[%s]\n", + __func__, state->conn->session_info->unix_info->unix_name, + (uintmax_t)geteuid(), (uintmax_t)getegid(), + state->conn->cwd_fname->base_name)); +} + +static void smbd_impersonate_conn_sess_after_immediate_handler( + struct tevent_context *wrap_ev, + void *private_data, + struct tevent_context *main_ev, + struct tevent_immediate *im, + const char *handler_name, + const char *location) +{ + DEBUG(11,("%s: im[%p] handler_name[%s] location[%s]\n", + __func__, im, handler_name, location)); + + /* be lazy and defer unbecome_user() */ +} + +static void smbd_impersonate_conn_sess_before_signal_handler( + struct tevent_context *wrap_ev, + void *private_data, + struct tevent_context *main_ev, + struct tevent_signal *se, + int signum, + int count, + void *siginfo, + const char *handler_name, + const char *location) +{ + struct smbd_impersonate_conn_sess_state *state = talloc_get_type_abort( + private_data, struct smbd_impersonate_conn_sess_state); + bool ok; + + DEBUG(11,("%s: se[%p] signum[%d] count[%d] siginfo[%p] " + "handler_name[%s] location[%s]\n", + __func__, se, signum, count, siginfo, handler_name, location)); + + ok = change_to_user_by_session(state->conn, state->session_info); + if (!ok) { + smb_panic("smbd_impersonate_conn_sess_before_si_handler failed"); + return; + } + + DEBUG(11,("%s: impersonated user[%s] uid[%ju] gid[%ju] cwd[%s]\n", + __func__, state->conn->session_info->unix_info->unix_name, + (uintmax_t)geteuid(), (uintmax_t)getegid(), + state->conn->cwd_fname->base_name)); +} + +static void smbd_impersonate_conn_sess_after_signal_handler( + struct tevent_context *wrap_ev, + void *private_data, + struct tevent_context *main_ev, + struct tevent_signal *se, + int signum, + int count, + void *siginfo, + const char *handler_name, + const char *location) +{ + DEBUG(11,("%s: se[%p] handler_name[%s] location[%s]\n", + __func__, se, handler_name, location)); + + /* be lazy and defer change_to_root_user() */ +} + +static const struct tevent_wrapper_ops smbd_impersonate_conn_sess_ops = { + .name = "smbd_impersonate_conn_sess", + .before_use = smbd_impersonate_conn_sess_before_use, + .after_use = smbd_impersonate_conn_sess_after_use, + .before_fd_handler = smbd_impersonate_conn_sess_before_fd_handler, + .after_fd_handler = smbd_impersonate_conn_sess_after_fd_handler, + .before_timer_handler = smbd_impersonate_conn_sess_before_timer_handler, + .after_timer_handler = smbd_impersonate_conn_sess_after_timer_handler, + .before_immediate_handler = smbd_impersonate_conn_sess_before_immediate_handler, + .after_immediate_handler = smbd_impersonate_conn_sess_after_immediate_handler, + .before_signal_handler = smbd_impersonate_conn_sess_before_signal_handler, + .after_signal_handler = smbd_impersonate_conn_sess_after_signal_handler, +}; + struct tevent_context *smbd_impersonate_conn_sess_create( struct tevent_context *main_ev, struct connection_struct *conn, struct auth_session_info *session_info) { - struct tevent_context *wrap_ev = NULL; + struct tevent_context *ev = NULL; + struct smbd_impersonate_conn_sess_state *state = NULL; + + ev = tevent_context_wrapper_create(main_ev, + conn, + &smbd_impersonate_conn_sess_ops, + &state, + struct smbd_impersonate_conn_sess_state); + if (ev == NULL) { + return NULL; + } + state->conn = conn; + state->session_info = session_info; + + return ev; +} - wrap_ev = smbd_impersonate_debug_create(main_ev, - "conn_sess", - DBGLVL_DEBUG); +struct smbd_impersonate_root_state { + uint8_t _dummy; +}; - return wrap_ev; +static bool smbd_impersonate_root_before_use(struct tevent_context *wrap_ev, + void *private_data, + struct tevent_context *main_ev, + const char *location) +{ + DEBUG(11,("%s: wrap_ev[%p] main_ev[%p] location[%s]" + "uid[%ju] gid[%ju]\n", + __func__, wrap_ev, main_ev, location, + (uintmax_t)geteuid(), (uintmax_t)getegid())); + + become_root(); + return true; +} + +static void smbd_impersonate_root_after_use(struct tevent_context *wrap_ev, + void *private_data, + struct tevent_context *main_ev, + const char *location) +{ + unbecome_root(); + + DEBUG(11,("%s: uid[%ju] gid[%ju] location[%s]\n", + __func__, (uintmax_t)geteuid(), (uintmax_t)getegid(), + location)); +} + +static void smbd_impersonate_root_before_fd_handler(struct tevent_context *wrap_ev, + void *private_data, + struct tevent_context *main_ev, + struct tevent_fd *fde, + uint16_t flags, + const char *handler_name, + const char *location) +{ + DEBUG(11,("%s: fde[%p] flags[%ju] handler_name[%s] location[%s]\n", + __func__, fde, (uintmax_t)flags, handler_name, location)); + + smbd_impersonate_root_before_use(wrap_ev, private_data, main_ev, location); +} + +static void smbd_impersonate_root_after_fd_handler(struct tevent_context *wrap_ev, + void *private_data, + struct tevent_context *main_ev, + struct tevent_fd *fde, + uint16_t flags, + const char *handler_name, + const char *location) +{ + DEBUG(11,("%s: fde[%p] handler_name[%s] location[%s]\n", + __func__, fde, handler_name, location)); + + smbd_impersonate_root_after_use(wrap_ev, private_data, main_ev, location); } +static void smbd_impersonate_root_before_timer_handler(struct tevent_context *wrap_ev, + void *private_data, + struct tevent_context *main_ev, + struct tevent_timer *te, + struct timeval requested_time, + struct timeval trigger_time, + const char *handler_name, + const char *location) +{ + struct timeval_buf requested_buf; + struct timeval_buf trigger_buf; + + DEBUG(11,("%s: te[%p] requested_time[%s] trigger_time[%s] " + "handler_name[%s] location[%s]\n", + __func__, te, + timeval_str_buf(&requested_time, true, true, &requested_buf), + timeval_str_buf(&trigger_time, true, true, &trigger_buf), + handler_name, location)); + + smbd_impersonate_root_before_use(wrap_ev, private_data, main_ev, location); +} + +static void smbd_impersonate_root_after_timer_handler(struct tevent_context *wrap_ev, + void *private_data, + struct tevent_context *main_ev, + struct tevent_timer *te, + struct timeval requested_time, + struct timeval trigger_time, + const char *handler_name, + const char *location) +{ + DEBUG(11,("%s: te[%p] handler_name[%s] location[%s]\n", + __func__, te, handler_name, location)); + + smbd_impersonate_root_after_use(wrap_ev, private_data, main_ev, location); +} + +static void smbd_impersonate_root_before_immediate_handler(struct tevent_context *wrap_ev, + void *private_data, + struct tevent_context *main_ev, + struct tevent_immediate *im, + const char *handler_name, + const char *location) +{ + DEBUG(11,("%s: im[%p] handler_name[%s] location[%s]\n", + __func__, im, handler_name, location)); + + smbd_impersonate_root_before_use(wrap_ev, private_data, main_ev, location); +} + +static void smbd_impersonate_root_after_immediate_handler(struct tevent_context *wrap_ev, + void *private_data, + struct tevent_context *main_ev, + struct tevent_immediate *im, + const char *handler_name, + const char *location) +{ + DEBUG(11,("%s: im[%p] handler_name[%s] location[%s]\n", + __func__, im, handler_name, location)); + + smbd_impersonate_root_after_use(wrap_ev, private_data, main_ev, location); +} + +static void smbd_impersonate_root_before_signal_handler(struct tevent_context *wrap_ev, + void *private_data, + struct tevent_context *main_ev, + struct tevent_signal *se, + int signum, + int count, + void *siginfo, + const char *handler_name, + const char *location) +{ + DEBUG(11,("%s: se[%p] signum[%d] count[%d] siginfo[%p] " + "handler_name[%s] location[%s]\n", + __func__, se, signum, count, siginfo, handler_name, location)); + + smbd_impersonate_root_before_use(wrap_ev, private_data, main_ev, location); +} + +static void smbd_impersonate_root_after_signal_handler(struct tevent_context *wrap_ev, + void *private_data, + struct tevent_context *main_ev, + struct tevent_signal *se, + int signum, + int count, + void *siginfo, + const char *handler_name, + const char *location) +{ + DEBUG(11,("%s: se[%p] handler_name[%s] location[%s]\n", + __func__, se, handler_name, location)); + + smbd_impersonate_root_after_use(wrap_ev, private_data, main_ev, location); +} + +static const struct tevent_wrapper_ops smbd_impersonate_root_ops = { + .name = "smbd_impersonate_root", + .before_use = smbd_impersonate_root_before_use, + .after_use = smbd_impersonate_root_after_use, + .before_fd_handler = smbd_impersonate_root_before_fd_handler, + .after_fd_handler = smbd_impersonate_root_after_fd_handler, + .before_timer_handler = smbd_impersonate_root_before_timer_handler, + .after_timer_handler = smbd_impersonate_root_after_timer_handler, + .before_immediate_handler = smbd_impersonate_root_before_immediate_handler, + .after_immediate_handler = smbd_impersonate_root_after_immediate_handler, + .before_signal_handler = smbd_impersonate_root_before_signal_handler, + .after_signal_handler = smbd_impersonate_root_after_signal_handler, +}; + struct tevent_context *smbd_impersonate_root_create(struct tevent_context *main_ev) { - struct tevent_context *wrap_ev = NULL; + struct tevent_context *ev = NULL; + struct smbd_impersonate_root_state *state = NULL; + + ev = tevent_context_wrapper_create(main_ev, + main_ev, + &smbd_impersonate_root_ops, + &state, + struct smbd_impersonate_root_state); + if (ev == NULL) { + return NULL; + } - wrap_ev = smbd_impersonate_debug_create(main_ev, - "root", - DBGLVL_DEBUG); + return ev; +} - return wrap_ev; +struct smbd_impersonate_guest_state { + uint8_t _dummy; +}; + +static bool smbd_impersonate_guest_before_use(struct tevent_context *wrap_ev, + void *private_data, + struct tevent_context *main_ev, + const char *location) +{ + DEBUG(11,("%s: wrap_ev[%p] main_ev[%p] location[%s]" + "uid[%ju] gid[%ju]\n", + __func__, wrap_ev, main_ev, location, + (uintmax_t)geteuid(), (uintmax_t)getegid())); + + return become_guest(); } -struct tevent_context *smbd_impersonate_guest_create(struct tevent_context *main_ev) +static void smbd_impersonate_guest_after_use(struct tevent_context *wrap_ev, + void *private_data, + struct tevent_context *main_ev, + const char *location) { - struct tevent_context *wrap_ev = NULL; + unbecome_guest(); + + DEBUG(11,("%s: uid[%ju] gid[%ju] location[%s]\n", + __func__, (uintmax_t)geteuid(), (uintmax_t)getegid(), + location)); +} + +static void smbd_impersonate_guest_before_fd_handler(struct tevent_context *wrap_ev, + void *private_data, + struct tevent_context *main_ev, + struct tevent_fd *fde, + uint16_t flags, + const char *handler_name, + const char *location) +{ + bool ok; - wrap_ev = smbd_impersonate_debug_create(main_ev, - "guest", - DBGLVL_DEBUG); + DEBUG(11,("%s: fde[%p] flags[%ju] handler_name[%s] location[%s]\n", + __func__, fde, (uintmax_t)flags, handler_name, location)); - return wrap_ev; + ok = smbd_impersonate_guest_before_use(wrap_ev, private_data, + main_ev, location); + if (!ok) { + smb_panic("smbd_impersonate_guest_before_use() - failed"); + return; + } +} + +static void smbd_impersonate_guest_after_fd_handler(struct tevent_context *wrap_ev, + void *private_data, + struct tevent_context *main_ev, + struct tevent_fd *fde, + uint16_t flags, + const char *handler_name, + const char *location) +{ + DEBUG(11,("%s: fde[%p] handler_name[%s] location[%s]\n", + __func__, fde, handler_name, location)); + + smbd_impersonate_guest_after_use(wrap_ev, private_data, main_ev, location); +} + +static void smbd_impersonate_guest_before_timer_handler(struct tevent_context *wrap_ev, + void *private_data, + struct tevent_context *main_ev, + struct tevent_timer *te, + struct timeval requested_time, + struct timeval trigger_time, + const char *handler_name, + const char *location) +{ + bool ok; + struct timeval_buf requested_buf; + struct timeval_buf trigger_buf; + + DEBUG(11,("%s: te[%p] requested_time[%s] trigger_time[%s] " + "handler_name[%s] location[%s]\n", + __func__, te, + timeval_str_buf(&requested_time, true, true, &requested_buf), + timeval_str_buf(&trigger_time, true, true, &trigger_buf), + handler_name, location)); + + ok = smbd_impersonate_guest_before_use(wrap_ev, private_data, + main_ev, location); + if (!ok) { + smb_panic("smbd_impersonate_guest_before_use() - failed"); + return; + } +} + +static void smbd_impersonate_guest_after_timer_handler(struct tevent_context *wrap_ev, + void *private_data, + struct tevent_context *main_ev, + struct tevent_timer *te, + struct timeval requested_time, + struct timeval trigger_time, + const char *handler_name, + const char *location) +{ + DEBUG(11,("%s: te[%p] handler_name[%s] location[%s]\n", + __func__, te, handler_name, location)); + + smbd_impersonate_guest_after_use(wrap_ev, private_data, main_ev, location); +} + +static void smbd_impersonate_guest_before_immediate_handler(struct tevent_context *wrap_ev, + void *private_data, + struct tevent_context *main_ev, + struct tevent_immediate *im, + const char *handler_name, + const char *location) +{ + bool ok; + + DEBUG(11,("%s: im[%p] handler_name[%s] location[%s]\n", + __func__, im, handler_name, location)); + + ok = smbd_impersonate_guest_before_use(wrap_ev, private_data, + main_ev, location); + if (!ok) { + smb_panic("smbd_impersonate_guest_before_use() - failed"); + return; + } +} + +static void smbd_impersonate_guest_after_immediate_handler(struct tevent_context *wrap_ev, + void *private_data, + struct tevent_context *main_ev, + struct tevent_immediate *im, + const char *handler_name, + const char *location) +{ + DEBUG(11,("%s: im[%p] handler_name[%s] location[%s]\n", + __func__, im, handler_name, location)); + + smbd_impersonate_guest_after_use(wrap_ev, private_data, main_ev, location); +} + +static void smbd_impersonate_guest_before_signal_handler(struct tevent_context *wrap_ev, + void *private_data, + struct tevent_context *main_ev, + struct tevent_signal *se, + int signum, + int count, + void *siginfo, + const char *handler_name, + const char *location) +{ + bool ok; + + DEBUG(11,("%s: se[%p] signum[%d] count[%d] siginfo[%p] " + "handler_name[%s] location[%s]\n", + __func__, se, signum, count, siginfo, handler_name, location)); + + ok = smbd_impersonate_guest_before_use(wrap_ev, private_data, + main_ev, location); + if (!ok) { + smb_panic("smbd_impersonate_guest_before_use() - failed"); + return; + } +} + +static void smbd_impersonate_guest_after_signal_handler(struct tevent_context *wrap_ev, + void *private_data, + struct tevent_context *main_ev, + struct tevent_signal *se, + int signum, + int count, + void *siginfo, + const char *handler_name, + const char *location) +{ + DEBUG(11,("%s: se[%p] handler_name[%s] location[%s]\n", + __func__, se, handler_name, location)); + + smbd_impersonate_guest_after_use(wrap_ev, private_data, main_ev, location); +} + +static const struct tevent_wrapper_ops smbd_impersonate_guest_ops = { + .name = "smbd_impersonate_guest", + .before_use = smbd_impersonate_guest_before_use, + .after_use = smbd_impersonate_guest_after_use, + .before_fd_handler = smbd_impersonate_guest_before_fd_handler, + .after_fd_handler = smbd_impersonate_guest_after_fd_handler, + .before_timer_handler = smbd_impersonate_guest_before_timer_handler, + .after_timer_handler = smbd_impersonate_guest_after_timer_handler, + .before_immediate_handler = smbd_impersonate_guest_before_immediate_handler, + .after_immediate_handler = smbd_impersonate_guest_after_immediate_handler, + .before_signal_handler = smbd_impersonate_guest_before_signal_handler, + .after_signal_handler = smbd_impersonate_guest_after_signal_handler, +}; + +struct tevent_context *smbd_impersonate_guest_create(struct tevent_context *main_ev) +{ + struct tevent_context *ev = NULL; + struct smbd_impersonate_guest_state *state = NULL; + + ev = tevent_context_wrapper_create(main_ev, + main_ev, + &smbd_impersonate_guest_ops, + &state, + struct smbd_impersonate_guest_state); + if (ev == NULL) { + return NULL; + } + + return ev; }