LCOV - code coverage report
Current view: top level - source3/auth - auth_util.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 661 1028 64.3 %
Date: 2024-04-21 15:09:00 Functions: 32 35 91.4 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    Authentication utility functions
       4             :    Copyright (C) Andrew Tridgell 1992-1998
       5             :    Copyright (C) Andrew Bartlett 2001-2011
       6             :    Copyright (C) Jeremy Allison 2000-2001
       7             :    Copyright (C) Rafal Szczesniak 2002
       8             :    Copyright (C) Volker Lendecke 2006-2008
       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 "dom_sid.h"
      25             : #include "includes.h"
      26             : #include "auth.h"
      27             : #include "lib/util_unixsids.h"
      28             : #include "../libcli/auth/libcli_auth.h"
      29             : #include "rpc_client/init_lsa.h"
      30             : #include "../libcli/security/security.h"
      31             : #include "../lib/util/util_pw.h"
      32             : #include "lib/winbind_util.h"
      33             : #include "passdb.h"
      34             : #include "../librpc/gen_ndr/ndr_auth.h"
      35             : #include "../auth/auth_sam_reply.h"
      36             : #include "../librpc/gen_ndr/idmap.h"
      37             : #include "lib/param/loadparm.h"
      38             : #include "../lib/tsocket/tsocket.h"
      39             : #include "rpc_client/util_netlogon.h"
      40             : #include "source4/auth/auth.h"
      41             : #include "auth/auth_util.h"
      42             : #include "source3/lib/substitute.h"
      43             : 
      44             : #undef DBGC_CLASS
      45             : #define DBGC_CLASS DBGC_AUTH
      46             : 
      47             : /****************************************************************************
      48             :  Create a UNIX user on demand.
      49             : ****************************************************************************/
      50             : 
      51           0 : static int _smb_create_user(const char *domain, const char *unix_username, const char *homedir)
      52             : {
      53           0 :         TALLOC_CTX *ctx = talloc_tos();
      54           0 :         const struct loadparm_substitution *lp_sub =
      55           0 :                 loadparm_s3_global_substitution();
      56           0 :         char *add_script;
      57           0 :         int ret;
      58             : 
      59           0 :         add_script = lp_add_user_script(ctx, lp_sub);
      60           0 :         if (!add_script || !*add_script) {
      61           0 :                 return -1;
      62             :         }
      63           0 :         add_script = talloc_all_string_sub(ctx,
      64             :                                 add_script,
      65             :                                 "%u",
      66             :                                 unix_username);
      67           0 :         if (!add_script) {
      68           0 :                 return -1;
      69             :         }
      70           0 :         if (domain) {
      71           0 :                 add_script = talloc_all_string_sub(ctx,
      72             :                                         add_script,
      73             :                                         "%D",
      74             :                                         domain);
      75           0 :                 if (!add_script) {
      76           0 :                         return -1;
      77             :                 }
      78             :         }
      79           0 :         if (homedir) {
      80           0 :                 add_script = talloc_all_string_sub(ctx,
      81             :                                 add_script,
      82             :                                 "%H",
      83             :                                 homedir);
      84           0 :                 if (!add_script) {
      85           0 :                         return -1;
      86             :                 }
      87             :         }
      88           0 :         ret = smbrun(add_script, NULL, NULL);
      89           0 :         flush_pwnam_cache();
      90           0 :         DEBUG(ret ? 0 : 3,
      91             :                 ("smb_create_user: Running the command `%s' gave %d\n",
      92             :                  add_script,ret));
      93           0 :         return ret;
      94             : }
      95             : 
      96             : /****************************************************************************
      97             :  Create an auth_usersupplied_data structure after appropriate mapping.
      98             : ****************************************************************************/
      99             : 
     100       23675 : NTSTATUS make_user_info_map(TALLOC_CTX *mem_ctx,
     101             :                             struct auth_usersupplied_info **user_info,
     102             :                             const char *smb_name,
     103             :                             const char *client_domain,
     104             :                             const char *workstation_name,
     105             :                             const struct tsocket_address *remote_address,
     106             :                             const struct tsocket_address *local_address,
     107             :                             const char *service_description,
     108             :                             const DATA_BLOB *lm_pwd,
     109             :                             const DATA_BLOB *nt_pwd,
     110             :                             const struct samr_Password *lm_interactive_pwd,
     111             :                             const struct samr_Password *nt_interactive_pwd,
     112             :                             const char *plaintext,
     113             :                             enum auth_password_state password_state)
     114             : {
     115           0 :         const char *domain;
     116           0 :         NTSTATUS result;
     117           0 :         bool was_mapped;
     118       23675 :         char *internal_username = NULL;
     119             : 
     120       23675 :         was_mapped = map_username(talloc_tos(), smb_name, &internal_username);
     121       23675 :         if (!internal_username) {
     122           0 :                 return NT_STATUS_NO_MEMORY;
     123             :         }
     124             : 
     125       23675 :         DEBUG(5, ("Mapping user [%s]\\[%s] from workstation [%s]\n",
     126             :                  client_domain, smb_name, workstation_name));
     127             : 
     128             :         /*
     129             :          * We let the auth stack canonicalize, username
     130             :          * and domain.
     131             :          */
     132       23675 :         domain = client_domain;
     133             : 
     134       23675 :         result = make_user_info(mem_ctx, user_info, smb_name, internal_username,
     135             :                                 client_domain, domain, workstation_name,
     136             :                                 remote_address, local_address,
     137             :                                 service_description, lm_pwd, nt_pwd,
     138             :                                 lm_interactive_pwd, nt_interactive_pwd,
     139             :                                 plaintext, password_state);
     140       23675 :         if (NT_STATUS_IS_OK(result)) {
     141             :                 /* did we actually map the user to a different name? */
     142       23675 :                 (*user_info)->was_mapped = was_mapped;
     143             :         }
     144       23675 :         return result;
     145             : }
     146             : 
     147             : /****************************************************************************
     148             :  Create an auth_usersupplied_data, making the DATA_BLOBs here.
     149             :  Decrypt and encrypt the passwords.
     150             : ****************************************************************************/
     151             : 
     152         288 : bool make_user_info_netlogon_network(TALLOC_CTX *mem_ctx,
     153             :                                      struct auth_usersupplied_info **user_info,
     154             :                                      const char *smb_name,
     155             :                                      const char *client_domain,
     156             :                                      const char *workstation_name,
     157             :                                      const struct tsocket_address *remote_address,
     158             :                                      const struct tsocket_address *local_address,
     159             :                                      uint32_t logon_parameters,
     160             :                                      const uchar *lm_network_pwd,
     161             :                                      int lm_pwd_len,
     162             :                                      const uchar *nt_network_pwd,
     163             :                                      int nt_pwd_len)
     164             : {
     165           0 :         bool ret;
     166           0 :         NTSTATUS status;
     167         288 :         DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
     168         288 :         DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
     169             : 
     170         288 :         status = make_user_info_map(mem_ctx, user_info,
     171             :                                     smb_name, client_domain,
     172             :                                     workstation_name,
     173             :                                     remote_address,
     174             :                                     local_address,
     175             :                                     "SamLogon",
     176             :                                     lm_pwd_len ? &lm_blob : NULL,
     177             :                                     nt_pwd_len ? &nt_blob : NULL,
     178             :                                     NULL, NULL, NULL,
     179             :                                     AUTH_PASSWORD_RESPONSE);
     180             : 
     181         288 :         if (NT_STATUS_IS_OK(status)) {
     182         288 :                 (*user_info)->logon_parameters = logon_parameters;
     183             :         }
     184         288 :         ret = NT_STATUS_IS_OK(status) ? true : false;
     185             : 
     186         288 :         data_blob_free(&lm_blob);
     187         288 :         data_blob_free(&nt_blob);
     188         288 :         return ret;
     189             : }
     190             : 
     191             : /****************************************************************************
     192             :  Create an auth_usersupplied_data, making the DATA_BLOBs here.
     193             :  Decrypt and encrypt the passwords.
     194             : ****************************************************************************/
     195             : 
     196          16 : bool make_user_info_netlogon_interactive(TALLOC_CTX *mem_ctx,
     197             :                                          struct auth_usersupplied_info **user_info,
     198             :                                          const char *smb_name,
     199             :                                          const char *client_domain,
     200             :                                          const char *workstation_name,
     201             :                                          const struct tsocket_address *remote_address,
     202             :                                          const struct tsocket_address *local_address,
     203             :                                          uint32_t logon_parameters,
     204             :                                          const uchar chal[8],
     205             :                                          const uchar lm_interactive_pwd[16],
     206             :                                          const uchar nt_interactive_pwd[16])
     207             : {
     208           0 :         struct samr_Password lm_pwd;
     209           0 :         struct samr_Password nt_pwd;
     210           0 :         unsigned char local_lm_response[24];
     211           0 :         unsigned char local_nt_response[24];
     212           0 :         int rc;
     213             : 
     214          16 :         if (lm_interactive_pwd)
     215          16 :                 memcpy(lm_pwd.hash, lm_interactive_pwd, sizeof(lm_pwd.hash));
     216             : 
     217          16 :         if (nt_interactive_pwd)
     218          16 :                 memcpy(nt_pwd.hash, nt_interactive_pwd, sizeof(nt_pwd.hash));
     219             : 
     220          16 :         if (lm_interactive_pwd) {
     221          16 :                 rc = SMBOWFencrypt(lm_pwd.hash, chal,
     222             :                                    local_lm_response);
     223          16 :                 if (rc != 0) {
     224           0 :                         return false;
     225             :                 }
     226             :         }
     227             : 
     228          16 :         if (nt_interactive_pwd) {
     229          16 :                 rc = SMBOWFencrypt(nt_pwd.hash, chal,
     230             :                               local_nt_response);
     231          16 :                 if (rc != 0) {
     232           0 :                         return false;
     233             :                 }
     234             :         }
     235             : 
     236             :         {
     237           0 :                 bool ret;
     238           0 :                 NTSTATUS nt_status;
     239          16 :                 DATA_BLOB local_lm_blob = data_blob_null;
     240          16 :                 DATA_BLOB local_nt_blob = data_blob_null;
     241             : 
     242          16 :                 if (lm_interactive_pwd) {
     243          16 :                         local_lm_blob = data_blob(local_lm_response,
     244             :                                                   sizeof(local_lm_response));
     245             :                 }
     246             : 
     247          16 :                 if (nt_interactive_pwd) {
     248          16 :                         local_nt_blob = data_blob(local_nt_response,
     249             :                                                   sizeof(local_nt_response));
     250             :                 }
     251             : 
     252          16 :                 nt_status = make_user_info_map(
     253             :                         mem_ctx,
     254             :                         user_info,
     255             :                         smb_name, client_domain, workstation_name,
     256             :                         remote_address,
     257             :                         local_address,
     258             :                         "SamLogon",
     259             :                         lm_interactive_pwd ? &local_lm_blob : NULL,
     260             :                         nt_interactive_pwd ? &local_nt_blob : NULL,
     261             :                         lm_interactive_pwd ? &lm_pwd : NULL,
     262             :                         nt_interactive_pwd ? &nt_pwd : NULL,
     263             :                         NULL, AUTH_PASSWORD_HASH);
     264             : 
     265          16 :                 if (NT_STATUS_IS_OK(nt_status)) {
     266          16 :                         (*user_info)->logon_parameters = logon_parameters;
     267          16 :                         (*user_info)->flags |= USER_INFO_INTERACTIVE_LOGON;
     268             :                 }
     269             : 
     270          16 :                 ret = NT_STATUS_IS_OK(nt_status) ? true : false;
     271          16 :                 data_blob_free(&local_lm_blob);
     272          16 :                 data_blob_free(&local_nt_blob);
     273          16 :                 return ret;
     274             :         }
     275             : }
     276             : 
     277             : 
     278             : /****************************************************************************
     279             :  Create an auth_usersupplied_data structure
     280             : ****************************************************************************/
     281             : 
     282           0 : bool make_user_info_for_reply(TALLOC_CTX *mem_ctx,
     283             :                               struct auth_usersupplied_info **user_info,
     284             :                               const char *smb_name,
     285             :                               const char *client_domain,
     286             :                               const struct tsocket_address *remote_address,
     287             :                               const struct tsocket_address *local_address,
     288             :                               const char *service_description,
     289             :                               const uint8_t chal[8],
     290             :                               DATA_BLOB plaintext_password)
     291             : {
     292             : 
     293           0 :         DATA_BLOB local_lm_blob;
     294           0 :         DATA_BLOB local_nt_blob;
     295           0 :         NTSTATUS ret;
     296           0 :         char *plaintext_password_string;
     297             :         /*
     298             :          * Not encrypted - do so.
     299             :          */
     300             : 
     301           0 :         DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted "
     302             :                  "format.\n"));
     303           0 :         if (plaintext_password.data && plaintext_password.length) {
     304           0 :                 unsigned char local_lm_response[24];
     305             : 
     306             : #ifdef DEBUG_PASSWORD
     307           0 :                 DEBUG(10,("Unencrypted password (len %d):\n",
     308             :                           (int)plaintext_password.length));
     309           0 :                 dump_data(100, plaintext_password.data,
     310           0 :                           plaintext_password.length);
     311             : #endif
     312             : 
     313           0 :                 SMBencrypt( (const char *)plaintext_password.data,
     314             :                             (const uchar*)chal, local_lm_response);
     315           0 :                 local_lm_blob = data_blob(local_lm_response, 24);
     316             : 
     317             :                 /* We can't do an NT hash here, as the password needs to be
     318             :                    case insensitive */
     319           0 :                 local_nt_blob = data_blob_null;
     320             :         } else {
     321           0 :                 local_lm_blob = data_blob_null;
     322           0 :                 local_nt_blob = data_blob_null;
     323             :         }
     324             : 
     325           0 :         plaintext_password_string = talloc_strndup(talloc_tos(),
     326           0 :                                                    (const char *)plaintext_password.data,
     327             :                                                    plaintext_password.length);
     328           0 :         if (!plaintext_password_string) {
     329           0 :                 return false;
     330             :         }
     331             : 
     332           0 :         ret = make_user_info(mem_ctx,
     333             :                 user_info, smb_name, smb_name, client_domain, client_domain,
     334             :                 get_remote_machine_name(),
     335             :                 remote_address,
     336             :                 local_address,
     337             :                 service_description,
     338           0 :                 local_lm_blob.data ? &local_lm_blob : NULL,
     339           0 :                 local_nt_blob.data ? &local_nt_blob : NULL,
     340             :                 NULL, NULL,
     341             :                 plaintext_password_string,
     342             :                 AUTH_PASSWORD_PLAIN);
     343             : 
     344           0 :         if (plaintext_password_string) {
     345           0 :                 memset(plaintext_password_string, '\0', strlen(plaintext_password_string));
     346           0 :                 talloc_free(plaintext_password_string);
     347             :         }
     348             : 
     349           0 :         data_blob_free(&local_lm_blob);
     350           0 :         return NT_STATUS_IS_OK(ret) ? true : false;
     351             : }
     352             : 
     353             : /****************************************************************************
     354             :  Create an auth_usersupplied_data structure
     355             : ****************************************************************************/
     356             : 
     357          63 : NTSTATUS make_user_info_for_reply_enc(TALLOC_CTX *mem_ctx,
     358             :                                       struct auth_usersupplied_info **user_info,
     359             :                                       const char *smb_name,
     360             :                                       const char *client_domain,
     361             :                                       const struct tsocket_address *remote_address,
     362             :                                       const struct tsocket_address *local_address,
     363             :                                       const char *service_description,
     364             :                                       DATA_BLOB lm_resp, DATA_BLOB nt_resp)
     365             : {
     366          63 :         bool allow_raw = lp_raw_ntlmv2_auth();
     367             : 
     368          63 :         if (!allow_raw && nt_resp.length >= 48) {
     369             :                 /*
     370             :                  * NTLMv2_RESPONSE has at least 48 bytes
     371             :                  * and should only be supported via NTLMSSP.
     372             :                  */
     373           2 :                 DEBUG(2,("Rejecting raw NTLMv2 authentication with "
     374             :                          "user [%s\\%s] from[%s]\n",
     375             :                          client_domain, smb_name,
     376             :                          tsocket_address_string(remote_address, mem_ctx)));
     377           2 :                 return NT_STATUS_INVALID_PARAMETER;
     378             :         }
     379             : 
     380         122 :         return make_user_info(mem_ctx,
     381             :                               user_info, smb_name, smb_name,
     382             :                               client_domain, client_domain,
     383             :                               get_remote_machine_name(),
     384             :                               remote_address,
     385             :                               local_address,
     386             :                               service_description,
     387          61 :                               lm_resp.data && (lm_resp.length > 0) ? &lm_resp : NULL,
     388          61 :                               nt_resp.data && (nt_resp.length > 0) ? &nt_resp : NULL,
     389             :                               NULL, NULL, NULL,
     390             :                               AUTH_PASSWORD_RESPONSE);
     391             : }
     392             : 
     393             : /****************************************************************************
     394             :  Create a guest user_info blob, for anonymous authentication.
     395             : ****************************************************************************/
     396             : 
     397          37 : bool make_user_info_guest(TALLOC_CTX *mem_ctx,
     398             :                           const struct tsocket_address *remote_address,
     399             :                           const struct tsocket_address *local_address,
     400             :                           const char *service_description,
     401             :                           struct auth_usersupplied_info **user_info)
     402             : {
     403           0 :         NTSTATUS nt_status;
     404             : 
     405          37 :         nt_status = make_user_info(mem_ctx,
     406             :                                    user_info,
     407             :                                    "","",
     408             :                                    "","",
     409             :                                    "",
     410             :                                    remote_address,
     411             :                                    local_address,
     412             :                                    service_description,
     413             :                                    NULL, NULL,
     414             :                                    NULL, NULL,
     415             :                                    NULL,
     416             :                                    AUTH_PASSWORD_RESPONSE);
     417             : 
     418          37 :         return NT_STATUS_IS_OK(nt_status) ? true : false;
     419             : }
     420             : 
     421       23332 : static NTSTATUS log_nt_token(struct security_token *token)
     422             : {
     423       23332 :         TALLOC_CTX *frame = talloc_stackframe();
     424           0 :         const struct loadparm_substitution *lp_sub =
     425       23332 :                 loadparm_s3_global_substitution();
     426           0 :         char *command;
     427           0 :         char *group_sidstr;
     428           0 :         struct dom_sid_buf buf;
     429           0 :         size_t i;
     430             : 
     431       23332 :         if ((lp_log_nt_token_command(frame, lp_sub) == NULL) ||
     432       23332 :             (strlen(lp_log_nt_token_command(frame, lp_sub)) == 0)) {
     433       23332 :                 TALLOC_FREE(frame);
     434       23332 :                 return NT_STATUS_OK;
     435             :         }
     436             : 
     437           0 :         group_sidstr = talloc_strdup(frame, "");
     438           0 :         for (i=1; i<token->num_sids; i++) {
     439           0 :                 group_sidstr = talloc_asprintf(
     440             :                         frame, "%s %s", group_sidstr,
     441           0 :                         dom_sid_str_buf(&token->sids[i], &buf));
     442             :         }
     443             : 
     444           0 :         command = talloc_string_sub(
     445           0 :                 frame, lp_log_nt_token_command(frame, lp_sub),
     446           0 :                 "%s", dom_sid_str_buf(&token->sids[0], &buf));
     447           0 :         command = talloc_string_sub(frame, command, "%t", group_sidstr);
     448             : 
     449           0 :         if (command == NULL) {
     450           0 :                 TALLOC_FREE(frame);
     451           0 :                 return NT_STATUS_NO_MEMORY;
     452             :         }
     453             : 
     454           0 :         DEBUG(8, ("running command: [%s]\n", command));
     455           0 :         if (smbrun(command, NULL, NULL) != 0) {
     456           0 :                 DEBUG(0, ("Could not log NT token\n"));
     457           0 :                 TALLOC_FREE(frame);
     458           0 :                 return NT_STATUS_ACCESS_DENIED;
     459             :         }
     460             : 
     461           0 :         TALLOC_FREE(frame);
     462           0 :         return NT_STATUS_OK;
     463             : }
     464             : 
     465             : /*
     466             :  * Create the token to use from server_info->info3 and
     467             :  * server_info->sids (the info3/sam groups). Find the unix gids.
     468             :  */
     469             : 
     470       22564 : NTSTATUS create_local_token(TALLOC_CTX *mem_ctx,
     471             :                             const struct auth_serversupplied_info *server_info,
     472             :                             DATA_BLOB *session_key,
     473             :                             const char *smb_username, /* for ->sanitized_username, for %U subs */
     474             :                             struct auth_session_info **session_info_out)
     475             : {
     476           0 :         struct security_token *t;
     477           0 :         NTSTATUS status;
     478           0 :         size_t i;
     479           0 :         struct dom_sid tmp_sid;
     480       22564 :         struct auth_session_info *session_info = NULL;
     481           0 :         struct unixid *ids;
     482       22564 :         bool is_allowed = false;
     483             : 
     484             :         /* Ensure we can't possible take a code path leading to a
     485             :          * null deref. */
     486       22564 :         if (!server_info) {
     487           0 :                 return NT_STATUS_LOGON_FAILURE;
     488             :         }
     489             : 
     490       22564 :         if (is_allowed_domain(server_info->info3->base.logon_domain.string)) {
     491       22560 :                 is_allowed = true;
     492             :         }
     493             : 
     494             :         /* Check if we have extra info about the user. */
     495       22564 :         if (dom_sid_in_domain(&global_sid_Unix_Users,
     496       22452 :                               &server_info->extra.user_sid) ||
     497       22452 :             dom_sid_in_domain(&global_sid_Unix_Groups,
     498             :                               &server_info->extra.pgid_sid))
     499             :         {
     500         112 :                 is_allowed = true;
     501             :         }
     502             : 
     503       22564 :         if (!is_allowed) {
     504           0 :                 DBG_NOTICE("Authentication failed for user [%s] "
     505             :                            "from firewalled domain [%s]\n",
     506             :                            server_info->info3->base.account_name.string,
     507             :                            server_info->info3->base.logon_domain.string);
     508           0 :                 return NT_STATUS_AUTHENTICATION_FIREWALL_FAILED;
     509             :         }
     510             : 
     511       22564 :         if (server_info->cached_session_info != NULL) {
     512         617 :                 session_info = copy_session_info(mem_ctx,
     513         617 :                                 server_info->cached_session_info);
     514         617 :                 if (session_info == NULL) {
     515           0 :                         goto nomem;
     516             :                 }
     517             : 
     518             :                 /* This is a potentially untrusted username for use in %U */
     519        1234 :                 session_info->unix_info->sanitized_username =
     520         617 :                         talloc_alpha_strcpy(session_info->unix_info,
     521             :                                             smb_username,
     522             :                                             SAFE_NETBIOS_CHARS "$");
     523         617 :                 if (session_info->unix_info->sanitized_username == NULL) {
     524           0 :                         goto nomem;
     525             :                 }
     526             : 
     527         617 :                 session_info->unique_session_token = GUID_random();
     528             : 
     529         617 :                 *session_info_out = session_info;
     530         617 :                 return NT_STATUS_OK;
     531             :         }
     532             : 
     533       21947 :         session_info = talloc_zero(mem_ctx, struct auth_session_info);
     534       21947 :         if (!session_info) {
     535           0 :                 goto nomem;
     536             :         }
     537             : 
     538       21947 :         session_info->unix_token = talloc_zero(session_info, struct security_unix_token);
     539       21947 :         if (!session_info->unix_token) {
     540           0 :                 goto nomem;
     541             :         }
     542             : 
     543       21947 :         session_info->unix_token->uid = server_info->utok.uid;
     544       21947 :         session_info->unix_token->gid = server_info->utok.gid;
     545             : 
     546       21947 :         session_info->unix_info = talloc_zero(session_info, struct auth_user_info_unix);
     547       21947 :         if (!session_info->unix_info) {
     548           0 :                 goto nomem;
     549             :         }
     550             : 
     551       21947 :         session_info->unix_info->unix_name = talloc_strdup(session_info, server_info->unix_name);
     552       21947 :         if (!session_info->unix_info->unix_name) {
     553           0 :                 goto nomem;
     554             :         }
     555             : 
     556             :         /* This is a potentially untrusted username for use in %U */
     557       43894 :         session_info->unix_info->sanitized_username =
     558       21947 :                 talloc_alpha_strcpy(session_info->unix_info,
     559             :                                     smb_username,
     560             :                                     SAFE_NETBIOS_CHARS "$");
     561       21947 :         if (session_info->unix_info->sanitized_username == NULL) {
     562           0 :                 goto nomem;
     563             :         }
     564             : 
     565       21947 :         if (session_key) {
     566           0 :                 data_blob_free(&session_info->session_key);
     567           0 :                 session_info->session_key = data_blob_talloc(session_info,
     568             :                                                                   session_key->data,
     569             :                                                                   session_key->length);
     570           0 :                 if (!session_info->session_key.data && session_key->length) {
     571           0 :                         goto nomem;
     572             :                 }
     573             :         } else {
     574       21947 :                 session_info->session_key = data_blob_talloc( session_info, server_info->session_key.data,
     575             :                                                               server_info->session_key.length);
     576             :         }
     577             : 
     578             :         /* We need to populate session_info->info with the information found in server_info->info3 */
     579       21947 :         status = make_user_info_SamBaseInfo(session_info, "", &server_info->info3->base,
     580       21947 :                                             server_info->guest == false,
     581       21947 :                                             &session_info->info);
     582       21947 :         if (!NT_STATUS_IS_OK(status)) {
     583           0 :                 DEBUG(0, ("conversion of info3 into auth_user_info failed!\n"));
     584           0 :                 goto fail;
     585             :         }
     586             : 
     587             :         /*
     588             :          * If the user name was mapped to some local unix user,
     589             :          * we can not make much use of the SIDs the
     590             :          * domain controller provided us with.
     591             :          */
     592       21947 :         if (server_info->nss_token) {
     593         270 :                 char *found_username = NULL;
     594         270 :                 status = create_token_from_username(session_info,
     595         270 :                                                     server_info->unix_name,
     596         270 :                                                     server_info->guest,
     597         270 :                                                     &session_info->unix_token->uid,
     598         270 :                                                     &session_info->unix_token->gid,
     599             :                                                     &found_username,
     600             :                                                     &session_info->security_token);
     601         270 :                 if (NT_STATUS_IS_OK(status)) {
     602         270 :                         session_info->unix_info->unix_name = found_username;
     603             :                 }
     604             :         } else {
     605       21677 :                 status = create_local_nt_token_from_info3(session_info,
     606       21677 :                                                           server_info->guest,
     607       21677 :                                                           server_info->info3,
     608             :                                                           &server_info->extra,
     609             :                                                           &session_info->security_token);
     610             :         }
     611             : 
     612       21947 :         if (!NT_STATUS_IS_OK(status)) {
     613           0 :                 goto fail;
     614             :         }
     615             : 
     616             :         /* Convert the SIDs to gids. */
     617             : 
     618       21947 :         session_info->unix_token->ngroups = 0;
     619       21947 :         session_info->unix_token->groups = NULL;
     620             : 
     621       21947 :         t = session_info->security_token;
     622             : 
     623       21947 :         ids = talloc_array(talloc_tos(), struct unixid,
     624             :                            t->num_sids);
     625       21947 :         if (ids == NULL) {
     626           0 :                 goto nomem;
     627             :         }
     628             : 
     629       21947 :         if (!sids_to_unixids(t->sids, t->num_sids, ids)) {
     630           0 :                 goto nomem;
     631             :         }
     632             : 
     633      184312 :         for (i=0; i<t->num_sids; i++) {
     634             : 
     635      162365 :                 if (i == 0 && ids[i].type != ID_TYPE_BOTH) {
     636       21301 :                         continue;
     637             :                 }
     638             : 
     639      141064 :                 if (ids[i].type != ID_TYPE_GID &&
     640       33890 :                     ids[i].type != ID_TYPE_BOTH) {
     641           0 :                         struct dom_sid_buf buf;
     642       29858 :                         DEBUG(10, ("Could not convert SID %s to gid, "
     643             :                                    "ignoring it\n",
     644             :                                    dom_sid_str_buf(&t->sids[i], &buf)));
     645       29858 :                         continue;
     646             :                 }
     647      111206 :                 if (!add_gid_to_array_unique(session_info->unix_token,
     648      111206 :                                              ids[i].id,
     649      111206 :                                              &session_info->unix_token->groups,
     650      111206 :                                              &session_info->unix_token->ngroups)) {
     651           0 :                         goto nomem;
     652             :                 }
     653             :         }
     654             : 
     655             :         /*
     656             :          * Add the "Unix Group" SID for each gid to catch mapped groups
     657             :          * and their Unix equivalent.  This is to solve the backwards
     658             :          * compatibility problem of 'valid users = +ntadmin' where
     659             :          * ntadmin has been paired with "Domain Admins" in the group
     660             :          * mapping table.  Otherwise smb.conf would need to be changed
     661             :          * to 'valid user = "Domain Admins"'.  --jerry
     662             :          *
     663             :          * For consistency we also add the "Unix User" SID,
     664             :          * so that the complete unix token is represented within
     665             :          * the nt token.
     666             :          */
     667             : 
     668       21947 :         uid_to_unix_users_sid(session_info->unix_token->uid, &tmp_sid);
     669       21947 :         status = add_sid_to_array_unique(
     670       21947 :                 session_info->security_token,
     671             :                 &tmp_sid,
     672       21947 :                 &session_info->security_token->sids,
     673       21947 :                 &session_info->security_token->num_sids);
     674       21947 :         if (!NT_STATUS_IS_OK(status)) {
     675           0 :                 goto fail;
     676             :         }
     677             : 
     678       21947 :         gid_to_unix_groups_sid(session_info->unix_token->gid, &tmp_sid);
     679       21947 :         status = add_sid_to_array_unique(
     680       21947 :                 session_info->security_token,
     681             :                 &tmp_sid,
     682       21947 :                 &session_info->security_token->sids,
     683       21947 :                 &session_info->security_token->num_sids);
     684       21947 :         if (!NT_STATUS_IS_OK(status)) {
     685           0 :                 goto fail;
     686             :         }
     687             : 
     688      133035 :         for ( i=0; i<session_info->unix_token->ngroups; i++ ) {
     689      111088 :                 gid_to_unix_groups_sid(session_info->unix_token->groups[i], &tmp_sid);
     690      111088 :                 status = add_sid_to_array_unique(
     691      111088 :                         session_info->security_token,
     692             :                         &tmp_sid,
     693      111088 :                         &session_info->security_token->sids,
     694      111088 :                         &session_info->security_token->num_sids);
     695      111088 :                 if (!NT_STATUS_IS_OK(status)) {
     696           0 :                         goto fail;
     697             :                 }
     698             :         }
     699             : 
     700       21947 :         security_token_debug(DBGC_AUTH, 10, session_info->security_token);
     701       21947 :         debug_unix_user_token(DBGC_AUTH, 10,
     702       21947 :                               session_info->unix_token->uid,
     703       21947 :                               session_info->unix_token->gid,
     704       21947 :                               session_info->unix_token->ngroups,
     705       21947 :                               session_info->unix_token->groups);
     706             : 
     707       21947 :         status = log_nt_token(session_info->security_token);
     708       21947 :         if (!NT_STATUS_IS_OK(status)) {
     709           0 :                 goto fail;
     710             :         }
     711             : 
     712       21947 :         session_info->unique_session_token = GUID_random();
     713             : 
     714       21947 :         *session_info_out = session_info;
     715       21947 :         return NT_STATUS_OK;
     716           0 : nomem:
     717           0 :         status = NT_STATUS_NO_MEMORY;
     718           0 : fail:
     719           0 :         TALLOC_FREE(session_info);
     720           0 :         return status;
     721             : }
     722             : 
     723        1385 : NTSTATUS auth3_user_info_dc_add_hints(struct auth_user_info_dc *user_info_dc,
     724             :                                       uid_t uid,
     725             :                                       gid_t gid,
     726             :                                       uint32_t flags)
     727             : {
     728        1385 :         uint32_t orig_num_sids = user_info_dc->num_sids;
     729        1385 :         struct dom_sid tmp_sid = { 0, };
     730           0 :         NTSTATUS status;
     731             : 
     732             :         /*
     733             :          * We add S-5-88-1-X in order to pass the uid
     734             :          * for the unix token.
     735             :          */
     736        1385 :         sid_compose(&tmp_sid,
     737             :                     &global_sid_Unix_NFS_Users,
     738             :                     (uint32_t)uid);
     739        1385 :         status = add_sid_to_array_attrs_unique(user_info_dc->sids,
     740             :                                                &tmp_sid,
     741             :                                                SE_GROUP_DEFAULT_FLAGS,
     742             :                                                &user_info_dc->sids,
     743             :                                                &user_info_dc->num_sids);
     744        1385 :         if (!NT_STATUS_IS_OK(status)) {
     745           0 :                 DEBUG(0, ("add_sid_to_array_unique failed: %s\n",
     746             :                           nt_errstr(status)));
     747           0 :                 goto fail;
     748             :         }
     749             : 
     750             :         /*
     751             :          * We add S-5-88-2-X in order to pass the gid
     752             :          * for the unix token.
     753             :          */
     754        1385 :         sid_compose(&tmp_sid,
     755             :                     &global_sid_Unix_NFS_Groups,
     756             :                     (uint32_t)gid);
     757        1385 :         status = add_sid_to_array_attrs_unique(user_info_dc->sids,
     758             :                                                &tmp_sid,
     759             :                                                SE_GROUP_DEFAULT_FLAGS,
     760             :                                                &user_info_dc->sids,
     761             :                                                &user_info_dc->num_sids);
     762        1385 :         if (!NT_STATUS_IS_OK(status)) {
     763           0 :                 DEBUG(0, ("add_sid_to_array_unique failed: %s\n",
     764             :                           nt_errstr(status)));
     765           0 :                 goto fail;
     766             :         }
     767             : 
     768             :         /*
     769             :          * We add S-5-88-3-X in order to pass some flags
     770             :          * (AUTH3_UNIX_HINT_*) to auth3_create_session_info().
     771             :          */
     772        1385 :         sid_compose(&tmp_sid,
     773             :                     &global_sid_Unix_NFS_Mode,
     774             :                     flags);
     775        1385 :         status = add_sid_to_array_attrs_unique(user_info_dc->sids,
     776             :                                                &tmp_sid,
     777             :                                                SE_GROUP_DEFAULT_FLAGS,
     778             :                                                &user_info_dc->sids,
     779             :                                                &user_info_dc->num_sids);
     780        1385 :         if (!NT_STATUS_IS_OK(status)) {
     781           0 :                 DEBUG(0, ("add_sid_to_array_unique failed: %s\n",
     782             :                           nt_errstr(status)));
     783           0 :                 goto fail;
     784             :         }
     785             : 
     786        1385 :         return NT_STATUS_OK;
     787             : 
     788           0 : fail:
     789           0 :         user_info_dc->num_sids = orig_num_sids;
     790           0 :         return status;
     791             : }
     792             : 
     793        1385 : static NTSTATUS auth3_session_info_create(
     794             :         TALLOC_CTX *mem_ctx,
     795             :         const struct auth_user_info_dc *user_info_dc,
     796             :         const char *original_user_name,
     797             :         uint32_t session_info_flags,
     798             :         struct auth_session_info **session_info_out)
     799             : {
     800        1385 :         TALLOC_CTX *frame = talloc_stackframe();
     801        1385 :         struct auth_session_info *session_info = NULL;
     802        1385 :         uid_t hint_uid = -1;
     803        1385 :         bool found_hint_uid = false;
     804        1385 :         uid_t hint_gid = -1;
     805        1385 :         bool found_hint_gid = false;
     806        1385 :         uint32_t hint_flags = 0;
     807        1385 :         bool found_hint_flags = false;
     808        1385 :         bool need_getpwuid = false;
     809        1385 :         struct unixid *ids = NULL;
     810        1385 :         uint32_t num_gids = 0;
     811        1385 :         gid_t *gids = NULL;
     812        1385 :         struct dom_sid tmp_sid = { 0, };
     813           0 :         NTSTATUS status;
     814           0 :         size_t i;
     815           0 :         bool ok;
     816             : 
     817        1385 :         *session_info_out = NULL;
     818             : 
     819        1385 :         if (user_info_dc->num_sids == 0) {
     820           0 :                 TALLOC_FREE(frame);
     821           0 :                 return NT_STATUS_INVALID_TOKEN;
     822             :         }
     823             : 
     824        1385 :         if (user_info_dc->info == NULL) {
     825           0 :                 TALLOC_FREE(frame);
     826           0 :                 return NT_STATUS_INVALID_TOKEN;
     827             :         }
     828             : 
     829        1385 :         if (user_info_dc->info->account_name == NULL) {
     830           0 :                 TALLOC_FREE(frame);
     831           0 :                 return NT_STATUS_INVALID_TOKEN;
     832             :         }
     833             : 
     834        1385 :         session_info = talloc_zero(mem_ctx, struct auth_session_info);
     835        1385 :         if (session_info == NULL) {
     836           0 :                 TALLOC_FREE(frame);
     837           0 :                 return NT_STATUS_NO_MEMORY;
     838             :         }
     839             :         /* keep this under frame for easier cleanup */
     840        1385 :         talloc_reparent(mem_ctx, frame, session_info);
     841             : 
     842        2770 :         session_info->info = auth_user_info_copy(session_info,
     843        1385 :                                                  user_info_dc->info);
     844        1385 :         if (session_info->info == NULL) {
     845           0 :                 TALLOC_FREE(frame);
     846           0 :                 return NT_STATUS_NO_MEMORY;
     847             :         }
     848             : 
     849        1385 :         session_info->security_token = talloc_zero(session_info,
     850             :                                                    struct security_token);
     851        1385 :         if (session_info->security_token == NULL) {
     852           0 :                 TALLOC_FREE(frame);
     853           0 :                 return NT_STATUS_NO_MEMORY;
     854             :         }
     855             : 
     856             :         /*
     857             :          * Avoid a lot of reallocations and allocate what we'll
     858             :          * use in most cases.
     859             :          */
     860        1385 :         session_info->security_token->sids = talloc_zero_array(
     861             :                                                 session_info->security_token,
     862             :                                                 struct dom_sid,
     863             :                                                 user_info_dc->num_sids);
     864        1385 :         if (session_info->security_token->sids == NULL) {
     865           0 :                 TALLOC_FREE(frame);
     866           0 :                 return NT_STATUS_NO_MEMORY;
     867             :         }
     868             : 
     869        6925 :         for (i = PRIMARY_USER_SID_INDEX; i < user_info_dc->num_sids; i++) {
     870        5540 :                 struct security_token *nt_token = session_info->security_token;
     871           0 :                 int cmp;
     872             : 
     873             :                 /*
     874             :                  * S-1-5-88-X-Y sids are only used to give hints
     875             :                  * to the unix token construction.
     876             :                  *
     877             :                  * S-1-5-88-1-Y gives the uid=Y
     878             :                  * S-1-5-88-2-Y gives the gid=Y
     879             :                  * S-1-5-88-3-Y gives flags=Y: AUTH3_UNIX_HINT_*
     880             :                  */
     881        5540 :                 cmp = dom_sid_compare_domain(&global_sid_Unix_NFS,
     882        5540 :                                              &user_info_dc->sids[i].sid);
     883        5540 :                 if (cmp == 0) {
     884           0 :                         bool match;
     885        4155 :                         uint32_t hint = 0;
     886             : 
     887        4155 :                         match = sid_peek_rid(&user_info_dc->sids[i].sid, &hint);
     888        4155 :                         if (!match) {
     889        4155 :                                 continue;
     890             :                         }
     891             : 
     892        4155 :                         match = dom_sid_in_domain(&global_sid_Unix_NFS_Users,
     893        4155 :                                                   &user_info_dc->sids[i].sid);
     894        4155 :                         if (match) {
     895        1385 :                                 if (found_hint_uid) {
     896           0 :                                         TALLOC_FREE(frame);
     897           0 :                                         return NT_STATUS_INVALID_TOKEN;
     898             :                                 }
     899        1385 :                                 found_hint_uid = true;
     900        1385 :                                 hint_uid = (uid_t)hint;
     901        1385 :                                 continue;
     902             :                         }
     903             : 
     904        2770 :                         match = dom_sid_in_domain(&global_sid_Unix_NFS_Groups,
     905        2770 :                                                   &user_info_dc->sids[i].sid);
     906        2770 :                         if (match) {
     907        1385 :                                 if (found_hint_gid) {
     908           0 :                                         TALLOC_FREE(frame);
     909           0 :                                         return NT_STATUS_INVALID_TOKEN;
     910             :                                 }
     911        1385 :                                 found_hint_gid = true;
     912        1385 :                                 hint_gid = (gid_t)hint;
     913        1385 :                                 continue;
     914             :                         }
     915             : 
     916        1385 :                         match = dom_sid_in_domain(&global_sid_Unix_NFS_Mode,
     917        1385 :                                                   &user_info_dc->sids[i].sid);
     918        1385 :                         if (match) {
     919        1385 :                                 if (found_hint_flags) {
     920           0 :                                         TALLOC_FREE(frame);
     921           0 :                                         return NT_STATUS_INVALID_TOKEN;
     922             :                                 }
     923        1385 :                                 found_hint_flags = true;
     924        1385 :                                 hint_flags = hint;
     925        1385 :                                 continue;
     926             :                         }
     927             : 
     928           0 :                         continue;
     929             :                 }
     930             : 
     931        1385 :                 status = add_sid_to_array_unique(nt_token->sids,
     932        1385 :                                                  &user_info_dc->sids[i].sid,
     933             :                                                  &nt_token->sids,
     934             :                                                  &nt_token->num_sids);
     935        1385 :                 if (!NT_STATUS_IS_OK(status)) {
     936           0 :                         TALLOC_FREE(frame);
     937           0 :                         return status;
     938             :                 }
     939             :         }
     940             : 
     941             :         /*
     942             :          * We need at least one usable SID
     943             :          */
     944        1385 :         if (session_info->security_token->num_sids == 0) {
     945           0 :                 TALLOC_FREE(frame);
     946           0 :                 return NT_STATUS_INVALID_TOKEN;
     947             :         }
     948             : 
     949             :         /*
     950             :          * We need all tree hints: uid, gid, flags
     951             :          * or none of them.
     952             :          */
     953        1385 :         if (found_hint_uid || found_hint_gid || found_hint_flags) {
     954        1385 :                 if (!found_hint_uid) {
     955           0 :                         TALLOC_FREE(frame);
     956           0 :                         return NT_STATUS_INVALID_TOKEN;
     957             :                 }
     958             : 
     959        1385 :                 if (!found_hint_gid) {
     960           0 :                         TALLOC_FREE(frame);
     961           0 :                         return NT_STATUS_INVALID_TOKEN;
     962             :                 }
     963             : 
     964        1385 :                 if (!found_hint_flags) {
     965           0 :                         TALLOC_FREE(frame);
     966           0 :                         return NT_STATUS_INVALID_TOKEN;
     967             :                 }
     968             :         }
     969             : 
     970        1385 :         if (!(user_info_dc->info->user_flags & NETLOGON_GUEST)) {
     971         609 :                 session_info_flags |= AUTH_SESSION_INFO_AUTHENTICATED;
     972             :         }
     973             : 
     974        1385 :         status = finalize_local_nt_token(session_info->security_token,
     975             :                                          session_info_flags);
     976        1385 :         if (!NT_STATUS_IS_OK(status)) {
     977           0 :                 TALLOC_FREE(frame);
     978           0 :                 return status;
     979             :         }
     980             : 
     981             :         /*
     982             :          * unless set otherwise, the session key is the user session
     983             :          * key from the auth subsystem
     984             :          */
     985        1385 :         if (user_info_dc->user_session_key.length != 0) {
     986        1385 :                 session_info->session_key = data_blob_dup_talloc(session_info,
     987             :                                                 user_info_dc->user_session_key);
     988        1385 :                 if (session_info->session_key.data == NULL) {
     989           0 :                         TALLOC_FREE(frame);
     990           0 :                         return NT_STATUS_NO_MEMORY;
     991             :                 }
     992             :         }
     993             : 
     994        1385 :         if (!(session_info_flags & AUTH_SESSION_INFO_UNIX_TOKEN)) {
     995           0 :                 goto done;
     996             :         }
     997             : 
     998        1385 :         session_info->unix_token = talloc_zero(session_info, struct security_unix_token);
     999        1385 :         if (session_info->unix_token == NULL) {
    1000           0 :                 TALLOC_FREE(frame);
    1001           0 :                 return NT_STATUS_NO_MEMORY;
    1002             :         }
    1003        1385 :         session_info->unix_token->uid = -1;
    1004        1385 :         session_info->unix_token->gid = -1;
    1005             : 
    1006        1385 :         session_info->unix_info = talloc_zero(session_info, struct auth_user_info_unix);
    1007        1385 :         if (session_info->unix_info == NULL) {
    1008           0 :                 TALLOC_FREE(frame);
    1009           0 :                 return NT_STATUS_NO_MEMORY;
    1010             :         }
    1011             : 
    1012             :         /* Convert the SIDs to uid/gids. */
    1013             : 
    1014        1385 :         ids = talloc_zero_array(frame, struct unixid,
    1015             :                                 session_info->security_token->num_sids);
    1016        1385 :         if (ids == NULL) {
    1017           0 :                 TALLOC_FREE(frame);
    1018           0 :                 return NT_STATUS_NO_MEMORY;
    1019             :         }
    1020             : 
    1021        1385 :         if (!(hint_flags & AUTH3_UNIX_HINT_DONT_TRANSLATE_FROM_SIDS)) {
    1022         776 :                 ok = sids_to_unixids(session_info->security_token->sids,
    1023         776 :                                      session_info->security_token->num_sids,
    1024             :                                      ids);
    1025         776 :                 if (!ok) {
    1026           0 :                         TALLOC_FREE(frame);
    1027           0 :                         return NT_STATUS_NO_MEMORY;
    1028             :                 }
    1029             :         }
    1030             : 
    1031        1385 :         if (found_hint_uid) {
    1032        1385 :                 session_info->unix_token->uid = hint_uid;
    1033           0 :         } else if (ids[0].type == ID_TYPE_UID) {
    1034             :                 /*
    1035             :                  * The primary SID resolves to a UID only.
    1036             :                  */
    1037           0 :                 session_info->unix_token->uid = ids[0].id;
    1038           0 :         } else if (ids[0].type == ID_TYPE_BOTH) {
    1039             :                 /*
    1040             :                  * The primary SID resolves to a UID and GID,
    1041             :                  * use it as uid and add it as first element
    1042             :                  * to the groups array.
    1043             :                  */
    1044           0 :                 session_info->unix_token->uid = ids[0].id;
    1045             : 
    1046           0 :                 ok = add_gid_to_array_unique(session_info->unix_token,
    1047           0 :                                              session_info->unix_token->uid,
    1048           0 :                                              &session_info->unix_token->groups,
    1049           0 :                                              &session_info->unix_token->ngroups);
    1050           0 :                 if (!ok) {
    1051           0 :                         TALLOC_FREE(frame);
    1052           0 :                         return NT_STATUS_NO_MEMORY;
    1053             :                 }
    1054             :         } else {
    1055             :                 /*
    1056             :                  * It we can't get a uid, we can't imporsonate
    1057             :                  * the user.
    1058             :                  */
    1059           0 :                 TALLOC_FREE(frame);
    1060           0 :                 return NT_STATUS_INVALID_TOKEN;
    1061             :         }
    1062             : 
    1063        1385 :         if (found_hint_gid) {
    1064        1385 :                 session_info->unix_token->gid = hint_gid;
    1065             :         } else {
    1066           0 :                 need_getpwuid = true;
    1067             :         }
    1068             : 
    1069        1385 :         if (hint_flags & AUTH3_UNIX_HINT_QUALIFIED_NAME) {
    1070        1218 :                 session_info->unix_info->unix_name =
    1071        1218 :                         talloc_asprintf(session_info->unix_info,
    1072             :                                         "%s%c%s",
    1073         609 :                                         session_info->info->domain_name,
    1074         609 :                                         *lp_winbind_separator(),
    1075         609 :                                         session_info->info->account_name);
    1076         609 :                 if (session_info->unix_info->unix_name == NULL) {
    1077           0 :                         TALLOC_FREE(frame);
    1078           0 :                         return NT_STATUS_NO_MEMORY;
    1079             :                 }
    1080         776 :         } else if (hint_flags & AUTH3_UNIX_HINT_ISLOLATED_NAME) {
    1081           0 :                 session_info->unix_info->unix_name =
    1082           0 :                         talloc_strdup(session_info->unix_info,
    1083           0 :                                       session_info->info->account_name);
    1084           0 :                 if (session_info->unix_info->unix_name == NULL) {
    1085           0 :                         TALLOC_FREE(frame);
    1086           0 :                         return NT_STATUS_NO_MEMORY;
    1087             :                 }
    1088             :         } else {
    1089         776 :                 need_getpwuid = true;
    1090             :         }
    1091             : 
    1092        1385 :         if (need_getpwuid) {
    1093         776 :                 struct passwd *pwd = NULL;
    1094             : 
    1095             :                 /*
    1096             :                  * Ask the system for the primary gid
    1097             :                  * and the real unix name.
    1098             :                  */
    1099         776 :                 pwd = getpwuid_alloc(frame, session_info->unix_token->uid);
    1100         776 :                 if (pwd == NULL) {
    1101           0 :                         TALLOC_FREE(frame);
    1102           0 :                         return NT_STATUS_INVALID_TOKEN;
    1103             :                 }
    1104         776 :                 if (!found_hint_gid) {
    1105           0 :                         session_info->unix_token->gid = pwd->pw_gid;
    1106             :                 }
    1107             : 
    1108        1552 :                 session_info->unix_info->unix_name =
    1109         776 :                         talloc_strdup(session_info->unix_info, pwd->pw_name);
    1110         776 :                 if (session_info->unix_info->unix_name == NULL) {
    1111           0 :                         TALLOC_FREE(frame);
    1112           0 :                         return NT_STATUS_NO_MEMORY;
    1113             :                 }
    1114             : 
    1115         776 :                 TALLOC_FREE(pwd);
    1116             :         }
    1117             : 
    1118        1385 :         ok = add_gid_to_array_unique(session_info->unix_token,
    1119        1385 :                                      session_info->unix_token->gid,
    1120        1385 :                                      &session_info->unix_token->groups,
    1121        1385 :                                      &session_info->unix_token->ngroups);
    1122        1385 :         if (!ok) {
    1123           0 :                 TALLOC_FREE(frame);
    1124           0 :                 return NT_STATUS_NO_MEMORY;
    1125             :         }
    1126             : 
    1127             :         /* This is a potentially untrusted username for use in %U */
    1128        2770 :         session_info->unix_info->sanitized_username =
    1129        1385 :                 talloc_alpha_strcpy(session_info->unix_info,
    1130             :                                     original_user_name,
    1131             :                                     SAFE_NETBIOS_CHARS "$");
    1132        1385 :         if (session_info->unix_info->sanitized_username == NULL) {
    1133           0 :                 TALLOC_FREE(frame);
    1134           0 :                 return NT_STATUS_NO_MEMORY;
    1135             :         }
    1136             : 
    1137        4322 :         for (i=0; i < session_info->security_token->num_sids; i++) {
    1138             : 
    1139        2937 :                 if (ids[i].type != ID_TYPE_GID &&
    1140        1829 :                     ids[i].type != ID_TYPE_BOTH) {
    1141        1345 :                         struct security_token *nt_token =
    1142        1345 :                                 session_info->security_token;
    1143           0 :                         struct dom_sid_buf buf;
    1144             : 
    1145        1345 :                         DEBUG(10, ("Could not convert SID %s to gid, "
    1146             :                                    "ignoring it\n",
    1147             :                                    dom_sid_str_buf(&nt_token->sids[i], &buf)));
    1148        1345 :                         continue;
    1149             :                 }
    1150             : 
    1151        1592 :                 ok = add_gid_to_array_unique(session_info->unix_token,
    1152        1592 :                                              ids[i].id,
    1153        1592 :                                              &session_info->unix_token->groups,
    1154        1592 :                                              &session_info->unix_token->ngroups);
    1155        1592 :                 if (!ok) {
    1156           0 :                         TALLOC_FREE(frame);
    1157           0 :                         return NT_STATUS_NO_MEMORY;
    1158             :                 }
    1159             :         }
    1160        1385 :         TALLOC_FREE(ids);
    1161             : 
    1162             :         /*
    1163             :          * Now we must get any groups this user has been
    1164             :          * added to in /etc/group and merge them in.
    1165             :          * This has to be done in every code path
    1166             :          * that creates an NT token, as remote users
    1167             :          * may have been added to the local /etc/group
    1168             :          * database. Tokens created merely from the
    1169             :          * info3 structs (via the DC or via the krb5 PAC)
    1170             :          * won't have these local groups. Note the
    1171             :          * groups added here will only be UNIX groups
    1172             :          * (S-1-22-2-XXXX groups) as getgroups_unix_user()
    1173             :          * turns off winbindd before calling getgroups().
    1174             :          *
    1175             :          * NB. This is duplicating work already
    1176             :          * done in the 'unix_user:' case of
    1177             :          * create_token_from_sid() but won't
    1178             :          * do anything other than be inefficient
    1179             :          * in that case.
    1180             :          */
    1181        1385 :         if (!(hint_flags & AUTH3_UNIX_HINT_DONT_EXPAND_UNIX_GROUPS)) {
    1182         776 :                 ok = getgroups_unix_user(frame,
    1183         776 :                                          session_info->unix_info->unix_name,
    1184         776 :                                          session_info->unix_token->gid,
    1185             :                                          &gids, &num_gids);
    1186         776 :                 if (!ok) {
    1187           0 :                         TALLOC_FREE(frame);
    1188           0 :                         return NT_STATUS_INVALID_TOKEN;
    1189             :                 }
    1190             :         }
    1191             : 
    1192        2937 :         for (i=0; i < num_gids; i++) {
    1193             : 
    1194        1552 :                 ok = add_gid_to_array_unique(session_info->unix_token,
    1195        1552 :                                              gids[i],
    1196        1552 :                                              &session_info->unix_token->groups,
    1197        1552 :                                              &session_info->unix_token->ngroups);
    1198        1552 :                 if (!ok) {
    1199           0 :                         TALLOC_FREE(frame);
    1200           0 :                         return NT_STATUS_NO_MEMORY;
    1201             :                 }
    1202             :         }
    1203        1385 :         TALLOC_FREE(gids);
    1204             : 
    1205        1385 :         if (hint_flags & AUTH3_UNIX_HINT_DONT_TRANSLATE_TO_SIDS) {
    1206             :                 /*
    1207             :                  * We should not translate the unix token uid/gids
    1208             :                  * to S-1-22-X-Y SIDs.
    1209             :                  */
    1210         609 :                 goto done;
    1211             :         }
    1212             : 
    1213             :         /*
    1214             :          * Add the "Unix Group" SID for each gid to catch mapped groups
    1215             :          * and their Unix equivalent.  This is to solve the backwards
    1216             :          * compatibility problem of 'valid users = +ntadmin' where
    1217             :          * ntadmin has been paired with "Domain Admins" in the group
    1218             :          * mapping table.  Otherwise smb.conf would need to be changed
    1219             :          * to 'valid user = "Domain Admins"'.  --jerry
    1220             :          *
    1221             :          * For consistency we also add the "Unix User" SID,
    1222             :          * so that the complete unix token is represented within
    1223             :          * the nt token.
    1224             :          */
    1225             : 
    1226         776 :         uid_to_unix_users_sid(session_info->unix_token->uid, &tmp_sid);
    1227         776 :         status = add_sid_to_array_unique(session_info->security_token, &tmp_sid,
    1228         776 :                                          &session_info->security_token->sids,
    1229         776 :                                          &session_info->security_token->num_sids);
    1230         776 :         if (!NT_STATUS_IS_OK(status)) {
    1231           0 :                 TALLOC_FREE(frame);
    1232           0 :                 return status;
    1233             :         }
    1234             : 
    1235         776 :         gid_to_unix_groups_sid(session_info->unix_token->gid, &tmp_sid);
    1236         776 :         status = add_sid_to_array_unique(session_info->security_token, &tmp_sid,
    1237         776 :                                          &session_info->security_token->sids,
    1238         776 :                                          &session_info->security_token->num_sids);
    1239         776 :         if (!NT_STATUS_IS_OK(status)) {
    1240           0 :                 TALLOC_FREE(frame);
    1241           0 :                 return status;
    1242             :         }
    1243             : 
    1244        3920 :         for (i=0; i < session_info->unix_token->ngroups; i++ ) {
    1245        3144 :                 struct security_token *nt_token = session_info->security_token;
    1246             : 
    1247        3144 :                 gid_to_unix_groups_sid(session_info->unix_token->groups[i],
    1248             :                                        &tmp_sid);
    1249        3144 :                 status = add_sid_to_array_unique(nt_token->sids,
    1250             :                                                  &tmp_sid,
    1251             :                                                  &nt_token->sids,
    1252             :                                                  &nt_token->num_sids);
    1253        3144 :                 if (!NT_STATUS_IS_OK(status)) {
    1254           0 :                         TALLOC_FREE(frame);
    1255           0 :                         return status;
    1256             :                 }
    1257             :         }
    1258             : 
    1259         776 : done:
    1260        1385 :         security_token_debug(DBGC_AUTH, 10, session_info->security_token);
    1261        1385 :         if (session_info->unix_token != NULL) {
    1262        1385 :                 debug_unix_user_token(DBGC_AUTH, 10,
    1263        1385 :                                       session_info->unix_token->uid,
    1264        1385 :                                       session_info->unix_token->gid,
    1265        1385 :                                       session_info->unix_token->ngroups,
    1266        1385 :                                       session_info->unix_token->groups);
    1267             :         }
    1268             : 
    1269        1385 :         status = log_nt_token(session_info->security_token);
    1270        1385 :         if (!NT_STATUS_IS_OK(status)) {
    1271           0 :                 TALLOC_FREE(frame);
    1272           0 :                 return status;
    1273             :         }
    1274             : 
    1275        1385 :         session_info->unique_session_token = GUID_random();
    1276             : 
    1277        1385 :         *session_info_out = talloc_move(mem_ctx, &session_info);
    1278        1385 :         TALLOC_FREE(frame);
    1279        1385 :         return NT_STATUS_OK;
    1280             : }
    1281             : 
    1282             : /***************************************************************************
    1283             :  Make (and fill) a server_info struct from a 'struct passwd' by conversion
    1284             :  to a struct samu
    1285             : ***************************************************************************/
    1286             : 
    1287         256 : NTSTATUS make_server_info_pw(TALLOC_CTX *mem_ctx,
    1288             :                              const char *unix_username,
    1289             :                              const struct passwd *pwd,
    1290             :                              struct auth_serversupplied_info **server_info)
    1291             : {
    1292           0 :         NTSTATUS status;
    1293         256 :         TALLOC_CTX *tmp_ctx = NULL;
    1294           0 :         struct auth_serversupplied_info *result;
    1295             : 
    1296         256 :         tmp_ctx = talloc_stackframe();
    1297         256 :         if (tmp_ctx == NULL) {
    1298           0 :                 return NT_STATUS_NO_MEMORY;
    1299             :         }
    1300             : 
    1301         256 :         result = make_server_info(tmp_ctx);
    1302         256 :         if (result == NULL) {
    1303           0 :                 status = NT_STATUS_NO_MEMORY;
    1304           0 :                 goto done;
    1305             :         }
    1306             : 
    1307         256 :         status = passwd_to_SamInfo3(result,
    1308             :                                     unix_username,
    1309             :                                     pwd,
    1310         256 :                                     &result->info3,
    1311         256 :                                     &result->extra);
    1312         256 :         if (!NT_STATUS_IS_OK(status)) {
    1313           0 :                 goto done;
    1314             :         }
    1315             : 
    1316         256 :         result->unix_name = talloc_strdup(result, unix_username);
    1317         256 :         if (result->unix_name == NULL) {
    1318           0 :                 status = NT_STATUS_NO_MEMORY;
    1319           0 :                 goto done;
    1320             :         }
    1321             : 
    1322         256 :         result->utok.uid = pwd->pw_uid;
    1323         256 :         result->utok.gid = pwd->pw_gid;
    1324             : 
    1325         256 :         *server_info = talloc_move(mem_ctx, &result);
    1326         256 :         status = NT_STATUS_OK;
    1327         256 : done:
    1328         256 :         talloc_free(tmp_ctx);
    1329             : 
    1330         256 :         return status;
    1331             : }
    1332             : 
    1333         776 : static NTSTATUS get_guest_info3(TALLOC_CTX *mem_ctx,
    1334             :                                 struct netr_SamInfo3 *info3)
    1335             : {
    1336         776 :         const char *guest_account = lp_guest_account();
    1337           0 :         struct dom_sid domain_sid;
    1338           0 :         struct passwd *pwd;
    1339           0 :         const char *tmp;
    1340             : 
    1341         776 :         pwd = Get_Pwnam_alloc(mem_ctx, guest_account);
    1342         776 :         if (pwd == NULL) {
    1343           0 :                 DEBUG(0,("SamInfo3_for_guest: Unable to locate guest "
    1344             :                          "account [%s]!\n", guest_account));
    1345           0 :                 return NT_STATUS_NO_SUCH_USER;
    1346             :         }
    1347             : 
    1348             :         /* Set account name */
    1349         776 :         tmp = talloc_strdup(mem_ctx, pwd->pw_name);
    1350         776 :         if (tmp == NULL) {
    1351           0 :                 return NT_STATUS_NO_MEMORY;
    1352             :         }
    1353         776 :         init_lsa_String(&info3->base.account_name, tmp);
    1354             : 
    1355             :         /* Set domain name */
    1356         776 :         tmp = talloc_strdup(mem_ctx, get_global_sam_name());
    1357         776 :         if (tmp == NULL) {
    1358           0 :                 return NT_STATUS_NO_MEMORY;
    1359             :         }
    1360         776 :         init_lsa_StringLarge(&info3->base.logon_domain, tmp);
    1361             : 
    1362             :         /* Domain sid */
    1363         776 :         sid_copy(&domain_sid, get_global_sam_sid());
    1364             : 
    1365         776 :         info3->base.domain_sid = dom_sid_dup(mem_ctx, &domain_sid);
    1366         776 :         if (info3->base.domain_sid == NULL) {
    1367           0 :                 return NT_STATUS_NO_MEMORY;
    1368             :         }
    1369             : 
    1370             :         /* Guest rid */
    1371         776 :         info3->base.rid = DOMAIN_RID_GUEST;
    1372             : 
    1373             :         /* Primary gid */
    1374         776 :         info3->base.primary_gid = DOMAIN_RID_GUESTS;
    1375             : 
    1376             :         /* Set as guest */
    1377         776 :         info3->base.user_flags = NETLOGON_GUEST;
    1378             : 
    1379         776 :         TALLOC_FREE(pwd);
    1380         776 :         return NT_STATUS_OK;
    1381             : }
    1382             : 
    1383             : /***************************************************************************
    1384             :  Make (and fill) a user_info struct for a guest login.
    1385             :  This *must* succeed for smbd to start. If there is no mapping entry for
    1386             :  the guest gid, then create one.
    1387             : 
    1388             :  The resulting structure is a 'session_info' because
    1389             :  create_local_token() has already been called on it.  This is quite
    1390             :  nasty, as the auth subsystem isn't expect this, but the behavior is
    1391             :  left as-is for now.
    1392             : ***************************************************************************/
    1393             : 
    1394         776 : static NTSTATUS make_new_session_info_guest(TALLOC_CTX *mem_ctx,
    1395             :                 struct auth_session_info **_session_info,
    1396             :                 struct auth_serversupplied_info **_server_info)
    1397             : {
    1398         776 :         struct auth_session_info *session_info = NULL;
    1399         776 :         struct auth_serversupplied_info *server_info = NULL;
    1400         776 :         const char *guest_account = lp_guest_account();
    1401         776 :         const char *domain = lp_netbios_name();
    1402           0 :         struct netr_SamInfo3 info3;
    1403           0 :         TALLOC_CTX *tmp_ctx;
    1404           0 :         NTSTATUS status;
    1405             : 
    1406         776 :         tmp_ctx = talloc_stackframe();
    1407         776 :         if (tmp_ctx == NULL) {
    1408           0 :                 return NT_STATUS_NO_MEMORY;
    1409             :         }
    1410             : 
    1411         776 :         ZERO_STRUCT(info3);
    1412             : 
    1413         776 :         status = get_guest_info3(tmp_ctx, &info3);
    1414         776 :         if (!NT_STATUS_IS_OK(status)) {
    1415           0 :                 DEBUG(0, ("get_guest_info3 failed with %s\n",
    1416             :                           nt_errstr(status)));
    1417           0 :                 goto done;
    1418             :         }
    1419             : 
    1420         776 :         status = make_server_info_info3(tmp_ctx,
    1421             :                                         guest_account,
    1422             :                                         domain,
    1423             :                                         &server_info,
    1424             :                                         &info3);
    1425         776 :         if (!NT_STATUS_IS_OK(status)) {
    1426           0 :                 DEBUG(0, ("make_server_info_info3 failed with %s\n",
    1427             :                           nt_errstr(status)));
    1428           0 :                 goto done;
    1429             :         }
    1430             : 
    1431         776 :         server_info->guest = true;
    1432             : 
    1433             :         /* This should not be done here (we should produce a server
    1434             :          * info, and later construct a session info from it), but for
    1435             :          * now this does not change the previous behavior */
    1436         776 :         status = create_local_token(tmp_ctx, server_info, NULL,
    1437         776 :                                     server_info->info3->base.account_name.string,
    1438             :                                     &session_info);
    1439         776 :         if (!NT_STATUS_IS_OK(status)) {
    1440           0 :                 DEBUG(0, ("create_local_token failed: %s\n",
    1441             :                           nt_errstr(status)));
    1442           0 :                 goto done;
    1443             :         }
    1444             : 
    1445             :         /*
    1446             :          * It's ugly, but for now it's
    1447             :          * needed to force Builtin_Guests
    1448             :          * here, because memberships of
    1449             :          * Builtin_Guests might be incomplete.
    1450             :          */
    1451         776 :         status = add_sid_to_array_unique(session_info->security_token,
    1452             :                                          &global_sid_Builtin_Guests,
    1453         776 :                                          &session_info->security_token->sids,
    1454         776 :                                          &session_info->security_token->num_sids);
    1455         776 :         if (!NT_STATUS_IS_OK(status)) {
    1456           0 :                 DBG_ERR("Failed to force Builtin_Guests to nt token\n");
    1457           0 :                 goto done;
    1458             :         }
    1459             : 
    1460             :         /* annoying, but the Guest really does have a session key, and it is
    1461             :            all zeros! */
    1462         776 :         session_info->session_key = data_blob_talloc_zero(session_info, 16);
    1463             : 
    1464         776 :         *_session_info = talloc_move(mem_ctx, &session_info);
    1465         776 :         *_server_info = talloc_move(mem_ctx, &server_info);
    1466             : 
    1467         776 :         status = NT_STATUS_OK;
    1468         776 : done:
    1469         776 :         TALLOC_FREE(tmp_ctx);
    1470         776 :         return status;
    1471             : }
    1472             : 
    1473             : /***************************************************************************
    1474             :  Make (and fill) a auth_session_info struct for a system user login.
    1475             :  This *must* succeed for smbd to start.
    1476             : ***************************************************************************/
    1477             : 
    1478         609 : static NTSTATUS make_new_session_info_system(TALLOC_CTX *mem_ctx,
    1479             :                                             struct auth_session_info **session_info)
    1480             : {
    1481         609 :         TALLOC_CTX *frame = talloc_stackframe();
    1482         609 :         struct auth_user_info_dc *user_info_dc = NULL;
    1483         609 :         uid_t uid = -1;
    1484         609 :         gid_t gid = -1;
    1485         609 :         uint32_t hint_flags = 0;
    1486         609 :         uint32_t session_info_flags = 0;
    1487           0 :         NTSTATUS status;
    1488             : 
    1489         609 :         status = auth_system_user_info_dc(frame, lp_netbios_name(),
    1490             :                                           &user_info_dc);
    1491         609 :         if (!NT_STATUS_IS_OK(status)) {
    1492           0 :                 DEBUG(0, ("auth_system_user_info_dc failed: %s\n",
    1493             :                           nt_errstr(status)));
    1494           0 :                 goto done;
    1495             :         }
    1496             : 
    1497             :         /*
    1498             :          * Just get the initial uid/gid
    1499             :          * and don't expand the unix groups.
    1500             :          */
    1501         609 :         uid = sec_initial_uid();
    1502         609 :         gid = sec_initial_gid();
    1503         609 :         hint_flags |= AUTH3_UNIX_HINT_DONT_EXPAND_UNIX_GROUPS;
    1504             : 
    1505             :         /*
    1506             :          * Also avoid sid mapping to gids,
    1507             :          * as well as adding the unix_token uid/gids as
    1508             :          * S-1-22-X-Y SIDs to the nt token.
    1509             :          */
    1510         609 :         hint_flags |= AUTH3_UNIX_HINT_DONT_TRANSLATE_FROM_SIDS;
    1511         609 :         hint_flags |= AUTH3_UNIX_HINT_DONT_TRANSLATE_TO_SIDS;
    1512             : 
    1513             :         /*
    1514             :          * The unix name will be "NT AUTHORITY+SYSTEM",
    1515             :          * where '+' is the "winbind separator" character.
    1516             :          */
    1517         609 :         hint_flags |= AUTH3_UNIX_HINT_QUALIFIED_NAME;
    1518         609 :         status = auth3_user_info_dc_add_hints(user_info_dc,
    1519             :                                               uid,
    1520             :                                               gid,
    1521             :                                               hint_flags);
    1522         609 :         if (!NT_STATUS_IS_OK(status)) {
    1523           0 :                 DEBUG(0, ("auth3_user_info_dc_add_hints failed: %s\n",
    1524             :                           nt_errstr(status)));
    1525           0 :                 goto done;
    1526             :         }
    1527             : 
    1528         609 :         session_info_flags |= AUTH_SESSION_INFO_SIMPLE_PRIVILEGES;
    1529         609 :         session_info_flags |= AUTH_SESSION_INFO_UNIX_TOKEN;
    1530         609 :         status = auth3_session_info_create(mem_ctx, user_info_dc,
    1531         609 :                                            user_info_dc->info->account_name,
    1532             :                                            session_info_flags,
    1533             :                                            session_info);
    1534         609 :         if (!NT_STATUS_IS_OK(status)) {
    1535           0 :                 DEBUG(0, ("auth3_session_info_create failed: %s\n",
    1536             :                           nt_errstr(status)));
    1537           0 :                 goto done;
    1538             :         }
    1539             : 
    1540         609 : done:
    1541         609 :         TALLOC_FREE(frame);
    1542         609 :         return status;
    1543             : }
    1544             : 
    1545         776 : static NTSTATUS make_new_session_info_anonymous(TALLOC_CTX *mem_ctx,
    1546             :                                         struct auth_session_info **session_info)
    1547             : {
    1548         776 :         TALLOC_CTX *frame = talloc_stackframe();
    1549         776 :         const char *guest_account = lp_guest_account();
    1550         776 :         struct auth_user_info_dc *user_info_dc = NULL;
    1551         776 :         struct passwd *pwd = NULL;
    1552         776 :         uint32_t hint_flags = 0;
    1553         776 :         uint32_t session_info_flags = 0;
    1554           0 :         NTSTATUS status;
    1555             : 
    1556             :         /*
    1557             :          * We use the guest account for the unix token
    1558             :          * while we use a true anonymous nt token.
    1559             :          *
    1560             :          * It's very important to have a separate
    1561             :          * nt token for anonymous.
    1562             :          */
    1563             : 
    1564         776 :         pwd = Get_Pwnam_alloc(frame, guest_account);
    1565         776 :         if (pwd == NULL) {
    1566           0 :                 DBG_ERR("Unable to locate guest account [%s]!\n",
    1567             :                         guest_account);
    1568           0 :                 status = NT_STATUS_NO_SUCH_USER;
    1569           0 :                 goto done;
    1570             :         }
    1571             : 
    1572         776 :         status = auth_anonymous_user_info_dc(frame, lp_netbios_name(),
    1573             :                                              &user_info_dc);
    1574         776 :         if (!NT_STATUS_IS_OK(status)) {
    1575           0 :                 DEBUG(0, ("auth_anonymous_user_info_dc failed: %s\n",
    1576             :                           nt_errstr(status)));
    1577           0 :                 goto done;
    1578             :         }
    1579             : 
    1580             :         /*
    1581             :          * Note we don't pass AUTH3_UNIX_HINT_QUALIFIED_NAME
    1582             :          * nor AUTH3_UNIX_HINT_ISOLATED_NAME here
    1583             :          * as we want the unix name be found by getpwuid_alloc().
    1584             :          */
    1585             : 
    1586         776 :         status = auth3_user_info_dc_add_hints(user_info_dc,
    1587             :                                               pwd->pw_uid,
    1588             :                                               pwd->pw_gid,
    1589             :                                               hint_flags);
    1590         776 :         if (!NT_STATUS_IS_OK(status)) {
    1591           0 :                 DEBUG(0, ("auth3_user_info_dc_add_hints failed: %s\n",
    1592             :                           nt_errstr(status)));
    1593           0 :                 goto done;
    1594             :         }
    1595             : 
    1596             :         /*
    1597             :          * In future we may want to remove
    1598             :          * AUTH_SESSION_INFO_DEFAULT_GROUPS.
    1599             :          *
    1600             :          * Similar to Windows with EveryoneIncludesAnonymous
    1601             :          * and RestrictAnonymous.
    1602             :          *
    1603             :          * We may introduce AUTH_SESSION_INFO_ANON_WORLD...
    1604             :          *
    1605             :          * But for this is required to keep the existing tests
    1606             :          * working.
    1607             :          */
    1608         776 :         session_info_flags |= AUTH_SESSION_INFO_DEFAULT_GROUPS;
    1609         776 :         session_info_flags |= AUTH_SESSION_INFO_SIMPLE_PRIVILEGES;
    1610         776 :         session_info_flags |= AUTH_SESSION_INFO_UNIX_TOKEN;
    1611         776 :         status = auth3_session_info_create(mem_ctx, user_info_dc,
    1612             :                                            "",
    1613             :                                            session_info_flags,
    1614             :                                            session_info);
    1615         776 :         if (!NT_STATUS_IS_OK(status)) {
    1616           0 :                 DEBUG(0, ("auth3_session_info_create failed: %s\n",
    1617             :                           nt_errstr(status)));
    1618           0 :                 goto done;
    1619             :         }
    1620             : 
    1621         776 : done:
    1622         776 :         TALLOC_FREE(frame);
    1623         776 :         return status;
    1624             : }
    1625             : 
    1626             : /****************************************************************************
    1627             :   Fake a auth_session_info just from a username (as a
    1628             :   session_info structure, with create_local_token() already called on
    1629             :   it.
    1630             : ****************************************************************************/
    1631             : 
    1632         256 : NTSTATUS make_session_info_from_username(TALLOC_CTX *mem_ctx,
    1633             :                                          const char *username,
    1634             :                                          bool is_guest,
    1635             :                                          struct auth_session_info **session_info)
    1636             : {
    1637           0 :         struct passwd *pwd;
    1638           0 :         NTSTATUS status;
    1639           0 :         struct auth_serversupplied_info *result;
    1640           0 :         TALLOC_CTX *tmp_ctx;
    1641             : 
    1642         256 :         tmp_ctx = talloc_stackframe();
    1643         256 :         if (tmp_ctx == NULL) {
    1644           0 :                 return NT_STATUS_NO_MEMORY;
    1645             :         }
    1646             : 
    1647         256 :         pwd = Get_Pwnam_alloc(tmp_ctx, username);
    1648         256 :         if (pwd == NULL) {
    1649           0 :                 status = NT_STATUS_NO_SUCH_USER;
    1650           0 :                 goto done;
    1651             :         }
    1652             : 
    1653         256 :         status = make_server_info_pw(tmp_ctx, pwd->pw_name, pwd, &result);
    1654         256 :         if (!NT_STATUS_IS_OK(status)) {
    1655           0 :                 goto done;
    1656             :         }
    1657             : 
    1658         256 :         result->nss_token = true;
    1659         256 :         result->guest = is_guest;
    1660             : 
    1661             :         /* Now turn the server_info into a session_info with the full token etc */
    1662         256 :         status = create_local_token(mem_ctx,
    1663             :                                     result,
    1664             :                                     NULL,
    1665         256 :                                     pwd->pw_name,
    1666             :                                     session_info);
    1667             : 
    1668         256 : done:
    1669         256 :         talloc_free(tmp_ctx);
    1670             : 
    1671         256 :         return status;
    1672             : }
    1673             : 
    1674             : /* This function MUST only used to create the cached server_info for
    1675             :  * guest.
    1676             :  *
    1677             :  * This is a lossy conversion.  Variables known to be lost so far
    1678             :  * include:
    1679             :  *
    1680             :  * - nss_token (not needed because the only read doesn't happen
    1681             :  * for the GUEST user, as this routine populates ->security_token
    1682             :  *
    1683             :  * - extra (not needed because the guest account must have valid RIDs per the output of get_guest_info3())
    1684             :  *
    1685             :  * - The 'server_info' parameter allows the missing 'info3' to be copied across.
    1686             :  */
    1687         563 : static struct auth_serversupplied_info *copy_session_info_serverinfo_guest(TALLOC_CTX *mem_ctx,
    1688             :                                                                            const struct auth_session_info *src,
    1689             :                                                                            struct auth_serversupplied_info *server_info)
    1690             : {
    1691           0 :         struct auth_serversupplied_info *dst;
    1692           0 :         NTSTATUS status;
    1693             : 
    1694         563 :         dst = make_server_info(mem_ctx);
    1695         563 :         if (dst == NULL) {
    1696           0 :                 return NULL;
    1697             :         }
    1698             : 
    1699             :         /* This element must be provided to convert back to an auth_serversupplied_info */
    1700         563 :         SMB_ASSERT(src->unix_info);
    1701             : 
    1702         563 :         dst->guest = true;
    1703             : 
    1704             :         /* This element must be provided to convert back to an
    1705             :          * auth_serversupplied_info.  This needs to be from the
    1706             :          * auth_session_info because the group values in particular
    1707             :          * may change during create_local_token() processing */
    1708         563 :         SMB_ASSERT(src->unix_token);
    1709         563 :         dst->utok.uid = src->unix_token->uid;
    1710         563 :         dst->utok.gid = src->unix_token->gid;
    1711         563 :         dst->utok.ngroups = src->unix_token->ngroups;
    1712         563 :         if (src->unix_token->ngroups != 0) {
    1713         563 :                 dst->utok.groups = (gid_t *)talloc_memdup(
    1714             :                         dst, src->unix_token->groups,
    1715             :                         sizeof(gid_t)*dst->utok.ngroups);
    1716             :         } else {
    1717           0 :                 dst->utok.groups = NULL;
    1718             :         }
    1719             : 
    1720             :         /* We must have a security_token as otherwise the lossy
    1721             :          * conversion without nss_token would cause create_local_token
    1722             :          * to take the wrong path */
    1723         563 :         SMB_ASSERT(src->security_token);
    1724             : 
    1725         563 :         dst->session_key = data_blob_talloc( dst, src->session_key.data,
    1726             :                                                 src->session_key.length);
    1727             : 
    1728             :         /* This is OK because this functions is only used for the
    1729             :          * GUEST account, which has all-zero keys for both values */
    1730         563 :         dst->lm_session_key = data_blob_talloc(dst, src->session_key.data,
    1731             :                                                 src->session_key.length);
    1732             : 
    1733         563 :         status = copy_netr_SamInfo3(dst,
    1734         563 :                                     server_info->info3,
    1735             :                                     &dst->info3);
    1736         563 :         if (!NT_STATUS_IS_OK(status)) {
    1737           0 :                 TALLOC_FREE(dst);
    1738           0 :                 return NULL;
    1739             :         }
    1740             : 
    1741         563 :         dst->unix_name = talloc_strdup(dst, src->unix_info->unix_name);
    1742         563 :         if (!dst->unix_name) {
    1743           0 :                 TALLOC_FREE(dst);
    1744           0 :                 return NULL;
    1745             :         }
    1746             : 
    1747         563 :         dst->cached_session_info = src;
    1748         563 :         return dst;
    1749             : }
    1750             : 
    1751             : /*
    1752             :  * Set a new session key. Used in the rpc server where we have to override the
    1753             :  * SMB level session key with SystemLibraryDTC
    1754             :  */
    1755             : 
    1756           0 : bool session_info_set_session_key(struct auth_session_info *info,
    1757             :                                  DATA_BLOB session_key)
    1758             : {
    1759           0 :         TALLOC_FREE(info->session_key.data);
    1760             : 
    1761           0 :         info->session_key = data_blob_talloc(
    1762             :                 info, session_key.data, session_key.length);
    1763             : 
    1764           0 :         return (info->session_key.data != NULL);
    1765             : }
    1766             : 
    1767             : static struct auth_session_info *guest_info = NULL;
    1768             : static struct auth_session_info *anonymous_info = NULL;
    1769             : 
    1770             : static struct auth_serversupplied_info *guest_server_info = NULL;
    1771             : 
    1772         776 : bool init_guest_session_info(TALLOC_CTX *mem_ctx)
    1773             : {
    1774           0 :         NTSTATUS status;
    1775             : 
    1776         776 :         if (guest_info != NULL)
    1777           0 :                 return true;
    1778             : 
    1779         776 :         status = make_new_session_info_guest(mem_ctx,
    1780             :                                              &guest_info,
    1781             :                                              &guest_server_info);
    1782         776 :         if (!NT_STATUS_IS_OK(status)) {
    1783           0 :                 return false;
    1784             :         }
    1785             : 
    1786         776 :         status = make_new_session_info_anonymous(mem_ctx,
    1787             :                                                  &anonymous_info);
    1788         776 :         if (!NT_STATUS_IS_OK(status)) {
    1789           0 :                 return false;
    1790             :         }
    1791             : 
    1792         776 :         return true;
    1793             : }
    1794             : 
    1795          39 : bool reinit_guest_session_info(TALLOC_CTX *mem_ctx)
    1796             : {
    1797          39 :         TALLOC_FREE(guest_info);
    1798          39 :         TALLOC_FREE(guest_server_info);
    1799          39 :         TALLOC_FREE(anonymous_info);
    1800             : 
    1801          39 :         DBG_DEBUG("Reinitialing guest info\n");
    1802             : 
    1803          39 :         return init_guest_session_info(mem_ctx);
    1804             : }
    1805             : 
    1806          29 : NTSTATUS make_server_info_guest(TALLOC_CTX *mem_ctx,
    1807             :                                 struct auth_serversupplied_info **server_info)
    1808             : {
    1809             :         /* This is trickier than it would appear to need to be because
    1810             :          * we are trying to avoid certain costly operations when the
    1811             :          * structure is converted to a 'auth_session_info' again in
    1812             :          * create_local_token() */
    1813          29 :         *server_info = copy_session_info_serverinfo_guest(mem_ctx, guest_info, guest_server_info);
    1814          29 :         return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
    1815             : }
    1816             : 
    1817         140 : NTSTATUS make_session_info_guest(TALLOC_CTX *mem_ctx,
    1818             :                                 struct auth_session_info **session_info)
    1819             : {
    1820         140 :         *session_info = copy_session_info(mem_ctx, guest_info);
    1821         140 :         return (*session_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
    1822             : }
    1823             : 
    1824         534 : NTSTATUS make_server_info_anonymous(TALLOC_CTX *mem_ctx,
    1825             :                                     struct auth_serversupplied_info **server_info)
    1826             : {
    1827         534 :         if (anonymous_info == NULL) {
    1828           0 :                 return NT_STATUS_UNSUCCESSFUL;
    1829             :         }
    1830             : 
    1831             :         /*
    1832             :          * This is trickier than it would appear to need to be because
    1833             :          * we are trying to avoid certain costly operations when the
    1834             :          * structure is converted to a 'auth_session_info' again in
    1835             :          * create_local_token()
    1836             :          *
    1837             :          * We use a guest server_info, but with the anonymous session info,
    1838             :          * which means create_local_token() will return a copy
    1839             :          * of the anonymous token.
    1840             :          *
    1841             :          * The server info is just used as legacy in order to
    1842             :          * keep existing code working. Maybe some debug messages
    1843             :          * will still refer to guest instead of anonymous.
    1844             :          */
    1845         534 :         *server_info = copy_session_info_serverinfo_guest(mem_ctx, anonymous_info,
    1846             :                                                           guest_server_info);
    1847         534 :         if (*server_info == NULL) {
    1848           0 :                 return NT_STATUS_NO_MEMORY;
    1849             :         }
    1850             : 
    1851         534 :         return NT_STATUS_OK;
    1852             : }
    1853             : 
    1854        1026 : NTSTATUS make_session_info_anonymous(TALLOC_CTX *mem_ctx,
    1855             :                                      struct auth_session_info **session_info)
    1856             : {
    1857        1026 :         if (anonymous_info == NULL) {
    1858           0 :                 return NT_STATUS_UNSUCCESSFUL;
    1859             :         }
    1860             : 
    1861        1026 :         *session_info = copy_session_info(mem_ctx, anonymous_info);
    1862        1026 :         if (*session_info == NULL) {
    1863           0 :                 return NT_STATUS_NO_MEMORY;
    1864             :         }
    1865             : 
    1866        1026 :         return NT_STATUS_OK;
    1867             : }
    1868             : 
    1869             : static struct auth_session_info *system_info = NULL;
    1870             : 
    1871         609 : NTSTATUS init_system_session_info(TALLOC_CTX *mem_ctx)
    1872             : {
    1873         609 :         if (system_info != NULL)
    1874           0 :                 return NT_STATUS_OK;
    1875             : 
    1876         609 :         return make_new_session_info_system(mem_ctx, &system_info);
    1877             : }
    1878             : 
    1879         247 : NTSTATUS make_session_info_system(TALLOC_CTX *mem_ctx,
    1880             :                                 struct auth_session_info **session_info)
    1881             : {
    1882         247 :         if (system_info == NULL) return NT_STATUS_UNSUCCESSFUL;
    1883         247 :         *session_info = copy_session_info(mem_ctx, system_info);
    1884         247 :         return (*session_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
    1885             : }
    1886             : 
    1887       28584 : const struct auth_session_info *get_session_info_system(void)
    1888             : {
    1889       28584 :     return system_info;
    1890             : }
    1891             : 
    1892             : /***************************************************************************
    1893             :  Purely internal function for make_server_info_info3
    1894             : ***************************************************************************/
    1895             : 
    1896        1871 : static NTSTATUS check_account(TALLOC_CTX *mem_ctx, const char *domain,
    1897             :                               const char *username,
    1898             :                               const struct dom_sid *sid,
    1899             :                               char **found_username,
    1900             :                               struct passwd **pwd,
    1901             :                               bool *username_was_mapped)
    1902             : {
    1903        1871 :         char *orig_dom_user = NULL;
    1904        1871 :         char *dom_user = NULL;
    1905        1871 :         char *lower_username = NULL;
    1906        1871 :         char *real_username = NULL;
    1907           0 :         struct passwd *passwd;
    1908             : 
    1909        1871 :         lower_username = talloc_strdup(mem_ctx, username);
    1910        1871 :         if (!lower_username) {
    1911           0 :                 return NT_STATUS_NO_MEMORY;
    1912             :         }
    1913        1871 :         if (!strlower_m( lower_username )) {
    1914           0 :                 return NT_STATUS_INVALID_PARAMETER;
    1915             :         }
    1916             : 
    1917        1871 :         orig_dom_user = talloc_asprintf(mem_ctx,
    1918             :                                 "%s%c%s",
    1919             :                                 domain,
    1920        1871 :                                 *lp_winbind_separator(),
    1921             :                                 lower_username);
    1922        1871 :         if (!orig_dom_user) {
    1923           0 :                 return NT_STATUS_NO_MEMORY;
    1924             :         }
    1925             : 
    1926             :         /* Get the passwd struct.  Try to create the account if necessary. */
    1927             : 
    1928        1871 :         *username_was_mapped = map_username(mem_ctx, orig_dom_user, &dom_user);
    1929        1871 :         if (!dom_user) {
    1930           0 :                 return NT_STATUS_NO_MEMORY;
    1931             :         }
    1932             : 
    1933        1871 :         passwd = smb_getpwnam(mem_ctx, dom_user, &real_username, false);
    1934        1871 :         if (!passwd && !*username_was_mapped) {
    1935           0 :                 struct dom_sid_buf buf;
    1936           0 :                 uid_t uid;
    1937           0 :                 bool ok;
    1938             : 
    1939           8 :                 DBG_DEBUG("Failed to find authenticated user %s via "
    1940             :                           "getpwnam(), fallback to sid_to_uid(%s).\n",
    1941             :                           dom_user, dom_sid_str_buf(sid, &buf));
    1942             : 
    1943           8 :                 ok = sid_to_uid(sid, &uid);
    1944           8 :                 if (!ok) {
    1945           4 :                         DBG_ERR("Failed to convert SID %s to a UID (dom_user[%s])\n",
    1946             :                                 dom_sid_str_buf(sid, &buf), dom_user);
    1947           4 :                         return NT_STATUS_NO_SUCH_USER;
    1948             :                 }
    1949           4 :                 passwd = getpwuid_alloc(mem_ctx, uid);
    1950           4 :                 if (!passwd) {
    1951           0 :                         DBG_ERR("Failed to find local account with UID %lld for SID %s (dom_user[%s])\n",
    1952             :                                 (long long)uid,
    1953             :                                 dom_sid_str_buf(sid, &buf),
    1954             :                                 dom_user);
    1955           0 :                         return NT_STATUS_NO_SUCH_USER;
    1956             :                 }
    1957           4 :                 real_username = talloc_strdup(mem_ctx, passwd->pw_name);
    1958             :         }
    1959        1867 :         if (!passwd) {
    1960           0 :                 DEBUG(3, ("Failed to find authenticated user %s via "
    1961             :                           "getpwnam(), denying access.\n", dom_user));
    1962           0 :                 return NT_STATUS_NO_SUCH_USER;
    1963             :         }
    1964             : 
    1965        1867 :         if (!real_username) {
    1966           0 :                 return NT_STATUS_NO_MEMORY;
    1967             :         }
    1968             : 
    1969        1867 :         *pwd = passwd;
    1970             : 
    1971             :         /* This is pointless -- there is no support for differing
    1972             :            unix and windows names.  Make sure to always store the
    1973             :            one we actually looked up and succeeded. Have I mentioned
    1974             :            why I hate the 'winbind use default domain' parameter?
    1975             :                                          --jerry              */
    1976             : 
    1977        1867 :         *found_username = talloc_strdup( mem_ctx, real_username );
    1978             : 
    1979        1867 :         return NT_STATUS_OK;
    1980             : }
    1981             : 
    1982             : /****************************************************************************
    1983             :  Wrapper to allow the getpwnam() call to strip the domain name and
    1984             :  try again in case a local UNIX user is already there.  Also run through
    1985             :  the username if we fallback to the username only.
    1986             :  ****************************************************************************/
    1987             : 
    1988        1871 : struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, const char *domuser,
    1989             :                              char **p_save_username, bool create )
    1990             : {
    1991        1871 :         struct passwd *pw = NULL;
    1992        1871 :         char *p = NULL;
    1993        1871 :         const char *username = NULL;
    1994             : 
    1995             :         /* we only save a copy of the username it has been mangled
    1996             :            by winbindd use default domain */
    1997        1871 :         *p_save_username = NULL;
    1998             : 
    1999             :         /* don't call map_username() here since it has to be done higher
    2000             :            up the stack so we don't call it multiple times */
    2001             : 
    2002        1871 :         username = talloc_strdup(mem_ctx, domuser);
    2003        1871 :         if (!username) {
    2004           0 :                 return NULL;
    2005             :         }
    2006             : 
    2007        1871 :         p = strchr_m( username, *lp_winbind_separator() );
    2008             : 
    2009             :         /* code for a DOMAIN\user string */
    2010             : 
    2011        1871 :         if ( p ) {
    2012        1855 :                 const char *domain = NULL;
    2013             : 
    2014             :                 /* split the domain and username into 2 strings */
    2015        1855 :                 *p = '\0';
    2016        1855 :                 domain = username;
    2017        1855 :                 p++;
    2018        1855 :                 username = p;
    2019             : 
    2020        1855 :                 if (strequal(domain, get_global_sam_name())) {
    2021             :                         /*
    2022             :                          * This typically don't happen
    2023             :                          * as check_sam_Security()
    2024             :                          * don't call make_server_info_info3()
    2025             :                          * and thus check_account().
    2026             :                          *
    2027             :                          * But we better keep this.
    2028             :                          */
    2029         777 :                         goto username_only;
    2030             :                 }
    2031             : 
    2032        1078 :                 pw = Get_Pwnam_alloc( mem_ctx, domuser );
    2033        1078 :                 if (pw == NULL) {
    2034           8 :                         return NULL;
    2035             :                 }
    2036             :                 /* make sure we get the case of the username correct */
    2037             :                 /* work around 'winbind use default domain = yes' */
    2038             : 
    2039        1070 :                 if ( lp_winbind_use_default_domain() &&
    2040           0 :                      !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
    2041           0 :                         *p_save_username = talloc_asprintf(mem_ctx,
    2042             :                                                         "%s%c%s",
    2043             :                                                         domain,
    2044           0 :                                                         *lp_winbind_separator(),
    2045             :                                                         pw->pw_name);
    2046           0 :                         if (!*p_save_username) {
    2047           0 :                                 TALLOC_FREE(pw);
    2048           0 :                                 return NULL;
    2049             :                         }
    2050             :                 } else {
    2051        1070 :                         *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
    2052             :                 }
    2053             : 
    2054             :                 /* whew -- done! */
    2055        1070 :                 return pw;
    2056             : 
    2057             :         }
    2058             : 
    2059             :         /* just lookup a plain username */
    2060          16 : username_only:
    2061         793 :         pw = Get_Pwnam_alloc(mem_ctx, username);
    2062             : 
    2063             :         /* Create local user if requested but only if winbindd
    2064             :            is not running.  We need to protect against cases
    2065             :            where winbindd is failing and then prematurely
    2066             :            creating users in /etc/passwd */
    2067             : 
    2068         793 :         if ( !pw && create && !winbind_ping() ) {
    2069             :                 /* Don't add a machine account. */
    2070           0 :                 if (username[strlen(username)-1] == '$')
    2071           0 :                         return NULL;
    2072             : 
    2073           0 :                 _smb_create_user(NULL, username, NULL);
    2074           0 :                 pw = Get_Pwnam_alloc(mem_ctx, username);
    2075             :         }
    2076             : 
    2077             :         /* one last check for a valid passwd struct */
    2078             : 
    2079         793 :         if (pw) {
    2080         793 :                 *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
    2081             :         }
    2082         793 :         return pw;
    2083             : }
    2084             : 
    2085             : /***************************************************************************
    2086             :  Make a server_info struct from the info3 returned by a domain logon
    2087             : ***************************************************************************/
    2088             : 
    2089        1871 : NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
    2090             :                                 const char *sent_nt_username,
    2091             :                                 const char *domain,
    2092             :                                 struct auth_serversupplied_info **server_info,
    2093             :                                 const struct netr_SamInfo3 *info3)
    2094             : {
    2095           0 :         NTSTATUS nt_status;
    2096        1871 :         char *found_username = NULL;
    2097           0 :         const char *nt_domain;
    2098           0 :         const char *nt_username;
    2099           0 :         struct dom_sid user_sid;
    2100           0 :         struct dom_sid group_sid;
    2101           0 :         bool username_was_mapped;
    2102           0 :         struct passwd *pwd;
    2103           0 :         struct auth_serversupplied_info *result;
    2104           0 :         struct dom_sid sid;
    2105        1871 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
    2106             : 
    2107             :         /*
    2108             :            Here is where we should check the list of
    2109             :            trusted domains, and verify that the SID
    2110             :            matches.
    2111             :         */
    2112             : 
    2113        1871 :         if (!sid_compose(&user_sid, info3->base.domain_sid, info3->base.rid)) {
    2114           0 :                 nt_status = NT_STATUS_INVALID_PARAMETER;
    2115           0 :                 goto out;
    2116             :         }
    2117             : 
    2118        1871 :         if (!sid_compose(&group_sid, info3->base.domain_sid,
    2119        1871 :                          info3->base.primary_gid)) {
    2120           0 :                 nt_status = NT_STATUS_INVALID_PARAMETER;
    2121           0 :                 goto out;
    2122             :         }
    2123             : 
    2124        1871 :         nt_username = talloc_strdup(tmp_ctx, info3->base.account_name.string);
    2125        1871 :         if (!nt_username) {
    2126             :                 /* If the server didn't give us one, just use the one we sent
    2127             :                  * them */
    2128           0 :                 nt_username = sent_nt_username;
    2129             :         }
    2130             : 
    2131        1871 :         nt_domain = talloc_strdup(mem_ctx, info3->base.logon_domain.string);
    2132        1871 :         if (!nt_domain) {
    2133             :                 /* If the server didn't give us one, just use the one we sent
    2134             :                  * them */
    2135           0 :                 nt_domain = domain;
    2136             :         }
    2137             : 
    2138             :         /* If getpwnam() fails try the add user script (2.2.x behavior).
    2139             : 
    2140             :            We use the _unmapped_ username here in an attempt to provide
    2141             :            consistent username mapping behavior between kerberos and NTLM[SSP]
    2142             :            authentication in domain mode security.  I.E. Username mapping
    2143             :            should be applied to the fully qualified username
    2144             :            (e.g. DOMAIN\user) and not just the login name.  Yes this means we
    2145             :            called map_username() unnecessarily in make_user_info_map() but
    2146             :            that is how the current code is designed.  Making the change here
    2147             :            is the least disruptive place.  -- jerry */
    2148             : 
    2149             :         /* this call will try to create the user if necessary */
    2150             : 
    2151        1871 :         sid_copy(&sid, info3->base.domain_sid);
    2152        1871 :         sid_append_rid(&sid, info3->base.rid);
    2153             : 
    2154        1871 :         nt_status = check_account(tmp_ctx,
    2155             :                                   nt_domain,
    2156             :                                   nt_username,
    2157             :                                   &sid,
    2158             :                                   &found_username,
    2159             :                                   &pwd,
    2160             :                                   &username_was_mapped);
    2161             : 
    2162        1871 :         if (!NT_STATUS_IS_OK(nt_status)) {
    2163             :                 /* Handle 'map to guest = Bad Uid */
    2164           8 :                 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) &&
    2165           8 :                     (lp_security() == SEC_ADS || lp_security() == SEC_DOMAIN) &&
    2166           4 :                     lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID) {
    2167           0 :                         DBG_NOTICE("Try to map %s to guest account\n",
    2168             :                                    nt_username);
    2169           0 :                         nt_status = make_server_info_guest(tmp_ctx, &result);
    2170           0 :                         if (NT_STATUS_IS_OK(nt_status)) {
    2171           0 :                                 *server_info = talloc_move(mem_ctx, &result);
    2172             :                         }
    2173             :                 }
    2174           4 :                 goto out;
    2175        1867 :         } else if ((lp_security() == SEC_ADS || lp_security() == SEC_DOMAIN) &&
    2176        1249 :                    !is_myname(domain) && pwd->pw_uid < lp_min_domain_uid()) {
    2177             :                 /*
    2178             :                  * !is_myname(domain) because when smbd starts tries to setup
    2179             :                  * the guest user info, calling this function with nobody
    2180             :                  * username. Nobody is usually uid 65535 but it can be changed
    2181             :                  * to a regular user with 'guest account' parameter
    2182             :                  */
    2183           4 :                 nt_status = NT_STATUS_INVALID_TOKEN;
    2184           4 :                 DBG_NOTICE("Username '%s%s%s' is invalid on this system, "
    2185             :                            "it does not meet 'min domain uid' "
    2186             :                            "restriction (%u < %u): %s\n",
    2187             :                            nt_domain, lp_winbind_separator(), nt_username,
    2188             :                            pwd->pw_uid, lp_min_domain_uid(),
    2189             :                            nt_errstr(nt_status));
    2190           4 :                 goto out;
    2191             :         }
    2192             : 
    2193        1863 :         result = make_server_info(tmp_ctx);
    2194        1863 :         if (result == NULL) {
    2195           0 :                 DEBUG(4, ("make_server_info failed!\n"));
    2196           0 :                 nt_status = NT_STATUS_NO_MEMORY;
    2197           0 :                 goto out;
    2198             :         }
    2199             : 
    2200        1863 :         result->unix_name = talloc_strdup(result, found_username);
    2201             : 
    2202             :         /* copy in the info3 */
    2203        1863 :         nt_status = copy_netr_SamInfo3(result,
    2204             :                                        info3,
    2205        1863 :                                        &result->info3);
    2206        1863 :         if (!NT_STATUS_IS_OK(nt_status)) {
    2207           0 :                 goto out;
    2208             :         }
    2209             : 
    2210             :         /* Fill in the unix info we found on the way */
    2211             : 
    2212        1863 :         result->utok.uid = pwd->pw_uid;
    2213        1863 :         result->utok.gid = pwd->pw_gid;
    2214             : 
    2215             :         /* ensure we are never given NULL session keys */
    2216             : 
    2217        1863 :         if (all_zero(info3->base.key.key, sizeof(info3->base.key.key))) {
    2218        1634 :                 result->session_key = data_blob_null;
    2219             :         } else {
    2220         229 :                 result->session_key = data_blob_talloc(
    2221             :                         result, info3->base.key.key,
    2222             :                         sizeof(info3->base.key.key));
    2223             :         }
    2224             : 
    2225        1863 :         if (all_zero(info3->base.LMSessKey.key,
    2226             :                      sizeof(info3->base.LMSessKey.key))) {
    2227        1639 :                 result->lm_session_key = data_blob_null;
    2228             :         } else {
    2229         224 :                 result->lm_session_key = data_blob_talloc(
    2230             :                         result, info3->base.LMSessKey.key,
    2231             :                         sizeof(info3->base.LMSessKey.key));
    2232             :         }
    2233             : 
    2234        1863 :         result->nss_token |= username_was_mapped;
    2235             : 
    2236        1863 :         result->guest = (info3->base.user_flags & NETLOGON_GUEST);
    2237             : 
    2238        1863 :         *server_info = talloc_move(mem_ctx, &result);
    2239             : 
    2240        1863 :         nt_status = NT_STATUS_OK;
    2241        1871 : out:
    2242        1871 :         talloc_free(tmp_ctx);
    2243             : 
    2244        1871 :         return nt_status;
    2245             : }
    2246             : 
    2247             : /*****************************************************************************
    2248             :  Make a server_info struct from the wbcAuthUserInfo returned by a domain logon
    2249             : ******************************************************************************/
    2250             : 
    2251        1094 : NTSTATUS make_server_info_wbcAuthUserInfo(TALLOC_CTX *mem_ctx,
    2252             :                                           const char *sent_nt_username,
    2253             :                                           const char *domain,
    2254             :                                           const struct wbcAuthUserInfo *info,
    2255             :                                           struct auth_serversupplied_info **server_info)
    2256             : {
    2257           0 :         struct netr_SamInfo3 info3;
    2258           0 :         struct netr_SamInfo6 *info6;
    2259             : 
    2260        1094 :         info6 = wbcAuthUserInfo_to_netr_SamInfo6(mem_ctx, info);
    2261        1094 :         if (!info6) {
    2262           0 :                 return NT_STATUS_NO_MEMORY;
    2263             :         }
    2264             : 
    2265        1094 :         info3.base = info6->base;
    2266        1094 :         info3.sidcount = info6->sidcount;
    2267        1094 :         info3.sids = info6->sids;
    2268             : 
    2269        1094 :         return make_server_info_info3(mem_ctx,
    2270             :                                       sent_nt_username, domain,
    2271             :                                       server_info, &info3);
    2272             : }
    2273             : 
    2274             : /**
    2275             :  * Verify whether or not given domain is trusted.
    2276             :  *
    2277             :  * This should only be used on a DC.
    2278             :  *
    2279             :  * @param domain_name name of the domain to be verified
    2280             :  * @return true if domain is one of the trusted ones or
    2281             :  *         false if otherwise
    2282             :  **/
    2283             : 
    2284          24 : bool is_trusted_domain(const char* dom_name)
    2285             : {
    2286           0 :         bool ret;
    2287             : 
    2288          24 :         if (!IS_DC) {
    2289           0 :                 return false;
    2290             :         }
    2291             : 
    2292          24 :         if (dom_name == NULL || dom_name[0] == '\0') {
    2293           0 :                 return false;
    2294             :         }
    2295             : 
    2296          24 :         if (strequal(dom_name, get_global_sam_name())) {
    2297          24 :                 return false;
    2298             :         }
    2299             : 
    2300           0 :         become_root();
    2301           0 :         DEBUG (5,("is_trusted_domain: Checking for domain trust with "
    2302             :                   "[%s]\n", dom_name ));
    2303           0 :         ret = pdb_get_trusteddom_pw(dom_name, NULL, NULL, NULL);
    2304           0 :         unbecome_root();
    2305             : 
    2306           0 :         return ret;
    2307             : }
    2308             : 
    2309             : 
    2310             : 
    2311             : /*
    2312             :   on a logon error possibly map the error to success if "map to guest"
    2313             :   is set appropriately
    2314             : */
    2315        2360 : NTSTATUS do_map_to_guest_server_info(TALLOC_CTX *mem_ctx,
    2316             :                                      NTSTATUS status,
    2317             :                                      const char *user,
    2318             :                                      const char *domain,
    2319             :                                      struct auth_serversupplied_info **server_info)
    2320             : {
    2321        2360 :         user = user ? user : "";
    2322        2360 :         domain = domain ? domain : "";
    2323             : 
    2324        2360 :         if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
    2325        4341 :                 if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER) ||
    2326        2156 :                     (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD)) {
    2327          29 :                         DEBUG(3,("No such user %s [%s] - using guest account\n",
    2328             :                                  user, domain));
    2329          29 :                         return make_server_info_guest(mem_ctx, server_info);
    2330             :                 }
    2331         175 :         } else if (NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
    2332         164 :                 if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD) {
    2333           0 :                         DEBUG(3,("Registered username %s for guest access\n",
    2334             :                                 user));
    2335           0 :                         return make_server_info_guest(mem_ctx, server_info);
    2336             :                 }
    2337             :         }
    2338             : 
    2339        2331 :         return status;
    2340             : }
    2341             : 
    2342             : /*
    2343             :   Extract session key from a session info and return it in a blob
    2344             :   if intent is KEY_USE_16BYTES, truncate it to 16 bytes
    2345             : 
    2346             :   See sections 3.2.4.15 and 3.3.4.2 of MS-SMB
    2347             :   Also see https://lists.samba.org/archive/cifs-protocol/2012-January/002265.html for details
    2348             : 
    2349             :   Note that returned session_key is referencing the original key, it is supposed to be
    2350             :   short-lived. If original session_info->session_key is gone, the reference will be broken.
    2351             : */
    2352         137 : NTSTATUS session_extract_session_key(const struct auth_session_info *session_info, DATA_BLOB *session_key, enum session_key_use_intent intent)
    2353             : {
    2354             : 
    2355         137 :         if (session_key == NULL || session_info == NULL) {
    2356           0 :                 return NT_STATUS_INVALID_PARAMETER;
    2357             :         }
    2358             : 
    2359         137 :         if (session_info->session_key.length == 0) {
    2360           0 :                 return NT_STATUS_NO_USER_SESSION_KEY;
    2361             :         }
    2362             : 
    2363         137 :         *session_key = session_info->session_key;
    2364         137 :         if (intent == KEY_USE_16BYTES) {
    2365         137 :                 session_key->length = MIN(session_info->session_key.length, 16);
    2366             :         }
    2367         137 :         return NT_STATUS_OK;
    2368             : }

Generated by: LCOV version 1.14