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 9 This program is free software; you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation; either version 2 of the License, or 12 (at your option) any later version. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program; if not, write to the Free Software 21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 22*/ 23 24#include "includes.h" 25 26#undef DBGC_CLASS 27#define DBGC_CLASS DBGC_AUTH 28 29extern DOM_SID global_sid_World; 30extern DOM_SID global_sid_Network; 31extern DOM_SID global_sid_Builtin_Guests; 32extern DOM_SID global_sid_Authenticated_Users; 33 34 35/**************************************************************************** 36 Create a UNIX user on demand. 37****************************************************************************/ 38 39static int smb_create_user(const char *domain, const char *unix_username, const char *homedir) 40{ 41 pstring add_script; 42 int ret; 43 44 pstrcpy(add_script, lp_adduser_script()); 45 if (! *add_script) 46 return -1; 47 all_string_sub(add_script, "%u", unix_username, sizeof(pstring)); 48 if (domain) 49 all_string_sub(add_script, "%D", domain, sizeof(pstring)); 50 if (homedir) 51 all_string_sub(add_script, "%H", homedir, sizeof(pstring)); 52 ret = smbrun(add_script,NULL); 53 flush_pwnam_cache(); 54 DEBUG(ret ? 0 : 3,("smb_create_user: Running the command `%s' gave %d\n",add_script,ret)); 55 return ret; 56} 57 58/**************************************************************************** 59 Add and Delete UNIX users on demand, based on NTSTATUS codes. 60 We don't care about RID's here so ignore. 61****************************************************************************/ 62 63void auth_add_user_script(const char *domain, const char *username) 64{ 65 /* 66 * User validated ok against Domain controller. 67 * If the admin wants us to try and create a UNIX 68 * user on the fly, do so. 69 */ 70 71 if ( *lp_adduser_script() ) 72 smb_create_user(domain, username, NULL); 73 else { 74 DEBUG(10,("auth_add_user_script: no 'add user script'. Asking winbindd\n")); 75 76 /* should never get here is we a re a domain member running winbindd 77 However, a host set for 'security = server' might run winbindd for 78 account allocation */ 79 80 if ( !winbind_create_user(username, NULL) ) { 81 DEBUG(5,("auth_add_user_script: winbindd_create_user() failed\n")); 82 } 83 } 84} 85 86/**************************************************************************** 87 Create a SAM_ACCOUNT - either by looking in the pdb, or by faking it up from 88 unix info. 89****************************************************************************/ 90 91NTSTATUS auth_get_sam_account(const char *user, SAM_ACCOUNT **account) 92{ 93 BOOL pdb_ret; 94 NTSTATUS nt_status; 95 if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(account))) { 96 return nt_status; 97 } 98 99 become_root(); 100 pdb_ret = pdb_getsampwnam(*account, user); 101 unbecome_root(); 102 103 if (!pdb_ret) { 104 105 struct passwd *pass = Get_Pwnam(user); 106 if (!pass) 107 return NT_STATUS_NO_SUCH_USER; 108 109 if (!NT_STATUS_IS_OK(nt_status = pdb_fill_sam_pw(*account, pass))) { 110 return nt_status; 111 } 112 } 113 return NT_STATUS_OK; 114} 115 116/**************************************************************************** 117 Create an auth_usersupplied_data structure 118****************************************************************************/ 119 120static NTSTATUS make_user_info(auth_usersupplied_info **user_info, 121 const char *smb_name, 122 const char *internal_username, 123 const char *client_domain, 124 const char *domain, 125 const char *wksta_name, 126 DATA_BLOB *lm_pwd, DATA_BLOB *nt_pwd, 127 DATA_BLOB *lm_interactive_pwd, DATA_BLOB *nt_interactive_pwd, 128 DATA_BLOB *plaintext, 129 BOOL encrypted) 130{ 131 132 DEBUG(5,("attempting to make a user_info for %s (%s)\n", internal_username, smb_name)); 133 134 *user_info = SMB_MALLOC_P(auth_usersupplied_info); 135 if (!user_info) { 136 DEBUG(0,("malloc failed for user_info (size %lu)\n", (unsigned long)sizeof(*user_info))); 137 return NT_STATUS_NO_MEMORY; 138 } 139 140 ZERO_STRUCTP(*user_info); 141 142 DEBUG(5,("making strings for %s's user_info struct\n", internal_username)); 143 144 (*user_info)->smb_name.str = SMB_STRDUP(smb_name); 145 if ((*user_info)->smb_name.str) { 146 (*user_info)->smb_name.len = strlen(smb_name); 147 } else { 148 free_user_info(user_info); 149 return NT_STATUS_NO_MEMORY; 150 } 151 152 (*user_info)->internal_username.str = SMB_STRDUP(internal_username); 153 if ((*user_info)->internal_username.str) { 154 (*user_info)->internal_username.len = strlen(internal_username); 155 } else { 156 free_user_info(user_info); 157 return NT_STATUS_NO_MEMORY; 158 } 159 160 (*user_info)->domain.str = SMB_STRDUP(domain); 161 if ((*user_info)->domain.str) { 162 (*user_info)->domain.len = strlen(domain); 163 } else { 164 free_user_info(user_info); 165 return NT_STATUS_NO_MEMORY; 166 } 167 168 (*user_info)->client_domain.str = SMB_STRDUP(client_domain); 169 if ((*user_info)->client_domain.str) { 170 (*user_info)->client_domain.len = strlen(client_domain); 171 } else { 172 free_user_info(user_info); 173 return NT_STATUS_NO_MEMORY; 174 } 175 176 (*user_info)->wksta_name.str = SMB_STRDUP(wksta_name); 177 if ((*user_info)->wksta_name.str) { 178 (*user_info)->wksta_name.len = strlen(wksta_name); 179 } else { 180 free_user_info(user_info); 181 return NT_STATUS_NO_MEMORY; 182 } 183 184 DEBUG(5,("making blobs for %s's user_info struct\n", internal_username)); 185 186 if (lm_pwd) 187 (*user_info)->lm_resp = data_blob(lm_pwd->data, lm_pwd->length); 188 if (nt_pwd) 189 (*user_info)->nt_resp = data_blob(nt_pwd->data, nt_pwd->length); 190 if (lm_interactive_pwd) 191 (*user_info)->lm_interactive_pwd = data_blob(lm_interactive_pwd->data, lm_interactive_pwd->length); 192 if (nt_interactive_pwd) 193 (*user_info)->nt_interactive_pwd = data_blob(nt_interactive_pwd->data, nt_interactive_pwd->length); 194 195 if (plaintext) 196 (*user_info)->plaintext_password = data_blob(plaintext->data, plaintext->length); 197 198 (*user_info)->encrypted = encrypted; 199 200 DEBUG(10,("made an %sencrypted user_info for %s (%s)\n", encrypted ? "":"un" , internal_username, smb_name)); 201 202 return NT_STATUS_OK; 203} 204 205/**************************************************************************** 206 Create an auth_usersupplied_data structure after appropriate mapping. 207****************************************************************************/ 208 209NTSTATUS make_user_info_map(auth_usersupplied_info **user_info, 210 const char *smb_name, 211 const char *client_domain, 212 const char *wksta_name, 213 DATA_BLOB *lm_pwd, DATA_BLOB *nt_pwd, 214 DATA_BLOB *lm_interactive_pwd, DATA_BLOB *nt_interactive_pwd, 215 DATA_BLOB *plaintext, 216 BOOL encrypted) 217{ 218 const char *domain; 219 fstring internal_username; 220 fstrcpy(internal_username, smb_name); 221 map_username(internal_username); 222 223 DEBUG(5, ("make_user_info_map: Mapping user [%s]\\[%s] from workstation [%s]\n", 224 client_domain, smb_name, wksta_name)); 225 226 /* don't allow "" as a domain, fixes a Win9X bug 227 where it doens't supply a domain for logon script 228 'net use' commands. */ 229 230 if ( *client_domain ) 231 domain = client_domain; 232 else 233 domain = lp_workgroup(); 234 235 /* do what win2k does. Always map unknown domains to our own 236 and let the "passdb backend" handle unknown users. */ 237 238 if ( !is_trusted_domain(domain) && !strequal(domain, get_global_sam_name()) ) 239 domain = get_default_sam_name(); 240 241 /* we know that it is a trusted domain (and we are allowing them) or it is our domain */ 242 243 return make_user_info(user_info, smb_name, internal_username, 244 client_domain, domain, wksta_name, 245 lm_pwd, nt_pwd, 246 lm_interactive_pwd, nt_interactive_pwd, 247 plaintext, encrypted); 248} 249 250/**************************************************************************** 251 Create an auth_usersupplied_data, making the DATA_BLOBs here. 252 Decrypt and encrypt the passwords. 253****************************************************************************/ 254 255BOOL make_user_info_netlogon_network(auth_usersupplied_info **user_info, 256 const char *smb_name, 257 const char *client_domain, 258 const char *wksta_name, 259 const uchar *lm_network_pwd, int lm_pwd_len, 260 const uchar *nt_network_pwd, int nt_pwd_len) 261{ 262 BOOL ret; 263 NTSTATUS nt_status; 264 DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len); 265 DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len); 266 267 nt_status = make_user_info_map(user_info, 268 smb_name, client_domain, 269 wksta_name, 270 lm_pwd_len ? &lm_blob : NULL, 271 nt_pwd_len ? &nt_blob : NULL, 272 NULL, NULL, NULL, 273 True); 274 275 ret = NT_STATUS_IS_OK(nt_status) ? True : False; 276 277 data_blob_free(&lm_blob); 278 data_blob_free(&nt_blob); 279 return ret; 280} 281 282/**************************************************************************** 283 Create an auth_usersupplied_data, making the DATA_BLOBs here. 284 Decrypt and encrypt the passwords. 285****************************************************************************/ 286 287BOOL make_user_info_netlogon_interactive(auth_usersupplied_info **user_info, 288 const char *smb_name, 289 const char *client_domain, 290 const char *wksta_name, 291 const uchar chal[8], 292 const uchar lm_interactive_pwd[16], 293 const uchar nt_interactive_pwd[16], 294 const uchar *dc_sess_key) 295{ 296 char lm_pwd[16]; 297 char nt_pwd[16]; 298 unsigned char local_lm_response[24]; 299 unsigned char local_nt_response[24]; 300 unsigned char key[16]; 301 302 ZERO_STRUCT(key); 303 memcpy(key, dc_sess_key, 8); 304 305 if (lm_interactive_pwd) memcpy(lm_pwd, lm_interactive_pwd, sizeof(lm_pwd)); 306 if (nt_interactive_pwd) memcpy(nt_pwd, nt_interactive_pwd, sizeof(nt_pwd)); 307 308#ifdef DEBUG_PASSWORD 309 DEBUG(100,("key:")); 310 dump_data(100, (char *)key, sizeof(key)); 311 312 DEBUG(100,("lm owf password:")); 313 dump_data(100, lm_pwd, sizeof(lm_pwd)); 314 315 DEBUG(100,("nt owf password:")); 316 dump_data(100, nt_pwd, sizeof(nt_pwd)); 317#endif 318 319 if (lm_interactive_pwd) 320 SamOEMhash((uchar *)lm_pwd, key, sizeof(lm_pwd)); 321 322 if (nt_interactive_pwd) 323 SamOEMhash((uchar *)nt_pwd, key, sizeof(nt_pwd)); 324 325#ifdef DEBUG_PASSWORD 326 DEBUG(100,("decrypt of lm owf password:")); 327 dump_data(100, lm_pwd, sizeof(lm_pwd)); 328 329 DEBUG(100,("decrypt of nt owf password:")); 330 dump_data(100, nt_pwd, sizeof(nt_pwd)); 331#endif 332 333 if (lm_interactive_pwd) 334 SMBOWFencrypt((const unsigned char *)lm_pwd, chal, local_lm_response); 335 336 if (nt_interactive_pwd) 337 SMBOWFencrypt((const unsigned char *)nt_pwd, chal, local_nt_response); 338 339 /* Password info paranoia */ 340 ZERO_STRUCT(key); 341 342 { 343 BOOL ret; 344 NTSTATUS nt_status; 345 DATA_BLOB local_lm_blob; 346 DATA_BLOB local_nt_blob; 347 348 DATA_BLOB lm_interactive_blob; 349 DATA_BLOB nt_interactive_blob; 350 351 if (lm_interactive_pwd) { 352 local_lm_blob = data_blob(local_lm_response, sizeof(local_lm_response)); 353 lm_interactive_blob = data_blob(lm_pwd, sizeof(lm_pwd)); 354 ZERO_STRUCT(lm_pwd); 355 } 356 357 if (nt_interactive_pwd) { 358 local_nt_blob = data_blob(local_nt_response, sizeof(local_nt_response)); 359 nt_interactive_blob = data_blob(nt_pwd, sizeof(nt_pwd)); 360 ZERO_STRUCT(nt_pwd); 361 } 362 363 nt_status = make_user_info_map(user_info, 364 smb_name, client_domain, 365 wksta_name, 366 lm_interactive_pwd ? &local_lm_blob : NULL, 367 nt_interactive_pwd ? &local_nt_blob : NULL, 368 lm_interactive_pwd ? &lm_interactive_blob : NULL, 369 nt_interactive_pwd ? &nt_interactive_blob : NULL, 370 NULL, 371 True); 372 373 ret = NT_STATUS_IS_OK(nt_status) ? True : False; 374 data_blob_free(&local_lm_blob); 375 data_blob_free(&local_nt_blob); 376 data_blob_free(&lm_interactive_blob); 377 data_blob_free(&nt_interactive_blob); 378 return ret; 379 } 380} 381 382 383/**************************************************************************** 384 Create an auth_usersupplied_data structure 385****************************************************************************/ 386 387BOOL make_user_info_for_reply(auth_usersupplied_info **user_info, 388 const char *smb_name, 389 const char *client_domain, 390 const uint8 chal[8], 391 DATA_BLOB plaintext_password) 392{ 393 394 DATA_BLOB local_lm_blob; 395 DATA_BLOB local_nt_blob; 396 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; 397 398 /* 399 * Not encrypted - do so. 400 */ 401 402 DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted format.\n")); 403 404 if (plaintext_password.data) { 405 unsigned char local_lm_response[24]; 406 407#ifdef DEBUG_PASSWORD 408 DEBUG(10,("Unencrypted password (len %d):\n",plaintext_password.length)); 409 dump_data(100, plaintext_password.data, plaintext_password.length); 410#endif 411 412 SMBencrypt( (const char *)plaintext_password.data, (const uchar*)chal, local_lm_response); 413 local_lm_blob = data_blob(local_lm_response, 24); 414 415 /* We can't do an NT hash here, as the password needs to be 416 case insensitive */ 417 local_nt_blob = data_blob(NULL, 0); 418 419 } else { 420 local_lm_blob = data_blob(NULL, 0); 421 local_nt_blob = data_blob(NULL, 0); 422 } 423 424 ret = make_user_info_map(user_info, smb_name, 425 client_domain, 426 get_remote_machine_name(), 427 local_lm_blob.data ? &local_lm_blob : NULL, 428 local_nt_blob.data ? &local_nt_blob : NULL, 429 NULL, NULL, 430 plaintext_password.data ? &plaintext_password : NULL, 431 False); 432 433 data_blob_free(&local_lm_blob); 434 return NT_STATUS_IS_OK(ret) ? True : False; 435} 436 437/**************************************************************************** 438 Create an auth_usersupplied_data structure 439****************************************************************************/ 440 441NTSTATUS make_user_info_for_reply_enc(auth_usersupplied_info **user_info, 442 const char *smb_name, 443 const char *client_domain, 444 DATA_BLOB lm_resp, DATA_BLOB nt_resp) 445{ 446 return make_user_info_map(user_info, smb_name, 447 client_domain, 448 get_remote_machine_name(), 449 lm_resp.data ? &lm_resp : NULL, 450 nt_resp.data ? &nt_resp : NULL, 451 NULL, NULL, NULL, 452 True); 453} 454 455/**************************************************************************** 456 Create a guest user_info blob, for anonymous authenticaion. 457****************************************************************************/ 458 459BOOL make_user_info_guest(auth_usersupplied_info **user_info) 460{ 461 NTSTATUS nt_status; 462 463 nt_status = make_user_info(user_info, 464 "","", 465 "","", 466 "", 467 NULL, NULL, 468 NULL, NULL, 469 NULL, 470 True); 471 472 return NT_STATUS_IS_OK(nt_status) ? True : False; 473} 474 475/**************************************************************************** 476 prints a NT_USER_TOKEN to debug output. 477****************************************************************************/ 478 479void debug_nt_user_token(int dbg_class, int dbg_lev, NT_USER_TOKEN *token) 480{ 481 fstring sid_str; 482 size_t i; 483 484 if (!token) { 485 DEBUGC(dbg_class, dbg_lev, ("NT user token: (NULL)\n")); 486 return; 487 } 488 489 DEBUGC(dbg_class, dbg_lev, ("NT user token of user %s\n", 490 sid_to_string(sid_str, &token->user_sids[0]) )); 491 DEBUGADDC(dbg_class, dbg_lev, ("contains %lu SIDs\n", (unsigned long)token->num_sids)); 492 for (i = 0; i < token->num_sids; i++) 493 DEBUGADDC(dbg_class, dbg_lev, ("SID[%3lu]: %s\n", (unsigned long)i, 494 sid_to_string(sid_str, &token->user_sids[i]))); 495 496 dump_se_priv( dbg_class, dbg_lev, &token->privileges ); 497} 498 499/**************************************************************************** 500 prints a UNIX 'token' to debug output. 501****************************************************************************/ 502 503void debug_unix_user_token(int dbg_class, int dbg_lev, uid_t uid, gid_t gid, int n_groups, gid_t *groups) 504{ 505 int i; 506 DEBUGC(dbg_class, dbg_lev, ("UNIX token of user %ld\n", (long int)uid)); 507 508 DEBUGADDC(dbg_class, dbg_lev, ("Primary group is %ld and contains %i supplementary groups\n", (long int)gid, n_groups)); 509 for (i = 0; i < n_groups; i++) 510 DEBUGADDC(dbg_class, dbg_lev, ("Group[%3i]: %ld\n", i, 511 (long int)groups[i])); 512} 513 514/**************************************************************************** 515 Create the SID list for this user. 516****************************************************************************/ 517 518static NTSTATUS create_nt_user_token(const DOM_SID *user_sid, const DOM_SID *group_sid, 519 int n_groupSIDs, DOM_SID *groupSIDs, 520 BOOL is_guest, NT_USER_TOKEN **token) 521{ 522 NTSTATUS nt_status = NT_STATUS_OK; 523 NT_USER_TOKEN *ptoken; 524 int i; 525 int sid_ndx; 526 527 if ((ptoken = SMB_MALLOC_P(NT_USER_TOKEN)) == NULL) { 528 DEBUG(0, ("create_nt_token: Out of memory allocating token\n")); 529 nt_status = NT_STATUS_NO_MEMORY; 530 return nt_status; 531 } 532 533 ZERO_STRUCTP(ptoken); 534 535 ptoken->num_sids = n_groupSIDs + 5; 536 537 if ((ptoken->user_sids = SMB_MALLOC_ARRAY( DOM_SID, ptoken->num_sids )) == NULL) { 538 DEBUG(0, ("create_nt_token: Out of memory allocating SIDs\n")); 539 nt_status = NT_STATUS_NO_MEMORY; 540 return nt_status; 541 } 542 543 memset((char*)ptoken->user_sids,0,sizeof(DOM_SID) * ptoken->num_sids); 544 545 /* 546 * Note - user SID *MUST* be first in token ! 547 * se_access_check depends on this. 548 * 549 * Primary group SID is second in token. Convention. 550 */ 551 552 sid_copy(&ptoken->user_sids[PRIMARY_USER_SID_INDEX], user_sid); 553 if (group_sid) 554 sid_copy(&ptoken->user_sids[PRIMARY_GROUP_SID_INDEX], group_sid); 555 556 /* 557 * Finally add the "standard" SIDs. 558 * The only difference between guest and "anonymous" (which we 559 * don't really support) is the addition of Authenticated_Users. 560 */ 561 562 sid_copy(&ptoken->user_sids[2], &global_sid_World); 563 sid_copy(&ptoken->user_sids[3], &global_sid_Network); 564 565 if (is_guest) 566 sid_copy(&ptoken->user_sids[4], &global_sid_Builtin_Guests); 567 else 568 sid_copy(&ptoken->user_sids[4], &global_sid_Authenticated_Users); 569 570 sid_ndx = 5; /* next available spot */ 571 572 for (i = 0; i < n_groupSIDs; i++) { 573 size_t check_sid_idx; 574 for (check_sid_idx = 1; check_sid_idx < ptoken->num_sids; check_sid_idx++) { 575 if (sid_equal(&ptoken->user_sids[check_sid_idx], 576 &groupSIDs[i])) { 577 break; 578 } 579 } 580 581 if (check_sid_idx >= ptoken->num_sids) /* Not found already */ { 582 sid_copy(&ptoken->user_sids[sid_ndx++], &groupSIDs[i]); 583 } else { 584 ptoken->num_sids--; 585 } 586 } 587 588 /* add privileges assigned to this user */ 589 590 get_privileges_for_sids( &ptoken->privileges, ptoken->user_sids, ptoken->num_sids ); 591 592 debug_nt_user_token(DBGC_AUTH, 10, ptoken); 593 594 if ((lp_log_nt_token_command() != NULL) && 595 (strlen(lp_log_nt_token_command()) > 0)) { 596 TALLOC_CTX *mem_ctx; 597 char *command; 598 fstring sidstr; 599 char *user_sidstr, *group_sidstr; 600 601 mem_ctx = talloc_init("setnttoken"); 602 if (mem_ctx == NULL) 603 return NT_STATUS_NO_MEMORY; 604 605 sid_to_string(sidstr, &ptoken->user_sids[0]); 606 user_sidstr = talloc_strdup(mem_ctx, sidstr); 607 608 group_sidstr = talloc_strdup(mem_ctx, ""); 609 for (i=1; i<ptoken->num_sids; i++) { 610 sid_to_string(sidstr, &ptoken->user_sids[i]); 611 group_sidstr = talloc_asprintf(mem_ctx, "%s %s", 612 group_sidstr, sidstr); 613 } 614 615 command = strdup(lp_log_nt_token_command()); 616 command = realloc_string_sub(command, "%s", user_sidstr); 617 command = realloc_string_sub(command, "%t", group_sidstr); 618 DEBUG(8, ("running command: [%s]\n", command)); 619 if (smbrun(command, NULL) != 0) { 620 DEBUG(0, ("Could not log NT token\n")); 621 nt_status = NT_STATUS_ACCESS_DENIED; 622 } 623 talloc_destroy(mem_ctx); 624 SAFE_FREE(command); 625 } 626 627 *token = ptoken; 628 629 return nt_status; 630} 631 632/**************************************************************************** 633 Create the SID list for this user. 634****************************************************************************/ 635 636NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups, BOOL is_guest) 637{ 638 DOM_SID user_sid; 639 DOM_SID group_sid; 640 DOM_SID *group_sids; 641 NT_USER_TOKEN *token; 642 int i; 643 644 if (!NT_STATUS_IS_OK(uid_to_sid(&user_sid, uid))) { 645 return NULL; 646 } 647 if (!NT_STATUS_IS_OK(gid_to_sid(&group_sid, gid))) { 648 return NULL; 649 } 650 651 group_sids = SMB_MALLOC_ARRAY(DOM_SID, ngroups); 652 if (!group_sids) { 653 DEBUG(0, ("create_nt_token: malloc() failed for DOM_SID list!\n")); 654 return NULL; 655 } 656 657 for (i = 0; i < ngroups; i++) { 658 if (!NT_STATUS_IS_OK(gid_to_sid(&(group_sids)[i], (groups)[i]))) { 659 DEBUG(1, ("create_nt_token: failed to convert gid %ld to a sid!\n", (long int)groups[i])); 660 SAFE_FREE(group_sids); 661 return NULL; 662 } 663 } 664 665 if (!NT_STATUS_IS_OK(create_nt_user_token(&user_sid, &group_sid, 666 ngroups, group_sids, is_guest, &token))) { 667 SAFE_FREE(group_sids); 668 return NULL; 669 } 670 671 SAFE_FREE(group_sids); 672 673 return token; 674} 675 676/****************************************************************************** 677 * this function returns the groups (SIDs) of the local SAM the user is in. 678 * If this samba server is a DC of the domain the user belongs to, it returns 679 * both domain groups and local / builtin groups. If the user is in a trusted 680 * domain, or samba is a member server of a domain, then this function returns 681 * local and builtin groups the user is a member of. 682 * 683 * currently this is a hack, as there is no sam implementation that is capable 684 * of groups. 685 * 686 * NOTE!! This function will fail if you pass in a winbind user without 687 * the domain --jerry 688 ******************************************************************************/ 689 690static NTSTATUS get_user_groups(const char *username, uid_t uid, gid_t gid, 691 int *n_groups, DOM_SID **groups, gid_t **unix_groups) 692{ 693 int n_unix_groups; 694 int i; 695 696 *n_groups = 0; 697 *groups = NULL; 698 699 if (strchr(username, *lp_winbind_separator()) == NULL) { 700 NTSTATUS result; 701 702 become_root(); 703 result = pdb_enum_group_memberships(username, gid, groups, 704 unix_groups, n_groups); 705 unbecome_root(); 706 return result; 707 } 708 709 /* We have the separator, this must be winbind */ 710 711 n_unix_groups = winbind_getgroups( username, unix_groups ); 712 713 DEBUG(10,("get_user_groups: winbind_getgroups(%s): result = %s\n", 714 username, n_unix_groups == -1 ? "FAIL" : "SUCCESS")); 715 716 if ( n_unix_groups == -1 ) 717 return NT_STATUS_NO_SUCH_USER; /* what should this return 718 * value be? */ 719 720 debug_unix_user_token(DBGC_CLASS, 5, uid, gid, n_unix_groups, *unix_groups); 721 722 /* now setup the space for storing the SIDS */ 723 724 if (n_unix_groups > 0) { 725 726 *groups = SMB_MALLOC_ARRAY(DOM_SID, n_unix_groups); 727 728 if (!*groups) { 729 DEBUG(0, ("get_user_group: malloc() failed for DOM_SID list!\n")); 730 SAFE_FREE(*unix_groups); 731 return NT_STATUS_NO_MEMORY; 732 } 733 } 734 735 *n_groups = n_unix_groups; 736 737 for (i = 0; i < *n_groups; i++) { 738 if (!NT_STATUS_IS_OK(gid_to_sid(&(*groups)[i], (*unix_groups)[i]))) { 739 DEBUG(1, ("get_user_groups: failed to convert gid %ld to a sid!\n", 740 (long int)(*unix_groups)[i+1])); 741 SAFE_FREE(*groups); 742 SAFE_FREE(*unix_groups); 743 return NT_STATUS_NO_SUCH_USER; 744 } 745 } 746 747 return NT_STATUS_OK; 748} 749 750/*************************************************************************** 751 Make a user_info struct 752***************************************************************************/ 753 754static NTSTATUS make_server_info(auth_serversupplied_info **server_info) 755{ 756 *server_info = SMB_MALLOC_P(auth_serversupplied_info); 757 if (!*server_info) { 758 DEBUG(0,("make_server_info: malloc failed!\n")); 759 return NT_STATUS_NO_MEMORY; 760 } 761 ZERO_STRUCTP(*server_info); 762 763 /* Initialise the uid and gid values to something non-zero 764 which may save us from giving away root access if there 765 is a bug in allocating these fields. */ 766 767 (*server_info)->uid = -1; 768 (*server_info)->gid = -1; 769 770 return NT_STATUS_OK; 771} 772 773/*************************************************************************** 774Fill a server_info struct from a SAM_ACCOUNT with their groups 775***************************************************************************/ 776 777static NTSTATUS add_user_groups(auth_serversupplied_info **server_info, 778 const char * unix_username, 779 SAM_ACCOUNT *sampass, 780 uid_t uid, gid_t gid) 781{ 782 NTSTATUS nt_status; 783 const DOM_SID *user_sid = pdb_get_user_sid(sampass); 784 const DOM_SID *group_sid = pdb_get_group_sid(sampass); 785 int n_groupSIDs = 0; 786 DOM_SID *groupSIDs = NULL; 787 gid_t *unix_groups = NULL; 788 NT_USER_TOKEN *token; 789 BOOL is_guest; 790 uint32 rid; 791 792 nt_status = get_user_groups(unix_username, uid, gid, 793 &n_groupSIDs, &groupSIDs, &unix_groups); 794 795 if (!NT_STATUS_IS_OK(nt_status)) { 796 DEBUG(4,("get_user_groups_from_local_sam failed\n")); 797 free_server_info(server_info); 798 return nt_status; 799 } 800 801 is_guest = (sid_peek_rid(user_sid, &rid) && rid == DOMAIN_USER_RID_GUEST); 802 803 if (!NT_STATUS_IS_OK(nt_status = create_nt_user_token(user_sid, group_sid, 804 n_groupSIDs, groupSIDs, is_guest, 805 &token))) 806 { 807 DEBUG(4,("create_nt_user_token failed\n")); 808 SAFE_FREE(groupSIDs); 809 SAFE_FREE(unix_groups); 810 free_server_info(server_info); 811 return nt_status; 812 } 813 814 SAFE_FREE(groupSIDs); 815 816 (*server_info)->n_groups = n_groupSIDs; 817 (*server_info)->groups = unix_groups; 818 (*server_info)->ptok = token; 819 820 return nt_status; 821} 822 823/*************************************************************************** 824 Make (and fill) a user_info struct from a SAM_ACCOUNT 825***************************************************************************/ 826 827NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info, 828 SAM_ACCOUNT *sampass) 829{ 830 NTSTATUS nt_status; 831 struct passwd *pwd; 832 833 if (!NT_STATUS_IS_OK(nt_status = make_server_info(server_info))) 834 return nt_status; 835 836 (*server_info)->sam_account = sampass; 837 838 if ( !(pwd = getpwnam_alloc(pdb_get_username(sampass))) ) { 839 DEBUG(1, ("User %s in passdb, but getpwnam() fails!\n", 840 pdb_get_username(sampass))); 841 free_server_info(server_info); 842 return NT_STATUS_NO_SUCH_USER; 843 } 844 (*server_info)->unix_name = smb_xstrdup(pwd->pw_name); 845 (*server_info)->gid = pwd->pw_gid; 846 (*server_info)->uid = pwd->pw_uid; 847 848 passwd_free(&pwd); 849 850 if (!NT_STATUS_IS_OK(nt_status = add_user_groups(server_info, pdb_get_username(sampass), 851 sampass, 852 (*server_info)->uid, 853 (*server_info)->gid))) 854 { 855 free_server_info(server_info); 856 return nt_status; 857 } 858 859 (*server_info)->sam_fill_level = SAM_FILL_ALL; 860 DEBUG(5,("make_server_info_sam: made server info for user %s -> %s\n", 861 pdb_get_username(sampass), 862 (*server_info)->unix_name)); 863 864 return nt_status; 865} 866 867/*************************************************************************** 868 Make (and fill) a user_info struct from a 'struct passwd' by conversion 869 to a SAM_ACCOUNT 870***************************************************************************/ 871 872NTSTATUS make_server_info_pw(auth_serversupplied_info **server_info, 873 char *unix_username, 874 struct passwd *pwd) 875{ 876 NTSTATUS nt_status; 877 SAM_ACCOUNT *sampass = NULL; 878 if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_pw(&sampass, pwd))) { 879 return nt_status; 880 } 881 if (!NT_STATUS_IS_OK(nt_status = make_server_info(server_info))) { 882 return nt_status; 883 } 884 885 (*server_info)->sam_account = sampass; 886 887 if (!NT_STATUS_IS_OK(nt_status = add_user_groups(server_info, unix_username, 888 sampass, pwd->pw_uid, pwd->pw_gid))) 889 { 890 return nt_status; 891 } 892 893 (*server_info)->unix_name = smb_xstrdup(unix_username); 894 895 (*server_info)->sam_fill_level = SAM_FILL_ALL; 896 (*server_info)->uid = pwd->pw_uid; 897 (*server_info)->gid = pwd->pw_gid; 898 return nt_status; 899} 900 901/*************************************************************************** 902 Make (and fill) a user_info struct for a guest login. 903***************************************************************************/ 904 905static NTSTATUS make_new_server_info_guest(auth_serversupplied_info **server_info) 906{ 907 NTSTATUS nt_status; 908 SAM_ACCOUNT *sampass = NULL; 909 DOM_SID guest_sid; 910 911 if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(&sampass))) { 912 return nt_status; 913 } 914 915 sid_copy(&guest_sid, get_global_sam_sid()); 916 sid_append_rid(&guest_sid, DOMAIN_USER_RID_GUEST); 917 918 become_root(); 919 if (!pdb_getsampwsid(sampass, &guest_sid)) { 920 unbecome_root(); 921 return NT_STATUS_NO_SUCH_USER; 922 } 923 unbecome_root(); 924 925 nt_status = make_server_info_sam(server_info, sampass); 926 927 if (NT_STATUS_IS_OK(nt_status)) { 928 static const char zeros[16]; 929 (*server_info)->guest = True; 930 931 /* annoying, but the Guest really does have a session key, 932 and it is all zeros! */ 933 (*server_info)->user_session_key = data_blob(zeros, sizeof(zeros)); 934 (*server_info)->lm_session_key = data_blob(zeros, sizeof(zeros)); 935 } 936 937 return nt_status; 938} 939 940static auth_serversupplied_info *copy_serverinfo(auth_serversupplied_info *src) 941{ 942 auth_serversupplied_info *dst; 943 944 if (!NT_STATUS_IS_OK(make_server_info(&dst))) 945 return NULL; 946 947 dst->guest = src->guest; 948 dst->uid = src->uid; 949 dst->gid = src->gid; 950 dst->n_groups = src->n_groups; 951 if (src->n_groups != 0) 952 dst->groups = memdup(src->groups, sizeof(gid_t)*dst->n_groups); 953 else 954 dst->groups = NULL; 955 dst->ptok = dup_nt_token(src->ptok); 956 dst->user_session_key = data_blob(src->user_session_key.data, 957 src->user_session_key.length); 958 dst->lm_session_key = data_blob(src->lm_session_key.data, 959 src->lm_session_key.length); 960 pdb_copy_sam_account(src->sam_account, &dst->sam_account); 961 dst->pam_handle = NULL; 962 dst->unix_name = smb_xstrdup(src->unix_name); 963 964 return dst; 965} 966 967static auth_serversupplied_info *guest_info = NULL; 968 969BOOL init_guest_info(void) 970{ 971 if (guest_info != NULL) 972 return True; 973 974 return NT_STATUS_IS_OK(make_new_server_info_guest(&guest_info)); 975} 976 977NTSTATUS make_server_info_guest(auth_serversupplied_info **server_info) 978{ 979 *server_info = copy_serverinfo(guest_info); 980 return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY; 981} 982 983/*************************************************************************** 984 Purely internal function for make_server_info_info3 985 Fill the sam account from getpwnam 986***************************************************************************/ 987static NTSTATUS fill_sam_account(TALLOC_CTX *mem_ctx, 988 const char *domain, 989 const char *username, 990 char **found_username, 991 uid_t *uid, gid_t *gid, 992 SAM_ACCOUNT **sam_account) 993{ 994 fstring dom_user, lower_username; 995 fstring real_username; 996 struct passwd *passwd; 997 998 fstrcpy( lower_username, username ); 999 strlower_m( lower_username ); 1000 1001 fstr_sprintf(dom_user, "%s%c%s", domain, *lp_winbind_separator(), 1002 lower_username); 1003 1004 /* get the passwd struct but don't create the user if he/she 1005 does not exist. We were explicitly called from a following 1006 a winbindd authentication request so we should assume that 1007 nss_winbindd is working */ 1008 1009 map_username( dom_user ); 1010 1011 if ( !(passwd = smb_getpwnam( dom_user, real_username, True )) ) 1012 return NT_STATUS_NO_SUCH_USER; 1013 1014 *uid = passwd->pw_uid; 1015 *gid = passwd->pw_gid; 1016 1017 /* This is pointless -- there is no suport for differing 1018 unix and windows names. Make sure to always store the 1019 one we actually looked up and succeeded. Have I mentioned 1020 why I hate the 'winbind use default domain' parameter? 1021 --jerry */ 1022 1023 *found_username = talloc_strdup( mem_ctx, real_username ); 1024 1025 DEBUG(5,("fill_sam_account: located username was [%s]\n", 1026 *found_username)); 1027 1028 return pdb_init_sam_pw(sam_account, passwd); 1029} 1030 1031/**************************************************************************** 1032 Wrapper to allow the getpwnam() call to strip the domain name and 1033 try again in case a local UNIX user is already there. Also run through 1034 the username if we fallback to the username only. 1035 ****************************************************************************/ 1036 1037struct passwd *smb_getpwnam( char *domuser, fstring save_username, BOOL create ) 1038{ 1039 struct passwd *pw = NULL; 1040 char *p; 1041 fstring username; 1042 1043 /* we only save a copy of the username it has been mangled 1044 by winbindd use default domain */ 1045 1046 save_username[0] = '\0'; 1047 1048 /* don't call map_username() here since it has to be done higher 1049 up the stack so we don't call it mutliple times */ 1050 1051 fstrcpy( username, domuser ); 1052 1053 p = strchr_m( username, *lp_winbind_separator() ); 1054 1055 /* code for a DOMAIN\user string */ 1056 1057 if ( p ) { 1058 fstring strip_username; 1059 1060 pw = Get_Pwnam( domuser ); 1061 if ( pw ) { 1062 /* make sure we get the case of the username correct */ 1063 /* work around 'winbind use default domain = yes' */ 1064 1065 if ( !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) { 1066 char *domain; 1067 1068 /* split the domain and username into 2 strings */ 1069 *p = '\0'; 1070 domain = username; 1071 1072 fstr_sprintf(save_username, "%s%c%s", domain, *lp_winbind_separator(), pw->pw_name); 1073 } 1074 else 1075 fstrcpy( save_username, pw->pw_name ); 1076 1077 /* whew -- done! */ 1078 return pw; 1079 } 1080 1081 /* setup for lookup of just the username */ 1082 /* remember that p and username are overlapping memory */ 1083 1084 p++; 1085 fstrcpy( strip_username, p ); 1086 fstrcpy( username, strip_username ); 1087 } 1088 1089 /* just lookup a plain username */ 1090 1091 pw = Get_Pwnam(username); 1092 1093 /* Create local user if requested. */ 1094 1095 if ( !pw && create ) { 1096 /* Don't add a machine account. */ 1097 if (username[strlen(username)-1] == '$') 1098 return NULL; 1099 1100 auth_add_user_script(NULL, username); 1101 pw = Get_Pwnam(username); 1102 } 1103 1104 /* one last check for a valid passwd struct */ 1105 1106 if ( pw ) 1107 fstrcpy( save_username, pw->pw_name ); 1108 1109 return pw; 1110} 1111 1112/*************************************************************************** 1113 Make a server_info struct from the info3 returned by a domain logon 1114***************************************************************************/ 1115 1116NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, 1117 const char *internal_username, 1118 const char *sent_nt_username, 1119 const char *domain, 1120 auth_serversupplied_info **server_info, 1121 NET_USER_INFO_3 *info3) 1122{ 1123 static const char zeros[16]; 1124 1125 NTSTATUS nt_status = NT_STATUS_OK; 1126 char *found_username; 1127 const char *nt_domain; 1128 const char *nt_username; 1129 1130 SAM_ACCOUNT *sam_account = NULL; 1131 DOM_SID user_sid; 1132 DOM_SID group_sid; 1133 1134 uid_t uid; 1135 gid_t gid; 1136 1137 int n_lgroupSIDs; 1138 DOM_SID *lgroupSIDs = NULL; 1139 1140 gid_t *unix_groups = NULL; 1141 NT_USER_TOKEN *token; 1142 1143 DOM_SID *all_group_SIDs; 1144 size_t i; 1145 1146 /* 1147 Here is where we should check the list of 1148 trusted domains, and verify that the SID 1149 matches. 1150 */ 1151 1152 sid_copy(&user_sid, &info3->dom_sid.sid); 1153 if (!sid_append_rid(&user_sid, info3->user_rid)) { 1154 return NT_STATUS_INVALID_PARAMETER; 1155 } 1156 1157 sid_copy(&group_sid, &info3->dom_sid.sid); 1158 if (!sid_append_rid(&group_sid, info3->group_rid)) { 1159 return NT_STATUS_INVALID_PARAMETER; 1160 } 1161 1162 if (!(nt_username = unistr2_tdup(mem_ctx, &(info3->uni_user_name)))) { 1163 /* If the server didn't give us one, just use the one we sent them */ 1164 nt_username = sent_nt_username; 1165 } 1166 1167 if (!(nt_domain = unistr2_tdup(mem_ctx, &(info3->uni_logon_dom)))) { 1168 /* If the server didn't give us one, just use the one we sent them */ 1169 nt_domain = domain; 1170 } 1171 1172 /* try to fill the SAM account.. If getpwnam() fails, then try the 1173 add user script (2.2.x behavior). 1174 1175 We use the _unmapped_ username here in an attempt to provide 1176 consistent username mapping behavior between kerberos and NTLM[SSP] 1177 authentication in domain mode security. I.E. Username mapping should 1178 be applied to the fully qualified username (e.g. DOMAIN\user) and 1179 no just the login name. Yes this mean swe called map_username() 1180 unnecessarily in make_user_info_map() but that is how the current 1181 code is designed. Making the change here is the least disruptive 1182 place. -- jerry */ 1183 1184 nt_status = fill_sam_account(mem_ctx, nt_domain, sent_nt_username, 1185 &found_username, &uid, &gid, &sam_account); 1186 1187 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER)) { 1188 DEBUG(3,("User %s does not exist, trying to add it\n", internal_username)); 1189 auth_add_user_script( nt_domain, sent_nt_username ); 1190 nt_status = fill_sam_account( mem_ctx, nt_domain, sent_nt_username, 1191 &found_username, &uid, &gid, &sam_account ); 1192 } 1193 1194 if (!NT_STATUS_IS_OK(nt_status)) { 1195 DEBUG(0, ("make_server_info_info3: pdb_init_sam failed!\n")); 1196 return nt_status; 1197 } 1198 1199 if (!pdb_set_nt_username(sam_account, nt_username, PDB_CHANGED)) { 1200 pdb_free_sam(&sam_account); 1201 return NT_STATUS_NO_MEMORY; 1202 } 1203 1204 if (!pdb_set_username(sam_account, nt_username, PDB_CHANGED)) { 1205 pdb_free_sam(&sam_account); 1206 return NT_STATUS_NO_MEMORY; 1207 } 1208 1209 if (!pdb_set_domain(sam_account, nt_domain, PDB_CHANGED)) { 1210 pdb_free_sam(&sam_account); 1211 return NT_STATUS_NO_MEMORY; 1212 } 1213 1214 if (!pdb_set_user_sid(sam_account, &user_sid, PDB_CHANGED)) { 1215 pdb_free_sam(&sam_account); 1216 return NT_STATUS_UNSUCCESSFUL; 1217 } 1218 1219 if (!pdb_set_group_sid(sam_account, &group_sid, PDB_CHANGED)) { 1220 pdb_free_sam(&sam_account); 1221 return NT_STATUS_UNSUCCESSFUL; 1222 } 1223 1224 if (!pdb_set_fullname(sam_account, unistr2_static(&(info3->uni_full_name)), 1225 PDB_CHANGED)) { 1226 pdb_free_sam(&sam_account); 1227 return NT_STATUS_NO_MEMORY; 1228 } 1229 1230 if (!pdb_set_logon_script(sam_account, unistr2_static(&(info3->uni_logon_script)), PDB_CHANGED)) { 1231 pdb_free_sam(&sam_account); 1232 return NT_STATUS_NO_MEMORY; 1233 } 1234 1235 if (!pdb_set_profile_path(sam_account, unistr2_static(&(info3->uni_profile_path)), PDB_CHANGED)) { 1236 pdb_free_sam(&sam_account); 1237 return NT_STATUS_NO_MEMORY; 1238 } 1239 1240 if (!pdb_set_homedir(sam_account, unistr2_static(&(info3->uni_home_dir)), PDB_CHANGED)) { 1241 pdb_free_sam(&sam_account); 1242 return NT_STATUS_NO_MEMORY; 1243 } 1244 1245 if (!pdb_set_dir_drive(sam_account, unistr2_static(&(info3->uni_dir_drive)), PDB_CHANGED)) { 1246 pdb_free_sam(&sam_account); 1247 return NT_STATUS_NO_MEMORY; 1248 } 1249 1250 if (!NT_STATUS_IS_OK(nt_status = make_server_info(server_info))) { 1251 DEBUG(4, ("make_server_info failed!\n")); 1252 pdb_free_sam(&sam_account); 1253 return nt_status; 1254 } 1255 1256 /* save this here to _net_sam_logon() doesn't fail (it assumes a 1257 valid SAM_ACCOUNT) */ 1258 1259 (*server_info)->sam_account = sam_account; 1260 1261 (*server_info)->unix_name = smb_xstrdup(found_username); 1262 1263 /* Fill in the unix info we found on the way */ 1264 1265 (*server_info)->sam_fill_level = SAM_FILL_ALL; 1266 (*server_info)->uid = uid; 1267 (*server_info)->gid = gid; 1268 1269 /* Store the user group information in the server_info 1270 returned to the caller. */ 1271 1272 nt_status = get_user_groups((*server_info)->unix_name, 1273 uid, gid, &n_lgroupSIDs, &lgroupSIDs, &unix_groups); 1274 1275 if ( !NT_STATUS_IS_OK(nt_status) ) { 1276 DEBUG(4,("get_user_groups failed\n")); 1277 return nt_status; 1278 } 1279 1280 (*server_info)->groups = unix_groups; 1281 (*server_info)->n_groups = n_lgroupSIDs; 1282 1283 /* Create a 'combined' list of all SIDs we might want in the SD */ 1284 1285 all_group_SIDs = SMB_MALLOC_ARRAY(DOM_SID,info3->num_groups2 + info3->num_other_sids + n_lgroupSIDs); 1286 1287 if (!all_group_SIDs) { 1288 DEBUG(0, ("malloc() failed for DOM_SID list!\n")); 1289 SAFE_FREE(lgroupSIDs); 1290 free_server_info(server_info); 1291 return NT_STATUS_NO_MEMORY; 1292 } 1293 1294 /* and create (by appending rids) the 'domain' sids */ 1295 1296 for (i = 0; i < info3->num_groups2; i++) { 1297 1298 sid_copy(&all_group_SIDs[i], &(info3->dom_sid.sid)); 1299 1300 if (!sid_append_rid(&all_group_SIDs[i], info3->gids[i].g_rid)) { 1301 1302 nt_status = NT_STATUS_INVALID_PARAMETER; 1303 1304 DEBUG(3,("could not append additional group rid 0x%x\n", 1305 info3->gids[i].g_rid)); 1306 1307 SAFE_FREE(lgroupSIDs); 1308 SAFE_FREE(all_group_SIDs); 1309 free_server_info(server_info); 1310 1311 return nt_status; 1312 1313 } 1314 } 1315 1316 /* Copy 'other' sids. We need to do sid filtering here to 1317 prevent possible elevation of privileges. See: 1318 1319 http://www.microsoft.com/windows2000/techinfo/administration/security/sidfilter.asp 1320 */ 1321 1322 for (i = 0; i < info3->num_other_sids; i++) { 1323 sid_copy(&all_group_SIDs[info3->num_groups2 + i], 1324 &info3->other_sids[i].sid); 1325 } 1326 1327 1328 /* add local alias sids */ 1329 1330 for (i = 0; i < n_lgroupSIDs; i++) { 1331 sid_copy(&all_group_SIDs[info3->num_groups2 + 1332 info3->num_other_sids + i], 1333 &lgroupSIDs[i]); 1334 } 1335 1336 /* Where are the 'global' sids... */ 1337 1338 /* can the user be guest? if yes, where is it stored? */ 1339 1340 nt_status = create_nt_user_token(&user_sid, &group_sid, 1341 info3->num_groups2 + info3->num_other_sids + n_lgroupSIDs, 1342 all_group_SIDs, False, &token); 1343 1344 if ( !NT_STATUS_IS_OK(nt_status) ) { 1345 DEBUG(4,("create_nt_user_token failed\n")); 1346 SAFE_FREE(lgroupSIDs); 1347 SAFE_FREE(all_group_SIDs); 1348 free_server_info(server_info); 1349 return nt_status; 1350 } 1351 1352 (*server_info)->ptok = token; 1353 1354 SAFE_FREE(lgroupSIDs); 1355 SAFE_FREE(all_group_SIDs); 1356 1357 /* ensure we are never given NULL session keys */ 1358 1359 if (memcmp(info3->user_sess_key, zeros, sizeof(zeros)) == 0) { 1360 (*server_info)->user_session_key = data_blob(NULL, 0); 1361 } else { 1362 (*server_info)->user_session_key = data_blob(info3->user_sess_key, sizeof(info3->user_sess_key)); 1363 } 1364 1365 if (memcmp(info3->lm_sess_key, zeros, 8) == 0) { 1366 (*server_info)->lm_session_key = data_blob(NULL, 0); 1367 } else { 1368 (*server_info)->lm_session_key = data_blob(info3->lm_sess_key, sizeof(info3->lm_sess_key)); 1369 } 1370 1371 return NT_STATUS_OK; 1372} 1373 1374/*************************************************************************** 1375 Free a user_info struct 1376***************************************************************************/ 1377 1378void free_user_info(auth_usersupplied_info **user_info) 1379{ 1380 DEBUG(5,("attempting to free (and zero) a user_info structure\n")); 1381 if (*user_info != NULL) { 1382 if ((*user_info)->smb_name.str) { 1383 DEBUG(10,("structure was created for %s\n", (*user_info)->smb_name.str)); 1384 } 1385 SAFE_FREE((*user_info)->smb_name.str); 1386 SAFE_FREE((*user_info)->internal_username.str); 1387 SAFE_FREE((*user_info)->client_domain.str); 1388 SAFE_FREE((*user_info)->domain.str); 1389 SAFE_FREE((*user_info)->wksta_name.str); 1390 data_blob_free(&(*user_info)->lm_resp); 1391 data_blob_free(&(*user_info)->nt_resp); 1392 data_blob_clear_free(&(*user_info)->lm_interactive_pwd); 1393 data_blob_clear_free(&(*user_info)->nt_interactive_pwd); 1394 data_blob_clear_free(&(*user_info)->plaintext_password); 1395 ZERO_STRUCT(**user_info); 1396 } 1397 SAFE_FREE(*user_info); 1398} 1399 1400/*************************************************************************** 1401 Clear out a server_info struct that has been allocated 1402***************************************************************************/ 1403 1404void free_server_info(auth_serversupplied_info **server_info) 1405{ 1406 DEBUG(5,("attempting to free (and zero) a server_info structure\n")); 1407 if (*server_info != NULL) { 1408 pdb_free_sam(&(*server_info)->sam_account); 1409 1410 /* call pam_end here, unless we know we are keeping it */ 1411 delete_nt_token( &(*server_info)->ptok ); 1412 SAFE_FREE((*server_info)->groups); 1413 SAFE_FREE((*server_info)->unix_name); 1414 data_blob_free(&(*server_info)->lm_session_key); 1415 data_blob_free(&(*server_info)->user_session_key); 1416 ZERO_STRUCT(**server_info); 1417 } 1418 SAFE_FREE(*server_info); 1419} 1420 1421/*************************************************************************** 1422 Make an auth_methods struct 1423***************************************************************************/ 1424 1425BOOL make_auth_methods(struct auth_context *auth_context, auth_methods **auth_method) 1426{ 1427 if (!auth_context) { 1428 smb_panic("no auth_context supplied to make_auth_methods()!\n"); 1429 } 1430 1431 if (!auth_method) { 1432 smb_panic("make_auth_methods: pointer to auth_method pointer is NULL!\n"); 1433 } 1434 1435 *auth_method = TALLOC_P(auth_context->mem_ctx, auth_methods); 1436 if (!*auth_method) { 1437 DEBUG(0,("make_auth_method: malloc failed!\n")); 1438 return False; 1439 } 1440 ZERO_STRUCTP(*auth_method); 1441 1442 return True; 1443} 1444 1445/**************************************************************************** 1446 Delete a SID token. 1447****************************************************************************/ 1448 1449void delete_nt_token(NT_USER_TOKEN **pptoken) 1450{ 1451 if (*pptoken) { 1452 NT_USER_TOKEN *ptoken = *pptoken; 1453 1454 SAFE_FREE( ptoken->user_sids ); 1455 ZERO_STRUCTP(ptoken); 1456 } 1457 SAFE_FREE(*pptoken); 1458} 1459 1460/**************************************************************************** 1461 Duplicate a SID token. 1462****************************************************************************/ 1463 1464NT_USER_TOKEN *dup_nt_token(NT_USER_TOKEN *ptoken) 1465{ 1466 NT_USER_TOKEN *token; 1467 1468 if (!ptoken) 1469 return NULL; 1470 1471 if ((token = SMB_MALLOC_P(NT_USER_TOKEN)) == NULL) 1472 return NULL; 1473 1474 ZERO_STRUCTP(token); 1475 1476 token->user_sids = (DOM_SID *)memdup( ptoken->user_sids, sizeof(DOM_SID) * ptoken->num_sids ); 1477 1478 if ( !token ) { 1479 SAFE_FREE(token); 1480 return NULL; 1481 } 1482 1483 token->num_sids = ptoken->num_sids; 1484 1485 /* copy the privileges; don't consider failure to be critical here */ 1486 1487 if ( !se_priv_copy( &token->privileges, &ptoken->privileges ) ) { 1488 DEBUG(0,("dup_nt_token: Failure to copy SE_PRIV!. Continuing with 0 privileges assigned.\n")); 1489 } 1490 1491 return token; 1492} 1493 1494/**************************************************************************** 1495 Check for a SID in an NT_USER_TOKEN 1496****************************************************************************/ 1497 1498BOOL nt_token_check_sid ( DOM_SID *sid, NT_USER_TOKEN *token ) 1499{ 1500 int i; 1501 1502 if ( !sid || !token ) 1503 return False; 1504 1505 for ( i=0; i<token->num_sids; i++ ) { 1506 if ( sid_equal( sid, &token->user_sids[i] ) ) 1507 return True; 1508 } 1509 1510 return False; 1511} 1512 1513BOOL nt_token_check_domain_rid( NT_USER_TOKEN *token, uint32 rid ) 1514{ 1515 DOM_SID domain_sid; 1516 1517 /* if we are a domain member, the get the domain SID, else for 1518 a DC or standalone server, use our own SID */ 1519 1520 if ( lp_server_role() == ROLE_DOMAIN_MEMBER ) { 1521 if ( !secrets_fetch_domain_sid( lp_workgroup(), &domain_sid ) ) { 1522 DEBUG(1,("nt_token_check_domain_rid: Cannot lookup SID for domain [%s]\n", 1523 lp_workgroup())); 1524 return False; 1525 } 1526 } 1527 else 1528 sid_copy( &domain_sid, get_global_sam_sid() ); 1529 1530 sid_append_rid( &domain_sid, rid ); 1531 1532 return nt_token_check_sid( &domain_sid, token );\ 1533} 1534 1535/** 1536 * Verify whether or not given domain is trusted. 1537 * 1538 * @param domain_name name of the domain to be verified 1539 * @return true if domain is one of the trusted once or 1540 * false if otherwise 1541 **/ 1542 1543BOOL is_trusted_domain(const char* dom_name) 1544{ 1545 DOM_SID trustdom_sid; 1546 char *pass = NULL; 1547 time_t lct; 1548 BOOL ret; 1549 1550 /* no trusted domains for a standalone server */ 1551 1552 if ( lp_server_role() == ROLE_STANDALONE ) 1553 return False; 1554 1555 /* if we are a DC, then check for a direct trust relationships */ 1556 1557 if ( IS_DC ) { 1558 become_root(); 1559 DEBUG (5,("is_trusted_domain: Checking for domain trust with [%s]\n", 1560 dom_name )); 1561 ret = secrets_fetch_trusted_domain_password(dom_name, &pass, &trustdom_sid, &lct); 1562 unbecome_root(); 1563 SAFE_FREE(pass); 1564 if (ret) 1565 return True; 1566 } 1567 else { 1568 /* if winbindd is not up and we are a domain member) then we need to update the 1569 trustdom_cache ourselves */ 1570 1571 if ( !winbind_ping() ) 1572 update_trustdom_cache(); 1573 } 1574 1575 /* now the trustdom cache should be available a DC could still 1576 * have a transitive trust so fall back to the cache of trusted 1577 * domains (like a domain member would use */ 1578 1579 if ( trustdom_cache_fetch(dom_name, &trustdom_sid) ) { 1580 return True; 1581 } 1582 1583 return False; 1584} 1585 1586