Coverage Report

Created: 2026-01-16 06:47

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