Changeset 745 for trunk/server/source3/auth/token_util.c
- Timestamp:
- Nov 27, 2012, 4:43:17 PM (13 years ago)
- Location:
- trunk/server
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/server
- Property svn:mergeinfo changed
/vendor/current merged: 581,587,591,594,597,600,615,618,740
- Property svn:mergeinfo changed
-
trunk/server/source3/auth/token_util.c
r414 r745 26 26 27 27 #include "includes.h" 28 #include "auth.h" 29 #include "secrets.h" 30 #include "memcache.h" 31 #include "../librpc/gen_ndr/netlogon.h" 32 #include "../libcli/security/security.h" 33 #include "../lib/util/util_pw.h" 34 #include "passdb.h" 35 #include "lib/privileges.h" 28 36 29 37 /**************************************************************************** 30 Check for a SID in an NT_USER_TOKEN38 Check for a SID in an struct security_token 31 39 ****************************************************************************/ 32 40 33 bool nt_token_check_sid ( const DOM_SID *sid, const NT_USER_TOKEN *token ) 34 { 35 int i; 36 41 bool nt_token_check_sid ( const struct dom_sid *sid, const struct security_token *token ) 42 { 37 43 if ( !sid || !token ) 38 44 return False; 39 45 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 ) 49 { 50 DOM_SID domain_sid; 46 return security_token_has_sid(token, sid); 47 } 48 49 bool nt_token_check_domain_rid( struct security_token *token, uint32 rid ) 50 { 51 struct dom_sid domain_sid; 51 52 52 53 /* if we are a domain member, the get the domain SID, else for … … 73 74 This is similar to running under the context of the LOCAL_SYSTEM account 74 75 in Windows. This is a read-only token. Do not modify it or free() it. 75 Create a copy if you rneed to change it.76 Create a copy if you need to change it. 76 77 ******************************************************************************/ 77 78 78 NT_USER_TOKEN*get_root_nt_token( void )79 { 80 struct nt_user_token *token, *for_cache;81 DOM_SIDu_sid, g_sid;79 struct security_token *get_root_nt_token( void ) 80 { 81 struct security_token *token, *for_cache; 82 struct dom_sid u_sid, g_sid; 82 83 struct passwd *pw; 83 84 void *cache_data; … … 89 90 if (cache_data != NULL) { 90 91 return talloc_get_type_abort( 91 cache_data, struct nt_user_token);92 cache_data, struct security_token); 92 93 } 93 94 … … 106 107 gid_to_sid(&g_sid, pw->pw_gid); 107 108 108 token = create_local_nt_token(talloc_ autofree_context(), &u_sid, False,109 token = create_local_nt_token(talloc_tos(), &u_sid, False, 109 110 1, &global_sid_Builtin_Administrators); 110 111 111 token->privileges = se_disk_operators;112 security_token_set_privilege(token, SEC_PRIV_DISK_OPERATOR); 112 113 113 114 for_cache = token; … … 125 126 */ 126 127 127 NTSTATUS add_aliases(const DOM_SID*domain_sid,128 struct nt_user_token *token)128 NTSTATUS add_aliases(const struct dom_sid *domain_sid, 129 struct security_token *token) 129 130 { 130 131 uint32 *aliases; … … 141 142 142 143 status = pdb_enum_alias_memberships(tmp_ctx, domain_sid, 143 token-> user_sids,144 token->sids, 144 145 token->num_sids, 145 146 &aliases, &num_aliases); … … 152 153 153 154 for (i=0; i<num_aliases; i++) { 154 DOM_SIDalias_sid;155 struct dom_sid alias_sid; 155 156 sid_compose(&alias_sid, domain_sid, aliases[i]); 156 157 status = add_sid_to_array_unique(token, &alias_sid, 157 &token-> user_sids,158 &token->sids, 158 159 &token->num_sids); 159 160 if (!NT_STATUS_IS_OK(status)) { … … 171 172 *******************************************************************/ 172 173 173 static NTSTATUS add_builtin_administrators(struct nt_user_token *token,174 const DOM_SID*dom_sid)175 { 176 DOM_SIDdomadm;174 static NTSTATUS add_builtin_administrators(struct security_token *token, 175 const struct dom_sid *dom_sid) 176 { 177 struct dom_sid domadm; 177 178 NTSTATUS status; 178 179 … … 190 191 sid_copy(&domadm, dom_sid); 191 192 } 192 sid_append_rid( &domadm, DOMAIN_ GROUP_RID_ADMINS );193 sid_append_rid( &domadm, DOMAIN_RID_ADMINS ); 193 194 194 195 /* Add Administrators if the user beloongs to Domain Admins */ … … 197 198 status = add_sid_to_array(token, 198 199 &global_sid_Builtin_Administrators, 199 &token-> user_sids, &token->num_sids);200 &token->sids, &token->num_sids); 200 201 if (!NT_STATUS_IS_OK(status)) { 201 202 return status; … … 206 207 } 207 208 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 */ 215 static 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 */ 241 static 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 270 NTSTATUS create_builtin_users(const DOM_SID *dom_sid) 271 { 209 static NTSTATUS finalize_local_nt_token(struct security_token *result, 210 bool is_guest); 211 212 NTSTATUS create_local_nt_token_from_info3(TALLOC_CTX *mem_ctx, 213 bool is_guest, 214 struct netr_SamInfo3 *info3, 215 struct extra_auth_info *extra, 216 struct security_token **ntok) 217 { 218 struct security_token *usrtok = NULL; 272 219 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 295 NTSTATUS 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 ) { 220 int i; 221 222 DEBUG(10, ("Create local NT token for %s\n", 223 info3->base.account_name.string)); 224 225 usrtok = talloc_zero(mem_ctx, struct security_token); 226 if (!usrtok) { 227 DEBUG(0, ("talloc failed\n")); 323 228 return NT_STATUS_NO_MEMORY; 324 229 } 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 343 struct 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 } 230 231 /* Add the user and primary group sid FIRST */ 232 /* check if the user rid is the special "Domain Guests" rid. 233 * If so pick the first sid for the extra sids instead as it 234 * is a local fake account */ 235 usrtok->sids = talloc_array(usrtok, struct dom_sid, 2); 236 if (!usrtok->sids) { 237 TALLOC_FREE(usrtok); 238 return NT_STATUS_NO_MEMORY; 239 } 240 usrtok->num_sids = 2; 241 242 /* USER SID */ 243 if (info3->base.rid == (uint32_t)(-1)) { 244 /* this is a signal the user was fake and generated, 245 * the actual SID we want to use is stored in the extra 246 * sids */ 247 if (is_null_sid(&extra->user_sid)) { 248 /* we couldn't find the user sid, bail out */ 249 DEBUG(3, ("Invalid user SID\n")); 250 TALLOC_FREE(usrtok); 251 return NT_STATUS_UNSUCCESSFUL; 252 } 253 sid_copy(&usrtok->sids[0], &extra->user_sid); 401 254 } 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 } 255 sid_copy(&usrtok->sids[0], info3->base.domain_sid); 256 sid_append_rid(&usrtok->sids[0], info3->base.rid); 257 } 258 259 /* GROUP SID */ 260 if (info3->base.primary_gid == (uint32_t)(-1)) { 261 /* this is a signal the user was fake and generated, 262 * the actual SID we want to use is stored in the extra 263 * sids */ 264 if (is_null_sid(&extra->pgid_sid)) { 265 /* we couldn't find the user sid, bail out */ 266 DEBUG(3, ("Invalid group SID\n")); 267 TALLOC_FREE(usrtok); 268 return NT_STATUS_UNSUCCESSFUL; 269 } 270 sid_copy(&usrtok->sids[1], &extra->pgid_sid); 271 } else { 272 sid_copy(&usrtok->sids[1], info3->base.domain_sid); 273 sid_append_rid(&usrtok->sids[1], 274 info3->base.primary_gid); 409 275 } 410 276 … … 415 281 * first group sid as primary above. */ 416 282 283 for (i = 0; i < info3->base.groups.count; i++) { 284 struct dom_sid tmp_sid; 285 286 sid_copy(&tmp_sid, info3->base.domain_sid); 287 sid_append_rid(&tmp_sid, info3->base.groups.rids[i].rid); 288 289 status = add_sid_to_array_unique(usrtok, &tmp_sid, 290 &usrtok->sids, 291 &usrtok->num_sids); 292 if (!NT_STATUS_IS_OK(status)) { 293 DEBUG(3, ("Failed to add SID to nt token\n")); 294 TALLOC_FREE(usrtok); 295 return status; 296 } 297 } 298 299 /* now also add extra sids if they are not the special user/group 300 * sids */ 301 for (i = 0; i < info3->sidcount; i++) { 302 status = add_sid_to_array_unique(usrtok, 303 info3->sids[i].sid, 304 &usrtok->sids, 305 &usrtok->num_sids); 306 if (!NT_STATUS_IS_OK(status)) { 307 DEBUG(3, ("Failed to add SID to nt token\n")); 308 TALLOC_FREE(usrtok); 309 return status; 310 } 311 } 312 313 status = finalize_local_nt_token(usrtok, is_guest); 314 if (!NT_STATUS_IS_OK(status)) { 315 DEBUG(3, ("Failed to finalize nt token\n")); 316 TALLOC_FREE(usrtok); 317 return status; 318 } 319 320 *ntok = usrtok; 321 return NT_STATUS_OK; 322 } 323 324 /******************************************************************* 325 Create a NT token for the user, expanding local aliases 326 *******************************************************************/ 327 328 struct security_token *create_local_nt_token(TALLOC_CTX *mem_ctx, 329 const struct dom_sid *user_sid, 330 bool is_guest, 331 int num_groupsids, 332 const struct dom_sid *groupsids) 333 { 334 struct security_token *result = NULL; 335 int i; 336 NTSTATUS status; 337 338 DEBUG(10, ("Create local NT token for %s\n", 339 sid_string_dbg(user_sid))); 340 341 if (!(result = TALLOC_ZERO_P(mem_ctx, struct security_token))) { 342 DEBUG(0, ("talloc failed\n")); 343 return NULL; 344 } 345 346 /* Add the user and primary group sid */ 347 348 status = add_sid_to_array(result, user_sid, 349 &result->sids, &result->num_sids); 350 if (!NT_STATUS_IS_OK(status)) { 351 TALLOC_FREE(result); 352 return NULL; 353 } 354 355 /* For guest, num_groupsids may be zero. */ 356 if (num_groupsids) { 357 status = add_sid_to_array(result, &groupsids[0], 358 &result->sids, 359 &result->num_sids); 360 if (!NT_STATUS_IS_OK(status)) { 361 TALLOC_FREE(result); 362 return NULL; 363 } 364 } 365 366 /* Now the SIDs we got from authentication. These are the ones from 367 * the info3 struct or from the pdb_enum_group_memberships, depending 368 * on who authenticated the user. 369 * Note that we start the for loop at "1" here, we already added the 370 * first group sid as primary above. */ 371 417 372 for (i=1; i<num_groupsids; i++) { 418 373 status = add_sid_to_array_unique(result, &groupsids[i], 419 &result-> user_sids,374 &result->sids, 420 375 &result->num_sids); 421 376 if (!NT_STATUS_IS_OK(status)) { 377 TALLOC_FREE(result); 422 378 return NULL; 379 } 380 } 381 382 status = finalize_local_nt_token(result, is_guest); 383 if (!NT_STATUS_IS_OK(status)) { 384 TALLOC_FREE(result); 385 return NULL; 386 } 387 388 return result; 389 } 390 391 static NTSTATUS finalize_local_nt_token(struct security_token *result, 392 bool is_guest) 393 { 394 struct dom_sid dom_sid; 395 gid_t gid; 396 NTSTATUS status; 397 398 /* Add in BUILTIN sids */ 399 400 status = add_sid_to_array(result, &global_sid_World, 401 &result->sids, &result->num_sids); 402 if (!NT_STATUS_IS_OK(status)) { 403 return status; 404 } 405 status = add_sid_to_array(result, &global_sid_Network, 406 &result->sids, &result->num_sids); 407 if (!NT_STATUS_IS_OK(status)) { 408 return status; 409 } 410 411 if (is_guest) { 412 status = add_sid_to_array(result, &global_sid_Builtin_Guests, 413 &result->sids, 414 &result->num_sids); 415 if (!NT_STATUS_IS_OK(status)) { 416 return status; 417 } 418 } else { 419 status = add_sid_to_array(result, 420 &global_sid_Authenticated_Users, 421 &result->sids, 422 &result->num_sids); 423 if (!NT_STATUS_IS_OK(status)) { 424 return status; 423 425 } 424 426 } … … 491 493 if (!NT_STATUS_IS_OK(status)) { 492 494 unbecome_root(); 493 TALLOC_FREE(result); 494 return NULL; 495 return status; 495 496 } 496 497 … … 501 502 if (!NT_STATUS_IS_OK(status)) { 502 503 unbecome_root(); 503 TALLOC_FREE(result); 504 return NULL; 504 return status; 505 505 } 506 506 … … 508 508 } 509 509 510 511 get_privileges_for_sids(&result->privileges, result->user_sids, 510 /* Add privileges based on current user sids */ 511 512 get_privileges_for_sids(&result->privilege_mask, result->sids, 512 513 result->num_sids); 513 return result; 514 } 515 516 /**************************************************************************** 517 prints a NT_USER_TOKEN to debug output. 518 ****************************************************************************/ 519 520 void 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 ); 514 515 return NT_STATUS_OK; 540 516 } 541 517 … … 559 535 } 560 536 537 /* 538 * Create an artificial NT token given just a username. (Initially intended 539 * for force user) 540 * 541 * We go through lookup_name() to avoid problems we had with 'winbind use 542 * default domain'. 543 * 544 * We have 3 cases: 545 * 546 * unmapped unix users: Go directly to nss to find the user's group. 547 * 548 * A passdb user: The list of groups is provided by pdb_enum_group_memberships. 549 * 550 * If the user is provided by winbind, the primary gid is set to "domain 551 * users" of the user's domain. For an explanation why this is necessary, see 552 * the thread starting at 553 * http://lists.samba.org/archive/samba-technical/2006-January/044803.html. 554 */ 555 556 NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username, 557 bool is_guest, 558 uid_t *uid, gid_t *gid, 559 char **found_username, 560 struct security_token **token) 561 { 562 NTSTATUS result = NT_STATUS_NO_SUCH_USER; 563 TALLOC_CTX *tmp_ctx = talloc_stackframe(); 564 struct dom_sid user_sid; 565 enum lsa_SidType type; 566 gid_t *gids; 567 struct dom_sid *group_sids; 568 struct dom_sid unix_group_sid; 569 uint32_t num_group_sids; 570 uint32_t num_gids; 571 uint32_t i; 572 573 if (!lookup_name_smbconf(tmp_ctx, username, LOOKUP_NAME_ALL, 574 NULL, NULL, &user_sid, &type)) { 575 DEBUG(1, ("lookup_name_smbconf for %s failed\n", username)); 576 goto done; 577 } 578 579 if (type != SID_NAME_USER) { 580 DEBUG(1, ("%s is a %s, not a user\n", username, 581 sid_type_lookup(type))); 582 goto done; 583 } 584 585 if (sid_check_is_in_our_domain(&user_sid)) { 586 bool ret; 587 uint32_t pdb_num_group_sids; 588 /* This is a passdb user, so ask passdb */ 589 590 struct samu *sam_acct = NULL; 591 592 if ( !(sam_acct = samu_new( tmp_ctx )) ) { 593 result = NT_STATUS_NO_MEMORY; 594 goto done; 595 } 596 597 become_root(); 598 ret = pdb_getsampwsid(sam_acct, &user_sid); 599 unbecome_root(); 600 601 if (!ret) { 602 DEBUG(1, ("pdb_getsampwsid(%s) for user %s failed\n", 603 sid_string_dbg(&user_sid), username)); 604 DEBUGADD(1, ("Fall back to unix user %s\n", username)); 605 goto unix_user; 606 } 607 608 result = pdb_enum_group_memberships(tmp_ctx, sam_acct, 609 &group_sids, &gids, 610 &pdb_num_group_sids); 611 if (!NT_STATUS_IS_OK(result)) { 612 DEBUG(1, ("enum_group_memberships failed for %s (%s): " 613 "%s\n", username, sid_string_dbg(&user_sid), 614 nt_errstr(result))); 615 DEBUGADD(1, ("Fall back to unix user %s\n", username)); 616 goto unix_user; 617 } 618 num_group_sids = pdb_num_group_sids; 619 620 /* see the smb_panic() in pdb_default_enum_group_memberships */ 621 SMB_ASSERT(num_group_sids > 0); 622 623 *gid = gids[0]; 624 625 /* Ensure we're returning the found_username on the right context. */ 626 *found_username = talloc_strdup(mem_ctx, 627 pdb_get_username(sam_acct)); 628 629 /* 630 * If the SID from lookup_name() was the guest sid, passdb knows 631 * about the mapping of guest sid to lp_guestaccount() 632 * username and will return the unix_pw info for a guest 633 * user. Use it if it's there, else lookup the *uid details 634 * using Get_Pwnam_alloc(). See bug #6291 for details. JRA. 635 */ 636 637 /* We must always assign the *uid. */ 638 if (sam_acct->unix_pw == NULL) { 639 struct passwd *pwd = Get_Pwnam_alloc(sam_acct, *found_username ); 640 if (!pwd) { 641 DEBUG(10, ("Get_Pwnam_alloc failed for %s\n", 642 *found_username)); 643 result = NT_STATUS_NO_SUCH_USER; 644 goto done; 645 } 646 result = samu_set_unix(sam_acct, pwd ); 647 if (!NT_STATUS_IS_OK(result)) { 648 DEBUG(10, ("samu_set_unix failed for %s\n", 649 *found_username)); 650 result = NT_STATUS_NO_SUCH_USER; 651 goto done; 652 } 653 } 654 *uid = sam_acct->unix_pw->pw_uid; 655 656 } else if (sid_check_is_in_unix_users(&user_sid)) { 657 uint32_t getgroups_num_group_sids; 658 /* This is a unix user not in passdb. We need to ask nss 659 * directly, without consulting passdb */ 660 661 struct passwd *pass; 662 663 /* 664 * This goto target is used as a fallback for the passdb 665 * case. The concrete bug report is when passdb gave us an 666 * unmapped gid. 667 */ 668 669 unix_user: 670 671 if (!sid_to_uid(&user_sid, uid)) { 672 DEBUG(1, ("unix_user case, sid_to_uid for %s (%s) failed\n", 673 username, sid_string_dbg(&user_sid))); 674 result = NT_STATUS_NO_SUCH_USER; 675 goto done; 676 } 677 678 uid_to_unix_users_sid(*uid, &user_sid); 679 680 pass = getpwuid_alloc(tmp_ctx, *uid); 681 if (pass == NULL) { 682 DEBUG(1, ("getpwuid(%u) for user %s failed\n", 683 (unsigned int)*uid, username)); 684 goto done; 685 } 686 687 if (!getgroups_unix_user(tmp_ctx, username, pass->pw_gid, 688 &gids, &getgroups_num_group_sids)) { 689 DEBUG(1, ("getgroups_unix_user for user %s failed\n", 690 username)); 691 goto done; 692 } 693 num_group_sids = getgroups_num_group_sids; 694 695 if (num_group_sids) { 696 group_sids = TALLOC_ARRAY(tmp_ctx, struct dom_sid, num_group_sids); 697 if (group_sids == NULL) { 698 DEBUG(1, ("TALLOC_ARRAY failed\n")); 699 result = NT_STATUS_NO_MEMORY; 700 goto done; 701 } 702 } else { 703 group_sids = NULL; 704 } 705 706 for (i=0; i<num_group_sids; i++) { 707 gid_to_sid(&group_sids[i], gids[i]); 708 } 709 710 /* In getgroups_unix_user we always set the primary gid */ 711 SMB_ASSERT(num_group_sids > 0); 712 713 *gid = gids[0]; 714 715 /* Ensure we're returning the found_username on the right context. */ 716 *found_username = talloc_strdup(mem_ctx, pass->pw_name); 717 } else { 718 719 /* This user is from winbind, force the primary gid to the 720 * user's "domain users" group. Under certain circumstances 721 * (user comes from NT4), this might be a loss of 722 * information. But we can not rely on winbind getting the 723 * correct info. AD might prohibit winbind looking up that 724 * information. */ 725 726 /* We must always assign the *uid. */ 727 if (!sid_to_uid(&user_sid, uid)) { 728 DEBUG(1, ("winbindd case, sid_to_uid for %s (%s) failed\n", 729 username, sid_string_dbg(&user_sid))); 730 result = NT_STATUS_NO_SUCH_USER; 731 goto done; 732 } 733 734 num_group_sids = 1; 735 group_sids = TALLOC_ARRAY(tmp_ctx, struct dom_sid, num_group_sids); 736 if (group_sids == NULL) { 737 DEBUG(1, ("TALLOC_ARRAY failed\n")); 738 result = NT_STATUS_NO_MEMORY; 739 goto done; 740 } 741 742 sid_copy(&group_sids[0], &user_sid); 743 sid_split_rid(&group_sids[0], NULL); 744 sid_append_rid(&group_sids[0], DOMAIN_RID_USERS); 745 746 if (!sid_to_gid(&group_sids[0], gid)) { 747 DEBUG(1, ("sid_to_gid(%s) failed\n", 748 sid_string_dbg(&group_sids[0]))); 749 goto done; 750 } 751 752 gids = gid; 753 754 /* Ensure we're returning the found_username on the right context. */ 755 *found_username = talloc_strdup(mem_ctx, username); 756 } 757 758 /* Add the "Unix Group" SID for each gid to catch mapped groups 759 and their Unix equivalent. This is to solve the backwards 760 compatibility problem of 'valid users = +ntadmin' where 761 ntadmin has been paired with "Domain Admins" in the group 762 mapping table. Otherwise smb.conf would need to be changed 763 to 'valid user = "Domain Admins"'. --jerry */ 764 765 num_gids = num_group_sids; 766 for ( i=0; i<num_gids; i++ ) { 767 gid_t high, low; 768 769 /* don't pickup anything managed by Winbind */ 770 771 if ( lp_idmap_gid(&low, &high) && (gids[i] >= low) && (gids[i] <= high) ) 772 continue; 773 774 gid_to_unix_groups_sid(gids[i], &unix_group_sid); 775 776 result = add_sid_to_array_unique(tmp_ctx, &unix_group_sid, 777 &group_sids, &num_group_sids); 778 if (!NT_STATUS_IS_OK(result)) { 779 goto done; 780 } 781 } 782 783 /* Ensure we're creating the nt_token on the right context. */ 784 *token = create_local_nt_token(mem_ctx, &user_sid, 785 is_guest, num_group_sids, group_sids); 786 787 if ((*token == NULL) || (*found_username == NULL)) { 788 result = NT_STATUS_NO_MEMORY; 789 goto done; 790 } 791 792 result = NT_STATUS_OK; 793 done: 794 TALLOC_FREE(tmp_ctx); 795 return result; 796 } 797 798 /*************************************************************************** 799 Build upon create_token_from_username: 800 801 Expensive helper function to figure out whether a user given its name is 802 member of a particular group. 803 ***************************************************************************/ 804 805 bool user_in_group_sid(const char *username, const struct dom_sid *group_sid) 806 { 807 NTSTATUS status; 808 uid_t uid; 809 gid_t gid; 810 char *found_username; 811 struct security_token *token; 812 bool result; 813 TALLOC_CTX *mem_ctx = talloc_stackframe(); 814 815 status = create_token_from_username(mem_ctx, username, False, 816 &uid, &gid, &found_username, 817 &token); 818 819 if (!NT_STATUS_IS_OK(status)) { 820 DEBUG(10, ("could not create token for %s\n", username)); 821 TALLOC_FREE(mem_ctx); 822 return False; 823 } 824 825 result = security_token_has_sid(token, group_sid); 826 827 TALLOC_FREE(mem_ctx); 828 return result; 829 } 830 831 bool user_in_group(const char *username, const char *groupname) 832 { 833 TALLOC_CTX *mem_ctx = talloc_stackframe(); 834 struct dom_sid group_sid; 835 bool ret; 836 837 ret = lookup_name(mem_ctx, groupname, LOOKUP_NAME_ALL, 838 NULL, NULL, &group_sid, NULL); 839 TALLOC_FREE(mem_ctx); 840 841 if (!ret) { 842 DEBUG(10, ("lookup_name for (%s) failed.\n", groupname)); 843 return False; 844 } 845 846 return user_in_group_sid(username, &group_sid); 847 } 848 561 849 /* END */
Note:
See TracChangeset
for help on using the changeset viewer.