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 33bool nt_token_check_sid ( const DOM_SID *sid, const NT_USER_TOKEN *token ) 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 48bool nt_token_check_domain_rid( NT_USER_TOKEN *token, uint32 rid ) 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 78NT_USER_TOKEN *get_root_nt_token( void ) 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_getpwuid(0)) ) { 95 if ( !(pw = sys_getpwnam("root")) ) { 96 DEBUG(0,("get_root_nt_token: both sys_getpwuid(0) " 97 "and sys_getpwnam(\"root\") failed!\n")); 98 return NULL; 99 } 100 } 101 102 /* get the user and primary group SIDs; although the 103 BUILTIN\Administrators SId is really the one that matters here */ 104 105 uid_to_sid(&u_sid, pw->pw_uid); 106 gid_to_sid(&g_sid, pw->pw_gid); 107 108 token = create_local_nt_token(talloc_autofree_context(), &u_sid, False, 109 1, &global_sid_Builtin_Administrators); 110 111 token->privileges = se_disk_operators; 112 113 for_cache = token; 114 115 memcache_add_talloc( 116 NULL, SINGLETON_CACHE_TALLOC, 117 data_blob_string_const_null("root_nt_token"), &for_cache); 118 119 return token; 120} 121 122 123/* 124 * Add alias SIDs from memberships within the partially created token SID list 125 */ 126 127NTSTATUS add_aliases(const DOM_SID *domain_sid, 128 struct nt_user_token *token) 129{ 130 uint32 *aliases; 131 size_t i, num_aliases; 132 NTSTATUS status; 133 TALLOC_CTX *tmp_ctx; 134 135 if (!(tmp_ctx = talloc_init("add_aliases"))) { 136 return NT_STATUS_NO_MEMORY; 137 } 138 139 aliases = NULL; 140 num_aliases = 0; 141 142 status = pdb_enum_alias_memberships(tmp_ctx, domain_sid, 143 token->user_sids, 144 token->num_sids, 145 &aliases, &num_aliases); 146 147 if (!NT_STATUS_IS_OK(status)) { 148 DEBUG(10, ("pdb_enum_alias_memberships failed: %s\n", 149 nt_errstr(status))); 150 goto done; 151 } 152 153 for (i=0; i<num_aliases; i++) { 154 DOM_SID alias_sid; 155 sid_compose(&alias_sid, domain_sid, aliases[i]); 156 status = add_sid_to_array_unique(token, &alias_sid, 157 &token->user_sids, 158 &token->num_sids); 159 if (!NT_STATUS_IS_OK(status)) { 160 DEBUG(0, ("add_sid_to_array failed\n")); 161 goto done; 162 } 163 } 164 165done: 166 TALLOC_FREE(tmp_ctx); 167 return NT_STATUS_OK; 168} 169 170/******************************************************************* 171*******************************************************************/ 172 173static NTSTATUS add_builtin_administrators(struct nt_user_token *token, 174 const DOM_SID *dom_sid) 175{ 176 DOM_SID domadm; 177 NTSTATUS status; 178 179 /* nothing to do if we aren't in a domain */ 180 181 if ( !(IS_DC || lp_server_role()==ROLE_DOMAIN_MEMBER) ) { 182 return NT_STATUS_OK; 183 } 184 185 /* Find the Domain Admins SID */ 186 187 if ( IS_DC ) { 188 sid_copy( &domadm, get_global_sam_sid() ); 189 } else { 190 sid_copy(&domadm, dom_sid); 191 } 192 sid_append_rid( &domadm, DOMAIN_GROUP_RID_ADMINS ); 193 194 /* Add Administrators if the user beloongs to Domain Admins */ 195 196 if ( nt_token_check_sid( &domadm, token ) ) { 197 status = add_sid_to_array(token, 198 &global_sid_Builtin_Administrators, 199 &token->user_sids, &token->num_sids); 200 if (!NT_STATUS_IS_OK(status)) { 201 return status; 202 } 203 } 204 205 return NT_STATUS_OK; 206} 207 208/** 209 * Create the requested BUILTIN if it doesn't already exist. This requires 210 * winbindd to be running. 211 * 212 * @param[in] rid BUILTIN rid to create 213 * @return Normal NTSTATUS return. 214 */ 215static NTSTATUS create_builtin(uint32 rid) 216{ 217 NTSTATUS status = NT_STATUS_OK; 218 DOM_SID sid; 219 gid_t gid; 220 221 if (!sid_compose(&sid, &global_sid_Builtin, rid)) { 222 return NT_STATUS_NO_SUCH_ALIAS; 223 } 224 225 if (!sid_to_gid(&sid, &gid)) { 226 if (!lp_winbind_nested_groups() || !winbind_ping()) { 227 return NT_STATUS_PROTOCOL_UNREACHABLE; 228 } 229 status = pdb_create_builtin_alias(rid); 230 } 231 return status; 232} 233 234/** 235 * Add sid as a member of builtin_sid. 236 * 237 * @param[in] builtin_sid An existing builtin group. 238 * @param[in] dom_sid sid to add as a member of builtin_sid. 239 * @return Normal NTSTATUS return 240 */ 241static NTSTATUS add_sid_to_builtin(const DOM_SID *builtin_sid, 242 const DOM_SID *dom_sid) 243{ 244 NTSTATUS status = NT_STATUS_OK; 245 246 if (!dom_sid || !builtin_sid) { 247 return NT_STATUS_INVALID_PARAMETER; 248 } 249 250 status = pdb_add_aliasmem(builtin_sid, dom_sid); 251 252 if (NT_STATUS_EQUAL(status, NT_STATUS_MEMBER_IN_ALIAS)) { 253 DEBUG(5, ("add_sid_to_builtin %s is already a member of %s\n", 254 sid_string_dbg(dom_sid), 255 sid_string_dbg(builtin_sid))); 256 return NT_STATUS_OK; 257 } 258 259 if (!NT_STATUS_IS_OK(status)) { 260 DEBUG(4, ("add_sid_to_builtin %s could not be added to %s: " 261 "%s\n", sid_string_dbg(dom_sid), 262 sid_string_dbg(builtin_sid), nt_errstr(status))); 263 } 264 return status; 265} 266 267/******************************************************************* 268*******************************************************************/ 269 270NTSTATUS create_builtin_users(const DOM_SID *dom_sid) 271{ 272 NTSTATUS status; 273 DOM_SID dom_users; 274 275 status = create_builtin(BUILTIN_ALIAS_RID_USERS); 276 if ( !NT_STATUS_IS_OK(status) ) { 277 DEBUG(5,("create_builtin_users: Failed to create Users\n")); 278 return status; 279 } 280 281 /* add domain users */ 282 if ((IS_DC || (lp_server_role() == ROLE_DOMAIN_MEMBER)) 283 && sid_compose(&dom_users, dom_sid, DOMAIN_GROUP_RID_USERS)) 284 { 285 status = add_sid_to_builtin(&global_sid_Builtin_Users, 286 &dom_users); 287 } 288 289 return status; 290} 291 292/******************************************************************* 293*******************************************************************/ 294 295NTSTATUS create_builtin_administrators(const DOM_SID *dom_sid) 296{ 297 NTSTATUS status; 298 DOM_SID dom_admins, root_sid; 299 fstring root_name; 300 enum lsa_SidType type; 301 TALLOC_CTX *ctx; 302 bool ret; 303 304 status = create_builtin(BUILTIN_ALIAS_RID_ADMINS); 305 if ( !NT_STATUS_IS_OK(status) ) { 306 DEBUG(5,("create_builtin_administrators: Failed to create Administrators\n")); 307 return status; 308 } 309 310 /* add domain admins */ 311 if ((IS_DC || (lp_server_role() == ROLE_DOMAIN_MEMBER)) 312 && sid_compose(&dom_admins, dom_sid, DOMAIN_GROUP_RID_ADMINS)) 313 { 314 status = add_sid_to_builtin(&global_sid_Builtin_Administrators, 315 &dom_admins); 316 if (!NT_STATUS_IS_OK(status)) { 317 return status; 318 } 319 } 320 321 /* add root */ 322 if ( (ctx = talloc_init("create_builtin_administrators")) == NULL ) { 323 return NT_STATUS_NO_MEMORY; 324 } 325 fstr_sprintf( root_name, "%s\\root", get_global_sam_name() ); 326 ret = lookup_name(ctx, root_name, LOOKUP_NAME_DOMAIN, NULL, NULL, 327 &root_sid, &type); 328 TALLOC_FREE( ctx ); 329 330 if ( ret ) { 331 status = add_sid_to_builtin(&global_sid_Builtin_Administrators, 332 &root_sid); 333 } 334 335 return status; 336} 337 338 339/******************************************************************* 340 Create a NT token for the user, expanding local aliases 341*******************************************************************/ 342 343struct nt_user_token *create_local_nt_token(TALLOC_CTX *mem_ctx, 344 const DOM_SID *user_sid, 345 bool is_guest, 346 int num_groupsids, 347 const DOM_SID *groupsids) 348{ 349 struct nt_user_token *result = NULL; 350 int i; 351 NTSTATUS status; 352 gid_t gid; 353 DOM_SID dom_sid; 354 355 DEBUG(10, ("Create local NT token for %s\n", 356 sid_string_dbg(user_sid))); 357 358 if (!(result = TALLOC_ZERO_P(mem_ctx, struct nt_user_token))) { 359 DEBUG(0, ("talloc failed\n")); 360 return NULL; 361 } 362 363 /* Add the user and primary group sid */ 364 365 status = add_sid_to_array(result, user_sid, 366 &result->user_sids, &result->num_sids); 367 if (!NT_STATUS_IS_OK(status)) { 368 return NULL; 369 } 370 371 /* For guest, num_groupsids may be zero. */ 372 if (num_groupsids) { 373 status = add_sid_to_array(result, &groupsids[0], 374 &result->user_sids, 375 &result->num_sids); 376 if (!NT_STATUS_IS_OK(status)) { 377 return NULL; 378 } 379 } 380 381 /* Add in BUILTIN sids */ 382 383 status = add_sid_to_array(result, &global_sid_World, 384 &result->user_sids, &result->num_sids); 385 if (!NT_STATUS_IS_OK(status)) { 386 return NULL; 387 } 388 status = add_sid_to_array(result, &global_sid_Network, 389 &result->user_sids, &result->num_sids); 390 if (!NT_STATUS_IS_OK(status)) { 391 return NULL; 392 } 393 394 if (is_guest) { 395 status = add_sid_to_array(result, &global_sid_Builtin_Guests, 396 &result->user_sids, 397 &result->num_sids); 398 if (!NT_STATUS_IS_OK(status)) { 399 return NULL; 400 } 401 } else { 402 status = add_sid_to_array(result, 403 &global_sid_Authenticated_Users, 404 &result->user_sids, 405 &result->num_sids); 406 if (!NT_STATUS_IS_OK(status)) { 407 return NULL; 408 } 409 } 410 411 /* Now the SIDs we got from authentication. These are the ones from 412 * the info3 struct or from the pdb_enum_group_memberships, depending 413 * on who authenticated the user. 414 * Note that we start the for loop at "1" here, we already added the 415 * first group sid as primary above. */ 416 417 for (i=1; i<num_groupsids; i++) { 418 status = add_sid_to_array_unique(result, &groupsids[i], 419 &result->user_sids, 420 &result->num_sids); 421 if (!NT_STATUS_IS_OK(status)) { 422 return NULL; 423 } 424 } 425 426 /* Deal with the BUILTIN\Administrators group. If the SID can 427 be resolved then assume that the add_aliasmem( S-1-5-32 ) 428 handled it. */ 429 430 if (!sid_to_gid(&global_sid_Builtin_Administrators, &gid)) { 431 432 become_root(); 433 if (!secrets_fetch_domain_sid(lp_workgroup(), &dom_sid)) { 434 status = NT_STATUS_OK; 435 DEBUG(3, ("Failed to fetch domain sid for %s\n", 436 lp_workgroup())); 437 } else { 438 status = create_builtin_administrators(&dom_sid); 439 } 440 unbecome_root(); 441 442 if (NT_STATUS_EQUAL(status, NT_STATUS_PROTOCOL_UNREACHABLE)) { 443 /* Add BUILTIN\Administrators directly to token. */ 444 status = add_builtin_administrators(result, &dom_sid); 445 if ( !NT_STATUS_IS_OK(status) ) { 446 DEBUG(3, ("Failed to check for local " 447 "Administrators membership (%s)\n", 448 nt_errstr(status))); 449 } 450 } else if (!NT_STATUS_IS_OK(status)) { 451 DEBUG(2, ("WARNING: Failed to create " 452 "BUILTIN\\Administrators group! Can " 453 "Winbind allocate gids?\n")); 454 } 455 } 456 457 /* Deal with the BUILTIN\Users group. If the SID can 458 be resolved then assume that the add_aliasmem( S-1-5-32 ) 459 handled it. */ 460 461 if (!sid_to_gid(&global_sid_Builtin_Users, &gid)) { 462 463 become_root(); 464 if (!secrets_fetch_domain_sid(lp_workgroup(), &dom_sid)) { 465 status = NT_STATUS_OK; 466 DEBUG(3, ("Failed to fetch domain sid for %s\n", 467 lp_workgroup())); 468 } else { 469 status = create_builtin_users(&dom_sid); 470 } 471 unbecome_root(); 472 473 if (!NT_STATUS_EQUAL(status, NT_STATUS_PROTOCOL_UNREACHABLE) && 474 !NT_STATUS_IS_OK(status)) 475 { 476 DEBUG(2, ("WARNING: Failed to create BUILTIN\\Users group! " 477 "Can Winbind allocate gids?\n")); 478 } 479 } 480 481 /* Deal with local groups */ 482 483 if (lp_winbind_nested_groups()) { 484 485 become_root(); 486 487 /* Now add the aliases. First the one from our local SAM */ 488 489 status = add_aliases(get_global_sam_sid(), result); 490 491 if (!NT_STATUS_IS_OK(status)) { 492 unbecome_root(); 493 TALLOC_FREE(result); 494 return NULL; 495 } 496 497 /* Finally the builtin ones */ 498 499 status = add_aliases(&global_sid_Builtin, result); 500 501 if (!NT_STATUS_IS_OK(status)) { 502 unbecome_root(); 503 TALLOC_FREE(result); 504 return NULL; 505 } 506 507 unbecome_root(); 508 } 509 510 511 get_privileges_for_sids(&result->privileges, result->user_sids, 512 result->num_sids); 513 return result; 514} 515 516/**************************************************************************** 517 prints a NT_USER_TOKEN to debug output. 518****************************************************************************/ 519 520void debug_nt_user_token(int dbg_class, int dbg_lev, NT_USER_TOKEN *token) 521{ 522 size_t i; 523 524 if (!token) { 525 DEBUGC(dbg_class, dbg_lev, ("NT user token: (NULL)\n")); 526 return; 527 } 528 529 DEBUGC(dbg_class, dbg_lev, 530 ("NT user token of user %s\n", 531 sid_string_dbg(&token->user_sids[0]) )); 532 DEBUGADDC(dbg_class, dbg_lev, 533 ("contains %lu SIDs\n", (unsigned long)token->num_sids)); 534 for (i = 0; i < token->num_sids; i++) 535 DEBUGADDC(dbg_class, dbg_lev, 536 ("SID[%3lu]: %s\n", (unsigned long)i, 537 sid_string_dbg(&token->user_sids[i]))); 538 539 dump_se_priv( dbg_class, dbg_lev, &token->privileges ); 540} 541 542/**************************************************************************** 543 prints a UNIX 'token' to debug output. 544****************************************************************************/ 545 546void debug_unix_user_token(int dbg_class, int dbg_lev, uid_t uid, gid_t gid, 547 int n_groups, gid_t *groups) 548{ 549 int i; 550 DEBUGC(dbg_class, dbg_lev, 551 ("UNIX token of user %ld\n", (long int)uid)); 552 553 DEBUGADDC(dbg_class, dbg_lev, 554 ("Primary group is %ld and contains %i supplementary " 555 "groups\n", (long int)gid, n_groups)); 556 for (i = 0; i < n_groups; i++) 557 DEBUGADDC(dbg_class, dbg_lev, ("Group[%3i]: %ld\n", i, 558 (long int)groups[i])); 559} 560 561/* END */ 562