1 /*
2    Unix SMB/CIFS implementation.
3    uid/user handling
4    Copyright (C) Andrew Tridgell 1992-1998
5 
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.
10 
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.
15 
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/>.
18 */
19 
20 #include "includes.h"
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"
27 #include "auth.h"
28 #include "../auth/auth_util.h"
29 
30 /* what user is current? */
31 extern struct current_user current_user;
32 
33 /****************************************************************************
34  Become the guest user without changing the security context stack.
35 ****************************************************************************/
36 
change_to_guest(void)37 bool change_to_guest(void)
38 {
39 	struct passwd *pass;
40 
41 	pass = Get_Pwnam_alloc(talloc_tos(), lp_guest_account());
42 	if (!pass) {
43 		return false;
44 	}
45 
46 #ifdef AIX
47 	/* MWW: From AIX FAQ patch to WU-ftpd: call initgroups before
48 	   setting IDs */
49 	initgroups(pass->pw_name, pass->pw_gid);
50 #endif
51 
52 	set_sec_ctx(pass->pw_uid, pass->pw_gid, 0, NULL, NULL);
53 
54 	current_user.conn = NULL;
55 	current_user.vuid = UID_FIELD_INVALID;
56 
57 	TALLOC_FREE(pass);
58 
59 	return true;
60 }
61 
62 /****************************************************************************
63  talloc free the conn->session_info if not used in the vuid cache.
64 ****************************************************************************/
65 
free_conn_session_info_if_unused(connection_struct * conn)66 static void free_conn_session_info_if_unused(connection_struct *conn)
67 {
68 	unsigned int i;
69 
70 	for (i = 0; i < VUID_CACHE_SIZE; i++) {
71 		struct vuid_cache_entry *ent;
72 		ent = &conn->vuid_cache->array[i];
73 		if (ent->vuid != UID_FIELD_INVALID &&
74 				conn->session_info == ent->session_info) {
75 			return;
76 		}
77 	}
78 	/* Not used, safe to free. */
79 	TALLOC_FREE(conn->session_info);
80 }
81 
82 /****************************************************************************
83   Setup the share access mask for a connection.
84 ****************************************************************************/
85 
create_share_access_mask(int snum,bool readonly_share,const struct security_token * token)86 static uint32_t create_share_access_mask(int snum,
87 				bool readonly_share,
88 				const struct security_token *token)
89 {
90 	uint32_t share_access = 0;
91 
92 	share_access_check(token,
93 			lp_const_servicename(snum),
94 			MAXIMUM_ALLOWED_ACCESS,
95 			&share_access);
96 
97 	if (readonly_share) {
98 		share_access &=
99 			~(SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA |
100 			  SEC_FILE_WRITE_EA | SEC_FILE_WRITE_ATTRIBUTE |
101 			  SEC_DIR_DELETE_CHILD );
102 	}
103 
104 	if (security_token_has_privilege(token, SEC_PRIV_SECURITY)) {
105 		share_access |= SEC_FLAG_SYSTEM_SECURITY;
106 	}
107 	if (security_token_has_privilege(token, SEC_PRIV_RESTORE)) {
108 		share_access |= SEC_RIGHTS_PRIV_RESTORE;
109 	}
110 	if (security_token_has_privilege(token, SEC_PRIV_BACKUP)) {
111 		share_access |= SEC_RIGHTS_PRIV_BACKUP;
112 	}
113 	if (security_token_has_privilege(token, SEC_PRIV_TAKE_OWNERSHIP)) {
114 		share_access |= SEC_STD_WRITE_OWNER;
115 	}
116 
117 	return share_access;
118 }
119 
120 /*******************************************************************
121  Calculate access mask and if this user can access this share.
122 ********************************************************************/
123 
check_user_share_access(connection_struct * conn,const struct auth_session_info * session_info,uint32_t * p_share_access,bool * p_readonly_share)124 NTSTATUS check_user_share_access(connection_struct *conn,
125 				const struct auth_session_info *session_info,
126 				uint32_t *p_share_access,
127 				bool *p_readonly_share)
128 {
129 	int snum = SNUM(conn);
130 	uint32_t share_access = 0;
131 	bool readonly_share = false;
132 
133 	if (!user_ok_token(session_info->unix_info->unix_name,
134 			   session_info->info->domain_name,
135 			   session_info->security_token, snum)) {
136 		return NT_STATUS_ACCESS_DENIED;
137 	}
138 
139 	readonly_share = is_share_read_only_for_token(
140 		session_info->unix_info->unix_name,
141 		session_info->info->domain_name,
142 		session_info->security_token,
143 		conn);
144 
145 	share_access = create_share_access_mask(snum,
146 					readonly_share,
147 					session_info->security_token);
148 
149 	if ((share_access & (FILE_READ_DATA|FILE_WRITE_DATA)) == 0) {
150 		/* No access, read or write. */
151 		DBG_NOTICE("user %s connection to %s denied due to share "
152 			 "security descriptor.\n",
153 			 session_info->unix_info->unix_name,
154 			 lp_const_servicename(snum));
155 		return NT_STATUS_ACCESS_DENIED;
156 	}
157 
158 	if (!readonly_share &&
159 	    !(share_access & FILE_WRITE_DATA)) {
160 		/* smb.conf allows r/w, but the security descriptor denies
161 		 * write. Fall back to looking at readonly. */
162 		readonly_share = true;
163 		DBG_INFO("falling back to read-only access-evaluation due to "
164 			 "security descriptor\n");
165 	}
166 
167 	*p_share_access = share_access;
168 	*p_readonly_share = readonly_share;
169 
170 	return NT_STATUS_OK;
171 }
172 
173 /*******************************************************************
174  Check if a username is OK.
175 
176  This sets up conn->session_info with a copy related to this vuser that
177  later code can then mess with.
178 ********************************************************************/
179 
check_user_ok(connection_struct * conn,uint64_t vuid,const struct auth_session_info * session_info,int snum)180 static bool check_user_ok(connection_struct *conn,
181 			uint64_t vuid,
182 			const struct auth_session_info *session_info,
183 			int snum)
184 {
185 	unsigned int i;
186 	bool readonly_share = false;
187 	bool admin_user = false;
188 	struct vuid_cache_entry *ent = NULL;
189 	uint32_t share_access = 0;
190 	NTSTATUS status;
191 
192 	for (i=0; i<VUID_CACHE_SIZE; i++) {
193 		ent = &conn->vuid_cache->array[i];
194 		if (ent->vuid == vuid) {
195 			if (vuid == UID_FIELD_INVALID) {
196 				/*
197 				 * Slow path, we don't care
198 				 * about the array traversal.
199 				*/
200 				continue;
201 			}
202 			free_conn_session_info_if_unused(conn);
203 			conn->session_info = ent->session_info;
204 			conn->read_only = ent->read_only;
205 			conn->share_access = ent->share_access;
206 			conn->vuid = ent->vuid;
207 			return(True);
208 		}
209 	}
210 
211 	status = check_user_share_access(conn,
212 					session_info,
213 					&share_access,
214 					&readonly_share);
215 	if (!NT_STATUS_IS_OK(status)) {
216 		return false;
217 	}
218 
219 	admin_user = token_contains_name_in_list(
220 		session_info->unix_info->unix_name,
221 		session_info->info->domain_name,
222 		NULL, session_info->security_token, lp_admin_users(snum));
223 
224 	ent = &conn->vuid_cache->array[conn->vuid_cache->next_entry];
225 
226 	conn->vuid_cache->next_entry =
227 		(conn->vuid_cache->next_entry + 1) % VUID_CACHE_SIZE;
228 
229 	TALLOC_FREE(ent->session_info);
230 
231 	/*
232 	 * If force_user was set, all session_info's are based on the same
233 	 * username-based faked one.
234 	 */
235 
236 	ent->session_info = copy_session_info(
237 		conn, conn->force_user ? conn->session_info : session_info);
238 
239 	if (ent->session_info == NULL) {
240 		ent->vuid = UID_FIELD_INVALID;
241 		return false;
242 	}
243 
244 	if (admin_user) {
245 		DEBUG(2,("check_user_ok: user %s is an admin user. "
246 			"Setting uid as %d\n",
247 			ent->session_info->unix_info->unix_name,
248 			sec_initial_uid() ));
249 		ent->session_info->unix_token->uid = sec_initial_uid();
250 	}
251 
252 	/*
253 	 * It's actually OK to call check_user_ok() with
254 	 * vuid == UID_FIELD_INVALID as called from become_user_by_session().
255 	 * All this will do is throw away one entry in the cache.
256 	 */
257 
258 	ent->vuid = vuid;
259 	ent->read_only = readonly_share;
260 	ent->share_access = share_access;
261 	free_conn_session_info_if_unused(conn);
262 	conn->session_info = ent->session_info;
263 	conn->vuid = ent->vuid;
264 	if (vuid == UID_FIELD_INVALID) {
265 		/*
266 		 * Not strictly needed, just make it really
267 		 * clear this entry is actually an unused one.
268 		 */
269 		ent->read_only = false;
270 		ent->share_access = 0;
271 		ent->session_info = NULL;
272 	}
273 
274 	conn->read_only = readonly_share;
275 	conn->share_access = share_access;
276 
277 	return(True);
278 }
279 
print_impersonation_info(connection_struct * conn)280 static void print_impersonation_info(connection_struct *conn)
281 {
282 	struct smb_filename *cwdfname = NULL;
283 
284 	if (!CHECK_DEBUGLVL(DBGLVL_INFO)) {
285 		return;
286 	}
287 
288 	cwdfname = vfs_GetWd(talloc_tos(), conn);
289 	if (cwdfname == NULL) {
290 		return;
291 	}
292 
293 	DBG_INFO("Impersonated user: uid=(%d,%d), gid=(%d,%d), cwd=[%s]\n",
294 		 (int)getuid(),
295 		 (int)geteuid(),
296 		 (int)getgid(),
297 		 (int)getegid(),
298 		 cwdfname->base_name);
299 	TALLOC_FREE(cwdfname);
300 }
301 
302 /****************************************************************************
303  Become the user of a connection number without changing the security context
304  stack, but modify the current_user entries.
305 ****************************************************************************/
306 
change_to_user_impersonate(connection_struct * conn,const struct auth_session_info * session_info,uint64_t vuid)307 static bool change_to_user_impersonate(connection_struct *conn,
308 				       const struct auth_session_info *session_info,
309 				       uint64_t vuid)
310 {
311 	const struct loadparm_substitution *lp_sub =
312 		loadparm_s3_global_substitution();
313 	int snum;
314 	gid_t gid;
315 	uid_t uid;
316 	const char *force_group_name;
317 	char group_c;
318 	int num_groups = 0;
319 	gid_t *group_list = NULL;
320 	bool ok;
321 
322 	if ((current_user.conn == conn) &&
323 	    (current_user.vuid == vuid) &&
324 	    (current_user.ut.uid == session_info->unix_token->uid))
325 	{
326 		DBG_INFO("Skipping user change - already user\n");
327 		return true;
328 	}
329 
330 	set_current_user_info(session_info->unix_info->sanitized_username,
331 			      session_info->unix_info->unix_name,
332 			      session_info->info->domain_name);
333 
334 	snum = SNUM(conn);
335 
336 	ok = check_user_ok(conn, vuid, session_info, snum);
337 	if (!ok) {
338 		DBG_WARNING("SMB user %s (unix user %s) "
339 			 "not permitted access to share %s.\n",
340 			 session_info->unix_info->sanitized_username,
341 			 session_info->unix_info->unix_name,
342 			 lp_const_servicename(snum));
343 		return false;
344 	}
345 
346 	uid = conn->session_info->unix_token->uid;
347 	gid = conn->session_info->unix_token->gid;
348 	num_groups = conn->session_info->unix_token->ngroups;
349 	group_list  = conn->session_info->unix_token->groups;
350 
351 	/*
352 	 * See if we should force group for this service. If so this overrides
353 	 * any group set in the force user code.
354 	 */
355 	force_group_name = lp_force_group(talloc_tos(), lp_sub, snum);
356 	group_c = *force_group_name;
357 
358 	if ((group_c != '\0') && (conn->force_group_gid == (gid_t)-1)) {
359 		/*
360 		 * This can happen if "force group" is added to a
361 		 * share definition whilst an existing connection
362 		 * to that share exists. In that case, don't change
363 		 * the existing credentials for force group, only
364 		 * do so for new connections.
365 		 *
366 		 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=13690
367 		 */
368 		DBG_INFO("Not forcing group %s on existing connection to "
369 			"share %s for SMB user %s (unix user %s)\n",
370 			force_group_name,
371 			lp_const_servicename(snum),
372 			session_info->unix_info->sanitized_username,
373 			session_info->unix_info->unix_name);
374 	}
375 
376 	if((group_c != '\0') && (conn->force_group_gid != (gid_t)-1)) {
377 		/*
378 		 * Only force group for connections where
379 		 * conn->force_group_gid has already been set
380 		 * to the correct value (i.e. the connection
381 		 * happened after the 'force group' definition
382 		 * was added to the share definition. Connections
383 		 * that were made before force group was added
384 		 * should stay with their existing credentials.
385 		 *
386 		 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=13690
387 		 */
388 
389 		if (group_c == '+') {
390 			int i;
391 
392 			/*
393 			 * Only force group if the user is a member of the
394 			 * service group. Check the group memberships for this
395 			 * user (we already have this) to see if we should force
396 			 * the group.
397 			 */
398 			for (i = 0; i < num_groups; i++) {
399 				if (group_list[i] == conn->force_group_gid) {
400 					conn->session_info->unix_token->gid =
401 						conn->force_group_gid;
402 					gid = conn->force_group_gid;
403 					gid_to_sid(&conn->session_info->security_token
404 						   ->sids[1], gid);
405 					break;
406 				}
407 			}
408 		} else {
409 			conn->session_info->unix_token->gid = conn->force_group_gid;
410 			gid = conn->force_group_gid;
411 			gid_to_sid(&conn->session_info->security_token->sids[1],
412 				   gid);
413 		}
414 	}
415 
416 	/*Set current_user since we will immediately also call set_sec_ctx() */
417 	current_user.ut.ngroups = num_groups;
418 	current_user.ut.groups  = group_list;
419 
420 	set_sec_ctx(uid,
421 		    gid,
422 		    current_user.ut.ngroups,
423 		    current_user.ut.groups,
424 		    conn->session_info->security_token);
425 
426 	current_user.conn = conn;
427 	current_user.vuid = vuid;
428 	return true;
429 }
430 
431 /**
432  * Impersonate user and change directory to service
433  *
434  * change_to_user_and_service() is used to impersonate the user associated with
435  * the given vuid and to change the working directory of the process to the
436  * service base directory.
437  **/
change_to_user_and_service(connection_struct * conn,uint64_t vuid)438 bool change_to_user_and_service(connection_struct *conn, uint64_t vuid)
439 {
440 	int snum = SNUM(conn);
441 	struct auth_session_info *si = NULL;
442 	NTSTATUS status;
443 	bool ok;
444 
445 	if (conn == NULL) {
446 		DBG_WARNING("Connection not open\n");
447 		return false;
448 	}
449 
450 	status = smbXsrv_session_info_lookup(conn->sconn->client,
451 					     vuid,
452 					     &si);
453 	if (!NT_STATUS_IS_OK(status)) {
454 		DBG_WARNING("Invalid vuid %llu used on share %s.\n",
455 			    (unsigned long long)vuid,
456 			    lp_const_servicename(snum));
457 		return false;
458 	}
459 
460 	ok = change_to_user_impersonate(conn, si, vuid);
461 	if (!ok) {
462 		return false;
463 	}
464 
465 	if (conn->tcon_done) {
466 		ok = chdir_current_service(conn);
467 		if (!ok) {
468 			return false;
469 		}
470 	}
471 
472 	print_impersonation_info(conn);
473 	return true;
474 }
475 
476 /**
477  * Impersonate user and change directory to service
478  *
479  * change_to_user_and_service_by_fsp() is used to impersonate the user
480  * associated with the given vuid and to change the working directory of the
481  * process to the service base directory.
482  **/
change_to_user_and_service_by_fsp(struct files_struct * fsp)483 bool change_to_user_and_service_by_fsp(struct files_struct *fsp)
484 {
485 	return change_to_user_and_service(fsp->conn, fsp->vuid);
486 }
487 
488 /****************************************************************************
489  Go back to being root without changing the security context stack,
490  but modify the current_user entries.
491 ****************************************************************************/
492 
smbd_change_to_root_user(void)493 bool smbd_change_to_root_user(void)
494 {
495 	set_root_sec_ctx();
496 
497 	DEBUG(5,("change_to_root_user: now uid=(%d,%d) gid=(%d,%d)\n",
498 		(int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid()));
499 
500 	current_user.conn = NULL;
501 	current_user.vuid = UID_FIELD_INVALID;
502 
503 	return(True);
504 }
505 
506 /****************************************************************************
507  Become the user of an authenticated connected named pipe.
508  When this is called we are currently running as the connection
509  user. Doesn't modify current_user.
510 ****************************************************************************/
511 
smbd_become_authenticated_pipe_user(struct auth_session_info * session_info)512 bool smbd_become_authenticated_pipe_user(struct auth_session_info *session_info)
513 {
514 	if (!push_sec_ctx())
515 		return False;
516 
517 	set_sec_ctx(session_info->unix_token->uid, session_info->unix_token->gid,
518 		    session_info->unix_token->ngroups, session_info->unix_token->groups,
519 		    session_info->security_token);
520 
521 	DEBUG(5, ("Impersonated user: uid=(%d,%d), gid=(%d,%d)\n",
522 		 (int)getuid(),
523 		 (int)geteuid(),
524 		 (int)getgid(),
525 		 (int)getegid()));
526 
527 	return True;
528 }
529 
530 /****************************************************************************
531  Unbecome the user of an authenticated connected named pipe.
532  When this is called we are running as the authenticated pipe
533  user and need to go back to being the connection user. Doesn't modify
534  current_user.
535 ****************************************************************************/
536 
smbd_unbecome_authenticated_pipe_user(void)537 bool smbd_unbecome_authenticated_pipe_user(void)
538 {
539 	return pop_sec_ctx();
540 }
541 
542 /****************************************************************************
543  Utility functions used by become_xxx/unbecome_xxx.
544 ****************************************************************************/
545 
push_conn_ctx(void)546 static void push_conn_ctx(void)
547 {
548 	struct conn_ctx *ctx_p;
549 	extern userdom_struct current_user_info;
550 
551 	/* Check we don't overflow our stack */
552 
553 	if (conn_ctx_stack_ndx == MAX_SEC_CTX_DEPTH) {
554 		DEBUG(0, ("Connection context stack overflow!\n"));
555 		smb_panic("Connection context stack overflow!\n");
556 	}
557 
558 	/* Store previous user context */
559 	ctx_p = &conn_ctx_stack[conn_ctx_stack_ndx];
560 
561 	ctx_p->conn = current_user.conn;
562 	ctx_p->vuid = current_user.vuid;
563 	ctx_p->user_info = current_user_info;
564 
565 	DEBUG(4, ("push_conn_ctx(%llu) : conn_ctx_stack_ndx = %d\n",
566 		(unsigned long long)ctx_p->vuid, conn_ctx_stack_ndx));
567 
568 	conn_ctx_stack_ndx++;
569 }
570 
pop_conn_ctx(void)571 static void pop_conn_ctx(void)
572 {
573 	struct conn_ctx *ctx_p;
574 
575 	/* Check for stack underflow. */
576 
577 	if (conn_ctx_stack_ndx == 0) {
578 		DEBUG(0, ("Connection context stack underflow!\n"));
579 		smb_panic("Connection context stack underflow!\n");
580 	}
581 
582 	conn_ctx_stack_ndx--;
583 	ctx_p = &conn_ctx_stack[conn_ctx_stack_ndx];
584 
585 	set_current_user_info(ctx_p->user_info.smb_name,
586 			      ctx_p->user_info.unix_name,
587 			      ctx_p->user_info.domain);
588 
589 	current_user.conn = ctx_p->conn;
590 	current_user.vuid = ctx_p->vuid;
591 
592 	*ctx_p = (struct conn_ctx) {
593 		.vuid = UID_FIELD_INVALID,
594 	};
595 }
596 
597 /****************************************************************************
598  Temporarily become a root user.  Must match with unbecome_root(). Saves and
599  restores the connection context.
600 ****************************************************************************/
601 
smbd_become_root(void)602 void smbd_become_root(void)
603 {
604 	 /*
605 	  * no good way to handle push_sec_ctx() failing without changing
606 	  * the prototype of become_root()
607 	  */
608 	if (!push_sec_ctx()) {
609 		smb_panic("become_root: push_sec_ctx failed");
610 	}
611 	push_conn_ctx();
612 	set_root_sec_ctx();
613 }
614 
615 /* Unbecome the root user */
616 
smbd_unbecome_root(void)617 void smbd_unbecome_root(void)
618 {
619 	pop_sec_ctx();
620 	pop_conn_ctx();
621 }
622 
623 /****************************************************************************
624  Push the current security context then force a change via change_to_user().
625  Saves and restores the connection context.
626 ****************************************************************************/
627 
become_user_without_service(connection_struct * conn,uint64_t vuid)628 bool become_user_without_service(connection_struct *conn, uint64_t vuid)
629 {
630 	struct auth_session_info *session_info = NULL;
631 	int snum = SNUM(conn);
632 	NTSTATUS status;
633 	bool ok;
634 
635 	if (conn == NULL) {
636 		DBG_WARNING("Connection not open\n");
637 		return false;
638 	}
639 
640 	status = smbXsrv_session_info_lookup(conn->sconn->client,
641 					     vuid,
642 					     &session_info);
643 	if (!NT_STATUS_IS_OK(status)) {
644 		/* Invalid vuid sent */
645 		DBG_WARNING("Invalid vuid %llu used on share %s.\n",
646 			    (unsigned long long)vuid,
647 			    lp_const_servicename(snum));
648 		return false;
649 	}
650 
651 	ok = push_sec_ctx();
652 	if (!ok) {
653 		return false;
654 	}
655 
656 	push_conn_ctx();
657 
658 	ok = change_to_user_impersonate(conn, session_info, vuid);
659 	if (!ok) {
660 		pop_sec_ctx();
661 		pop_conn_ctx();
662 		return false;
663 	}
664 
665 	return true;
666 }
667 
become_user_without_service_by_fsp(struct files_struct * fsp)668 bool become_user_without_service_by_fsp(struct files_struct *fsp)
669 {
670 	return become_user_without_service(fsp->conn, fsp->vuid);
671 }
672 
become_user_without_service_by_session(connection_struct * conn,const struct auth_session_info * session_info)673 bool become_user_without_service_by_session(connection_struct *conn,
674 			    const struct auth_session_info *session_info)
675 {
676 	bool ok;
677 
678 	SMB_ASSERT(conn != NULL);
679 	SMB_ASSERT(session_info != NULL);
680 
681 	ok = push_sec_ctx();
682 	if (!ok) {
683 		return false;
684 	}
685 
686 	push_conn_ctx();
687 
688 	ok = change_to_user_impersonate(conn, session_info, UID_FIELD_INVALID);
689 	if (!ok) {
690 		pop_sec_ctx();
691 		pop_conn_ctx();
692 		return false;
693 	}
694 
695 	return true;
696 }
697 
unbecome_user_without_service(void)698 bool unbecome_user_without_service(void)
699 {
700 	pop_sec_ctx();
701 	pop_conn_ctx();
702 	return True;
703 }
704 
705 /****************************************************************************
706  Return the current user we are running effectively as on this connection.
707  I'd like to make this return conn->session_info->unix_token->uid, but become_root()
708  doesn't alter this value.
709 ****************************************************************************/
710 
get_current_uid(connection_struct * conn)711 uid_t get_current_uid(connection_struct *conn)
712 {
713 	return current_user.ut.uid;
714 }
715 
716 /****************************************************************************
717  Return the current group we are running effectively as on this connection.
718  I'd like to make this return conn->session_info->unix_token->gid, but become_root()
719  doesn't alter this value.
720 ****************************************************************************/
721 
get_current_gid(connection_struct * conn)722 gid_t get_current_gid(connection_struct *conn)
723 {
724 	return current_user.ut.gid;
725 }
726 
727 /****************************************************************************
728  Return the UNIX token we are running effectively as on this connection.
729  I'd like to make this return &conn->session_info->unix_token-> but become_root()
730  doesn't alter this value.
731 ****************************************************************************/
732 
get_current_utok(connection_struct * conn)733 const struct security_unix_token *get_current_utok(connection_struct *conn)
734 {
735 	return &current_user.ut;
736 }
737 
738 /****************************************************************************
739  Return the Windows token we are running effectively as on this connection.
740  If this is currently a NULL token as we're inside become_root() - a temporary
741  UNIX security override, then we search up the stack for the previous active
742  token.
743 ****************************************************************************/
744 
get_current_nttok(connection_struct * conn)745 const struct security_token *get_current_nttok(connection_struct *conn)
746 {
747 	if (current_user.nt_user_token) {
748 		return current_user.nt_user_token;
749 	}
750 	return sec_ctx_active_token();
751 }
752 
get_current_vuid(connection_struct * conn)753 uint64_t get_current_vuid(connection_struct *conn)
754 {
755 	return current_user.vuid;
756 }
757