root/source3/auth/token_util.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. nt_token_check_sid
  2. nt_token_check_domain_rid
  3. get_root_nt_token
  4. add_aliases
  5. add_builtin_administrators
  6. create_builtin
  7. add_sid_to_builtin
  8. create_builtin_users
  9. create_builtin_administrators
  10. create_local_nt_token
  11. debug_nt_user_token
  12. debug_unix_user_token

   1 /*
   2  *  Unix SMB/CIFS implementation.
   3  *  Authentication utility functions
   4  *  Copyright (C) Andrew Tridgell 1992-1998
   5  *  Copyright (C) Andrew Bartlett 2001
   6  *  Copyright (C) Jeremy Allison 2000-2001
   7  *  Copyright (C) Rafal Szczesniak 2002
   8  *  Copyright (C) Volker Lendecke 2006
   9  *  Copyright (C) Michael Adam 2007
  10  *
  11  *  This program is free software; you can redistribute it and/or modify
  12  *  it under the terms of the GNU General Public License as published by
  13  *  the Free Software Foundation; either version 3 of the License, or
  14  *  (at your option) any later version.
  15  *
  16  *  This program is distributed in the hope that it will be useful,
  17  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  18  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19  *  GNU General Public License for more details.
  20  *
  21  *  You should have received a copy of the GNU General Public License
  22  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
  23  */
  24 
  25 /* functions moved from auth/auth_util.c to minimize linker deps */
  26 
  27 #include "includes.h"
  28 
  29 /****************************************************************************
  30  Check for a SID in an NT_USER_TOKEN
  31 ****************************************************************************/
  32 
  33 bool nt_token_check_sid ( const DOM_SID *sid, const NT_USER_TOKEN *token )
     /* [<][>][^][v][top][bottom][index][help] */
  34 {
  35         int i;
  36 
  37         if ( !sid || !token )
  38                 return False;
  39 
  40         for ( i=0; i<token->num_sids; i++ ) {
  41                 if ( sid_equal( sid, &token->user_sids[i] ) )
  42                         return True;
  43         }
  44 
  45         return False;
  46 }
  47 
  48 bool nt_token_check_domain_rid( NT_USER_TOKEN *token, uint32 rid )
     /* [<][>][^][v][top][bottom][index][help] */
  49 {
  50         DOM_SID domain_sid;
  51 
  52         /* if we are a domain member, the get the domain SID, else for
  53            a DC or standalone server, use our own SID */
  54 
  55         if ( lp_server_role() == ROLE_DOMAIN_MEMBER ) {
  56                 if ( !secrets_fetch_domain_sid( lp_workgroup(),
  57                                                 &domain_sid ) ) {
  58                         DEBUG(1,("nt_token_check_domain_rid: Cannot lookup "
  59                                  "SID for domain [%s]\n", lp_workgroup()));
  60                         return False;
  61                 }
  62         }
  63         else
  64                 sid_copy( &domain_sid, get_global_sam_sid() );
  65 
  66         sid_append_rid( &domain_sid, rid );
  67 
  68         return nt_token_check_sid( &domain_sid, token );\
  69 }
  70 
  71 /******************************************************************************
  72  Create a token for the root user to be used internally by smbd.
  73  This is similar to running under the context of the LOCAL_SYSTEM account
  74  in Windows.  This is a read-only token.  Do not modify it or free() it.
  75  Create a copy if your need to change it.
  76 ******************************************************************************/
  77 
  78 NT_USER_TOKEN *get_root_nt_token( void )
     /* [<][>][^][v][top][bottom][index][help] */
  79 {
  80         struct nt_user_token *token, *for_cache;
  81         DOM_SID u_sid, g_sid;
  82         struct passwd *pw;
  83         void *cache_data;
  84 
  85         cache_data = memcache_lookup_talloc(
  86                 NULL, SINGLETON_CACHE_TALLOC,
  87                 data_blob_string_const_null("root_nt_token"));
  88 
  89         if (cache_data != NULL) {
  90                 return talloc_get_type_abort(
  91                         cache_data, struct nt_user_token);
  92         }
  93 
  94         if ( !(pw = sys_getpwnam( "root" )) ) {
  95                 DEBUG(0,("get_root_nt_token: getpwnam(\"root\") failed!\n"));
  96                 return NULL;
  97         }
  98 
  99         /* get the user and primary group SIDs; although the
 100            BUILTIN\Administrators SId is really the one that matters here */
 101 
 102         uid_to_sid(&u_sid, pw->pw_uid);
 103         gid_to_sid(&g_sid, pw->pw_gid);
 104 
 105         token = create_local_nt_token(talloc_autofree_context(), &u_sid, False,
 106                                       1, &global_sid_Builtin_Administrators);
 107 
 108         token->privileges = se_disk_operators;
 109 
 110         for_cache = token;
 111 
 112         memcache_add_talloc(
 113                 NULL, SINGLETON_CACHE_TALLOC,
 114                 data_blob_string_const_null("root_nt_token"), &for_cache);
 115 
 116         return token;
 117 }
 118 
 119 
 120 /*
 121  * Add alias SIDs from memberships within the partially created token SID list
 122  */
 123 
 124 NTSTATUS add_aliases(const DOM_SID *domain_sid,
     /* [<][>][^][v][top][bottom][index][help] */
 125                      struct nt_user_token *token)
 126 {
 127         uint32 *aliases;
 128         size_t i, num_aliases;
 129         NTSTATUS status;
 130         TALLOC_CTX *tmp_ctx;
 131 
 132         if (!(tmp_ctx = talloc_init("add_aliases"))) {
 133                 return NT_STATUS_NO_MEMORY;
 134         }
 135 
 136         aliases = NULL;
 137         num_aliases = 0;
 138 
 139         status = pdb_enum_alias_memberships(tmp_ctx, domain_sid,
 140                                             token->user_sids,
 141                                             token->num_sids,
 142                                             &aliases, &num_aliases);
 143 
 144         if (!NT_STATUS_IS_OK(status)) {
 145                 DEBUG(10, ("pdb_enum_alias_memberships failed: %s\n",
 146                            nt_errstr(status)));
 147                 goto done;
 148         }
 149 
 150         for (i=0; i<num_aliases; i++) {
 151                 DOM_SID alias_sid;
 152                 sid_compose(&alias_sid, domain_sid, aliases[i]);
 153                 status = add_sid_to_array_unique(token, &alias_sid,
 154                                                  &token->user_sids,
 155                                                  &token->num_sids);
 156                 if (!NT_STATUS_IS_OK(status)) {
 157                         DEBUG(0, ("add_sid_to_array failed\n"));
 158                         goto done;
 159                 }
 160         }
 161 
 162 done:
 163         TALLOC_FREE(tmp_ctx);
 164         return NT_STATUS_OK;
 165 }
 166 
 167 /*******************************************************************
 168 *******************************************************************/
 169 
 170 static NTSTATUS add_builtin_administrators(struct nt_user_token *token,
     /* [<][>][^][v][top][bottom][index][help] */
 171                                            const DOM_SID *dom_sid)
 172 {
 173         DOM_SID domadm;
 174         NTSTATUS status;
 175 
 176         /* nothing to do if we aren't in a domain */
 177 
 178         if ( !(IS_DC || lp_server_role()==ROLE_DOMAIN_MEMBER) ) {
 179                 return NT_STATUS_OK;
 180         }
 181 
 182         /* Find the Domain Admins SID */
 183 
 184         if ( IS_DC ) {
 185                 sid_copy( &domadm, get_global_sam_sid() );
 186         } else {
 187                 sid_copy(&domadm, dom_sid);
 188         }
 189         sid_append_rid( &domadm, DOMAIN_GROUP_RID_ADMINS );
 190 
 191         /* Add Administrators if the user beloongs to Domain Admins */
 192 
 193         if ( nt_token_check_sid( &domadm, token ) ) {
 194                 status = add_sid_to_array(token,
 195                                           &global_sid_Builtin_Administrators,
 196                                           &token->user_sids, &token->num_sids);
 197         if (!NT_STATUS_IS_OK(status)) {
 198                         return status;
 199                 }
 200         }
 201 
 202         return NT_STATUS_OK;
 203 }
 204 
 205 /**
 206  * Create the requested BUILTIN if it doesn't already exist.  This requires
 207  * winbindd to be running.
 208  *
 209  * @param[in] rid BUILTIN rid to create
 210  * @return Normal NTSTATUS return.
 211  */
 212 static NTSTATUS create_builtin(uint32 rid)
     /* [<][>][^][v][top][bottom][index][help] */
 213 {
 214         NTSTATUS status = NT_STATUS_OK;
 215         DOM_SID sid;
 216         gid_t gid;
 217 
 218         if (!sid_compose(&sid, &global_sid_Builtin, rid)) {
 219                 return NT_STATUS_NO_SUCH_ALIAS;
 220         }
 221 
 222         if (!sid_to_gid(&sid, &gid)) {
 223                 if (!lp_winbind_nested_groups() || !winbind_ping()) {
 224                         return NT_STATUS_PROTOCOL_UNREACHABLE;
 225                 }
 226                 status = pdb_create_builtin_alias(rid);
 227         }
 228         return status;
 229 }
 230 
 231 /**
 232  * Add sid as a member of builtin_sid.
 233  *
 234  * @param[in] builtin_sid       An existing builtin group.
 235  * @param[in] dom_sid           sid to add as a member of builtin_sid.
 236  * @return Normal NTSTATUS return
 237  */
 238 static NTSTATUS add_sid_to_builtin(const DOM_SID *builtin_sid,
     /* [<][>][^][v][top][bottom][index][help] */
 239                                    const DOM_SID *dom_sid)
 240 {
 241         NTSTATUS status = NT_STATUS_OK;
 242 
 243         if (!dom_sid || !builtin_sid) {
 244                 return NT_STATUS_INVALID_PARAMETER;
 245         }
 246 
 247         status = pdb_add_aliasmem(builtin_sid, dom_sid);
 248 
 249         if (NT_STATUS_EQUAL(status, NT_STATUS_MEMBER_IN_ALIAS)) {
 250                 DEBUG(5, ("add_sid_to_builtin %s is already a member of %s\n",
 251                           sid_string_dbg(dom_sid),
 252                           sid_string_dbg(builtin_sid)));
 253                 return NT_STATUS_OK;
 254         }
 255 
 256         if (!NT_STATUS_IS_OK(status)) {
 257                 DEBUG(4, ("add_sid_to_builtin %s could not be added to %s: "
 258                           "%s\n", sid_string_dbg(dom_sid),
 259                           sid_string_dbg(builtin_sid), nt_errstr(status)));
 260         }
 261         return status;
 262 }
 263 
 264 /*******************************************************************
 265 *******************************************************************/
 266 
 267 NTSTATUS create_builtin_users(const DOM_SID *dom_sid)
     /* [<][>][^][v][top][bottom][index][help] */
 268 {
 269         NTSTATUS status;
 270         DOM_SID dom_users;
 271 
 272         status = create_builtin(BUILTIN_ALIAS_RID_USERS);
 273         if ( !NT_STATUS_IS_OK(status) ) {
 274                 DEBUG(5,("create_builtin_users: Failed to create Users\n"));
 275                 return status;
 276         }
 277 
 278         /* add domain users */
 279         if ((IS_DC || (lp_server_role() == ROLE_DOMAIN_MEMBER))
 280                 && sid_compose(&dom_users, dom_sid, DOMAIN_GROUP_RID_USERS))
 281         {
 282                 status = add_sid_to_builtin(&global_sid_Builtin_Users,
 283                                             &dom_users);
 284         }
 285 
 286         return status;
 287 }
 288 
 289 /*******************************************************************
 290 *******************************************************************/
 291 
 292 NTSTATUS create_builtin_administrators(const DOM_SID *dom_sid)
     /* [<][>][^][v][top][bottom][index][help] */
 293 {
 294         NTSTATUS status;
 295         DOM_SID dom_admins, root_sid;
 296         fstring root_name;
 297         enum lsa_SidType type;
 298         TALLOC_CTX *ctx;
 299         bool ret;
 300 
 301         status = create_builtin(BUILTIN_ALIAS_RID_ADMINS);
 302         if ( !NT_STATUS_IS_OK(status) ) {
 303                 DEBUG(5,("create_builtin_administrators: Failed to create Administrators\n"));
 304                 return status;
 305         }
 306 
 307         /* add domain admins */
 308         if ((IS_DC || (lp_server_role() == ROLE_DOMAIN_MEMBER))
 309                 && sid_compose(&dom_admins, dom_sid, DOMAIN_GROUP_RID_ADMINS))
 310         {
 311                 status = add_sid_to_builtin(&global_sid_Builtin_Administrators,
 312                                             &dom_admins);
 313                 if (!NT_STATUS_IS_OK(status)) {
 314                         return status;
 315                 }
 316         }
 317 
 318         /* add root */
 319         if ( (ctx = talloc_init("create_builtin_administrators")) == NULL ) {
 320                 return NT_STATUS_NO_MEMORY;
 321         }
 322         fstr_sprintf( root_name, "%s\\root", get_global_sam_name() );
 323         ret = lookup_name(ctx, root_name, LOOKUP_NAME_DOMAIN, NULL, NULL,
 324                           &root_sid, &type);
 325         TALLOC_FREE( ctx );
 326 
 327         if ( ret ) {
 328                 status = add_sid_to_builtin(&global_sid_Builtin_Administrators,
 329                                             &root_sid);
 330         }
 331 
 332         return status;
 333 }
 334 
 335 
 336 /*******************************************************************
 337  Create a NT token for the user, expanding local aliases
 338 *******************************************************************/
 339 
 340 struct nt_user_token *create_local_nt_token(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 341                                             const DOM_SID *user_sid,
 342                                             bool is_guest,
 343                                             int num_groupsids,
 344                                             const DOM_SID *groupsids)
 345 {
 346         struct nt_user_token *result = NULL;
 347         int i;
 348         NTSTATUS status;
 349         gid_t gid;
 350         DOM_SID dom_sid;
 351 
 352         DEBUG(10, ("Create local NT token for %s\n",
 353                    sid_string_dbg(user_sid)));
 354 
 355         if (!(result = TALLOC_ZERO_P(mem_ctx, struct nt_user_token))) {
 356                 DEBUG(0, ("talloc failed\n"));
 357                 return NULL;
 358         }
 359 
 360         /* Add the user and primary group sid */
 361 
 362         status = add_sid_to_array(result, user_sid,
 363                                   &result->user_sids, &result->num_sids);
 364         if (!NT_STATUS_IS_OK(status)) {
 365                 return NULL;
 366         }
 367 
 368         /* For guest, num_groupsids may be zero. */
 369         if (num_groupsids) {
 370                 status = add_sid_to_array(result, &groupsids[0],
 371                                           &result->user_sids,
 372                                           &result->num_sids);
 373                 if (!NT_STATUS_IS_OK(status)) {
 374                         return NULL;
 375                 }
 376         }
 377 
 378         /* Add in BUILTIN sids */
 379 
 380         status = add_sid_to_array(result, &global_sid_World,
 381                                   &result->user_sids, &result->num_sids);
 382         if (!NT_STATUS_IS_OK(status)) {
 383                 return NULL;
 384         }
 385         status = add_sid_to_array(result, &global_sid_Network,
 386                                   &result->user_sids, &result->num_sids);
 387         if (!NT_STATUS_IS_OK(status)) {
 388                 return NULL;
 389         }
 390 
 391         if (is_guest) {
 392                 status = add_sid_to_array(result, &global_sid_Builtin_Guests,
 393                                           &result->user_sids,
 394                                           &result->num_sids);
 395                 if (!NT_STATUS_IS_OK(status)) {
 396                         return NULL;
 397                 }
 398         } else {
 399                 status = add_sid_to_array(result,
 400                                           &global_sid_Authenticated_Users,
 401                                           &result->user_sids,
 402                                           &result->num_sids);
 403                 if (!NT_STATUS_IS_OK(status)) {
 404                         return NULL;
 405                 }
 406         }
 407 
 408         /* Now the SIDs we got from authentication. These are the ones from
 409          * the info3 struct or from the pdb_enum_group_memberships, depending
 410          * on who authenticated the user.
 411          * Note that we start the for loop at "1" here, we already added the
 412          * first group sid as primary above. */
 413 
 414         for (i=1; i<num_groupsids; i++) {
 415                 status = add_sid_to_array_unique(result, &groupsids[i],
 416                                                  &result->user_sids,
 417                                                  &result->num_sids);
 418                 if (!NT_STATUS_IS_OK(status)) {
 419                         return NULL;
 420                 }
 421         }
 422 
 423         /* Deal with the BUILTIN\Administrators group.  If the SID can
 424            be resolved then assume that the add_aliasmem( S-1-5-32 )
 425            handled it. */
 426 
 427         if (!sid_to_gid(&global_sid_Builtin_Administrators, &gid)) {
 428 
 429                 become_root();
 430                 if (!secrets_fetch_domain_sid(lp_workgroup(), &dom_sid)) {
 431                         status = NT_STATUS_OK;
 432                         DEBUG(3, ("Failed to fetch domain sid for %s\n",
 433                                   lp_workgroup()));
 434                 } else {
 435                         status = create_builtin_administrators(&dom_sid);
 436                 }
 437                 unbecome_root();
 438 
 439                 if (NT_STATUS_EQUAL(status, NT_STATUS_PROTOCOL_UNREACHABLE)) {
 440                         /* Add BUILTIN\Administrators directly to token. */
 441                         status = add_builtin_administrators(result, &dom_sid);
 442                         if ( !NT_STATUS_IS_OK(status) ) {
 443                                 DEBUG(3, ("Failed to check for local "
 444                                           "Administrators membership (%s)\n",
 445                                           nt_errstr(status)));
 446                         }
 447                 } else if (!NT_STATUS_IS_OK(status)) {
 448                         DEBUG(2, ("WARNING: Failed to create "
 449                                   "BUILTIN\\Administrators group!  Can "
 450                                   "Winbind allocate gids?\n"));
 451                 }
 452         }
 453 
 454         /* Deal with the BUILTIN\Users group.  If the SID can
 455            be resolved then assume that the add_aliasmem( S-1-5-32 )
 456            handled it. */
 457 
 458         if (!sid_to_gid(&global_sid_Builtin_Users, &gid)) {
 459 
 460                 become_root();
 461                 if (!secrets_fetch_domain_sid(lp_workgroup(), &dom_sid)) {
 462                         status = NT_STATUS_OK;
 463                         DEBUG(3, ("Failed to fetch domain sid for %s\n",
 464                                   lp_workgroup()));
 465                 } else {
 466                         status = create_builtin_users(&dom_sid);
 467                 }
 468                 unbecome_root();
 469 
 470                 if (!NT_STATUS_EQUAL(status, NT_STATUS_PROTOCOL_UNREACHABLE) &&
 471                     !NT_STATUS_IS_OK(status))
 472                 {
 473                         DEBUG(2, ("WARNING: Failed to create BUILTIN\\Users group! "
 474                                   "Can Winbind allocate gids?\n"));
 475                 }
 476         }
 477 
 478         /* Deal with local groups */
 479 
 480         if (lp_winbind_nested_groups()) {
 481 
 482                 become_root();
 483 
 484                 /* Now add the aliases. First the one from our local SAM */
 485 
 486                 status = add_aliases(get_global_sam_sid(), result);
 487 
 488                 if (!NT_STATUS_IS_OK(status)) {
 489                         unbecome_root();
 490                         TALLOC_FREE(result);
 491                         return NULL;
 492                 }
 493 
 494                 /* Finally the builtin ones */
 495 
 496                 status = add_aliases(&global_sid_Builtin, result);
 497 
 498                 if (!NT_STATUS_IS_OK(status)) {
 499                         unbecome_root();
 500                         TALLOC_FREE(result);
 501                         return NULL;
 502                 }
 503 
 504                 unbecome_root();
 505         }
 506 
 507 
 508         get_privileges_for_sids(&result->privileges, result->user_sids,
 509                                 result->num_sids);
 510         return result;
 511 }
 512 
 513 /****************************************************************************
 514  prints a NT_USER_TOKEN to debug output.
 515 ****************************************************************************/
 516 
 517 void debug_nt_user_token(int dbg_class, int dbg_lev, NT_USER_TOKEN *token)
     /* [<][>][^][v][top][bottom][index][help] */
 518 {
 519         size_t     i;
 520 
 521         if (!token) {
 522                 DEBUGC(dbg_class, dbg_lev, ("NT user token: (NULL)\n"));
 523                 return;
 524         }
 525 
 526         DEBUGC(dbg_class, dbg_lev,
 527                ("NT user token of user %s\n",
 528                 sid_string_dbg(&token->user_sids[0]) ));
 529         DEBUGADDC(dbg_class, dbg_lev,
 530                   ("contains %lu SIDs\n", (unsigned long)token->num_sids));
 531         for (i = 0; i < token->num_sids; i++)
 532                 DEBUGADDC(dbg_class, dbg_lev,
 533                           ("SID[%3lu]: %s\n", (unsigned long)i,
 534                            sid_string_dbg(&token->user_sids[i])));
 535 
 536         dump_se_priv( dbg_class, dbg_lev, &token->privileges );
 537 }
 538 
 539 /****************************************************************************
 540  prints a UNIX 'token' to debug output.
 541 ****************************************************************************/
 542 
 543 void debug_unix_user_token(int dbg_class, int dbg_lev, uid_t uid, gid_t gid,
     /* [<][>][^][v][top][bottom][index][help] */
 544                            int n_groups, gid_t *groups)
 545 {
 546         int     i;
 547         DEBUGC(dbg_class, dbg_lev,
 548                ("UNIX token of user %ld\n", (long int)uid));
 549 
 550         DEBUGADDC(dbg_class, dbg_lev,
 551                   ("Primary group is %ld and contains %i supplementary "
 552                    "groups\n", (long int)gid, n_groups));
 553         for (i = 0; i < n_groups; i++)
 554                 DEBUGADDC(dbg_class, dbg_lev, ("Group[%3i]: %ld\n", i,
 555                         (long int)groups[i]));
 556 }
 557 
 558 /* END */

/* [<][>][^][v][top][bottom][index][help] */