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

Generated by: LCOV version 1.14