| 1 | /* 
 | 
|---|
| 2 |    Unix SMB/CIFS implementation.
 | 
|---|
| 3 |    uid/user handling
 | 
|---|
| 4 |    Copyright (C) Tim Potter 2000
 | 
|---|
| 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 "smbd/globals.h"
 | 
|---|
| 22 | 
 | 
|---|
| 23 | extern struct current_user current_user;
 | 
|---|
| 24 | 
 | 
|---|
| 25 | /****************************************************************************
 | 
|---|
| 26 |  Are two UNIX tokens equal ?
 | 
|---|
| 27 | ****************************************************************************/
 | 
|---|
| 28 | 
 | 
|---|
| 29 | bool unix_token_equal(const UNIX_USER_TOKEN *t1, const UNIX_USER_TOKEN *t2)
 | 
|---|
| 30 | {
 | 
|---|
| 31 |         if (t1->uid != t2->uid || t1->gid != t2->gid ||
 | 
|---|
| 32 |                         t1->ngroups != t2->ngroups) {
 | 
|---|
| 33 |                 return false;
 | 
|---|
| 34 |         }
 | 
|---|
| 35 |         if (memcmp(t1->groups, t2->groups,
 | 
|---|
| 36 |                         t1->ngroups*sizeof(gid_t)) != 0) {
 | 
|---|
| 37 |                 return false;
 | 
|---|
| 38 |         }
 | 
|---|
| 39 |         return true;
 | 
|---|
| 40 | }
 | 
|---|
| 41 | 
 | 
|---|
| 42 | /****************************************************************************
 | 
|---|
| 43 |  Become the specified uid.
 | 
|---|
| 44 | ****************************************************************************/
 | 
|---|
| 45 | 
 | 
|---|
| 46 | static bool become_uid(uid_t uid)
 | 
|---|
| 47 | {
 | 
|---|
| 48 |         /* Check for dodgy uid values */
 | 
|---|
| 49 | 
 | 
|---|
| 50 |         if (uid == (uid_t)-1 || 
 | 
|---|
| 51 |             ((sizeof(uid_t) == 2) && (uid == (uid_t)65535))) {
 | 
|---|
| 52 |                 if (!become_uid_done) {
 | 
|---|
| 53 |                         DEBUG(1,("WARNING: using uid %d is a security risk\n",
 | 
|---|
| 54 |                                  (int)uid));
 | 
|---|
| 55 |                         become_uid_done = true;
 | 
|---|
| 56 |                 }
 | 
|---|
| 57 |         }
 | 
|---|
| 58 | 
 | 
|---|
| 59 |         /* Set effective user id */
 | 
|---|
| 60 | 
 | 
|---|
| 61 |         set_effective_uid(uid);
 | 
|---|
| 62 | 
 | 
|---|
| 63 |         DO_PROFILE_INC(uid_changes);
 | 
|---|
| 64 |         return True;
 | 
|---|
| 65 | }
 | 
|---|
| 66 | 
 | 
|---|
| 67 | /****************************************************************************
 | 
|---|
| 68 |  Become the specified gid.
 | 
|---|
| 69 | ****************************************************************************/
 | 
|---|
| 70 | 
 | 
|---|
| 71 | static bool become_gid(gid_t gid)
 | 
|---|
| 72 | {
 | 
|---|
| 73 |         /* Check for dodgy gid values */
 | 
|---|
| 74 | 
 | 
|---|
| 75 |         if (gid == (gid_t)-1 || ((sizeof(gid_t) == 2) && 
 | 
|---|
| 76 |                                  (gid == (gid_t)65535))) {
 | 
|---|
| 77 |                 if (!become_gid_done) {
 | 
|---|
| 78 |                         DEBUG(1,("WARNING: using gid %d is a security risk\n",
 | 
|---|
| 79 |                                  (int)gid));  
 | 
|---|
| 80 |                         become_gid_done = true;
 | 
|---|
| 81 |                 }
 | 
|---|
| 82 |         }
 | 
|---|
| 83 |   
 | 
|---|
| 84 |         /* Set effective group id */
 | 
|---|
| 85 | 
 | 
|---|
| 86 |         set_effective_gid(gid);
 | 
|---|
| 87 |         return True;
 | 
|---|
| 88 | }
 | 
|---|
| 89 | 
 | 
|---|
| 90 | /****************************************************************************
 | 
|---|
| 91 |  Become the specified uid and gid.
 | 
|---|
| 92 | ****************************************************************************/
 | 
|---|
| 93 | 
 | 
|---|
| 94 | static bool become_id(uid_t uid, gid_t gid)
 | 
|---|
| 95 | {
 | 
|---|
| 96 |         return become_gid(gid) && become_uid(uid);
 | 
|---|
| 97 | }
 | 
|---|
| 98 | 
 | 
|---|
| 99 | /****************************************************************************
 | 
|---|
| 100 |  Drop back to root privileges in order to change to another user.
 | 
|---|
| 101 | ****************************************************************************/
 | 
|---|
| 102 | 
 | 
|---|
| 103 | static void gain_root(void)
 | 
|---|
| 104 | {
 | 
|---|
| 105 |         if (non_root_mode()) {
 | 
|---|
| 106 |                 return;
 | 
|---|
| 107 |         }
 | 
|---|
| 108 | 
 | 
|---|
| 109 |         if (geteuid() != 0) {
 | 
|---|
| 110 |                 set_effective_uid(0);
 | 
|---|
| 111 | 
 | 
|---|
| 112 |                 if (geteuid() != 0) {
 | 
|---|
| 113 |                         DEBUG(0,
 | 
|---|
| 114 |                               ("Warning: You appear to have a trapdoor "
 | 
|---|
| 115 |                                "uid system\n"));
 | 
|---|
| 116 |                 }
 | 
|---|
| 117 |         }
 | 
|---|
| 118 | 
 | 
|---|
| 119 |         if (getegid() != 0) {
 | 
|---|
| 120 |                 set_effective_gid(0);
 | 
|---|
| 121 | 
 | 
|---|
| 122 |                 if (getegid() != 0) {
 | 
|---|
| 123 |                         DEBUG(0,
 | 
|---|
| 124 |                               ("Warning: You appear to have a trapdoor "
 | 
|---|
| 125 |                                "gid system\n"));
 | 
|---|
| 126 |                 }
 | 
|---|
| 127 |         }
 | 
|---|
| 128 | }
 | 
|---|
| 129 | 
 | 
|---|
| 130 | /****************************************************************************
 | 
|---|
| 131 |  Get the list of current groups.
 | 
|---|
| 132 | ****************************************************************************/
 | 
|---|
| 133 | 
 | 
|---|
| 134 | static int get_current_groups(gid_t gid, size_t *p_ngroups, gid_t **p_groups)
 | 
|---|
| 135 | {
 | 
|---|
| 136 |         int i;
 | 
|---|
| 137 |         gid_t grp;
 | 
|---|
| 138 |         int ngroups;
 | 
|---|
| 139 |         gid_t *groups = NULL;
 | 
|---|
| 140 | 
 | 
|---|
| 141 |         (*p_ngroups) = 0;
 | 
|---|
| 142 |         (*p_groups) = NULL;
 | 
|---|
| 143 | 
 | 
|---|
| 144 |         /* this looks a little strange, but is needed to cope with
 | 
|---|
| 145 |            systems that put the current egid in the group list
 | 
|---|
| 146 |            returned from getgroups() (tridge) */
 | 
|---|
| 147 |         save_re_gid();
 | 
|---|
| 148 |         set_effective_gid(gid);
 | 
|---|
| 149 |         setgid(gid);
 | 
|---|
| 150 | 
 | 
|---|
| 151 |         ngroups = sys_getgroups(0,&grp);
 | 
|---|
| 152 |         if (ngroups <= 0) {
 | 
|---|
| 153 |                 goto fail;
 | 
|---|
| 154 |         }
 | 
|---|
| 155 | 
 | 
|---|
| 156 |         if((groups = SMB_MALLOC_ARRAY(gid_t, ngroups+1)) == NULL) {
 | 
|---|
| 157 |                 DEBUG(0,("setup_groups malloc fail !\n"));
 | 
|---|
| 158 |                 goto fail;
 | 
|---|
| 159 |         }
 | 
|---|
| 160 | 
 | 
|---|
| 161 |         if ((ngroups = sys_getgroups(ngroups,groups)) == -1) {
 | 
|---|
| 162 |                 goto fail;
 | 
|---|
| 163 |         }
 | 
|---|
| 164 | 
 | 
|---|
| 165 |         restore_re_gid();
 | 
|---|
| 166 | 
 | 
|---|
| 167 |         (*p_ngroups) = ngroups;
 | 
|---|
| 168 |         (*p_groups) = groups;
 | 
|---|
| 169 | 
 | 
|---|
| 170 |         DEBUG( 3, ( "get_current_groups: user is in %u groups: ", ngroups));
 | 
|---|
| 171 |         for (i = 0; i < ngroups; i++ ) {
 | 
|---|
| 172 |                 DEBUG( 3, ( "%s%d", (i ? ", " : ""), (int)groups[i] ) );
 | 
|---|
| 173 |         }
 | 
|---|
| 174 |         DEBUG( 3, ( "\n" ) );
 | 
|---|
| 175 | 
 | 
|---|
| 176 |         return ngroups;
 | 
|---|
| 177 | 
 | 
|---|
| 178 | fail:
 | 
|---|
| 179 |         SAFE_FREE(groups);
 | 
|---|
| 180 |         restore_re_gid();
 | 
|---|
| 181 |         return -1;
 | 
|---|
| 182 | }
 | 
|---|
| 183 | 
 | 
|---|
| 184 | /****************************************************************************
 | 
|---|
| 185 |  Create a new security context on the stack.  It is the same as the old
 | 
|---|
| 186 |  one.  User changes are done using the set_sec_ctx() function.
 | 
|---|
| 187 | ****************************************************************************/
 | 
|---|
| 188 | 
 | 
|---|
| 189 | bool push_sec_ctx(void)
 | 
|---|
| 190 | {
 | 
|---|
| 191 |         struct sec_ctx *ctx_p;
 | 
|---|
| 192 | 
 | 
|---|
| 193 |         /* Check we don't overflow our stack */
 | 
|---|
| 194 | 
 | 
|---|
| 195 |         if (sec_ctx_stack_ndx == MAX_SEC_CTX_DEPTH) {
 | 
|---|
| 196 |                 DEBUG(0, ("Security context stack overflow!\n"));
 | 
|---|
| 197 |                 smb_panic("Security context stack overflow!");
 | 
|---|
| 198 |         }
 | 
|---|
| 199 | 
 | 
|---|
| 200 |         /* Store previous user context */
 | 
|---|
| 201 | 
 | 
|---|
| 202 |         sec_ctx_stack_ndx++;
 | 
|---|
| 203 | 
 | 
|---|
| 204 |         ctx_p = &sec_ctx_stack[sec_ctx_stack_ndx];
 | 
|---|
| 205 | 
 | 
|---|
| 206 |         ctx_p->ut.uid = geteuid();
 | 
|---|
| 207 |         ctx_p->ut.gid = getegid();
 | 
|---|
| 208 | 
 | 
|---|
| 209 |         DEBUG(3, ("push_sec_ctx(%u, %u) : sec_ctx_stack_ndx = %d\n", 
 | 
|---|
| 210 |                   (unsigned int)ctx_p->ut.uid, (unsigned int)ctx_p->ut.gid, sec_ctx_stack_ndx ));
 | 
|---|
| 211 | 
 | 
|---|
| 212 |         ctx_p->token = dup_nt_token(NULL,
 | 
|---|
| 213 |                                     sec_ctx_stack[sec_ctx_stack_ndx-1].token);
 | 
|---|
| 214 | 
 | 
|---|
| 215 |         ctx_p->ut.ngroups = sys_getgroups(0, NULL);
 | 
|---|
| 216 | 
 | 
|---|
| 217 |         if (ctx_p->ut.ngroups != 0) {
 | 
|---|
| 218 |                 if (!(ctx_p->ut.groups = SMB_MALLOC_ARRAY(gid_t, ctx_p->ut.ngroups))) {
 | 
|---|
| 219 |                         DEBUG(0, ("Out of memory in push_sec_ctx()\n"));
 | 
|---|
| 220 |                         TALLOC_FREE(ctx_p->token);
 | 
|---|
| 221 |                         return False;
 | 
|---|
| 222 |                 }
 | 
|---|
| 223 | 
 | 
|---|
| 224 |                 sys_getgroups(ctx_p->ut.ngroups, ctx_p->ut.groups);
 | 
|---|
| 225 |         } else {
 | 
|---|
| 226 |                 ctx_p->ut.groups = NULL;
 | 
|---|
| 227 |         }
 | 
|---|
| 228 | 
 | 
|---|
| 229 |         return True;
 | 
|---|
| 230 | }
 | 
|---|
| 231 | 
 | 
|---|
| 232 | /****************************************************************************
 | 
|---|
| 233 |  Change UNIX security context. Calls panic if not successful so no return value.
 | 
|---|
| 234 | ****************************************************************************/
 | 
|---|
| 235 | 
 | 
|---|
| 236 | #ifndef HAVE_DARWIN_INITGROUPS
 | 
|---|
| 237 | 
 | 
|---|
| 238 | /* Normal credential switch path. */
 | 
|---|
| 239 | 
 | 
|---|
| 240 | static void set_unix_security_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups)
 | 
|---|
| 241 | {
 | 
|---|
| 242 |         /* Start context switch */
 | 
|---|
| 243 |         gain_root();
 | 
|---|
| 244 | #ifdef HAVE_SETGROUPS
 | 
|---|
| 245 |         if (sys_setgroups(gid, ngroups, groups) != 0 && !non_root_mode()) {
 | 
|---|
| 246 |                 smb_panic("sys_setgroups failed");
 | 
|---|
| 247 |         }
 | 
|---|
| 248 | #endif
 | 
|---|
| 249 |         become_id(uid, gid);
 | 
|---|
| 250 |         /* end context switch */
 | 
|---|
| 251 | }
 | 
|---|
| 252 | 
 | 
|---|
| 253 | #else /* HAVE_DARWIN_INITGROUPS */
 | 
|---|
| 254 | 
 | 
|---|
| 255 | /* The Darwin groups implementation is a little unusual. The list of
 | 
|---|
| 256 | * groups in the kernel credential is not exhaustive, but more like
 | 
|---|
| 257 | * a cache. The full group list is held in userspace and checked
 | 
|---|
| 258 | * dynamically.
 | 
|---|
| 259 | *
 | 
|---|
| 260 | * This is an optional mechanism, and setgroups(2) opts out
 | 
|---|
| 261 | * of it. That is, if you call setgroups, then the list of groups you
 | 
|---|
| 262 | * set are the only groups that are ever checked. This is not what we
 | 
|---|
| 263 | * want. We want to opt in to the dynamic resolution mechanism, so we
 | 
|---|
| 264 | * need to specify the uid of the user whose group list (cache) we are
 | 
|---|
| 265 | * setting.
 | 
|---|
| 266 | *
 | 
|---|
| 267 | * The Darwin rules are:
 | 
|---|
| 268 | *  1. Thou shalt setegid, initgroups and seteuid IN THAT ORDER
 | 
|---|
| 269 | *  2. Thou shalt not pass more that NGROUPS_MAX to initgroups
 | 
|---|
| 270 | *  3. Thou shalt leave the first entry in the groups list well alone
 | 
|---|
| 271 | */
 | 
|---|
| 272 | 
 | 
|---|
| 273 | #include <sys/syscall.h>
 | 
|---|
| 274 | 
 | 
|---|
| 275 | static void set_unix_security_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups)
 | 
|---|
| 276 | {
 | 
|---|
| 277 |         int max = groups_max();
 | 
|---|
| 278 | 
 | 
|---|
| 279 |         /* Start context switch */
 | 
|---|
| 280 |         gain_root();
 | 
|---|
| 281 | 
 | 
|---|
| 282 |         become_gid(gid);
 | 
|---|
| 283 | 
 | 
|---|
| 284 | 
 | 
|---|
| 285 |         if (syscall(SYS_initgroups, (ngroups > max) ? max : ngroups,
 | 
|---|
| 286 |                         groups, uid) == -1 && !non_root_mode()) {
 | 
|---|
| 287 |                 DEBUG(0, ("WARNING: failed to set group list "
 | 
|---|
| 288 |                         "(%d groups) for UID %ld: %s\n",
 | 
|---|
| 289 |                         ngroups, uid, strerror(errno)));
 | 
|---|
| 290 |                 smb_panic("sys_setgroups failed");
 | 
|---|
| 291 |         }
 | 
|---|
| 292 | 
 | 
|---|
| 293 |         become_uid(uid);
 | 
|---|
| 294 |         /* end context switch */
 | 
|---|
| 295 | }
 | 
|---|
| 296 | 
 | 
|---|
| 297 | #endif /* HAVE_DARWIN_INITGROUPS */
 | 
|---|
| 298 | 
 | 
|---|
| 299 | /****************************************************************************
 | 
|---|
| 300 |  Set the current security context to a given user.
 | 
|---|
| 301 | ****************************************************************************/
 | 
|---|
| 302 | 
 | 
|---|
| 303 | void set_sec_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups, NT_USER_TOKEN *token)
 | 
|---|
| 304 | {
 | 
|---|
| 305 |         struct sec_ctx *ctx_p = &sec_ctx_stack[sec_ctx_stack_ndx];
 | 
|---|
| 306 |         
 | 
|---|
| 307 |         /* Set the security context */
 | 
|---|
| 308 | 
 | 
|---|
| 309 |         DEBUG(3, ("setting sec ctx (%u, %u) - sec_ctx_stack_ndx = %d\n", 
 | 
|---|
| 310 |                 (unsigned int)uid, (unsigned int)gid, sec_ctx_stack_ndx));
 | 
|---|
| 311 | 
 | 
|---|
| 312 |         debug_nt_user_token(DBGC_CLASS, 5, token);
 | 
|---|
| 313 |         debug_unix_user_token(DBGC_CLASS, 5, uid, gid, ngroups, groups);
 | 
|---|
| 314 | 
 | 
|---|
| 315 |         /* Change uid, gid and supplementary group list. */
 | 
|---|
| 316 |         set_unix_security_ctx(uid, gid, ngroups, groups);
 | 
|---|
| 317 | 
 | 
|---|
| 318 |         ctx_p->ut.ngroups = ngroups;
 | 
|---|
| 319 | 
 | 
|---|
| 320 |         SAFE_FREE(ctx_p->ut.groups);
 | 
|---|
| 321 |         if (token && (token == ctx_p->token)) {
 | 
|---|
| 322 |                 smb_panic("DUPLICATE_TOKEN");
 | 
|---|
| 323 |         }
 | 
|---|
| 324 | 
 | 
|---|
| 325 |         TALLOC_FREE(ctx_p->token);
 | 
|---|
| 326 |         
 | 
|---|
| 327 |         if (ngroups) {
 | 
|---|
| 328 |                 ctx_p->ut.groups = (gid_t *)memdup(groups,
 | 
|---|
| 329 |                                                    sizeof(gid_t) * ngroups);
 | 
|---|
| 330 |                 if (!ctx_p->ut.groups) {
 | 
|---|
| 331 |                         smb_panic("memdup failed");
 | 
|---|
| 332 |                 }
 | 
|---|
| 333 |         } else {
 | 
|---|
| 334 |                 ctx_p->ut.groups = NULL;
 | 
|---|
| 335 |         }
 | 
|---|
| 336 | 
 | 
|---|
| 337 |         if (token) {
 | 
|---|
| 338 |                 ctx_p->token = dup_nt_token(NULL, token);
 | 
|---|
| 339 |                 if (!ctx_p->token) {
 | 
|---|
| 340 |                         smb_panic("dup_nt_token failed");
 | 
|---|
| 341 |                 }
 | 
|---|
| 342 |         } else {
 | 
|---|
| 343 |                 ctx_p->token = NULL;
 | 
|---|
| 344 |         }
 | 
|---|
| 345 | 
 | 
|---|
| 346 |         ctx_p->ut.uid = uid;
 | 
|---|
| 347 |         ctx_p->ut.gid = gid;
 | 
|---|
| 348 | 
 | 
|---|
| 349 |         /* Update current_user stuff */
 | 
|---|
| 350 | 
 | 
|---|
| 351 |         current_user.ut.uid = uid;
 | 
|---|
| 352 |         current_user.ut.gid = gid;
 | 
|---|
| 353 |         current_user.ut.ngroups = ngroups;
 | 
|---|
| 354 |         current_user.ut.groups = groups;
 | 
|---|
| 355 |         current_user.nt_user_token = ctx_p->token;
 | 
|---|
| 356 | }
 | 
|---|
| 357 | 
 | 
|---|
| 358 | /****************************************************************************
 | 
|---|
| 359 |  Become root context.
 | 
|---|
| 360 | ****************************************************************************/
 | 
|---|
| 361 | 
 | 
|---|
| 362 | void set_root_sec_ctx(void)
 | 
|---|
| 363 | {
 | 
|---|
| 364 |         /* May need to worry about supplementary groups at some stage */
 | 
|---|
| 365 | 
 | 
|---|
| 366 |         set_sec_ctx(0, 0, 0, NULL, NULL);
 | 
|---|
| 367 | }
 | 
|---|
| 368 | 
 | 
|---|
| 369 | /****************************************************************************
 | 
|---|
| 370 |  Pop a security context from the stack.
 | 
|---|
| 371 | ****************************************************************************/
 | 
|---|
| 372 | 
 | 
|---|
| 373 | bool pop_sec_ctx(void)
 | 
|---|
| 374 | {
 | 
|---|
| 375 |         struct sec_ctx *ctx_p;
 | 
|---|
| 376 |         struct sec_ctx *prev_ctx_p;
 | 
|---|
| 377 | 
 | 
|---|
| 378 |         /* Check for stack underflow */
 | 
|---|
| 379 | 
 | 
|---|
| 380 |         if (sec_ctx_stack_ndx == 0) {
 | 
|---|
| 381 |                 DEBUG(0, ("Security context stack underflow!\n"));
 | 
|---|
| 382 |                 smb_panic("Security context stack underflow!");
 | 
|---|
| 383 |         }
 | 
|---|
| 384 | 
 | 
|---|
| 385 |         ctx_p = &sec_ctx_stack[sec_ctx_stack_ndx];
 | 
|---|
| 386 | 
 | 
|---|
| 387 |         /* Clear previous user info */
 | 
|---|
| 388 | 
 | 
|---|
| 389 |         ctx_p->ut.uid = (uid_t)-1;
 | 
|---|
| 390 |         ctx_p->ut.gid = (gid_t)-1;
 | 
|---|
| 391 | 
 | 
|---|
| 392 |         SAFE_FREE(ctx_p->ut.groups);
 | 
|---|
| 393 |         ctx_p->ut.ngroups = 0;
 | 
|---|
| 394 | 
 | 
|---|
| 395 |         TALLOC_FREE(ctx_p->token);
 | 
|---|
| 396 | 
 | 
|---|
| 397 |         /* Pop back previous user */
 | 
|---|
| 398 | 
 | 
|---|
| 399 |         sec_ctx_stack_ndx--;
 | 
|---|
| 400 | 
 | 
|---|
| 401 |         prev_ctx_p = &sec_ctx_stack[sec_ctx_stack_ndx];
 | 
|---|
| 402 | 
 | 
|---|
| 403 |         /* Change uid, gid and supplementary group list. */
 | 
|---|
| 404 |         set_unix_security_ctx(prev_ctx_p->ut.uid,
 | 
|---|
| 405 |                         prev_ctx_p->ut.gid,
 | 
|---|
| 406 |                         prev_ctx_p->ut.ngroups,
 | 
|---|
| 407 |                         prev_ctx_p->ut.groups);
 | 
|---|
| 408 | 
 | 
|---|
| 409 |         /* Update current_user stuff */
 | 
|---|
| 410 | 
 | 
|---|
| 411 |         current_user.ut.uid = prev_ctx_p->ut.uid;
 | 
|---|
| 412 |         current_user.ut.gid = prev_ctx_p->ut.gid;
 | 
|---|
| 413 |         current_user.ut.ngroups = prev_ctx_p->ut.ngroups;
 | 
|---|
| 414 |         current_user.ut.groups = prev_ctx_p->ut.groups;
 | 
|---|
| 415 |         current_user.nt_user_token = prev_ctx_p->token;
 | 
|---|
| 416 | 
 | 
|---|
| 417 |         DEBUG(3, ("pop_sec_ctx (%u, %u) - sec_ctx_stack_ndx = %d\n", 
 | 
|---|
| 418 |                 (unsigned int)geteuid(), (unsigned int)getegid(), sec_ctx_stack_ndx));
 | 
|---|
| 419 | 
 | 
|---|
| 420 |         return True;
 | 
|---|
| 421 | }
 | 
|---|
| 422 | 
 | 
|---|
| 423 | /* Initialise the security context system */
 | 
|---|
| 424 | 
 | 
|---|
| 425 | void init_sec_ctx(void)
 | 
|---|
| 426 | {
 | 
|---|
| 427 |         int i;
 | 
|---|
| 428 |         struct sec_ctx *ctx_p;
 | 
|---|
| 429 | 
 | 
|---|
| 430 |         /* Initialise security context stack */
 | 
|---|
| 431 | 
 | 
|---|
| 432 |         memset(sec_ctx_stack, 0, sizeof(struct sec_ctx) * MAX_SEC_CTX_DEPTH);
 | 
|---|
| 433 | 
 | 
|---|
| 434 |         for (i = 0; i < MAX_SEC_CTX_DEPTH; i++) {
 | 
|---|
| 435 |                 sec_ctx_stack[i].ut.uid = (uid_t)-1;
 | 
|---|
| 436 |                 sec_ctx_stack[i].ut.gid = (gid_t)-1;
 | 
|---|
| 437 |         }
 | 
|---|
| 438 | 
 | 
|---|
| 439 |         /* Initialise first level of stack.  It is the current context */
 | 
|---|
| 440 |         ctx_p = &sec_ctx_stack[0];
 | 
|---|
| 441 | 
 | 
|---|
| 442 |         ctx_p->ut.uid = geteuid();
 | 
|---|
| 443 |         ctx_p->ut.gid = getegid();
 | 
|---|
| 444 | 
 | 
|---|
| 445 |         get_current_groups(ctx_p->ut.gid, &ctx_p->ut.ngroups, &ctx_p->ut.groups);
 | 
|---|
| 446 | 
 | 
|---|
| 447 |         ctx_p->token = NULL; /* Maps to guest user. */
 | 
|---|
| 448 | 
 | 
|---|
| 449 |         /* Initialise current_user global */
 | 
|---|
| 450 | 
 | 
|---|
| 451 |         current_user.ut.uid = ctx_p->ut.uid;
 | 
|---|
| 452 |         current_user.ut.gid = ctx_p->ut.gid;
 | 
|---|
| 453 |         current_user.ut.ngroups = ctx_p->ut.ngroups;
 | 
|---|
| 454 |         current_user.ut.groups = ctx_p->ut.groups;
 | 
|---|
| 455 | 
 | 
|---|
| 456 |         /* The conn and vuid are usually taken care of by other modules.
 | 
|---|
| 457 |            We initialise them here. */
 | 
|---|
| 458 | 
 | 
|---|
| 459 |         current_user.conn = NULL;
 | 
|---|
| 460 |         current_user.vuid = UID_FIELD_INVALID;
 | 
|---|
| 461 |         current_user.nt_user_token = NULL;
 | 
|---|
| 462 | }
 | 
|---|