2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1992-1998
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "system/passwd.h"
22 #include "smbd/smbd.h"
23 #include "smbd/globals.h"
24 #include "../librpc/gen_ndr/netlogon.h"
25 #include "libcli/security/security.h"
26 #include "passdb/lookup_sid.h"
28 #include "lib/util/time_basic.h"
30 struct smbd_impersonate_debug_state {
35 static bool smbd_impersonate_debug_before_use(struct tevent_context *wrap_ev,
37 struct tevent_context *main_ev,
40 struct smbd_impersonate_debug_state *state =
41 (struct smbd_impersonate_debug_state *)private_data;
43 DEBUG(state->dbg_lvl, (
44 "%s: name[%s] wrap_ev[%p] state[%p] main_ev[%p] location[%s]\n",
45 __func__, state->name, wrap_ev, state, main_ev, location));
50 static void smbd_impersonate_debug_after_use(struct tevent_context *wrap_ev,
52 struct tevent_context *main_ev,
55 struct smbd_impersonate_debug_state *state =
56 (struct smbd_impersonate_debug_state *)private_data;
58 DEBUG(state->dbg_lvl, (
59 "%s: name[%s] wrap_ev[%p] state[%p] main_ev[%p] location[%s]\n",
60 __func__, state->name, wrap_ev, state, main_ev, location));
63 static void smbd_impersonate_debug_before_fd_handler(struct tevent_context *wrap_ev,
65 struct tevent_context *main_ev,
66 struct tevent_fd *fde,
68 const char *handler_name,
71 struct smbd_impersonate_debug_state *state =
72 (struct smbd_impersonate_debug_state *)private_data;
74 DEBUG(state->dbg_lvl, (
75 "%s: name[%s] wrap_ev[%p] state[%p] main_ev[%p] "
76 "fde[%p] flags[0x%X] handler_name[%s] location[%s]\n",
77 __func__, state->name, wrap_ev, state, main_ev,
78 fde, flags, handler_name, location));
81 static void smbd_impersonate_debug_after_fd_handler(struct tevent_context *wrap_ev,
83 struct tevent_context *main_ev,
84 struct tevent_fd *fde,
86 const char *handler_name,
89 struct smbd_impersonate_debug_state *state =
90 (struct smbd_impersonate_debug_state *)private_data;
92 DEBUG(state->dbg_lvl, (
93 "%s: name[%s] wrap_ev[%p] state[%p] main_ev[%p] "
94 "fde[%p] flags[0x%X] handler_name[%s] location[%s]\n",
95 __func__, state->name, wrap_ev, state, main_ev,
96 fde, flags, handler_name, location));
99 static void smbd_impersonate_debug_before_timer_handler(struct tevent_context *wrap_ev,
101 struct tevent_context *main_ev,
102 struct tevent_timer *te,
103 struct timeval requested_time,
104 struct timeval trigger_time,
105 const char *handler_name,
106 const char *location)
108 struct smbd_impersonate_debug_state *state =
109 (struct smbd_impersonate_debug_state *)private_data;
110 struct timeval_buf requested_buf;
111 struct timeval_buf trigger_buf;
113 DEBUG(state->dbg_lvl, (
114 "%s: name[%s] wrap_ev[%p] state[%p] main_ev[%p] "
115 "te[%p] requested_time[%s] trigger_time[%s] handler_name[%s] location[%s]\n",
116 __func__, state->name, wrap_ev, state, main_ev, te,
117 timeval_str_buf(&requested_time, true, true, &requested_buf),
118 timeval_str_buf(&trigger_time, true, true, &trigger_buf),
119 handler_name, location));
122 static void smbd_impersonate_debug_after_timer_handler(struct tevent_context *wrap_ev,
124 struct tevent_context *main_ev,
125 struct tevent_timer *te,
126 struct timeval requested_time,
127 struct timeval trigger_time,
128 const char *handler_name,
129 const char *location)
131 struct smbd_impersonate_debug_state *state =
132 (struct smbd_impersonate_debug_state *)private_data;
133 struct timeval_buf requested_buf;
134 struct timeval_buf trigger_buf;
136 DEBUG(state->dbg_lvl, (
137 "%s: name[%s] wrap_ev[%p] state[%p] main_ev[%p] "
138 "te[%p] requested_time[%s] trigger_time[%s] handler_name[%s] location[%s]\n",
139 __func__, state->name, wrap_ev, state, main_ev, te,
140 timeval_str_buf(&requested_time, true, true, &requested_buf),
141 timeval_str_buf(&trigger_time, true, true, &trigger_buf),
142 handler_name, location));
145 static void smbd_impersonate_debug_before_immediate_handler(struct tevent_context *wrap_ev,
147 struct tevent_context *main_ev,
148 struct tevent_immediate *im,
149 const char *handler_name,
150 const char *location)
152 struct smbd_impersonate_debug_state *state =
153 (struct smbd_impersonate_debug_state *)private_data;
155 DEBUG(state->dbg_lvl, (
156 "%s: name[%s] wrap_ev[%p] state[%p] main_ev[%p] "
157 "im[%p] handler_name[%s] location[%s]\n",
158 __func__, state->name, wrap_ev, state, main_ev,
159 im, handler_name, location));
162 static void smbd_impersonate_debug_after_immediate_handler(struct tevent_context *wrap_ev,
164 struct tevent_context *main_ev,
165 struct tevent_immediate *im,
166 const char *handler_name,
167 const char *location)
169 struct smbd_impersonate_debug_state *state =
170 (struct smbd_impersonate_debug_state *)private_data;
172 DEBUG(state->dbg_lvl, (
173 "%s: name[%s] wrap_ev[%p] state[%p] main_ev[%p] "
174 "im[%p] handler_name[%s] location[%s]\n",
175 __func__, state->name, wrap_ev, state, main_ev,
176 im, handler_name, location));
179 static void smbd_impersonate_debug_before_signal_handler(struct tevent_context *wrap_ev,
181 struct tevent_context *main_ev,
182 struct tevent_signal *se,
186 const char *handler_name,
187 const char *location)
189 struct smbd_impersonate_debug_state *state =
190 (struct smbd_impersonate_debug_state *)private_data;
192 DEBUG(state->dbg_lvl, (
193 "%s: name[%s] wrap_ev[%p] state[%p] main_ev[%p] "
194 "se[%p] signum[%d] count[%d] siginfo[%p] handler_name[%s] location[%s]\n",
195 __func__, state->name, wrap_ev, state, main_ev,
196 se, signum, count, siginfo, handler_name, location));
199 static void smbd_impersonate_debug_after_signal_handler(struct tevent_context *wrap_ev,
201 struct tevent_context *main_ev,
202 struct tevent_signal *se,
206 const char *handler_name,
207 const char *location)
209 struct smbd_impersonate_debug_state *state =
210 (struct smbd_impersonate_debug_state *)private_data;
212 DEBUG(state->dbg_lvl, (
213 "%s: name[%s] wrap_ev[%p] state[%p] main_ev[%p] "
214 "se[%p] signum[%d] count[%d] siginfo[%p] handler_name[%s] location[%s]\n",
215 __func__, state->name, wrap_ev, state, main_ev,
216 se, signum, count, siginfo, handler_name, location));
219 static const struct tevent_wrapper_ops smbd_impersonate_debug_ops = {
220 .name = "smbd_impersonate_debug",
221 .before_use = smbd_impersonate_debug_before_use,
222 .after_use = smbd_impersonate_debug_after_use,
223 .before_fd_handler = smbd_impersonate_debug_before_fd_handler,
224 .after_fd_handler = smbd_impersonate_debug_after_fd_handler,
225 .before_timer_handler = smbd_impersonate_debug_before_timer_handler,
226 .after_timer_handler = smbd_impersonate_debug_after_timer_handler,
227 .before_immediate_handler = smbd_impersonate_debug_before_immediate_handler,
228 .after_immediate_handler = smbd_impersonate_debug_after_immediate_handler,
229 .before_signal_handler = smbd_impersonate_debug_before_signal_handler,
230 .after_signal_handler = smbd_impersonate_debug_after_signal_handler,
233 struct tevent_context *_smbd_impersonate_debug_create(struct tevent_context *main_ev,
236 const char *location)
238 struct tevent_context *wrap_ev = NULL;
239 struct smbd_impersonate_debug_state *state = NULL;
241 wrap_ev = tevent_context_wrapper_create(main_ev,
243 &smbd_impersonate_debug_ops,
245 struct smbd_impersonate_debug_state);
246 if (wrap_ev == NULL) {
250 state->dbg_lvl = dbg_lvl;
251 DEBUG(state->dbg_lvl, (
252 "%s: name[%s] wrap_ev[%p] state[%p] main_ev[%p] location[%s]\n",
253 __func__, state->name, wrap_ev, state, main_ev, location));
258 /* what user is current? */
259 extern struct current_user current_user;
261 /****************************************************************************
262 Become the guest user without changing the security context stack.
263 ****************************************************************************/
265 bool change_to_guest(void)
269 pass = Get_Pwnam_alloc(talloc_tos(), lp_guest_account());
275 /* MWW: From AIX FAQ patch to WU-ftpd: call initgroups before
277 initgroups(pass->pw_name, pass->pw_gid);
280 set_sec_ctx(pass->pw_uid, pass->pw_gid, 0, NULL, NULL);
282 current_user.conn = NULL;
283 current_user.vuid = UID_FIELD_INVALID;
284 current_user.need_chdir = false;
285 current_user.done_chdir = false;
292 /****************************************************************************
293 talloc free the conn->session_info if not used in the vuid cache.
294 ****************************************************************************/
296 static void free_conn_session_info_if_unused(connection_struct *conn)
300 for (i = 0; i < VUID_CACHE_SIZE; i++) {
301 struct vuid_cache_entry *ent;
302 ent = &conn->vuid_cache->array[i];
303 if (ent->vuid != UID_FIELD_INVALID &&
304 conn->session_info == ent->session_info) {
308 /* Not used, safe to free. */
309 TALLOC_FREE(conn->user_ev_ctx);
310 TALLOC_FREE(conn->session_info);
313 /****************************************************************************
314 Setup the share access mask for a connection.
315 ****************************************************************************/
317 static uint32_t create_share_access_mask(int snum,
319 const struct security_token *token)
321 uint32_t share_access = 0;
323 share_access_check(token,
324 lp_const_servicename(snum),
325 MAXIMUM_ALLOWED_ACCESS,
328 if (readonly_share) {
330 ~(SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA |
331 SEC_FILE_WRITE_EA | SEC_FILE_WRITE_ATTRIBUTE |
332 SEC_DIR_DELETE_CHILD );
335 if (security_token_has_privilege(token, SEC_PRIV_SECURITY)) {
336 share_access |= SEC_FLAG_SYSTEM_SECURITY;
338 if (security_token_has_privilege(token, SEC_PRIV_RESTORE)) {
339 share_access |= SEC_RIGHTS_PRIV_RESTORE;
341 if (security_token_has_privilege(token, SEC_PRIV_BACKUP)) {
342 share_access |= SEC_RIGHTS_PRIV_BACKUP;
344 if (security_token_has_privilege(token, SEC_PRIV_TAKE_OWNERSHIP)) {
345 share_access |= SEC_STD_WRITE_OWNER;
351 /*******************************************************************
352 Calculate access mask and if this user can access this share.
353 ********************************************************************/
355 NTSTATUS check_user_share_access(connection_struct *conn,
356 const struct auth_session_info *session_info,
357 uint32_t *p_share_access,
358 bool *p_readonly_share)
360 int snum = SNUM(conn);
361 uint32_t share_access = 0;
362 bool readonly_share = false;
364 if (!user_ok_token(session_info->unix_info->unix_name,
365 session_info->info->domain_name,
366 session_info->security_token, snum)) {
367 return NT_STATUS_ACCESS_DENIED;
370 readonly_share = is_share_read_only_for_token(
371 session_info->unix_info->unix_name,
372 session_info->info->domain_name,
373 session_info->security_token,
376 share_access = create_share_access_mask(snum,
378 session_info->security_token);
380 if ((share_access & (FILE_READ_DATA|FILE_WRITE_DATA)) == 0) {
381 /* No access, read or write. */
382 DBG_NOTICE("user %s connection to %s denied due to share "
383 "security descriptor.\n",
384 session_info->unix_info->unix_name,
385 lp_const_servicename(snum));
386 return NT_STATUS_ACCESS_DENIED;
389 if (!readonly_share &&
390 !(share_access & FILE_WRITE_DATA)) {
391 /* smb.conf allows r/w, but the security descriptor denies
392 * write. Fall back to looking at readonly. */
393 readonly_share = true;
394 DBG_INFO("falling back to read-only access-evaluation due to "
395 "security descriptor\n");
398 *p_share_access = share_access;
399 *p_readonly_share = readonly_share;
404 /*******************************************************************
405 Check if a username is OK.
407 This sets up conn->session_info with a copy related to this vuser that
408 later code can then mess with.
409 ********************************************************************/
411 static bool check_user_ok(connection_struct *conn,
413 const struct auth_session_info *session_info,
417 bool readonly_share = false;
418 bool admin_user = false;
419 struct vuid_cache_entry *ent = NULL;
420 uint32_t share_access = 0;
423 for (i=0; i<VUID_CACHE_SIZE; i++) {
424 ent = &conn->vuid_cache->array[i];
425 if (ent->vuid == vuid) {
426 if (vuid == UID_FIELD_INVALID) {
428 * Slow path, we don't care
429 * about the array traversal.
433 free_conn_session_info_if_unused(conn);
434 conn->session_info = ent->session_info;
435 conn->user_ev_ctx = ent->user_ev_ctx;
436 conn->read_only = ent->read_only;
437 conn->share_access = ent->share_access;
438 conn->vuid = ent->vuid;
443 status = check_user_share_access(conn,
447 if (!NT_STATUS_IS_OK(status)) {
451 admin_user = token_contains_name_in_list(
452 session_info->unix_info->unix_name,
453 session_info->info->domain_name,
454 NULL, session_info->security_token, lp_admin_users(snum));
456 ent = &conn->vuid_cache->array[conn->vuid_cache->next_entry];
458 conn->vuid_cache->next_entry =
459 (conn->vuid_cache->next_entry + 1) % VUID_CACHE_SIZE;
461 TALLOC_FREE(ent->session_info);
464 * If force_user was set, all session_info's are based on the same
465 * username-based faked one.
468 ent->session_info = copy_session_info(
469 conn, conn->force_user ? conn->session_info : session_info);
471 if (ent->session_info == NULL) {
472 ent->vuid = UID_FIELD_INVALID;
477 DEBUG(2,("check_user_ok: user %s is an admin user. "
478 "Setting uid as %d\n",
479 ent->session_info->unix_info->unix_name,
480 sec_initial_uid() ));
481 ent->session_info->unix_token->uid = sec_initial_uid();
484 if (vuid == UID_FIELD_INVALID) {
485 ent->user_ev_ctx = smbd_impersonate_conn_sess_create(
486 conn->sconn->raw_ev_ctx, conn, ent->session_info);
487 if (ent->user_ev_ctx == NULL) {
488 TALLOC_FREE(ent->session_info);
489 ent->vuid = UID_FIELD_INVALID;
493 ent->user_ev_ctx = smbd_impersonate_conn_vuid_create(
494 conn->sconn->raw_ev_ctx, conn, vuid);
495 if (ent->user_ev_ctx == NULL) {
496 TALLOC_FREE(ent->session_info);
497 ent->vuid = UID_FIELD_INVALID;
503 * It's actually OK to call check_user_ok() with
504 * vuid == UID_FIELD_INVALID as called from change_to_user_by_session().
505 * All this will do is throw away one entry in the cache.
509 ent->read_only = readonly_share;
510 ent->share_access = share_access;
511 free_conn_session_info_if_unused(conn);
512 conn->session_info = ent->session_info;
513 conn->vuid = ent->vuid;
514 conn->user_ev_ctx = ent->user_ev_ctx;
515 if (vuid == UID_FIELD_INVALID) {
517 * Not strictly needed, just make it really
518 * clear this entry is actually an unused one.
520 ent->read_only = false;
521 ent->share_access = 0;
522 ent->session_info = NULL;
523 ent->user_ev_ctx = NULL;
526 conn->read_only = readonly_share;
527 conn->share_access = share_access;
532 /****************************************************************************
533 Become the user of a connection number without changing the security context
534 stack, but modify the current_user entries.
535 ****************************************************************************/
537 static bool change_to_user_internal(connection_struct *conn,
538 const struct auth_session_info *session_info,
546 gid_t *group_list = NULL;
549 if ((current_user.conn == conn) &&
550 (current_user.vuid == vuid) &&
551 (current_user.need_chdir == conn->tcon_done) &&
552 (current_user.ut.uid == session_info->unix_token->uid))
554 DBG_INFO("Skipping user change - already user\n");
558 set_current_user_info(session_info->unix_info->sanitized_username,
559 session_info->unix_info->unix_name,
560 session_info->info->domain_name);
564 ok = check_user_ok(conn, vuid, session_info, snum);
566 DBG_WARNING("SMB user %s (unix user %s) "
567 "not permitted access to share %s.\n",
568 session_info->unix_info->sanitized_username,
569 session_info->unix_info->unix_name,
570 lp_const_servicename(snum));
574 uid = conn->session_info->unix_token->uid;
575 gid = conn->session_info->unix_token->gid;
576 num_groups = conn->session_info->unix_token->ngroups;
577 group_list = conn->session_info->unix_token->groups;
580 * See if we should force group for this service. If so this overrides
581 * any group set in the force user code.
583 if((group_c = *lp_force_group(talloc_tos(), snum))) {
585 SMB_ASSERT(conn->force_group_gid != (gid_t)-1);
587 if (group_c == '+') {
591 * Only force group if the user is a member of the
592 * service group. Check the group memberships for this
593 * user (we already have this) to see if we should force
596 for (i = 0; i < num_groups; i++) {
597 if (group_list[i] == conn->force_group_gid) {
598 conn->session_info->unix_token->gid =
599 conn->force_group_gid;
600 gid = conn->force_group_gid;
601 gid_to_sid(&conn->session_info->security_token
607 conn->session_info->unix_token->gid = conn->force_group_gid;
608 gid = conn->force_group_gid;
609 gid_to_sid(&conn->session_info->security_token->sids[1],
614 /*Set current_user since we will immediately also call set_sec_ctx() */
615 current_user.ut.ngroups = num_groups;
616 current_user.ut.groups = group_list;
620 current_user.ut.ngroups,
621 current_user.ut.groups,
622 conn->session_info->security_token);
624 current_user.conn = conn;
625 current_user.vuid = vuid;
626 current_user.need_chdir = conn->tcon_done;
628 if (current_user.need_chdir) {
629 ok = chdir_current_service(conn);
631 DBG_ERR("chdir_current_service() failed!\n");
634 current_user.done_chdir = true;
637 if (CHECK_DEBUGLVL(DBGLVL_INFO)) {
638 struct smb_filename *cwdfname = vfs_GetWd(talloc_tos(), conn);
639 if (cwdfname == NULL) {
642 DBG_INFO("Impersonated user: uid=(%d,%d), gid=(%d,%d), cwd=[%s]\n",
647 cwdfname->base_name);
648 TALLOC_FREE(cwdfname);
654 bool change_to_user(connection_struct *conn, uint64_t vuid)
656 struct user_struct *vuser;
657 int snum = SNUM(conn);
660 DEBUG(2,("Connection not open\n"));
664 vuser = get_valid_user_struct(conn->sconn, vuid);
666 /* Invalid vuid sent */
667 DBG_WARNING("Invalid vuid %llu used on share %s.\n",
668 (unsigned long long)vuid,
669 lp_const_servicename(snum));
673 return change_to_user_internal(conn, vuser->session_info, vuid);
676 bool change_to_user_by_fsp(struct files_struct *fsp)
678 return change_to_user(fsp->conn, fsp->vuid);
681 static bool change_to_user_by_session(connection_struct *conn,
682 const struct auth_session_info *session_info)
684 SMB_ASSERT(conn != NULL);
685 SMB_ASSERT(session_info != NULL);
687 return change_to_user_internal(conn, session_info, UID_FIELD_INVALID);
690 /****************************************************************************
691 Go back to being root without changing the security context stack,
692 but modify the current_user entries.
693 ****************************************************************************/
695 bool smbd_change_to_root_user(void)
699 DEBUG(5,("change_to_root_user: now uid=(%d,%d) gid=(%d,%d)\n",
700 (int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid()));
702 current_user.conn = NULL;
703 current_user.vuid = UID_FIELD_INVALID;
704 current_user.need_chdir = false;
705 current_user.done_chdir = false;
710 /****************************************************************************
711 Become the user of an authenticated connected named pipe.
712 When this is called we are currently running as the connection
713 user. Doesn't modify current_user.
714 ****************************************************************************/
716 bool smbd_become_authenticated_pipe_user(struct auth_session_info *session_info)
721 set_sec_ctx(session_info->unix_token->uid, session_info->unix_token->gid,
722 session_info->unix_token->ngroups, session_info->unix_token->groups,
723 session_info->security_token);
725 DEBUG(5, ("Impersonated user: uid=(%d,%d), gid=(%d,%d)\n",
734 /****************************************************************************
735 Unbecome the user of an authenticated connected named pipe.
736 When this is called we are running as the authenticated pipe
737 user and need to go back to being the connection user. Doesn't modify
739 ****************************************************************************/
741 bool smbd_unbecome_authenticated_pipe_user(void)
743 return pop_sec_ctx();
746 /****************************************************************************
747 Utility functions used by become_xxx/unbecome_xxx.
748 ****************************************************************************/
750 static void push_conn_ctx(void)
752 struct conn_ctx *ctx_p;
753 extern userdom_struct current_user_info;
755 /* Check we don't overflow our stack */
757 if (conn_ctx_stack_ndx == MAX_SEC_CTX_DEPTH) {
758 DEBUG(0, ("Connection context stack overflow!\n"));
759 smb_panic("Connection context stack overflow!\n");
762 /* Store previous user context */
763 ctx_p = &conn_ctx_stack[conn_ctx_stack_ndx];
765 ctx_p->conn = current_user.conn;
766 ctx_p->vuid = current_user.vuid;
767 ctx_p->need_chdir = current_user.need_chdir;
768 ctx_p->done_chdir = current_user.done_chdir;
769 ctx_p->user_info = current_user_info;
771 DEBUG(4, ("push_conn_ctx(%llu) : conn_ctx_stack_ndx = %d\n",
772 (unsigned long long)ctx_p->vuid, conn_ctx_stack_ndx));
774 conn_ctx_stack_ndx++;
777 static void pop_conn_ctx(void)
779 struct conn_ctx *ctx_p;
781 /* Check for stack underflow. */
783 if (conn_ctx_stack_ndx == 0) {
784 DEBUG(0, ("Connection context stack underflow!\n"));
785 smb_panic("Connection context stack underflow!\n");
788 conn_ctx_stack_ndx--;
789 ctx_p = &conn_ctx_stack[conn_ctx_stack_ndx];
791 set_current_user_info(ctx_p->user_info.smb_name,
792 ctx_p->user_info.unix_name,
793 ctx_p->user_info.domain);
796 * Check if the current context did a chdir_current_service()
797 * and restore the cwd_fname of the previous context
800 if (current_user.done_chdir && ctx_p->need_chdir) {
803 ret = vfs_ChDir(ctx_p->conn, ctx_p->conn->cwd_fname);
805 DBG_ERR("vfs_ChDir() failed!\n");
806 smb_panic("vfs_ChDir() failed!\n");
810 current_user.conn = ctx_p->conn;
811 current_user.vuid = ctx_p->vuid;
812 current_user.need_chdir = ctx_p->need_chdir;
813 current_user.done_chdir = ctx_p->done_chdir;
815 *ctx_p = (struct conn_ctx) {
816 .vuid = UID_FIELD_INVALID,
820 /****************************************************************************
821 Temporarily become a root user. Must match with unbecome_root(). Saves and
822 restores the connection context.
823 ****************************************************************************/
825 void smbd_become_root(void)
828 * no good way to handle push_sec_ctx() failing without changing
829 * the prototype of become_root()
831 if (!push_sec_ctx()) {
832 smb_panic("become_root: push_sec_ctx failed");
838 /* Unbecome the root user */
840 void smbd_unbecome_root(void)
846 bool become_guest(void)
857 ok = change_to_guest();
867 void unbecome_guest(void)
874 /****************************************************************************
875 Push the current security context then force a change via change_to_user().
876 Saves and restores the connection context.
877 ****************************************************************************/
879 bool become_user(connection_struct *conn, uint64_t vuid)
886 if (!change_to_user(conn, vuid)) {
895 bool become_user_by_fsp(struct files_struct *fsp)
897 return become_user(fsp->conn, fsp->vuid);
900 bool become_user_by_session(connection_struct *conn,
901 const struct auth_session_info *session_info)
908 if (!change_to_user_by_session(conn, session_info)) {
917 bool unbecome_user(void)
924 /****************************************************************************
925 Return the current user we are running effectively as on this connection.
926 I'd like to make this return conn->session_info->unix_token->uid, but become_root()
927 doesn't alter this value.
928 ****************************************************************************/
930 uid_t get_current_uid(connection_struct *conn)
932 return current_user.ut.uid;
935 /****************************************************************************
936 Return the current group we are running effectively as on this connection.
937 I'd like to make this return conn->session_info->unix_token->gid, but become_root()
938 doesn't alter this value.
939 ****************************************************************************/
941 gid_t get_current_gid(connection_struct *conn)
943 return current_user.ut.gid;
946 /****************************************************************************
947 Return the UNIX token we are running effectively as on this connection.
948 I'd like to make this return &conn->session_info->unix_token-> but become_root()
949 doesn't alter this value.
950 ****************************************************************************/
952 const struct security_unix_token *get_current_utok(connection_struct *conn)
954 return ¤t_user.ut;
957 /****************************************************************************
958 Return the Windows token we are running effectively as on this connection.
959 If this is currently a NULL token as we're inside become_root() - a temporary
960 UNIX security override, then we search up the stack for the previous active
962 ****************************************************************************/
964 const struct security_token *get_current_nttok(connection_struct *conn)
966 if (current_user.nt_user_token) {
967 return current_user.nt_user_token;
969 return sec_ctx_active_token();
972 uint64_t get_current_vuid(connection_struct *conn)
974 return current_user.vuid;
977 struct smbd_impersonate_conn_vuid_state {
978 struct connection_struct *conn;
982 static bool smbd_impersonate_conn_vuid_before_use(
983 struct tevent_context *wrap_ev,
985 struct tevent_context *main_ev,
986 const char *location)
988 struct smbd_impersonate_conn_vuid_state *state =
989 talloc_get_type_abort(private_data,
990 struct smbd_impersonate_conn_vuid_state);
993 DEBUG(11,("%s: wrap_ev[%p] main_ev[%p] location[%s]"
994 "old uid[%ju] old gid[%ju] vuid[%ju] cwd[%s]\n",
995 __func__, wrap_ev, main_ev, location,
996 (uintmax_t)geteuid(), (uintmax_t)getegid(),
997 (uintmax_t)state->vuid, state->conn->cwd_fname->base_name));
999 ok = become_user(state->conn, state->vuid);
1001 smb_panic("smbd_impersonate_conn_vuid_before_use() - failed");
1005 DEBUG(11,("%s: impersonated user[%s] uid[%ju] gid[%ju] cwd[%s]\n",
1006 __func__, state->conn->session_info->unix_info->unix_name,
1007 (uintmax_t)geteuid(), (uintmax_t)getegid(),
1008 state->conn->cwd_fname->base_name));
1013 static void smbd_impersonate_conn_vuid_after_use(
1014 struct tevent_context *wrap_ev,
1016 struct tevent_context *main_ev,
1017 const char *location)
1019 struct smbd_impersonate_conn_vuid_state *state =
1020 talloc_get_type_abort(private_data,
1021 struct smbd_impersonate_conn_vuid_state);
1024 DEBUG(11,("%s: deimpersonating[%s] uid[%ju] gid[%ju] cwd[%s] "
1026 __func__, state->conn->session_info->unix_info->unix_name,
1027 (uintmax_t)geteuid(), (uintmax_t)getegid(),
1028 state->conn->cwd_fname->base_name, location));
1030 ok = unbecome_user();
1032 smb_panic("smbd_impersonate_conn_vuid_after_use() - failed");
1036 DEBUG(11,("%s: impersonated user[%s] uid[%ju] gid[%ju] cwd[%s]\n",
1037 __func__, state->conn->session_info->unix_info->unix_name,
1038 (uintmax_t)geteuid(), (uintmax_t)getegid(),
1039 state->conn->cwd_fname->base_name));
1042 static void smbd_impersonate_conn_vuid_before_fd_handler(
1043 struct tevent_context *wrap_ev,
1045 struct tevent_context *main_ev,
1046 struct tevent_fd *fde,
1048 const char *handler_name,
1049 const char *location)
1051 struct smbd_impersonate_conn_vuid_state *state = talloc_get_type_abort(
1052 private_data, struct smbd_impersonate_conn_vuid_state);
1055 DEBUG(11,("%s: fde[%p] flags[%ju] handler_name[%s] location[%s]\n",
1056 __func__, fde, (uintmax_t)flags, handler_name, location));
1058 ok = change_to_user(state->conn, state->vuid);
1060 smb_panic("smbd_impersonate_conn_vuid_before_use() - failed");
1064 DEBUG(11,("%s: impersonated user[%s] uid[%ju] gid[%ju] cwd[%s]\n",
1065 __func__, state->conn->session_info->unix_info->unix_name,
1066 (uintmax_t)geteuid(), (uintmax_t)getegid(),
1067 state->conn->cwd_fname->base_name));
1070 static void smbd_impersonate_conn_vuid_after_fd_handler(
1071 struct tevent_context *wrap_ev,
1073 struct tevent_context *main_ev,
1074 struct tevent_fd *fde,
1076 const char *handler_name,
1077 const char *location)
1079 DEBUG(11,("%s: fde[%p] handler_name[%s] location[%s]\n",
1080 __func__, fde, handler_name, location));
1082 /* be lazy and defer change_to_root_user() */
1085 static void smbd_impersonate_conn_vuid_before_timer_handler(
1086 struct tevent_context *wrap_ev,
1088 struct tevent_context *main_ev,
1089 struct tevent_timer *te,
1090 struct timeval requested_time,
1091 struct timeval trigger_time,
1092 const char *handler_name,
1093 const char *location)
1095 struct smbd_impersonate_conn_vuid_state *state = talloc_get_type_abort(
1096 private_data, struct smbd_impersonate_conn_vuid_state);
1097 struct timeval_buf requested_buf;
1098 struct timeval_buf trigger_buf;
1101 DEBUG(11,("%s: te[%p] requested_time[%s] trigger_time[%s] "
1102 "handler_name[%s] location[%s]\n",
1104 timeval_str_buf(&requested_time, true, true, &requested_buf),
1105 timeval_str_buf(&trigger_time, true, true, &trigger_buf),
1106 handler_name, location));
1108 ok = change_to_user(state->conn, state->vuid);
1110 smb_panic("smbd_impersonate_conn_vuid_before_use() - failed");
1114 DEBUG(11,("%s: impersonated user[%s] uid[%ju] gid[%ju] cwd[%s]\n",
1115 __func__, state->conn->session_info->unix_info->unix_name,
1116 (uintmax_t)geteuid(), (uintmax_t)getegid(),
1117 state->conn->cwd_fname->base_name));
1120 static void smbd_impersonate_conn_vuid_after_timer_handler(
1121 struct tevent_context *wrap_ev,
1123 struct tevent_context *main_ev,
1124 struct tevent_timer *te,
1125 struct timeval requested_time,
1126 struct timeval trigger_time,
1127 const char *handler_name,
1128 const char *location)
1130 DEBUG(11,("%s: te[%p] handler_name[%s] location[%s]\n",
1131 __func__, te, handler_name, location));
1133 /* be lazy and defer change_to_root_user() */
1136 static void smbd_impersonate_conn_vuid_before_immediate_handler(
1137 struct tevent_context *wrap_ev,
1139 struct tevent_context *main_ev,
1140 struct tevent_immediate *im,
1141 const char *handler_name,
1142 const char *location)
1144 struct smbd_impersonate_conn_vuid_state *state = talloc_get_type_abort(
1145 private_data, struct smbd_impersonate_conn_vuid_state);
1148 DEBUG(11,("%s: im[%p] handler_name[%s] location[%s]\n",
1149 __func__, im, handler_name, location));
1151 ok = change_to_user(state->conn, state->vuid);
1153 smb_panic("smbd_impersonate_conn_vuid_before_use() - failed");
1157 DEBUG(11,("%s: impersonated user[%s] uid[%ju] gid[%ju] cwd[%s]\n",
1158 __func__, state->conn->session_info->unix_info->unix_name,
1159 (uintmax_t)geteuid(), (uintmax_t)getegid(),
1160 state->conn->cwd_fname->base_name));
1163 static void smbd_impersonate_conn_vuid_after_immediate_handler(
1164 struct tevent_context *wrap_ev,
1166 struct tevent_context *main_ev,
1167 struct tevent_immediate *im,
1168 const char *handler_name,
1169 const char *location)
1171 DEBUG(11,("%s: im[%p] handler_name[%s] location[%s]\n",
1172 __func__, im, handler_name, location));
1174 /* be lazy and defer unbecome_user() */
1177 static void smbd_impersonate_conn_vuid_before_signal_handler(
1178 struct tevent_context *wrap_ev,
1180 struct tevent_context *main_ev,
1181 struct tevent_signal *se,
1185 const char *handler_name,
1186 const char *location)
1188 struct smbd_impersonate_conn_vuid_state *state = talloc_get_type_abort(
1189 private_data, struct smbd_impersonate_conn_vuid_state);
1192 DEBUG(11,("%s: se[%p] signum[%d] count[%d] siginfo[%p] "
1193 "handler_name[%s] location[%s]\n",
1194 __func__, se, signum, count, siginfo, handler_name, location));
1196 ok = change_to_user(state->conn, state->vuid);
1198 smb_panic("smbd_impersonate_conn_vuid_before_use() - failed");
1202 DEBUG(11,("%s: impersonated user[%s] uid[%ju] gid[%ju] cwd[%s]\n",
1203 __func__, state->conn->session_info->unix_info->unix_name,
1204 (uintmax_t)geteuid(), (uintmax_t)getegid(),
1205 state->conn->cwd_fname->base_name));
1208 static void smbd_impersonate_conn_vuid_after_signal_handler(
1209 struct tevent_context *wrap_ev,
1211 struct tevent_context *main_ev,
1212 struct tevent_signal *se,
1216 const char *handler_name,
1217 const char *location)
1219 DEBUG(11,("%s: se[%p] handler_name[%s] location[%s]\n",
1220 __func__, se, handler_name, location));
1222 /* be lazy and defer change_to_root_user() */
1225 static const struct tevent_wrapper_ops smbd_impersonate_conn_vuid_ops = {
1226 .name = "smbd_impersonate_conn_vuid",
1227 .before_use = smbd_impersonate_conn_vuid_before_use,
1228 .after_use = smbd_impersonate_conn_vuid_after_use,
1229 .before_fd_handler = smbd_impersonate_conn_vuid_before_fd_handler,
1230 .after_fd_handler = smbd_impersonate_conn_vuid_after_fd_handler,
1231 .before_timer_handler = smbd_impersonate_conn_vuid_before_timer_handler,
1232 .after_timer_handler = smbd_impersonate_conn_vuid_after_timer_handler,
1233 .before_immediate_handler = smbd_impersonate_conn_vuid_before_immediate_handler,
1234 .after_immediate_handler = smbd_impersonate_conn_vuid_after_immediate_handler,
1235 .before_signal_handler = smbd_impersonate_conn_vuid_before_signal_handler,
1236 .after_signal_handler = smbd_impersonate_conn_vuid_after_signal_handler,
1239 struct tevent_context *smbd_impersonate_conn_vuid_create(
1240 struct tevent_context *main_ev,
1241 struct connection_struct *conn,
1244 struct tevent_context *ev = NULL;
1245 struct smbd_impersonate_conn_vuid_state *state = NULL;
1247 ev = tevent_context_wrapper_create(main_ev,
1249 &smbd_impersonate_conn_vuid_ops,
1251 struct smbd_impersonate_conn_vuid_state);
1261 struct smbd_impersonate_conn_sess_state {
1262 struct connection_struct *conn;
1263 struct auth_session_info *session_info;
1266 static bool smbd_impersonate_conn_sess_before_use(struct tevent_context *wrap_ev,
1268 struct tevent_context *main_ev,
1269 const char *location)
1271 struct smbd_impersonate_conn_sess_state *state = talloc_get_type_abort(
1272 private_data, struct smbd_impersonate_conn_sess_state);
1275 DEBUG(11,("%s: impersonating user[%s] wrap_ev[%p] main_ev[%p] "
1276 "location[%s] old uid[%ju] old gid[%ju] cwd[%s]\n",
1277 __func__, state->session_info->unix_info->unix_name,
1278 wrap_ev, main_ev, location,
1279 (uintmax_t)geteuid(), (uintmax_t)getegid(),
1280 state->conn->cwd_fname->base_name));
1282 ok = become_user_by_session(state->conn, state->session_info);
1287 DEBUG(11,("%s: impersonated user[%s] uid[%ju] gid[%ju] cwd[%s]\n",
1288 __func__, state->conn->session_info->unix_info->unix_name,
1289 (uintmax_t)geteuid(), (uintmax_t)getegid(),
1290 state->conn->cwd_fname->base_name));
1295 static void smbd_impersonate_conn_sess_after_use(struct tevent_context *wrap_ev,
1297 struct tevent_context *main_ev,
1298 const char *location)
1300 struct smbd_impersonate_conn_sess_state *state = talloc_get_type_abort(
1301 private_data, struct smbd_impersonate_conn_sess_state);
1304 DEBUG(11,("%s: deimpersonating[%s] uid[%ju] gid[%ju] cwd[%s] "
1306 __func__, state->session_info->unix_info->unix_name,
1307 (uintmax_t)geteuid(), (uintmax_t)getegid(),
1308 state->conn->cwd_fname->base_name, location));
1310 ok = unbecome_user();
1312 smb_panic("smbd_impersonate_conn_sess_after_use() - failed");
1316 DEBUG(11,("%s: deimpersonated user[%s] uid[%ju] gid[%ju] cwd[%s]\n",
1317 __func__, state->conn->session_info->unix_info->unix_name,
1318 (uintmax_t)geteuid(), (uintmax_t)getegid(),
1319 state->conn->cwd_fname->base_name));
1322 static void smbd_impersonate_conn_sess_before_fd_handler(
1323 struct tevent_context *wrap_ev,
1325 struct tevent_context *main_ev,
1326 struct tevent_fd *fde,
1328 const char *handler_name,
1329 const char *location)
1331 struct smbd_impersonate_conn_sess_state *state = talloc_get_type_abort(
1332 private_data, struct smbd_impersonate_conn_sess_state);
1335 DEBUG(11,("%s: fde[%p] flags[%ju] handler_name[%s] location[%s]\n",
1336 __func__, fde, (uintmax_t)flags, handler_name, location));
1338 ok = change_to_user_by_session(state->conn, state->session_info);
1340 smb_panic("smbd_impersonate_conn_sess_before_fd_handler failed");
1344 DEBUG(11,("%s: impersonated user[%s] uid[%ju] gid[%ju] cwd[%s]\n",
1345 __func__, state->conn->session_info->unix_info->unix_name,
1346 (uintmax_t)geteuid(), (uintmax_t)getegid(),
1347 state->conn->cwd_fname->base_name));
1350 static void smbd_impersonate_conn_sess_after_fd_handler(struct tevent_context *wrap_ev,
1352 struct tevent_context *main_ev,
1353 struct tevent_fd *fde,
1355 const char *handler_name,
1356 const char *location)
1358 DEBUG(11,("%s: fde[%p] handler_name[%s] location[%s]\n",
1359 __func__, fde, handler_name, location));
1361 /* be lazy and defer change_to_root_user() */
1364 static void smbd_impersonate_conn_sess_before_timer_handler(
1365 struct tevent_context *wrap_ev,
1367 struct tevent_context *main_ev,
1368 struct tevent_timer *te,
1369 struct timeval requested_time,
1370 struct timeval trigger_time,
1371 const char *handler_name,
1372 const char *location)
1374 struct smbd_impersonate_conn_sess_state *state = talloc_get_type_abort(
1375 private_data, struct smbd_impersonate_conn_sess_state);
1376 struct timeval_buf requested_buf;
1377 struct timeval_buf trigger_buf;
1380 DEBUG(11,("%s: te[%p] requested_time[%s] trigger_time[%s] "
1381 "handler_name[%s] location[%s]\n",
1383 timeval_str_buf(&requested_time, true, true, &requested_buf),
1384 timeval_str_buf(&trigger_time, true, true, &trigger_buf),
1385 handler_name, location));
1387 ok = change_to_user_by_session(state->conn, state->session_info);
1389 smb_panic("smbd_impersonate_conn_sess_before_tm_handler failed");
1393 DEBUG(11,("%s: impersonated user[%s] uid[%ju] gid[%ju] cwd[%s]\n",
1394 __func__, state->conn->session_info->unix_info->unix_name,
1395 (uintmax_t)geteuid(), (uintmax_t)getegid(),
1396 state->conn->cwd_fname->base_name));
1399 static void smbd_impersonate_conn_sess_after_timer_handler(
1400 struct tevent_context *wrap_ev,
1402 struct tevent_context *main_ev,
1403 struct tevent_timer *te,
1404 struct timeval requested_time,
1405 struct timeval trigger_time,
1406 const char *handler_name,
1407 const char *location)
1409 DEBUG(11,("%s: te[%p] handler_name[%s] location[%s]\n",
1410 __func__, te, handler_name, location));
1412 /* be lazy and defer change_to_root_user() */
1415 static void smbd_impersonate_conn_sess_before_immediate_handler(
1416 struct tevent_context *wrap_ev,
1418 struct tevent_context *main_ev,
1419 struct tevent_immediate *im,
1420 const char *handler_name,
1421 const char *location)
1423 struct smbd_impersonate_conn_sess_state *state = talloc_get_type_abort(
1424 private_data, struct smbd_impersonate_conn_sess_state);
1427 DEBUG(11,("%s: im[%p] handler_name[%s] location[%s]\n",
1428 __func__, im, handler_name, location));
1430 ok = change_to_user_by_session(state->conn, state->session_info);
1432 smb_panic("smbd_impersonate_conn_sess_before_im_handler failed");
1436 DEBUG(11,("%s: impersonated user[%s] uid[%ju] gid[%ju] cwd[%s]\n",
1437 __func__, state->conn->session_info->unix_info->unix_name,
1438 (uintmax_t)geteuid(), (uintmax_t)getegid(),
1439 state->conn->cwd_fname->base_name));
1442 static void smbd_impersonate_conn_sess_after_immediate_handler(
1443 struct tevent_context *wrap_ev,
1445 struct tevent_context *main_ev,
1446 struct tevent_immediate *im,
1447 const char *handler_name,
1448 const char *location)
1450 DEBUG(11,("%s: im[%p] handler_name[%s] location[%s]\n",
1451 __func__, im, handler_name, location));
1453 /* be lazy and defer unbecome_user() */
1456 static void smbd_impersonate_conn_sess_before_signal_handler(
1457 struct tevent_context *wrap_ev,
1459 struct tevent_context *main_ev,
1460 struct tevent_signal *se,
1464 const char *handler_name,
1465 const char *location)
1467 struct smbd_impersonate_conn_sess_state *state = talloc_get_type_abort(
1468 private_data, struct smbd_impersonate_conn_sess_state);
1471 DEBUG(11,("%s: se[%p] signum[%d] count[%d] siginfo[%p] "
1472 "handler_name[%s] location[%s]\n",
1473 __func__, se, signum, count, siginfo, handler_name, location));
1475 ok = change_to_user_by_session(state->conn, state->session_info);
1477 smb_panic("smbd_impersonate_conn_sess_before_si_handler failed");
1481 DEBUG(11,("%s: impersonated user[%s] uid[%ju] gid[%ju] cwd[%s]\n",
1482 __func__, state->conn->session_info->unix_info->unix_name,
1483 (uintmax_t)geteuid(), (uintmax_t)getegid(),
1484 state->conn->cwd_fname->base_name));
1487 static void smbd_impersonate_conn_sess_after_signal_handler(
1488 struct tevent_context *wrap_ev,
1490 struct tevent_context *main_ev,
1491 struct tevent_signal *se,
1495 const char *handler_name,
1496 const char *location)
1498 DEBUG(11,("%s: se[%p] handler_name[%s] location[%s]\n",
1499 __func__, se, handler_name, location));
1501 /* be lazy and defer change_to_root_user() */
1504 static const struct tevent_wrapper_ops smbd_impersonate_conn_sess_ops = {
1505 .name = "smbd_impersonate_conn_sess",
1506 .before_use = smbd_impersonate_conn_sess_before_use,
1507 .after_use = smbd_impersonate_conn_sess_after_use,
1508 .before_fd_handler = smbd_impersonate_conn_sess_before_fd_handler,
1509 .after_fd_handler = smbd_impersonate_conn_sess_after_fd_handler,
1510 .before_timer_handler = smbd_impersonate_conn_sess_before_timer_handler,
1511 .after_timer_handler = smbd_impersonate_conn_sess_after_timer_handler,
1512 .before_immediate_handler = smbd_impersonate_conn_sess_before_immediate_handler,
1513 .after_immediate_handler = smbd_impersonate_conn_sess_after_immediate_handler,
1514 .before_signal_handler = smbd_impersonate_conn_sess_before_signal_handler,
1515 .after_signal_handler = smbd_impersonate_conn_sess_after_signal_handler,
1518 struct tevent_context *smbd_impersonate_conn_sess_create(
1519 struct tevent_context *main_ev,
1520 struct connection_struct *conn,
1521 struct auth_session_info *session_info)
1523 struct tevent_context *ev = NULL;
1524 struct smbd_impersonate_conn_sess_state *state = NULL;
1526 ev = tevent_context_wrapper_create(main_ev,
1528 &smbd_impersonate_conn_sess_ops,
1530 struct smbd_impersonate_conn_sess_state);
1535 state->session_info = session_info;
1540 struct smbd_impersonate_root_state {
1544 static bool smbd_impersonate_root_before_use(struct tevent_context *wrap_ev,
1546 struct tevent_context *main_ev,
1547 const char *location)
1549 DEBUG(11,("%s: wrap_ev[%p] main_ev[%p] location[%s]"
1550 "uid[%ju] gid[%ju]\n",
1551 __func__, wrap_ev, main_ev, location,
1552 (uintmax_t)geteuid(), (uintmax_t)getegid()));
1558 static void smbd_impersonate_root_after_use(struct tevent_context *wrap_ev,
1560 struct tevent_context *main_ev,
1561 const char *location)
1565 DEBUG(11,("%s: uid[%ju] gid[%ju] location[%s]\n",
1566 __func__, (uintmax_t)geteuid(), (uintmax_t)getegid(),
1570 static void smbd_impersonate_root_before_fd_handler(struct tevent_context *wrap_ev,
1572 struct tevent_context *main_ev,
1573 struct tevent_fd *fde,
1575 const char *handler_name,
1576 const char *location)
1578 DEBUG(11,("%s: fde[%p] flags[%ju] handler_name[%s] location[%s]\n",
1579 __func__, fde, (uintmax_t)flags, handler_name, location));
1581 smbd_impersonate_root_before_use(wrap_ev, private_data, main_ev, location);
1584 static void smbd_impersonate_root_after_fd_handler(struct tevent_context *wrap_ev,
1586 struct tevent_context *main_ev,
1587 struct tevent_fd *fde,
1589 const char *handler_name,
1590 const char *location)
1592 DEBUG(11,("%s: fde[%p] handler_name[%s] location[%s]\n",
1593 __func__, fde, handler_name, location));
1595 smbd_impersonate_root_after_use(wrap_ev, private_data, main_ev, location);
1598 static void smbd_impersonate_root_before_timer_handler(struct tevent_context *wrap_ev,
1600 struct tevent_context *main_ev,
1601 struct tevent_timer *te,
1602 struct timeval requested_time,
1603 struct timeval trigger_time,
1604 const char *handler_name,
1605 const char *location)
1607 struct timeval_buf requested_buf;
1608 struct timeval_buf trigger_buf;
1610 DEBUG(11,("%s: te[%p] requested_time[%s] trigger_time[%s] "
1611 "handler_name[%s] location[%s]\n",
1613 timeval_str_buf(&requested_time, true, true, &requested_buf),
1614 timeval_str_buf(&trigger_time, true, true, &trigger_buf),
1615 handler_name, location));
1617 smbd_impersonate_root_before_use(wrap_ev, private_data, main_ev, location);
1620 static void smbd_impersonate_root_after_timer_handler(struct tevent_context *wrap_ev,
1622 struct tevent_context *main_ev,
1623 struct tevent_timer *te,
1624 struct timeval requested_time,
1625 struct timeval trigger_time,
1626 const char *handler_name,
1627 const char *location)
1629 DEBUG(11,("%s: te[%p] handler_name[%s] location[%s]\n",
1630 __func__, te, handler_name, location));
1632 smbd_impersonate_root_after_use(wrap_ev, private_data, main_ev, location);
1635 static void smbd_impersonate_root_before_immediate_handler(struct tevent_context *wrap_ev,
1637 struct tevent_context *main_ev,
1638 struct tevent_immediate *im,
1639 const char *handler_name,
1640 const char *location)
1642 DEBUG(11,("%s: im[%p] handler_name[%s] location[%s]\n",
1643 __func__, im, handler_name, location));
1645 smbd_impersonate_root_before_use(wrap_ev, private_data, main_ev, location);
1648 static void smbd_impersonate_root_after_immediate_handler(struct tevent_context *wrap_ev,
1650 struct tevent_context *main_ev,
1651 struct tevent_immediate *im,
1652 const char *handler_name,
1653 const char *location)
1655 DEBUG(11,("%s: im[%p] handler_name[%s] location[%s]\n",
1656 __func__, im, handler_name, location));
1658 smbd_impersonate_root_after_use(wrap_ev, private_data, main_ev, location);
1661 static void smbd_impersonate_root_before_signal_handler(struct tevent_context *wrap_ev,
1663 struct tevent_context *main_ev,
1664 struct tevent_signal *se,
1668 const char *handler_name,
1669 const char *location)
1671 DEBUG(11,("%s: se[%p] signum[%d] count[%d] siginfo[%p] "
1672 "handler_name[%s] location[%s]\n",
1673 __func__, se, signum, count, siginfo, handler_name, location));
1675 smbd_impersonate_root_before_use(wrap_ev, private_data, main_ev, location);
1678 static void smbd_impersonate_root_after_signal_handler(struct tevent_context *wrap_ev,
1680 struct tevent_context *main_ev,
1681 struct tevent_signal *se,
1685 const char *handler_name,
1686 const char *location)
1688 DEBUG(11,("%s: se[%p] handler_name[%s] location[%s]\n",
1689 __func__, se, handler_name, location));
1691 smbd_impersonate_root_after_use(wrap_ev, private_data, main_ev, location);
1694 static const struct tevent_wrapper_ops smbd_impersonate_root_ops = {
1695 .name = "smbd_impersonate_root",
1696 .before_use = smbd_impersonate_root_before_use,
1697 .after_use = smbd_impersonate_root_after_use,
1698 .before_fd_handler = smbd_impersonate_root_before_fd_handler,
1699 .after_fd_handler = smbd_impersonate_root_after_fd_handler,
1700 .before_timer_handler = smbd_impersonate_root_before_timer_handler,
1701 .after_timer_handler = smbd_impersonate_root_after_timer_handler,
1702 .before_immediate_handler = smbd_impersonate_root_before_immediate_handler,
1703 .after_immediate_handler = smbd_impersonate_root_after_immediate_handler,
1704 .before_signal_handler = smbd_impersonate_root_before_signal_handler,
1705 .after_signal_handler = smbd_impersonate_root_after_signal_handler,
1708 struct tevent_context *smbd_impersonate_root_create(struct tevent_context *main_ev)
1710 struct tevent_context *ev = NULL;
1711 struct smbd_impersonate_root_state *state = NULL;
1713 ev = tevent_context_wrapper_create(main_ev,
1715 &smbd_impersonate_root_ops,
1717 struct smbd_impersonate_root_state);
1725 struct smbd_impersonate_guest_state {
1729 static bool smbd_impersonate_guest_before_use(struct tevent_context *wrap_ev,
1731 struct tevent_context *main_ev,
1732 const char *location)
1734 DEBUG(11,("%s: wrap_ev[%p] main_ev[%p] location[%s]"
1735 "uid[%ju] gid[%ju]\n",
1736 __func__, wrap_ev, main_ev, location,
1737 (uintmax_t)geteuid(), (uintmax_t)getegid()));
1739 return become_guest();
1742 static void smbd_impersonate_guest_after_use(struct tevent_context *wrap_ev,
1744 struct tevent_context *main_ev,
1745 const char *location)
1749 DEBUG(11,("%s: uid[%ju] gid[%ju] location[%s]\n",
1750 __func__, (uintmax_t)geteuid(), (uintmax_t)getegid(),
1754 static void smbd_impersonate_guest_before_fd_handler(struct tevent_context *wrap_ev,
1756 struct tevent_context *main_ev,
1757 struct tevent_fd *fde,
1759 const char *handler_name,
1760 const char *location)
1764 DEBUG(11,("%s: fde[%p] flags[%ju] handler_name[%s] location[%s]\n",
1765 __func__, fde, (uintmax_t)flags, handler_name, location));
1767 ok = smbd_impersonate_guest_before_use(wrap_ev, private_data,
1770 smb_panic("smbd_impersonate_guest_before_use() - failed");
1775 static void smbd_impersonate_guest_after_fd_handler(struct tevent_context *wrap_ev,
1777 struct tevent_context *main_ev,
1778 struct tevent_fd *fde,
1780 const char *handler_name,
1781 const char *location)
1783 DEBUG(11,("%s: fde[%p] handler_name[%s] location[%s]\n",
1784 __func__, fde, handler_name, location));
1786 smbd_impersonate_guest_after_use(wrap_ev, private_data, main_ev, location);
1789 static void smbd_impersonate_guest_before_timer_handler(struct tevent_context *wrap_ev,
1791 struct tevent_context *main_ev,
1792 struct tevent_timer *te,
1793 struct timeval requested_time,
1794 struct timeval trigger_time,
1795 const char *handler_name,
1796 const char *location)
1799 struct timeval_buf requested_buf;
1800 struct timeval_buf trigger_buf;
1802 DEBUG(11,("%s: te[%p] requested_time[%s] trigger_time[%s] "
1803 "handler_name[%s] location[%s]\n",
1805 timeval_str_buf(&requested_time, true, true, &requested_buf),
1806 timeval_str_buf(&trigger_time, true, true, &trigger_buf),
1807 handler_name, location));
1809 ok = smbd_impersonate_guest_before_use(wrap_ev, private_data,
1812 smb_panic("smbd_impersonate_guest_before_use() - failed");
1817 static void smbd_impersonate_guest_after_timer_handler(struct tevent_context *wrap_ev,
1819 struct tevent_context *main_ev,
1820 struct tevent_timer *te,
1821 struct timeval requested_time,
1822 struct timeval trigger_time,
1823 const char *handler_name,
1824 const char *location)
1826 DEBUG(11,("%s: te[%p] handler_name[%s] location[%s]\n",
1827 __func__, te, handler_name, location));
1829 smbd_impersonate_guest_after_use(wrap_ev, private_data, main_ev, location);
1832 static void smbd_impersonate_guest_before_immediate_handler(struct tevent_context *wrap_ev,
1834 struct tevent_context *main_ev,
1835 struct tevent_immediate *im,
1836 const char *handler_name,
1837 const char *location)
1841 DEBUG(11,("%s: im[%p] handler_name[%s] location[%s]\n",
1842 __func__, im, handler_name, location));
1844 ok = smbd_impersonate_guest_before_use(wrap_ev, private_data,
1847 smb_panic("smbd_impersonate_guest_before_use() - failed");
1852 static void smbd_impersonate_guest_after_immediate_handler(struct tevent_context *wrap_ev,
1854 struct tevent_context *main_ev,
1855 struct tevent_immediate *im,
1856 const char *handler_name,
1857 const char *location)
1859 DEBUG(11,("%s: im[%p] handler_name[%s] location[%s]\n",
1860 __func__, im, handler_name, location));
1862 smbd_impersonate_guest_after_use(wrap_ev, private_data, main_ev, location);
1865 static void smbd_impersonate_guest_before_signal_handler(struct tevent_context *wrap_ev,
1867 struct tevent_context *main_ev,
1868 struct tevent_signal *se,
1872 const char *handler_name,
1873 const char *location)
1877 DEBUG(11,("%s: se[%p] signum[%d] count[%d] siginfo[%p] "
1878 "handler_name[%s] location[%s]\n",
1879 __func__, se, signum, count, siginfo, handler_name, location));
1881 ok = smbd_impersonate_guest_before_use(wrap_ev, private_data,
1884 smb_panic("smbd_impersonate_guest_before_use() - failed");
1889 static void smbd_impersonate_guest_after_signal_handler(struct tevent_context *wrap_ev,
1891 struct tevent_context *main_ev,
1892 struct tevent_signal *se,
1896 const char *handler_name,
1897 const char *location)
1899 DEBUG(11,("%s: se[%p] handler_name[%s] location[%s]\n",
1900 __func__, se, handler_name, location));
1902 smbd_impersonate_guest_after_use(wrap_ev, private_data, main_ev, location);
1905 static const struct tevent_wrapper_ops smbd_impersonate_guest_ops = {
1906 .name = "smbd_impersonate_guest",
1907 .before_use = smbd_impersonate_guest_before_use,
1908 .after_use = smbd_impersonate_guest_after_use,
1909 .before_fd_handler = smbd_impersonate_guest_before_fd_handler,
1910 .after_fd_handler = smbd_impersonate_guest_after_fd_handler,
1911 .before_timer_handler = smbd_impersonate_guest_before_timer_handler,
1912 .after_timer_handler = smbd_impersonate_guest_after_timer_handler,
1913 .before_immediate_handler = smbd_impersonate_guest_before_immediate_handler,
1914 .after_immediate_handler = smbd_impersonate_guest_after_immediate_handler,
1915 .before_signal_handler = smbd_impersonate_guest_before_signal_handler,
1916 .after_signal_handler = smbd_impersonate_guest_after_signal_handler,
1919 struct tevent_context *smbd_impersonate_guest_create(struct tevent_context *main_ev)
1921 struct tevent_context *ev = NULL;
1922 struct smbd_impersonate_guest_state *state = NULL;
1924 ev = tevent_context_wrapper_create(main_ev,
1926 &smbd_impersonate_guest_ops,
1928 struct smbd_impersonate_guest_state);