Coverage Report

Created: 2026-05-24 06:47

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/samba/source3/passdb/lookup_sid.c
Line
Count
Source
1
/*
2
   Unix SMB/CIFS implementation.
3
   uid/user handling
4
   Copyright (C) Andrew Tridgell         1992-1998
5
   Copyright (C) Gerald (Jerry) Carter   2003
6
   Copyright (C) Volker Lendecke   2005
7
8
   This program is free software; you can redistribute it and/or modify
9
   it under the terms of the GNU General Public License as published by
10
   the Free Software Foundation; either version 3 of the License, or
11
   (at your option) any later version.
12
13
   This program is distributed in the hope that it will be useful,
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
   GNU General Public License for more details.
17
18
   You should have received a copy of the GNU General Public License
19
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
*/
21
22
#include "includes.h"
23
#include "passdb.h"
24
#include "lib/util_unixsids.h"
25
#include "../librpc/gen_ndr/ndr_security.h"
26
#include "secrets.h"
27
#include "../lib/util/memcache.h"
28
#include "idmap_cache.h"
29
#include "../libcli/security/security.h"
30
#include "lib/winbind_util.h"
31
#include "../librpc/gen_ndr/idmap.h"
32
#include "lib/util/bitmap.h"
33
34
static bool lookup_unix_user_name(const char *name, struct dom_sid *sid)
35
0
{
36
0
  struct passwd *pwd;
37
0
  bool ret;
38
39
0
  pwd = Get_Pwnam_alloc(talloc_tos(), name);
40
0
  if (pwd == NULL) {
41
0
    return False;
42
0
  }
43
44
  /*
45
   * For 64-bit uid's we have enough space in the whole SID,
46
   * should they become necessary
47
   */
48
0
  ret = sid_compose(sid, &global_sid_Unix_Users, pwd->pw_uid);
49
0
  TALLOC_FREE(pwd);
50
0
  return ret;
51
0
}
52
53
static bool lookup_unix_group_name(const char *name, struct dom_sid *sid)
54
0
{
55
0
  struct group *grp;
56
57
0
  grp = getgrnam(name);
58
0
  if (grp == NULL) {
59
0
    return False;
60
0
  }
61
62
  /*
63
   * For 64-bit gid's we have enough space in the whole SID,
64
   * should they become necessary
65
   */
66
0
  return sid_compose(sid, &global_sid_Unix_Groups, grp->gr_gid);
67
0
}
68
69
/*****************************************************************
70
 Dissect a user-provided name into domain, name, sid and type.
71
72
 If an explicit domain name was given in the form domain\user, it
73
 has to try that. If no explicit domain name was given, we have
74
 to do guesswork.
75
*****************************************************************/
76
77
static NTSTATUS lookup_name_internal(TALLOC_CTX *mem_ctx,
78
             const char *full_name,
79
             int flags,
80
             const char **ret_domain,
81
             const char **ret_name,
82
             struct dom_sid *ret_sid,
83
             enum lsa_SidType *ret_type)
84
0
{
85
0
  const char *p;
86
0
  const char *tmp;
87
0
  const char *domain = NULL;
88
0
  const char *name = NULL;
89
0
  uint32_t rid;
90
0
  struct dom_sid sid;
91
0
  enum lsa_SidType type;
92
0
  TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
93
0
  NTSTATUS status;
94
95
0
  if (tmp_ctx == NULL) {
96
0
    DEBUG(0, ("talloc_new failed\n"));
97
0
    return NT_STATUS_NO_MEMORY;
98
0
  }
99
100
0
  p = strchr_m(full_name, '\\');
101
102
0
  if (p != NULL) {
103
0
    domain = talloc_strndup(tmp_ctx, full_name,
104
0
          PTR_DIFF(p, full_name));
105
0
    name = talloc_strdup(tmp_ctx, p+1);
106
0
  } else {
107
0
    const char *q = strchr_m(full_name, '@');
108
109
    /* Set the domain for UPNs */
110
0
    if (q != NULL) {
111
0
      name = talloc_strndup(tmp_ctx,
112
0
                full_name,
113
0
                PTR_DIFF(q, full_name));
114
0
      domain = talloc_strdup(tmp_ctx, q + 1);
115
0
    } else {
116
0
      domain = talloc_strdup(tmp_ctx, "");
117
0
      name = talloc_strdup(tmp_ctx, full_name);
118
0
    }
119
0
  }
120
121
0
  if ((domain == NULL) || (name == NULL)) {
122
0
    DEBUG(0, ("talloc failed\n"));
123
0
    TALLOC_FREE(tmp_ctx);
124
0
    return NT_STATUS_NO_MEMORY;
125
0
  }
126
127
0
  DEBUG(10,("lookup_name: %s => domain=[%s], name=[%s]\n",
128
0
    full_name, domain, name));
129
0
  DEBUG(10, ("lookup_name: flags = 0x0%x\n", flags));
130
131
0
  if ((flags & LOOKUP_NAME_DOMAIN) || (flags == 0)) {
132
0
    bool check_global_sam = false;
133
134
0
    check_global_sam = strequal(domain, get_global_sam_name());
135
136
    /* If we are running on a DC that has PASSDB module with domain
137
     * information, check if DNS forest name is matching the domain
138
     * name. This is the case of IPA domain controller when
139
     * trusted AD DC looks up users found in a Global Catalog of
140
     * the forest root domain. */
141
0
    if (!check_global_sam && (IS_DC)) {
142
0
      struct pdb_domain_info *dom_info = NULL;
143
0
      dom_info = pdb_get_domain_info(tmp_ctx);
144
145
0
      if ((dom_info != NULL) && (dom_info->dns_forest != NULL)) {
146
0
        check_global_sam = strequal(domain, dom_info->dns_forest);
147
0
      }
148
149
0
      TALLOC_FREE(dom_info);
150
0
    }
151
152
0
    if (check_global_sam) {
153
      /* It's our own domain, lookup the name in passdb */
154
0
      if (lookup_global_sam_name(name, flags, &rid, &type)) {
155
0
        sid_compose(&sid, get_global_sam_sid(), rid);
156
0
        goto ok;
157
0
      }
158
0
      TALLOC_FREE(tmp_ctx);
159
0
      *ret_type = SID_NAME_UNKNOWN;
160
0
      return NT_STATUS_OK;
161
0
    }
162
0
  }
163
164
0
  if ((flags & LOOKUP_NAME_BUILTIN) &&
165
0
      strequal(domain, builtin_domain_name()))
166
0
  {
167
0
    if (strlen(name) == 0) {
168
      /* Swap domain and name */
169
0
      tmp = name; name = domain; domain = tmp;
170
0
      sid_copy(&sid, &global_sid_Builtin);
171
0
      type = SID_NAME_DOMAIN;
172
0
      goto ok;
173
0
    }
174
175
    /* Explicit request for a name in BUILTIN */
176
0
    if (lookup_builtin_name(name, &rid)) {
177
0
      sid_compose(&sid, &global_sid_Builtin, rid);
178
0
      type = SID_NAME_ALIAS;
179
0
      goto ok;
180
0
    }
181
0
    TALLOC_FREE(tmp_ctx);
182
0
    *ret_type = SID_NAME_UNKNOWN;
183
0
    return NT_STATUS_OK;
184
0
  }
185
186
  /* Try the explicit winbind lookup first, don't let it guess the
187
   * domain yet at this point yet. This comes later. */
188
189
0
  if ((domain[0] != '\0') &&
190
0
      (flags & ~(LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED)))
191
0
  {
192
0
    status = winbind_lookup_name_ex(domain, name, &sid, &type);
193
0
    if (!NT_STATUS_IS_OK(status)) {
194
0
      return status;
195
0
    }
196
0
    if (type != SID_NAME_UNKNOWN) {
197
0
      goto ok;
198
0
    }
199
0
  }
200
201
0
  if (((flags & (LOOKUP_NAME_NO_NSS|LOOKUP_NAME_GROUP)) == 0)
202
0
      && strequal(domain, unix_users_domain_name())) {
203
0
    if (lookup_unix_user_name(name, &sid)) {
204
0
      type = SID_NAME_USER;
205
0
      goto ok;
206
0
    }
207
0
    TALLOC_FREE(tmp_ctx);
208
0
    *ret_type = SID_NAME_UNKNOWN;
209
0
    return NT_STATUS_OK;
210
0
  }
211
212
0
  if (((flags & LOOKUP_NAME_NO_NSS) == 0)
213
0
      && strequal(domain, unix_groups_domain_name())) {
214
0
    if (lookup_unix_group_name(name, &sid)) {
215
0
      type = SID_NAME_DOM_GRP;
216
0
      goto ok;
217
0
    }
218
0
    TALLOC_FREE(tmp_ctx);
219
0
    *ret_type = SID_NAME_UNKNOWN;
220
0
    return NT_STATUS_OK;
221
0
  }
222
223
  /*
224
   * Finally check for a well known domain name ("NT Authority"),
225
   * this is being taken care of in lookup_wellknown_name().
226
   */
227
0
  if ((domain[0] != '\0') &&
228
0
      (flags & LOOKUP_NAME_WKN) &&
229
0
      lookup_wellknown_name(tmp_ctx, name, &sid, &domain))
230
0
  {
231
0
    type = SID_NAME_WKN_GRP;
232
0
    goto ok;
233
0
  }
234
235
  /*
236
   * If we're told not to look up 'isolated' names then we're
237
   * done.
238
   */
239
0
  if (!(flags & LOOKUP_NAME_ISOLATED)) {
240
0
    TALLOC_FREE(tmp_ctx);
241
0
    *ret_type = SID_NAME_UNKNOWN;
242
0
    return NT_STATUS_OK;
243
0
  }
244
245
  /*
246
   * No domain names beyond this point
247
   */
248
0
  if (domain[0] != '\0') {
249
0
    TALLOC_FREE(tmp_ctx);
250
0
    *ret_type = SID_NAME_UNKNOWN;
251
0
    return NT_STATUS_OK;
252
0
  }
253
254
  /* Now the guesswork begins, we haven't been given an explicit
255
   * domain. Try the sequence as documented on
256
   * http://msdn.microsoft.com/library/en-us/secmgmt/security/lsalookupnames.asp
257
   * November 27, 2005 */
258
259
  /* 1. well-known names */
260
261
  /*
262
   * Check for well known names without a domain name.
263
   * e.g. \Creator Owner.
264
   */
265
266
0
  if ((flags & LOOKUP_NAME_WKN) &&
267
0
      lookup_wellknown_name(tmp_ctx, name, &sid, &domain))
268
0
  {
269
0
    type = SID_NAME_WKN_GRP;
270
0
    goto ok;
271
0
  }
272
273
  /* 2. Builtin domain as such */
274
275
0
  if ((flags & (LOOKUP_NAME_BUILTIN|LOOKUP_NAME_REMOTE)) &&
276
0
      strequal(name, builtin_domain_name()))
277
0
  {
278
    /* Swap domain and name */
279
0
    tmp = name; name = domain; domain = tmp;
280
0
    sid_copy(&sid, &global_sid_Builtin);
281
0
    type = SID_NAME_DOMAIN;
282
0
    goto ok;
283
0
  }
284
285
  /* 3. Account domain */
286
287
0
  if ((flags & LOOKUP_NAME_DOMAIN) &&
288
0
      strequal(name, get_global_sam_name()))
289
0
  {
290
0
    if (!secrets_fetch_domain_sid(name, &sid)) {
291
0
      DEBUG(3, ("Could not fetch my SID\n"));
292
0
      TALLOC_FREE(tmp_ctx);
293
0
      return NT_STATUS_INTERNAL_DB_CORRUPTION;
294
0
    }
295
    /* Swap domain and name */
296
0
    tmp = name; name = domain; domain = tmp;
297
0
    type = SID_NAME_DOMAIN;
298
0
    goto ok;
299
0
  }
300
301
  /* 4. Primary domain */
302
303
0
  if ((flags & LOOKUP_NAME_DOMAIN) && !IS_DC &&
304
0
      strequal(name, lp_workgroup()))
305
0
  {
306
0
    if (!secrets_fetch_domain_sid(name, &sid)) {
307
0
      DEBUG(3, ("Could not fetch the domain SID\n"));
308
0
      TALLOC_FREE(tmp_ctx);
309
0
      return NT_STATUS_INTERNAL_DB_CORRUPTION;
310
0
    }
311
    /* Swap domain and name */
312
0
    tmp = name; name = domain; domain = tmp;
313
0
    type = SID_NAME_DOMAIN;
314
0
    goto ok;
315
0
  }
316
317
  /* 5. Trusted domains as such, to me it looks as if members don't do
318
              this, tested an XP workstation in a NT domain -- vl */
319
320
0
  if ((flags & LOOKUP_NAME_REMOTE) && IS_DC &&
321
0
      (pdb_get_trusteddom_pw(name, NULL, &sid, NULL)))
322
0
  {
323
    /* Swap domain and name */
324
0
    tmp = name; name = domain; domain = tmp;
325
0
    type = SID_NAME_DOMAIN;
326
0
    goto ok;
327
0
  }
328
329
  /* 6. Builtin aliases */
330
331
0
  if ((flags & LOOKUP_NAME_BUILTIN) &&
332
0
      lookup_builtin_name(name, &rid))
333
0
  {
334
0
    domain = talloc_strdup(tmp_ctx, builtin_domain_name());
335
0
    sid_compose(&sid, &global_sid_Builtin, rid);
336
0
    type = SID_NAME_ALIAS;
337
0
    goto ok;
338
0
  }
339
340
  /* 7. Local systems' SAM (DCs don't have a local SAM) */
341
  /* 8. Primary SAM (On members, this is the domain) */
342
343
  /* Both cases are done by looking at our passdb */
344
345
0
  if ((flags & LOOKUP_NAME_DOMAIN) &&
346
0
      lookup_global_sam_name(name, flags, &rid, &type))
347
0
  {
348
0
    domain = talloc_strdup(tmp_ctx, get_global_sam_name());
349
0
    sid_compose(&sid, get_global_sam_sid(), rid);
350
0
    goto ok;
351
0
  }
352
353
  /* Now our local possibilities are exhausted. */
354
355
0
  if (!(flags & LOOKUP_NAME_REMOTE)) {
356
0
    TALLOC_FREE(tmp_ctx);
357
0
    *ret_type = SID_NAME_UNKNOWN;
358
0
    return NT_STATUS_OK;
359
0
  }
360
361
  /* If we are not a DC, we have to ask in our primary domain. Let
362
   * winbind do that. */
363
364
0
  if (!IS_DC) {
365
0
    status = winbind_lookup_name_ex(lp_workgroup(), name, &sid, &type);
366
0
    if (!NT_STATUS_IS_OK(status)) {
367
0
      return status;
368
0
    }
369
0
    if (type != SID_NAME_UNKNOWN) {
370
0
      goto ok;
371
0
    }
372
0
  }
373
374
  /* 9. Trusted domains */
375
376
  /* If we're a DC we have to ask all trusted DC's. Winbind does not do
377
   * that (yet), but give it a chance. */
378
379
0
  if (IS_DC) {
380
0
    struct dom_sid dom_sid;
381
0
    enum lsa_SidType domain_type;
382
383
0
    status = winbind_lookup_name_ex("", name, &sid, &type);
384
0
    if (!NT_STATUS_IS_OK(status)) {
385
0
      return status;
386
0
    }
387
0
    if (type != SID_NAME_UNKNOWN) {
388
0
      if (type == SID_NAME_DOMAIN) {
389
        /* Swap name and type */
390
0
        tmp = name; name = domain; domain = tmp;
391
0
        goto ok;
392
0
      }
393
394
      /* Here we have to cope with a little deficiency
395
       * in the winbind API: We have to ask it again
396
       * for the name of the domain it figured out
397
       * itself. Maybe fix that later... */
398
399
0
      sid_copy(&dom_sid, &sid);
400
0
      sid_split_rid(&dom_sid, NULL);
401
402
0
      if (!winbind_lookup_sid(tmp_ctx, &dom_sid,
403
0
            &domain, NULL,
404
0
            &domain_type) ||
405
0
          (domain_type != SID_NAME_DOMAIN))
406
0
      {
407
0
        DBG_INFO("winbind could not find the "
408
0
           "domain's name it just looked "
409
0
           "up for us\n");
410
0
        TALLOC_FREE(tmp_ctx);
411
0
        *ret_type = SID_NAME_UNKNOWN;
412
0
        return NT_STATUS_OK;
413
0
      }
414
0
      goto ok;
415
0
    }
416
0
  }
417
418
  /* 10. Don't translate */
419
420
  /* 11. Ok, windows would end here. Samba has two more options:
421
               Unmapped users and unmapped groups */
422
423
0
  if (((flags & (LOOKUP_NAME_NO_NSS|LOOKUP_NAME_GROUP)) == 0)
424
0
      && lookup_unix_user_name(name, &sid)) {
425
0
    domain = talloc_strdup(tmp_ctx, unix_users_domain_name());
426
0
    type = SID_NAME_USER;
427
0
    goto ok;
428
0
  }
429
430
0
  if (((flags & LOOKUP_NAME_NO_NSS) == 0)
431
0
      && lookup_unix_group_name(name, &sid)) {
432
0
    domain = talloc_strdup(tmp_ctx, unix_groups_domain_name());
433
0
    type = SID_NAME_DOM_GRP;
434
0
    goto ok;
435
0
  }
436
437
  /*
438
   * Ok, all possibilities tried. Fail.
439
   */
440
441
0
  TALLOC_FREE(tmp_ctx);
442
0
  *ret_type = SID_NAME_UNKNOWN;
443
0
  return NT_STATUS_OK;
444
445
0
 ok:
446
0
  if ((domain == NULL) || (name == NULL)) {
447
0
    DEBUG(0, ("talloc failed\n"));
448
0
    TALLOC_FREE(tmp_ctx);
449
0
    return NT_STATUS_NO_MEMORY;
450
0
  }
451
452
  /*
453
   * Hand over the results to the talloc context we've been given.
454
   */
455
456
0
  if ((ret_name != NULL) &&
457
0
      !(*ret_name = talloc_strdup(mem_ctx, name))) {
458
0
    DEBUG(0, ("talloc failed\n"));
459
0
    TALLOC_FREE(tmp_ctx);
460
0
    return NT_STATUS_NO_MEMORY;
461
0
  }
462
463
0
  if (ret_domain != NULL) {
464
0
    char *tmp_dom;
465
0
    if (!(tmp_dom = talloc_strdup(mem_ctx, domain))) {
466
0
      DEBUG(0, ("talloc failed\n"));
467
0
      TALLOC_FREE(tmp_ctx);
468
0
      return NT_STATUS_NO_MEMORY;
469
0
    }
470
0
    if (!strupper_m(tmp_dom)) {
471
0
      TALLOC_FREE(tmp_ctx);
472
0
      return NT_STATUS_INTERNAL_ERROR;
473
0
    }
474
0
    *ret_domain = tmp_dom;
475
0
  }
476
477
0
  if (ret_sid != NULL) {
478
0
    sid_copy(ret_sid, &sid);
479
0
  }
480
481
0
  *ret_type = type;
482
483
0
  TALLOC_FREE(tmp_ctx);
484
0
  return NT_STATUS_OK;
485
0
}
486
487
bool lookup_name(TALLOC_CTX *mem_ctx,
488
     const char *full_name,
489
     int flags,
490
     const char **ret_domain,
491
     const char **ret_name,
492
     struct dom_sid *ret_sid,
493
     enum lsa_SidType *ret_type)
494
0
{
495
0
  enum lsa_SidType type;
496
0
  NTSTATUS status;
497
498
0
  status = lookup_name_internal(mem_ctx,
499
0
              full_name,
500
0
              flags,
501
0
              ret_domain,
502
0
              ret_name,
503
0
              ret_sid,
504
0
              &type);
505
0
  if (!NT_STATUS_IS_OK(status)) {
506
0
    return false;
507
0
  }
508
0
  if (ret_type != NULL) {
509
0
    *ret_type = type;
510
0
  }
511
0
  if (type == SID_NAME_UNKNOWN) {
512
0
    return false;
513
0
  }
514
0
  return true;
515
0
}
516
517
/************************************************************************
518
 Names from smb.conf can be unqualified. eg. valid users = foo
519
 These names should never map to a remote name. Try global_sam_name()\foo,
520
 and then "Unix Users"\foo (or "Unix Groups"\foo).
521
************************************************************************/
522
523
NTSTATUS lookup_name_smbconf_ex(TALLOC_CTX *mem_ctx,
524
        const char *full_name,
525
        int flags,
526
        const char **ret_domain,
527
        const char **ret_name,
528
        struct dom_sid *ret_sid,
529
        enum lsa_SidType *ret_type)
530
0
{
531
0
  char *qualified_name = NULL;
532
0
  const char *p = strchr_m(full_name, *lp_winbind_separator());
533
0
  bool is_qualified = p != NULL || strchr_m(full_name, '@') != NULL;
534
0
  NTSTATUS status;
535
536
  /* For DOMAIN\user or user@REALM directly call lookup_name(). */
537
0
  if (is_qualified) {
538
539
    /* The name is already qualified with a domain. */
540
541
0
    if (p != NULL && *lp_winbind_separator() != '\\') {
542
      /* lookup_name() needs '\\' as a separator */
543
544
0
      qualified_name = talloc_strdup(mem_ctx, full_name);
545
0
      if (qualified_name == NULL) {
546
0
        return NT_STATUS_NO_MEMORY;
547
0
      }
548
0
      qualified_name[p - full_name] = '\\';
549
0
      full_name = qualified_name;
550
0
    }
551
552
0
    return lookup_name_internal(mem_ctx,
553
0
              full_name,
554
0
              flags,
555
0
              ret_domain,
556
0
              ret_name,
557
0
              ret_sid,
558
0
              ret_type);
559
0
  }
560
561
  /* Try with winbind default domain name. */
562
0
  if (lp_winbind_use_default_domain()) {
563
0
    qualified_name = talloc_asprintf(mem_ctx,
564
0
             "%s\\%s",
565
0
             lp_workgroup(),
566
0
             full_name);
567
0
    if (qualified_name == NULL) {
568
0
      return NT_STATUS_NO_MEMORY;
569
0
    }
570
571
0
    status= lookup_name_internal(mem_ctx,
572
0
               qualified_name,
573
0
               flags,
574
0
               ret_domain,
575
0
               ret_name,
576
0
               ret_sid,
577
0
               ret_type);
578
0
    if (NT_STATUS_IS_OK(status) &&
579
0
        *ret_type != SID_NAME_UNKNOWN)
580
0
    {
581
0
      return NT_STATUS_OK;
582
0
    }
583
0
  }
584
585
  /* Try with our own SAM name. */
586
0
  qualified_name = talloc_asprintf(mem_ctx, "%s\\%s",
587
0
        get_global_sam_name(),
588
0
        full_name );
589
0
  if (!qualified_name) {
590
0
    return NT_STATUS_NO_MEMORY;
591
0
  }
592
593
0
  status = lookup_name_internal(mem_ctx,
594
0
              qualified_name,
595
0
              flags,
596
0
              ret_domain,
597
0
              ret_name,
598
0
              ret_sid,
599
0
              ret_type);
600
0
  if (NT_STATUS_IS_OK(status) &&
601
0
      *ret_type != SID_NAME_UNKNOWN)
602
0
  {
603
0
    return NT_STATUS_OK;
604
0
  }
605
606
  /* Finally try with "Unix Users" or "Unix Group" */
607
0
  qualified_name = talloc_asprintf(mem_ctx, "%s\\%s",
608
0
        flags & LOOKUP_NAME_GROUP ?
609
0
          unix_groups_domain_name() :
610
0
          unix_users_domain_name(),
611
0
        full_name );
612
0
  if (!qualified_name) {
613
0
    return NT_STATUS_NO_MEMORY;
614
0
  }
615
616
0
  return lookup_name_internal(mem_ctx,
617
0
            qualified_name,
618
0
            flags,
619
0
            ret_domain,
620
0
            ret_name,
621
0
            ret_sid,
622
0
            ret_type);
623
0
}
624
625
bool lookup_name_smbconf(TALLOC_CTX *mem_ctx,
626
     const char *full_name, int flags,
627
     const char **ret_domain, const char **ret_name,
628
     struct dom_sid *ret_sid, enum lsa_SidType *ret_type)
629
0
{
630
0
  enum lsa_SidType type;
631
0
  NTSTATUS status;
632
633
0
  status = lookup_name_smbconf_ex(mem_ctx,
634
0
          full_name,
635
0
          flags,
636
0
          ret_domain,
637
0
          ret_name,
638
0
          ret_sid,
639
0
          &type);
640
0
  if (!NT_STATUS_IS_OK(status)) {
641
0
    return false;
642
0
  }
643
0
  if (ret_type != NULL) {
644
0
    *ret_type = type;
645
0
  }
646
0
  if (type == SID_NAME_UNKNOWN) {
647
0
    return false;
648
0
  }
649
0
  return true;
650
0
}
651
652
static bool wb_lookup_rids(TALLOC_CTX *mem_ctx,
653
         const struct dom_sid *domain_sid,
654
         int num_rids, uint32_t *rids,
655
         const char **domain_name,
656
         const char **names, enum lsa_SidType *types)
657
0
{
658
0
  int i;
659
0
  const char **my_names;
660
0
  enum lsa_SidType *my_types;
661
0
  TALLOC_CTX *tmp_ctx;
662
663
0
  if (!(tmp_ctx = talloc_init("wb_lookup_rids"))) {
664
0
    return false;
665
0
  }
666
667
0
  if (!winbind_lookup_rids(tmp_ctx, domain_sid, num_rids, rids,
668
0
         domain_name, &my_names, &my_types)) {
669
0
    *domain_name = "";
670
0
    for (i=0; i<num_rids; i++) {
671
0
      names[i] = "";
672
0
      types[i] = SID_NAME_UNKNOWN;
673
0
    }
674
0
    TALLOC_FREE(tmp_ctx);
675
0
    return true;
676
0
  }
677
678
0
  if (!(*domain_name = talloc_strdup(mem_ctx, *domain_name))) {
679
0
    TALLOC_FREE(tmp_ctx);
680
0
    return false;
681
0
  }
682
683
  /*
684
   * winbind_lookup_rids allocates its own array. We've been given the
685
   * array, so copy it over
686
   */
687
688
0
  for (i=0; i<num_rids; i++) {
689
0
    if (my_names[i] == NULL) {
690
0
      TALLOC_FREE(tmp_ctx);
691
0
      return false;
692
0
    }
693
0
    if (!(names[i] = talloc_strdup(names, my_names[i]))) {
694
0
      TALLOC_FREE(tmp_ctx);
695
0
      return false;
696
0
    }
697
0
    types[i] = my_types[i];
698
0
  }
699
0
  TALLOC_FREE(tmp_ctx);
700
0
  return true;
701
0
}
702
703
static bool lookup_rids(TALLOC_CTX *mem_ctx, const struct dom_sid *domain_sid,
704
      int num_rids, uint32_t *rids,
705
      const char **domain_name,
706
      const char ***names, enum lsa_SidType **types)
707
0
{
708
0
  int i;
709
0
  struct dom_sid_buf buf;
710
711
0
  DEBUG(10, ("lookup_rids called for domain sid '%s'\n",
712
0
       dom_sid_str_buf(domain_sid, &buf)));
713
714
0
  if (num_rids) {
715
0
    *names = talloc_zero_array(mem_ctx, const char *, num_rids);
716
0
    *types = talloc_array(mem_ctx, enum lsa_SidType, num_rids);
717
718
0
    if ((*names == NULL) || (*types == NULL)) {
719
0
      return false;
720
0
    }
721
722
0
    for (i = 0; i < num_rids; i++)
723
0
      (*types)[i] = SID_NAME_UNKNOWN;
724
0
  } else {
725
0
    *names = NULL;
726
0
    *types = NULL;
727
0
  }
728
729
0
  if (sid_check_is_our_sam(domain_sid)) {
730
0
    NTSTATUS result;
731
732
0
    if (*domain_name == NULL) {
733
0
      *domain_name = talloc_strdup(
734
0
        mem_ctx, get_global_sam_name());
735
0
    }
736
737
0
    if (*domain_name == NULL) {
738
0
      return false;
739
0
    }
740
741
0
    become_root();
742
0
    result = pdb_lookup_rids(domain_sid, num_rids, rids,
743
0
           *names, *types);
744
0
    unbecome_root();
745
746
0
    return (NT_STATUS_IS_OK(result) ||
747
0
      NT_STATUS_EQUAL(result, NT_STATUS_NONE_MAPPED) ||
748
0
      NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED));
749
0
  }
750
751
0
  if (sid_check_is_builtin(domain_sid)) {
752
753
0
    if (*domain_name == NULL) {
754
0
      *domain_name = talloc_strdup(
755
0
        mem_ctx, builtin_domain_name());
756
0
    }
757
758
0
    if (*domain_name == NULL) {
759
0
      return false;
760
0
    }
761
762
0
    for (i=0; i<num_rids; i++) {
763
0
      if (lookup_builtin_rid(*names, rids[i],
764
0
                 &(*names)[i])) {
765
0
        if ((*names)[i] == NULL) {
766
0
          return false;
767
0
        }
768
0
        (*types)[i] = SID_NAME_ALIAS;
769
0
      } else {
770
0
        (*types)[i] = SID_NAME_UNKNOWN;
771
0
      }
772
0
    }
773
0
    return true;
774
0
  }
775
776
0
  if (sid_check_is_wellknown_domain(domain_sid, NULL)) {
777
0
    for (i=0; i<num_rids; i++) {
778
0
      struct dom_sid sid;
779
0
      sid_compose(&sid, domain_sid, rids[i]);
780
0
      if (lookup_wellknown_sid(mem_ctx, &sid,
781
0
             domain_name, &(*names)[i])) {
782
0
        if ((*names)[i] == NULL) {
783
0
          return false;
784
0
        }
785
0
        (*types)[i] = SID_NAME_WKN_GRP;
786
0
      } else {
787
0
        (*types)[i] = SID_NAME_UNKNOWN;
788
0
      }
789
0
    }
790
0
    return true;
791
0
  }
792
793
0
  if (sid_check_is_unix_users(domain_sid)) {
794
0
    if (*domain_name == NULL) {
795
0
      *domain_name = talloc_strdup(
796
0
        mem_ctx, unix_users_domain_name());
797
0
      if (*domain_name == NULL) {
798
0
        return false;
799
0
      }
800
0
    }
801
0
    for (i=0; i<num_rids; i++) {
802
0
      (*names)[i] = talloc_strdup(
803
0
        (*names), uidtoname(rids[i]));
804
0
      if ((*names)[i] == NULL) {
805
0
        return false;
806
0
      }
807
0
      (*types)[i] = SID_NAME_USER;
808
0
    }
809
0
    return true;
810
0
  }
811
812
0
  if (sid_check_is_unix_groups(domain_sid)) {
813
0
    if (*domain_name == NULL) {
814
0
      *domain_name = talloc_strdup(
815
0
        mem_ctx, unix_groups_domain_name());
816
0
      if (*domain_name == NULL) {
817
0
        return false;
818
0
      }
819
0
    }
820
0
    for (i=0; i<num_rids; i++) {
821
0
      (*names)[i] = talloc_strdup(
822
0
        (*names), gidtoname(rids[i]));
823
0
      if ((*names)[i] == NULL) {
824
0
        return false;
825
0
      }
826
0
      (*types)[i] = SID_NAME_DOM_GRP;
827
0
    }
828
0
    return true;
829
0
  }
830
831
0
  return wb_lookup_rids(mem_ctx, domain_sid, num_rids, rids,
832
0
            domain_name, *names, *types);
833
0
}
834
835
/*
836
 * Is the SID a domain as such? If yes, lookup its name.
837
 */
838
839
static bool lookup_as_domain(const struct dom_sid *sid, TALLOC_CTX *mem_ctx,
840
           const char **name)
841
0
{
842
0
  const char *tmp;
843
0
  enum lsa_SidType type;
844
845
0
  if (sid_check_is_our_sam(sid)) {
846
0
    *name = talloc_strdup(mem_ctx, get_global_sam_name());
847
0
    return true;
848
0
  }
849
850
0
  if (sid_check_is_builtin(sid)) {
851
0
    *name = talloc_strdup(mem_ctx, builtin_domain_name());
852
0
    return true;
853
0
  }
854
855
0
  if (sid_check_is_wellknown_domain(sid, &tmp)) {
856
0
    *name = talloc_strdup(mem_ctx, tmp);
857
0
    return true;
858
0
  }
859
860
0
  if (sid_check_is_unix_users(sid)) {
861
0
    *name = talloc_strdup(mem_ctx, unix_users_domain_name());
862
0
    return true;
863
0
  }
864
865
0
  if (sid_check_is_unix_groups(sid)) {
866
0
    *name = talloc_strdup(mem_ctx, unix_groups_domain_name());
867
0
    return true;
868
0
  }
869
870
0
  if (sid->num_auths != 4) {
871
    /* This can't be a domain */
872
0
    return false;
873
0
  }
874
875
0
  if (IS_DC) {
876
0
    uint32_t i, num_domains;
877
0
    struct trustdom_info **domains;
878
879
    /* This is relatively expensive, but it happens only on DCs
880
     * and for SIDs that have 4 sub-authorities and thus look like
881
     * domains */
882
883
0
    if (!NT_STATUS_IS_OK(pdb_enum_trusteddoms(mem_ctx,
884
0
                      &num_domains,
885
0
                      &domains))) {
886
0
      return false;
887
0
    }
888
889
0
    for (i=0; i<num_domains; i++) {
890
0
      if (dom_sid_equal(sid, &domains[i]->sid)) {
891
0
        *name = talloc_strdup(mem_ctx,
892
0
                  domains[i]->name);
893
0
        return true;
894
0
      }
895
0
    }
896
0
    return false;
897
0
  }
898
899
0
  if (winbind_lookup_sid(mem_ctx, sid, &tmp, NULL, &type) &&
900
0
      (type == SID_NAME_DOMAIN)) {
901
0
    *name = tmp;
902
0
    return true;
903
0
  }
904
905
0
  return false;
906
0
}
907
908
/*
909
 * This tries to implement the rather weird rules for the lsa_lookup level
910
 * parameter.
911
 *
912
 * This is as close as we can get to what W2k3 does. With this we survive the
913
 * RPC-LSALOOKUP samba4 test as of 2006-01-08. NT4 as a PDC is a bit more
914
 * different, but I assume that's just being too liberal. For example, W2k3
915
 * replies to everything else but the levels 1-6 with INVALID_PARAMETER
916
 * whereas NT4 does the same as level 1 (I think). I did not fully test that
917
 * with NT4, this is what w2k3 does.
918
 *
919
 * Level 1: Ask everywhere
920
 * Level 2: Ask domain and trusted domains, no builtin and wkn
921
 * Level 3: Only ask domain
922
 * Level 4: W2k3ad: Only ask AD trusts
923
 * Level 5: Only ask transitive forest trusts
924
 * Level 6: Like 4
925
 */
926
927
static bool check_dom_sid_to_level(const struct dom_sid *sid, int level)
928
0
{
929
0
  struct dom_sid_buf buf;
930
0
  int ret = false;
931
932
0
  switch(level) {
933
0
  case 1:
934
0
    ret = true;
935
0
    break;
936
0
  case 2:
937
0
    ret = (!sid_check_is_builtin(sid) &&
938
0
           !sid_check_is_wellknown_domain(sid, NULL));
939
0
    break;
940
0
  case 3:
941
0
  case 4:
942
0
  case 6:
943
0
    ret = sid_check_is_our_sam(sid);
944
0
    break;
945
0
  case 5:
946
0
    ret = false;
947
0
    break;
948
0
  }
949
950
0
  DEBUG(10, ("%s SID %s in level %d\n",
951
0
       ret ? "Accepting" : "Rejecting",
952
0
       dom_sid_str_buf(sid, &buf),
953
0
       level));
954
0
  return ret;
955
0
}
956
957
/*
958
 * Lookup a bunch of SIDs. This is modeled after lsa_lookup_sids with
959
 * references to domains, it is explicitly made for this.
960
 *
961
 * This attempts to be as efficient as possible: It collects all SIDs
962
 * belonging to a domain and hands them in bulk to the appropriate lookup
963
 * function. In particular pdb_lookup_rids with ldapsam_trusted benefits
964
 * *hugely* from this.
965
 */
966
967
NTSTATUS lookup_sids(TALLOC_CTX *mem_ctx, int num_sids,
968
         const struct dom_sid **sids, int level,
969
         struct lsa_dom_info **ret_domains,
970
         struct lsa_name_info **ret_names)
971
0
{
972
0
  TALLOC_CTX *tmp_ctx;
973
0
  NTSTATUS result;
974
0
  struct lsa_name_info *name_infos;
975
0
  struct lsa_dom_info *dom_infos = NULL;
976
977
0
  int i, j;
978
979
0
  if (!(tmp_ctx = talloc_new(mem_ctx))) {
980
0
    DEBUG(0, ("talloc_new failed\n"));
981
0
    return NT_STATUS_NO_MEMORY;
982
0
  }
983
984
0
  if (num_sids) {
985
0
    name_infos = talloc_array(mem_ctx, struct lsa_name_info, num_sids);
986
0
    if (name_infos == NULL) {
987
0
      result = NT_STATUS_NO_MEMORY;
988
0
      goto fail;
989
0
    }
990
0
  } else {
991
0
    name_infos = NULL;
992
0
  }
993
994
0
  dom_infos = talloc_zero_array(mem_ctx, struct lsa_dom_info,
995
0
              LSA_REF_DOMAIN_LIST_MULTIPLIER);
996
0
  if (dom_infos == NULL) {
997
0
    result = NT_STATUS_NO_MEMORY;
998
0
    goto fail;
999
0
  }
1000
1001
  /* First build up the data structures:
1002
   *
1003
   * dom_infos is a list of domains referenced in the list of
1004
   * SIDs. Later we will walk the list of domains and look up the RIDs
1005
   * in bulk.
1006
   *
1007
   * name_infos is a shadow-copy of the SIDs array to collect the real
1008
   * data.
1009
   *
1010
   * dom_info->idxs is an index into the name_infos array. The
1011
   * difficulty we have here is that we need to keep the SIDs the client
1012
   * asked for in the same order for the reply
1013
   */
1014
1015
0
  for (i=0; i<num_sids; i++) {
1016
0
    struct dom_sid sid;
1017
0
    uint32_t rid = 0;
1018
0
    const char *domain_name = NULL;
1019
1020
0
    sid_copy(&sid, sids[i]);
1021
0
    name_infos[i].type = SID_NAME_USE_NONE;
1022
1023
0
    if (lookup_as_domain(&sid, name_infos, &domain_name)) {
1024
      /* We can't push that through the normal lookup
1025
       * process, as this would reference illegal
1026
       * domains.
1027
       *
1028
       * For example S-1-5-32 would end up referencing
1029
       * domain S-1-5- with RID 32 which is clearly wrong.
1030
       */
1031
0
      if (domain_name == NULL) {
1032
0
        result = NT_STATUS_NO_MEMORY;
1033
0
        goto fail;
1034
0
      }
1035
1036
0
      name_infos[i].rid = 0;
1037
0
      name_infos[i].type = SID_NAME_DOMAIN;
1038
0
      name_infos[i].name = NULL;
1039
1040
0
      if (sid_check_is_builtin(&sid)) {
1041
        /* Yes, W2k3 returns "BUILTIN" both as domain
1042
         * and name here */
1043
0
        name_infos[i].name = talloc_strdup(
1044
0
          name_infos, builtin_domain_name());
1045
0
        if (name_infos[i].name == NULL) {
1046
0
          result = NT_STATUS_NO_MEMORY;
1047
0
          goto fail;
1048
0
        }
1049
0
      }
1050
0
    } else {
1051
      /* This is a normal SID with rid component */
1052
0
      if (!sid_split_rid(&sid, &rid)) {
1053
0
        result = NT_STATUS_INVALID_SID;
1054
0
        goto fail;
1055
0
      }
1056
0
    }
1057
1058
0
    if (!check_dom_sid_to_level(&sid, level)) {
1059
0
      name_infos[i].rid = 0;
1060
0
      name_infos[i].type = SID_NAME_UNKNOWN;
1061
0
      name_infos[i].name = NULL;
1062
0
      continue;
1063
0
    }
1064
1065
0
    for (j=0; j<LSA_REF_DOMAIN_LIST_MULTIPLIER; j++) {
1066
0
      if (!dom_infos[j].valid) {
1067
0
        break;
1068
0
      }
1069
0
      if (dom_sid_equal(&sid, &dom_infos[j].sid)) {
1070
0
        break;
1071
0
      }
1072
0
    }
1073
1074
0
    if (j == LSA_REF_DOMAIN_LIST_MULTIPLIER) {
1075
      /* TODO: What's the right error message here? */
1076
0
      result = NT_STATUS_TOO_MANY_CONTEXT_IDS;
1077
0
      goto fail;
1078
0
    }
1079
1080
0
    if (!dom_infos[j].valid) {
1081
      /* We found a domain not yet referenced, create a new
1082
       * ref. */
1083
0
      dom_infos[j].valid = true;
1084
0
      sid_copy(&dom_infos[j].sid, &sid);
1085
1086
0
      if (domain_name != NULL) {
1087
        /* This name was being found above in the case
1088
         * when we found a domain SID */
1089
0
        dom_infos[j].name =
1090
0
          talloc_strdup(dom_infos, domain_name);
1091
0
        if (dom_infos[j].name == NULL) {
1092
0
          result = NT_STATUS_NO_MEMORY;
1093
0
          goto fail;
1094
0
        }
1095
0
      } else {
1096
        /* lookup_rids will take care of this */
1097
0
        dom_infos[j].name = NULL;
1098
0
      }
1099
0
    }
1100
1101
0
    name_infos[i].dom_idx = j;
1102
1103
0
    if (name_infos[i].type == SID_NAME_USE_NONE) {
1104
0
      name_infos[i].rid = rid;
1105
1106
0
      ADD_TO_ARRAY(dom_infos, int, i, &dom_infos[j].idxs,
1107
0
             &dom_infos[j].num_idxs);
1108
1109
0
      if (dom_infos[j].idxs == NULL) {
1110
0
        result = NT_STATUS_NO_MEMORY;
1111
0
        goto fail;
1112
0
      }
1113
0
    }
1114
0
  }
1115
1116
  /* Iterate over the domains found */
1117
1118
0
  for (i=0; i<LSA_REF_DOMAIN_LIST_MULTIPLIER; i++) {
1119
0
    uint32_t *rids;
1120
0
    const char *domain_name = NULL;
1121
0
    const char **names;
1122
0
    enum lsa_SidType *types;
1123
0
    struct lsa_dom_info *dom = &dom_infos[i];
1124
1125
0
    if (!dom->valid) {
1126
      /* No domains left, we're done */
1127
0
      break;
1128
0
    }
1129
1130
0
    if (dom->num_idxs == 0) {
1131
      /*
1132
       * This happens only if the only sid related to
1133
       * this domain is the domain sid itself, which
1134
       * is mapped to SID_NAME_DOMAIN above.
1135
       */
1136
0
      continue;
1137
0
    }
1138
1139
0
    if (!(rids = talloc_array(tmp_ctx, uint32_t, dom->num_idxs))) {
1140
0
      result = NT_STATUS_NO_MEMORY;
1141
0
      goto fail;
1142
0
    }
1143
1144
0
    for (j=0; j<dom->num_idxs; j++) {
1145
0
      rids[j] = name_infos[dom->idxs[j]].rid;
1146
0
    }
1147
1148
0
    if (!lookup_rids(tmp_ctx, &dom->sid,
1149
0
         dom->num_idxs, rids, &domain_name,
1150
0
         &names, &types)) {
1151
0
      result = NT_STATUS_NO_MEMORY;
1152
0
      goto fail;
1153
0
    }
1154
1155
0
    if (!(dom->name = talloc_strdup(dom_infos, domain_name))) {
1156
0
      result = NT_STATUS_NO_MEMORY;
1157
0
      goto fail;
1158
0
    }
1159
1160
0
    for (j=0; j<dom->num_idxs; j++) {
1161
0
      int idx = dom->idxs[j];
1162
0
      name_infos[idx].type = types[j];
1163
0
      if (types[j] != SID_NAME_UNKNOWN) {
1164
0
        name_infos[idx].name =
1165
0
          talloc_strdup(name_infos, names[j]);
1166
0
        if (name_infos[idx].name == NULL) {
1167
0
          result = NT_STATUS_NO_MEMORY;
1168
0
          goto fail;
1169
0
        }
1170
0
      } else {
1171
0
        name_infos[idx].name = NULL;
1172
0
      }
1173
0
    }
1174
0
  }
1175
1176
0
  *ret_domains = dom_infos;
1177
0
  *ret_names = name_infos;
1178
0
  TALLOC_FREE(tmp_ctx);
1179
0
  return NT_STATUS_OK;
1180
1181
0
 fail:
1182
0
  TALLOC_FREE(dom_infos);
1183
0
  TALLOC_FREE(name_infos);
1184
0
  TALLOC_FREE(tmp_ctx);
1185
0
  return result;
1186
0
}
1187
1188
/*****************************************************************
1189
 *THE CANONICAL* convert SID to name function.
1190
*****************************************************************/
1191
1192
bool lookup_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid,
1193
    const char **ret_domain, const char **ret_name,
1194
    enum lsa_SidType *ret_type)
1195
0
{
1196
0
  struct lsa_dom_info *domain;
1197
0
  struct lsa_name_info *name;
1198
0
  struct dom_sid_buf buf;
1199
0
  TALLOC_CTX *tmp_ctx;
1200
0
  bool ret = false;
1201
1202
0
  DEBUG(10, ("lookup_sid called for SID '%s'\n",
1203
0
       dom_sid_str_buf(sid, &buf)));
1204
1205
0
  if (!(tmp_ctx = talloc_new(mem_ctx))) {
1206
0
    DEBUG(0, ("talloc_new failed\n"));
1207
0
    return false;
1208
0
  }
1209
1210
0
  if (!NT_STATUS_IS_OK(lookup_sids(tmp_ctx, 1, &sid, 1,
1211
0
           &domain, &name))) {
1212
0
    goto done;
1213
0
  }
1214
1215
0
  if (name->type == SID_NAME_UNKNOWN) {
1216
0
    goto done;
1217
0
  }
1218
1219
0
  if ((ret_domain != NULL) &&
1220
0
      !(*ret_domain = talloc_strdup(mem_ctx, domain->name))) {
1221
0
    goto done;
1222
0
  }
1223
1224
0
  if ((ret_name != NULL) &&
1225
0
      !(*ret_name = talloc_strdup(mem_ctx, name->name))) {
1226
0
    goto done;
1227
0
  }
1228
1229
0
  if (ret_type != NULL) {
1230
0
    *ret_type = name->type;
1231
0
  }
1232
1233
0
  ret = true;
1234
1235
0
 done:
1236
0
  if (ret) {
1237
0
    DEBUG(10, ("Sid %s -> %s\\%s(%d)\n",
1238
0
         dom_sid_str_buf(sid, &buf),
1239
0
         domain->name, name->name, name->type));
1240
0
  } else {
1241
0
    DEBUG(10, ("failed to lookup sid %s\n",
1242
0
         dom_sid_str_buf(sid, &buf)));
1243
0
  }
1244
0
  TALLOC_FREE(tmp_ctx);
1245
0
  return ret;
1246
0
}
1247
1248
/*****************************************************************
1249
 *THE LEGACY* convert SID to id function.
1250
*****************************************************************/
1251
1252
static bool legacy_sid_to_unixid(const struct dom_sid *psid, struct unixid *id)
1253
0
{
1254
0
  bool ret;
1255
1256
0
  become_root();
1257
0
  ret = pdb_sid_to_id(psid, id);
1258
0
  unbecome_root();
1259
1260
0
  if (!ret) {
1261
0
    struct dom_sid_buf buf;
1262
0
    DEBUG(10,("LEGACY: mapping failed for sid %s\n",
1263
0
        dom_sid_str_buf(psid, &buf)));
1264
0
    return false;
1265
0
  }
1266
1267
0
  return true;
1268
0
}
1269
1270
static bool legacy_sid_to_gid(const struct dom_sid *psid, gid_t *pgid)
1271
0
{
1272
0
  struct unixid id;
1273
0
  if (!legacy_sid_to_unixid(psid, &id)) {
1274
0
    return false;
1275
0
  }
1276
0
  if (id.type == ID_TYPE_GID || id.type == ID_TYPE_BOTH) {
1277
0
    *pgid = id.id;
1278
0
    return true;
1279
0
  }
1280
0
  return false;
1281
0
}
1282
1283
static bool legacy_sid_to_uid(const struct dom_sid *psid, uid_t *puid)
1284
0
{
1285
0
  struct unixid id;
1286
0
  if (!legacy_sid_to_unixid(psid, &id)) {
1287
0
    return false;
1288
0
  }
1289
0
  if (id.type == ID_TYPE_UID || id.type == ID_TYPE_BOTH) {
1290
0
    *puid = id.id;
1291
0
    return true;
1292
0
  }
1293
0
  return false;
1294
0
}
1295
1296
void xid_to_sid(struct dom_sid *psid, const struct unixid *xid)
1297
0
{
1298
0
  bool expired = true;
1299
0
  bool ret;
1300
0
  struct dom_sid_buf buf;
1301
1302
0
  SMB_ASSERT(xid->type == ID_TYPE_UID || xid->type == ID_TYPE_GID);
1303
1304
0
  *psid = (struct dom_sid) {0};
1305
1306
0
  ret = idmap_cache_find_xid2sid(xid, psid, &expired);
1307
0
  if (ret && !expired) {
1308
0
    DBG_DEBUG("%cID %"PRIu32" -> %s from cache\n",
1309
0
        xid->type == ID_TYPE_UID ? 'U' : 'G',
1310
0
        xid->id,
1311
0
        dom_sid_str_buf(psid, &buf));
1312
0
    goto done;
1313
0
  }
1314
1315
0
  ret = winbind_xid_to_sid(psid, xid);
1316
0
  if (ret) {
1317
    /*
1318
     * winbind can return an explicit negative mapping
1319
     * here. It's up to winbind to prime the cache either
1320
     * positively or negatively, don't mess with the cache
1321
     * here.
1322
     */
1323
0
    DBG_DEBUG("%cID %"PRIu32" -> %s from cache\n",
1324
0
        xid->type == ID_TYPE_UID ? 'U' : 'G',
1325
0
        xid->id,
1326
0
        dom_sid_str_buf(psid, &buf));
1327
0
    goto done;
1328
0
  }
1329
1330
0
  {
1331
    /*
1332
     * Make a copy, pdb_id_to_sid might want to turn
1333
     * xid->type into ID_TYPE_BOTH, which we ignore here.
1334
     */
1335
0
    struct unixid rw_xid = *xid;
1336
1337
0
    become_root();
1338
0
    ret = pdb_id_to_sid(&rw_xid, psid);
1339
0
    unbecome_root();
1340
0
  }
1341
1342
0
  if (ret) {
1343
0
    DBG_DEBUG("%cID %"PRIu32" -> %s from passdb\n",
1344
0
        xid->type == ID_TYPE_UID ? 'U' : 'G',
1345
0
        xid->id,
1346
0
        dom_sid_str_buf(psid, &buf));
1347
0
    goto done;
1348
0
  }
1349
1350
0
done:
1351
0
  if (is_null_sid(psid)) {
1352
    /*
1353
     * Nobody found anything: Return S-1-22-xx-yy. Don't
1354
     * store that in caches, this is up to the layers
1355
     * beneath us.
1356
     */
1357
0
    if (xid->type == ID_TYPE_UID) {
1358
0
      uid_to_unix_users_sid(xid->id, psid);
1359
0
    } else {
1360
0
      gid_to_unix_groups_sid(xid->id, psid);
1361
0
    }
1362
1363
0
    DBG_DEBUG("%cID %"PRIu32" -> %s fallback\n",
1364
0
        xid->type == ID_TYPE_UID ? 'U' : 'G',
1365
0
        xid->id,
1366
0
        dom_sid_str_buf(psid, &buf));
1367
0
  }
1368
0
}
1369
1370
void uid_to_sid(struct dom_sid *psid, uid_t uid)
1371
0
{
1372
0
  struct unixid xid = { .type = ID_TYPE_UID, .id = uid};
1373
0
  xid_to_sid(psid, &xid);
1374
0
}
1375
1376
void gid_to_sid(struct dom_sid *psid, gid_t gid)
1377
0
{
1378
0
  struct unixid xid = { .type = ID_TYPE_GID, .id = gid};
1379
0
  xid_to_sid(psid, &xid);
1380
0
}
1381
1382
bool sids_to_unixids(const struct dom_sid *sids, uint32_t num_sids,
1383
         struct unixid *ids)
1384
0
{
1385
0
  struct wbcDomainSid *wbc_sids = NULL;
1386
0
  struct wbcUnixId *wbc_ids = NULL;
1387
0
  struct bitmap *found = NULL;
1388
0
  uint32_t i, num_not_cached;
1389
0
  uint32_t wbc_ids_size = 0;
1390
0
  wbcErr err;
1391
0
  bool ret = false;
1392
1393
0
  wbc_sids = talloc_array(talloc_tos(), struct wbcDomainSid, num_sids);
1394
0
  if (wbc_sids == NULL) {
1395
0
    return false;
1396
0
  }
1397
0
  found = bitmap_talloc(wbc_sids, num_sids);
1398
0
  if (found == NULL) {
1399
0
    goto fail;
1400
0
  }
1401
1402
  /*
1403
   * We go through the requested SID array three times.
1404
   * First time to look for global_sid_Unix_Users
1405
   * and global_sid_Unix_Groups SIDS, and to look
1406
   * for mappings cached in the idmap_cache.
1407
   *
1408
   * Use bitmap_set() to mark an ids[] array entry as
1409
   * being mapped.
1410
   */
1411
1412
0
  num_not_cached = 0;
1413
1414
0
  for (i=0; i<num_sids; i++) {
1415
0
    bool expired;
1416
0
    uint32_t rid;
1417
1418
0
    if (sid_peek_check_rid(&global_sid_Unix_Users,
1419
0
               &sids[i], &rid)) {
1420
0
      ids[i].type = ID_TYPE_UID;
1421
0
      ids[i].id = rid;
1422
0
      bitmap_set(found, i);
1423
0
      continue;
1424
0
    }
1425
0
    if (sid_peek_check_rid(&global_sid_Unix_Groups,
1426
0
               &sids[i], &rid)) {
1427
0
      ids[i].type = ID_TYPE_GID;
1428
0
      ids[i].id = rid;
1429
0
      bitmap_set(found, i);
1430
0
      continue;
1431
0
    }
1432
0
    if (idmap_cache_find_sid2unixid(&sids[i], &ids[i], &expired)
1433
0
        && !expired)
1434
0
    {
1435
0
      bitmap_set(found, i);
1436
0
      continue;
1437
0
    }
1438
0
    ids[i].type = ID_TYPE_NOT_SPECIFIED;
1439
0
    memcpy(&wbc_sids[num_not_cached], &sids[i],
1440
0
           ndr_size_dom_sid(&sids[i], 0));
1441
0
    num_not_cached += 1;
1442
0
  }
1443
0
  if (num_not_cached == 0) {
1444
0
    goto done;
1445
0
  }
1446
1447
  /*
1448
   * For the ones that we couldn't map in the loop above, query winbindd
1449
   * via wbcSidsToUnixIds().
1450
   */
1451
1452
0
  wbc_ids_size = num_not_cached;
1453
0
  wbc_ids = talloc_array(talloc_tos(), struct wbcUnixId, wbc_ids_size);
1454
0
  if (wbc_ids == NULL) {
1455
0
    goto fail;
1456
0
  }
1457
0
  for (i=0; i<wbc_ids_size; i++) {
1458
0
    wbc_ids[i].type = WBC_ID_TYPE_NOT_SPECIFIED;
1459
0
    wbc_ids[i].id.gid = (uint32_t)-1;
1460
0
  }
1461
0
  err = wbcSidsToUnixIds(wbc_sids, wbc_ids_size, wbc_ids);
1462
0
  if (!WBC_ERROR_IS_OK(err)) {
1463
0
    DEBUG(10, ("wbcSidsToUnixIds returned %s\n",
1464
0
         wbcErrorString(err)));
1465
0
  }
1466
1467
  /*
1468
   * Second time through the SID array, replace
1469
   * the ids[] entries that wbcSidsToUnixIds() was able to
1470
   * map.
1471
   *
1472
   * Use bitmap_set() to mark an ids[] array entry as
1473
   * being mapped.
1474
   */
1475
1476
0
  num_not_cached = 0;
1477
1478
0
  for (i=0; i<num_sids; i++) {
1479
0
    if (bitmap_query(found, i)) {
1480
0
      continue;
1481
0
    }
1482
1483
0
    SMB_ASSERT(num_not_cached < wbc_ids_size);
1484
1485
0
    switch (wbc_ids[num_not_cached].type) {
1486
0
    case WBC_ID_TYPE_UID:
1487
0
      ids[i].type = ID_TYPE_UID;
1488
0
      ids[i].id = wbc_ids[num_not_cached].id.uid;
1489
0
      bitmap_set(found, i);
1490
0
      break;
1491
0
    case WBC_ID_TYPE_GID:
1492
0
      ids[i].type = ID_TYPE_GID;
1493
0
      ids[i].id = wbc_ids[num_not_cached].id.gid;
1494
0
      bitmap_set(found, i);
1495
0
      break;
1496
0
    case WBC_ID_TYPE_BOTH:
1497
0
      ids[i].type = ID_TYPE_BOTH;
1498
0
      ids[i].id = wbc_ids[num_not_cached].id.uid;
1499
0
      bitmap_set(found, i);
1500
0
      break;
1501
0
    case WBC_ID_TYPE_NOT_SPECIFIED:
1502
      /*
1503
       * wbcSidsToUnixIds() wasn't able to map this
1504
       * so we still need to check legacy_sid_to_XXX()
1505
       * below. Don't mark the bitmap entry
1506
       * as being found so the final loop knows
1507
       * to try and map this entry.
1508
       */
1509
0
      ids[i].type = ID_TYPE_NOT_SPECIFIED;
1510
0
      ids[i].id = (uint32_t)-1;
1511
0
      break;
1512
0
    default:
1513
      /*
1514
       * A successful return from wbcSidsToUnixIds()
1515
       * cannot return anything other than the values
1516
       * checked for above. Ensure this is so.
1517
       */
1518
0
      smb_panic(__location__);
1519
0
      break;
1520
0
    }
1521
0
    num_not_cached += 1;
1522
0
  }
1523
1524
  /*
1525
   * Third and final time through the SID array,
1526
   * try legacy_sid_to_gid()/legacy_sid_to_uid()
1527
   * for entries we haven't already been able to
1528
   * map.
1529
   *
1530
   * Use bitmap_set() to mark an ids[] array entry as
1531
   * being mapped.
1532
   */
1533
1534
0
  for (i=0; i<num_sids; i++) {
1535
0
    if (bitmap_query(found, i)) {
1536
0
      continue;
1537
0
    }
1538
0
    if (legacy_sid_to_gid(&sids[i], &ids[i].id)) {
1539
0
      ids[i].type = ID_TYPE_GID;
1540
0
      bitmap_set(found, i);
1541
0
      continue;
1542
0
    }
1543
0
    if (legacy_sid_to_uid(&sids[i], &ids[i].id)) {
1544
0
      ids[i].type = ID_TYPE_UID;
1545
0
      bitmap_set(found, i);
1546
0
      continue;
1547
0
    }
1548
0
  }
1549
0
done:
1550
  /*
1551
   * Pass through the return array for consistency.
1552
   * Any ids[].id mapped to (uint32_t)-1 must be returned
1553
   * as ID_TYPE_NOT_SPECIFIED.
1554
   */
1555
0
  for (i=0; i<num_sids; i++) {
1556
0
    switch(ids[i].type) {
1557
0
    case ID_TYPE_GID:
1558
0
    case ID_TYPE_UID:
1559
0
    case ID_TYPE_BOTH:
1560
0
      if (ids[i].id == (uint32_t)-1) {
1561
0
        ids[i].type = ID_TYPE_NOT_SPECIFIED;
1562
0
      }
1563
0
      break;
1564
0
    case ID_TYPE_NOT_SPECIFIED:
1565
0
      break;
1566
0
    case ID_TYPE_WB_REQUIRE_TYPE:
1567
      /*
1568
       * these are internal between winbindd
1569
       * parent and child.
1570
       */
1571
0
      smb_panic(__location__);
1572
0
      break;
1573
0
    }
1574
0
  }
1575
1576
0
  ret = true;
1577
0
fail:
1578
0
  TALLOC_FREE(wbc_ids);
1579
0
  TALLOC_FREE(wbc_sids);
1580
0
  return ret;
1581
0
}
1582
1583
/*****************************************************************
1584
 *THE CANONICAL* convert SID to uid function.
1585
*****************************************************************/
1586
1587
bool sid_to_uid(const struct dom_sid *psid, uid_t *puid)
1588
0
{
1589
0
  bool expired = true;
1590
0
  bool ret;
1591
0
  uint32_t rid;
1592
0
  struct dom_sid_buf buf;
1593
1594
  /* Optimize for the Unix Users Domain
1595
   * as the conversion is straightforward */
1596
0
  if (sid_peek_check_rid(&global_sid_Unix_Users, psid, &rid)) {
1597
0
    uid_t uid = rid;
1598
0
    *puid = uid;
1599
1600
    /* return here, don't cache */
1601
0
    DEBUG(10,("sid %s -> uid %u\n",
1602
0
        dom_sid_str_buf(psid, &buf),
1603
0
        (unsigned int)*puid ));
1604
0
    return true;
1605
0
  }
1606
1607
0
  if (sid_check_is_in_unix_groups(psid)) {
1608
0
    DBG_DEBUG("SID %s is a group, failing\n",
1609
0
        dom_sid_str_buf(psid, &buf));
1610
0
    return false;
1611
0
  }
1612
1613
  /* Check the winbindd cache directly. */
1614
0
  ret = idmap_cache_find_sid2uid(psid, puid, &expired);
1615
1616
0
  if (ret && !expired && (*puid == (uid_t)-1)) {
1617
    /*
1618
     * Negative cache entry, we already asked.
1619
     * do legacy.
1620
     */
1621
0
    return legacy_sid_to_uid(psid, puid);
1622
0
  }
1623
1624
0
  if (!ret || expired) {
1625
    /* Not in cache. Ask winbindd. */
1626
0
    if (!winbind_sid_to_uid(puid, psid)) {
1627
0
      DEBUG(5, ("winbind failed to find a uid for sid %s\n",
1628
0
          dom_sid_str_buf(psid, &buf)));
1629
      /* winbind failed. do legacy */
1630
0
      return legacy_sid_to_uid(psid, puid);
1631
0
    }
1632
0
  }
1633
1634
  /* TODO: Here would be the place to allocate both a gid and a uid for
1635
   * the SID in question */
1636
1637
0
  DEBUG(10,("sid %s -> uid %u\n",
1638
0
      dom_sid_str_buf(psid, &buf),
1639
0
    (unsigned int)*puid ));
1640
1641
0
  return true;
1642
0
}
1643
1644
/*****************************************************************
1645
 *THE CANONICAL* convert SID to gid function.
1646
 Group mapping is used for gids that maps to Wellknown SIDs
1647
*****************************************************************/
1648
1649
bool sid_to_gid(const struct dom_sid *psid, gid_t *pgid)
1650
0
{
1651
0
  bool expired = true;
1652
0
  bool ret;
1653
0
  uint32_t rid;
1654
0
  struct dom_sid_buf buf;
1655
1656
  /* Optimize for the Unix Groups Domain
1657
   * as the conversion is straightforward */
1658
0
  if (sid_peek_check_rid(&global_sid_Unix_Groups, psid, &rid)) {
1659
0
    gid_t gid = rid;
1660
0
    *pgid = gid;
1661
1662
    /* return here, don't cache */
1663
0
    DEBUG(10,("sid %s -> gid %u\n",
1664
0
        dom_sid_str_buf(psid, &buf),
1665
0
      (unsigned int)*pgid ));
1666
0
    return true;
1667
0
  }
1668
1669
0
  if (sid_check_is_in_unix_users(psid)) {
1670
0
    DBG_DEBUG("SID %s is a user, failing\n",
1671
0
        dom_sid_str_buf(psid, &buf));
1672
0
    return false;
1673
0
  }
1674
1675
  /* Check the winbindd cache directly. */
1676
0
  ret = idmap_cache_find_sid2gid(psid, pgid, &expired);
1677
1678
0
  if (ret && !expired && (*pgid == (gid_t)-1)) {
1679
    /*
1680
     * Negative cache entry, we already asked.
1681
     * do legacy.
1682
     */
1683
0
    return legacy_sid_to_gid(psid, pgid);
1684
0
  }
1685
1686
0
  if (!ret || expired) {
1687
    /* Not in cache or negative. Ask winbindd. */
1688
    /* Ask winbindd if it can map this sid to a gid.
1689
     * (Idmap will check it is a valid SID and of the right type) */
1690
1691
0
    if ( !winbind_sid_to_gid(pgid, psid) ) {
1692
1693
0
      DEBUG(10,("winbind failed to find a gid for sid %s\n",
1694
0
          dom_sid_str_buf(psid, &buf)));
1695
      /* winbind failed. do legacy */
1696
0
      return legacy_sid_to_gid(psid, pgid);
1697
0
    }
1698
0
  }
1699
1700
0
  DEBUG(10,("sid %s -> gid %u\n",
1701
0
      dom_sid_str_buf(psid, &buf),
1702
0
      (unsigned int)*pgid ));
1703
1704
0
  return true;
1705
0
}
1706
1707
/**
1708
 * @brief This function gets the primary group SID mapping the primary
1709
 *        GID of the user as obtained by an actual getpwnam() call.
1710
 *        This is necessary to avoid issues with arbitrary group SIDs
1711
 *        stored in passdb. We try as hard as we can to get the SID
1712
 *        corresponding to the GID, including trying group mapping.
1713
 *        If nothing else works, we will force "Domain Users" as the
1714
 *        primary group.
1715
 *        This is needed because we must always be able to lookup the
1716
 *        primary group SID, so we cannot settle for an arbitrary SID.
1717
 *
1718
 *        This call can be expensive. Use with moderation.
1719
 *        If you have a "samu" struct around use pdb_get_group_sid()
1720
 *        instead as it does properly cache results.
1721
 *
1722
 * @param mem_ctx[in]     The memory context iused to allocate the result.
1723
 * @param username[in]    The user's name
1724
 * @param _pwd[in|out]    If available, pass in user's passwd struct.
1725
 *                        It will contain a tallocated passwd if NULL was
1726
 *                        passed in.
1727
 * @param _group_sid[out] The user's Primary Group SID
1728
 *
1729
 * @return NTSTATUS error code.
1730
 */
1731
NTSTATUS get_primary_group_sid(TALLOC_CTX *mem_ctx,
1732
        const char *username,
1733
        struct passwd **_pwd,
1734
        struct dom_sid **_group_sid)
1735
0
{
1736
0
  TALLOC_CTX *tmp_ctx;
1737
0
  bool need_lookup_sid = false;
1738
0
  struct dom_sid *group_sid;
1739
0
  struct passwd *pwd = *_pwd;
1740
1741
0
  tmp_ctx = talloc_new(mem_ctx);
1742
0
  if (!tmp_ctx) {
1743
0
    return NT_STATUS_NO_MEMORY;
1744
0
  }
1745
1746
0
  if (!pwd) {
1747
0
    pwd = Get_Pwnam_alloc(mem_ctx, username);
1748
0
    if (!pwd) {
1749
0
      DEBUG(0, ("Failed to find a Unix account for %s\n",
1750
0
          username));
1751
0
      TALLOC_FREE(tmp_ctx);
1752
0
      return NT_STATUS_NO_SUCH_USER;
1753
0
    }
1754
0
  }
1755
1756
0
  group_sid = talloc_zero(mem_ctx, struct dom_sid);
1757
0
  if (!group_sid) {
1758
0
    TALLOC_FREE(tmp_ctx);
1759
0
    return NT_STATUS_NO_MEMORY;
1760
0
  }
1761
1762
0
  gid_to_sid(group_sid, pwd->pw_gid);
1763
0
  if (!is_null_sid(group_sid)) {
1764
0
    struct dom_sid domain_sid;
1765
0
    uint32_t rid;
1766
1767
    /* We need a sid within our domain */
1768
0
    sid_copy(&domain_sid, group_sid);
1769
0
    sid_split_rid(&domain_sid, &rid);
1770
0
    if (dom_sid_equal(&domain_sid, get_global_sam_sid())) {
1771
      /*
1772
       * As shortcut for the expensive lookup_sid call
1773
       * compare the domain sid part
1774
       */
1775
0
      switch (rid) {
1776
0
      case DOMAIN_RID_ADMINS:
1777
0
      case DOMAIN_RID_USERS:
1778
0
        goto done;
1779
0
      default:
1780
0
        need_lookup_sid = true;
1781
0
        break;
1782
0
      }
1783
0
    } else {
1784
      /* Try group mapping */
1785
0
      struct unixid id;
1786
1787
0
      id.id = pwd->pw_gid;
1788
0
      id.type = ID_TYPE_GID;
1789
1790
0
      ZERO_STRUCTP(group_sid);
1791
0
      if (pdb_id_to_sid(&id, group_sid)) {
1792
0
        need_lookup_sid = true;
1793
0
      }
1794
0
    }
1795
0
  }
1796
1797
  /* We must verify that this is a valid SID that resolves to a
1798
   * group of the correct type */
1799
0
  if (need_lookup_sid) {
1800
0
    enum lsa_SidType type = SID_NAME_UNKNOWN;
1801
0
    bool lookup_ret;
1802
0
    struct dom_sid_buf buf;
1803
1804
0
    DEBUG(10, ("do lookup_sid(%s) for group of user %s\n",
1805
0
         dom_sid_str_buf(group_sid, &buf),
1806
0
         username));
1807
1808
    /* Now check that it's actually a domain group and
1809
     * not something else */
1810
0
    lookup_ret = lookup_sid(tmp_ctx, group_sid,
1811
0
          NULL, NULL, &type);
1812
1813
0
    if (lookup_ret && (type == SID_NAME_DOM_GRP)) {
1814
0
      goto done;
1815
0
    }
1816
1817
0
    DEBUG(3, ("Primary group %s for user %s is"
1818
0
        " a %s and not a domain group\n",
1819
0
        dom_sid_str_buf(group_sid, &buf),
1820
0
        username,
1821
0
        sid_type_lookup(type)));
1822
0
  }
1823
1824
  /* Everything else, failed.
1825
   * Just set it to the 'Domain Users' RID of 513 which will
1826
     always resolve to a name */
1827
0
  DEBUG(3, ("Forcing Primary Group to 'Domain Users' for %s\n",
1828
0
      username));
1829
1830
0
  sid_compose(group_sid, get_global_sam_sid(), DOMAIN_RID_USERS);
1831
1832
0
done:
1833
0
  *_pwd = talloc_move(mem_ctx, &pwd);
1834
0
  *_group_sid = talloc_move(mem_ctx, &group_sid);
1835
0
  TALLOC_FREE(tmp_ctx);
1836
0
  return NT_STATUS_OK;
1837
0
}
1838