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