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