LCOV - code coverage report
Current view: top level - source3/auth - auth_util.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 604 951 63.5 %
Date: 2024-06-13 04:01:37 Functions: 27 35 77.1 %

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

Generated by: LCOV version 1.13