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 18 : bool change_to_guest(void)
39 : {
40 0 : struct passwd *pass;
41 :
42 18 : pass = Get_Pwnam_alloc(talloc_tos(), lp_guest_account());
43 18 : 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 18 : set_sec_ctx(pass->pw_uid, pass->pw_gid, 0, NULL, NULL);
54 :
55 18 : current_user.conn = NULL;
56 18 : current_user.vuid = UID_FIELD_INVALID;
57 :
58 18 : TALLOC_FREE(pass);
59 :
60 18 : return true;
61 : }
62 :
63 : /****************************************************************************
64 : talloc free the conn->session_info if not used in the vuid cache.
65 : ****************************************************************************/
66 :
67 102776 : static void free_conn_session_info_if_unused(connection_struct *conn)
68 : {
69 1602 : unsigned int i;
70 :
71 1649148 : for (i = 0; i < VUID_CACHE_SIZE; i++) {
72 25875 : struct vuid_cache_entry *ent;
73 1600824 : ent = &conn->vuid_cache->array[i];
74 1600824 : if (ent->vuid != UID_FIELD_INVALID &&
75 102680 : conn->session_info == ent->session_info) {
76 53633 : return;
77 : }
78 : }
79 : /* Not used, safe to free. */
80 48324 : TALLOC_FREE(conn->session_info);
81 : }
82 :
83 : /****************************************************************************
84 : Setup the share access mask for a connection.
85 : ****************************************************************************/
86 :
87 96406 : static uint32_t create_share_access_mask(int snum,
88 : bool readonly_share,
89 : const struct security_token *token)
90 : {
91 96406 : uint32_t share_access = 0;
92 :
93 96406 : share_access_check(token,
94 : lp_const_servicename(snum),
95 : MAXIMUM_ALLOWED_ACCESS,
96 : &share_access);
97 :
98 96406 : if (readonly_share) {
99 52946 : 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 96406 : if (security_token_has_privilege(token, SEC_PRIV_SECURITY)) {
106 15582 : share_access |= SEC_FLAG_SYSTEM_SECURITY;
107 : }
108 96406 : if (security_token_has_privilege(token, SEC_PRIV_RESTORE)) {
109 17046 : share_access |= SEC_RIGHTS_PRIV_RESTORE;
110 : }
111 96406 : if (security_token_has_privilege(token, SEC_PRIV_BACKUP)) {
112 15566 : share_access |= SEC_RIGHTS_PRIV_BACKUP;
113 : }
114 96406 : if (security_token_has_privilege(token, SEC_PRIV_TAKE_OWNERSHIP)) {
115 15566 : share_access |= SEC_STD_WRITE_OWNER;
116 : }
117 :
118 96406 : return share_access;
119 : }
120 :
121 : /*******************************************************************
122 : Calculate access mask and if this user can access this share.
123 : ********************************************************************/
124 :
125 96406 : 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 96406 : int snum = SNUM(conn);
131 96406 : uint32_t share_access = 0;
132 96406 : bool readonly_share = false;
133 :
134 96406 : if (!user_ok_token(session_info->unix_info->unix_name,
135 96406 : session_info->info->domain_name,
136 96406 : session_info->security_token, snum)) {
137 0 : return NT_STATUS_ACCESS_DENIED;
138 : }
139 :
140 97948 : readonly_share = is_share_read_only_for_token(
141 96406 : session_info->unix_info->unix_name,
142 96406 : session_info->info->domain_name,
143 96406 : session_info->security_token,
144 : conn);
145 :
146 97948 : share_access = create_share_access_mask(snum,
147 : readonly_share,
148 96406 : session_info->security_token);
149 :
150 96406 : if ((share_access & (FILE_READ_DATA|FILE_WRITE_DATA)) == 0) {
151 : /* No access, read or write. */
152 6 : 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 6 : return NT_STATUS_ACCESS_DENIED;
157 : }
158 :
159 96400 : if (!readonly_share &&
160 43454 : !(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 6 : readonly_share = true;
164 6 : DBG_INFO("falling back to read-only access-evaluation due to "
165 : "security descriptor\n");
166 : }
167 :
168 96400 : *p_share_access = share_access;
169 96400 : *p_readonly_share = readonly_share;
170 :
171 96400 : 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 102776 : 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 1602 : unsigned int i;
187 102776 : bool readonly_share = false;
188 102776 : bool admin_user = false;
189 102776 : struct vuid_cache_entry *ent = NULL;
190 102776 : uint32_t share_access = 0;
191 1602 : NTSTATUS status;
192 :
193 1649592 : for (i=0; i<VUID_CACHE_SIZE; i++) {
194 1601254 : ent = &conn->vuid_cache->array[i];
195 1601254 : if (ent->vuid == vuid) {
196 57638 : if (vuid == UID_FIELD_INVALID) {
197 : /*
198 : * Slow path, we don't care
199 : * about the array traversal.
200 : */
201 3200 : continue;
202 : }
203 54438 : free_conn_session_info_if_unused(conn);
204 54438 : conn->session_info = ent->session_info;
205 54438 : conn->read_only = ent->read_only;
206 54438 : conn->share_access = ent->share_access;
207 54438 : conn->vuid = ent->vuid;
208 54438 : return(True);
209 : }
210 : }
211 :
212 48338 : status = check_user_share_access(conn,
213 : session_info,
214 : &share_access,
215 : &readonly_share);
216 48338 : if (!NT_STATUS_IS_OK(status)) {
217 0 : return false;
218 : }
219 :
220 48338 : admin_user = token_contains_name_in_list(
221 48338 : session_info->unix_info->unix_name,
222 48338 : session_info->info->domain_name,
223 48338 : NULL, session_info->security_token, lp_admin_users(snum));
224 :
225 48338 : ent = &conn->vuid_cache->array[conn->vuid_cache->next_entry];
226 :
227 48338 : conn->vuid_cache->next_entry =
228 48338 : (conn->vuid_cache->next_entry + 1) % VUID_CACHE_SIZE;
229 :
230 48338 : 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 48338 : ent->session_info = copy_session_info(
238 48338 : conn, conn->force_user ? conn->session_info : session_info);
239 :
240 48338 : if (ent->session_info == NULL) {
241 0 : ent->vuid = UID_FIELD_INVALID;
242 0 : return false;
243 : }
244 :
245 48338 : if (admin_user) {
246 88 : 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 88 : 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 48338 : ent->vuid = vuid;
260 48338 : ent->read_only = readonly_share;
261 48338 : ent->share_access = share_access;
262 48338 : free_conn_session_info_if_unused(conn);
263 48338 : conn->session_info = ent->session_info;
264 48338 : conn->vuid = ent->vuid;
265 48338 : 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 100 : ent->read_only = false;
271 100 : ent->share_access = 0;
272 100 : ent->session_info = NULL;
273 : }
274 :
275 48338 : conn->read_only = readonly_share;
276 48338 : conn->share_access = share_access;
277 :
278 48338 : return(True);
279 : }
280 :
281 1835944 : static void print_impersonation_info(connection_struct *conn)
282 : {
283 1835944 : struct smb_filename *cwdfname = NULL;
284 :
285 1835944 : if (!CHECK_DEBUGLVL(DBGLVL_INFO)) {
286 1819025 : 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 1836156 : static bool change_to_user_impersonate(connection_struct *conn,
309 : const struct auth_session_info *session_info,
310 : uint64_t vuid)
311 : {
312 16919 : const struct loadparm_substitution *lp_sub =
313 1836156 : loadparm_s3_global_substitution();
314 16919 : int snum;
315 16919 : gid_t gid;
316 16919 : uid_t uid;
317 16919 : const char *force_group_name;
318 16919 : char group_c;
319 1836156 : int num_groups = 0;
320 1836156 : gid_t *group_list = NULL;
321 16919 : bool ok;
322 :
323 1836156 : if ((current_user.conn == conn) &&
324 1733437 : (current_user.vuid == vuid) &&
325 1733433 : (current_user.ut.uid == session_info->unix_token->uid))
326 : {
327 1733380 : DBG_INFO("Skipping user change - already user\n");
328 1733380 : return true;
329 : }
330 :
331 102776 : set_current_user_info(session_info->unix_info->sanitized_username,
332 102776 : session_info->unix_info->unix_name,
333 102776 : session_info->info->domain_name);
334 :
335 102776 : snum = SNUM(conn);
336 :
337 102776 : ok = check_user_ok(conn, vuid, session_info, snum);
338 102776 : 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 102776 : uid = conn->session_info->unix_token->uid;
348 102776 : gid = conn->session_info->unix_token->gid;
349 102776 : num_groups = conn->session_info->unix_token->ngroups;
350 102776 : 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 102776 : force_group_name = lp_force_group(talloc_tos(), lp_sub, snum);
357 102776 : group_c = *force_group_name;
358 :
359 102776 : 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 4 : 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 102776 : 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 252 : 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 252 : conn->session_info->unix_token->gid = conn->force_group_gid;
411 252 : gid = conn->force_group_gid;
412 252 : gid_to_sid(&conn->session_info->security_token->sids[1],
413 : gid);
414 : }
415 : }
416 :
417 102776 : set_sec_ctx(uid,
418 : gid,
419 : num_groups,
420 : group_list,
421 102776 : conn->session_info->security_token);
422 :
423 102776 : current_user.conn = conn;
424 102776 : current_user.vuid = vuid;
425 102776 : 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 1836061 : bool change_to_user_and_service(connection_struct *conn, uint64_t vuid)
436 : {
437 1836061 : int snum = SNUM(conn);
438 1836061 : struct auth_session_info *si = NULL;
439 16920 : NTSTATUS status;
440 16920 : bool ok;
441 :
442 1836061 : if (conn == NULL) {
443 0 : DBG_WARNING("Connection not open\n");
444 0 : return false;
445 : }
446 :
447 1836061 : status = smbXsrv_session_info_lookup(conn->sconn->client,
448 : vuid,
449 : &si);
450 1836061 : if (!NT_STATUS_IS_OK(status)) {
451 17 : DBG_WARNING("Invalid vuid %llu used on share %s.\n",
452 : (unsigned long long)vuid,
453 : lp_const_servicename(snum));
454 17 : return false;
455 : }
456 :
457 1836044 : ok = change_to_user_impersonate(conn, si, vuid);
458 1836044 : if (!ok) {
459 0 : return false;
460 : }
461 :
462 1836044 : if (conn->tcon_done) {
463 1788000 : ok = chdir_current_service(conn);
464 1788000 : if (!ok) {
465 100 : return false;
466 : }
467 : }
468 :
469 1835944 : print_impersonation_info(conn);
470 1835944 : 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 91820 : bool change_to_user_and_service_by_fsp(struct files_struct *fsp)
481 : {
482 91820 : 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 787520 : bool smbd_change_to_root_user(void)
491 : {
492 787520 : set_root_sec_ctx();
493 :
494 787520 : 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 787520 : current_user.conn = NULL;
498 787520 : current_user.vuid = UID_FIELD_INVALID;
499 :
500 787520 : 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 614643 : bool smbd_become_authenticated_pipe_user(struct auth_session_info *session_info)
510 : {
511 614643 : if (!push_sec_ctx())
512 0 : return False;
513 :
514 614643 : set_current_user_info(session_info->unix_info->sanitized_username,
515 614643 : session_info->unix_info->unix_name,
516 614643 : session_info->info->domain_name);
517 :
518 614643 : set_sec_ctx(session_info->unix_token->uid, session_info->unix_token->gid,
519 614643 : session_info->unix_token->ngroups, session_info->unix_token->groups,
520 614643 : session_info->security_token);
521 :
522 614643 : 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 614643 : 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 614643 : bool smbd_unbecome_authenticated_pipe_user(void)
539 : {
540 614643 : return pop_sec_ctx();
541 : }
542 :
543 : /****************************************************************************
544 : Utility functions used by become_xxx/unbecome_xxx.
545 : ****************************************************************************/
546 :
547 3924365 : static void push_conn_ctx(void)
548 : {
549 7602 : struct conn_ctx *ctx_p;
550 7602 : extern userdom_struct current_user_info;
551 :
552 : /* Check we don't overflow our stack */
553 :
554 3924365 : 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 3924365 : ctx_p = &conn_ctx_stack[conn_ctx_stack_ndx];
561 :
562 3924365 : ctx_p->conn = current_user.conn;
563 3924365 : ctx_p->vuid = current_user.vuid;
564 3924365 : ctx_p->user_info = current_user_info;
565 :
566 3924365 : 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 3924365 : conn_ctx_stack_ndx++;
570 3924365 : }
571 :
572 3924359 : static void pop_conn_ctx(void)
573 : {
574 7602 : struct conn_ctx *ctx_p;
575 :
576 : /* Check for stack underflow. */
577 :
578 3924359 : 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 3924359 : conn_ctx_stack_ndx--;
584 3924359 : ctx_p = &conn_ctx_stack[conn_ctx_stack_ndx];
585 :
586 3924359 : set_current_user_info(ctx_p->user_info.smb_name,
587 3924359 : ctx_p->user_info.unix_name,
588 3924359 : ctx_p->user_info.domain);
589 :
590 3924359 : current_user.conn = ctx_p->conn;
591 3924359 : current_user.vuid = ctx_p->vuid;
592 :
593 3924359 : *ctx_p = (struct conn_ctx) {
594 : .vuid = UID_FIELD_INVALID,
595 : };
596 3924359 : }
597 :
598 : /****************************************************************************
599 : Temporarily become a root user. Must match with unbecome_root(). Saves and
600 : restores the connection context.
601 : ****************************************************************************/
602 :
603 3924253 : 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 3924253 : if (!push_sec_ctx()) {
610 0 : smb_panic("become_root: push_sec_ctx failed");
611 : }
612 3924253 : push_conn_ctx();
613 3924253 : set_root_sec_ctx();
614 3924253 : }
615 :
616 : /* Unbecome the root user */
617 :
618 3924253 : void smbd_unbecome_root(void)
619 : {
620 3924253 : pop_sec_ctx();
621 3924253 : pop_conn_ctx();
622 3924253 : }
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 0 : NTSTATUS status;
634 0 : 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 100 : bool become_user_without_service_by_session(connection_struct *conn,
675 : const struct auth_session_info *session_info)
676 : {
677 0 : bool ok;
678 :
679 100 : SMB_ASSERT(conn != NULL);
680 100 : SMB_ASSERT(session_info != NULL);
681 :
682 100 : ok = push_sec_ctx();
683 100 : if (!ok) {
684 0 : return false;
685 : }
686 :
687 100 : push_conn_ctx();
688 :
689 100 : ok = change_to_user_impersonate(conn, session_info, UID_FIELD_INVALID);
690 100 : if (!ok) {
691 0 : pop_sec_ctx();
692 0 : pop_conn_ctx();
693 0 : return false;
694 : }
695 :
696 100 : return true;
697 : }
698 :
699 106 : bool unbecome_user_without_service(void)
700 : {
701 106 : pop_sec_ctx();
702 106 : pop_conn_ctx();
703 106 : 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 1210082 : uid_t get_current_uid(connection_struct *conn)
713 : {
714 1210082 : 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 5582 : gid_t get_current_gid(connection_struct *conn)
724 : {
725 5582 : 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 171001 : const struct security_unix_token *get_current_utok(connection_struct *conn)
735 : {
736 171001 : 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 671016 : const struct security_token *get_current_nttok(connection_struct *conn)
747 : {
748 671016 : if (current_user.nt_user_token) {
749 669213 : return current_user.nt_user_token;
750 : }
751 0 : return sec_ctx_active_token();
752 : }
|