root/source3/auth/auth_util.c

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

DEFINITIONS

This source file includes following definitions.
  1. sort_sid_array_for_smbd
  2. _smb_create_user
  3. make_user_info
  4. make_user_info_map
  5. make_user_info_netlogon_network
  6. make_user_info_netlogon_interactive
  7. make_user_info_for_reply
  8. make_user_info_for_reply_enc
  9. make_user_info_guest
  10. server_info_dtor
  11. make_server_info
  12. sanitize_username
  13. is_our_machine_account
  14. make_server_info_sam
  15. log_nt_token
  16. create_local_token
  17. create_token_from_username
  18. user_in_group_sid
  19. user_in_group
  20. make_server_info_pw
  21. make_new_server_info_guest
  22. make_serverinfo_from_username
  23. copy_serverinfo
  24. server_info_set_session_key
  25. init_guest_info
  26. make_server_info_guest
  27. copy_current_user
  28. fill_sam_account
  29. smb_getpwnam
  30. make_server_info_info3
  31. make_server_info_wbcAuthUserInfo
  32. free_user_info
  33. make_auth_methods
  34. is_trusted_domain

   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 
  10    This program is free software; you can redistribute it and/or modify
  11    it under the terms of the GNU General Public License as published by
  12    the Free Software Foundation; either version 3 of the License, or
  13    (at your option) any later version.
  14    
  15    This program is distributed in the hope that it will be useful,
  16    but WITHOUT ANY WARRANTY; without even the implied warranty of
  17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18    GNU General Public License for more details.
  19    
  20    You should have received a copy of the GNU General Public License
  21    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  22 */
  23 
  24 #include "includes.h"
  25 
  26 #undef DBGC_CLASS
  27 #define DBGC_CLASS DBGC_AUTH
  28 
  29 /****************************************************************************
  30  Ensure primary group SID is always at position 0 in a 
  31  auth_serversupplied_info struct.
  32 ****************************************************************************/
  33 
  34 static void sort_sid_array_for_smbd(auth_serversupplied_info *result,
     /* [<][>][^][v][top][bottom][index][help] */
  35                                 const DOM_SID *pgroup_sid)
  36 {
  37         unsigned int i;
  38 
  39         if (!result->sids) {
  40                 return;
  41         }
  42 
  43         if (sid_compare(&result->sids[0], pgroup_sid)==0) {
  44                 return;
  45         }
  46 
  47         for (i = 1; i < result->num_sids; i++) {
  48                 if (sid_compare(pgroup_sid,
  49                                 &result->sids[i]) == 0) {
  50                         sid_copy(&result->sids[i], &result->sids[0]);
  51                         sid_copy(&result->sids[0], pgroup_sid);
  52                         return;
  53                 }
  54         }
  55 }
  56 
  57 /****************************************************************************
  58  Create a UNIX user on demand.
  59 ****************************************************************************/
  60 
  61 static int _smb_create_user(const char *domain, const char *unix_username, const char *homedir)
     /* [<][>][^][v][top][bottom][index][help] */
  62 {
  63         TALLOC_CTX *ctx = talloc_tos();
  64         char *add_script;
  65         int ret;
  66 
  67         add_script = talloc_strdup(ctx, lp_adduser_script());
  68         if (!add_script || !*add_script) {
  69                 return -1;
  70         }
  71         add_script = talloc_all_string_sub(ctx,
  72                                 add_script,
  73                                 "%u",
  74                                 unix_username);
  75         if (!add_script) {
  76                 return -1;
  77         }
  78         if (domain) {
  79                 add_script = talloc_all_string_sub(ctx,
  80                                         add_script,
  81                                         "%D",
  82                                         domain);
  83                 if (!add_script) {
  84                         return -1;
  85                 }
  86         }
  87         if (homedir) {
  88                 add_script = talloc_all_string_sub(ctx,
  89                                 add_script,
  90                                 "%H",
  91                                 homedir);
  92                 if (!add_script) {
  93                         return -1;
  94                 }
  95         }
  96         ret = smbrun(add_script,NULL);
  97         flush_pwnam_cache();
  98         DEBUG(ret ? 0 : 3,
  99                 ("smb_create_user: Running the command `%s' gave %d\n",
 100                  add_script,ret));
 101         return ret;
 102 }
 103 
 104 /****************************************************************************
 105  Create an auth_usersupplied_data structure
 106 ****************************************************************************/
 107 
 108 static NTSTATUS make_user_info(auth_usersupplied_info **user_info,
     /* [<][>][^][v][top][bottom][index][help] */
 109                                const char *smb_name,
 110                                const char *internal_username,
 111                                const char *client_domain,
 112                                const char *domain,
 113                                const char *wksta_name,
 114                                DATA_BLOB *lm_pwd, DATA_BLOB *nt_pwd,
 115                                DATA_BLOB *lm_interactive_pwd, DATA_BLOB *nt_interactive_pwd,
 116                                DATA_BLOB *plaintext,
 117                                bool encrypted)
 118 {
 119 
 120         DEBUG(5,("attempting to make a user_info for %s (%s)\n", internal_username, smb_name));
 121 
 122         *user_info = SMB_MALLOC_P(auth_usersupplied_info);
 123         if (*user_info == NULL) {
 124                 DEBUG(0,("malloc failed for user_info (size %lu)\n", (unsigned long)sizeof(*user_info)));
 125                 return NT_STATUS_NO_MEMORY;
 126         }
 127 
 128         ZERO_STRUCTP(*user_info);
 129 
 130         DEBUG(5,("making strings for %s's user_info struct\n", internal_username));
 131 
 132         (*user_info)->smb_name = SMB_STRDUP(smb_name);
 133         if ((*user_info)->smb_name == NULL) { 
 134                 free_user_info(user_info);
 135                 return NT_STATUS_NO_MEMORY;
 136         }
 137         
 138         (*user_info)->internal_username = SMB_STRDUP(internal_username);
 139         if ((*user_info)->internal_username == NULL) { 
 140                 free_user_info(user_info);
 141                 return NT_STATUS_NO_MEMORY;
 142         }
 143 
 144         (*user_info)->domain = SMB_STRDUP(domain);
 145         if ((*user_info)->domain == NULL) { 
 146                 free_user_info(user_info);
 147                 return NT_STATUS_NO_MEMORY;
 148         }
 149 
 150         (*user_info)->client_domain = SMB_STRDUP(client_domain);
 151         if ((*user_info)->client_domain == NULL) { 
 152                 free_user_info(user_info);
 153                 return NT_STATUS_NO_MEMORY;
 154         }
 155 
 156         (*user_info)->wksta_name = SMB_STRDUP(wksta_name);
 157         if ((*user_info)->wksta_name == NULL) { 
 158                 free_user_info(user_info);
 159                 return NT_STATUS_NO_MEMORY;
 160         }
 161 
 162         DEBUG(5,("making blobs for %s's user_info struct\n", internal_username));
 163 
 164         if (lm_pwd)
 165                 (*user_info)->lm_resp = data_blob(lm_pwd->data, lm_pwd->length);
 166         if (nt_pwd)
 167                 (*user_info)->nt_resp = data_blob(nt_pwd->data, nt_pwd->length);
 168         if (lm_interactive_pwd)
 169                 (*user_info)->lm_interactive_pwd = data_blob(lm_interactive_pwd->data, lm_interactive_pwd->length);
 170         if (nt_interactive_pwd)
 171                 (*user_info)->nt_interactive_pwd = data_blob(nt_interactive_pwd->data, nt_interactive_pwd->length);
 172 
 173         if (plaintext)
 174                 (*user_info)->plaintext_password = data_blob(plaintext->data, plaintext->length);
 175 
 176         (*user_info)->encrypted = encrypted;
 177 
 178         (*user_info)->logon_parameters = 0;
 179 
 180         DEBUG(10,("made an %sencrypted user_info for %s (%s)\n", encrypted ? "":"un" , internal_username, smb_name));
 181 
 182         return NT_STATUS_OK;
 183 }
 184 
 185 /****************************************************************************
 186  Create an auth_usersupplied_data structure after appropriate mapping.
 187 ****************************************************************************/
 188 
 189 NTSTATUS make_user_info_map(auth_usersupplied_info **user_info,
     /* [<][>][^][v][top][bottom][index][help] */
 190                             const char *smb_name,
 191                             const char *client_domain,
 192                             const char *wksta_name,
 193                             DATA_BLOB *lm_pwd,
 194                             DATA_BLOB *nt_pwd,
 195                             DATA_BLOB *lm_interactive_pwd,
 196                             DATA_BLOB *nt_interactive_pwd,
 197                             DATA_BLOB *plaintext,
 198                             bool encrypted)
 199 {
 200         const char *domain;
 201         NTSTATUS result;
 202         bool was_mapped;
 203         fstring internal_username;
 204         fstrcpy(internal_username, smb_name);
 205         was_mapped = map_username(internal_username);
 206 
 207         DEBUG(5, ("Mapping user [%s]\\[%s] from workstation [%s]\n",
 208                  client_domain, smb_name, wksta_name));
 209 
 210         domain = client_domain;
 211 
 212         /* If you connect to a Windows domain member using a bogus domain name,
 213          * the Windows box will map the BOGUS\user to SAMNAME\user.  Thus, if
 214          * the Windows box is a DC the name will become DOMAIN\user and be
 215          * authenticated against AD, if the Windows box is a member server but
 216          * not a DC the name will become WORKSTATION\user.  A standalone
 217          * non-domain member box will also map to WORKSTATION\user.
 218          * This also deals with the client passing in a "" domain */
 219 
 220         if (!is_trusted_domain(domain) &&
 221             !strequal(domain, my_sam_name()))
 222         {
 223                 if (lp_map_untrusted_to_domain())
 224                         domain = my_sam_name();
 225                 else
 226                         domain = get_global_sam_name();
 227                 DEBUG(5, ("Mapped domain from [%s] to [%s] for user [%s] from "
 228                           "workstation [%s]\n",
 229                           client_domain, domain, smb_name, wksta_name));
 230         }
 231 
 232         /* We know that the given domain is trusted (and we are allowing them),
 233          * it is our global SAM name, or for legacy behavior it is our
 234          * primary domain name */
 235 
 236         result = make_user_info(user_info, smb_name, internal_username,
 237                               client_domain, domain, wksta_name,
 238                               lm_pwd, nt_pwd,
 239                               lm_interactive_pwd, nt_interactive_pwd,
 240                               plaintext, encrypted);
 241         if (NT_STATUS_IS_OK(result)) {
 242                 (*user_info)->was_mapped = was_mapped;
 243         }
 244         return result;
 245 }
 246 
 247 /****************************************************************************
 248  Create an auth_usersupplied_data, making the DATA_BLOBs here. 
 249  Decrypt and encrypt the passwords.
 250 ****************************************************************************/
 251 
 252 bool make_user_info_netlogon_network(auth_usersupplied_info **user_info, 
     /* [<][>][^][v][top][bottom][index][help] */
 253                                      const char *smb_name, 
 254                                      const char *client_domain, 
 255                                      const char *wksta_name, 
 256                                      uint32 logon_parameters,
 257                                      const uchar *lm_network_pwd,
 258                                      int lm_pwd_len,
 259                                      const uchar *nt_network_pwd,
 260                                      int nt_pwd_len)
 261 {
 262         bool ret;
 263         NTSTATUS 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         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         if (NT_STATUS_IS_OK(status)) {
 276                 (*user_info)->logon_parameters = logon_parameters;
 277         }
 278         ret = NT_STATUS_IS_OK(status) ? True : False;
 279 
 280         data_blob_free(&lm_blob);
 281         data_blob_free(&nt_blob);
 282         return ret;
 283 }
 284 
 285 /****************************************************************************
 286  Create an auth_usersupplied_data, making the DATA_BLOBs here. 
 287  Decrypt and encrypt the passwords.
 288 ****************************************************************************/
 289 
 290 bool make_user_info_netlogon_interactive(auth_usersupplied_info **user_info, 
     /* [<][>][^][v][top][bottom][index][help] */
 291                                          const char *smb_name, 
 292                                          const char *client_domain, 
 293                                          const char *wksta_name, 
 294                                          uint32 logon_parameters,
 295                                          const uchar chal[8], 
 296                                          const uchar lm_interactive_pwd[16], 
 297                                          const uchar nt_interactive_pwd[16], 
 298                                          const uchar *dc_sess_key)
 299 {
 300         unsigned char lm_pwd[16];
 301         unsigned char nt_pwd[16];
 302         unsigned char local_lm_response[24];
 303         unsigned char local_nt_response[24];
 304         unsigned char key[16];
 305         
 306         memcpy(key, dc_sess_key, 16);
 307         
 308         if (lm_interactive_pwd)
 309                 memcpy(lm_pwd, lm_interactive_pwd, sizeof(lm_pwd));
 310 
 311         if (nt_interactive_pwd)
 312                 memcpy(nt_pwd, nt_interactive_pwd, sizeof(nt_pwd));
 313         
 314 #ifdef DEBUG_PASSWORD
 315         DEBUG(100,("key:"));
 316         dump_data(100, key, sizeof(key));
 317         
 318         DEBUG(100,("lm owf password:"));
 319         dump_data(100, lm_pwd, sizeof(lm_pwd));
 320         
 321         DEBUG(100,("nt owf password:"));
 322         dump_data(100, nt_pwd, sizeof(nt_pwd));
 323 #endif
 324         
 325         if (lm_interactive_pwd)
 326                 SamOEMhash(lm_pwd, key, sizeof(lm_pwd));
 327         
 328         if (nt_interactive_pwd)
 329                 SamOEMhash(nt_pwd, key, sizeof(nt_pwd));
 330         
 331 #ifdef DEBUG_PASSWORD
 332         DEBUG(100,("decrypt of lm owf password:"));
 333         dump_data(100, lm_pwd, sizeof(lm_pwd));
 334         
 335         DEBUG(100,("decrypt of nt owf password:"));
 336         dump_data(100, nt_pwd, sizeof(nt_pwd));
 337 #endif
 338         
 339         if (lm_interactive_pwd)
 340                 SMBOWFencrypt(lm_pwd, chal,
 341                               local_lm_response);
 342 
 343         if (nt_interactive_pwd)
 344                 SMBOWFencrypt(nt_pwd, chal,
 345                               local_nt_response);
 346         
 347         /* Password info paranoia */
 348         ZERO_STRUCT(key);
 349 
 350         {
 351                 bool ret;
 352                 NTSTATUS nt_status;
 353                 DATA_BLOB local_lm_blob;
 354                 DATA_BLOB local_nt_blob;
 355 
 356                 DATA_BLOB lm_interactive_blob;
 357                 DATA_BLOB nt_interactive_blob;
 358                 
 359                 if (lm_interactive_pwd) {
 360                         local_lm_blob = data_blob(local_lm_response,
 361                                                   sizeof(local_lm_response));
 362                         lm_interactive_blob = data_blob(lm_pwd,
 363                                                         sizeof(lm_pwd));
 364                         ZERO_STRUCT(lm_pwd);
 365                 }
 366                 
 367                 if (nt_interactive_pwd) {
 368                         local_nt_blob = data_blob(local_nt_response,
 369                                                   sizeof(local_nt_response));
 370                         nt_interactive_blob = data_blob(nt_pwd,
 371                                                         sizeof(nt_pwd));
 372                         ZERO_STRUCT(nt_pwd);
 373                 }
 374 
 375                 nt_status = make_user_info_map(
 376                         user_info, 
 377                         smb_name, client_domain, wksta_name, 
 378                         lm_interactive_pwd ? &local_lm_blob : NULL,
 379                         nt_interactive_pwd ? &local_nt_blob : NULL,
 380                         lm_interactive_pwd ? &lm_interactive_blob : NULL,
 381                         nt_interactive_pwd ? &nt_interactive_blob : NULL,
 382                         NULL, True);
 383 
 384                 if (NT_STATUS_IS_OK(nt_status)) {
 385                         (*user_info)->logon_parameters = logon_parameters;
 386                 }
 387 
 388                 ret = NT_STATUS_IS_OK(nt_status) ? True : False;
 389                 data_blob_free(&local_lm_blob);
 390                 data_blob_free(&local_nt_blob);
 391                 data_blob_free(&lm_interactive_blob);
 392                 data_blob_free(&nt_interactive_blob);
 393                 return ret;
 394         }
 395 }
 396 
 397 
 398 /****************************************************************************
 399  Create an auth_usersupplied_data structure
 400 ****************************************************************************/
 401 
 402 bool make_user_info_for_reply(auth_usersupplied_info **user_info, 
     /* [<][>][^][v][top][bottom][index][help] */
 403                               const char *smb_name, 
 404                               const char *client_domain,
 405                               const uint8 chal[8],
 406                               DATA_BLOB plaintext_password)
 407 {
 408 
 409         DATA_BLOB local_lm_blob;
 410         DATA_BLOB local_nt_blob;
 411         NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
 412                         
 413         /*
 414          * Not encrypted - do so.
 415          */
 416         
 417         DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted "
 418                  "format.\n"));
 419         
 420         if (plaintext_password.data) {
 421                 unsigned char local_lm_response[24];
 422                 
 423 #ifdef DEBUG_PASSWORD
 424                 DEBUG(10,("Unencrypted password (len %d):\n",
 425                           (int)plaintext_password.length));
 426                 dump_data(100, plaintext_password.data,
 427                           plaintext_password.length);
 428 #endif
 429 
 430                 SMBencrypt( (const char *)plaintext_password.data,
 431                             (const uchar*)chal, local_lm_response);
 432                 local_lm_blob = data_blob(local_lm_response, 24);
 433                 
 434                 /* We can't do an NT hash here, as the password needs to be
 435                    case insensitive */
 436                 local_nt_blob = data_blob_null; 
 437                 
 438         } else {
 439                 local_lm_blob = data_blob_null; 
 440                 local_nt_blob = data_blob_null; 
 441         }
 442         
 443         ret = make_user_info_map(
 444                 user_info, smb_name, client_domain, 
 445                 get_remote_machine_name(),
 446                 local_lm_blob.data ? &local_lm_blob : NULL,
 447                 local_nt_blob.data ? &local_nt_blob : NULL,
 448                 NULL, NULL,
 449                 plaintext_password.data ? &plaintext_password : NULL, 
 450                 False);
 451         
 452         data_blob_free(&local_lm_blob);
 453         return NT_STATUS_IS_OK(ret) ? True : False;
 454 }
 455 
 456 /****************************************************************************
 457  Create an auth_usersupplied_data structure
 458 ****************************************************************************/
 459 
 460 NTSTATUS make_user_info_for_reply_enc(auth_usersupplied_info **user_info, 
     /* [<][>][^][v][top][bottom][index][help] */
 461                                       const char *smb_name,
 462                                       const char *client_domain, 
 463                                       DATA_BLOB lm_resp, DATA_BLOB nt_resp)
 464 {
 465         return make_user_info_map(user_info, smb_name, 
 466                                   client_domain, 
 467                                   get_remote_machine_name(), 
 468                                   lm_resp.data ? &lm_resp : NULL, 
 469                                   nt_resp.data ? &nt_resp : NULL, 
 470                                   NULL, NULL, NULL,
 471                                   True);
 472 }
 473 
 474 /****************************************************************************
 475  Create a guest user_info blob, for anonymous authenticaion.
 476 ****************************************************************************/
 477 
 478 bool make_user_info_guest(auth_usersupplied_info **user_info) 
     /* [<][>][^][v][top][bottom][index][help] */
 479 {
 480         NTSTATUS nt_status;
 481 
 482         nt_status = make_user_info(user_info, 
 483                                    "","", 
 484                                    "","", 
 485                                    "", 
 486                                    NULL, NULL, 
 487                                    NULL, NULL, 
 488                                    NULL,
 489                                    True);
 490                               
 491         return NT_STATUS_IS_OK(nt_status) ? True : False;
 492 }
 493 
 494 static int server_info_dtor(auth_serversupplied_info *server_info)
     /* [<][>][^][v][top][bottom][index][help] */
 495 {
 496         TALLOC_FREE(server_info->sam_account);
 497         ZERO_STRUCTP(server_info);
 498         return 0;
 499 }
 500 
 501 /***************************************************************************
 502  Make a server_info struct. Free with TALLOC_FREE().
 503 ***************************************************************************/
 504 
 505 static auth_serversupplied_info *make_server_info(TALLOC_CTX *mem_ctx)
     /* [<][>][^][v][top][bottom][index][help] */
 506 {
 507         struct auth_serversupplied_info *result;
 508 
 509         result = TALLOC_ZERO_P(mem_ctx, auth_serversupplied_info);
 510         if (result == NULL) {
 511                 DEBUG(0, ("talloc failed\n"));
 512                 return NULL;
 513         }
 514 
 515         talloc_set_destructor(result, server_info_dtor);
 516 
 517         /* Initialise the uid and gid values to something non-zero
 518            which may save us from giving away root access if there
 519            is a bug in allocating these fields. */
 520 
 521         result->utok.uid = -1;
 522         result->utok.gid = -1;
 523         return result;
 524 }
 525 
 526 static char *sanitize_username(TALLOC_CTX *mem_ctx, const char *username)
     /* [<][>][^][v][top][bottom][index][help] */
 527 {
 528         fstring tmp;
 529 
 530         alpha_strcpy(tmp, username, ". _-$", sizeof(tmp));
 531         return talloc_strdup(mem_ctx, tmp);
 532 }
 533 
 534 /***************************************************************************
 535  Is the incoming username our own machine account ?
 536  If so, the connection is almost certainly from winbindd.
 537 ***************************************************************************/
 538 
 539 static bool is_our_machine_account(const char *username)
     /* [<][>][^][v][top][bottom][index][help] */
 540 {
 541         bool ret;
 542         char *truncname = NULL;
 543         size_t ulen = strlen(username);
 544 
 545         if (ulen == 0 || username[ulen-1] != '$') {
 546                 return false;
 547         }
 548         truncname = SMB_STRDUP(username);
 549         if (!truncname) {
 550                 return false;
 551         }
 552         truncname[ulen-1] = '\0';
 553         ret = strequal(truncname, global_myname());
 554         SAFE_FREE(truncname);
 555         return ret;
 556 }
 557 
 558 /***************************************************************************
 559  Make (and fill) a user_info struct from a struct samu
 560 ***************************************************************************/
 561 
 562 NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info,
     /* [<][>][^][v][top][bottom][index][help] */
 563                               struct samu *sampass)
 564 {
 565         struct passwd *pwd;
 566         gid_t *gids;
 567         auth_serversupplied_info *result;
 568         const char *username = pdb_get_username(sampass);
 569         NTSTATUS status;
 570 
 571         if ( !(result = make_server_info(NULL)) ) {
 572                 return NT_STATUS_NO_MEMORY;
 573         }
 574 
 575         if ( !(pwd = getpwnam_alloc(result, username)) ) {
 576                 DEBUG(1, ("User %s in passdb, but getpwnam() fails!\n",
 577                           pdb_get_username(sampass)));
 578                 TALLOC_FREE(result);
 579                 return NT_STATUS_NO_SUCH_USER;
 580         }
 581 
 582         result->sam_account = sampass;
 583         result->unix_name = pwd->pw_name;
 584         /* Ensure that we keep pwd->pw_name, because we will free pwd below */
 585         talloc_steal(result, pwd->pw_name);
 586         result->utok.gid = pwd->pw_gid;
 587         result->utok.uid = pwd->pw_uid;
 588 
 589         TALLOC_FREE(pwd);
 590 
 591         result->sanitized_username = sanitize_username(result,
 592                                                        result->unix_name);
 593         if (result->sanitized_username == NULL) {
 594                 TALLOC_FREE(result);
 595                 return NT_STATUS_NO_MEMORY;
 596         }
 597 
 598         if (IS_DC && is_our_machine_account(username)) {
 599                 /*
 600                  * Ensure for a connection from our own
 601                  * machine account (from winbindd on a DC)
 602                  * there are no supplementary groups.
 603                  * Prevents loops in calling gid_to_sid().
 604                  */
 605                 result->sids = NULL;
 606                 gids = NULL;
 607                 result->num_sids = 0;
 608 
 609                 /*
 610                  * This is a hack of monstrous proportions.
 611                  * If we know it's winbindd talking to us,
 612                  * we know we must never recurse into it,
 613                  * so turn off contacting winbindd for this
 614                  * entire process. This will get fixed when
 615                  * winbindd doesn't need to talk to smbd on
 616                  * a PDC. JRA.
 617                  */
 618 
 619                 (void)winbind_off();
 620 
 621                 DEBUG(10, ("make_server_info_sam: our machine account %s "
 622                         "setting supplementary group list empty and "
 623                         "turning off winbindd requests.\n",
 624                         username));
 625         } else {
 626                 status = pdb_enum_group_memberships(result, sampass,
 627                                             &result->sids, &gids,
 628                                             &result->num_sids);
 629 
 630                 if (!NT_STATUS_IS_OK(status)) {
 631                         DEBUG(10, ("pdb_enum_group_memberships failed: %s\n",
 632                                    nt_errstr(status)));
 633                         result->sam_account = NULL; /* Don't free on error exit. */
 634                         TALLOC_FREE(result);
 635                         return status;
 636                 }
 637         }
 638 
 639         /* For now we throw away the gids and convert via sid_to_gid
 640          * later. This needs fixing, but I'd like to get the code straight and
 641          * simple first. */
 642          
 643         TALLOC_FREE(gids);
 644 
 645         DEBUG(5,("make_server_info_sam: made server info for user %s -> %s\n",
 646                  pdb_get_username(sampass), result->unix_name));
 647 
 648         *server_info = result;
 649         /* Ensure that the sampass will be freed with the result */
 650         talloc_steal(result, sampass);
 651 
 652         return NT_STATUS_OK;
 653 }
 654 
 655 static NTSTATUS log_nt_token(NT_USER_TOKEN *token)
     /* [<][>][^][v][top][bottom][index][help] */
 656 {
 657         TALLOC_CTX *frame = talloc_stackframe();
 658         char *command;
 659         char *group_sidstr;
 660         size_t i;
 661 
 662         if ((lp_log_nt_token_command() == NULL) ||
 663             (strlen(lp_log_nt_token_command()) == 0)) {
 664                 TALLOC_FREE(frame);
 665                 return NT_STATUS_OK;
 666         }
 667 
 668         group_sidstr = talloc_strdup(frame, "");
 669         for (i=1; i<token->num_sids; i++) {
 670                 group_sidstr = talloc_asprintf(
 671                         frame, "%s %s", group_sidstr,
 672                         sid_string_talloc(frame, &token->user_sids[i]));
 673         }
 674 
 675         command = talloc_string_sub(
 676                 frame, lp_log_nt_token_command(),
 677                 "%s", sid_string_talloc(frame, &token->user_sids[0]));
 678         command = talloc_string_sub(frame, command, "%t", group_sidstr);
 679 
 680         if (command == NULL) {
 681                 TALLOC_FREE(frame);
 682                 return NT_STATUS_NO_MEMORY;
 683         }
 684 
 685         DEBUG(8, ("running command: [%s]\n", command));
 686         if (smbrun(command, NULL) != 0) {
 687                 DEBUG(0, ("Could not log NT token\n"));
 688                 TALLOC_FREE(frame);
 689                 return NT_STATUS_ACCESS_DENIED;
 690         }
 691 
 692         TALLOC_FREE(frame);
 693         return NT_STATUS_OK;
 694 }
 695 
 696 /*
 697  * Create the token to use from server_info->sam_account and
 698  * server_info->sids (the info3/sam groups). Find the unix gids.
 699  */
 700 
 701 NTSTATUS create_local_token(auth_serversupplied_info *server_info)
     /* [<][>][^][v][top][bottom][index][help] */
 702 {
 703         NTSTATUS status;
 704         size_t i;
 705         struct dom_sid tmp_sid;
 706 
 707         /*
 708          * If winbind is not around, we can not make much use of the SIDs the
 709          * domain controller provided us with. Likewise if the user name was
 710          * mapped to some local unix user.
 711          */
 712 
 713         if (((lp_server_role() == ROLE_DOMAIN_MEMBER) && !winbind_ping()) ||
 714             (server_info->nss_token)) {
 715                 status = create_token_from_username(server_info,
 716                                                     server_info->unix_name,
 717                                                     server_info->guest,
 718                                                     &server_info->utok.uid,
 719                                                     &server_info->utok.gid,
 720                                                     &server_info->unix_name,
 721                                                     &server_info->ptok);
 722 
 723         } else {
 724                 server_info->ptok = create_local_nt_token(
 725                         server_info,
 726                         pdb_get_user_sid(server_info->sam_account),
 727                         server_info->guest,
 728                         server_info->num_sids, server_info->sids);
 729                 status = server_info->ptok ?
 730                         NT_STATUS_OK : NT_STATUS_NO_SUCH_USER;
 731         }
 732 
 733         if (!NT_STATUS_IS_OK(status)) {
 734                 return status;
 735         }
 736 
 737         /* Convert the SIDs to gids. */
 738 
 739         server_info->utok.ngroups = 0;
 740         server_info->utok.groups = NULL;
 741 
 742         /* Start at index 1, where the groups start. */
 743 
 744         for (i=1; i<server_info->ptok->num_sids; i++) {
 745                 gid_t gid;
 746                 DOM_SID *sid = &server_info->ptok->user_sids[i];
 747 
 748                 if (!sid_to_gid(sid, &gid)) {
 749                         DEBUG(10, ("Could not convert SID %s to gid, "
 750                                    "ignoring it\n", sid_string_dbg(sid)));
 751                         continue;
 752                 }
 753                 add_gid_to_array_unique(server_info, gid,
 754                                         &server_info->utok.groups,
 755                                         &server_info->utok.ngroups);
 756         }
 757 
 758         /*
 759          * Add the "Unix Group" SID for each gid to catch mapped groups
 760          * and their Unix equivalent.  This is to solve the backwards
 761          * compatibility problem of 'valid users = +ntadmin' where
 762          * ntadmin has been paired with "Domain Admins" in the group
 763          * mapping table.  Otherwise smb.conf would need to be changed
 764          * to 'valid user = "Domain Admins"'.  --jerry
 765          *
 766          * For consistency we also add the "Unix User" SID,
 767          * so that the complete unix token is represented within
 768          * the nt token.
 769          */
 770 
 771         if (!uid_to_unix_users_sid(server_info->utok.uid, &tmp_sid)) {
 772                 DEBUG(1,("create_local_token: Failed to create SID "
 773                         "for uid %u!\n", (unsigned int)server_info->utok.uid));
 774         }
 775         add_sid_to_array_unique(server_info->ptok, &tmp_sid,
 776                                 &server_info->ptok->user_sids,
 777                                 &server_info->ptok->num_sids);
 778 
 779         for ( i=0; i<server_info->utok.ngroups; i++ ) {
 780                 if (!gid_to_unix_groups_sid( server_info->utok.groups[i], &tmp_sid ) ) {
 781                         DEBUG(1,("create_local_token: Failed to create SID "
 782                                 "for gid %u!\n", (unsigned int)server_info->utok.groups[i]));
 783                         continue;
 784                 }
 785                 add_sid_to_array_unique(server_info->ptok, &tmp_sid,
 786                                         &server_info->ptok->user_sids,
 787                                         &server_info->ptok->num_sids);
 788         }
 789 
 790         debug_nt_user_token(DBGC_AUTH, 10, server_info->ptok);
 791         debug_unix_user_token(DBGC_AUTH, 10,
 792                               server_info->utok.uid,
 793                               server_info->utok.gid,
 794                               server_info->utok.ngroups,
 795                               server_info->utok.groups);
 796 
 797         status = log_nt_token(server_info->ptok);
 798         return status;
 799 }
 800 
 801 /*
 802  * Create an artificial NT token given just a username. (Initially intended
 803  * for force user)
 804  *
 805  * We go through lookup_name() to avoid problems we had with 'winbind use
 806  * default domain'.
 807  *
 808  * We have 3 cases:
 809  *
 810  * unmapped unix users: Go directly to nss to find the user's group.
 811  *
 812  * A passdb user: The list of groups is provided by pdb_enum_group_memberships.
 813  *
 814  * If the user is provided by winbind, the primary gid is set to "domain
 815  * users" of the user's domain. For an explanation why this is necessary, see
 816  * the thread starting at
 817  * http://lists.samba.org/archive/samba-technical/2006-January/044803.html.
 818  */
 819 
 820 NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username,
     /* [<][>][^][v][top][bottom][index][help] */
 821                                     bool is_guest,
 822                                     uid_t *uid, gid_t *gid,
 823                                     char **found_username,
 824                                     struct nt_user_token **token)
 825 {
 826         NTSTATUS result = NT_STATUS_NO_SUCH_USER;
 827         TALLOC_CTX *tmp_ctx;
 828         DOM_SID user_sid;
 829         enum lsa_SidType type;
 830         gid_t *gids;
 831         DOM_SID *group_sids;
 832         DOM_SID unix_group_sid;
 833         size_t num_group_sids;
 834         size_t num_gids;
 835         size_t i;
 836 
 837         tmp_ctx = talloc_new(NULL);
 838         if (tmp_ctx == NULL) {
 839                 DEBUG(0, ("talloc_new failed\n"));
 840                 return NT_STATUS_NO_MEMORY;
 841         }
 842 
 843         if (!lookup_name_smbconf(tmp_ctx, username, LOOKUP_NAME_ALL,
 844                          NULL, NULL, &user_sid, &type)) {
 845                 DEBUG(1, ("lookup_name_smbconf for %s failed\n", username));
 846                 goto done;
 847         }
 848 
 849         if (type != SID_NAME_USER) {
 850                 DEBUG(1, ("%s is a %s, not a user\n", username,
 851                           sid_type_lookup(type)));
 852                 goto done;
 853         }
 854 
 855         if (sid_check_is_in_our_domain(&user_sid)) {
 856                 bool ret;
 857 
 858                 /* This is a passdb user, so ask passdb */
 859 
 860                 struct samu *sam_acct = NULL;
 861 
 862                 if ( !(sam_acct = samu_new( tmp_ctx )) ) {
 863                         result = NT_STATUS_NO_MEMORY;
 864                         goto done;
 865                 }
 866 
 867                 become_root();
 868                 ret = pdb_getsampwsid(sam_acct, &user_sid);
 869                 unbecome_root();
 870 
 871                 if (!ret) {
 872                         DEBUG(1, ("pdb_getsampwsid(%s) for user %s failed\n",
 873                                   sid_string_dbg(&user_sid), username));
 874                         DEBUGADD(1, ("Fall back to unix user %s\n", username));
 875                         goto unix_user;
 876                 }
 877 
 878                 result = pdb_enum_group_memberships(tmp_ctx, sam_acct,
 879                                                     &group_sids, &gids,
 880                                                     &num_group_sids);
 881                 if (!NT_STATUS_IS_OK(result)) {
 882                         DEBUG(10, ("enum_group_memberships failed for %s\n",
 883                                    username));
 884                         DEBUGADD(1, ("Fall back to unix user %s\n", username));
 885                         goto unix_user;
 886                 }
 887 
 888                 /* see the smb_panic() in pdb_default_enum_group_memberships */
 889                 SMB_ASSERT(num_group_sids > 0); 
 890 
 891                 *gid = gids[0];
 892 
 893                 /* Ensure we're returning the found_username on the right context. */
 894                 *found_username = talloc_strdup(mem_ctx,
 895                                                 pdb_get_username(sam_acct));
 896 
 897                 /*
 898                  * If the SID from lookup_name() was the guest sid, passdb knows
 899                  * about the mapping of guest sid to lp_guestaccount()
 900                  * username and will return the unix_pw info for a guest
 901                  * user. Use it if it's there, else lookup the *uid details
 902                  * using getpwnam_alloc(). See bug #6291 for details. JRA.
 903                  */
 904 
 905                 /* We must always assign the *uid. */
 906                 if (sam_acct->unix_pw == NULL) {
 907                         struct passwd *pwd = getpwnam_alloc(sam_acct, *found_username );
 908                         if (!pwd) {
 909                                 DEBUG(10, ("getpwnam_alloc failed for %s\n",
 910                                         *found_username));
 911                                 result = NT_STATUS_NO_SUCH_USER;
 912                                 goto done;
 913                         }
 914                         result = samu_set_unix(sam_acct, pwd );
 915                         if (!NT_STATUS_IS_OK(result)) {
 916                                 DEBUG(10, ("samu_set_unix failed for %s\n",
 917                                         *found_username));
 918                                 result = NT_STATUS_NO_SUCH_USER;
 919                                 goto done;
 920                         }
 921                 }
 922                 *uid = sam_acct->unix_pw->pw_uid;
 923 
 924         } else  if (sid_check_is_in_unix_users(&user_sid)) {
 925 
 926                 /* This is a unix user not in passdb. We need to ask nss
 927                  * directly, without consulting passdb */
 928 
 929                 struct passwd *pass;
 930 
 931                 /*
 932                  * This goto target is used as a fallback for the passdb
 933                  * case. The concrete bug report is when passdb gave us an
 934                  * unmapped gid.
 935                  */
 936 
 937         unix_user:
 938 
 939                 if (!sid_to_uid(&user_sid, uid)) {
 940                         DEBUG(1, ("unix_user case, sid_to_uid for %s (%s) failed\n",
 941                                   username, sid_string_dbg(&user_sid)));
 942                         result = NT_STATUS_NO_SUCH_USER;
 943                         goto done;
 944                 }
 945 
 946                 uid_to_unix_users_sid(*uid, &user_sid);
 947 
 948                 pass = getpwuid_alloc(tmp_ctx, *uid);
 949                 if (pass == NULL) {
 950                         DEBUG(1, ("getpwuid(%u) for user %s failed\n",
 951                                   (unsigned int)*uid, username));
 952                         goto done;
 953                 }
 954 
 955                 if (!getgroups_unix_user(tmp_ctx, username, pass->pw_gid,
 956                                          &gids, &num_group_sids)) {
 957                         DEBUG(1, ("getgroups_unix_user for user %s failed\n",
 958                                   username));
 959                         goto done;
 960                 }
 961 
 962                 if (num_group_sids) {
 963                         group_sids = TALLOC_ARRAY(tmp_ctx, DOM_SID, num_group_sids);
 964                         if (group_sids == NULL) {
 965                                 DEBUG(1, ("TALLOC_ARRAY failed\n"));
 966                                 result = NT_STATUS_NO_MEMORY;
 967                                 goto done;
 968                         }
 969                 } else {
 970                         group_sids = NULL;
 971                 }
 972 
 973                 for (i=0; i<num_group_sids; i++) {
 974                         gid_to_sid(&group_sids[i], gids[i]);
 975                 }
 976 
 977                 /* In getgroups_unix_user we always set the primary gid */
 978                 SMB_ASSERT(num_group_sids > 0); 
 979 
 980                 *gid = gids[0];
 981 
 982                 /* Ensure we're returning the found_username on the right context. */
 983                 *found_username = talloc_strdup(mem_ctx, pass->pw_name);
 984         } else {
 985 
 986                 /* This user is from winbind, force the primary gid to the
 987                  * user's "domain users" group. Under certain circumstances
 988                  * (user comes from NT4), this might be a loss of
 989                  * information. But we can not rely on winbind getting the
 990                  * correct info. AD might prohibit winbind looking up that
 991                  * information. */
 992 
 993                 uint32 dummy;
 994 
 995                 /* We must always assign the *uid. */
 996                 if (!sid_to_uid(&user_sid, uid)) {
 997                         DEBUG(1, ("winbindd case, sid_to_uid for %s (%s) failed\n",
 998                                   username, sid_string_dbg(&user_sid)));
 999                         result = NT_STATUS_NO_SUCH_USER;
1000                         goto done;
1001                 }
1002 
1003                 num_group_sids = 1;
1004                 group_sids = TALLOC_ARRAY(tmp_ctx, DOM_SID, num_group_sids);
1005                 if (group_sids == NULL) {
1006                         DEBUG(1, ("TALLOC_ARRAY failed\n"));
1007                         result = NT_STATUS_NO_MEMORY;
1008                         goto done;
1009                 }
1010 
1011                 sid_copy(&group_sids[0], &user_sid);
1012                 sid_split_rid(&group_sids[0], &dummy);
1013                 sid_append_rid(&group_sids[0], DOMAIN_GROUP_RID_USERS);
1014 
1015                 if (!sid_to_gid(&group_sids[0], gid)) {
1016                         DEBUG(1, ("sid_to_gid(%s) failed\n",
1017                                   sid_string_dbg(&group_sids[0])));
1018                         goto done;
1019                 }
1020 
1021                 gids = gid;
1022 
1023                 /* Ensure we're returning the found_username on the right context. */
1024                 *found_username = talloc_strdup(mem_ctx, username);
1025         }
1026 
1027         /* Add the "Unix Group" SID for each gid to catch mapped groups
1028            and their Unix equivalent.  This is to solve the backwards
1029            compatibility problem of 'valid users = +ntadmin' where
1030            ntadmin has been paired with "Domain Admins" in the group
1031            mapping table.  Otherwise smb.conf would need to be changed
1032            to 'valid user = "Domain Admins"'.  --jerry */
1033 
1034         num_gids = num_group_sids;
1035         for ( i=0; i<num_gids; i++ ) {
1036                 gid_t high, low;
1037 
1038                 /* don't pickup anything managed by Winbind */
1039 
1040                 if ( lp_idmap_gid(&low, &high) && (gids[i] >= low) && (gids[i] <= high) )
1041                         continue;
1042 
1043                 if ( !gid_to_unix_groups_sid( gids[i], &unix_group_sid ) ) {
1044                         DEBUG(1,("create_token_from_username: Failed to create SID "
1045                                 "for gid %u!\n", (unsigned int)gids[i]));
1046                         continue;
1047                 }
1048                 result = add_sid_to_array_unique(tmp_ctx, &unix_group_sid,
1049                                                  &group_sids, &num_group_sids);
1050                 if (!NT_STATUS_IS_OK(result)) {
1051                         goto done;
1052                 }
1053         }
1054 
1055         /* Ensure we're creating the nt_token on the right context. */
1056         *token = create_local_nt_token(mem_ctx, &user_sid,
1057                                        is_guest, num_group_sids, group_sids);
1058 
1059         if ((*token == NULL) || (*found_username == NULL)) {
1060                 result = NT_STATUS_NO_MEMORY;
1061                 goto done;
1062         }
1063 
1064         result = NT_STATUS_OK;
1065  done:
1066         TALLOC_FREE(tmp_ctx);
1067         return result;
1068 }
1069 
1070 /***************************************************************************
1071  Build upon create_token_from_username:
1072 
1073  Expensive helper function to figure out whether a user given its name is
1074  member of a particular group.
1075 ***************************************************************************/
1076 
1077 bool user_in_group_sid(const char *username, const DOM_SID *group_sid)
     /* [<][>][^][v][top][bottom][index][help] */
1078 {
1079         NTSTATUS status;
1080         uid_t uid;
1081         gid_t gid;
1082         char *found_username;
1083         struct nt_user_token *token;
1084         bool result;
1085 
1086         TALLOC_CTX *mem_ctx;
1087 
1088         mem_ctx = talloc_new(NULL);
1089         if (mem_ctx == NULL) {
1090                 DEBUG(0, ("talloc_new failed\n"));
1091                 return False;
1092         }
1093 
1094         status = create_token_from_username(mem_ctx, username, False,
1095                                             &uid, &gid, &found_username,
1096                                             &token);
1097 
1098         if (!NT_STATUS_IS_OK(status)) {
1099                 DEBUG(10, ("could not create token for %s\n", username));
1100                 return False;
1101         }
1102 
1103         result = nt_token_check_sid(group_sid, token);
1104 
1105         TALLOC_FREE(mem_ctx);
1106         return result;
1107         
1108 }
1109 
1110 bool user_in_group(const char *username, const char *groupname)
     /* [<][>][^][v][top][bottom][index][help] */
1111 {
1112         TALLOC_CTX *mem_ctx;
1113         DOM_SID group_sid;
1114         bool ret;
1115 
1116         mem_ctx = talloc_new(NULL);
1117         if (mem_ctx == NULL) {
1118                 DEBUG(0, ("talloc_new failed\n"));
1119                 return False;
1120         }
1121 
1122         ret = lookup_name(mem_ctx, groupname, LOOKUP_NAME_ALL,
1123                           NULL, NULL, &group_sid, NULL);
1124         TALLOC_FREE(mem_ctx);
1125 
1126         if (!ret) {
1127                 DEBUG(10, ("lookup_name for (%s) failed.\n", groupname));
1128                 return False;
1129         }
1130 
1131         return user_in_group_sid(username, &group_sid);
1132 }
1133 
1134 /***************************************************************************
1135  Make (and fill) a server_info struct from a 'struct passwd' by conversion
1136  to a struct samu
1137 ***************************************************************************/
1138 
1139 NTSTATUS make_server_info_pw(auth_serversupplied_info **server_info, 
     /* [<][>][^][v][top][bottom][index][help] */
1140                              char *unix_username,
1141                              struct passwd *pwd)
1142 {
1143         NTSTATUS status;
1144         struct samu *sampass = NULL;
1145         gid_t *gids;
1146         char *qualified_name = NULL;
1147         TALLOC_CTX *mem_ctx = NULL;
1148         DOM_SID u_sid;
1149         enum lsa_SidType type;
1150         auth_serversupplied_info *result;
1151         
1152         if ( !(sampass = samu_new( NULL )) ) {
1153                 return NT_STATUS_NO_MEMORY;
1154         }
1155         
1156         status = samu_set_unix( sampass, pwd );
1157         if (!NT_STATUS_IS_OK(status)) {
1158                 return status;
1159         }
1160 
1161         result = make_server_info(NULL);
1162         if (result == NULL) {
1163                 TALLOC_FREE(sampass);
1164                 return NT_STATUS_NO_MEMORY;
1165         }
1166 
1167         result->sam_account = sampass;
1168 
1169         result->unix_name = talloc_strdup(result, unix_username);
1170         result->sanitized_username = sanitize_username(result, unix_username);
1171 
1172         if ((result->unix_name == NULL)
1173             || (result->sanitized_username == NULL)) {
1174                 TALLOC_FREE(sampass);
1175                 TALLOC_FREE(result);
1176                 return NT_STATUS_NO_MEMORY;
1177         }
1178 
1179         result->utok.uid = pwd->pw_uid;
1180         result->utok.gid = pwd->pw_gid;
1181 
1182         status = pdb_enum_group_memberships(result, sampass,
1183                                             &result->sids, &gids,
1184                                             &result->num_sids);
1185 
1186         if (!NT_STATUS_IS_OK(status)) {
1187                 DEBUG(10, ("pdb_enum_group_memberships failed: %s\n",
1188                            nt_errstr(status)));
1189                 TALLOC_FREE(result);
1190                 return status;
1191         }
1192 
1193         /*
1194          * The SID returned in server_info->sam_account is based
1195          * on our SAM sid even though for a pure UNIX account this should
1196          * not be the case as it doesn't really exist in the SAM db.
1197          * This causes lookups on "[in]valid users" to fail as they
1198          * will lookup this name as a "Unix User" SID to check against
1199          * the user token. Fix this by adding the "Unix User"\unix_username
1200          * SID to the sid array. The correct fix should probably be
1201          * changing the server_info->sam_account user SID to be a
1202          * S-1-22 Unix SID, but this might break old configs where
1203          * plaintext passwords were used with no SAM backend.
1204          */
1205 
1206         mem_ctx = talloc_init("make_server_info_pw_tmp");
1207         if (!mem_ctx) {
1208                 TALLOC_FREE(result);
1209                 return NT_STATUS_NO_MEMORY;
1210         }
1211 
1212         qualified_name = talloc_asprintf(mem_ctx, "%s\\%s",
1213                                         unix_users_domain_name(),
1214                                         unix_username );
1215         if (!qualified_name) {
1216                 TALLOC_FREE(result);
1217                 TALLOC_FREE(mem_ctx);
1218                 return NT_STATUS_NO_MEMORY;
1219         }
1220 
1221         if (!lookup_name(mem_ctx, qualified_name, LOOKUP_NAME_ALL,
1222                                                 NULL, NULL,
1223                                                 &u_sid, &type)) {
1224                 TALLOC_FREE(result);
1225                 TALLOC_FREE(mem_ctx);
1226                 return NT_STATUS_NO_SUCH_USER;
1227         }
1228 
1229         TALLOC_FREE(mem_ctx);
1230 
1231         if (type != SID_NAME_USER) {
1232                 TALLOC_FREE(result);
1233                 return NT_STATUS_NO_SUCH_USER;
1234         }
1235 
1236         status = add_sid_to_array_unique(result, &u_sid,
1237                                          &result->sids,
1238                                          &result->num_sids);
1239         if (!NT_STATUS_IS_OK(status)) {
1240                 TALLOC_FREE(result);
1241                 return status;
1242         }
1243 
1244         /* For now we throw away the gids and convert via sid_to_gid
1245          * later. This needs fixing, but I'd like to get the code straight and
1246          * simple first. */
1247         TALLOC_FREE(gids);
1248 
1249         *server_info = result;
1250 
1251         return NT_STATUS_OK;
1252 }
1253 
1254 /***************************************************************************
1255  Make (and fill) a user_info struct for a guest login.
1256  This *must* succeed for smbd to start. If there is no mapping entry for
1257  the guest gid, then create one.
1258 ***************************************************************************/
1259 
1260 static NTSTATUS make_new_server_info_guest(auth_serversupplied_info **server_info)
     /* [<][>][^][v][top][bottom][index][help] */
1261 {
1262         NTSTATUS status;
1263         struct samu *sampass = NULL;
1264         DOM_SID guest_sid;
1265         bool ret;
1266         char zeros[16];
1267         fstring tmp;
1268 
1269         if ( !(sampass = samu_new( NULL )) ) {
1270                 return NT_STATUS_NO_MEMORY;
1271         }
1272 
1273         sid_copy(&guest_sid, get_global_sam_sid());
1274         sid_append_rid(&guest_sid, DOMAIN_USER_RID_GUEST);
1275 
1276         become_root();
1277         ret = pdb_getsampwsid(sampass, &guest_sid);
1278         unbecome_root();
1279 
1280         if (!ret) {
1281                 TALLOC_FREE(sampass);
1282                 return NT_STATUS_NO_SUCH_USER;
1283         }
1284 
1285         status = make_server_info_sam(server_info, sampass);
1286         if (!NT_STATUS_IS_OK(status)) {
1287                 TALLOC_FREE(sampass);
1288                 return status;
1289         }
1290         
1291         (*server_info)->guest = True;
1292 
1293         status = create_local_token(*server_info);
1294         if (!NT_STATUS_IS_OK(status)) {
1295                 DEBUG(10, ("create_local_token failed: %s\n",
1296                            nt_errstr(status)));
1297                 return status;
1298         }
1299 
1300         /* annoying, but the Guest really does have a session key, and it is
1301            all zeros! */
1302         ZERO_STRUCT(zeros);
1303         (*server_info)->user_session_key = data_blob(zeros, sizeof(zeros));
1304         (*server_info)->lm_session_key = data_blob(zeros, sizeof(zeros));
1305 
1306         alpha_strcpy(tmp, pdb_get_username(sampass), ". _-$", sizeof(tmp));
1307         (*server_info)->sanitized_username = talloc_strdup(*server_info, tmp);
1308 
1309         return NT_STATUS_OK;
1310 }
1311 
1312 /****************************************************************************
1313   Fake a auth_serversupplied_info just from a username
1314 ****************************************************************************/
1315 
1316 NTSTATUS make_serverinfo_from_username(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
1317                                        const char *username,
1318                                        bool is_guest,
1319                                        struct auth_serversupplied_info **presult)
1320 {
1321         struct auth_serversupplied_info *result;
1322         struct passwd *pwd;
1323         NTSTATUS status;
1324 
1325         pwd = getpwnam_alloc(talloc_tos(), username);
1326         if (pwd == NULL) {
1327                 return NT_STATUS_NO_SUCH_USER;
1328         }
1329 
1330         status = make_server_info_pw(&result, pwd->pw_name, pwd);
1331 
1332         TALLOC_FREE(pwd);
1333 
1334         if (!NT_STATUS_IS_OK(status)) {
1335                 return status;
1336         }
1337 
1338         result->nss_token = true;
1339         result->guest = is_guest;
1340 
1341         status = create_local_token(result);
1342 
1343         if (!NT_STATUS_IS_OK(status)) {
1344                 TALLOC_FREE(result);
1345                 return status;
1346         }
1347 
1348         *presult = result;
1349         return NT_STATUS_OK;
1350 }
1351 
1352 
1353 struct auth_serversupplied_info *copy_serverinfo(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
1354                                                  const auth_serversupplied_info *src)
1355 {
1356         auth_serversupplied_info *dst;
1357 
1358         dst = make_server_info(mem_ctx);
1359         if (dst == NULL) {
1360                 return NULL;
1361         }
1362 
1363         dst->guest = src->guest;
1364         dst->utok.uid = src->utok.uid;
1365         dst->utok.gid = src->utok.gid;
1366         dst->utok.ngroups = src->utok.ngroups;
1367         if (src->utok.ngroups != 0) {
1368                 dst->utok.groups = (gid_t *)TALLOC_MEMDUP(
1369                         dst, src->utok.groups,
1370                         sizeof(gid_t)*dst->utok.ngroups);
1371         } else {
1372                 dst->utok.groups = NULL;
1373         }
1374 
1375         if (src->ptok) {
1376                 dst->ptok = dup_nt_token(dst, src->ptok);
1377                 if (!dst->ptok) {
1378                         TALLOC_FREE(dst);
1379                         return NULL;
1380                 }
1381         }
1382         
1383         dst->user_session_key = data_blob_talloc( dst, src->user_session_key.data,
1384                                                 src->user_session_key.length);
1385 
1386         dst->lm_session_key = data_blob_talloc(dst, src->lm_session_key.data,
1387                                                 src->lm_session_key.length);
1388 
1389         dst->sam_account = samu_new(NULL);
1390         if (!dst->sam_account) {
1391                 TALLOC_FREE(dst);
1392                 return NULL;
1393         }
1394 
1395         if (!pdb_copy_sam_account(dst->sam_account, src->sam_account)) {
1396                 TALLOC_FREE(dst);
1397                 return NULL;
1398         }
1399         
1400         dst->pam_handle = NULL;
1401         dst->unix_name = talloc_strdup(dst, src->unix_name);
1402         if (!dst->unix_name) {
1403                 TALLOC_FREE(dst);
1404                 return NULL;
1405         }
1406 
1407         dst->sanitized_username = talloc_strdup(dst, src->sanitized_username);
1408         if (!dst->sanitized_username) {
1409                 TALLOC_FREE(dst);
1410                 return NULL;
1411         }
1412 
1413         return dst;
1414 }
1415 
1416 /*
1417  * Set a new session key. Used in the rpc server where we have to override the
1418  * SMB level session key with SystemLibraryDTC
1419  */
1420 
1421 bool server_info_set_session_key(struct auth_serversupplied_info *info,
     /* [<][>][^][v][top][bottom][index][help] */
1422                                  DATA_BLOB session_key)
1423 {
1424         TALLOC_FREE(info->user_session_key.data);
1425 
1426         info->user_session_key = data_blob_talloc(
1427                 info, session_key.data, session_key.length);
1428 
1429         return (info->user_session_key.data != NULL);
1430 }
1431 
1432 static auth_serversupplied_info *guest_info = NULL;
1433 
1434 bool init_guest_info(void)
     /* [<][>][^][v][top][bottom][index][help] */
1435 {
1436         if (guest_info != NULL)
1437                 return True;
1438 
1439         return NT_STATUS_IS_OK(make_new_server_info_guest(&guest_info));
1440 }
1441 
1442 NTSTATUS make_server_info_guest(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
1443                                 auth_serversupplied_info **server_info)
1444 {
1445         *server_info = copy_serverinfo(mem_ctx, guest_info);
1446         return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1447 }
1448 
1449 bool copy_current_user(struct current_user *dst, struct current_user *src)
     /* [<][>][^][v][top][bottom][index][help] */
1450 {
1451         gid_t *groups;
1452         NT_USER_TOKEN *nt_token;
1453 
1454         groups = (gid_t *)memdup(src->ut.groups,
1455                                  sizeof(gid_t) * src->ut.ngroups);
1456         if ((src->ut.ngroups != 0) && (groups == NULL)) {
1457                 return False;
1458         }
1459 
1460         nt_token = dup_nt_token(NULL, src->nt_user_token);
1461         if (nt_token == NULL) {
1462                 SAFE_FREE(groups);
1463                 return False;
1464         }
1465 
1466         dst->conn = src->conn;
1467         dst->vuid = src->vuid;
1468         dst->ut.uid = src->ut.uid;
1469         dst->ut.gid = src->ut.gid;
1470         dst->ut.ngroups = src->ut.ngroups;
1471         dst->ut.groups = groups;
1472         dst->nt_user_token = nt_token;
1473         return True;
1474 }
1475 
1476 /***************************************************************************
1477  Purely internal function for make_server_info_info3
1478  Fill the sam account from getpwnam
1479 ***************************************************************************/
1480 static NTSTATUS fill_sam_account(TALLOC_CTX *mem_ctx, 
     /* [<][>][^][v][top][bottom][index][help] */
1481                                  const char *domain,
1482                                  const char *username,
1483                                  char **found_username,
1484                                  uid_t *uid, gid_t *gid,
1485                                  struct samu *account,
1486                                  bool *username_was_mapped)
1487 {
1488         NTSTATUS nt_status;
1489         fstring dom_user, lower_username;
1490         fstring real_username;
1491         struct passwd *passwd;
1492 
1493         fstrcpy( lower_username, username );
1494         strlower_m( lower_username );
1495 
1496         fstr_sprintf(dom_user, "%s%c%s", domain, *lp_winbind_separator(), 
1497                 lower_username);
1498 
1499         /* Get the passwd struct.  Try to create the account is necessary. */
1500 
1501         *username_was_mapped = map_username( dom_user );
1502 
1503         if ( !(passwd = smb_getpwnam( NULL, dom_user, real_username, True )) )
1504                 return NT_STATUS_NO_SUCH_USER;
1505 
1506         *uid = passwd->pw_uid;
1507         *gid = passwd->pw_gid;
1508 
1509         /* This is pointless -- there is no suport for differing 
1510            unix and windows names.  Make sure to always store the 
1511            one we actually looked up and succeeded. Have I mentioned
1512            why I hate the 'winbind use default domain' parameter?   
1513                                          --jerry              */
1514            
1515         *found_username = talloc_strdup( mem_ctx, real_username );
1516         
1517         DEBUG(5,("fill_sam_account: located username was [%s]\n", *found_username));
1518 
1519         nt_status = samu_set_unix( account, passwd );
1520         
1521         TALLOC_FREE(passwd);
1522         
1523         return nt_status;
1524 }
1525 
1526 /****************************************************************************
1527  Wrapper to allow the getpwnam() call to strip the domain name and 
1528  try again in case a local UNIX user is already there.  Also run through 
1529  the username if we fallback to the username only.
1530  ****************************************************************************/
1531  
1532 struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, char *domuser,
     /* [<][>][^][v][top][bottom][index][help] */
1533                              fstring save_username, bool create )
1534 {
1535         struct passwd *pw = NULL;
1536         char *p;
1537         fstring username;
1538         
1539         /* we only save a copy of the username it has been mangled 
1540            by winbindd use default domain */
1541            
1542         save_username[0] = '\0';
1543            
1544         /* don't call map_username() here since it has to be done higher 
1545            up the stack so we don't call it mutliple times */
1546 
1547         fstrcpy( username, domuser );
1548         
1549         p = strchr_m( username, *lp_winbind_separator() );
1550         
1551         /* code for a DOMAIN\user string */
1552         
1553         if ( p ) {
1554                 fstring strip_username;
1555 
1556                 pw = Get_Pwnam_alloc( mem_ctx, domuser );
1557                 if ( pw ) {     
1558                         /* make sure we get the case of the username correct */
1559                         /* work around 'winbind use default domain = yes' */
1560 
1561                         if ( !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
1562                                 char *domain;
1563                                 
1564                                 /* split the domain and username into 2 strings */
1565                                 *p = '\0';
1566                                 domain = username;
1567 
1568                                 fstr_sprintf(save_username, "%s%c%s", domain, *lp_winbind_separator(), pw->pw_name);
1569                         }
1570                         else
1571                                 fstrcpy( save_username, pw->pw_name );
1572 
1573                         /* whew -- done! */             
1574                         return pw;
1575                 }
1576 
1577                 /* setup for lookup of just the username */
1578                 /* remember that p and username are overlapping memory */
1579 
1580                 p++;
1581                 fstrcpy( strip_username, p );
1582                 fstrcpy( username, strip_username );
1583         }
1584         
1585         /* just lookup a plain username */
1586         
1587         pw = Get_Pwnam_alloc(mem_ctx, username);
1588                 
1589         /* Create local user if requested but only if winbindd
1590            is not running.  We need to protect against cases
1591            where winbindd is failing and then prematurely
1592            creating users in /etc/passwd */
1593         
1594         if ( !pw && create && !winbind_ping() ) {
1595                 /* Don't add a machine account. */
1596                 if (username[strlen(username)-1] == '$')
1597                         return NULL;
1598 
1599                 _smb_create_user(NULL, username, NULL);
1600                 pw = Get_Pwnam_alloc(mem_ctx, username);
1601         }
1602         
1603         /* one last check for a valid passwd struct */
1604         
1605         if ( pw )
1606                 fstrcpy( save_username, pw->pw_name );
1607 
1608         return pw;
1609 }
1610 
1611 /***************************************************************************
1612  Make a server_info struct from the info3 returned by a domain logon 
1613 ***************************************************************************/
1614 
1615 NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, 
     /* [<][>][^][v][top][bottom][index][help] */
1616                                 const char *sent_nt_username,
1617                                 const char *domain,
1618                                 auth_serversupplied_info **server_info, 
1619                                 struct netr_SamInfo3 *info3)
1620 {
1621         char zeros[16];
1622 
1623         NTSTATUS nt_status = NT_STATUS_OK;
1624         char *found_username = NULL;
1625         const char *nt_domain;
1626         const char *nt_username;
1627         struct samu *sam_account = NULL;
1628         DOM_SID user_sid;
1629         DOM_SID group_sid;
1630         bool username_was_mapped;
1631 
1632         uid_t uid = (uid_t)-1;
1633         gid_t gid = (gid_t)-1;
1634 
1635         auth_serversupplied_info *result;
1636 
1637         /* 
1638            Here is where we should check the list of
1639            trusted domains, and verify that the SID 
1640            matches.
1641         */
1642 
1643         sid_copy(&user_sid, info3->base.domain_sid);
1644         if (!sid_append_rid(&user_sid, info3->base.rid)) {
1645                 return NT_STATUS_INVALID_PARAMETER;
1646         }
1647         
1648         sid_copy(&group_sid, info3->base.domain_sid);
1649         if (!sid_append_rid(&group_sid, info3->base.primary_gid)) {
1650                 return NT_STATUS_INVALID_PARAMETER;
1651         }
1652 
1653         nt_username = talloc_strdup(mem_ctx, info3->base.account_name.string);
1654         if (!nt_username) {
1655                 /* If the server didn't give us one, just use the one we sent
1656                  * them */
1657                 nt_username = sent_nt_username;
1658         }
1659 
1660         nt_domain = talloc_strdup(mem_ctx, info3->base.domain.string);
1661         if (!nt_domain) {
1662                 /* If the server didn't give us one, just use the one we sent
1663                  * them */
1664                 nt_domain = domain;
1665         }
1666         
1667         /* try to fill the SAM account..  If getpwnam() fails, then try the 
1668            add user script (2.2.x behavior).
1669 
1670            We use the _unmapped_ username here in an attempt to provide
1671            consistent username mapping behavior between kerberos and NTLM[SSP]
1672            authentication in domain mode security.  I.E. Username mapping
1673            should be applied to the fully qualified username
1674            (e.g. DOMAIN\user) and not just the login name.  Yes this means we
1675            called map_username() unnecessarily in make_user_info_map() but
1676            that is how the current code is designed.  Making the change here
1677            is the least disruptive place.  -- jerry */
1678            
1679         if ( !(sam_account = samu_new( NULL )) ) {
1680                 return NT_STATUS_NO_MEMORY;
1681         }
1682 
1683         /* this call will try to create the user if necessary */
1684 
1685         nt_status = fill_sam_account(mem_ctx, nt_domain, sent_nt_username,
1686                                      &found_username, &uid, &gid, sam_account,
1687                                      &username_was_mapped);
1688 
1689         
1690         /* if we still don't have a valid unix account check for 
1691           'map to guest = bad uid' */
1692           
1693         if (!NT_STATUS_IS_OK(nt_status)) {
1694                 TALLOC_FREE( sam_account );
1695                 if ( lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID ) {
1696                         make_server_info_guest(NULL, server_info);
1697                         return NT_STATUS_OK;
1698                 }
1699                 return nt_status;
1700         }
1701                 
1702         if (!pdb_set_nt_username(sam_account, nt_username, PDB_CHANGED)) {
1703                 TALLOC_FREE(sam_account);
1704                 return NT_STATUS_NO_MEMORY;
1705         }
1706 
1707         if (!pdb_set_username(sam_account, nt_username, PDB_CHANGED)) {
1708                 TALLOC_FREE(sam_account);
1709                 return NT_STATUS_NO_MEMORY;
1710         }
1711 
1712         if (!pdb_set_domain(sam_account, nt_domain, PDB_CHANGED)) {
1713                 TALLOC_FREE(sam_account);
1714                 return NT_STATUS_NO_MEMORY;
1715         }
1716 
1717         if (!pdb_set_user_sid(sam_account, &user_sid, PDB_CHANGED)) {
1718                 TALLOC_FREE(sam_account);
1719                 return NT_STATUS_UNSUCCESSFUL;
1720         }
1721 
1722         if (!pdb_set_group_sid(sam_account, &group_sid, PDB_CHANGED)) {
1723                 TALLOC_FREE(sam_account);
1724                 return NT_STATUS_UNSUCCESSFUL;
1725         }
1726 
1727         if (!pdb_set_fullname(sam_account,
1728                               info3->base.full_name.string,
1729                               PDB_CHANGED)) {
1730                 TALLOC_FREE(sam_account);
1731                 return NT_STATUS_NO_MEMORY;
1732         }
1733 
1734         if (!pdb_set_logon_script(sam_account,
1735                                   info3->base.logon_script.string,
1736                                   PDB_CHANGED)) {
1737                 TALLOC_FREE(sam_account);
1738                 return NT_STATUS_NO_MEMORY;
1739         }
1740 
1741         if (!pdb_set_profile_path(sam_account,
1742                                   info3->base.profile_path.string,
1743                                   PDB_CHANGED)) {
1744                 TALLOC_FREE(sam_account);
1745                 return NT_STATUS_NO_MEMORY;
1746         }
1747 
1748         if (!pdb_set_homedir(sam_account,
1749                              info3->base.home_directory.string,
1750                              PDB_CHANGED)) {
1751                 TALLOC_FREE(sam_account);
1752                 return NT_STATUS_NO_MEMORY;
1753         }
1754 
1755         if (!pdb_set_dir_drive(sam_account,
1756                                info3->base.home_drive.string,
1757                                PDB_CHANGED)) {
1758                 TALLOC_FREE(sam_account);
1759                 return NT_STATUS_NO_MEMORY;
1760         }
1761 
1762         if (!pdb_set_acct_ctrl(sam_account, info3->base.acct_flags, PDB_CHANGED)) {
1763                 TALLOC_FREE(sam_account);
1764                 return NT_STATUS_NO_MEMORY;
1765         }
1766 
1767         if (!pdb_set_pass_last_set_time(
1768                     sam_account,
1769                     nt_time_to_unix(info3->base.last_password_change),
1770                     PDB_CHANGED)) {
1771                 TALLOC_FREE(sam_account);
1772                 return NT_STATUS_NO_MEMORY;
1773         }
1774 
1775         if (!pdb_set_pass_can_change_time(
1776                     sam_account,
1777                     nt_time_to_unix(info3->base.allow_password_change),
1778                     PDB_CHANGED)) {
1779                 TALLOC_FREE(sam_account);
1780                 return NT_STATUS_NO_MEMORY;
1781         }
1782 
1783         if (!pdb_set_pass_must_change_time(
1784                     sam_account,
1785                     nt_time_to_unix(info3->base.force_password_change),
1786                     PDB_CHANGED)) {
1787                 TALLOC_FREE(sam_account);
1788                 return NT_STATUS_NO_MEMORY;
1789         }
1790 
1791         result = make_server_info(NULL);
1792         if (result == NULL) {
1793                 DEBUG(4, ("make_server_info failed!\n"));
1794                 TALLOC_FREE(sam_account);
1795                 return NT_STATUS_NO_MEMORY;
1796         }
1797 
1798         /* save this here to _net_sam_logon() doesn't fail (it assumes a 
1799            valid struct samu) */
1800                    
1801         result->sam_account = sam_account;
1802         result->unix_name = talloc_strdup(result, found_username);
1803 
1804         result->sanitized_username = sanitize_username(result,
1805                                                        result->unix_name);
1806         if (result->sanitized_username == NULL) {
1807                 TALLOC_FREE(result);
1808                 return NT_STATUS_NO_MEMORY;
1809         }
1810 
1811         /* Fill in the unix info we found on the way */
1812 
1813         result->utok.uid = uid;
1814         result->utok.gid = gid;
1815 
1816         /* Create a 'combined' list of all SIDs we might want in the SD */
1817 
1818         result->num_sids = 0;
1819         result->sids = NULL;
1820 
1821         nt_status = sid_array_from_info3(result, info3,
1822                                          &result->sids,
1823                                          &result->num_sids,
1824                                          false, false);
1825         if (!NT_STATUS_IS_OK(nt_status)) {
1826                 TALLOC_FREE(result);
1827                 return nt_status;
1828         }
1829 
1830         /* Ensure the primary group sid is at position 0. */
1831         sort_sid_array_for_smbd(result, &group_sid);
1832 
1833         result->login_server = talloc_strdup(result,
1834                                              info3->base.logon_server.string);
1835 
1836         /* ensure we are never given NULL session keys */
1837 
1838         ZERO_STRUCT(zeros);
1839 
1840         if (memcmp(info3->base.key.key, zeros, sizeof(zeros)) == 0) {
1841                 result->user_session_key = data_blob_null;
1842         } else {
1843                 result->user_session_key = data_blob_talloc(
1844                         result, info3->base.key.key,
1845                         sizeof(info3->base.key.key));
1846         }
1847 
1848         if (memcmp(info3->base.LMSessKey.key, zeros, 8) == 0) {
1849                 result->lm_session_key = data_blob_null;
1850         } else {
1851                 result->lm_session_key = data_blob_talloc(
1852                         result, info3->base.LMSessKey.key,
1853                         sizeof(info3->base.LMSessKey.key));
1854         }
1855 
1856         result->nss_token |= username_was_mapped;
1857 
1858         *server_info = result;
1859 
1860         return NT_STATUS_OK;
1861 }
1862 
1863 /*****************************************************************************
1864  Make a server_info struct from the wbcAuthUserInfo returned by a domain logon
1865 ******************************************************************************/
1866 
1867 NTSTATUS make_server_info_wbcAuthUserInfo(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
1868                                           const char *sent_nt_username,
1869                                           const char *domain,
1870                                           const struct wbcAuthUserInfo *info,
1871                                           auth_serversupplied_info **server_info)
1872 {
1873         char zeros[16];
1874 
1875         NTSTATUS nt_status = NT_STATUS_OK;
1876         char *found_username = NULL;
1877         const char *nt_domain;
1878         const char *nt_username;
1879         struct samu *sam_account = NULL;
1880         DOM_SID user_sid;
1881         DOM_SID group_sid;
1882         bool username_was_mapped;
1883         uint32_t i;
1884 
1885         uid_t uid = (uid_t)-1;
1886         gid_t gid = (gid_t)-1;
1887 
1888         auth_serversupplied_info *result;
1889 
1890         result = make_server_info(NULL);
1891         if (result == NULL) {
1892                 DEBUG(4, ("make_server_info failed!\n"));
1893                 return NT_STATUS_NO_MEMORY;
1894         }
1895 
1896         /*
1897            Here is where we should check the list of
1898            trusted domains, and verify that the SID
1899            matches.
1900         */
1901 
1902         memcpy(&user_sid, &info->sids[0].sid, sizeof(user_sid));
1903         memcpy(&group_sid, &info->sids[1].sid, sizeof(group_sid));
1904 
1905         if (info->account_name) {
1906                 nt_username = talloc_strdup(result, info->account_name);
1907         } else {
1908                 /* If the server didn't give us one, just use the one we sent
1909                  * them */
1910                 nt_username = talloc_strdup(result, sent_nt_username);
1911         }
1912         if (!nt_username) {
1913                 TALLOC_FREE(result);
1914                 return NT_STATUS_NO_MEMORY;
1915         }
1916 
1917         if (info->domain_name) {
1918                 nt_domain = talloc_strdup(result, info->domain_name);
1919         } else {
1920                 /* If the server didn't give us one, just use the one we sent
1921                  * them */
1922                 nt_domain = talloc_strdup(result, domain);
1923         }
1924         if (!nt_domain) {
1925                 TALLOC_FREE(result);
1926                 return NT_STATUS_NO_MEMORY;
1927         }
1928 
1929         /* try to fill the SAM account..  If getpwnam() fails, then try the
1930            add user script (2.2.x behavior).
1931 
1932            We use the _unmapped_ username here in an attempt to provide
1933            consistent username mapping behavior between kerberos and NTLM[SSP]
1934            authentication in domain mode security.  I.E. Username mapping
1935            should be applied to the fully qualified username
1936            (e.g. DOMAIN\user) and not just the login name.  Yes this means we
1937            called map_username() unnecessarily in make_user_info_map() but
1938            that is how the current code is designed.  Making the change here
1939            is the least disruptive place.  -- jerry */
1940 
1941         if ( !(sam_account = samu_new( result )) ) {
1942                 TALLOC_FREE(result);
1943                 return NT_STATUS_NO_MEMORY;
1944         }
1945 
1946         /* this call will try to create the user if necessary */
1947 
1948         nt_status = fill_sam_account(result, nt_domain, sent_nt_username,
1949                                      &found_username, &uid, &gid, sam_account,
1950                                      &username_was_mapped);
1951 
1952         /* if we still don't have a valid unix account check for
1953           'map to guest = bad uid' */
1954 
1955         if (!NT_STATUS_IS_OK(nt_status)) {
1956                 TALLOC_FREE( result );
1957                 if ( lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID ) {
1958                         make_server_info_guest(NULL, server_info);
1959                         return NT_STATUS_OK;
1960                 }
1961                 return nt_status;
1962         }
1963 
1964         if (!pdb_set_nt_username(sam_account, nt_username, PDB_CHANGED)) {
1965                 TALLOC_FREE(result);
1966                 return NT_STATUS_NO_MEMORY;
1967         }
1968 
1969         if (!pdb_set_username(sam_account, nt_username, PDB_CHANGED)) {
1970                 TALLOC_FREE(result);
1971                 return NT_STATUS_NO_MEMORY;
1972         }
1973 
1974         if (!pdb_set_domain(sam_account, nt_domain, PDB_CHANGED)) {
1975                 TALLOC_FREE(result);
1976                 return NT_STATUS_NO_MEMORY;
1977         }
1978 
1979         if (!pdb_set_user_sid(sam_account, &user_sid, PDB_CHANGED)) {
1980                 TALLOC_FREE(result);
1981                 return NT_STATUS_UNSUCCESSFUL;
1982         }
1983 
1984         if (!pdb_set_group_sid(sam_account, &group_sid, PDB_CHANGED)) {
1985                 TALLOC_FREE(result);
1986                 return NT_STATUS_UNSUCCESSFUL;
1987         }
1988 
1989         if (!pdb_set_fullname(sam_account, info->full_name, PDB_CHANGED)) {
1990                 TALLOC_FREE(result);
1991                 return NT_STATUS_NO_MEMORY;
1992         }
1993 
1994         if (!pdb_set_logon_script(sam_account, info->logon_script, PDB_CHANGED)) {
1995                 TALLOC_FREE(result);
1996                 return NT_STATUS_NO_MEMORY;
1997         }
1998 
1999         if (!pdb_set_profile_path(sam_account, info->profile_path, PDB_CHANGED)) {
2000                 TALLOC_FREE(result);
2001                 return NT_STATUS_NO_MEMORY;
2002         }
2003 
2004         if (!pdb_set_homedir(sam_account, info->home_directory, PDB_CHANGED)) {
2005                 TALLOC_FREE(result);
2006                 return NT_STATUS_NO_MEMORY;
2007         }
2008 
2009         if (!pdb_set_dir_drive(sam_account, info->home_drive, PDB_CHANGED)) {
2010                 TALLOC_FREE(result);
2011                 return NT_STATUS_NO_MEMORY;
2012         }
2013 
2014         if (!pdb_set_acct_ctrl(sam_account, info->acct_flags, PDB_CHANGED)) {
2015                 TALLOC_FREE(result);
2016                 return NT_STATUS_NO_MEMORY;
2017         }
2018 
2019         if (!pdb_set_pass_last_set_time(
2020                     sam_account,
2021                     nt_time_to_unix(info->pass_last_set_time),
2022                     PDB_CHANGED)) {
2023                 TALLOC_FREE(result);
2024                 return NT_STATUS_NO_MEMORY;
2025         }
2026 
2027         if (!pdb_set_pass_can_change_time(
2028                     sam_account,
2029                     nt_time_to_unix(info->pass_can_change_time),
2030                     PDB_CHANGED)) {
2031                 TALLOC_FREE(result);
2032                 return NT_STATUS_NO_MEMORY;
2033         }
2034 
2035         if (!pdb_set_pass_must_change_time(
2036                     sam_account,
2037                     nt_time_to_unix(info->pass_must_change_time),
2038                     PDB_CHANGED)) {
2039                 TALLOC_FREE(result);
2040                 return NT_STATUS_NO_MEMORY;
2041         }
2042 
2043         /* save this here to _net_sam_logon() doesn't fail (it assumes a
2044            valid struct samu) */
2045 
2046         result->sam_account = sam_account;
2047         result->unix_name = talloc_strdup(result, found_username);
2048 
2049         result->sanitized_username = sanitize_username(result,
2050                                                        result->unix_name);
2051         result->login_server = talloc_strdup(result, info->logon_server);
2052 
2053         if ((result->unix_name == NULL)
2054             || (result->sanitized_username == NULL)
2055             || (result->login_server == NULL)) {
2056                 TALLOC_FREE(result);
2057                 return NT_STATUS_NO_MEMORY;
2058         }
2059 
2060         /* Fill in the unix info we found on the way */
2061 
2062         result->utok.uid = uid;
2063         result->utok.gid = gid;
2064 
2065         /* Create a 'combined' list of all SIDs we might want in the SD */
2066 
2067         result->num_sids = info->num_sids - 2;
2068         result->sids = talloc_array(result, DOM_SID, result->num_sids);
2069         if (result->sids == NULL) {
2070                 TALLOC_FREE(result);
2071                 return NT_STATUS_NO_MEMORY;
2072         }
2073 
2074         for (i=0; i < result->num_sids; i++) {
2075                 memcpy(&result->sids[i], &info->sids[i+2].sid, sizeof(result->sids[i]));
2076         }
2077 
2078         /* Ensure the primary group sid is at position 0. */
2079         sort_sid_array_for_smbd(result, &group_sid);
2080 
2081         /* ensure we are never given NULL session keys */
2082 
2083         ZERO_STRUCT(zeros);
2084 
2085         if (memcmp(info->user_session_key, zeros, sizeof(zeros)) == 0) {
2086                 result->user_session_key = data_blob_null;
2087         } else {
2088                 result->user_session_key = data_blob_talloc(
2089                         result, info->user_session_key,
2090                         sizeof(info->user_session_key));
2091         }
2092 
2093         if (memcmp(info->lm_session_key, zeros, 8) == 0) {
2094                 result->lm_session_key = data_blob_null;
2095         } else {
2096                 result->lm_session_key = data_blob_talloc(
2097                         result, info->lm_session_key,
2098                         sizeof(info->lm_session_key));
2099         }
2100 
2101         result->nss_token |= username_was_mapped;
2102 
2103         *server_info = result;
2104 
2105         return NT_STATUS_OK;
2106 }
2107 
2108 /***************************************************************************
2109  Free a user_info struct
2110 ***************************************************************************/
2111 
2112 void free_user_info(auth_usersupplied_info **user_info)
     /* [<][>][^][v][top][bottom][index][help] */
2113 {
2114         DEBUG(5,("attempting to free (and zero) a user_info structure\n"));
2115         if (*user_info != NULL) {
2116                 if ((*user_info)->smb_name) {
2117                         DEBUG(10,("structure was created for %s\n",
2118                                   (*user_info)->smb_name));
2119                 }
2120                 SAFE_FREE((*user_info)->smb_name);
2121                 SAFE_FREE((*user_info)->internal_username);
2122                 SAFE_FREE((*user_info)->client_domain);
2123                 SAFE_FREE((*user_info)->domain);
2124                 SAFE_FREE((*user_info)->wksta_name);
2125                 data_blob_free(&(*user_info)->lm_resp);
2126                 data_blob_free(&(*user_info)->nt_resp);
2127                 data_blob_clear_free(&(*user_info)->lm_interactive_pwd);
2128                 data_blob_clear_free(&(*user_info)->nt_interactive_pwd);
2129                 data_blob_clear_free(&(*user_info)->plaintext_password);
2130                 ZERO_STRUCT(**user_info);
2131         }
2132         SAFE_FREE(*user_info);
2133 }
2134 
2135 /***************************************************************************
2136  Make an auth_methods struct
2137 ***************************************************************************/
2138 
2139 bool make_auth_methods(struct auth_context *auth_context, auth_methods **auth_method) 
     /* [<][>][^][v][top][bottom][index][help] */
2140 {
2141         if (!auth_context) {
2142                 smb_panic("no auth_context supplied to "
2143                           "make_auth_methods()!\n");
2144         }
2145 
2146         if (!auth_method) {
2147                 smb_panic("make_auth_methods: pointer to auth_method pointer "
2148                           "is NULL!\n");
2149         }
2150 
2151         *auth_method = TALLOC_P(auth_context->mem_ctx, auth_methods);
2152         if (!*auth_method) {
2153                 DEBUG(0,("make_auth_method: malloc failed!\n"));
2154                 return False;
2155         }
2156         ZERO_STRUCTP(*auth_method);
2157         
2158         return True;
2159 }
2160 
2161 /**
2162  * Verify whether or not given domain is trusted.
2163  *
2164  * @param domain_name name of the domain to be verified
2165  * @return true if domain is one of the trusted once or
2166  *         false if otherwise
2167  **/
2168 
2169 bool is_trusted_domain(const char* dom_name)
     /* [<][>][^][v][top][bottom][index][help] */
2170 {
2171         DOM_SID trustdom_sid;
2172         bool ret;
2173 
2174         /* no trusted domains for a standalone server */
2175 
2176         if ( lp_server_role() == ROLE_STANDALONE )
2177                 return False;
2178 
2179         /* if we are a DC, then check for a direct trust relationships */
2180 
2181         if ( IS_DC ) {
2182                 become_root();
2183                 DEBUG (5,("is_trusted_domain: Checking for domain trust with "
2184                           "[%s]\n", dom_name ));
2185                 ret = pdb_get_trusteddom_pw(dom_name, NULL, NULL, NULL);
2186                 unbecome_root();
2187                 if (ret)
2188                         return True;
2189         }
2190         else {
2191                 wbcErr result;
2192 
2193                 /* If winbind is around, ask it */
2194 
2195                 result = wb_is_trusted_domain(dom_name);
2196 
2197                 if (result == WBC_ERR_SUCCESS) {
2198                         return True;
2199                 }
2200 
2201                 if (result == WBC_ERR_DOMAIN_NOT_FOUND) {
2202                         /* winbind could not find the domain */
2203                         return False;
2204                 }
2205 
2206                 /* The only other possible result is that winbind is not up
2207                    and running. We need to update the trustdom_cache
2208                    ourselves */
2209                 
2210                 update_trustdom_cache();
2211         }
2212 
2213         /* now the trustdom cache should be available a DC could still
2214          * have a transitive trust so fall back to the cache of trusted
2215          * domains (like a domain member would use  */
2216 
2217         if ( trustdom_cache_fetch(dom_name, &trustdom_sid) ) {
2218                 return True;
2219         }
2220 
2221         return False;
2222 }
2223 

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