Coverage Report

Created: 2026-01-16 06:47

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/samba/source3/passdb/pdb_ldap.c
Line
Count
Source
1
/*
2
   Unix SMB/CIFS implementation.
3
   LDAP protocol helper functions for SAMBA
4
   Copyright (C) Jean François Micouleau 1998
5
   Copyright (C) Gerald Carter      2001-2003
6
   Copyright (C) Shahms King      2001
7
   Copyright (C) Andrew Bartlett    2002-2003
8
   Copyright (C) Stefan (metze) Metzmacher  2002-2003
9
   Copyright (C) Simo Sorce     2006
10
11
   This program is free software; you can redistribute it and/or modify
12
   it under the terms of the GNU General Public License as published by
13
   the Free Software Foundation; either version 3 of the License, or
14
   (at your option) any later version.
15
16
   This program is distributed in the hope that it will be useful,
17
   but WITHOUT ANY WARRANTY; without even the implied warranty of
18
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
   GNU General Public License for more details.
20
21
   You should have received a copy of the GNU General Public License
22
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
23
24
*/
25
26
/* TODO:
27
*  persistent connections: if using NSS LDAP, many connections are made
28
*      however, using only one within Samba would be nice
29
*
30
*  Clean up SSL stuff, compile on OpenLDAP 1.x, 2.x, and Netscape SDK
31
*
32
*  Other LDAP based login attributes: accountExpires, etc.
33
*  (should be the domain of Samba proper, but the sam_password/struct samu
34
*  structures don't have fields for some of these attributes)
35
*
36
*  SSL is done, but can't get the certificate based authentication to work
37
*  against on my test platform (Linux 2.4, OpenLDAP 2.x)
38
*/
39
40
/* NOTE: this will NOT work against an Active Directory server
41
*  due to the fact that the two password fields cannot be retrieved
42
*  from a server; recommend using security = domain in this situation
43
*  and/or winbind
44
*/
45
46
#include "includes.h"
47
#include "passdb.h"
48
#include "../libcli/auth/libcli_auth.h"
49
#include "secrets.h"
50
#include "idmap_cache.h"
51
#include "../libcli/security/security.h"
52
#include "../lib/util/util_pw.h"
53
#include "lib/winbind_util.h"
54
#include "librpc/gen_ndr/idmap.h"
55
#include "lib/param/loadparm.h"
56
#include "lib/util_sid_passdb.h"
57
#include "lib/util/smb_strtox.h"
58
#include "lib/util/string_wrappers.h"
59
#include "source3/lib/substitute.h"
60
61
#undef DBGC_CLASS
62
0
#define DBGC_CLASS DBGC_PASSDB
63
64
#include <lber.h>
65
#include <ldap.h>
66
67
68
#include "smbldap.h"
69
#include "passdb/pdb_ldap.h"
70
#include "passdb/pdb_nds.h"
71
#include "passdb/pdb_ldap_util.h"
72
#include "passdb/pdb_ldap_schema.h"
73
74
/**********************************************************************
75
 Simple helper function to make stuff better readable
76
 **********************************************************************/
77
78
LDAP *priv2ld(struct ldapsam_privates *priv)
79
0
{
80
0
  return smbldap_get_ldap(priv->smbldap_state);
81
0
}
82
83
/**********************************************************************
84
 Get the attribute name given a user schema version.
85
 **********************************************************************/
86
87
static const char* get_userattr_key2string( int schema_ver, int key )
88
0
{
89
0
  switch ( schema_ver ) {
90
0
    case SCHEMAVER_SAMBASAMACCOUNT:
91
0
      return get_attr_key2string( attrib_map_v30, key );
92
93
0
    default:
94
0
      DEBUG(0,("get_userattr_key2string: unknown schema version specified\n"));
95
0
      break;
96
0
  }
97
0
  return NULL;
98
0
}
99
100
/**********************************************************************
101
 Return the list of attribute names given a user schema version.
102
**********************************************************************/
103
104
const char** get_userattr_list( TALLOC_CTX *mem_ctx, int schema_ver )
105
0
{
106
0
  switch ( schema_ver ) {
107
0
    case SCHEMAVER_SAMBASAMACCOUNT:
108
0
      return get_attr_list( mem_ctx, attrib_map_v30 );
109
0
    default:
110
0
      DEBUG(0,("get_userattr_list: unknown schema version specified!\n"));
111
0
      break;
112
0
  }
113
114
0
  return NULL;
115
0
}
116
117
/**************************************************************************
118
 Return the list of attribute names to delete given a user schema version.
119
**************************************************************************/
120
121
static const char** get_userattr_delete_list( TALLOC_CTX *mem_ctx,
122
                int schema_ver )
123
0
{
124
0
  switch ( schema_ver ) {
125
0
    case SCHEMAVER_SAMBASAMACCOUNT:
126
0
      return get_attr_list( mem_ctx,
127
0
                attrib_map_to_delete_v30 );
128
0
    default:
129
0
      DEBUG(0,("get_userattr_delete_list: unknown schema version specified!\n"));
130
0
      break;
131
0
  }
132
133
0
  return NULL;
134
0
}
135
136
137
/*******************************************************************
138
 Generate the LDAP search filter for the objectclass based on the
139
 version of the schema we are using.
140
******************************************************************/
141
142
static const char* get_objclass_filter( int schema_ver )
143
0
{
144
0
  fstring objclass_filter;
145
0
  char *result;
146
147
0
  switch( schema_ver ) {
148
0
    case SCHEMAVER_SAMBASAMACCOUNT:
149
0
      fstr_sprintf( objclass_filter, "(objectclass=%s)", LDAP_OBJ_SAMBASAMACCOUNT );
150
0
      break;
151
0
    default:
152
0
      DEBUG(0,("get_objclass_filter: Invalid schema version specified!\n"));
153
0
      objclass_filter[0] = '\0';
154
0
      break;
155
0
  }
156
157
0
  result = talloc_strdup(talloc_tos(), objclass_filter);
158
0
  SMB_ASSERT(result != NULL);
159
0
  return result;
160
0
}
161
162
/*****************************************************************
163
 Scan a sequence number off OpenLDAP's syncrepl contextCSN
164
******************************************************************/
165
166
static NTSTATUS ldapsam_get_seq_num(struct pdb_methods *my_methods, time_t *seq_num)
167
0
{
168
0
  struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
169
0
  NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL;
170
0
  LDAPMessage *msg = NULL;
171
0
  LDAPMessage *entry = NULL;
172
0
  TALLOC_CTX *mem_ctx;
173
0
  char **values = NULL;
174
0
  int rc, num_result, num_values, rid;
175
0
  char *suffix = NULL;
176
0
  char *tok;
177
0
  const char *p;
178
0
  const char **attrs;
179
180
  /* Unfortunately there is no proper way to detect syncrepl-support in
181
   * smbldap_connect_system(). The syncrepl OIDs are submitted for publication
182
   * but do not show up in the root-DSE yet. Neither we can query the
183
   * subschema-context for the syncProviderSubentry or syncConsumerSubentry
184
   * objectclass. Currently we require lp_ldap_suffix() to show up as
185
   * namingContext.  -  Guenther
186
   */
187
188
0
  if (!lp_parm_bool(-1, "ldapsam", "syncrepl_seqnum", False)) {
189
0
    return ntstatus;
190
0
  }
191
192
0
  if (!seq_num) {
193
0
    DEBUG(3,("ldapsam_get_seq_num: no sequence_number\n"));
194
0
    return ntstatus;
195
0
  }
196
197
0
  if (!smbldap_has_naming_context(
198
0
        smbldap_get_ldap(ldap_state->smbldap_state),
199
0
        lp_ldap_suffix())) {
200
0
    DEBUG(3,("ldapsam_get_seq_num: DIT not configured to hold %s "
201
0
       "as top-level namingContext\n", lp_ldap_suffix()));
202
0
    return ntstatus;
203
0
  }
204
205
0
  mem_ctx = talloc_init("ldapsam_get_seq_num");
206
207
0
  if (mem_ctx == NULL)
208
0
    return NT_STATUS_NO_MEMORY;
209
210
0
  if ((attrs = talloc_array(mem_ctx, const char *, 2)) == NULL) {
211
0
    ntstatus = NT_STATUS_NO_MEMORY;
212
0
    goto done;
213
0
  }
214
215
  /* if we got a syncrepl-rid (up to three digits long) we speak with a consumer */
216
0
  rid = lp_parm_int(-1, "ldapsam", "syncrepl_rid", -1);
217
0
  if (rid > 0) {
218
219
    /* consumer syncreplCookie: */
220
    /* csn=20050126161620Z#0000001#00#00000 */
221
0
    attrs[0] = talloc_strdup(mem_ctx, "syncreplCookie");
222
0
    attrs[1] = NULL;
223
0
    suffix = talloc_asprintf(mem_ctx,
224
0
        "cn=syncrepl%d,%s", rid, lp_ldap_suffix());
225
0
    if (!suffix) {
226
0
      ntstatus = NT_STATUS_NO_MEMORY;
227
0
      goto done;
228
0
    }
229
0
  } else {
230
231
    /* provider contextCSN */
232
    /* 20050126161620Z#000009#00#000000 */
233
0
    attrs[0] = talloc_strdup(mem_ctx, "contextCSN");
234
0
    attrs[1] = NULL;
235
0
    suffix = talloc_asprintf(mem_ctx,
236
0
        "cn=ldapsync,%s", lp_ldap_suffix());
237
238
0
    if (!suffix) {
239
0
      ntstatus = NT_STATUS_NO_MEMORY;
240
0
      goto done;
241
0
    }
242
0
  }
243
244
0
  rc = smbldap_search(ldap_state->smbldap_state, suffix,
245
0
          LDAP_SCOPE_BASE, "(objectclass=*)", attrs, 0, &msg);
246
247
0
  if (rc != LDAP_SUCCESS) {
248
0
    goto done;
249
0
  }
250
251
0
  num_result = ldap_count_entries(
252
0
    smbldap_get_ldap(ldap_state->smbldap_state), msg);
253
0
  if (num_result != 1) {
254
0
    DEBUG(3,("ldapsam_get_seq_num: Expected one entry, got %d\n", num_result));
255
0
    goto done;
256
0
  }
257
258
0
  entry = ldap_first_entry(
259
0
    smbldap_get_ldap(ldap_state->smbldap_state), msg);
260
0
  if (entry == NULL) {
261
0
    DEBUG(3,("ldapsam_get_seq_num: Could not retrieve entry\n"));
262
0
    goto done;
263
0
  }
264
265
0
  values = ldap_get_values(
266
0
    smbldap_get_ldap(ldap_state->smbldap_state), entry, attrs[0]);
267
0
  if (values == NULL) {
268
0
    DEBUG(3,("ldapsam_get_seq_num: no values\n"));
269
0
    goto done;
270
0
  }
271
272
0
  num_values = ldap_count_values(values);
273
0
  if (num_values == 0) {
274
0
    DEBUG(3,("ldapsam_get_seq_num: not a single value\n"));
275
0
    goto done;
276
0
  }
277
278
0
  p = values[0];
279
0
  if (!next_token_talloc(mem_ctx, &p, &tok, "#")) {
280
0
    DEBUG(0,("ldapsam_get_seq_num: failed to parse sequence number\n"));
281
0
    goto done;
282
0
  }
283
284
0
  p = tok;
285
0
  if (!strncmp(p, "csn=", strlen("csn=")))
286
0
    p += strlen("csn=");
287
288
0
  DEBUG(10,("ldapsam_get_seq_num: got %s: %s\n", attrs[0], p));
289
290
0
  *seq_num = generalized_to_unix_time(p);
291
292
  /* very basic sanity check */
293
0
  if (*seq_num <= 0) {
294
0
    DBG_NOTICE("invalid sequence number: %" PRIi64 "\n",
295
0
         (int64_t)(*seq_num));
296
0
    goto done;
297
0
  }
298
299
0
  ntstatus = NT_STATUS_OK;
300
301
0
 done:
302
0
  if (values != NULL)
303
0
    ldap_value_free(values);
304
0
  if (msg != NULL)
305
0
    ldap_msgfree(msg);
306
0
  TALLOC_FREE(mem_ctx);
307
308
0
  return ntstatus;
309
0
}
310
311
/*******************************************************************
312
 Run the search by name.
313
******************************************************************/
314
315
int ldapsam_search_suffix_by_name(struct ldapsam_privates *ldap_state,
316
            const char *user,
317
            LDAPMessage ** result,
318
            const char **attr)
319
0
{
320
0
  char *filter = NULL;
321
0
  char *escape_user = escape_ldap_string(talloc_tos(), user);
322
0
  int ret = -1;
323
324
0
  if (!escape_user) {
325
0
    return LDAP_NO_MEMORY;
326
0
  }
327
328
  /*
329
   * in the filter expression, replace %u with the real name
330
   * so in ldap filter, %u MUST exist :-)
331
   */
332
0
  filter = talloc_asprintf(talloc_tos(), "(&%s%s)", "(uid=%u)",
333
0
    get_objclass_filter(ldap_state->schema_ver));
334
0
  if (!filter) {
335
0
    TALLOC_FREE(escape_user);
336
0
    return LDAP_NO_MEMORY;
337
0
  }
338
  /*
339
   * have to use this here because $ is filtered out
340
   * in string_sub
341
   */
342
343
0
  filter = talloc_all_string_sub(talloc_tos(),
344
0
        filter, "%u", escape_user);
345
0
  TALLOC_FREE(escape_user);
346
0
  if (!filter) {
347
0
    return LDAP_NO_MEMORY;
348
0
  }
349
350
0
  ret = smbldap_search_suffix(ldap_state->smbldap_state,
351
0
      filter, attr, result);
352
0
  TALLOC_FREE(filter);
353
0
  return ret;
354
0
}
355
356
/*******************************************************************
357
 Run the search by SID.
358
******************************************************************/
359
360
static int ldapsam_search_suffix_by_sid (struct ldapsam_privates *ldap_state,
361
         const struct dom_sid *sid, LDAPMessage ** result,
362
         const char **attr)
363
0
{
364
0
  char *filter = NULL;
365
0
  int rc;
366
0
  struct dom_sid_buf sid_string;
367
368
0
  filter = talloc_asprintf(talloc_tos(), "(&(%s=%s)%s)",
369
0
    get_userattr_key2string(ldap_state->schema_ver,
370
0
      LDAP_ATTR_USER_SID),
371
0
    dom_sid_str_buf(sid, &sid_string),
372
0
    get_objclass_filter(ldap_state->schema_ver));
373
0
  if (!filter) {
374
0
    return LDAP_NO_MEMORY;
375
0
  }
376
377
0
  rc = smbldap_search_suffix(ldap_state->smbldap_state,
378
0
      filter, attr, result);
379
380
0
  TALLOC_FREE(filter);
381
0
  return rc;
382
0
}
383
384
/*******************************************************************
385
 Delete complete object or objectclass and attrs from
386
 object found in search_result depending on lp_ldap_delete_dn
387
******************************************************************/
388
389
static int ldapsam_delete_entry(struct ldapsam_privates *priv,
390
        TALLOC_CTX *mem_ctx,
391
        LDAPMessage *entry,
392
        const char *objectclass,
393
        const char **attrs)
394
0
{
395
0
  LDAPMod **mods = NULL;
396
0
  char *name;
397
0
  const char *dn;
398
0
  BerElement *ptr = NULL;
399
400
0
  dn = smbldap_talloc_dn(mem_ctx, priv2ld(priv), entry);
401
0
  if (dn == NULL) {
402
0
    return LDAP_NO_MEMORY;
403
0
  }
404
405
0
  if (lp_ldap_delete_dn()) {
406
0
    return smbldap_delete(priv->smbldap_state, dn);
407
0
  }
408
409
  /* Ok, delete only the SAM attributes */
410
411
0
  for (name = ldap_first_attribute(priv2ld(priv), entry, &ptr);
412
0
       name != NULL;
413
0
       name = ldap_next_attribute(priv2ld(priv), entry, ptr)) {
414
0
    const char **attrib;
415
416
    /* We are only allowed to delete the attributes that
417
       really exist. */
418
419
0
    for (attrib = attrs; *attrib != NULL; attrib++) {
420
0
      if (strequal(*attrib, name)) {
421
0
        DEBUG(10, ("ldapsam_delete_entry: deleting "
422
0
             "attribute %s\n", name));
423
0
        smbldap_set_mod(&mods, LDAP_MOD_DELETE, name,
424
0
            NULL);
425
0
      }
426
0
    }
427
0
    ldap_memfree(name);
428
0
  }
429
430
0
  if (ptr != NULL) {
431
0
    ber_free(ptr, 0);
432
0
  }
433
434
0
  smbldap_set_mod(&mods, LDAP_MOD_DELETE, "objectClass", objectclass);
435
0
  smbldap_talloc_autofree_ldapmod(mem_ctx, mods);
436
437
0
  return smbldap_modify(priv->smbldap_state, dn, mods);
438
0
}
439
440
static time_t ldapsam_get_entry_timestamp( struct ldapsam_privates *ldap_state, LDAPMessage * entry)
441
0
{
442
0
  char *temp;
443
0
  struct tm tm = {};
444
445
0
  temp = smbldap_talloc_single_attribute(
446
0
    smbldap_get_ldap(ldap_state->smbldap_state), entry,
447
0
    get_userattr_key2string(ldap_state->schema_ver,
448
0
          LDAP_ATTR_MOD_TIMESTAMP),
449
0
      talloc_tos());
450
0
  if (!temp) {
451
0
    return (time_t) 0;
452
0
  }
453
454
0
  if ( !strptime(temp, "%Y%m%d%H%M%SZ", &tm)) {
455
0
    DEBUG(2,("ldapsam_get_entry_timestamp: strptime failed on: %s\n",
456
0
      (char*)temp));
457
0
    TALLOC_FREE(temp);
458
0
    return (time_t) 0;
459
0
  }
460
0
  TALLOC_FREE(temp);
461
0
  tzset();
462
0
  return timegm(&tm);
463
0
}
464
465
/**********************************************************************
466
 Initialize struct samu from an LDAP query.
467
 (Based on init_sam_from_buffer in pdb_tdb.c)
468
*********************************************************************/
469
470
static bool init_sam_from_ldap(struct ldapsam_privates *ldap_state,
471
        struct samu * sampass,
472
        LDAPMessage * entry)
473
0
{
474
0
  time_t  logon_time,
475
0
      logoff_time,
476
0
      kickoff_time,
477
0
      pass_last_set_time,
478
0
      pass_can_change_time,
479
0
      ldap_entry_time,
480
0
      bad_password_time;
481
0
  char *username = NULL,
482
0
      *domain = NULL,
483
0
      *nt_username = NULL,
484
0
      *fullname = NULL,
485
0
      *homedir = NULL,
486
0
      *dir_drive = NULL,
487
0
      *logon_script = NULL,
488
0
      *profile_path = NULL,
489
0
      *acct_desc = NULL,
490
0
      *workstations = NULL,
491
0
      *munged_dial = NULL;
492
0
  uint32_t    user_rid;
493
0
  uint8_t   smblmpwd[LM_HASH_LEN],
494
0
      smbntpwd[NT_HASH_LEN];
495
0
  bool    use_samba_attrs = True;
496
0
  uint16_t    logon_divs;
497
0
  uint16_t    bad_password_count = 0,
498
0
      logon_count = 0;
499
0
  uint32_t hours_len;
500
0
  uint8_t   hours[MAX_HOURS_LEN];
501
0
  char *temp = NULL;
502
0
  struct login_cache cache_entry;
503
0
  uint32_t    pwHistLen;
504
0
  bool expand_explicit = lp_passdb_expand_explicit();
505
0
  bool ret = false;
506
0
  TALLOC_CTX *ctx = talloc_init("init_sam_from_ldap");
507
508
0
  if (!ctx) {
509
0
    return false;
510
0
  }
511
0
  if (sampass == NULL || ldap_state == NULL || entry == NULL) {
512
0
    DEBUG(0, ("init_sam_from_ldap: NULL parameters found!\n"));
513
0
    goto fn_exit;
514
0
  }
515
516
0
  if (priv2ld(ldap_state) == NULL) {
517
0
    DEBUG(0, ("init_sam_from_ldap: ldap_state->smbldap_state->"
518
0
        "ldap_struct is NULL!\n"));
519
0
    goto fn_exit;
520
0
  }
521
522
0
  if (!(username = smbldap_talloc_first_attribute(priv2ld(ldap_state),
523
0
          entry,
524
0
          "uid",
525
0
          ctx))) {
526
0
    DEBUG(1, ("init_sam_from_ldap: No uid attribute found for "
527
0
        "this user!\n"));
528
0
    goto fn_exit;
529
0
  }
530
531
0
  DEBUG(2, ("init_sam_from_ldap: Entry found for user: %s\n", username));
532
533
0
  nt_username = talloc_strdup(ctx, username);
534
0
  if (!nt_username) {
535
0
    goto fn_exit;
536
0
  }
537
538
0
  domain = talloc_strdup(ctx, ldap_state->domain_name);
539
0
  if (!domain) {
540
0
    goto fn_exit;
541
0
  }
542
543
0
  pdb_set_username(sampass, username, PDB_SET);
544
545
0
  pdb_set_domain(sampass, domain, PDB_DEFAULT);
546
0
  pdb_set_nt_username(sampass, nt_username, PDB_SET);
547
548
  /* deal with different attributes between the schema first */
549
550
0
  if ( ldap_state->schema_ver == SCHEMAVER_SAMBASAMACCOUNT ) {
551
0
    if ((temp = smbldap_talloc_single_attribute(
552
0
        smbldap_get_ldap(ldap_state->smbldap_state),
553
0
        entry,
554
0
        get_userattr_key2string(ldap_state->schema_ver,
555
0
          LDAP_ATTR_USER_SID),
556
0
        ctx))!=NULL) {
557
0
      pdb_set_user_sid_from_string(sampass, temp, PDB_SET);
558
0
    }
559
0
  } else {
560
0
    if ((temp = smbldap_talloc_single_attribute(
561
0
        smbldap_get_ldap(ldap_state->smbldap_state),
562
0
        entry,
563
0
        get_userattr_key2string(ldap_state->schema_ver,
564
0
          LDAP_ATTR_USER_RID),
565
0
        ctx))!=NULL) {
566
0
      user_rid = (uint32_t)atol(temp);
567
0
      pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
568
0
    }
569
0
  }
570
571
0
  if (IS_SAM_DEFAULT(sampass, PDB_USERSID)) {
572
0
    DEBUG(1, ("init_sam_from_ldap: no %s or %s attribute found for this user %s\n",
573
0
      get_userattr_key2string(ldap_state->schema_ver,
574
0
        LDAP_ATTR_USER_SID),
575
0
      get_userattr_key2string(ldap_state->schema_ver,
576
0
        LDAP_ATTR_USER_RID),
577
0
      username));
578
0
    return False;
579
0
  }
580
581
0
  temp = smbldap_talloc_single_attribute(
582
0
      smbldap_get_ldap(ldap_state->smbldap_state),
583
0
      entry,
584
0
      get_userattr_key2string(ldap_state->schema_ver,
585
0
        LDAP_ATTR_PWD_LAST_SET),
586
0
      ctx);
587
0
  if (temp) {
588
0
    pass_last_set_time = (time_t) atol(temp);
589
0
    pdb_set_pass_last_set_time(sampass,
590
0
        pass_last_set_time, PDB_SET);
591
0
  }
592
593
0
  temp = smbldap_talloc_single_attribute(
594
0
      smbldap_get_ldap(ldap_state->smbldap_state),
595
0
      entry,
596
0
      get_userattr_key2string(ldap_state->schema_ver,
597
0
        LDAP_ATTR_LOGON_TIME),
598
0
      ctx);
599
0
  if (temp) {
600
0
    logon_time = (time_t) atol(temp);
601
0
    pdb_set_logon_time(sampass, logon_time, PDB_SET);
602
0
  }
603
604
0
  temp = smbldap_talloc_single_attribute(
605
0
      smbldap_get_ldap(ldap_state->smbldap_state),
606
0
      entry,
607
0
      get_userattr_key2string(ldap_state->schema_ver,
608
0
        LDAP_ATTR_LOGOFF_TIME),
609
0
      ctx);
610
0
  if (temp) {
611
0
    logoff_time = (time_t) atol(temp);
612
0
    pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
613
0
  }
614
615
0
  temp = smbldap_talloc_single_attribute(
616
0
      smbldap_get_ldap(ldap_state->smbldap_state),
617
0
      entry,
618
0
      get_userattr_key2string(ldap_state->schema_ver,
619
0
        LDAP_ATTR_KICKOFF_TIME),
620
0
      ctx);
621
0
  if (temp) {
622
0
    kickoff_time = (time_t) atol(temp);
623
0
    pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
624
0
  }
625
626
0
  temp = smbldap_talloc_single_attribute(
627
0
      smbldap_get_ldap(ldap_state->smbldap_state),
628
0
      entry,
629
0
      get_userattr_key2string(ldap_state->schema_ver,
630
0
        LDAP_ATTR_PWD_CAN_CHANGE),
631
0
      ctx);
632
0
  if (temp) {
633
0
    pass_can_change_time = (time_t) atol(temp);
634
0
    pdb_set_pass_can_change_time(sampass,
635
0
        pass_can_change_time, PDB_SET);
636
0
  }
637
638
  /* recommend that 'gecos' and 'displayName' should refer to the same
639
   * attribute OID.  userFullName depreciated, only used by Samba
640
   * primary rules of LDAP: don't make a new attribute when one is already defined
641
   * that fits your needs; using cn then displayName rather than 'userFullName'
642
   */
643
644
0
  fullname = smbldap_talloc_single_attribute(
645
0
      smbldap_get_ldap(ldap_state->smbldap_state),
646
0
      entry,
647
0
      get_userattr_key2string(ldap_state->schema_ver,
648
0
        LDAP_ATTR_DISPLAY_NAME),
649
0
      ctx);
650
0
  if (fullname) {
651
0
    pdb_set_fullname(sampass, fullname, PDB_SET);
652
0
  } else {
653
0
    fullname = smbldap_talloc_single_attribute(
654
0
        smbldap_get_ldap(ldap_state->smbldap_state),
655
0
        entry,
656
0
        get_userattr_key2string(ldap_state->schema_ver,
657
0
          LDAP_ATTR_CN),
658
0
        ctx);
659
0
    if (fullname) {
660
0
      pdb_set_fullname(sampass, fullname, PDB_SET);
661
0
    }
662
0
  }
663
664
0
  dir_drive = smbldap_talloc_single_attribute(
665
0
      smbldap_get_ldap(ldap_state->smbldap_state),
666
0
      entry,
667
0
      get_userattr_key2string(ldap_state->schema_ver,
668
0
        LDAP_ATTR_HOME_DRIVE),
669
0
      ctx);
670
0
  if (dir_drive) {
671
0
    pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
672
0
  } else {
673
0
    pdb_set_dir_drive( sampass, lp_logon_drive(), PDB_DEFAULT );
674
0
  }
675
676
0
  homedir = smbldap_talloc_single_attribute(
677
0
      smbldap_get_ldap(ldap_state->smbldap_state),
678
0
      entry,
679
0
      get_userattr_key2string(ldap_state->schema_ver,
680
0
        LDAP_ATTR_HOME_PATH),
681
0
      ctx);
682
0
  if (homedir) {
683
0
    if (expand_explicit) {
684
0
      homedir = talloc_sub_basic(ctx,
685
0
            username,
686
0
            domain,
687
0
            homedir);
688
0
      if (!homedir) {
689
0
        goto fn_exit;
690
0
      }
691
0
    }
692
0
    pdb_set_homedir(sampass, homedir, PDB_SET);
693
0
  } else {
694
0
    pdb_set_homedir(sampass,
695
0
      talloc_sub_basic(ctx, username, domain,
696
0
           lp_logon_home()),
697
0
      PDB_DEFAULT);
698
0
  }
699
700
0
  logon_script = smbldap_talloc_single_attribute(
701
0
      smbldap_get_ldap(ldap_state->smbldap_state),
702
0
      entry,
703
0
      get_userattr_key2string(ldap_state->schema_ver,
704
0
        LDAP_ATTR_LOGON_SCRIPT),
705
0
      ctx);
706
0
  if (logon_script) {
707
0
    if (expand_explicit) {
708
0
      logon_script = talloc_sub_basic(ctx,
709
0
            username,
710
0
            domain,
711
0
            logon_script);
712
0
      if (!logon_script) {
713
0
        goto fn_exit;
714
0
      }
715
0
    }
716
0
    pdb_set_logon_script(sampass, logon_script, PDB_SET);
717
0
  } else {
718
0
    pdb_set_logon_script(sampass,
719
0
      talloc_sub_basic(ctx, username, domain,
720
0
           lp_logon_script()),
721
0
      PDB_DEFAULT );
722
0
  }
723
724
0
  profile_path = smbldap_talloc_single_attribute(
725
0
      smbldap_get_ldap(ldap_state->smbldap_state),
726
0
      entry,
727
0
      get_userattr_key2string(ldap_state->schema_ver,
728
0
        LDAP_ATTR_PROFILE_PATH),
729
0
      ctx);
730
0
  if (profile_path) {
731
0
    if (expand_explicit) {
732
0
      profile_path = talloc_sub_basic(ctx,
733
0
            username,
734
0
            domain,
735
0
            profile_path);
736
0
      if (!profile_path) {
737
0
        goto fn_exit;
738
0
      }
739
0
    }
740
0
    pdb_set_profile_path(sampass, profile_path, PDB_SET);
741
0
  } else {
742
0
    pdb_set_profile_path(sampass,
743
0
      talloc_sub_basic(ctx, username, domain,
744
0
            lp_logon_path()),
745
0
      PDB_DEFAULT );
746
0
  }
747
748
0
  acct_desc = smbldap_talloc_single_attribute(
749
0
      smbldap_get_ldap(ldap_state->smbldap_state),
750
0
      entry,
751
0
      get_userattr_key2string(ldap_state->schema_ver,
752
0
        LDAP_ATTR_DESC),
753
0
      ctx);
754
0
  if (acct_desc) {
755
0
    pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
756
0
  }
757
758
0
  workstations = smbldap_talloc_single_attribute(
759
0
      smbldap_get_ldap(ldap_state->smbldap_state),
760
0
      entry,
761
0
      get_userattr_key2string(ldap_state->schema_ver,
762
0
        LDAP_ATTR_USER_WKS),
763
0
      ctx);
764
0
  if (workstations) {
765
0
    pdb_set_workstations(sampass, workstations, PDB_SET);
766
0
  }
767
768
0
  munged_dial = smbldap_talloc_single_attribute(
769
0
      smbldap_get_ldap(ldap_state->smbldap_state),
770
0
      entry,
771
0
      get_userattr_key2string(ldap_state->schema_ver,
772
0
        LDAP_ATTR_MUNGED_DIAL),
773
0
      ctx);
774
0
  if (munged_dial) {
775
0
    pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
776
0
  }
777
778
  /* FIXME: hours stuff should be cleaner */
779
780
0
  logon_divs = 168;
781
0
  hours_len = 21;
782
0
  memset(hours, 0xff, hours_len);
783
784
0
  if (ldap_state->is_nds_ldap) {
785
0
    char *user_dn;
786
0
    size_t pwd_len;
787
0
    char clear_text_pw[512];
788
789
    /* Make call to Novell eDirectory ldap extension to get clear text password.
790
      NOTE: This will only work if we have an SSL connection to eDirectory. */
791
0
    user_dn = smbldap_talloc_dn(
792
0
      ctx, smbldap_get_ldap(ldap_state->smbldap_state),
793
0
      entry);
794
0
    if (user_dn != NULL) {
795
0
      DEBUG(3, ("init_sam_from_ldap: smbldap_talloc_dn(ctx, %s) returned '%s'\n", username, user_dn));
796
797
0
      pwd_len = sizeof(clear_text_pw);
798
0
      if (pdb_nds_get_password(ldap_state->smbldap_state, user_dn, &pwd_len, clear_text_pw) == LDAP_SUCCESS) {
799
0
        nt_lm_owf_gen(clear_text_pw, smbntpwd, smblmpwd);
800
0
        if (!pdb_set_lanman_passwd(sampass, smblmpwd, PDB_SET)) {
801
0
          TALLOC_FREE(user_dn);
802
0
          return False;
803
0
        }
804
0
        ZERO_STRUCT(smblmpwd);
805
0
        if (!pdb_set_nt_passwd(sampass, smbntpwd, PDB_SET)) {
806
0
          TALLOC_FREE(user_dn);
807
0
          return False;
808
0
        }
809
0
        ZERO_STRUCT(smbntpwd);
810
0
        use_samba_attrs = False;
811
0
      }
812
813
0
      TALLOC_FREE(user_dn);
814
815
0
    } else {
816
0
      DEBUG(0, ("init_sam_from_ldap: failed to get user_dn for '%s'\n", username));
817
0
    }
818
0
  }
819
820
0
  if (use_samba_attrs) {
821
0
    temp = smbldap_talloc_single_attribute(
822
0
        smbldap_get_ldap(ldap_state->smbldap_state),
823
0
        entry,
824
0
        get_userattr_key2string(ldap_state->schema_ver,
825
0
          LDAP_ATTR_LMPW),
826
0
        ctx);
827
0
    if (temp) {
828
0
      pdb_gethexpwd(temp, smblmpwd);
829
0
      memset((char *)temp, '\0', strlen(temp)+1);
830
0
      if (!pdb_set_lanman_passwd(sampass, smblmpwd, PDB_SET)) {
831
0
        goto fn_exit;
832
0
      }
833
0
      ZERO_STRUCT(smblmpwd);
834
0
    }
835
836
0
    temp = smbldap_talloc_single_attribute(
837
0
        smbldap_get_ldap(ldap_state->smbldap_state),
838
0
        entry,
839
0
        get_userattr_key2string(ldap_state->schema_ver,
840
0
          LDAP_ATTR_NTPW),
841
0
        ctx);
842
0
    if (temp) {
843
0
      pdb_gethexpwd(temp, smbntpwd);
844
0
      memset((char *)temp, '\0', strlen(temp)+1);
845
0
      if (!pdb_set_nt_passwd(sampass, smbntpwd, PDB_SET)) {
846
0
        goto fn_exit;
847
0
      }
848
0
      ZERO_STRUCT(smbntpwd);
849
0
    }
850
0
  }
851
852
0
  pwHistLen = 0;
853
854
0
  pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
855
0
  if (pwHistLen > 0){
856
0
    uint8_t *pwhist = NULL;
857
0
    int i;
858
0
    char *history_string = talloc_array(ctx, char,
859
0
            MAX_PW_HISTORY_LEN*64);
860
861
0
    if (!history_string) {
862
0
      goto fn_exit;
863
0
    }
864
865
0
    pwHistLen = MIN(pwHistLen, MAX_PW_HISTORY_LEN);
866
867
0
    pwhist = talloc_zero_array(ctx, uint8_t,
868
0
             pwHistLen * PW_HISTORY_ENTRY_LEN);
869
0
    if (pwhist == NULL) {
870
0
      DEBUG(0, ("init_sam_from_ldap: talloc failed!\n"));
871
0
      goto fn_exit;
872
0
    }
873
874
0
    if (smbldap_get_single_attribute(
875
0
        smbldap_get_ldap(ldap_state->smbldap_state),
876
0
        entry,
877
0
        get_userattr_key2string(ldap_state->schema_ver,
878
0
          LDAP_ATTR_PWD_HISTORY),
879
0
        history_string,
880
0
        MAX_PW_HISTORY_LEN*64)) {
881
0
      bool hex_failed = false;
882
0
      for (i = 0; i < pwHistLen; i++){
883
        /* Get the 16 byte salt. */
884
0
        if (!pdb_gethexpwd(&history_string[i*64],
885
0
          &pwhist[i*PW_HISTORY_ENTRY_LEN])) {
886
0
          hex_failed = true;
887
0
          break;
888
0
        }
889
        /* Get the 16 byte MD5 hash of salt+passwd. */
890
0
        if (!pdb_gethexpwd(&history_string[(i*64)+32],
891
0
          &pwhist[(i*PW_HISTORY_ENTRY_LEN)+
892
0
            PW_HISTORY_SALT_LEN])) {
893
0
          hex_failed = True;
894
0
          break;
895
0
        }
896
0
      }
897
0
      if (hex_failed) {
898
0
        DEBUG(2,("init_sam_from_ldap: Failed to get password history for user %s\n",
899
0
          username));
900
0
        memset(pwhist, '\0', pwHistLen * PW_HISTORY_ENTRY_LEN);
901
0
      }
902
0
    }
903
0
    if (!pdb_set_pw_history(sampass, pwhist, pwHistLen, PDB_SET)){
904
0
      goto fn_exit;
905
0
    }
906
0
  }
907
908
0
  temp = smbldap_talloc_single_attribute(
909
0
      smbldap_get_ldap(ldap_state->smbldap_state),
910
0
      entry,
911
0
      get_userattr_key2string(ldap_state->schema_ver,
912
0
        LDAP_ATTR_ACB_INFO),
913
0
      ctx);
914
0
  if (temp) {
915
0
    uint32_t acct_ctrl = 0;
916
0
    acct_ctrl = pdb_decode_acct_ctrl(temp);
917
918
0
    if (acct_ctrl == 0) {
919
0
      acct_ctrl |= ACB_NORMAL;
920
0
    }
921
922
0
    pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
923
0
  }
924
925
0
  pdb_set_hours_len(sampass, hours_len, PDB_SET);
926
0
  pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
927
928
0
  temp = smbldap_talloc_single_attribute(
929
0
      smbldap_get_ldap(ldap_state->smbldap_state),
930
0
      entry,
931
0
      get_userattr_key2string(ldap_state->schema_ver,
932
0
        LDAP_ATTR_BAD_PASSWORD_COUNT),
933
0
      ctx);
934
0
  if (temp) {
935
0
    bad_password_count = (uint32_t) atol(temp);
936
0
    pdb_set_bad_password_count(sampass,
937
0
        bad_password_count, PDB_SET);
938
0
  }
939
940
0
  temp = smbldap_talloc_single_attribute(
941
0
      smbldap_get_ldap(ldap_state->smbldap_state),
942
0
      entry,
943
0
      get_userattr_key2string(ldap_state->schema_ver,
944
0
        LDAP_ATTR_BAD_PASSWORD_TIME),
945
0
      ctx);
946
0
  if (temp) {
947
0
    bad_password_time = (time_t) atol(temp);
948
0
    pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
949
0
  }
950
951
952
0
  temp = smbldap_talloc_single_attribute(
953
0
      smbldap_get_ldap(ldap_state->smbldap_state),
954
0
      entry,
955
0
      get_userattr_key2string(ldap_state->schema_ver,
956
0
        LDAP_ATTR_LOGON_COUNT),
957
0
      ctx);
958
0
  if (temp) {
959
0
    logon_count = (uint32_t) atol(temp);
960
0
    pdb_set_logon_count(sampass, logon_count, PDB_SET);
961
0
  }
962
963
  /* pdb_set_unknown_6(sampass, unknown6, PDB_SET); */
964
965
0
  temp = smbldap_talloc_single_attribute(
966
0
      smbldap_get_ldap(ldap_state->smbldap_state),
967
0
      entry,
968
0
      get_userattr_key2string(ldap_state->schema_ver,
969
0
        LDAP_ATTR_LOGON_HOURS),
970
0
      ctx);
971
0
  if (temp) {
972
0
    pdb_gethexhours(temp, hours);
973
0
    memset((char *)temp, '\0', strlen(temp) +1);
974
0
    pdb_set_hours(sampass, hours, hours_len, PDB_SET);
975
0
    ZERO_STRUCT(hours);
976
0
  }
977
978
0
  if (lp_parm_bool(-1, "ldapsam", "trusted", False)) {
979
0
    struct passwd unix_pw;
980
0
    bool have_uid = false;
981
0
    bool have_gid = false;
982
0
    struct dom_sid mapped_gsid;
983
0
    const struct dom_sid *primary_gsid;
984
0
    struct unixid id;
985
0
    int error = 0;
986
987
0
    ZERO_STRUCT(unix_pw);
988
989
0
    unix_pw.pw_name = username;
990
0
    unix_pw.pw_passwd = discard_const_p(char, "x");
991
992
0
    temp = smbldap_talloc_single_attribute(
993
0
        priv2ld(ldap_state),
994
0
        entry,
995
0
        "uidNumber",
996
0
        ctx);
997
0
    if (temp) {
998
      /* We've got a uid, feed the cache */
999
0
      unix_pw.pw_uid = smb_strtoul(temp,
1000
0
                 NULL,
1001
0
                 10,
1002
0
                 &error,
1003
0
                 SMB_STR_STANDARD);
1004
0
      if (error != 0) {
1005
0
        DBG_ERR("Failed to convert UID\n");
1006
0
        goto fn_exit;
1007
0
      }
1008
0
      have_uid = true;
1009
0
    }
1010
0
    temp = smbldap_talloc_single_attribute(
1011
0
        priv2ld(ldap_state),
1012
0
        entry,
1013
0
        "gidNumber",
1014
0
        ctx);
1015
0
    if (temp) {
1016
      /* We've got a uid, feed the cache */
1017
0
      unix_pw.pw_gid = smb_strtoul(temp,
1018
0
                 NULL,
1019
0
                 10,
1020
0
                 &error,
1021
0
                 SMB_STR_STANDARD);
1022
0
      if (error != 0) {
1023
0
        DBG_ERR("Failed to convert GID\n");
1024
0
        goto fn_exit;
1025
0
      }
1026
0
      have_gid = true;
1027
0
    }
1028
0
    unix_pw.pw_gecos = smbldap_talloc_single_attribute(
1029
0
        priv2ld(ldap_state),
1030
0
        entry,
1031
0
        "gecos",
1032
0
        ctx);
1033
0
    if (unix_pw.pw_gecos == NULL) {
1034
0
      unix_pw.pw_gecos = fullname;
1035
0
    }
1036
0
    unix_pw.pw_dir = smbldap_talloc_single_attribute(
1037
0
        priv2ld(ldap_state),
1038
0
        entry,
1039
0
        "homeDirectory",
1040
0
        ctx);
1041
0
    if (unix_pw.pw_dir == NULL) {
1042
0
      unix_pw.pw_dir = discard_const_p(char, "");
1043
0
    }
1044
0
    unix_pw.pw_shell = smbldap_talloc_single_attribute(
1045
0
        priv2ld(ldap_state),
1046
0
        entry,
1047
0
        "loginShell",
1048
0
        ctx);
1049
0
    if (unix_pw.pw_shell == NULL) {
1050
0
      unix_pw.pw_shell = discard_const_p(char, "");
1051
0
    }
1052
1053
0
    if (have_uid && have_gid) {
1054
0
      sampass->unix_pw = tcopy_passwd(sampass, &unix_pw);
1055
0
    } else {
1056
0
      sampass->unix_pw = Get_Pwnam_alloc(sampass, unix_pw.pw_name);
1057
0
    }
1058
1059
0
    if (sampass->unix_pw == NULL) {
1060
0
      DEBUG(0,("init_sam_from_ldap: Failed to find Unix account for %s\n",
1061
0
         pdb_get_username(sampass)));
1062
0
      goto fn_exit;
1063
0
    }
1064
1065
0
    id.id = sampass->unix_pw->pw_uid;
1066
0
    id.type = ID_TYPE_UID;
1067
1068
0
    idmap_cache_set_sid2unixid(pdb_get_user_sid(sampass), &id);
1069
1070
0
    gid_to_sid(&mapped_gsid, sampass->unix_pw->pw_gid);
1071
0
    primary_gsid = pdb_get_group_sid(sampass);
1072
0
    if (primary_gsid && dom_sid_equal(primary_gsid, &mapped_gsid)) {
1073
0
      id.id = sampass->unix_pw->pw_gid;
1074
0
      id.type = ID_TYPE_GID;
1075
1076
0
      idmap_cache_set_sid2unixid(primary_gsid, &id);
1077
0
    }
1078
0
  }
1079
1080
  /* check the timestamp of the cache vs ldap entry */
1081
0
  if (!(ldap_entry_time = ldapsam_get_entry_timestamp(ldap_state,
1082
0
                  entry))) {
1083
0
    ret = true;
1084
0
    goto fn_exit;
1085
0
  }
1086
1087
  /* see if we have newer updates */
1088
0
  if (!login_cache_read(sampass, &cache_entry)) {
1089
0
    DEBUG (9, ("No cache entry, bad count = %u, bad time = %jd\n",
1090
0
         (unsigned int)pdb_get_bad_password_count(sampass),
1091
0
         (intmax_t)pdb_get_bad_password_time(sampass)));
1092
0
    ret = true;
1093
0
    goto fn_exit;
1094
0
  }
1095
1096
0
  DEBUG(7, ("ldap time is %jd, cache time is %jd, bad time = %jd\n",
1097
0
      (intmax_t)ldap_entry_time,
1098
0
      (intmax_t)cache_entry.entry_timestamp,
1099
0
      (intmax_t)cache_entry.bad_password_time));
1100
1101
0
  if (ldap_entry_time > cache_entry.entry_timestamp) {
1102
    /* cache is older than directory , so
1103
       we need to delete the entry but allow the
1104
       fields to be written out */
1105
0
    login_cache_delentry(sampass);
1106
0
  } else {
1107
    /* read cache in */
1108
0
    pdb_set_acct_ctrl(sampass,
1109
0
          pdb_get_acct_ctrl(sampass) |
1110
0
          (cache_entry.acct_ctrl & ACB_AUTOLOCK),
1111
0
          PDB_SET);
1112
0
    pdb_set_bad_password_count(sampass,
1113
0
             cache_entry.bad_password_count,
1114
0
             PDB_SET);
1115
0
    pdb_set_bad_password_time(sampass,
1116
0
            cache_entry.bad_password_time,
1117
0
            PDB_SET);
1118
0
  }
1119
1120
0
  ret = true;
1121
1122
0
  fn_exit:
1123
1124
0
  TALLOC_FREE(ctx);
1125
0
  return ret;
1126
0
}
1127
1128
/**********************************************************************
1129
 Initialize the ldap db from a struct samu. Called on update.
1130
 (Based on init_buffer_from_sam in pdb_tdb.c)
1131
*********************************************************************/
1132
1133
static bool init_ldap_from_sam (struct ldapsam_privates *ldap_state,
1134
        LDAPMessage *existing,
1135
        LDAPMod *** mods, struct samu * sampass,
1136
        bool (*need_update)(const struct samu *,
1137
                enum pdb_elements))
1138
0
{
1139
0
  char *temp = NULL;
1140
1141
0
  if (mods == NULL || sampass == NULL) {
1142
0
    DEBUG(0, ("init_ldap_from_sam: NULL parameters found!\n"));
1143
0
    return False;
1144
0
  }
1145
1146
0
  *mods = NULL;
1147
1148
  /*
1149
   * took out adding "objectclass: sambaAccount"
1150
   * do this on a per-mod basis
1151
   */
1152
0
  if (need_update(sampass, PDB_USERNAME)) {
1153
0
    smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state),
1154
0
         existing, mods,
1155
0
         "uid", pdb_get_username(sampass));
1156
0
    if (ldap_state->is_nds_ldap) {
1157
0
      smbldap_make_mod(
1158
0
        smbldap_get_ldap(ldap_state->smbldap_state),
1159
0
        existing, mods,
1160
0
        "cn", pdb_get_username(sampass));
1161
0
      smbldap_make_mod(
1162
0
        smbldap_get_ldap(ldap_state->smbldap_state),
1163
0
        existing, mods,
1164
0
        "sn", pdb_get_username(sampass));
1165
0
    }
1166
0
  }
1167
1168
0
  DEBUG(2, ("init_ldap_from_sam: Setting entry for user: %s\n", pdb_get_username(sampass)));
1169
1170
  /* only update the RID if we actually need to */
1171
0
  if (need_update(sampass, PDB_USERSID)) {
1172
0
    struct dom_sid_buf sid_str;
1173
0
    const struct dom_sid *user_sid = pdb_get_user_sid(sampass);
1174
1175
0
    switch ( ldap_state->schema_ver ) {
1176
0
      case SCHEMAVER_SAMBASAMACCOUNT:
1177
0
        smbldap_make_mod(
1178
0
          smbldap_get_ldap(
1179
0
            ldap_state->smbldap_state),
1180
0
          existing, mods,
1181
0
          get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID),
1182
0
          dom_sid_str_buf(user_sid, &sid_str));
1183
0
        break;
1184
1185
0
      default:
1186
0
        DEBUG(0,("init_ldap_from_sam: unknown schema version specified\n"));
1187
0
        break;
1188
0
    }
1189
0
  }
1190
1191
  /* we don't need to store the primary group RID - so leaving it
1192
     'free' to hang off the unix primary group makes life easier */
1193
1194
0
  if (need_update(sampass, PDB_GROUPSID)) {
1195
0
    struct dom_sid_buf sid_str;
1196
0
    const struct dom_sid *group_sid = pdb_get_group_sid(sampass);
1197
1198
0
    switch ( ldap_state->schema_ver ) {
1199
0
      case SCHEMAVER_SAMBASAMACCOUNT:
1200
0
        smbldap_make_mod(
1201
0
          smbldap_get_ldap(
1202
0
            ldap_state->smbldap_state),
1203
0
          existing, mods,
1204
0
          get_userattr_key2string(ldap_state->schema_ver,
1205
0
          LDAP_ATTR_PRIMARY_GROUP_SID),
1206
0
          dom_sid_str_buf(group_sid, &sid_str));
1207
0
        break;
1208
1209
0
      default:
1210
0
        DEBUG(0,("init_ldap_from_sam: unknown schema version specified\n"));
1211
0
        break;
1212
0
    }
1213
1214
0
  }
1215
1216
  /* displayName, cn, and gecos should all be the same
1217
   *  most easily accomplished by giving them the same OID
1218
   *  gecos isn't set here b/c it should be handled by the
1219
   *  add-user script
1220
   *  We change displayName only and fall back to cn if
1221
   *  it does not exist.
1222
   */
1223
1224
0
  if (need_update(sampass, PDB_FULLNAME))
1225
0
    smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state),
1226
0
         existing, mods,
1227
0
      get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_DISPLAY_NAME),
1228
0
      pdb_get_fullname(sampass));
1229
1230
0
  if (need_update(sampass, PDB_ACCTDESC))
1231
0
    smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state),
1232
0
         existing, mods,
1233
0
      get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_DESC),
1234
0
      pdb_get_acct_desc(sampass));
1235
1236
0
  if (need_update(sampass, PDB_WORKSTATIONS))
1237
0
    smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state),
1238
0
         existing, mods,
1239
0
      get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_WKS),
1240
0
      pdb_get_workstations(sampass));
1241
1242
0
  if (need_update(sampass, PDB_MUNGEDDIAL))
1243
0
    smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state),
1244
0
         existing, mods,
1245
0
      get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_MUNGED_DIAL),
1246
0
      pdb_get_munged_dial(sampass));
1247
1248
0
  if (need_update(sampass, PDB_SMBHOME))
1249
0
    smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state),
1250
0
         existing, mods,
1251
0
      get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_PATH),
1252
0
      pdb_get_homedir(sampass));
1253
1254
0
  if (need_update(sampass, PDB_DRIVE))
1255
0
    smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state),
1256
0
         existing, mods,
1257
0
      get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_DRIVE),
1258
0
      pdb_get_dir_drive(sampass));
1259
1260
0
  if (need_update(sampass, PDB_LOGONSCRIPT))
1261
0
    smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state),
1262
0
         existing, mods,
1263
0
      get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_SCRIPT),
1264
0
      pdb_get_logon_script(sampass));
1265
1266
0
  if (need_update(sampass, PDB_PROFILE))
1267
0
    smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state),
1268
0
         existing, mods,
1269
0
      get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PROFILE_PATH),
1270
0
      pdb_get_profile_path(sampass));
1271
1272
0
  if (asprintf(&temp, "%li", (long int)pdb_get_logon_time(sampass)) < 0) {
1273
0
    return false;
1274
0
  }
1275
0
  if (need_update(sampass, PDB_LOGONTIME))
1276
0
    smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state),
1277
0
         existing, mods,
1278
0
      get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_TIME), temp);
1279
0
  SAFE_FREE(temp);
1280
1281
0
  if (asprintf(&temp, "%li", (long int)pdb_get_logoff_time(sampass)) < 0) {
1282
0
    return false;
1283
0
  }
1284
0
  if (need_update(sampass, PDB_LOGOFFTIME))
1285
0
    smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state),
1286
0
         existing, mods,
1287
0
      get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGOFF_TIME), temp);
1288
0
  SAFE_FREE(temp);
1289
1290
0
  if (asprintf(&temp, "%li", (long int)pdb_get_kickoff_time(sampass)) < 0) {
1291
0
    return false;
1292
0
  }
1293
0
  if (need_update(sampass, PDB_KICKOFFTIME))
1294
0
    smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state),
1295
0
         existing, mods,
1296
0
      get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_KICKOFF_TIME), temp);
1297
0
  SAFE_FREE(temp);
1298
1299
0
  if (asprintf(&temp, "%li", (long int)pdb_get_pass_can_change_time_noncalc(sampass)) < 0) {
1300
0
    return false;
1301
0
  }
1302
0
  if (need_update(sampass, PDB_CANCHANGETIME))
1303
0
    smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state),
1304
0
         existing, mods,
1305
0
      get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_CAN_CHANGE), temp);
1306
0
  SAFE_FREE(temp);
1307
1308
0
  if ((pdb_get_acct_ctrl(sampass)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST))
1309
0
      || (lp_ldap_passwd_sync()!=LDAP_PASSWD_SYNC_ONLY)) {
1310
1311
0
    if (need_update(sampass, PDB_LMPASSWD)) {
1312
0
      const uchar *lm_pw = pdb_get_lanman_passwd(sampass);
1313
0
      if (lm_pw) {
1314
0
        char pwstr[34];
1315
0
        pdb_sethexpwd(pwstr, lm_pw,
1316
0
                pdb_get_acct_ctrl(sampass));
1317
0
        smbldap_make_mod(
1318
0
          smbldap_get_ldap(
1319
0
            ldap_state->smbldap_state),
1320
0
          existing, mods,
1321
0
             get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LMPW),
1322
0
             pwstr);
1323
0
      } else {
1324
0
        smbldap_make_mod(
1325
0
          smbldap_get_ldap(
1326
0
            ldap_state->smbldap_state),
1327
0
          existing, mods,
1328
0
             get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LMPW),
1329
0
             NULL);
1330
0
      }
1331
0
    }
1332
0
    if (need_update(sampass, PDB_NTPASSWD)) {
1333
0
      const uchar *nt_pw = pdb_get_nt_passwd(sampass);
1334
0
      if (nt_pw) {
1335
0
        char pwstr[34];
1336
0
        pdb_sethexpwd(pwstr, nt_pw,
1337
0
                pdb_get_acct_ctrl(sampass));
1338
0
        smbldap_make_mod(
1339
0
          smbldap_get_ldap(
1340
0
            ldap_state->smbldap_state),
1341
0
          existing, mods,
1342
0
             get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_NTPW),
1343
0
             pwstr);
1344
0
      } else {
1345
0
        smbldap_make_mod(
1346
0
          smbldap_get_ldap(
1347
0
            ldap_state->smbldap_state),
1348
0
          existing, mods,
1349
0
             get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_NTPW),
1350
0
             NULL);
1351
0
      }
1352
0
    }
1353
1354
0
    if (need_update(sampass, PDB_PWHISTORY)) {
1355
0
      char *pwstr = NULL;
1356
0
      uint32_t pwHistLen = 0;
1357
0
      pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
1358
1359
0
      pwstr = SMB_MALLOC_ARRAY(char, 1024);
1360
0
      if (!pwstr) {
1361
0
        return false;
1362
0
      }
1363
0
      if (pwHistLen == 0) {
1364
        /* Remove any password history from the LDAP store. */
1365
0
        memset(pwstr, '0', 64); /* NOTE !!!! '0' *NOT '\0' */
1366
0
        pwstr[64] = '\0';
1367
0
      } else {
1368
0
        int i;
1369
0
        uint32_t currHistLen = 0;
1370
0
        const uint8_t *pwhist = pdb_get_pw_history(sampass, &currHistLen);
1371
0
        if (pwhist != NULL) {
1372
          /* We can only store (1024-1/64 password history entries. */
1373
0
          pwHistLen = MIN(pwHistLen, ((1024-1)/64));
1374
0
          for (i=0; i< pwHistLen && i < currHistLen; i++) {
1375
            /* Store the salt. */
1376
0
            pdb_sethexpwd(&pwstr[i*64], &pwhist[i*PW_HISTORY_ENTRY_LEN], 0);
1377
            /* Followed by the md5 hash of salt + md4 hash */
1378
0
            pdb_sethexpwd(&pwstr[(i*64)+32],
1379
0
              &pwhist[(i*PW_HISTORY_ENTRY_LEN)+PW_HISTORY_SALT_LEN], 0);
1380
0
            DEBUG(100, ("pwstr=%s\n", pwstr));
1381
0
          }
1382
0
        }
1383
0
      }
1384
0
      smbldap_make_mod(
1385
0
        smbldap_get_ldap(ldap_state->smbldap_state),
1386
0
        existing, mods,
1387
0
           get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_HISTORY),
1388
0
           pwstr);
1389
0
      SAFE_FREE(pwstr);
1390
0
    }
1391
1392
0
    if (need_update(sampass, PDB_PASSLASTSET)) {
1393
0
      if (asprintf(&temp, "%li",
1394
0
        (long int)pdb_get_pass_last_set_time(sampass)) < 0) {
1395
0
        return false;
1396
0
      }
1397
0
      smbldap_make_mod(
1398
0
        smbldap_get_ldap(ldap_state->smbldap_state),
1399
0
        existing, mods,
1400
0
        get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_LAST_SET),
1401
0
        temp);
1402
0
      SAFE_FREE(temp);
1403
0
    }
1404
0
  }
1405
1406
0
  if (need_update(sampass, PDB_HOURS)) {
1407
0
    const uint8_t *hours = pdb_get_hours(sampass);
1408
0
    if (hours) {
1409
0
      char hourstr[44];
1410
0
      pdb_sethexhours(hourstr, hours);
1411
0
      smbldap_make_mod(
1412
0
        smbldap_get_ldap(ldap_state->smbldap_state),
1413
0
        existing,
1414
0
        mods,
1415
0
        get_userattr_key2string(ldap_state->schema_ver,
1416
0
            LDAP_ATTR_LOGON_HOURS),
1417
0
        hourstr);
1418
0
    }
1419
0
  }
1420
1421
0
  if (need_update(sampass, PDB_ACCTCTRL))
1422
0
    smbldap_make_mod(
1423
0
      smbldap_get_ldap(ldap_state->smbldap_state),
1424
0
      existing, mods,
1425
0
      get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_ACB_INFO),
1426
0
      pdb_encode_acct_ctrl (pdb_get_acct_ctrl(sampass), NEW_PW_FORMAT_SPACE_PADDED_LEN));
1427
1428
  /* password lockout cache:
1429
     - If we are now autolocking or clearing, we write to ldap
1430
     - If we are clearing, we delete the cache entry
1431
     - If the count is > 0, we update the cache
1432
1433
     This even means when autolocking, we cache, just in case the
1434
     update doesn't work, and we have to cache the autolock flag */
1435
1436
0
  if (need_update(sampass, PDB_BAD_PASSWORD_COUNT))  /* &&
1437
0
      need_update(sampass, PDB_BAD_PASSWORD_TIME)) */ {
1438
0
    uint16_t badcount = pdb_get_bad_password_count(sampass);
1439
0
    time_t badtime = pdb_get_bad_password_time(sampass);
1440
0
    uint32_t pol;
1441
0
    pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &pol);
1442
1443
0
    DEBUG(3, ("updating bad password fields, policy=%u, count=%u, time=%jd\n",
1444
0
      (unsigned int)pol, (unsigned int)badcount, (intmax_t)badtime));
1445
1446
0
    if ((badcount >= pol) || (badcount == 0)) {
1447
0
      DEBUG(7, ("making mods to update ldap, count=%u, time=%jd\n",
1448
0
        (unsigned int)badcount, (intmax_t)badtime));
1449
0
      if (asprintf(&temp, "%li", (long)badcount) < 0) {
1450
0
        return false;
1451
0
      }
1452
0
      smbldap_make_mod(
1453
0
        smbldap_get_ldap(ldap_state->smbldap_state),
1454
0
        existing, mods,
1455
0
        get_userattr_key2string(
1456
0
          ldap_state->schema_ver,
1457
0
          LDAP_ATTR_BAD_PASSWORD_COUNT),
1458
0
        temp);
1459
0
      SAFE_FREE(temp);
1460
1461
0
      if (asprintf(&temp, "%li", (long int)badtime) < 0) {
1462
0
        return false;
1463
0
      }
1464
0
      smbldap_make_mod(
1465
0
        smbldap_get_ldap(ldap_state->smbldap_state),
1466
0
        existing, mods,
1467
0
        get_userattr_key2string(
1468
0
          ldap_state->schema_ver,
1469
0
          LDAP_ATTR_BAD_PASSWORD_TIME),
1470
0
        temp);
1471
0
      SAFE_FREE(temp);
1472
0
    }
1473
0
    if (badcount == 0) {
1474
0
      DEBUG(7, ("bad password count is reset, deleting login cache entry for %s\n", pdb_get_nt_username(sampass)));
1475
0
      login_cache_delentry(sampass);
1476
0
    } else {
1477
0
      struct login_cache cache_entry;
1478
1479
0
      cache_entry.entry_timestamp = time(NULL);
1480
0
      cache_entry.acct_ctrl = pdb_get_acct_ctrl(sampass);
1481
0
      cache_entry.bad_password_count = badcount;
1482
0
      cache_entry.bad_password_time = badtime;
1483
1484
0
      DEBUG(7, ("Updating bad password count and time in login cache\n"));
1485
0
      login_cache_write(sampass, &cache_entry);
1486
0
    }
1487
0
  }
1488
1489
0
  return True;
1490
0
}
1491
1492
/**********************************************************************
1493
 End enumeration of the LDAP password list.
1494
*********************************************************************/
1495
1496
static void ldapsam_endsampwent(struct pdb_methods *my_methods)
1497
0
{
1498
0
  struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1499
0
  if (ldap_state->result) {
1500
0
    ldap_msgfree(ldap_state->result);
1501
0
    ldap_state->result = NULL;
1502
0
  }
1503
0
}
1504
1505
static void append_attr(TALLOC_CTX *mem_ctx, const char ***attr_list,
1506
      const char *new_attr)
1507
0
{
1508
0
  int i;
1509
1510
0
  if (new_attr == NULL) {
1511
0
    return;
1512
0
  }
1513
1514
0
  for (i=0; (*attr_list)[i] != NULL; i++) {
1515
0
    ;
1516
0
  }
1517
1518
0
  (*attr_list) = talloc_realloc(mem_ctx, (*attr_list),
1519
0
              const char *,  i+2);
1520
0
  SMB_ASSERT((*attr_list) != NULL);
1521
0
  (*attr_list)[i] = talloc_strdup((*attr_list), new_attr);
1522
0
  (*attr_list)[i+1] = NULL;
1523
0
}
1524
1525
static void ldapsam_add_unix_attributes(TALLOC_CTX *mem_ctx,
1526
          const char ***attr_list)
1527
0
{
1528
0
  append_attr(mem_ctx, attr_list, "uidNumber");
1529
0
  append_attr(mem_ctx, attr_list, "gidNumber");
1530
0
  append_attr(mem_ctx, attr_list, "homeDirectory");
1531
0
  append_attr(mem_ctx, attr_list, "loginShell");
1532
0
  append_attr(mem_ctx, attr_list, "gecos");
1533
0
}
1534
1535
/**********************************************************************
1536
Get struct samu entry from LDAP by username.
1537
*********************************************************************/
1538
1539
static NTSTATUS ldapsam_getsampwnam(struct pdb_methods *my_methods, struct samu *user, const char *sname)
1540
0
{
1541
0
  NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1542
0
  struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1543
0
  LDAPMessage *result = NULL;
1544
0
  LDAPMessage *entry = NULL;
1545
0
  int count;
1546
0
  const char ** attr_list;
1547
0
  int rc;
1548
1549
0
  attr_list = get_userattr_list( user, ldap_state->schema_ver );
1550
0
  append_attr(user, &attr_list,
1551
0
        get_userattr_key2string(ldap_state->schema_ver,
1552
0
              LDAP_ATTR_MOD_TIMESTAMP));
1553
0
  ldapsam_add_unix_attributes(user, &attr_list);
1554
0
  rc = ldapsam_search_suffix_by_name(ldap_state, sname, &result,
1555
0
             attr_list);
1556
0
  TALLOC_FREE( attr_list );
1557
1558
0
  if ( rc != LDAP_SUCCESS )
1559
0
    return NT_STATUS_NO_SUCH_USER;
1560
1561
0
  count = ldap_count_entries(smbldap_get_ldap(ldap_state->smbldap_state),
1562
0
           result);
1563
1564
0
  if (count < 1) {
1565
0
    DEBUG(4, ("ldapsam_getsampwnam: Unable to locate user [%s] count=%d\n", sname, count));
1566
0
    ldap_msgfree(result);
1567
0
    return NT_STATUS_NO_SUCH_USER;
1568
0
  } else if (count > 1) {
1569
0
    DEBUG(1, ("ldapsam_getsampwnam: Duplicate entries for this user [%s] Failing. count=%d\n", sname, count));
1570
0
    ldap_msgfree(result);
1571
0
    return NT_STATUS_NO_SUCH_USER;
1572
0
  }
1573
1574
0
  entry = ldap_first_entry(smbldap_get_ldap(ldap_state->smbldap_state),
1575
0
         result);
1576
0
  if (entry) {
1577
0
    if (!init_sam_from_ldap(ldap_state, user, entry)) {
1578
0
      DEBUG(1,("ldapsam_getsampwnam: init_sam_from_ldap failed for user '%s'!\n", sname));
1579
0
      ldap_msgfree(result);
1580
0
      return NT_STATUS_NO_SUCH_USER;
1581
0
    }
1582
0
    pdb_set_backend_private_data(user, result, NULL,
1583
0
               my_methods, PDB_CHANGED);
1584
0
    smbldap_talloc_autofree_ldapmsg(user, result);
1585
0
    ret = NT_STATUS_OK;
1586
0
  } else {
1587
0
    ldap_msgfree(result);
1588
0
  }
1589
0
  return ret;
1590
0
}
1591
1592
static int ldapsam_get_ldap_user_by_sid(struct ldapsam_privates *ldap_state,
1593
           const struct dom_sid *sid, LDAPMessage **result)
1594
0
{
1595
0
  int rc = -1;
1596
0
  const char ** attr_list;
1597
1598
0
  switch ( ldap_state->schema_ver ) {
1599
0
    case SCHEMAVER_SAMBASAMACCOUNT: {
1600
0
      TALLOC_CTX *tmp_ctx = talloc_new(NULL);
1601
0
      if (tmp_ctx == NULL) {
1602
0
        return LDAP_NO_MEMORY;
1603
0
      }
1604
1605
0
      attr_list = get_userattr_list(tmp_ctx,
1606
0
                  ldap_state->schema_ver);
1607
0
      append_attr(tmp_ctx, &attr_list,
1608
0
            get_userattr_key2string(
1609
0
              ldap_state->schema_ver,
1610
0
              LDAP_ATTR_MOD_TIMESTAMP));
1611
0
      ldapsam_add_unix_attributes(tmp_ctx, &attr_list);
1612
0
      rc = ldapsam_search_suffix_by_sid(ldap_state, sid,
1613
0
                result, attr_list);
1614
0
      TALLOC_FREE(tmp_ctx);
1615
1616
0
      if ( rc != LDAP_SUCCESS )
1617
0
        return rc;
1618
0
      break;
1619
0
    }
1620
1621
0
    default:
1622
0
      DEBUG(0,("Invalid schema version specified\n"));
1623
0
      break;
1624
0
  }
1625
0
  return rc;
1626
0
}
1627
1628
/**********************************************************************
1629
 Get struct samu entry from LDAP by SID.
1630
*********************************************************************/
1631
1632
static NTSTATUS ldapsam_getsampwsid(struct pdb_methods *my_methods, struct samu * user, const struct dom_sid *sid)
1633
0
{
1634
0
  struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1635
0
  LDAPMessage *result = NULL;
1636
0
  LDAPMessage *entry = NULL;
1637
0
  int count;
1638
0
  int rc;
1639
1640
0
  rc = ldapsam_get_ldap_user_by_sid(ldap_state,
1641
0
            sid, &result);
1642
0
  if (rc != LDAP_SUCCESS)
1643
0
    return NT_STATUS_NO_SUCH_USER;
1644
1645
0
  count = ldap_count_entries(smbldap_get_ldap(ldap_state->smbldap_state),
1646
0
           result);
1647
1648
0
  if (count < 1) {
1649
0
    struct dom_sid_buf buf;
1650
0
    DEBUG(4, ("ldapsam_getsampwsid: Unable to locate SID [%s] "
1651
0
        "count=%d\n",
1652
0
        dom_sid_str_buf(sid, &buf),
1653
0
        count));
1654
0
    ldap_msgfree(result);
1655
0
    return NT_STATUS_NO_SUCH_USER;
1656
0
  }  else if (count > 1) {
1657
0
    struct dom_sid_buf buf;
1658
0
    DEBUG(1, ("ldapsam_getsampwsid: More than one user with SID "
1659
0
        "[%s]. Failing. count=%d\n",
1660
0
        dom_sid_str_buf(sid, &buf),
1661
0
        count));
1662
0
    ldap_msgfree(result);
1663
0
    return NT_STATUS_NO_SUCH_USER;
1664
0
  }
1665
1666
0
  entry = ldap_first_entry(smbldap_get_ldap(ldap_state->smbldap_state),
1667
0
         result);
1668
0
  if (!entry) {
1669
0
    ldap_msgfree(result);
1670
0
    return NT_STATUS_NO_SUCH_USER;
1671
0
  }
1672
1673
0
  if (!init_sam_from_ldap(ldap_state, user, entry)) {
1674
0
    DEBUG(1,("ldapsam_getsampwsid: init_sam_from_ldap failed!\n"));
1675
0
    ldap_msgfree(result);
1676
0
    return NT_STATUS_NO_SUCH_USER;
1677
0
  }
1678
1679
0
  pdb_set_backend_private_data(user, result, NULL,
1680
0
             my_methods, PDB_CHANGED);
1681
0
  smbldap_talloc_autofree_ldapmsg(user, result);
1682
0
  return NT_STATUS_OK;
1683
0
}
1684
1685
/********************************************************************
1686
 Do the actual modification - also change a plaintext password if
1687
 it it set.
1688
**********************************************************************/
1689
1690
static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods,
1691
             struct samu *newpwd, char *dn,
1692
             LDAPMod **mods, int ldap_op,
1693
             bool (*need_update)(const struct samu *, enum pdb_elements))
1694
0
{
1695
0
  struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1696
0
  int rc;
1697
1698
0
  if (!newpwd || !dn) {
1699
0
    return NT_STATUS_INVALID_PARAMETER;
1700
0
  }
1701
1702
0
  if (!(pdb_get_acct_ctrl(newpwd)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST)) &&
1703
0
      (lp_ldap_passwd_sync() != LDAP_PASSWD_SYNC_OFF) &&
1704
0
      need_update(newpwd, PDB_PLAINTEXT_PW) &&
1705
0
      (pdb_get_plaintext_passwd(newpwd)!=NULL)) {
1706
0
    BerElement *ber;
1707
0
    struct berval *bv;
1708
0
    char *retoid = NULL;
1709
0
    struct berval *retdata = NULL;
1710
0
    char *utf8_password;
1711
0
    char *utf8_dn;
1712
0
    size_t converted_size;
1713
0
    int ret;
1714
1715
0
    if (!ldap_state->is_nds_ldap) {
1716
1717
0
      if (!smbldap_has_extension(
1718
0
            smbldap_get_ldap(
1719
0
              ldap_state->smbldap_state),
1720
0
            LDAP_EXOP_MODIFY_PASSWD)) {
1721
0
        DEBUG(2, ("ldap password change requested, but LDAP "
1722
0
            "server does not support it -- ignoring\n"));
1723
0
        return NT_STATUS_OK;
1724
0
      }
1725
0
    }
1726
1727
0
    if (!push_utf8_talloc(talloc_tos(), &utf8_password,
1728
0
          pdb_get_plaintext_passwd(newpwd),
1729
0
          &converted_size))
1730
0
    {
1731
0
      return NT_STATUS_NO_MEMORY;
1732
0
    }
1733
1734
0
    if (!push_utf8_talloc(talloc_tos(), &utf8_dn, dn, &converted_size)) {
1735
0
      TALLOC_FREE(utf8_password);
1736
0
      return NT_STATUS_NO_MEMORY;
1737
0
    }
1738
1739
0
    if ((ber = ber_alloc_t(LBER_USE_DER))==NULL) {
1740
0
      DEBUG(0,("ber_alloc_t returns NULL\n"));
1741
0
      TALLOC_FREE(utf8_password);
1742
0
      TALLOC_FREE(utf8_dn);
1743
0
      return NT_STATUS_UNSUCCESSFUL;
1744
0
    }
1745
1746
0
    if ((ber_printf (ber, "{") < 0) ||
1747
0
        (ber_printf (ber, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_ID,
1748
0
         utf8_dn) < 0)) {
1749
0
      DEBUG(0,("ldapsam_modify_entry: ber_printf returns a "
1750
0
         "value <0\n"));
1751
0
      ber_free(ber,1);
1752
0
      TALLOC_FREE(utf8_dn);
1753
0
      TALLOC_FREE(utf8_password);
1754
0
      return NT_STATUS_UNSUCCESSFUL;
1755
0
    }
1756
1757
0
    if ((utf8_password != NULL) && (*utf8_password != '\0')) {
1758
0
      ret = ber_printf(ber, "ts}",
1759
0
           LDAP_TAG_EXOP_MODIFY_PASSWD_NEW,
1760
0
           utf8_password);
1761
0
    } else {
1762
0
      ret = ber_printf(ber, "}");
1763
0
    }
1764
1765
0
    if (ret < 0) {
1766
0
      DEBUG(0,("ldapsam_modify_entry: ber_printf returns a "
1767
0
         "value <0\n"));
1768
0
      ber_free(ber,1);
1769
0
      TALLOC_FREE(utf8_dn);
1770
0
      TALLOC_FREE(utf8_password);
1771
0
      return NT_STATUS_UNSUCCESSFUL;
1772
0
    }
1773
1774
0
          if ((rc = ber_flatten (ber, &bv))<0) {
1775
0
      DEBUG(0,("ldapsam_modify_entry: ber_flatten returns a value <0\n"));
1776
0
      ber_free(ber,1);
1777
0
      TALLOC_FREE(utf8_dn);
1778
0
      TALLOC_FREE(utf8_password);
1779
0
      return NT_STATUS_UNSUCCESSFUL;
1780
0
    }
1781
1782
0
    TALLOC_FREE(utf8_dn);
1783
0
    TALLOC_FREE(utf8_password);
1784
0
    ber_free(ber, 1);
1785
1786
0
    if (!ldap_state->is_nds_ldap) {
1787
0
      rc = smbldap_extended_operation(ldap_state->smbldap_state,
1788
0
              LDAP_EXOP_MODIFY_PASSWD,
1789
0
              bv, NULL, NULL, &retoid,
1790
0
              &retdata);
1791
0
    } else {
1792
0
      rc = pdb_nds_set_password(ldap_state->smbldap_state, dn,
1793
0
              pdb_get_plaintext_passwd(newpwd));
1794
0
    }
1795
0
    if (rc != LDAP_SUCCESS) {
1796
0
      char *ld_error = NULL;
1797
1798
0
      if (rc == LDAP_OBJECT_CLASS_VIOLATION) {
1799
0
        DEBUG(3, ("Could not set userPassword "
1800
0
            "attribute due to an objectClass "
1801
0
            "violation -- ignoring\n"));
1802
0
        ber_bvfree(bv);
1803
0
        return NT_STATUS_OK;
1804
0
      }
1805
1806
0
      ldap_get_option(
1807
0
        smbldap_get_ldap(ldap_state->smbldap_state),
1808
0
        LDAP_OPT_ERROR_STRING,
1809
0
          &ld_error);
1810
0
      DEBUG(0,("ldapsam_modify_entry: LDAP Password could not be changed for user %s: %s\n\t%s\n",
1811
0
        pdb_get_username(newpwd), ldap_err2string(rc), ld_error?ld_error:"unknown"));
1812
0
      SAFE_FREE(ld_error);
1813
0
      ber_bvfree(bv);
1814
0
#if defined(LDAP_CONSTRAINT_VIOLATION)
1815
0
      if (rc == LDAP_CONSTRAINT_VIOLATION)
1816
0
        return NT_STATUS_PASSWORD_RESTRICTION;
1817
0
#endif
1818
0
      return NT_STATUS_UNSUCCESSFUL;
1819
0
    } else {
1820
0
      DEBUG(3,("ldapsam_modify_entry: LDAP Password changed for user %s\n",pdb_get_username(newpwd)));
1821
0
#ifdef DEBUG_PASSWORD
1822
0
      DEBUG(100,("ldapsam_modify_entry: LDAP Password changed to %s\n",pdb_get_plaintext_passwd(newpwd)));
1823
0
#endif
1824
0
      if (retdata)
1825
0
        ber_bvfree(retdata);
1826
0
      if (retoid)
1827
0
        ldap_memfree(retoid);
1828
0
    }
1829
0
    ber_bvfree(bv);
1830
0
  }
1831
1832
0
  if (!mods) {
1833
0
    DEBUG(5,("ldapsam_modify_entry: mods is empty: nothing to modify\n"));
1834
    /* may be password change below however */
1835
0
  } else {
1836
0
    switch(ldap_op) {
1837
0
      case LDAP_MOD_ADD:
1838
0
        if (ldap_state->is_nds_ldap) {
1839
0
          smbldap_set_mod(&mods, LDAP_MOD_ADD,
1840
0
              "objectclass",
1841
0
              "inetOrgPerson");
1842
0
        } else {
1843
0
          smbldap_set_mod(&mods, LDAP_MOD_ADD,
1844
0
              "objectclass",
1845
0
              LDAP_OBJ_ACCOUNT);
1846
0
        }
1847
0
        rc = smbldap_add(ldap_state->smbldap_state,
1848
0
             dn, mods);
1849
0
        break;
1850
0
      case LDAP_MOD_REPLACE:
1851
0
        rc = smbldap_modify(ldap_state->smbldap_state,
1852
0
                dn ,mods);
1853
0
        break;
1854
0
      default:
1855
0
        DEBUG(0,("ldapsam_modify_entry: Wrong LDAP operation type: %d!\n",
1856
0
           ldap_op));
1857
0
        return NT_STATUS_INVALID_PARAMETER;
1858
0
    }
1859
1860
0
    if (rc!=LDAP_SUCCESS) {
1861
0
      return NT_STATUS_UNSUCCESSFUL;
1862
0
    }
1863
0
  }
1864
1865
0
  return NT_STATUS_OK;
1866
0
}
1867
1868
/**********************************************************************
1869
 Delete entry from LDAP for username.
1870
*********************************************************************/
1871
1872
static NTSTATUS ldapsam_delete_sam_account(struct pdb_methods *my_methods,
1873
             struct samu * sam_acct)
1874
0
{
1875
0
  struct ldapsam_privates *priv =
1876
0
    (struct ldapsam_privates *)my_methods->private_data;
1877
0
  const char *sname;
1878
0
  int rc;
1879
0
  LDAPMessage *msg, *entry;
1880
0
  NTSTATUS result = NT_STATUS_NO_MEMORY;
1881
0
  const char **attr_list;
1882
0
  TALLOC_CTX *mem_ctx;
1883
1884
0
  if (!sam_acct) {
1885
0
    DEBUG(0, ("ldapsam_delete_sam_account: sam_acct was NULL!\n"));
1886
0
    return NT_STATUS_INVALID_PARAMETER;
1887
0
  }
1888
1889
0
  sname = pdb_get_username(sam_acct);
1890
1891
0
  DEBUG(3, ("ldapsam_delete_sam_account: Deleting user %s from "
1892
0
      "LDAP.\n", sname));
1893
1894
0
  mem_ctx = talloc_new(NULL);
1895
0
  if (mem_ctx == NULL) {
1896
0
    DEBUG(0, ("talloc_new failed\n"));
1897
0
    goto done;
1898
0
  }
1899
1900
0
  attr_list = get_userattr_delete_list(mem_ctx, priv->schema_ver );
1901
0
  if (attr_list == NULL) {
1902
0
    goto done;
1903
0
  }
1904
1905
0
  rc = ldapsam_search_suffix_by_name(priv, sname, &msg, attr_list);
1906
1907
0
  if ((rc != LDAP_SUCCESS) ||
1908
0
      (ldap_count_entries(priv2ld(priv), msg) != 1) ||
1909
0
      ((entry = ldap_first_entry(priv2ld(priv), msg)) == NULL)) {
1910
0
    DEBUG(5, ("Could not find user %s\n", sname));
1911
0
    result = NT_STATUS_NO_SUCH_USER;
1912
0
    goto done;
1913
0
  }
1914
1915
0
  rc = ldapsam_delete_entry(
1916
0
    priv, mem_ctx, entry,
1917
0
    priv->schema_ver == SCHEMAVER_SAMBASAMACCOUNT ?
1918
0
    LDAP_OBJ_SAMBASAMACCOUNT : 0,
1919
0
    attr_list);
1920
1921
0
  result = (rc == LDAP_SUCCESS) ?
1922
0
    NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
1923
1924
0
 done:
1925
0
  TALLOC_FREE(mem_ctx);
1926
0
  return result;
1927
0
}
1928
1929
/**********************************************************************
1930
 Update struct samu.
1931
*********************************************************************/
1932
1933
static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, struct samu * newpwd)
1934
0
{
1935
0
  NTSTATUS ret;
1936
0
  struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1937
0
  int rc = 0;
1938
0
  char *dn;
1939
0
  LDAPMessage *result = NULL;
1940
0
  LDAPMessage *entry = NULL;
1941
0
  LDAPMod **mods = NULL;
1942
0
  const char **attr_list;
1943
1944
0
  result = (LDAPMessage *)pdb_get_backend_private_data(newpwd, my_methods);
1945
0
  if (!result) {
1946
0
    attr_list = get_userattr_list(NULL, ldap_state->schema_ver);
1947
0
    if (pdb_get_username(newpwd) == NULL) {
1948
0
      return NT_STATUS_INVALID_PARAMETER;
1949
0
    }
1950
0
    rc = ldapsam_search_suffix_by_name(ldap_state, pdb_get_username(newpwd), &result, attr_list );
1951
0
    TALLOC_FREE( attr_list );
1952
0
    if (rc != LDAP_SUCCESS) {
1953
0
      return NT_STATUS_UNSUCCESSFUL;
1954
0
    }
1955
0
    pdb_set_backend_private_data(newpwd, result, NULL,
1956
0
               my_methods, PDB_CHANGED);
1957
0
    smbldap_talloc_autofree_ldapmsg(newpwd, result);
1958
0
  }
1959
1960
0
  if (ldap_count_entries(smbldap_get_ldap(ldap_state->smbldap_state),
1961
0
             result) == 0) {
1962
0
    DEBUG(0, ("ldapsam_update_sam_account: No user to modify!\n"));
1963
0
    return NT_STATUS_UNSUCCESSFUL;
1964
0
  }
1965
1966
0
  entry = ldap_first_entry(smbldap_get_ldap(ldap_state->smbldap_state),
1967
0
         result);
1968
0
  dn = smbldap_talloc_dn(talloc_tos(),
1969
0
             smbldap_get_ldap(ldap_state->smbldap_state),
1970
0
             entry);
1971
0
  if (!dn) {
1972
0
    return NT_STATUS_UNSUCCESSFUL;
1973
0
  }
1974
1975
0
  DEBUG(4, ("ldapsam_update_sam_account: user %s to be modified has dn: %s\n", pdb_get_username(newpwd), dn));
1976
1977
0
  if (!init_ldap_from_sam(ldap_state, entry, &mods, newpwd,
1978
0
        pdb_element_is_changed)) {
1979
0
    DEBUG(0, ("ldapsam_update_sam_account: init_ldap_from_sam failed!\n"));
1980
0
    TALLOC_FREE(dn);
1981
0
    if (mods != NULL)
1982
0
      ldap_mods_free(mods,True);
1983
0
    return NT_STATUS_UNSUCCESSFUL;
1984
0
  }
1985
1986
0
  if ((lp_ldap_passwd_sync() != LDAP_PASSWD_SYNC_ONLY)
1987
0
      && (mods == NULL)) {
1988
0
    DEBUG(4,("ldapsam_update_sam_account: mods is empty: nothing to update for user: %s\n",
1989
0
       pdb_get_username(newpwd)));
1990
0
    TALLOC_FREE(dn);
1991
0
    return NT_STATUS_OK;
1992
0
  }
1993
1994
0
  ret = ldapsam_modify_entry(my_methods,newpwd,dn,mods,LDAP_MOD_REPLACE, pdb_element_is_changed);
1995
1996
0
  if (mods != NULL) {
1997
0
    ldap_mods_free(mods,True);
1998
0
  }
1999
2000
0
  TALLOC_FREE(dn);
2001
2002
  /*
2003
   * We need to set the backend private data to NULL here. For example
2004
   * setuserinfo level 25 does a pdb_update_sam_account twice on the
2005
   * same one, and with the explicit delete / add logic for attribute
2006
   * values the second time we would use the wrong "old" value which
2007
   * does not exist in LDAP anymore. Thus the LDAP server would refuse
2008
   * the update.
2009
   * The existing LDAPMessage is still being auto-freed by the
2010
   * destructor.
2011
   */
2012
0
  pdb_set_backend_private_data(newpwd, NULL, NULL, my_methods,
2013
0
             PDB_CHANGED);
2014
2015
0
  if (!NT_STATUS_IS_OK(ret)) {
2016
0
    return ret;
2017
0
  }
2018
2019
0
  DEBUG(2, ("ldapsam_update_sam_account: successfully modified uid = %s in the LDAP database\n",
2020
0
      pdb_get_username(newpwd)));
2021
0
  return NT_STATUS_OK;
2022
0
}
2023
2024
/***************************************************************************
2025
 Renames a struct samu
2026
 - The "rename user script" has full responsibility for changing everything
2027
***************************************************************************/
2028
2029
static NTSTATUS ldapsam_del_groupmem(struct pdb_methods *my_methods,
2030
             TALLOC_CTX *tmp_ctx,
2031
             uint32_t group_rid,
2032
             uint32_t member_rid);
2033
2034
static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods,
2035
                 TALLOC_CTX *mem_ctx,
2036
                 struct samu *user,
2037
                 struct dom_sid **pp_sids,
2038
                 gid_t **pp_gids,
2039
                 uint32_t *p_num_groups);
2040
2041
static NTSTATUS ldapsam_rename_sam_account(struct pdb_methods *my_methods,
2042
             struct samu *old_acct,
2043
             const char *newname)
2044
0
{
2045
0
  const struct loadparm_substitution *lp_sub =
2046
0
    loadparm_s3_global_substitution();
2047
0
  const char *oldname;
2048
0
  int rc;
2049
0
  char *rename_script = NULL;
2050
0
  fstring oldname_lower, newname_lower;
2051
2052
0
  if (!old_acct) {
2053
0
    DEBUG(0, ("ldapsam_rename_sam_account: old_acct was NULL!\n"));
2054
0
    return NT_STATUS_INVALID_PARAMETER;
2055
0
  }
2056
0
  if (!newname) {
2057
0
    DEBUG(0, ("ldapsam_rename_sam_account: newname was NULL!\n"));
2058
0
    return NT_STATUS_INVALID_PARAMETER;
2059
0
  }
2060
2061
0
  oldname = pdb_get_username(old_acct);
2062
2063
  /* rename the posix user */
2064
0
  rename_script = lp_rename_user_script(talloc_tos(), lp_sub);
2065
0
  if (rename_script == NULL) {
2066
0
    return NT_STATUS_NO_MEMORY;
2067
0
  }
2068
2069
0
  if (!(*rename_script)) {
2070
0
    TALLOC_FREE(rename_script);
2071
0
    return NT_STATUS_ACCESS_DENIED;
2072
0
  }
2073
2074
0
  DEBUG (3, ("ldapsam_rename_sam_account: Renaming user %s to %s.\n",
2075
0
       oldname, newname));
2076
2077
  /* We have to allow the account name to end with a '$'.
2078
     Also, follow the semantics in _samr_create_user() and lower case the
2079
     posix name but preserve the case in passdb */
2080
2081
0
  fstrcpy( oldname_lower, oldname );
2082
0
  if (!strlower_m( oldname_lower )) {
2083
0
    return NT_STATUS_INVALID_PARAMETER;
2084
0
  }
2085
0
  fstrcpy( newname_lower, newname );
2086
0
  if (!strlower_m( newname_lower )) {
2087
0
    return NT_STATUS_INVALID_PARAMETER;
2088
0
  }
2089
2090
0
  rename_script = realloc_string_sub2(rename_script,
2091
0
          "%unew",
2092
0
          newname_lower,
2093
0
          true,
2094
0
          true);
2095
0
  if (!rename_script) {
2096
0
    return NT_STATUS_NO_MEMORY;
2097
0
  }
2098
0
  rename_script = realloc_string_sub2(rename_script,
2099
0
          "%uold",
2100
0
          oldname_lower,
2101
0
          true,
2102
0
          true);
2103
0
  rc = smbrun(rename_script, NULL, NULL);
2104
2105
0
  DEBUG(rc ? 0 : 3,("Running the command `%s' gave %d\n",
2106
0
        rename_script, rc));
2107
2108
0
  TALLOC_FREE(rename_script);
2109
2110
0
  if (rc == 0) {
2111
0
    smb_nscd_flush_user_cache();
2112
0
  }
2113
2114
0
  if (rc)
2115
0
    return NT_STATUS_UNSUCCESSFUL;
2116
2117
0
  return NT_STATUS_OK;
2118
0
}
2119
2120
/**********************************************************************
2121
 Add struct samu to LDAP.
2122
*********************************************************************/
2123
2124
static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, struct samu * newpwd)
2125
0
{
2126
0
  struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
2127
0
  int rc;
2128
0
  LDAPMessage   *result = NULL;
2129
0
  LDAPMessage   *entry  = NULL;
2130
0
  LDAPMod   **mods = NULL;
2131
0
  int   ldap_op = LDAP_MOD_REPLACE;
2132
0
  uint32_t    num_result;
2133
0
  const char  **attr_list;
2134
0
  char *escape_user = NULL;
2135
0
  const char  *username = pdb_get_username(newpwd);
2136
0
  const struct dom_sid  *sid = pdb_get_user_sid(newpwd);
2137
0
  char *filter = NULL;
2138
0
  char *dn = NULL;
2139
0
  NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
2140
0
  TALLOC_CTX *ctx = talloc_init("ldapsam_add_sam_account");
2141
2142
0
  if (!ctx) {
2143
0
    return NT_STATUS_NO_MEMORY;
2144
0
  }
2145
2146
0
  if (!username || !*username) {
2147
0
    DEBUG(0, ("ldapsam_add_sam_account: Cannot add user without a username!\n"));
2148
0
    status = NT_STATUS_INVALID_PARAMETER;
2149
0
    goto fn_exit;
2150
0
  }
2151
2152
  /* free this list after the second search or in case we exit on failure */
2153
0
  attr_list = get_userattr_list(ctx, ldap_state->schema_ver);
2154
2155
0
  rc = ldapsam_search_suffix_by_name (ldap_state, username, &result, attr_list);
2156
2157
0
  if (rc != LDAP_SUCCESS) {
2158
0
    goto fn_exit;
2159
0
  }
2160
2161
0
  if (ldap_count_entries(smbldap_get_ldap(ldap_state->smbldap_state),
2162
0
             result) != 0) {
2163
0
    DEBUG(0,("ldapsam_add_sam_account: User '%s' already in the base, with samba attributes\n",
2164
0
       username));
2165
0
    goto fn_exit;
2166
0
  }
2167
0
  ldap_msgfree(result);
2168
0
  result = NULL;
2169
2170
0
  if (pdb_element_is_set_or_changed(newpwd, PDB_USERSID)) {
2171
0
    rc = ldapsam_get_ldap_user_by_sid(ldap_state,
2172
0
              sid, &result);
2173
0
    if (rc == LDAP_SUCCESS) {
2174
0
      if (ldap_count_entries(
2175
0
            smbldap_get_ldap(
2176
0
              ldap_state->smbldap_state),
2177
0
            result) != 0) {
2178
0
        struct dom_sid_buf buf;
2179
0
        DEBUG(0,("ldapsam_add_sam_account: SID '%s' "
2180
0
           "already in the base, with samba "
2181
0
           "attributes\n",
2182
0
           dom_sid_str_buf(sid, &buf)));
2183
0
        goto fn_exit;
2184
0
      }
2185
0
      ldap_msgfree(result);
2186
0
      result = NULL;
2187
0
    }
2188
0
  }
2189
2190
  /* does the entry already exist but without a samba attributes?
2191
     we need to return the samba attributes here */
2192
2193
0
  escape_user = escape_ldap_string(talloc_tos(), username);
2194
0
  filter = talloc_strdup(attr_list, "(uid=%u)");
2195
0
  if (!filter) {
2196
0
    status = NT_STATUS_NO_MEMORY;
2197
0
    TALLOC_FREE(escape_user);
2198
0
    goto fn_exit;
2199
0
  }
2200
0
  filter = talloc_all_string_sub(attr_list, filter, "%u", escape_user);
2201
0
  TALLOC_FREE(escape_user);
2202
0
  if (!filter) {
2203
0
    status = NT_STATUS_NO_MEMORY;
2204
0
    goto fn_exit;
2205
0
  }
2206
2207
0
  rc = smbldap_search_suffix(ldap_state->smbldap_state,
2208
0
           filter, attr_list, &result);
2209
0
  if ( rc != LDAP_SUCCESS ) {
2210
0
    goto fn_exit;
2211
0
  }
2212
2213
0
  num_result = ldap_count_entries(
2214
0
    smbldap_get_ldap(ldap_state->smbldap_state), result);
2215
2216
0
  if (num_result > 1) {
2217
0
    DEBUG (0, ("ldapsam_add_sam_account: More than one user with that uid exists: bailing out!\n"));
2218
0
    goto fn_exit;
2219
0
  }
2220
2221
  /* Check if we need to update an existing entry */
2222
0
  if (num_result == 1) {
2223
0
    DEBUG(3,("ldapsam_add_sam_account: User exists without samba attributes: adding them\n"));
2224
0
    ldap_op = LDAP_MOD_REPLACE;
2225
0
    entry = ldap_first_entry(
2226
0
      smbldap_get_ldap(ldap_state->smbldap_state), result);
2227
0
    dn = smbldap_talloc_dn(
2228
0
      ctx, smbldap_get_ldap(ldap_state->smbldap_state),
2229
0
      entry);
2230
0
    if (!dn) {
2231
0
      status = NT_STATUS_NO_MEMORY;
2232
0
      goto fn_exit;
2233
0
    }
2234
2235
0
  } else if (ldap_state->schema_ver == SCHEMAVER_SAMBASAMACCOUNT) {
2236
2237
0
    struct dom_sid_buf buf;
2238
2239
    /* There might be a SID for this account already - say an idmap entry */
2240
2241
0
    filter = talloc_asprintf(ctx,
2242
0
        "(&(%s=%s)(|(objectClass=%s)(objectClass=%s)))",
2243
0
         get_userattr_key2string(ldap_state->schema_ver,
2244
0
           LDAP_ATTR_USER_SID),
2245
0
         dom_sid_str_buf(sid, &buf),
2246
0
         LDAP_OBJ_IDMAP_ENTRY,
2247
0
         LDAP_OBJ_SID_ENTRY);
2248
0
    if (!filter) {
2249
0
      status = NT_STATUS_NO_MEMORY;
2250
0
      goto fn_exit;
2251
0
    }
2252
2253
    /* free old result before doing a new search */
2254
0
    if (result != NULL) {
2255
0
      ldap_msgfree(result);
2256
0
      result = NULL;
2257
0
    }
2258
0
    rc = smbldap_search_suffix(ldap_state->smbldap_state,
2259
0
             filter, attr_list, &result);
2260
2261
0
    if ( rc != LDAP_SUCCESS ) {
2262
0
      goto fn_exit;
2263
0
    }
2264
2265
0
    num_result = ldap_count_entries(
2266
0
      smbldap_get_ldap(ldap_state->smbldap_state), result);
2267
2268
0
    if (num_result > 1) {
2269
0
      DEBUG (0, ("ldapsam_add_sam_account: More than one user with specified Sid exists: bailing out!\n"));
2270
0
      goto fn_exit;
2271
0
    }
2272
2273
    /* Check if we need to update an existing entry */
2274
0
    if (num_result == 1) {
2275
2276
0
      DEBUG(3,("ldapsam_add_sam_account: User exists without samba attributes: adding them\n"));
2277
0
      ldap_op = LDAP_MOD_REPLACE;
2278
0
      entry = ldap_first_entry (
2279
0
        smbldap_get_ldap(ldap_state->smbldap_state),
2280
0
        result);
2281
0
      dn = smbldap_talloc_dn (
2282
0
        ctx,
2283
0
        smbldap_get_ldap(ldap_state->smbldap_state),
2284
0
        entry);
2285
0
      if (!dn) {
2286
0
        status = NT_STATUS_NO_MEMORY;
2287
0
        goto fn_exit;
2288
0
      }
2289
0
    }
2290
0
  }
2291
2292
0
  if (num_result == 0) {
2293
0
    char *escape_username;
2294
    /* Check if we need to add an entry */
2295
0
    DEBUG(3,("ldapsam_add_sam_account: Adding new user\n"));
2296
0
    ldap_op = LDAP_MOD_ADD;
2297
2298
0
    escape_username = escape_rdn_val_string_alloc(username);
2299
0
    if (!escape_username) {
2300
0
      status = NT_STATUS_NO_MEMORY;
2301
0
      goto fn_exit;
2302
0
    }
2303
2304
0
    if (username[strlen(username)-1] == '$') {
2305
0
      dn = talloc_asprintf(ctx,
2306
0
          "uid=%s,%s",
2307
0
          escape_username,
2308
0
          lp_ldap_machine_suffix(talloc_tos()));
2309
0
    } else {
2310
0
      dn = talloc_asprintf(ctx,
2311
0
          "uid=%s,%s",
2312
0
          escape_username,
2313
0
          lp_ldap_user_suffix(talloc_tos()));
2314
0
    }
2315
2316
0
    SAFE_FREE(escape_username);
2317
0
    if (!dn) {
2318
0
      status = NT_STATUS_NO_MEMORY;
2319
0
      goto fn_exit;
2320
0
    }
2321
0
  }
2322
2323
0
  if (!init_ldap_from_sam(ldap_state, entry, &mods, newpwd,
2324
0
        pdb_element_is_set_or_changed)) {
2325
0
    DEBUG(0, ("ldapsam_add_sam_account: init_ldap_from_sam failed!\n"));
2326
0
    if (mods != NULL) {
2327
0
      ldap_mods_free(mods, true);
2328
0
    }
2329
0
    goto fn_exit;
2330
0
  }
2331
2332
0
  if (mods == NULL) {
2333
0
    DEBUG(0,("ldapsam_add_sam_account: mods is empty: nothing to add for user: %s\n",pdb_get_username(newpwd)));
2334
0
    goto fn_exit;
2335
0
  }
2336
0
  switch ( ldap_state->schema_ver ) {
2337
0
    case SCHEMAVER_SAMBASAMACCOUNT:
2338
0
      smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_SAMBASAMACCOUNT);
2339
0
      break;
2340
0
    default:
2341
0
      DEBUG(0,("ldapsam_add_sam_account: invalid schema version specified\n"));
2342
0
      break;
2343
0
  }
2344
2345
0
  status = ldapsam_modify_entry(my_methods,newpwd,dn,mods,ldap_op, pdb_element_is_set_or_changed);
2346
0
  if (!NT_STATUS_IS_OK(status)) {
2347
0
    DEBUG(0,("ldapsam_add_sam_account: failed to modify/add user with uid = %s (dn = %s)\n",
2348
0
       pdb_get_username(newpwd),dn));
2349
0
    ldap_mods_free(mods, true);
2350
0
    goto fn_exit;
2351
0
  }
2352
2353
0
  DEBUG(2,("ldapsam_add_sam_account: added: uid == %s in the LDAP database\n", pdb_get_username(newpwd)));
2354
0
  ldap_mods_free(mods, true);
2355
2356
0
  status = NT_STATUS_OK;
2357
2358
0
  fn_exit:
2359
2360
0
  TALLOC_FREE(ctx);
2361
0
  if (result) {
2362
0
    ldap_msgfree(result);
2363
0
  }
2364
0
  return status;
2365
0
}
2366
2367
/**********************************************************************
2368
 *********************************************************************/
2369
2370
static int ldapsam_search_one_group (struct ldapsam_privates *ldap_state,
2371
             const char *filter,
2372
             LDAPMessage ** result)
2373
0
{
2374
0
  int scope = LDAP_SCOPE_SUBTREE;
2375
0
  int rc;
2376
0
  const char **attr_list;
2377
2378
0
  attr_list = get_attr_list(NULL, groupmap_attr_list);
2379
0
  rc = smbldap_search(ldap_state->smbldap_state,
2380
0
          lp_ldap_suffix(), scope,
2381
0
          filter, attr_list, 0, result);
2382
0
  TALLOC_FREE(attr_list);
2383
2384
0
  return rc;
2385
0
}
2386
2387
/**********************************************************************
2388
 *********************************************************************/
2389
2390
static bool init_group_from_ldap(struct ldapsam_privates *ldap_state,
2391
         GROUP_MAP *map, LDAPMessage *entry)
2392
0
{
2393
0
  char *temp = NULL;
2394
0
  TALLOC_CTX *ctx = talloc_init("init_group_from_ldap");
2395
2396
0
  if (ldap_state == NULL || map == NULL || entry == NULL ||
2397
0
      smbldap_get_ldap(ldap_state->smbldap_state) == NULL) {
2398
0
    DEBUG(0, ("init_group_from_ldap: NULL parameters found!\n"));
2399
0
    TALLOC_FREE(ctx);
2400
0
    return false;
2401
0
  }
2402
2403
0
  temp = smbldap_talloc_single_attribute(
2404
0
      smbldap_get_ldap(ldap_state->smbldap_state),
2405
0
      entry,
2406
0
      get_attr_key2string(groupmap_attr_list,
2407
0
        LDAP_ATTR_GIDNUMBER),
2408
0
      ctx);
2409
0
  if (!temp) {
2410
0
    DEBUG(0, ("init_group_from_ldap: Mandatory attribute %s not found\n",
2411
0
      get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GIDNUMBER)));
2412
0
    TALLOC_FREE(ctx);
2413
0
    return false;
2414
0
  }
2415
0
  DEBUG(2, ("init_group_from_ldap: Entry found for group: %s\n", temp));
2416
2417
0
  map->gid = (gid_t)atol(temp);
2418
2419
0
  TALLOC_FREE(temp);
2420
0
  temp = smbldap_talloc_single_attribute(
2421
0
      smbldap_get_ldap(ldap_state->smbldap_state),
2422
0
      entry,
2423
0
      get_attr_key2string(groupmap_attr_list,
2424
0
        LDAP_ATTR_GROUP_SID),
2425
0
      ctx);
2426
0
  if (!temp) {
2427
0
    DEBUG(0, ("init_group_from_ldap: Mandatory attribute %s not found\n",
2428
0
      get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_SID)));
2429
0
    TALLOC_FREE(ctx);
2430
0
    return false;
2431
0
  }
2432
2433
0
  if (!string_to_sid(&map->sid, temp)) {
2434
0
    DEBUG(1, ("SID string [%s] could not be read as a valid SID\n", temp));
2435
0
    TALLOC_FREE(ctx);
2436
0
    return false;
2437
0
  }
2438
2439
0
  TALLOC_FREE(temp);
2440
0
  temp = smbldap_talloc_single_attribute(
2441
0
      smbldap_get_ldap(ldap_state->smbldap_state),
2442
0
      entry,
2443
0
      get_attr_key2string(groupmap_attr_list,
2444
0
        LDAP_ATTR_GROUP_TYPE),
2445
0
      ctx);
2446
0
  if (!temp) {
2447
0
    DEBUG(0, ("init_group_from_ldap: Mandatory attribute %s not found\n",
2448
0
      get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_TYPE)));
2449
0
    TALLOC_FREE(ctx);
2450
0
    return false;
2451
0
  }
2452
0
  map->sid_name_use = (enum lsa_SidType)atol(temp);
2453
2454
0
  if ((map->sid_name_use < SID_NAME_USER) ||
2455
0
      (map->sid_name_use > SID_NAME_UNKNOWN)) {
2456
0
    DEBUG(0, ("init_group_from_ldap: Unknown Group type: %d\n", map->sid_name_use));
2457
0
    TALLOC_FREE(ctx);
2458
0
    return false;
2459
0
  }
2460
2461
0
  TALLOC_FREE(temp);
2462
0
  temp = smbldap_talloc_single_attribute(
2463
0
      smbldap_get_ldap(ldap_state->smbldap_state),
2464
0
      entry,
2465
0
      get_attr_key2string(groupmap_attr_list,
2466
0
        LDAP_ATTR_DISPLAY_NAME),
2467
0
      ctx);
2468
0
  if (!temp) {
2469
0
    temp = smbldap_talloc_single_attribute(
2470
0
        smbldap_get_ldap(ldap_state->smbldap_state),
2471
0
        entry,
2472
0
        get_attr_key2string(groupmap_attr_list,
2473
0
          LDAP_ATTR_CN),
2474
0
        ctx);
2475
0
    if (!temp) {
2476
0
      DEBUG(0, ("init_group_from_ldap: Attributes cn not found either \
2477
0
for gidNumber(%lu)\n",(unsigned long)map->gid));
2478
0
      TALLOC_FREE(ctx);
2479
0
      return false;
2480
0
    }
2481
0
  }
2482
0
  map->nt_name = talloc_strdup(map, temp);
2483
0
  if (!map->nt_name) {
2484
0
    TALLOC_FREE(ctx);
2485
0
    return false;
2486
0
  }
2487
2488
0
  TALLOC_FREE(temp);
2489
0
  temp = smbldap_talloc_single_attribute(
2490
0
      smbldap_get_ldap(ldap_state->smbldap_state),
2491
0
      entry,
2492
0
      get_attr_key2string(groupmap_attr_list,
2493
0
        LDAP_ATTR_DESC),
2494
0
      ctx);
2495
0
  if (!temp) {
2496
0
    temp = talloc_strdup(ctx, "");
2497
0
    if (!temp) {
2498
0
      TALLOC_FREE(ctx);
2499
0
      return false;
2500
0
    }
2501
0
  }
2502
0
  map->comment = talloc_strdup(map, temp);
2503
0
  if (!map->comment) {
2504
0
    TALLOC_FREE(ctx);
2505
0
    return false;
2506
0
  }
2507
2508
0
  if (lp_parm_bool(-1, "ldapsam", "trusted", false)) {
2509
0
    struct unixid id;
2510
0
    id.id = map->gid;
2511
0
    id.type = ID_TYPE_GID;
2512
2513
0
    idmap_cache_set_sid2unixid(&map->sid, &id);
2514
0
  }
2515
2516
0
  TALLOC_FREE(ctx);
2517
0
  return true;
2518
0
}
2519
2520
/**********************************************************************
2521
 *********************************************************************/
2522
2523
static NTSTATUS ldapsam_getgroup(struct pdb_methods *methods,
2524
         const char *filter,
2525
         GROUP_MAP *map)
2526
0
{
2527
0
  struct ldapsam_privates *ldap_state =
2528
0
    (struct ldapsam_privates *)methods->private_data;
2529
0
  LDAPMessage *result = NULL;
2530
0
  LDAPMessage *entry = NULL;
2531
0
  int count;
2532
2533
0
  if (ldapsam_search_one_group(ldap_state, filter, &result)
2534
0
      != LDAP_SUCCESS) {
2535
0
    return NT_STATUS_NO_SUCH_GROUP;
2536
0
  }
2537
2538
0
  count = ldap_count_entries(priv2ld(ldap_state), result);
2539
2540
0
  if (count < 1) {
2541
0
    DEBUG(4, ("ldapsam_getgroup: Did not find group, filter was "
2542
0
        "%s\n", filter));
2543
0
    ldap_msgfree(result);
2544
0
    return NT_STATUS_NO_SUCH_GROUP;
2545
0
  }
2546
2547
0
  if (count > 1) {
2548
0
    DEBUG(1, ("ldapsam_getgroup: Duplicate entries for filter %s: "
2549
0
        "count=%d\n", filter, count));
2550
0
    ldap_msgfree(result);
2551
0
    return NT_STATUS_NO_SUCH_GROUP;
2552
0
  }
2553
2554
0
  entry = ldap_first_entry(priv2ld(ldap_state), result);
2555
2556
0
  if (!entry) {
2557
0
    ldap_msgfree(result);
2558
0
    return NT_STATUS_UNSUCCESSFUL;
2559
0
  }
2560
2561
0
  if (!init_group_from_ldap(ldap_state, map, entry)) {
2562
0
    DEBUG(1, ("ldapsam_getgroup: init_group_from_ldap failed for "
2563
0
        "group filter %s\n", filter));
2564
0
    ldap_msgfree(result);
2565
0
    return NT_STATUS_NO_SUCH_GROUP;
2566
0
  }
2567
2568
0
  ldap_msgfree(result);
2569
0
  return NT_STATUS_OK;
2570
0
}
2571
2572
/**********************************************************************
2573
 *********************************************************************/
2574
2575
static NTSTATUS ldapsam_getgrsid(struct pdb_methods *methods, GROUP_MAP *map,
2576
         struct dom_sid sid)
2577
0
{
2578
0
  char *filter = NULL;
2579
0
  NTSTATUS status;
2580
0
  struct dom_sid_buf tmp;
2581
2582
0
  if (asprintf(&filter, "(&(objectClass=%s)(%s=%s))",
2583
0
    LDAP_OBJ_GROUPMAP,
2584
0
    get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GROUP_SID),
2585
0
    dom_sid_str_buf(&sid, &tmp)) < 0) {
2586
0
    return NT_STATUS_NO_MEMORY;
2587
0
  }
2588
2589
0
  status = ldapsam_getgroup(methods, filter, map);
2590
0
  SAFE_FREE(filter);
2591
0
  return status;
2592
0
}
2593
2594
/**********************************************************************
2595
 *********************************************************************/
2596
2597
static NTSTATUS ldapsam_getgrgid(struct pdb_methods *methods, GROUP_MAP *map,
2598
         gid_t gid)
2599
0
{
2600
0
  char *filter = NULL;
2601
0
  NTSTATUS status;
2602
2603
0
  if (asprintf(&filter, "(&(objectClass=%s)(%s=%lu))",
2604
0
    LDAP_OBJ_GROUPMAP,
2605
0
    get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GIDNUMBER),
2606
0
    (unsigned long)gid) < 0) {
2607
0
    return NT_STATUS_NO_MEMORY;
2608
0
  }
2609
2610
0
  status = ldapsam_getgroup(methods, filter, map);
2611
0
  SAFE_FREE(filter);
2612
0
  return status;
2613
0
}
2614
2615
/**********************************************************************
2616
 *********************************************************************/
2617
2618
static NTSTATUS ldapsam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map,
2619
         const char *name)
2620
0
{
2621
0
  char *filter = NULL;
2622
0
  char *escape_name = escape_ldap_string(talloc_tos(), name);
2623
0
  NTSTATUS status;
2624
2625
0
  if (!escape_name) {
2626
0
    return NT_STATUS_NO_MEMORY;
2627
0
  }
2628
2629
0
  if (asprintf(&filter, "(&(objectClass=%s)(|(%s=%s)(%s=%s)))",
2630
0
    LDAP_OBJ_GROUPMAP,
2631
0
    get_attr_key2string(groupmap_attr_list, LDAP_ATTR_DISPLAY_NAME), escape_name,
2632
0
    get_attr_key2string(groupmap_attr_list, LDAP_ATTR_CN),
2633
0
    escape_name) < 0) {
2634
0
    TALLOC_FREE(escape_name);
2635
0
    return NT_STATUS_NO_MEMORY;
2636
0
  }
2637
2638
0
  TALLOC_FREE(escape_name);
2639
0
  status = ldapsam_getgroup(methods, filter, map);
2640
0
  SAFE_FREE(filter);
2641
0
  return status;
2642
0
}
2643
2644
static bool ldapsam_extract_rid_from_entry(LDAP *ldap_struct,
2645
             LDAPMessage *entry,
2646
             const struct dom_sid *domain_sid,
2647
             uint32_t *rid)
2648
0
{
2649
0
  fstring str;
2650
0
  struct dom_sid sid;
2651
2652
0
  if (!smbldap_get_single_attribute(ldap_struct, entry, "sambaSID",
2653
0
            str, sizeof(str)-1)) {
2654
0
    DEBUG(10, ("Could not find sambaSID attribute\n"));
2655
0
    return False;
2656
0
  }
2657
2658
0
  if (!string_to_sid(&sid, str)) {
2659
0
    DEBUG(10, ("Could not convert string %s to sid\n", str));
2660
0
    return False;
2661
0
  }
2662
2663
0
  if (dom_sid_compare_domain(&sid, domain_sid) != 0) {
2664
0
    struct dom_sid_buf buf;
2665
0
    DEBUG(10, ("SID %s is not in expected domain %s\n",
2666
0
         str,
2667
0
         dom_sid_str_buf(domain_sid, &buf)));
2668
0
    return False;
2669
0
  }
2670
2671
0
  if (!sid_peek_rid(&sid, rid)) {
2672
0
    DEBUG(10, ("Could not peek into RID\n"));
2673
0
    return False;
2674
0
  }
2675
2676
0
  return True;
2677
0
}
2678
2679
static NTSTATUS ldapsam_enum_group_members(struct pdb_methods *methods,
2680
             TALLOC_CTX *mem_ctx,
2681
             const struct dom_sid *group,
2682
             uint32_t **pp_member_rids,
2683
             size_t *p_num_members)
2684
0
{
2685
0
  struct ldapsam_privates *ldap_state =
2686
0
    (struct ldapsam_privates *)methods->private_data;
2687
0
  struct smbldap_state *conn = ldap_state->smbldap_state;
2688
0
  const char *id_attrs[] = { "memberUid", "gidNumber", NULL };
2689
0
  const char *sid_attrs[] = { "sambaSID", NULL };
2690
0
  NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
2691
0
  LDAPMessage *result = NULL;
2692
0
  LDAPMessage *entry;
2693
0
  char *filter;
2694
0
  char **values = NULL;
2695
0
  char **memberuid;
2696
0
  char *gidstr;
2697
0
  int rc, count;
2698
0
  struct dom_sid_buf buf;
2699
2700
0
  *pp_member_rids = NULL;
2701
0
  *p_num_members = 0;
2702
2703
0
  filter = talloc_asprintf(mem_ctx,
2704
0
         "(&(objectClass="LDAP_OBJ_POSIXGROUP")"
2705
0
         "(objectClass="LDAP_OBJ_GROUPMAP")"
2706
0
         "(sambaSID=%s))",
2707
0
         dom_sid_str_buf(group, &buf));
2708
0
  if (filter == NULL) {
2709
0
    ret = NT_STATUS_NO_MEMORY;
2710
0
    goto done;
2711
0
  }
2712
2713
0
  rc = smbldap_search(conn, lp_ldap_suffix(),
2714
0
          LDAP_SCOPE_SUBTREE, filter, id_attrs, 0,
2715
0
          &result);
2716
2717
0
  if (rc != LDAP_SUCCESS)
2718
0
    goto done;
2719
2720
0
  smbldap_talloc_autofree_ldapmsg(mem_ctx, result);
2721
2722
0
  count = ldap_count_entries(smbldap_get_ldap(conn), result);
2723
2724
0
  if (count > 1) {
2725
0
    DEBUG(1, ("Found more than one groupmap entry for %s\n",
2726
0
        dom_sid_str_buf(group, &buf)));
2727
0
    ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
2728
0
    goto done;
2729
0
  }
2730
2731
0
  if (count == 0) {
2732
0
    ret = NT_STATUS_NO_SUCH_GROUP;
2733
0
    goto done;
2734
0
  }
2735
2736
0
  entry = ldap_first_entry(smbldap_get_ldap(conn), result);
2737
0
  if (entry == NULL)
2738
0
    goto done;
2739
2740
0
  gidstr = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "gidNumber", mem_ctx);
2741
0
  if (!gidstr) {
2742
0
    DEBUG (0, ("ldapsam_enum_group_members: Unable to find the group's gid!\n"));
2743
0
    ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
2744
0
    goto done;
2745
0
  }
2746
2747
0
  values = ldap_get_values(smbldap_get_ldap(conn), entry, "memberUid");
2748
2749
0
  if ((values != NULL) && (values[0] != NULL)) {
2750
2751
0
    filter = talloc_strdup(mem_ctx, "(&(objectClass="LDAP_OBJ_SAMBASAMACCOUNT")(|");
2752
2753
0
    for (memberuid = values; *memberuid != NULL; memberuid += 1) {
2754
0
      char *escape_memberuid;
2755
2756
0
      escape_memberuid = escape_ldap_string(talloc_tos(),
2757
0
                    *memberuid);
2758
0
      if (escape_memberuid == NULL) {
2759
0
        ret = NT_STATUS_NO_MEMORY;
2760
0
        goto done;
2761
0
      }
2762
2763
0
      filter = talloc_asprintf_append_buffer(filter, "(uid=%s)", escape_memberuid);
2764
0
      TALLOC_FREE(escape_memberuid);
2765
0
      if (filter == NULL) {
2766
0
        ret = NT_STATUS_NO_MEMORY;
2767
0
        goto done;
2768
0
      }
2769
0
    }
2770
2771
0
    filter = talloc_asprintf_append_buffer(filter, "))");
2772
0
    if (filter == NULL) {
2773
0
      ret = NT_STATUS_NO_MEMORY;
2774
0
      goto done;
2775
0
    }
2776
2777
0
    rc = smbldap_search(conn, lp_ldap_suffix(),
2778
0
            LDAP_SCOPE_SUBTREE, filter, sid_attrs, 0,
2779
0
            &result);
2780
2781
0
    if (rc != LDAP_SUCCESS)
2782
0
      goto done;
2783
2784
0
    count = ldap_count_entries(smbldap_get_ldap(conn), result);
2785
0
    DEBUG(10,("ldapsam_enum_group_members: found %d accounts\n", count));
2786
2787
0
    smbldap_talloc_autofree_ldapmsg(mem_ctx, result);
2788
2789
0
    for (entry = ldap_first_entry(smbldap_get_ldap(conn), result);
2790
0
         entry != NULL;
2791
0
         entry = ldap_next_entry(smbldap_get_ldap(conn), entry))
2792
0
    {
2793
0
      char *sidstr;
2794
0
      struct dom_sid sid;
2795
0
      uint32_t rid;
2796
2797
0
      sidstr = smbldap_talloc_single_attribute(
2798
0
        smbldap_get_ldap(conn), entry, "sambaSID",
2799
0
        mem_ctx);
2800
0
      if (!sidstr) {
2801
0
        DEBUG(0, ("Severe DB error, %s can't miss the sambaSID"
2802
0
            "attribute\n", LDAP_OBJ_SAMBASAMACCOUNT));
2803
0
        ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
2804
0
        goto done;
2805
0
      }
2806
2807
0
      if (!string_to_sid(&sid, sidstr))
2808
0
        goto done;
2809
2810
0
      if (!sid_check_is_in_our_sam(&sid)) {
2811
0
        DEBUG(0, ("Inconsistent SAM -- group member uid not "
2812
0
            "in our domain\n"));
2813
0
        ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
2814
0
        goto done;
2815
0
      }
2816
2817
0
      sid_peek_rid(&sid, &rid);
2818
2819
0
      if (!add_rid_to_array_unique(mem_ctx, rid, pp_member_rids,
2820
0
            p_num_members)) {
2821
0
        ret = NT_STATUS_NO_MEMORY;
2822
0
        goto done;
2823
0
      }
2824
0
    }
2825
0
  }
2826
2827
0
  filter = talloc_asprintf(mem_ctx,
2828
0
         "(&(objectClass=%s)"
2829
0
         "(gidNumber=%s))",
2830
0
         LDAP_OBJ_SAMBASAMACCOUNT,
2831
0
         gidstr);
2832
2833
0
  rc = smbldap_search(conn, lp_ldap_suffix(),
2834
0
          LDAP_SCOPE_SUBTREE, filter, sid_attrs, 0,
2835
0
          &result);
2836
2837
0
  if (rc != LDAP_SUCCESS)
2838
0
    goto done;
2839
2840
0
  smbldap_talloc_autofree_ldapmsg(mem_ctx, result);
2841
2842
0
  for (entry = ldap_first_entry(smbldap_get_ldap(conn), result);
2843
0
       entry != NULL;
2844
0
       entry = ldap_next_entry(smbldap_get_ldap(conn), entry))
2845
0
  {
2846
0
    uint32_t rid;
2847
2848
0
    if (!ldapsam_extract_rid_from_entry(smbldap_get_ldap(conn),
2849
0
                entry,
2850
0
                get_global_sam_sid(),
2851
0
                &rid)) {
2852
0
      DEBUG(0, ("Severe DB error, %s can't miss the samba SID"
2853
0
          "attribute\n", LDAP_OBJ_SAMBASAMACCOUNT));
2854
0
      ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
2855
0
      goto done;
2856
0
    }
2857
2858
0
    if (!add_rid_to_array_unique(mem_ctx, rid, pp_member_rids,
2859
0
          p_num_members)) {
2860
0
      ret = NT_STATUS_NO_MEMORY;
2861
0
      goto done;
2862
0
    }
2863
0
  }
2864
2865
0
  ret = NT_STATUS_OK;
2866
2867
0
 done:
2868
2869
0
  if (values)
2870
0
    ldap_value_free(values);
2871
2872
0
  return ret;
2873
0
}
2874
2875
static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods,
2876
                 TALLOC_CTX *mem_ctx,
2877
                 struct samu *user,
2878
                 struct dom_sid **pp_sids,
2879
                 gid_t **pp_gids,
2880
                 uint32_t *p_num_groups)
2881
0
{
2882
0
  struct ldapsam_privates *ldap_state =
2883
0
    (struct ldapsam_privates *)methods->private_data;
2884
0
  struct smbldap_state *conn = ldap_state->smbldap_state;
2885
0
  char *filter;
2886
0
  const char *attrs[] = { "gidNumber", "sambaSID", NULL };
2887
0
  char *escape_name;
2888
0
  int rc, count;
2889
0
  LDAPMessage *result = NULL;
2890
0
  LDAPMessage *entry;
2891
0
  NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
2892
0
  uint32_t num_sids;
2893
0
  uint32_t num_gids;
2894
0
  char *gidstr;
2895
0
  gid_t primary_gid = -1;
2896
0
  int error = 0;
2897
2898
0
  *pp_sids = NULL;
2899
0
  num_sids = 0;
2900
2901
0
  if (pdb_get_username(user) == NULL) {
2902
0
    return NT_STATUS_INVALID_PARAMETER;
2903
0
  }
2904
2905
0
  escape_name = escape_ldap_string(talloc_tos(), pdb_get_username(user));
2906
0
  if (escape_name == NULL)
2907
0
    return NT_STATUS_NO_MEMORY;
2908
2909
0
  if (user->unix_pw) {
2910
0
    primary_gid = user->unix_pw->pw_gid;
2911
0
  } else {
2912
    /* retrieve the users primary gid */
2913
0
    filter = talloc_asprintf(mem_ctx,
2914
0
           "(&(objectClass="LDAP_OBJ_SAMBASAMACCOUNT")(uid=%s))",
2915
0
           escape_name);
2916
0
    if (filter == NULL) {
2917
0
      ret = NT_STATUS_NO_MEMORY;
2918
0
      goto done;
2919
0
    }
2920
2921
0
    rc = smbldap_search(conn, lp_ldap_suffix(),
2922
0
            LDAP_SCOPE_SUBTREE, filter, attrs, 0, &result);
2923
2924
0
    if (rc != LDAP_SUCCESS)
2925
0
      goto done;
2926
2927
0
    smbldap_talloc_autofree_ldapmsg(mem_ctx, result);
2928
2929
0
    count = ldap_count_entries(priv2ld(ldap_state), result);
2930
2931
0
    switch (count) {
2932
0
    case 0:
2933
0
      DEBUG(1, ("User account [%s] not found!\n", pdb_get_username(user)));
2934
0
      ret = NT_STATUS_NO_SUCH_USER;
2935
0
      goto done;
2936
0
    case 1:
2937
0
      entry = ldap_first_entry(priv2ld(ldap_state), result);
2938
2939
0
      gidstr = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "gidNumber", mem_ctx);
2940
0
      if (!gidstr) {
2941
0
        DEBUG (1, ("Unable to find the member's gid!\n"));
2942
0
        ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
2943
0
        goto done;
2944
0
      }
2945
0
      primary_gid = smb_strtoul(gidstr,
2946
0
              NULL,
2947
0
              10,
2948
0
              &error,
2949
0
              SMB_STR_STANDARD);
2950
0
      if (error != 0) {
2951
0
        DBG_ERR("Failed to convert GID\n");
2952
0
        goto done;
2953
0
      }
2954
0
      break;
2955
0
    default:
2956
0
      DEBUG(1, ("found more than one account with the same user name ?!\n"));
2957
0
      ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
2958
0
      goto done;
2959
0
    }
2960
0
  }
2961
2962
0
  filter = talloc_asprintf(mem_ctx,
2963
0
         "(&(objectClass="LDAP_OBJ_POSIXGROUP")(|(memberUid=%s)(gidNumber=%u)))",
2964
0
         escape_name, (unsigned int)primary_gid);
2965
0
  if (filter == NULL) {
2966
0
    ret = NT_STATUS_NO_MEMORY;
2967
0
    goto done;
2968
0
  }
2969
2970
0
  rc = smbldap_search(conn, lp_ldap_suffix(),
2971
0
          LDAP_SCOPE_SUBTREE, filter, attrs, 0, &result);
2972
2973
0
  if (rc != LDAP_SUCCESS)
2974
0
    goto done;
2975
2976
0
  smbldap_talloc_autofree_ldapmsg(mem_ctx, result);
2977
2978
0
  num_gids = 0;
2979
0
  *pp_gids = NULL;
2980
2981
0
  num_sids = 0;
2982
0
  *pp_sids = NULL;
2983
2984
  /* We need to add the primary group as the first gid/sid */
2985
2986
0
  if (!add_gid_to_array_unique(mem_ctx, primary_gid, pp_gids, &num_gids)) {
2987
0
    ret = NT_STATUS_NO_MEMORY;
2988
0
    goto done;
2989
0
  }
2990
2991
  /* This sid will be replaced later */
2992
2993
0
  ret = add_sid_to_array_unique(mem_ctx, &global_sid_NULL, pp_sids,
2994
0
              &num_sids);
2995
0
  if (!NT_STATUS_IS_OK(ret)) {
2996
0
    goto done;
2997
0
  }
2998
2999
0
  for (entry = ldap_first_entry(smbldap_get_ldap(conn), result);
3000
0
       entry != NULL;
3001
0
       entry = ldap_next_entry(smbldap_get_ldap(conn), entry))
3002
0
  {
3003
0
    fstring str;
3004
0
    struct dom_sid sid;
3005
0
    gid_t gid;
3006
3007
0
    if (!smbldap_get_single_attribute(smbldap_get_ldap(conn),
3008
0
              entry, "sambaSID",
3009
0
              str, sizeof(str)-1))
3010
0
      continue;
3011
3012
0
    if (!string_to_sid(&sid, str))
3013
0
      goto done;
3014
3015
0
    if (!smbldap_get_single_attribute(smbldap_get_ldap(conn),
3016
0
              entry, "gidNumber",
3017
0
              str, sizeof(str)-1))
3018
0
      continue;
3019
3020
0
    gid = smb_strtoul(str, NULL, 10, &error, SMB_STR_FULL_STR_CONV);
3021
3022
0
    if (error != 0) {
3023
0
      goto done;
3024
0
    }
3025
3026
0
    if (gid == primary_gid) {
3027
0
      sid_copy(&(*pp_sids)[0], &sid);
3028
0
    } else {
3029
0
      if (!add_gid_to_array_unique(mem_ctx, gid, pp_gids,
3030
0
            &num_gids)) {
3031
0
        ret = NT_STATUS_NO_MEMORY;
3032
0
        goto done;
3033
0
      }
3034
0
      ret = add_sid_to_array_unique(mem_ctx, &sid, pp_sids,
3035
0
                  &num_sids);
3036
0
      if (!NT_STATUS_IS_OK(ret)) {
3037
0
        goto done;
3038
0
      }
3039
0
    }
3040
0
  }
3041
3042
0
  if (dom_sid_compare(&global_sid_NULL, &(*pp_sids)[0]) == 0) {
3043
0
    DEBUG(3, ("primary group of [%s] not found\n",
3044
0
        pdb_get_username(user)));
3045
0
    ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
3046
0
    goto done;
3047
0
  }
3048
3049
0
  *p_num_groups = num_sids;
3050
3051
0
  ret = NT_STATUS_OK;
3052
3053
0
 done:
3054
3055
0
  TALLOC_FREE(escape_name);
3056
0
  return ret;
3057
0
}
3058
3059
/**********************************************************************
3060
 * Augment a posixGroup object with a sambaGroupMapping domgroup
3061
 *********************************************************************/
3062
3063
static NTSTATUS ldapsam_map_posixgroup(TALLOC_CTX *mem_ctx,
3064
               struct ldapsam_privates *ldap_state,
3065
               GROUP_MAP *map)
3066
0
{
3067
0
  const char *filter, *dn;
3068
0
  LDAPMessage *msg, *entry;
3069
0
  LDAPMod **mods;
3070
0
  struct dom_sid_buf buf;
3071
0
  int rc;
3072
3073
0
  filter = talloc_asprintf(mem_ctx,
3074
0
         "(&(objectClass="LDAP_OBJ_POSIXGROUP")(gidNumber=%u))",
3075
0
         (unsigned int)map->gid);
3076
0
  if (filter == NULL) {
3077
0
    return NT_STATUS_NO_MEMORY;
3078
0
  }
3079
3080
0
  rc = smbldap_search_suffix(ldap_state->smbldap_state, filter,
3081
0
           get_attr_list(mem_ctx, groupmap_attr_list),
3082
0
           &msg);
3083
0
  smbldap_talloc_autofree_ldapmsg(mem_ctx, msg);
3084
3085
0
  if ((rc != LDAP_SUCCESS) ||
3086
0
      (ldap_count_entries(smbldap_get_ldap(ldap_state->smbldap_state),
3087
0
        msg) != 1) ||
3088
0
      ((entry = ldap_first_entry(
3089
0
          smbldap_get_ldap(ldap_state->smbldap_state),
3090
0
          msg)) == NULL)) {
3091
0
    return NT_STATUS_NO_SUCH_GROUP;
3092
0
  }
3093
3094
0
  dn = smbldap_talloc_dn(mem_ctx,
3095
0
             smbldap_get_ldap(ldap_state->smbldap_state),
3096
0
             entry);
3097
0
  if (dn == NULL) {
3098
0
    return NT_STATUS_NO_MEMORY;
3099
0
  }
3100
3101
0
  mods = NULL;
3102
0
  smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass",
3103
0
      LDAP_OBJ_GROUPMAP);
3104
0
  smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), entry,
3105
0
       &mods, "sambaSid",
3106
0
       dom_sid_str_buf(&map->sid, &buf));
3107
0
  smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), entry,
3108
0
       &mods, "sambaGroupType",
3109
0
       talloc_asprintf(mem_ctx, "%d", map->sid_name_use));
3110
0
  smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), entry,
3111
0
       &mods, "displayName",
3112
0
       map->nt_name);
3113
0
  smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), entry,
3114
0
       &mods, "description",
3115
0
       map->comment);
3116
0
  smbldap_talloc_autofree_ldapmod(mem_ctx, mods);
3117
3118
0
  rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
3119
0
  if (rc != LDAP_SUCCESS) {
3120
0
    return NT_STATUS_ACCESS_DENIED;
3121
0
  }
3122
3123
0
  return NT_STATUS_OK;
3124
0
}
3125
3126
static NTSTATUS ldapsam_add_group_mapping_entry(struct pdb_methods *methods,
3127
            GROUP_MAP *map)
3128
0
{
3129
0
  struct ldapsam_privates *ldap_state =
3130
0
    (struct ldapsam_privates *)methods->private_data;
3131
0
  LDAPMessage *msg = NULL;
3132
0
  LDAPMod **mods = NULL;
3133
0
  const char *attrs[] = { NULL };
3134
0
  char *filter;
3135
3136
0
  char *dn;
3137
0
  TALLOC_CTX *mem_ctx;
3138
0
  NTSTATUS result;
3139
3140
0
  struct dom_sid sid;
3141
0
  struct dom_sid_buf buf;
3142
0
  struct unixid id;
3143
3144
0
  int rc;
3145
3146
0
  mem_ctx = talloc_new(NULL);
3147
0
  if (mem_ctx == NULL) {
3148
0
    DEBUG(0, ("talloc_new failed\n"));
3149
0
    return NT_STATUS_NO_MEMORY;
3150
0
  }
3151
3152
0
  filter = talloc_asprintf(mem_ctx, "(sambaSid=%s)",
3153
0
         dom_sid_str_buf(&map->sid, &buf));
3154
0
  if (filter == NULL) {
3155
0
    result = NT_STATUS_NO_MEMORY;
3156
0
    goto done;
3157
0
  }
3158
3159
0
  rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_suffix(),
3160
0
          LDAP_SCOPE_SUBTREE, filter, attrs, True, &msg);
3161
0
  smbldap_talloc_autofree_ldapmsg(mem_ctx, msg);
3162
3163
0
  if ((rc == LDAP_SUCCESS) &&
3164
0
      (ldap_count_entries(smbldap_get_ldap(ldap_state->smbldap_state),
3165
0
        msg) > 0)) {
3166
3167
0
    DEBUG(3, ("SID %s already present in LDAP, refusing to add "
3168
0
        "group mapping entry\n",
3169
0
        dom_sid_str_buf(&map->sid, &buf)));
3170
0
    result = NT_STATUS_GROUP_EXISTS;
3171
0
    goto done;
3172
0
  }
3173
3174
0
  switch (map->sid_name_use) {
3175
3176
0
  case SID_NAME_DOM_GRP:
3177
    /* To map a domain group we need to have a posix group
3178
       to attach to. */
3179
0
    result = ldapsam_map_posixgroup(mem_ctx, ldap_state, map);
3180
0
    goto done;
3181
0
    break;
3182
3183
0
  case SID_NAME_ALIAS:
3184
0
    if (!sid_check_is_in_our_sam(&map->sid)
3185
0
      && !sid_check_is_in_builtin(&map->sid) )
3186
0
    {
3187
0
      DEBUG(3, ("Refusing to map sid %s as an alias, not in our domain\n",
3188
0
          dom_sid_str_buf(&map->sid, &buf)));
3189
0
      result = NT_STATUS_INVALID_PARAMETER;
3190
0
      goto done;
3191
0
    }
3192
0
    break;
3193
3194
0
  default:
3195
0
    DEBUG(3, ("Got invalid use '%s' for mapping\n",
3196
0
        sid_type_lookup(map->sid_name_use)));
3197
0
    result = NT_STATUS_INVALID_PARAMETER;
3198
0
    goto done;
3199
0
  }
3200
3201
  /* Domain groups have been mapped in a separate routine, we have to
3202
   * create an alias now */
3203
3204
0
  if (map->gid == -1) {
3205
0
    DEBUG(10, ("Refusing to map gid==-1\n"));
3206
0
    result = NT_STATUS_INVALID_PARAMETER;
3207
0
    goto done;
3208
0
  }
3209
3210
0
  id.id = map->gid;
3211
0
  id.type = ID_TYPE_GID;
3212
3213
0
  if (pdb_id_to_sid(&id, &sid)) {
3214
0
    DEBUG(3, ("Gid %u is already mapped to SID %s, refusing to "
3215
0
        "add\n",
3216
0
        (unsigned int)map->gid,
3217
0
        dom_sid_str_buf(&sid, &buf)));
3218
0
    result = NT_STATUS_GROUP_EXISTS;
3219
0
    goto done;
3220
0
  }
3221
3222
  /* Ok, enough checks done. It's still racy to go ahead now, but that's
3223
   * the best we can get out of LDAP. */
3224
3225
0
  dn = talloc_asprintf(mem_ctx, "sambaSid=%s,%s",
3226
0
           dom_sid_str_buf(&map->sid, &buf),
3227
0
           lp_ldap_group_suffix(talloc_tos()));
3228
0
  if (dn == NULL) {
3229
0
    result = NT_STATUS_NO_MEMORY;
3230
0
    goto done;
3231
0
  }
3232
3233
0
  mods = NULL;
3234
3235
0
  smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), NULL,
3236
0
       &mods, "objectClass", LDAP_OBJ_SID_ENTRY);
3237
0
  smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), NULL,
3238
0
       &mods, "objectClass", LDAP_OBJ_GROUPMAP);
3239
0
  smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), NULL,
3240
0
       &mods, "sambaSid",
3241
0
       dom_sid_str_buf(&map->sid, &buf));
3242
0
  smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), NULL,
3243
0
       &mods, "sambaGroupType",
3244
0
       talloc_asprintf(mem_ctx, "%d", map->sid_name_use));
3245
0
  smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), NULL,
3246
0
       &mods, "displayName",
3247
0
       map->nt_name);
3248
0
  smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), NULL,
3249
0
       &mods, "description",
3250
0
       map->comment);
3251
0
  smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), NULL,
3252
0
       &mods, "gidNumber",
3253
0
       talloc_asprintf(mem_ctx, "%u",
3254
0
           (unsigned int)map->gid));
3255
0
  smbldap_talloc_autofree_ldapmod(mem_ctx, mods);
3256
3257
0
  rc = smbldap_add(ldap_state->smbldap_state, dn, mods);
3258
3259
0
  result = (rc == LDAP_SUCCESS) ?
3260
0
    NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
3261
3262
0
 done:
3263
0
  TALLOC_FREE(mem_ctx);
3264
0
  return result;
3265
0
}
3266
3267
/**********************************************************************
3268
 * Update a group mapping entry. We're quite strict about what can be changed:
3269
 * Only the description and displayname may be changed. It simply does not
3270
 * make any sense to change the SID, gid or the type in a mapping.
3271
 *********************************************************************/
3272
3273
static NTSTATUS ldapsam_update_group_mapping_entry(struct pdb_methods *methods,
3274
               GROUP_MAP *map)
3275
0
{
3276
0
  struct ldapsam_privates *ldap_state =
3277
0
    (struct ldapsam_privates *)methods->private_data;
3278
0
  int rc;
3279
0
  const char *filter, *dn;
3280
0
  LDAPMessage *msg = NULL;
3281
0
  LDAPMessage *entry = NULL;
3282
0
  LDAPMod **mods = NULL;
3283
0
  TALLOC_CTX *mem_ctx;
3284
0
  NTSTATUS result;
3285
0
  struct dom_sid_buf buf;
3286
3287
0
  mem_ctx = talloc_new(NULL);
3288
0
  if (mem_ctx == NULL) {
3289
0
    DEBUG(0, ("talloc_new failed\n"));
3290
0
    return NT_STATUS_NO_MEMORY;
3291
0
  }
3292
3293
  /* Make 100% sure that sid, gid and type are not changed by looking up
3294
   * exactly the values we're given in LDAP. */
3295
3296
0
  filter = talloc_asprintf(mem_ctx, "(&(objectClass="LDAP_OBJ_GROUPMAP")"
3297
0
         "(sambaSid=%s)(gidNumber=%u)"
3298
0
         "(sambaGroupType=%d))",
3299
0
         dom_sid_str_buf(&map->sid, &buf),
3300
0
         (unsigned int)map->gid, map->sid_name_use);
3301
0
  if (filter == NULL) {
3302
0
    result = NT_STATUS_NO_MEMORY;
3303
0
    goto done;
3304
0
  }
3305
3306
0
  rc = smbldap_search_suffix(ldap_state->smbldap_state, filter,
3307
0
           get_attr_list(mem_ctx, groupmap_attr_list),
3308
0
           &msg);
3309
0
  smbldap_talloc_autofree_ldapmsg(mem_ctx, msg);
3310
3311
0
  if ((rc != LDAP_SUCCESS) ||
3312
0
      (ldap_count_entries(smbldap_get_ldap(ldap_state->smbldap_state),
3313
0
        msg) != 1) ||
3314
0
      ((entry = ldap_first_entry(
3315
0
          smbldap_get_ldap(ldap_state->smbldap_state),
3316
0
          msg)) == NULL)) {
3317
0
    result = NT_STATUS_NO_SUCH_GROUP;
3318
0
    goto done;
3319
0
  }
3320
3321
0
  dn = smbldap_talloc_dn(
3322
0
    mem_ctx, smbldap_get_ldap(ldap_state->smbldap_state), entry);
3323
3324
0
  if (dn == NULL) {
3325
0
    result = NT_STATUS_NO_MEMORY;
3326
0
    goto done;
3327
0
  }
3328
3329
0
  mods = NULL;
3330
0
  smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), entry,
3331
0
       &mods, "displayName", map->nt_name);
3332
0
  smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), entry,
3333
0
       &mods, "description", map->comment);
3334
0
  smbldap_talloc_autofree_ldapmod(mem_ctx, mods);
3335
3336
0
  if (mods == NULL) {
3337
0
    DEBUG(4, ("ldapsam_update_group_mapping_entry: mods is empty: "
3338
0
        "nothing to do\n"));
3339
0
    result = NT_STATUS_OK;
3340
0
    goto done;
3341
0
  }
3342
3343
0
  rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
3344
3345
0
  if (rc != LDAP_SUCCESS) {
3346
0
    result = NT_STATUS_ACCESS_DENIED;
3347
0
    goto done;
3348
0
  }
3349
3350
0
  DEBUG(2, ("ldapsam_update_group_mapping_entry: successfully modified "
3351
0
      "group %lu in LDAP\n", (unsigned long)map->gid));
3352
3353
0
  result = NT_STATUS_OK;
3354
3355
0
 done:
3356
0
  TALLOC_FREE(mem_ctx);
3357
0
  return result;
3358
0
}
3359
3360
/**********************************************************************
3361
 *********************************************************************/
3362
3363
static NTSTATUS ldapsam_delete_group_mapping_entry(struct pdb_methods *methods,
3364
               struct dom_sid sid)
3365
0
{
3366
0
  struct ldapsam_privates *priv =
3367
0
    (struct ldapsam_privates *)methods->private_data;
3368
0
  LDAPMessage *msg, *entry;
3369
0
  int rc;
3370
0
  NTSTATUS result;
3371
0
  TALLOC_CTX *mem_ctx;
3372
0
  char *filter;
3373
0
  struct dom_sid_buf buf;
3374
3375
0
  mem_ctx = talloc_new(NULL);
3376
0
  if (mem_ctx == NULL) {
3377
0
    DEBUG(0, ("talloc_new failed\n"));
3378
0
    return NT_STATUS_NO_MEMORY;
3379
0
  }
3380
3381
0
  filter = talloc_asprintf(mem_ctx, "(&(objectClass="LDAP_OBJ_GROUPMAP")("LDAP_ATTRIBUTE_SID"=%s))",
3382
0
         dom_sid_str_buf(&sid, &buf));
3383
0
  if (filter == NULL) {
3384
0
    result = NT_STATUS_NO_MEMORY;
3385
0
    goto done;
3386
0
  }
3387
0
  rc = smbldap_search_suffix(priv->smbldap_state, filter,
3388
0
           get_attr_list(mem_ctx, groupmap_attr_list),
3389
0
           &msg);
3390
0
  smbldap_talloc_autofree_ldapmsg(mem_ctx, msg);
3391
3392
0
  if ((rc != LDAP_SUCCESS) ||
3393
0
      (ldap_count_entries(priv2ld(priv), msg) != 1) ||
3394
0
      ((entry = ldap_first_entry(priv2ld(priv), msg)) == NULL)) {
3395
0
    result = NT_STATUS_NO_SUCH_GROUP;
3396
0
    goto done;
3397
0
  }
3398
3399
0
  rc = ldapsam_delete_entry(priv, mem_ctx, entry, LDAP_OBJ_GROUPMAP,
3400
0
          get_attr_list(mem_ctx,
3401
0
            groupmap_attr_list_to_delete));
3402
3403
0
  if ((rc == LDAP_NAMING_VIOLATION) ||
3404
0
      (rc == LDAP_NOT_ALLOWED_ON_RDN) ||
3405
0
      (rc == LDAP_OBJECT_CLASS_VIOLATION)) {
3406
0
    const char *attrs[] = { "sambaGroupType", "description",
3407
0
          "displayName", "sambaSIDList",
3408
0
          NULL };
3409
3410
    /* Second try. Don't delete the sambaSID attribute, this is
3411
       for "old" entries that are tacked on a winbind
3412
       sambaIdmapEntry. */
3413
3414
0
    rc = ldapsam_delete_entry(priv, mem_ctx, entry,
3415
0
            LDAP_OBJ_GROUPMAP, attrs);
3416
0
  }
3417
3418
0
  if ((rc == LDAP_NAMING_VIOLATION) ||
3419
0
      (rc == LDAP_NOT_ALLOWED_ON_RDN) ||
3420
0
      (rc == LDAP_OBJECT_CLASS_VIOLATION)) {
3421
0
    const char *attrs[] = { "sambaGroupType", "description",
3422
0
          "displayName", "sambaSIDList",
3423
0
          "gidNumber", NULL };
3424
3425
    /* Third try. This is a post-3.0.21 alias (containing only
3426
     * sambaSidEntry and sambaGroupMapping classes), we also have
3427
     * to delete the gidNumber attribute, only the sambaSidEntry
3428
     * remains */
3429
3430
0
    rc = ldapsam_delete_entry(priv, mem_ctx, entry,
3431
0
            LDAP_OBJ_GROUPMAP, attrs);
3432
0
  }
3433
3434
0
  result = (rc == LDAP_SUCCESS) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
3435
3436
0
 done:
3437
0
  TALLOC_FREE(mem_ctx);
3438
0
  return result;
3439
0
 }
3440
3441
/**********************************************************************
3442
 *********************************************************************/
3443
3444
static NTSTATUS ldapsam_setsamgrent(struct pdb_methods *my_methods,
3445
            bool update)
3446
0
{
3447
0
  struct ldapsam_privates *ldap_state =
3448
0
    (struct ldapsam_privates *)my_methods->private_data;
3449
0
  const char *filter = NULL;
3450
0
  int rc;
3451
0
  const char **attr_list;
3452
3453
0
  filter = "(objectclass="LDAP_OBJ_GROUPMAP")";
3454
0
  attr_list = get_attr_list( NULL, groupmap_attr_list );
3455
0
  rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_suffix(),
3456
0
          LDAP_SCOPE_SUBTREE, filter,
3457
0
          attr_list, 0, &ldap_state->result);
3458
0
  TALLOC_FREE(attr_list);
3459
3460
0
  if (rc != LDAP_SUCCESS) {
3461
0
    DEBUG(0, ("ldapsam_setsamgrent: LDAP search failed: %s\n",
3462
0
        ldap_err2string(rc)));
3463
0
    DEBUG(3, ("ldapsam_setsamgrent: Query was: %s, %s\n",
3464
0
        lp_ldap_suffix(), filter));
3465
0
    ldap_msgfree(ldap_state->result);
3466
0
    ldap_state->result = NULL;
3467
0
    return NT_STATUS_UNSUCCESSFUL;
3468
0
  }
3469
3470
0
  DEBUG(2, ("ldapsam_setsamgrent: %d entries in the base!\n",
3471
0
      ldap_count_entries(
3472
0
        smbldap_get_ldap(ldap_state->smbldap_state),
3473
0
        ldap_state->result)));
3474
3475
0
  ldap_state->entry =
3476
0
    ldap_first_entry(smbldap_get_ldap(ldap_state->smbldap_state),
3477
0
         ldap_state->result);
3478
0
  ldap_state->index = 0;
3479
3480
0
  return NT_STATUS_OK;
3481
0
}
3482
3483
/**********************************************************************
3484
 *********************************************************************/
3485
3486
static void ldapsam_endsamgrent(struct pdb_methods *my_methods)
3487
0
{
3488
0
  ldapsam_endsampwent(my_methods);
3489
0
}
3490
3491
/**********************************************************************
3492
 *********************************************************************/
3493
3494
static NTSTATUS ldapsam_getsamgrent(struct pdb_methods *my_methods,
3495
            GROUP_MAP *map)
3496
0
{
3497
0
  NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
3498
0
  struct ldapsam_privates *ldap_state =
3499
0
    (struct ldapsam_privates *)my_methods->private_data;
3500
0
  bool bret = False;
3501
3502
0
  while (!bret) {
3503
0
    if (!ldap_state->entry)
3504
0
      return ret;
3505
3506
0
    ldap_state->index++;
3507
0
    bret = init_group_from_ldap(ldap_state, map,
3508
0
              ldap_state->entry);
3509
3510
0
    ldap_state->entry = ldap_next_entry(
3511
0
      smbldap_get_ldap(ldap_state->smbldap_state),
3512
0
      ldap_state->entry);
3513
0
  }
3514
3515
0
  return NT_STATUS_OK;
3516
0
}
3517
3518
/**********************************************************************
3519
 *********************************************************************/
3520
3521
static NTSTATUS ldapsam_enum_group_mapping(struct pdb_methods *methods,
3522
             const struct dom_sid *domsid, enum lsa_SidType sid_name_use,
3523
             GROUP_MAP ***pp_rmap,
3524
             size_t *p_num_entries,
3525
             bool unix_only)
3526
0
{
3527
0
  GROUP_MAP *map = NULL;
3528
0
  size_t entries = 0;
3529
3530
0
  *p_num_entries = 0;
3531
0
  *pp_rmap = NULL;
3532
3533
0
  if (!NT_STATUS_IS_OK(ldapsam_setsamgrent(methods, False))) {
3534
0
    DEBUG(0, ("ldapsam_enum_group_mapping: Unable to open "
3535
0
        "passdb\n"));
3536
0
    return NT_STATUS_ACCESS_DENIED;
3537
0
  }
3538
3539
0
  while (true) {
3540
3541
0
    map = talloc_zero(NULL, GROUP_MAP);
3542
0
    if (!map) {
3543
0
      return NT_STATUS_NO_MEMORY;
3544
0
    }
3545
3546
0
    if (!NT_STATUS_IS_OK(ldapsam_getsamgrent(methods, map))) {
3547
0
      TALLOC_FREE(map);
3548
0
      break;
3549
0
    }
3550
3551
0
    if (sid_name_use != SID_NAME_UNKNOWN &&
3552
0
        sid_name_use != map->sid_name_use) {
3553
0
      DEBUG(11,("ldapsam_enum_group_mapping: group %s is "
3554
0
          "not of the requested type\n",
3555
0
          map->nt_name));
3556
0
      continue;
3557
0
    }
3558
0
    if (unix_only == ENUM_ONLY_MAPPED && map->gid == -1) {
3559
0
      DEBUG(11,("ldapsam_enum_group_mapping: group %s is "
3560
0
          "non mapped\n", map->nt_name));
3561
0
      continue;
3562
0
    }
3563
3564
0
    *pp_rmap = talloc_realloc(NULL, *pp_rmap,
3565
0
            GROUP_MAP *, entries + 1);
3566
0
    if (!(*pp_rmap)) {
3567
0
      DEBUG(0,("ldapsam_enum_group_mapping: Unable to "
3568
0
         "enlarge group map!\n"));
3569
0
      return NT_STATUS_UNSUCCESSFUL;
3570
0
    }
3571
3572
0
    (*pp_rmap)[entries] = talloc_move((*pp_rmap), &map);
3573
3574
0
    entries += 1;
3575
0
  }
3576
3577
0
  ldapsam_endsamgrent(methods);
3578
3579
0
  *p_num_entries = entries;
3580
3581
0
  return NT_STATUS_OK;
3582
0
}
3583
3584
static NTSTATUS ldapsam_modify_aliasmem(struct pdb_methods *methods,
3585
          const struct dom_sid *alias,
3586
          const struct dom_sid *member,
3587
          int modop)
3588
0
{
3589
0
  struct ldapsam_privates *ldap_state =
3590
0
    (struct ldapsam_privates *)methods->private_data;
3591
0
  char *dn = NULL;
3592
0
  LDAPMessage *result = NULL;
3593
0
  LDAPMessage *entry = NULL;
3594
0
  int count;
3595
0
  LDAPMod **mods = NULL;
3596
0
  int rc;
3597
0
  enum lsa_SidType type = SID_NAME_USE_NONE;
3598
0
  struct dom_sid_buf tmp;
3599
3600
0
  char *filter = NULL;
3601
3602
0
  if (sid_check_is_in_builtin(alias)) {
3603
0
    type = SID_NAME_ALIAS;
3604
0
  }
3605
3606
0
  if (sid_check_is_in_our_sam(alias)) {
3607
0
    type = SID_NAME_ALIAS;
3608
0
  }
3609
3610
0
  if (type == SID_NAME_USE_NONE) {
3611
0
    struct dom_sid_buf buf;
3612
0
    DEBUG(5, ("SID %s is neither in builtin nor in our domain!\n",
3613
0
        dom_sid_str_buf(alias, &buf)));
3614
0
    return NT_STATUS_NO_SUCH_ALIAS;
3615
0
  }
3616
3617
0
  if (asprintf(&filter,
3618
0
         "(&(objectClass=%s)(sambaSid=%s)(sambaGroupType=%d))",
3619
0
         LDAP_OBJ_GROUPMAP,
3620
0
         dom_sid_str_buf(alias, &tmp),
3621
0
         type) < 0) {
3622
0
    return NT_STATUS_NO_MEMORY;
3623
0
  }
3624
3625
0
  if (ldapsam_search_one_group(ldap_state, filter,
3626
0
             &result) != LDAP_SUCCESS) {
3627
0
    SAFE_FREE(filter);
3628
0
    return NT_STATUS_NO_SUCH_ALIAS;
3629
0
  }
3630
3631
0
  count = ldap_count_entries(smbldap_get_ldap(ldap_state->smbldap_state),
3632
0
           result);
3633
3634
0
  if (count < 1) {
3635
0
    DEBUG(4, ("ldapsam_modify_aliasmem: Did not find alias\n"));
3636
0
    ldap_msgfree(result);
3637
0
    SAFE_FREE(filter);
3638
0
    return NT_STATUS_NO_SUCH_ALIAS;
3639
0
  }
3640
3641
0
  if (count > 1) {
3642
0
    DEBUG(1, ("ldapsam_modify_aliasmem: Duplicate entries for "
3643
0
        "filter %s: count=%d\n", filter, count));
3644
0
    ldap_msgfree(result);
3645
0
    SAFE_FREE(filter);
3646
0
    return NT_STATUS_NO_SUCH_ALIAS;
3647
0
  }
3648
3649
0
  SAFE_FREE(filter);
3650
3651
0
  entry = ldap_first_entry(smbldap_get_ldap(ldap_state->smbldap_state),
3652
0
         result);
3653
3654
0
  if (!entry) {
3655
0
    ldap_msgfree(result);
3656
0
    return NT_STATUS_UNSUCCESSFUL;
3657
0
  }
3658
3659
0
  dn = smbldap_talloc_dn(talloc_tos(),
3660
0
             smbldap_get_ldap(ldap_state->smbldap_state),
3661
0
             entry);
3662
0
  if (!dn) {
3663
0
    ldap_msgfree(result);
3664
0
    return NT_STATUS_UNSUCCESSFUL;
3665
0
  }
3666
3667
0
  smbldap_set_mod(&mods, modop,
3668
0
      get_attr_key2string(groupmap_attr_list,
3669
0
              LDAP_ATTR_SID_LIST),
3670
0
      dom_sid_str_buf(member, &tmp));
3671
3672
0
  rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
3673
3674
0
  ldap_mods_free(mods, True);
3675
0
  ldap_msgfree(result);
3676
0
  TALLOC_FREE(dn);
3677
3678
0
  if (rc == LDAP_TYPE_OR_VALUE_EXISTS) {
3679
0
    return NT_STATUS_MEMBER_IN_ALIAS;
3680
0
  }
3681
3682
0
  if (rc == LDAP_NO_SUCH_ATTRIBUTE) {
3683
0
    return NT_STATUS_MEMBER_NOT_IN_ALIAS;
3684
0
  }
3685
3686
0
  if (rc != LDAP_SUCCESS) {
3687
0
    return NT_STATUS_UNSUCCESSFUL;
3688
0
  }
3689
3690
0
  return NT_STATUS_OK;
3691
0
}
3692
3693
static NTSTATUS ldapsam_add_aliasmem(struct pdb_methods *methods,
3694
             const struct dom_sid *alias,
3695
             const struct dom_sid *member)
3696
0
{
3697
0
  return ldapsam_modify_aliasmem(methods, alias, member, LDAP_MOD_ADD);
3698
0
}
3699
3700
static NTSTATUS ldapsam_del_aliasmem(struct pdb_methods *methods,
3701
             const struct dom_sid *alias,
3702
             const struct dom_sid *member)
3703
0
{
3704
0
  return ldapsam_modify_aliasmem(methods, alias, member,
3705
0
               LDAP_MOD_DELETE);
3706
0
}
3707
3708
static NTSTATUS ldapsam_enum_aliasmem(struct pdb_methods *methods,
3709
              const struct dom_sid *alias,
3710
              TALLOC_CTX *mem_ctx,
3711
              struct dom_sid **pp_members,
3712
              size_t *p_num_members)
3713
0
{
3714
0
  struct ldapsam_privates *ldap_state =
3715
0
    (struct ldapsam_privates *)methods->private_data;
3716
0
  LDAPMessage *result = NULL;
3717
0
  LDAPMessage *entry = NULL;
3718
0
  int count;
3719
0
  char **values = NULL;
3720
0
  int i;
3721
0
  char *filter = NULL;
3722
0
  uint32_t num_members = 0;
3723
0
  enum lsa_SidType type = SID_NAME_USE_NONE;
3724
0
  struct dom_sid_buf tmp;
3725
3726
0
  *pp_members = NULL;
3727
0
  *p_num_members = 0;
3728
3729
0
  if (sid_check_is_in_builtin(alias)) {
3730
0
    type = SID_NAME_ALIAS;
3731
0
  }
3732
3733
0
  if (sid_check_is_in_our_sam(alias)) {
3734
0
    type = SID_NAME_ALIAS;
3735
0
  }
3736
3737
0
  if (type == SID_NAME_USE_NONE) {
3738
0
    DEBUG(5, ("SID %s is neither in builtin nor in our domain!\n",
3739
0
        dom_sid_str_buf(alias, &tmp)));
3740
0
    return NT_STATUS_NO_SUCH_ALIAS;
3741
0
  }
3742
3743
0
  if (asprintf(&filter,
3744
0
         "(&(objectClass=%s)(sambaSid=%s)(sambaGroupType=%d))",
3745
0
         LDAP_OBJ_GROUPMAP,
3746
0
         dom_sid_str_buf(alias, &tmp),
3747
0
         type) < 0) {
3748
0
    return NT_STATUS_NO_MEMORY;
3749
0
  }
3750
3751
0
  if (ldapsam_search_one_group(ldap_state, filter,
3752
0
             &result) != LDAP_SUCCESS) {
3753
0
    SAFE_FREE(filter);
3754
0
    return NT_STATUS_NO_SUCH_ALIAS;
3755
0
  }
3756
3757
0
  count = ldap_count_entries(smbldap_get_ldap(ldap_state->smbldap_state),
3758
0
           result);
3759
3760
0
  if (count < 1) {
3761
0
    DEBUG(4, ("ldapsam_enum_aliasmem: Did not find alias\n"));
3762
0
    ldap_msgfree(result);
3763
0
    SAFE_FREE(filter);
3764
0
    return NT_STATUS_NO_SUCH_ALIAS;
3765
0
  }
3766
3767
0
  if (count > 1) {
3768
0
    DEBUG(1, ("ldapsam_enum_aliasmem: Duplicate entries for "
3769
0
        "filter %s: count=%d\n", filter, count));
3770
0
    ldap_msgfree(result);
3771
0
    SAFE_FREE(filter);
3772
0
    return NT_STATUS_NO_SUCH_ALIAS;
3773
0
  }
3774
3775
0
  SAFE_FREE(filter);
3776
3777
0
  entry = ldap_first_entry(smbldap_get_ldap(ldap_state->smbldap_state),
3778
0
         result);
3779
3780
0
  if (!entry) {
3781
0
    ldap_msgfree(result);
3782
0
    return NT_STATUS_UNSUCCESSFUL;
3783
0
  }
3784
3785
0
  values = ldap_get_values(smbldap_get_ldap(ldap_state->smbldap_state),
3786
0
         entry,
3787
0
         get_attr_key2string(groupmap_attr_list,
3788
0
                 LDAP_ATTR_SID_LIST));
3789
3790
0
  if (values == NULL) {
3791
0
    ldap_msgfree(result);
3792
0
    return NT_STATUS_OK;
3793
0
  }
3794
3795
0
  count = ldap_count_values(values);
3796
3797
0
  for (i=0; i<count; i++) {
3798
0
    struct dom_sid member;
3799
0
    NTSTATUS status;
3800
3801
0
    if (!string_to_sid(&member, values[i]))
3802
0
      continue;
3803
3804
0
    status = add_sid_to_array(mem_ctx, &member, pp_members,
3805
0
            &num_members);
3806
0
    if (!NT_STATUS_IS_OK(status)) {
3807
0
      ldap_value_free(values);
3808
0
      ldap_msgfree(result);
3809
0
      return status;
3810
0
    }
3811
0
  }
3812
3813
0
  *p_num_members = num_members;
3814
0
  ldap_value_free(values);
3815
0
  ldap_msgfree(result);
3816
3817
0
  return NT_STATUS_OK;
3818
0
}
3819
3820
static NTSTATUS ldapsam_alias_memberships(struct pdb_methods *methods,
3821
            TALLOC_CTX *mem_ctx,
3822
            const struct dom_sid *domain_sid,
3823
            const struct dom_sid *members,
3824
            size_t num_members,
3825
            uint32_t **pp_alias_rids,
3826
            size_t *p_num_alias_rids)
3827
0
{
3828
0
  struct ldapsam_privates *ldap_state =
3829
0
    (struct ldapsam_privates *)methods->private_data;
3830
0
  LDAP *ldap_struct;
3831
3832
0
  const char *attrs[] = { LDAP_ATTRIBUTE_SID, NULL };
3833
3834
0
  LDAPMessage *result = NULL;
3835
0
  LDAPMessage *entry = NULL;
3836
0
  int i;
3837
0
  int rc;
3838
0
  char *filter;
3839
0
  enum lsa_SidType type = SID_NAME_USE_NONE;
3840
0
  bool is_builtin = false;
3841
0
  bool sid_added = false;
3842
3843
0
  *pp_alias_rids = NULL;
3844
0
  *p_num_alias_rids = 0;
3845
3846
0
  if (sid_check_is_builtin(domain_sid)) {
3847
0
    is_builtin = true;
3848
0
    type = SID_NAME_ALIAS;
3849
0
  }
3850
3851
0
  if (sid_check_is_our_sam(domain_sid)) {
3852
0
    type = SID_NAME_ALIAS;
3853
0
  }
3854
3855
0
  if (type == SID_NAME_USE_NONE) {
3856
0
    struct dom_sid_buf buf;
3857
0
    DEBUG(5, ("SID %s is neither builtin nor domain!\n",
3858
0
        dom_sid_str_buf(domain_sid, &buf)));
3859
0
    return NT_STATUS_UNSUCCESSFUL;
3860
0
  }
3861
3862
0
  if (num_members == 0) {
3863
0
    return NT_STATUS_OK;
3864
0
  }
3865
3866
0
  filter = talloc_asprintf(mem_ctx,
3867
0
         "(&(objectclass="LDAP_OBJ_GROUPMAP")(sambaGroupType=%d)(|",
3868
0
         type);
3869
3870
0
  for (i=0; i<num_members; i++) {
3871
0
    struct dom_sid_buf buf;
3872
0
    filter = talloc_asprintf(mem_ctx, "%s(sambaSIDList=%s)",
3873
0
           filter,
3874
0
           dom_sid_str_buf(&members[i], &buf));
3875
0
  }
3876
3877
0
  filter = talloc_asprintf(mem_ctx, "%s))", filter);
3878
3879
0
  if (filter == NULL) {
3880
0
    return NT_STATUS_NO_MEMORY;
3881
0
  }
3882
3883
0
  if (is_builtin &&
3884
0
      ldap_state->search_cache.filter &&
3885
0
      strcmp(ldap_state->search_cache.filter, filter) == 0) {
3886
0
    filter = talloc_move(filter, &ldap_state->search_cache.filter);
3887
0
    result = ldap_state->search_cache.result;
3888
0
    ldap_state->search_cache.result = NULL;
3889
0
  } else {
3890
0
    rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_suffix(),
3891
0
            LDAP_SCOPE_SUBTREE, filter, attrs, 0, &result);
3892
0
    if (rc != LDAP_SUCCESS) {
3893
0
      return NT_STATUS_UNSUCCESSFUL;
3894
0
    }
3895
0
    smbldap_talloc_autofree_ldapmsg(filter, result);
3896
0
  }
3897
3898
0
  ldap_struct = smbldap_get_ldap(ldap_state->smbldap_state);
3899
3900
0
  for (entry = ldap_first_entry(ldap_struct, result);
3901
0
       entry != NULL;
3902
0
       entry = ldap_next_entry(ldap_struct, entry))
3903
0
  {
3904
0
    fstring sid_str;
3905
0
    struct dom_sid sid;
3906
0
    uint32_t rid;
3907
3908
0
    if (!smbldap_get_single_attribute(ldap_struct, entry,
3909
0
              LDAP_ATTRIBUTE_SID,
3910
0
              sid_str,
3911
0
              sizeof(sid_str)-1))
3912
0
      continue;
3913
3914
0
    if (!string_to_sid(&sid, sid_str))
3915
0
      continue;
3916
3917
0
    if (!sid_peek_check_rid(domain_sid, &sid, &rid))
3918
0
      continue;
3919
3920
0
    sid_added = true;
3921
3922
0
    if (!add_rid_to_array_unique(mem_ctx, rid, pp_alias_rids,
3923
0
          p_num_alias_rids)) {
3924
0
      return NT_STATUS_NO_MEMORY;
3925
0
    }
3926
0
  }
3927
3928
0
  if (!is_builtin && !sid_added) {
3929
0
    TALLOC_FREE(ldap_state->search_cache.filter);
3930
    /*
3931
     * Note: result is a talloc child of filter because of the
3932
     * smbldap_talloc_autofree_ldapmsg() usage
3933
     */
3934
0
    ldap_state->search_cache.filter = talloc_move(ldap_state, &filter);
3935
0
    ldap_state->search_cache.result = result;
3936
0
  }
3937
3938
0
  return NT_STATUS_OK;
3939
0
}
3940
3941
static NTSTATUS ldapsam_set_account_policy_in_ldap(struct pdb_methods *methods,
3942
               enum pdb_policy_type type,
3943
               uint32_t value)
3944
0
{
3945
0
  NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL;
3946
0
  int rc;
3947
0
  LDAPMod **mods = NULL;
3948
0
  fstring value_string;
3949
0
  const char *policy_attr = NULL;
3950
3951
0
  struct ldapsam_privates *ldap_state =
3952
0
    (struct ldapsam_privates *)methods->private_data;
3953
3954
0
  DEBUG(10,("ldapsam_set_account_policy_in_ldap\n"));
3955
3956
0
  if (!ldap_state->domain_dn) {
3957
0
    return NT_STATUS_INVALID_PARAMETER;
3958
0
  }
3959
3960
0
  policy_attr = get_account_policy_attr(type);
3961
0
  if (policy_attr == NULL) {
3962
0
    DEBUG(0,("ldapsam_set_account_policy_in_ldap: invalid "
3963
0
       "policy\n"));
3964
0
    return ntstatus;
3965
0
  }
3966
3967
0
  slprintf(value_string, sizeof(value_string) - 1, "%i", value);
3968
3969
0
  smbldap_set_mod(&mods, LDAP_MOD_REPLACE, policy_attr, value_string);
3970
3971
0
  rc = smbldap_modify(ldap_state->smbldap_state, ldap_state->domain_dn,
3972
0
          mods);
3973
3974
0
  ldap_mods_free(mods, True);
3975
3976
0
  if (rc != LDAP_SUCCESS) {
3977
0
    return ntstatus;
3978
0
  }
3979
3980
0
  if (!cache_account_policy_set(type, value)) {
3981
0
    DEBUG(0,("ldapsam_set_account_policy_in_ldap: failed to "
3982
0
       "update local tdb cache\n"));
3983
0
    return ntstatus;
3984
0
  }
3985
3986
0
  return NT_STATUS_OK;
3987
0
}
3988
3989
static NTSTATUS ldapsam_set_account_policy(struct pdb_methods *methods,
3990
             enum pdb_policy_type type,
3991
             uint32_t value)
3992
0
{
3993
0
  return ldapsam_set_account_policy_in_ldap(methods, type,
3994
0
              value);
3995
0
}
3996
3997
static NTSTATUS ldapsam_get_account_policy_from_ldap(struct pdb_methods *methods,
3998
                 enum pdb_policy_type type,
3999
                 uint32_t *value)
4000
0
{
4001
0
  NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL;
4002
0
  LDAPMessage *result = NULL;
4003
0
  LDAPMessage *entry = NULL;
4004
0
  int count;
4005
0
  int rc;
4006
0
  char **vals = NULL;
4007
0
  const char *filter;
4008
0
  const char *policy_attr = NULL;
4009
4010
0
  struct ldapsam_privates *ldap_state =
4011
0
    (struct ldapsam_privates *)methods->private_data;
4012
4013
0
  const char *attrs[2];
4014
4015
0
  DEBUG(10,("ldapsam_get_account_policy_from_ldap\n"));
4016
4017
0
  if (!ldap_state->domain_dn) {
4018
0
    return NT_STATUS_INVALID_PARAMETER;
4019
0
  }
4020
4021
0
  policy_attr = get_account_policy_attr(type);
4022
0
  if (!policy_attr) {
4023
0
    DEBUG(0,("ldapsam_get_account_policy_from_ldap: invalid "
4024
0
       "policy index: %d\n", type));
4025
0
    return ntstatus;
4026
0
  }
4027
4028
0
  attrs[0] = policy_attr;
4029
0
  attrs[1] = NULL;
4030
4031
0
  filter = "(objectClass="LDAP_OBJ_DOMINFO")";
4032
0
  rc = smbldap_search(ldap_state->smbldap_state, ldap_state->domain_dn,
4033
0
          LDAP_SCOPE_BASE, filter, attrs, 0,
4034
0
          &result);
4035
0
  if (rc != LDAP_SUCCESS) {
4036
0
    return ntstatus;
4037
0
  }
4038
4039
0
  count = ldap_count_entries(priv2ld(ldap_state), result);
4040
0
  if (count < 1) {
4041
0
    goto out;
4042
0
  }
4043
4044
0
  entry = ldap_first_entry(priv2ld(ldap_state), result);
4045
0
  if (entry == NULL) {
4046
0
    goto out;
4047
0
  }
4048
4049
0
  vals = ldap_get_values(priv2ld(ldap_state), entry, policy_attr);
4050
0
  if (vals == NULL) {
4051
0
    goto out;
4052
0
  }
4053
4054
0
  *value = (uint32_t)atol(vals[0]);
4055
4056
0
  ntstatus = NT_STATUS_OK;
4057
4058
0
out:
4059
0
  if (vals)
4060
0
    ldap_value_free(vals);
4061
0
  ldap_msgfree(result);
4062
4063
0
  return ntstatus;
4064
0
}
4065
4066
/* wrapper around ldapsam_get_account_policy_from_ldap(), handles tdb as cache
4067
4068
   - if user hasn't decided to use account policies inside LDAP just reuse the
4069
     old tdb values
4070
4071
   - if there is a valid cache entry, return that
4072
   - if there is an LDAP entry, update cache and return
4073
   - otherwise set to default, update cache and return
4074
4075
   Guenther
4076
*/
4077
static NTSTATUS ldapsam_get_account_policy(struct pdb_methods *methods,
4078
             enum pdb_policy_type type,
4079
             uint32_t *value)
4080
0
{
4081
0
  NTSTATUS ntstatus;
4082
4083
0
  if (cache_account_policy_get(type, value)) {
4084
0
    DEBUG(11,("ldapsam_get_account_policy: got valid value from "
4085
0
        "cache\n"));
4086
0
    return NT_STATUS_OK;
4087
0
  }
4088
4089
0
  ntstatus = ldapsam_get_account_policy_from_ldap(methods, type,
4090
0
              value);
4091
0
  if (NT_STATUS_IS_OK(ntstatus)) {
4092
0
    goto update_cache;
4093
0
  }
4094
4095
0
  DEBUG(10,("ldapsam_get_account_policy: failed to retrieve from "
4096
0
      "ldap\n"));
4097
4098
#if 0
4099
  /* should we automagically migrate old tdb value here ? */
4100
  if (account_policy_get(type, value))
4101
    goto update_ldap;
4102
4103
  DEBUG(10,("ldapsam_get_account_policy: no tdb for %d, trying "
4104
      "default\n", type));
4105
#endif
4106
4107
0
  if (!account_policy_get_default(type, value)) {
4108
0
    return ntstatus;
4109
0
  }
4110
4111
/* update_ldap: */
4112
4113
0
  ntstatus = ldapsam_set_account_policy(methods, type, *value);
4114
0
  if (!NT_STATUS_IS_OK(ntstatus)) {
4115
0
    return ntstatus;
4116
0
  }
4117
4118
0
 update_cache:
4119
4120
0
  if (!cache_account_policy_set(type, *value)) {
4121
0
    DEBUG(0,("ldapsam_get_account_policy: failed to update local "
4122
0
       "tdb as a cache\n"));
4123
0
    return NT_STATUS_UNSUCCESSFUL;
4124
0
  }
4125
4126
0
  return NT_STATUS_OK;
4127
0
}
4128
4129
static NTSTATUS ldapsam_lookup_rids(struct pdb_methods *methods,
4130
            const struct dom_sid *domain_sid,
4131
            int num_rids,
4132
            uint32_t *rids,
4133
            const char **names,
4134
            enum lsa_SidType *attrs)
4135
0
{
4136
0
  struct ldapsam_privates *ldap_state =
4137
0
    (struct ldapsam_privates *)methods->private_data;
4138
0
  LDAPMessage *msg = NULL;
4139
0
  LDAPMessage *entry;
4140
0
  char *allsids = NULL;
4141
0
  size_t i, num_mapped;
4142
0
  int rc;
4143
0
  NTSTATUS result = NT_STATUS_NO_MEMORY;
4144
0
  TALLOC_CTX *mem_ctx;
4145
0
  LDAP *ld;
4146
0
  bool is_builtin;
4147
4148
0
  mem_ctx = talloc_new(NULL);
4149
0
  if (mem_ctx == NULL) {
4150
0
    DEBUG(0, ("talloc_new failed\n"));
4151
0
    goto done;
4152
0
  }
4153
4154
0
  if (!sid_check_is_builtin(domain_sid) &&
4155
0
      !sid_check_is_our_sam(domain_sid)) {
4156
0
    result = NT_STATUS_INVALID_PARAMETER;
4157
0
    goto done;
4158
0
  }
4159
4160
0
  if (num_rids == 0) {
4161
0
    result = NT_STATUS_NONE_MAPPED;
4162
0
    goto done;
4163
0
  }
4164
4165
0
  for (i=0; i<num_rids; i++)
4166
0
    attrs[i] = SID_NAME_UNKNOWN;
4167
4168
0
  allsids = talloc_strdup(mem_ctx, "");
4169
0
  if (allsids == NULL) {
4170
0
    goto done;
4171
0
  }
4172
4173
0
  for (i=0; i<num_rids; i++) {
4174
0
    struct dom_sid sid;
4175
0
    struct dom_sid_buf buf;
4176
0
    sid_compose(&sid, domain_sid, rids[i]);
4177
0
    allsids = talloc_asprintf_append_buffer(
4178
0
      allsids,
4179
0
      "(sambaSid=%s)",
4180
0
      dom_sid_str_buf(&sid, &buf));
4181
0
    if (allsids == NULL) {
4182
0
      goto done;
4183
0
    }
4184
0
  }
4185
4186
  /* First look for users */
4187
4188
0
  {
4189
0
    char *filter;
4190
0
    const char *ldap_attrs[] = { "uid", "sambaSid", NULL };
4191
4192
0
    filter = talloc_asprintf(
4193
0
      mem_ctx, ("(&(objectClass="LDAP_OBJ_SAMBASAMACCOUNT")(|%s))"),
4194
0
      allsids);
4195
4196
0
    if (filter == NULL) {
4197
0
      goto done;
4198
0
    }
4199
4200
0
    rc = smbldap_search(ldap_state->smbldap_state,
4201
0
            lp_ldap_user_suffix(talloc_tos()),
4202
0
            LDAP_SCOPE_SUBTREE, filter, ldap_attrs, 0,
4203
0
            &msg);
4204
0
    smbldap_talloc_autofree_ldapmsg(mem_ctx, msg);
4205
0
  }
4206
4207
0
  if (rc != LDAP_SUCCESS)
4208
0
    goto done;
4209
4210
0
  ld = smbldap_get_ldap(ldap_state->smbldap_state);
4211
0
  num_mapped = 0;
4212
4213
0
  for (entry = ldap_first_entry(ld, msg);
4214
0
       entry != NULL;
4215
0
       entry = ldap_next_entry(ld, entry)) {
4216
0
    uint32_t rid;
4217
0
    int rid_index;
4218
0
    const char *name;
4219
4220
0
    if (!ldapsam_extract_rid_from_entry(ld, entry, domain_sid,
4221
0
                &rid)) {
4222
0
      DEBUG(2, ("Could not find sid from ldap entry\n"));
4223
0
      continue;
4224
0
    }
4225
4226
0
    name = smbldap_talloc_single_attribute(ld, entry, "uid",
4227
0
                   names);
4228
0
    if (name == NULL) {
4229
0
      DEBUG(2, ("Could not retrieve uid attribute\n"));
4230
0
      continue;
4231
0
    }
4232
4233
0
    for (rid_index = 0; rid_index < num_rids; rid_index++) {
4234
0
      if (rid == rids[rid_index])
4235
0
        break;
4236
0
    }
4237
4238
0
    if (rid_index == num_rids) {
4239
0
      DEBUG(2, ("Got a RID not asked for: %d\n", rid));
4240
0
      continue;
4241
0
    }
4242
4243
0
    attrs[rid_index] = SID_NAME_USER;
4244
0
    names[rid_index] = name;
4245
0
    num_mapped += 1;
4246
0
  }
4247
4248
0
  if (num_mapped == num_rids) {
4249
    /* No need to look for groups anymore -- we're done */
4250
0
    result = NT_STATUS_OK;
4251
0
    goto done;
4252
0
  }
4253
4254
  /* Same game for groups */
4255
4256
0
  {
4257
0
    char *filter;
4258
0
    const char *ldap_attrs[] = { "cn", "displayName", "sambaSid",
4259
0
               "sambaGroupType", NULL };
4260
4261
0
    filter = talloc_asprintf(
4262
0
      mem_ctx, "(&(objectClass="LDAP_OBJ_GROUPMAP")(|%s))",
4263
0
      allsids);
4264
0
    if (filter == NULL) {
4265
0
      goto done;
4266
0
    }
4267
4268
0
    rc = smbldap_search(ldap_state->smbldap_state,
4269
0
            lp_ldap_suffix(),
4270
0
            LDAP_SCOPE_SUBTREE, filter, ldap_attrs, 0,
4271
0
            &msg);
4272
0
    smbldap_talloc_autofree_ldapmsg(mem_ctx, msg);
4273
0
  }
4274
4275
0
  if (rc != LDAP_SUCCESS)
4276
0
    goto done;
4277
4278
  /* ldap_struct might have changed due to a reconnect */
4279
4280
0
  ld = smbldap_get_ldap(ldap_state->smbldap_state);
4281
4282
  /* For consistency checks, we already checked we're only domain or builtin */
4283
4284
0
  is_builtin = sid_check_is_builtin(domain_sid);
4285
4286
0
  for (entry = ldap_first_entry(ld, msg);
4287
0
       entry != NULL;
4288
0
       entry = ldap_next_entry(ld, entry))
4289
0
  {
4290
0
    uint32_t rid;
4291
0
    int rid_index;
4292
0
    const char *attr;
4293
0
    enum lsa_SidType type;
4294
0
    const char *dn = smbldap_talloc_dn(mem_ctx, ld, entry);
4295
4296
0
    attr = smbldap_talloc_single_attribute(ld, entry, "sambaGroupType",
4297
0
                   mem_ctx);
4298
0
    if (attr == NULL) {
4299
0
      DEBUG(2, ("Could not extract type from ldap entry %s\n",
4300
0
          dn));
4301
0
      continue;
4302
0
    }
4303
4304
0
    type = (enum lsa_SidType)atol(attr);
4305
4306
    /* Consistency checks */
4307
0
    if ((is_builtin && (type != SID_NAME_ALIAS)) ||
4308
0
        (!is_builtin && ((type != SID_NAME_ALIAS) &&
4309
0
             (type != SID_NAME_DOM_GRP)))) {
4310
0
      DEBUG(2, ("Rejecting invalid group mapping entry %s\n", dn));
4311
0
    }
4312
4313
0
    if (!ldapsam_extract_rid_from_entry(ld, entry, domain_sid,
4314
0
                &rid)) {
4315
0
      DEBUG(2, ("Could not find sid from ldap entry %s\n", dn));
4316
0
      continue;
4317
0
    }
4318
4319
0
    attr = smbldap_talloc_single_attribute(ld, entry, "displayName", names);
4320
4321
0
    if (attr == NULL) {
4322
0
      DEBUG(10, ("Could not retrieve 'displayName' attribute from %s\n",
4323
0
           dn));
4324
0
      attr = smbldap_talloc_single_attribute(ld, entry, "cn", names);
4325
0
    }
4326
4327
0
    if (attr == NULL) {
4328
0
      DEBUG(2, ("Could not retrieve naming attribute from %s\n",
4329
0
          dn));
4330
0
      continue;
4331
0
    }
4332
4333
0
    for (rid_index = 0; rid_index < num_rids; rid_index++) {
4334
0
      if (rid == rids[rid_index])
4335
0
        break;
4336
0
    }
4337
4338
0
    if (rid_index == num_rids) {
4339
0
      DEBUG(2, ("Got a RID not asked for: %d\n", rid));
4340
0
      continue;
4341
0
    }
4342
4343
0
    attrs[rid_index] = type;
4344
0
    names[rid_index] = attr;
4345
0
    num_mapped += 1;
4346
0
  }
4347
4348
0
  result = NT_STATUS_NONE_MAPPED;
4349
4350
0
  if (num_mapped > 0)
4351
0
    result = (num_mapped == num_rids) ?
4352
0
      NT_STATUS_OK : STATUS_SOME_UNMAPPED;
4353
0
 done:
4354
0
  TALLOC_FREE(mem_ctx);
4355
0
  return result;
4356
0
}
4357
4358
static char *get_ldap_filter(TALLOC_CTX *mem_ctx, const char *username)
4359
0
{
4360
0
  char *filter = NULL;
4361
0
  char *escaped = NULL;
4362
0
  char *result = NULL;
4363
4364
0
  if (asprintf(&filter, "(&%s(objectclass=%s))",
4365
0
        "(uid=%u)", LDAP_OBJ_SAMBASAMACCOUNT) < 0) {
4366
0
    goto done;
4367
0
  }
4368
4369
0
  escaped = escape_ldap_string(talloc_tos(), username);
4370
0
  if (escaped == NULL) goto done;
4371
4372
0
  result = talloc_string_sub(mem_ctx, filter, "%u", username);
4373
4374
0
 done:
4375
0
  SAFE_FREE(filter);
4376
0
  TALLOC_FREE(escaped);
4377
4378
0
  return result;
4379
0
}
4380
4381
static const char **talloc_attrs(TALLOC_CTX *mem_ctx, ...)
4382
0
{
4383
0
  int i, num = 0;
4384
0
  va_list ap;
4385
0
  const char **result;
4386
4387
0
  va_start(ap, mem_ctx);
4388
0
  while (va_arg(ap, const char *) != NULL)
4389
0
    num += 1;
4390
0
  va_end(ap);
4391
4392
0
  if ((result = talloc_array(mem_ctx, const char *, num+1)) == NULL) {
4393
0
    return NULL;
4394
0
  }
4395
4396
0
  va_start(ap, mem_ctx);
4397
0
  for (i=0; i<num; i++) {
4398
0
    result[i] = talloc_strdup(result, va_arg(ap, const char*));
4399
0
    if (result[i] == NULL) {
4400
0
      talloc_free(result);
4401
0
      va_end(ap);
4402
0
      return NULL;
4403
0
    }
4404
0
  }
4405
0
  va_end(ap);
4406
4407
0
  result[num] = NULL;
4408
0
  return result;
4409
0
}
4410
4411
struct ldap_search_state {
4412
  struct smbldap_state *connection;
4413
4414
  uint32_t acct_flags;
4415
  uint16_t group_type;
4416
4417
  const char *base;
4418
  int scope;
4419
  const char *filter;
4420
  const char **attrs;
4421
  int attrsonly;
4422
  void *pagedresults_cookie;
4423
4424
  LDAPMessage *entries, *current_entry;
4425
  bool (*ldap2displayentry)(struct ldap_search_state *state,
4426
          TALLOC_CTX *mem_ctx,
4427
          LDAP *ld, LDAPMessage *entry,
4428
          struct samr_displayentry *result);
4429
};
4430
4431
static bool ldapsam_search_firstpage(struct pdb_search *search)
4432
0
{
4433
0
  struct ldap_search_state *state =
4434
0
    (struct ldap_search_state *)search->private_data;
4435
0
  LDAP *ld;
4436
0
  int rc = LDAP_OPERATIONS_ERROR;
4437
4438
0
  state->entries = NULL;
4439
4440
0
  if (smbldap_get_paged_results(state->connection)) {
4441
0
    rc = smbldap_search_paged(state->connection, state->base,
4442
0
            state->scope, state->filter,
4443
0
            state->attrs, state->attrsonly,
4444
0
            lp_ldap_page_size(), &state->entries,
4445
0
            &state->pagedresults_cookie);
4446
0
  }
4447
4448
0
  if ((rc != LDAP_SUCCESS) || (state->entries == NULL)) {
4449
4450
0
    if (state->entries != NULL) {
4451
      /* Left over from unsuccessful paged attempt */
4452
0
      ldap_msgfree(state->entries);
4453
0
      state->entries = NULL;
4454
0
    }
4455
4456
0
    rc = smbldap_search(state->connection, state->base,
4457
0
            state->scope, state->filter, state->attrs,
4458
0
            state->attrsonly, &state->entries);
4459
4460
0
    if ((rc != LDAP_SUCCESS) || (state->entries == NULL))
4461
0
      return False;
4462
4463
    /* Ok, the server was lying. It told us it could do paged
4464
     * searches when it could not. */
4465
0
    smbldap_set_paged_results(state->connection, false);
4466
0
  }
4467
4468
0
        ld = smbldap_get_ldap(state->connection);
4469
0
        if ( ld == NULL) {
4470
0
                DEBUG(5, ("Don't have an LDAP connection right after a "
4471
0
        "search\n"));
4472
0
                return False;
4473
0
        }
4474
0
        state->current_entry = ldap_first_entry(ld, state->entries);
4475
4476
0
  return True;
4477
0
}
4478
4479
static bool ldapsam_search_nextpage(struct pdb_search *search)
4480
0
{
4481
0
  struct ldap_search_state *state =
4482
0
    (struct ldap_search_state *)search->private_data;
4483
0
  int rc;
4484
4485
0
  if (!smbldap_get_paged_results(state->connection)) {
4486
    /* There is no next page when there are no paged results */
4487
0
    return False;
4488
0
  }
4489
4490
0
  rc = smbldap_search_paged(state->connection, state->base,
4491
0
          state->scope, state->filter, state->attrs,
4492
0
          state->attrsonly, lp_ldap_page_size(),
4493
0
          &state->entries,
4494
0
          &state->pagedresults_cookie);
4495
4496
0
  if ((rc != LDAP_SUCCESS) || (state->entries == NULL))
4497
0
    return False;
4498
4499
0
  state->current_entry = ldap_first_entry(
4500
0
    smbldap_get_ldap(state->connection), state->entries);
4501
4502
0
  if (state->current_entry == NULL) {
4503
0
    ldap_msgfree(state->entries);
4504
0
    state->entries = NULL;
4505
0
    return false;
4506
0
  }
4507
4508
0
  return True;
4509
0
}
4510
4511
static bool ldapsam_search_next_entry(struct pdb_search *search,
4512
              struct samr_displayentry *entry)
4513
0
{
4514
0
  struct ldap_search_state *state =
4515
0
    (struct ldap_search_state *)search->private_data;
4516
0
  bool result;
4517
4518
0
 retry:
4519
0
  if ((state->entries == NULL) && (state->pagedresults_cookie == NULL))
4520
0
    return False;
4521
4522
0
  if ((state->entries == NULL) &&
4523
0
      !ldapsam_search_nextpage(search))
4524
0
        return False;
4525
4526
0
  if (state->current_entry == NULL) {
4527
0
    return false;
4528
0
  }
4529
4530
0
  result = state->ldap2displayentry(state, search,
4531
0
            smbldap_get_ldap(state->connection),
4532
0
            state->current_entry, entry);
4533
4534
0
  if (!result) {
4535
0
    char *dn;
4536
0
    dn = ldap_get_dn(smbldap_get_ldap(state->connection),
4537
0
         state->current_entry);
4538
0
    DEBUG(5, ("Skipping entry %s\n", dn != NULL ? dn : "<NULL>"));
4539
0
    if (dn != NULL) ldap_memfree(dn);
4540
0
  }
4541
4542
0
  state->current_entry = ldap_next_entry(
4543
0
    smbldap_get_ldap(state->connection), state->current_entry);
4544
4545
0
  if (state->current_entry == NULL) {
4546
0
    ldap_msgfree(state->entries);
4547
0
    state->entries = NULL;
4548
0
  }
4549
4550
0
  if (!result) goto retry;
4551
4552
0
  return True;
4553
0
}
4554
4555
static void ldapsam_search_end(struct pdb_search *search)
4556
0
{
4557
0
  struct ldap_search_state *state =
4558
0
    (struct ldap_search_state *)search->private_data;
4559
0
  int rc;
4560
4561
0
  if (state->pagedresults_cookie == NULL)
4562
0
    return;
4563
4564
0
  if (state->entries != NULL)
4565
0
    ldap_msgfree(state->entries);
4566
4567
0
  state->entries = NULL;
4568
0
  state->current_entry = NULL;
4569
4570
0
  if (!smbldap_get_paged_results(state->connection)) {
4571
0
    return;
4572
0
  }
4573
4574
  /* Tell the LDAP server we're not interested in the rest anymore. */
4575
4576
0
  rc = smbldap_search_paged(state->connection, state->base, state->scope,
4577
0
          state->filter, state->attrs,
4578
0
          state->attrsonly, 0, &state->entries,
4579
0
          &state->pagedresults_cookie);
4580
4581
0
  if (rc != LDAP_SUCCESS)
4582
0
    DEBUG(5, ("Could not end search properly\n"));
4583
4584
0
  return;
4585
0
}
4586
4587
static bool ldapuser2displayentry(struct ldap_search_state *state,
4588
          TALLOC_CTX *mem_ctx,
4589
          LDAP *ld, LDAPMessage *entry,
4590
          struct samr_displayentry *result)
4591
0
{
4592
0
  char **vals;
4593
0
  size_t converted_size;
4594
0
  struct dom_sid sid;
4595
0
  uint32_t acct_flags;
4596
4597
0
  vals = ldap_get_values(ld, entry, "sambaAcctFlags");
4598
0
  if ((vals == NULL) || (vals[0] == NULL)) {
4599
0
    acct_flags = ACB_NORMAL;
4600
0
  } else {
4601
0
    acct_flags = pdb_decode_acct_ctrl(vals[0]);
4602
0
    ldap_value_free(vals);
4603
0
  }
4604
4605
0
  if ((state->acct_flags != 0) &&
4606
0
      ((state->acct_flags & acct_flags) == 0))
4607
0
    return False;
4608
4609
0
  result->acct_flags = acct_flags;
4610
0
  result->account_name = "";
4611
0
  result->fullname = "";
4612
0
  result->description = "";
4613
4614
0
  vals = ldap_get_values(ld, entry, "uid");
4615
0
  if ((vals == NULL) || (vals[0] == NULL)) {
4616
0
    DEBUG(5, ("\"uid\" not found\n"));
4617
0
    return False;
4618
0
  }
4619
0
  if (!pull_utf8_talloc(mem_ctx,
4620
0
            discard_const_p(char *, &result->account_name),
4621
0
            vals[0], &converted_size))
4622
0
  {
4623
0
    DEBUG(0,("ldapuser2displayentry: pull_utf8_talloc failed: %s\n",
4624
0
       strerror(errno)));
4625
0
  }
4626
4627
0
  ldap_value_free(vals);
4628
4629
0
  vals = ldap_get_values(ld, entry, "displayName");
4630
0
  if ((vals == NULL) || (vals[0] == NULL))
4631
0
    DEBUG(8, ("\"displayName\" not found\n"));
4632
0
  else if (!pull_utf8_talloc(mem_ctx,
4633
0
           discard_const_p(char *, &result->fullname),
4634
0
           vals[0], &converted_size))
4635
0
  {
4636
0
    DEBUG(0,("ldapuser2displayentry: pull_utf8_talloc failed: %s\n",
4637
0
       strerror(errno)));
4638
0
  }
4639
4640
0
  ldap_value_free(vals);
4641
4642
0
  vals = ldap_get_values(ld, entry, "description");
4643
0
  if ((vals == NULL) || (vals[0] == NULL))
4644
0
    DEBUG(8, ("\"description\" not found\n"));
4645
0
  else if (!pull_utf8_talloc(mem_ctx,
4646
0
           discard_const_p(char *, &result->description),
4647
0
           vals[0], &converted_size))
4648
0
  {
4649
0
    DEBUG(0,("ldapuser2displayentry: pull_utf8_talloc failed: %s\n",
4650
0
       strerror(errno)));
4651
0
  }
4652
4653
0
  ldap_value_free(vals);
4654
4655
0
  if ((result->account_name == NULL) ||
4656
0
      (result->fullname == NULL) ||
4657
0
      (result->description == NULL)) {
4658
0
    DEBUG(0, ("talloc failed\n"));
4659
0
    return False;
4660
0
  }
4661
4662
0
  vals = ldap_get_values(ld, entry, "sambaSid");
4663
0
  if ((vals == NULL) || (vals[0] == NULL)) {
4664
0
    DEBUG(0, ("\"objectSid\" not found\n"));
4665
0
    return False;
4666
0
  }
4667
4668
0
  if (!string_to_sid(&sid, vals[0])) {
4669
0
    DEBUG(0, ("Could not convert %s to SID\n", vals[0]));
4670
0
    ldap_value_free(vals);
4671
0
    return False;
4672
0
  }
4673
0
  ldap_value_free(vals);
4674
4675
0
  if (!sid_peek_check_rid(get_global_sam_sid(), &sid, &result->rid)) {
4676
0
    struct dom_sid_buf buf;
4677
0
    DEBUG(0, ("sid %s does not belong to our domain\n",
4678
0
        dom_sid_str_buf(&sid, &buf)));
4679
0
    return False;
4680
0
  }
4681
4682
0
  return True;
4683
0
}
4684
4685
4686
static bool ldapsam_search_users(struct pdb_methods *methods,
4687
         struct pdb_search *search,
4688
         uint32_t acct_flags)
4689
0
{
4690
0
  struct ldapsam_privates *ldap_state =
4691
0
    (struct ldapsam_privates *)methods->private_data;
4692
0
  struct ldap_search_state *state;
4693
4694
0
  state = talloc(search, struct ldap_search_state);
4695
0
  if (state == NULL) {
4696
0
    DEBUG(0, ("talloc failed\n"));
4697
0
    return False;
4698
0
  }
4699
4700
0
  state->connection = ldap_state->smbldap_state;
4701
4702
0
  if ((acct_flags != 0) && ((acct_flags & ACB_NORMAL) != 0))
4703
0
    state->base = lp_ldap_user_suffix(talloc_tos());
4704
0
  else if ((acct_flags != 0) &&
4705
0
     ((acct_flags & (ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST)) != 0))
4706
0
    state->base = lp_ldap_machine_suffix(talloc_tos());
4707
0
  else
4708
0
    state->base = lp_ldap_suffix();
4709
4710
0
  state->acct_flags = acct_flags;
4711
0
  state->base = talloc_strdup(search, state->base);
4712
0
  state->scope = LDAP_SCOPE_SUBTREE;
4713
0
  state->filter = get_ldap_filter(search, "*");
4714
0
  state->attrs = talloc_attrs(search, "uid", "sambaSid",
4715
0
            "displayName", "description",
4716
0
            "sambaAcctFlags", NULL);
4717
0
  state->attrsonly = 0;
4718
0
  state->pagedresults_cookie = NULL;
4719
0
  state->entries = NULL;
4720
0
  state->ldap2displayentry = ldapuser2displayentry;
4721
4722
0
  if ((state->filter == NULL) || (state->attrs == NULL)) {
4723
0
    DEBUG(0, ("talloc failed\n"));
4724
0
    return False;
4725
0
  }
4726
4727
0
  search->private_data = state;
4728
0
  search->next_entry = ldapsam_search_next_entry;
4729
0
  search->search_end = ldapsam_search_end;
4730
4731
0
  return ldapsam_search_firstpage(search);
4732
0
}
4733
4734
static bool ldapgroup2displayentry(struct ldap_search_state *state,
4735
           TALLOC_CTX *mem_ctx,
4736
           LDAP *ld, LDAPMessage *entry,
4737
           struct samr_displayentry *result)
4738
0
{
4739
0
  char **vals;
4740
0
  size_t converted_size;
4741
0
  struct dom_sid sid;
4742
0
  uint16_t group_type;
4743
4744
0
  result->account_name = "";
4745
0
  result->fullname = "";
4746
0
  result->description = "";
4747
4748
4749
0
  vals = ldap_get_values(ld, entry, "sambaGroupType");
4750
0
  if ((vals == NULL) || (vals[0] == NULL)) {
4751
0
    DEBUG(5, ("\"sambaGroupType\" not found\n"));
4752
0
    if (vals != NULL) {
4753
0
      ldap_value_free(vals);
4754
0
    }
4755
0
    return False;
4756
0
  }
4757
4758
0
  group_type = atoi(vals[0]);
4759
4760
0
  if ((state->group_type != 0) &&
4761
0
      ((state->group_type != group_type))) {
4762
0
    ldap_value_free(vals);
4763
0
    return False;
4764
0
  }
4765
4766
0
  ldap_value_free(vals);
4767
4768
  /* display name is the NT group name */
4769
4770
0
  vals = ldap_get_values(ld, entry, "displayName");
4771
0
  if ((vals == NULL) || (vals[0] == NULL)) {
4772
0
    DEBUG(8, ("\"displayName\" not found\n"));
4773
4774
    /* fallback to the 'cn' attribute */
4775
0
    vals = ldap_get_values(ld, entry, "cn");
4776
0
    if ((vals == NULL) || (vals[0] == NULL)) {
4777
0
      DEBUG(5, ("\"cn\" not found\n"));
4778
0
      return False;
4779
0
    }
4780
0
    if (!pull_utf8_talloc(mem_ctx,
4781
0
              discard_const_p(char *,
4782
0
                &result->account_name),
4783
0
              vals[0], &converted_size))
4784
0
    {
4785
0
      DEBUG(0,("ldapgroup2displayentry: pull_utf8_talloc "
4786
0
          "failed: %s\n", strerror(errno)));
4787
0
    }
4788
0
  }
4789
0
  else if (!pull_utf8_talloc(mem_ctx,
4790
0
           discard_const_p(char *,
4791
0
             &result->account_name),
4792
0
           vals[0], &converted_size))
4793
0
  {
4794
0
    DEBUG(0,("ldapgroup2displayentry: pull_utf8_talloc failed: %s\n",
4795
0
        strerror(errno)));
4796
0
  }
4797
4798
0
  ldap_value_free(vals);
4799
4800
0
  vals = ldap_get_values(ld, entry, "description");
4801
0
  if ((vals == NULL) || (vals[0] == NULL))
4802
0
    DEBUG(8, ("\"description\" not found\n"));
4803
0
  else if (!pull_utf8_talloc(mem_ctx,
4804
0
           discard_const_p(char *, &result->description),
4805
0
           vals[0], &converted_size))
4806
0
  {
4807
0
    DEBUG(0,("ldapgroup2displayentry: pull_utf8_talloc failed: %s\n",
4808
0
        strerror(errno)));
4809
0
  }
4810
0
  ldap_value_free(vals);
4811
4812
0
  if ((result->account_name == NULL) ||
4813
0
      (result->fullname == NULL) ||
4814
0
      (result->description == NULL)) {
4815
0
    DEBUG(0, ("talloc failed\n"));
4816
0
    return False;
4817
0
  }
4818
4819
0
  vals = ldap_get_values(ld, entry, "sambaSid");
4820
0
  if ((vals == NULL) || (vals[0] == NULL)) {
4821
0
    DEBUG(0, ("\"objectSid\" not found\n"));
4822
0
    if (vals != NULL) {
4823
0
      ldap_value_free(vals);
4824
0
    }
4825
0
    return False;
4826
0
  }
4827
4828
0
  if (!string_to_sid(&sid, vals[0])) {
4829
0
    DEBUG(0, ("Could not convert %s to SID\n", vals[0]));
4830
0
    return False;
4831
0
  }
4832
4833
0
  ldap_value_free(vals);
4834
4835
0
  switch (group_type) {
4836
0
    case SID_NAME_DOM_GRP:
4837
0
    case SID_NAME_ALIAS:
4838
4839
0
      if (!sid_peek_check_rid(get_global_sam_sid(), &sid, &result->rid)
4840
0
        && !sid_peek_check_rid(&global_sid_Builtin, &sid, &result->rid))
4841
0
      {
4842
0
        struct dom_sid_buf buf;
4843
0
        DEBUG(0, ("%s is not in our domain\n",
4844
0
            dom_sid_str_buf(&sid, &buf)));
4845
0
        return False;
4846
0
      }
4847
0
      break;
4848
4849
0
    default:
4850
0
      DEBUG(0,("unknown group type: %d\n", group_type));
4851
0
      return False;
4852
0
  }
4853
4854
0
  result->acct_flags = 0;
4855
4856
0
  return True;
4857
0
}
4858
4859
static bool ldapsam_search_grouptype(struct pdb_methods *methods,
4860
             struct pdb_search *search,
4861
                                     const struct dom_sid *sid,
4862
             enum lsa_SidType type)
4863
0
{
4864
0
  struct ldapsam_privates *ldap_state =
4865
0
    (struct ldapsam_privates *)methods->private_data;
4866
0
  struct ldap_search_state *state;
4867
0
  struct dom_sid_buf tmp;
4868
4869
0
  state = talloc(search, struct ldap_search_state);
4870
0
  if (state == NULL) {
4871
0
    DEBUG(0, ("talloc failed\n"));
4872
0
    return False;
4873
0
  }
4874
4875
0
  state->connection = ldap_state->smbldap_state;
4876
4877
0
  state->base = lp_ldap_suffix();
4878
0
  state->connection = ldap_state->smbldap_state;
4879
0
  state->scope = LDAP_SCOPE_SUBTREE;
4880
0
  state->filter = talloc_asprintf(search, "(&(objectclass="LDAP_OBJ_GROUPMAP")"
4881
0
          "(sambaGroupType=%d)(sambaSID=%s*))",
4882
0
           type,
4883
0
           dom_sid_str_buf(sid, &tmp));
4884
0
  state->attrs = talloc_attrs(search, "cn", "sambaSid",
4885
0
            "displayName", "description",
4886
0
            "sambaGroupType", NULL);
4887
0
  state->attrsonly = 0;
4888
0
  state->pagedresults_cookie = NULL;
4889
0
  state->entries = NULL;
4890
0
  state->group_type = type;
4891
0
  state->ldap2displayentry = ldapgroup2displayentry;
4892
4893
0
  if ((state->filter == NULL) || (state->attrs == NULL)) {
4894
0
    DEBUG(0, ("talloc failed\n"));
4895
0
    return False;
4896
0
  }
4897
4898
0
  search->private_data = state;
4899
0
  search->next_entry = ldapsam_search_next_entry;
4900
0
  search->search_end = ldapsam_search_end;
4901
4902
0
  return ldapsam_search_firstpage(search);
4903
0
}
4904
4905
static bool ldapsam_search_groups(struct pdb_methods *methods,
4906
          struct pdb_search *search)
4907
0
{
4908
0
  return ldapsam_search_grouptype(methods, search, get_global_sam_sid(), SID_NAME_DOM_GRP);
4909
0
}
4910
4911
static bool ldapsam_search_aliases(struct pdb_methods *methods,
4912
           struct pdb_search *search,
4913
           const struct dom_sid *sid)
4914
0
{
4915
0
  return ldapsam_search_grouptype(methods, search, sid, SID_NAME_ALIAS);
4916
0
}
4917
4918
static uint32_t ldapsam_capabilities(struct pdb_methods *methods)
4919
0
{
4920
0
  return PDB_CAP_STORE_RIDS;
4921
0
}
4922
4923
static NTSTATUS ldapsam_get_new_rid(struct ldapsam_privates *priv,
4924
            uint32_t *rid)
4925
0
{
4926
0
  struct smbldap_state *smbldap_state = priv->smbldap_state;
4927
4928
0
  LDAPMessage *result = NULL;
4929
0
  LDAPMessage *entry = NULL;
4930
0
  LDAPMod **mods = NULL;
4931
0
  NTSTATUS status;
4932
0
  char *value;
4933
0
  int rc;
4934
0
  uint32_t nextRid = 0;
4935
0
  const char *dn;
4936
0
  uint32_t tmp;
4937
0
  int error = 0;
4938
4939
0
  TALLOC_CTX *mem_ctx;
4940
4941
0
  mem_ctx = talloc_new(NULL);
4942
0
  if (mem_ctx == NULL) {
4943
0
    DEBUG(0, ("talloc_new failed\n"));
4944
0
    return NT_STATUS_NO_MEMORY;
4945
0
  }
4946
4947
0
  status = smbldap_search_domain_info(smbldap_state, &result,
4948
0
              get_global_sam_name(), False);
4949
0
  if (!NT_STATUS_IS_OK(status)) {
4950
0
    DEBUG(3, ("Could not get domain info: %s\n",
4951
0
        nt_errstr(status)));
4952
0
    goto done;
4953
0
  }
4954
4955
0
  smbldap_talloc_autofree_ldapmsg(mem_ctx, result);
4956
4957
0
  entry = ldap_first_entry(priv2ld(priv), result);
4958
0
  if (entry == NULL) {
4959
0
    DEBUG(0, ("Could not get domain info entry\n"));
4960
0
    status = NT_STATUS_INTERNAL_DB_CORRUPTION;
4961
0
    goto done;
4962
0
  }
4963
4964
  /* Find the largest of the three attributes "sambaNextRid",
4965
     "sambaNextGroupRid" and "sambaNextUserRid". I gave up on the
4966
     concept of differentiating between user and group rids, and will
4967
     use only "sambaNextRid" in the future. But for compatibility
4968
     reasons I look if others have chosen different strategies -- VL */
4969
4970
0
  value = smbldap_talloc_single_attribute(priv2ld(priv), entry,
4971
0
            "sambaNextRid", mem_ctx);
4972
0
  if (value != NULL) {
4973
0
    tmp = (uint32_t)smb_strtoul(value,
4974
0
              NULL,
4975
0
              10,
4976
0
              &error,
4977
0
              SMB_STR_STANDARD);
4978
0
    if (error != 0) {
4979
0
      goto done;
4980
0
    }
4981
4982
0
    nextRid = MAX(nextRid, tmp);
4983
0
  }
4984
4985
0
  value = smbldap_talloc_single_attribute(priv2ld(priv), entry,
4986
0
            "sambaNextUserRid", mem_ctx);
4987
0
  if (value != NULL) {
4988
0
    tmp = (uint32_t)smb_strtoul(value,
4989
0
              NULL,
4990
0
              10,
4991
0
              &error,
4992
0
              SMB_STR_STANDARD);
4993
0
    if (error != 0) {
4994
0
      goto done;
4995
0
    }
4996
4997
0
    nextRid = MAX(nextRid, tmp);
4998
0
  }
4999
5000
0
  value = smbldap_talloc_single_attribute(priv2ld(priv), entry,
5001
0
            "sambaNextGroupRid", mem_ctx);
5002
0
  if (value != NULL) {
5003
0
    tmp = (uint32_t)smb_strtoul(value,
5004
0
              NULL,
5005
0
              10,
5006
0
              &error,
5007
0
              SMB_STR_STANDARD);
5008
0
    if (error != 0) {
5009
0
      goto done;
5010
0
    }
5011
5012
0
    nextRid = MAX(nextRid, tmp);
5013
0
  }
5014
5015
0
  if (nextRid == 0) {
5016
0
    nextRid = BASE_RID-1;
5017
0
  }
5018
5019
0
  nextRid += 1;
5020
5021
0
  smbldap_make_mod(priv2ld(priv), entry, &mods, "sambaNextRid",
5022
0
       talloc_asprintf(mem_ctx, "%d", nextRid));
5023
0
  smbldap_talloc_autofree_ldapmod(mem_ctx, mods);
5024
5025
0
  if ((dn = smbldap_talloc_dn(mem_ctx, priv2ld(priv), entry)) == NULL) {
5026
0
    status = NT_STATUS_NO_MEMORY;
5027
0
    goto done;
5028
0
  }
5029
5030
0
  rc = smbldap_modify(smbldap_state, dn, mods);
5031
5032
  /* ACCESS_DENIED is used as a placeholder for "the modify failed,
5033
   * please retry" */
5034
5035
0
  status = (rc == LDAP_SUCCESS) ? NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
5036
5037
0
 done:
5038
0
  if (NT_STATUS_IS_OK(status)) {
5039
0
    *rid = nextRid;
5040
0
  }
5041
5042
0
  TALLOC_FREE(mem_ctx);
5043
0
  return status;
5044
0
}
5045
5046
static NTSTATUS ldapsam_new_rid_internal(struct pdb_methods *methods, uint32_t *rid)
5047
0
{
5048
0
  int i;
5049
5050
0
  for (i=0; i<10; i++) {
5051
0
    NTSTATUS result = ldapsam_get_new_rid(
5052
0
      (struct ldapsam_privates *)methods->private_data, rid);
5053
0
    if (NT_STATUS_IS_OK(result)) {
5054
0
      return result;
5055
0
    }
5056
5057
0
    if (!NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED)) {
5058
0
      return result;
5059
0
    }
5060
5061
    /* The ldap update failed (maybe a race condition), retry */
5062
0
  }
5063
5064
  /* Tried 10 times, fail. */
5065
0
  return NT_STATUS_ACCESS_DENIED;
5066
0
}
5067
5068
static bool ldapsam_new_rid(struct pdb_methods *methods, uint32_t *rid)
5069
0
{
5070
0
  NTSTATUS result = ldapsam_new_rid_internal(methods, rid);
5071
0
  return NT_STATUS_IS_OK(result) ? True : False;
5072
0
}
5073
5074
static bool ldapsam_sid_to_id(struct pdb_methods *methods,
5075
            const struct dom_sid *sid,
5076
            struct unixid *id)
5077
0
{
5078
0
  struct ldapsam_privates *priv =
5079
0
    (struct ldapsam_privates *)methods->private_data;
5080
0
  char *filter;
5081
0
  int error = 0;
5082
0
  struct dom_sid_buf buf;
5083
0
  const char *attrs[] = { "sambaGroupType", "gidNumber", "uidNumber",
5084
0
        NULL };
5085
0
  LDAPMessage *result = NULL;
5086
0
  LDAPMessage *entry = NULL;
5087
0
  bool ret = False;
5088
0
  char *value;
5089
0
  int rc;
5090
5091
0
  TALLOC_CTX *mem_ctx;
5092
5093
0
  ret = pdb_sid_to_id_unix_users_and_groups(sid, id);
5094
0
  if (ret == true) {
5095
0
    return true;
5096
0
  }
5097
5098
0
  mem_ctx = talloc_new(NULL);
5099
0
  if (mem_ctx == NULL) {
5100
0
    DEBUG(0, ("talloc_new failed\n"));
5101
0
    return False;
5102
0
  }
5103
5104
0
  filter = talloc_asprintf(mem_ctx,
5105
0
         "(&(sambaSid=%s)"
5106
0
         "(|(objectClass="LDAP_OBJ_GROUPMAP")(objectClass="LDAP_OBJ_SAMBASAMACCOUNT")))",
5107
0
         dom_sid_str_buf(sid, &buf));
5108
0
  if (filter == NULL) {
5109
0
    DEBUG(5, ("talloc_asprintf failed\n"));
5110
0
    goto done;
5111
0
  }
5112
5113
0
  rc = smbldap_search_suffix(priv->smbldap_state, filter,
5114
0
           attrs, &result);
5115
0
  if (rc != LDAP_SUCCESS) {
5116
0
    goto done;
5117
0
  }
5118
0
  smbldap_talloc_autofree_ldapmsg(mem_ctx, result);
5119
5120
0
  if (ldap_count_entries(priv2ld(priv), result) != 1) {
5121
0
    DEBUG(10, ("Got %d entries, expected one\n",
5122
0
         ldap_count_entries(priv2ld(priv), result)));
5123
0
    goto done;
5124
0
  }
5125
5126
0
  entry = ldap_first_entry(priv2ld(priv), result);
5127
5128
0
  value = smbldap_talloc_single_attribute(priv2ld(priv), entry,
5129
0
            "sambaGroupType", mem_ctx);
5130
5131
0
  if (value != NULL) {
5132
0
    const char *gid_str;
5133
    /* It's a group */
5134
5135
0
    gid_str = smbldap_talloc_single_attribute(
5136
0
      priv2ld(priv), entry, "gidNumber", mem_ctx);
5137
0
    if (gid_str == NULL) {
5138
0
      DEBUG(1, ("%s has sambaGroupType but no gidNumber\n",
5139
0
          smbldap_talloc_dn(mem_ctx, priv2ld(priv),
5140
0
                entry)));
5141
0
      goto done;
5142
0
    }
5143
5144
0
    id->id = smb_strtoul(gid_str,
5145
0
             NULL,
5146
0
             10,
5147
0
             &error,
5148
0
             SMB_STR_STANDARD);
5149
0
    if (error != 0) {
5150
0
      goto done;
5151
0
    }
5152
5153
0
    id->type = ID_TYPE_GID;
5154
0
    ret = True;
5155
0
    goto done;
5156
0
  }
5157
5158
  /* It must be a user */
5159
5160
0
  value = smbldap_talloc_single_attribute(priv2ld(priv), entry,
5161
0
            "uidNumber", mem_ctx);
5162
0
  if (value == NULL) {
5163
0
    DEBUG(1, ("Could not find uidNumber in %s\n",
5164
0
        smbldap_talloc_dn(mem_ctx, priv2ld(priv), entry)));
5165
0
    goto done;
5166
0
  }
5167
5168
0
  id->id = smb_strtoul(value, NULL, 10, &error, SMB_STR_STANDARD);
5169
0
  if (error != 0) {
5170
0
    goto done;
5171
0
  }
5172
5173
0
  id->type = ID_TYPE_UID;
5174
0
  ret = True;
5175
0
 done:
5176
0
  TALLOC_FREE(mem_ctx);
5177
0
  return ret;
5178
0
}
5179
5180
/**
5181
 * Find the SID for a uid.
5182
 * This is shortcut is only used if ldapsam:trusted is set to true.
5183
 */
5184
static bool ldapsam_uid_to_sid(struct pdb_methods *methods, uid_t uid,
5185
             struct dom_sid *sid)
5186
0
{
5187
0
  struct ldapsam_privates *priv =
5188
0
    (struct ldapsam_privates *)methods->private_data;
5189
0
  char *filter;
5190
0
  const char *attrs[] = { "sambaSID", NULL };
5191
0
  LDAPMessage *result = NULL;
5192
0
  LDAPMessage *entry = NULL;
5193
0
  bool ret = false;
5194
0
  char *user_sid_string;
5195
0
  struct dom_sid user_sid;
5196
0
  int rc;
5197
0
  TALLOC_CTX *tmp_ctx = talloc_stackframe();
5198
5199
0
  filter = talloc_asprintf(tmp_ctx,
5200
0
         "(&(uidNumber=%u)"
5201
0
         "(objectClass="LDAP_OBJ_POSIXACCOUNT")"
5202
0
         "(objectClass="LDAP_OBJ_SAMBASAMACCOUNT"))",
5203
0
         (unsigned int)uid);
5204
0
  if (filter == NULL) {
5205
0
    DEBUG(3, ("talloc_asprintf failed\n"));
5206
0
    goto done;
5207
0
  }
5208
5209
0
  rc = smbldap_search_suffix(priv->smbldap_state, filter, attrs, &result);
5210
0
  if (rc != LDAP_SUCCESS) {
5211
0
    goto done;
5212
0
  }
5213
0
  smbldap_talloc_autofree_ldapmsg(tmp_ctx, result);
5214
5215
0
  if (ldap_count_entries(priv2ld(priv), result) != 1) {
5216
0
    DEBUG(3, ("ERROR: Got %d entries for uid %u, expected one\n",
5217
0
         ldap_count_entries(priv2ld(priv), result),
5218
0
         (unsigned int)uid));
5219
0
    goto done;
5220
0
  }
5221
5222
0
  entry = ldap_first_entry(priv2ld(priv), result);
5223
5224
0
  user_sid_string = smbldap_talloc_single_attribute(priv2ld(priv), entry,
5225
0
                "sambaSID", tmp_ctx);
5226
0
  if (user_sid_string == NULL) {
5227
0
    DEBUG(1, ("Could not find sambaSID in object '%s'\n",
5228
0
        smbldap_talloc_dn(tmp_ctx, priv2ld(priv), entry)));
5229
0
    goto done;
5230
0
  }
5231
5232
0
  if (!string_to_sid(&user_sid, user_sid_string)) {
5233
0
    DEBUG(3, ("Error calling string_to_sid for sid '%s'\n",
5234
0
        user_sid_string));
5235
0
    goto done;
5236
0
  }
5237
5238
0
  sid_copy(sid, &user_sid);
5239
5240
0
  ret = true;
5241
5242
0
 done:
5243
0
  TALLOC_FREE(tmp_ctx);
5244
0
  return ret;
5245
0
}
5246
5247
/**
5248
 * Find the SID for a gid.
5249
 * This is shortcut is only used if ldapsam:trusted is set to true.
5250
 */
5251
static bool ldapsam_gid_to_sid(struct pdb_methods *methods, gid_t gid,
5252
             struct dom_sid *sid)
5253
0
{
5254
0
  struct ldapsam_privates *priv =
5255
0
    (struct ldapsam_privates *)methods->private_data;
5256
0
  char *filter;
5257
0
  const char *attrs[] = { "sambaSID", NULL };
5258
0
  LDAPMessage *result = NULL;
5259
0
  LDAPMessage *entry = NULL;
5260
0
  bool ret = false;
5261
0
  char *group_sid_string;
5262
0
  struct dom_sid group_sid;
5263
0
  int rc;
5264
0
  TALLOC_CTX *tmp_ctx = talloc_stackframe();
5265
5266
0
  filter = talloc_asprintf(tmp_ctx,
5267
0
         "(&(gidNumber=%u)"
5268
0
         "(objectClass="LDAP_OBJ_GROUPMAP"))",
5269
0
         (unsigned int)gid);
5270
0
  if (filter == NULL) {
5271
0
    DEBUG(3, ("talloc_asprintf failed\n"));
5272
0
    goto done;
5273
0
  }
5274
5275
0
  rc = smbldap_search_suffix(priv->smbldap_state, filter, attrs, &result);
5276
0
  if (rc != LDAP_SUCCESS) {
5277
0
    goto done;
5278
0
  }
5279
0
  smbldap_talloc_autofree_ldapmsg(tmp_ctx, result);
5280
5281
0
  if (ldap_count_entries(priv2ld(priv), result) != 1) {
5282
0
    DEBUG(3, ("ERROR: Got %d entries for gid %u, expected one\n",
5283
0
         ldap_count_entries(priv2ld(priv), result),
5284
0
         (unsigned int)gid));
5285
0
    goto done;
5286
0
  }
5287
5288
0
  entry = ldap_first_entry(priv2ld(priv), result);
5289
5290
0
  group_sid_string = smbldap_talloc_single_attribute(priv2ld(priv), entry,
5291
0
                "sambaSID", tmp_ctx);
5292
0
  if (group_sid_string == NULL) {
5293
0
    DEBUG(1, ("Could not find sambaSID in object '%s'\n",
5294
0
        smbldap_talloc_dn(tmp_ctx, priv2ld(priv), entry)));
5295
0
    goto done;
5296
0
  }
5297
5298
0
  if (!string_to_sid(&group_sid, group_sid_string)) {
5299
0
    DEBUG(3, ("Error calling string_to_sid for sid '%s'\n",
5300
0
        group_sid_string));
5301
0
    goto done;
5302
0
  }
5303
5304
0
  sid_copy(sid, &group_sid);
5305
5306
0
  ret = true;
5307
5308
0
 done:
5309
0
  TALLOC_FREE(tmp_ctx);
5310
0
  return ret;
5311
0
}
5312
5313
static bool ldapsam_id_to_sid(struct pdb_methods *methods, struct unixid *id,
5314
           struct dom_sid *sid)
5315
0
{
5316
0
  switch (id->type) {
5317
0
  case ID_TYPE_UID:
5318
0
    return ldapsam_uid_to_sid(methods, id->id, sid);
5319
5320
0
  case ID_TYPE_GID:
5321
0
    return ldapsam_gid_to_sid(methods, id->id, sid);
5322
5323
0
  default:
5324
0
    return false;
5325
0
  }
5326
0
}
5327
5328
5329
/*
5330
 * The following functions are called only if
5331
 * ldapsam:trusted and ldapsam:editposix are
5332
 * set to true
5333
 */
5334
5335
/*
5336
 * ldapsam_create_user creates a new
5337
 * posixAccount and sambaSamAccount object
5338
 * in the ldap users subtree
5339
 *
5340
 * The uid is allocated by winbindd.
5341
 */
5342
5343
static NTSTATUS ldapsam_create_user(struct pdb_methods *my_methods,
5344
            TALLOC_CTX *tmp_ctx, const char *name,
5345
            uint32_t acb_info, uint32_t *rid)
5346
0
{
5347
0
  struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
5348
0
  LDAPMessage *entry = NULL;
5349
0
  LDAPMessage *result = NULL;
5350
0
  uint32_t num_result;
5351
0
  bool is_machine = False;
5352
0
  bool add_posix = False;
5353
0
  bool init_okay = False;
5354
0
  LDAPMod **mods = NULL;
5355
0
  struct samu *user;
5356
0
  char *filter;
5357
0
  char *username;
5358
0
  char *homedir;
5359
0
  char *gidstr;
5360
0
  char *uidstr;
5361
0
  char *shell;
5362
0
  const char *dn = NULL;
5363
0
  struct dom_sid group_sid;
5364
0
  struct dom_sid user_sid;
5365
0
  gid_t gid = -1;
5366
0
  uid_t uid = -1;
5367
0
  NTSTATUS ret;
5368
0
  int rc;
5369
5370
0
  if (((acb_info & ACB_NORMAL) && name[strlen(name)-1] == '$') ||
5371
0
        acb_info & ACB_WSTRUST ||
5372
0
        acb_info & ACB_SVRTRUST ||
5373
0
        acb_info & ACB_DOMTRUST) {
5374
0
    is_machine = True;
5375
0
  }
5376
5377
0
  username = escape_ldap_string(talloc_tos(), name);
5378
0
  filter = talloc_asprintf(tmp_ctx, "(&(uid=%s)(objectClass="LDAP_OBJ_POSIXACCOUNT"))",
5379
0
         username);
5380
0
  TALLOC_FREE(username);
5381
5382
0
  rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
5383
0
  if (rc != LDAP_SUCCESS) {
5384
0
    DEBUG(0,("ldapsam_create_user: ldap search failed!\n"));
5385
0
    return NT_STATUS_ACCESS_DENIED;
5386
0
  }
5387
0
  smbldap_talloc_autofree_ldapmsg(tmp_ctx, result);
5388
5389
0
  num_result = ldap_count_entries(priv2ld(ldap_state), result);
5390
5391
0
  if (num_result > 1) {
5392
0
    DEBUG (0, ("ldapsam_create_user: More than one user with name [%s] ?!\n", name));
5393
0
    return NT_STATUS_INTERNAL_DB_CORRUPTION;
5394
0
  }
5395
5396
0
  if (num_result == 1) {
5397
0
    char *tmp;
5398
    /* check if it is just a posix account.
5399
     * or if there is a sid attached to this entry
5400
     */
5401
5402
0
    entry = ldap_first_entry(priv2ld(ldap_state), result);
5403
0
    if (!entry) {
5404
0
      return NT_STATUS_UNSUCCESSFUL;
5405
0
    }
5406
5407
0
    tmp = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "sambaSID", tmp_ctx);
5408
0
    if (tmp) {
5409
0
      DEBUG (1, ("ldapsam_create_user: The user [%s] already exist!\n", name));
5410
0
      return NT_STATUS_USER_EXISTS;
5411
0
    }
5412
5413
    /* it is just a posix account, retrieve the dn for later use */
5414
0
    dn = smbldap_talloc_dn(tmp_ctx, priv2ld(ldap_state), entry);
5415
0
    if (!dn) {
5416
0
      DEBUG(0,("ldapsam_create_user: Out of memory!\n"));
5417
0
      return NT_STATUS_NO_MEMORY;
5418
0
    }
5419
0
  }
5420
5421
0
  if (num_result == 0) {
5422
0
    add_posix = True;
5423
0
  }
5424
5425
  /* Create the basic samu structure and generate the mods for the ldap commit */
5426
0
  if (!NT_STATUS_IS_OK((ret = ldapsam_new_rid_internal(my_methods, rid)))) {
5427
0
    DEBUG(1, ("ldapsam_create_user: Could not allocate a new RID\n"));
5428
0
    return ret;
5429
0
  }
5430
5431
0
  sid_compose(&user_sid, get_global_sam_sid(), *rid);
5432
5433
0
  user = samu_new(tmp_ctx);
5434
0
  if (!user) {
5435
0
    DEBUG(1,("ldapsam_create_user: Unable to allocate user struct\n"));
5436
0
    return NT_STATUS_NO_MEMORY;
5437
0
  }
5438
5439
0
  if (!pdb_set_username(user, name, PDB_SET)) {
5440
0
    DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
5441
0
    return NT_STATUS_UNSUCCESSFUL;
5442
0
  }
5443
0
  if (!pdb_set_domain(user, get_global_sam_name(), PDB_SET)) {
5444
0
    DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
5445
0
    return NT_STATUS_UNSUCCESSFUL;
5446
0
  }
5447
0
  if (is_machine) {
5448
0
    if (acb_info & ACB_NORMAL) {
5449
0
      if (!pdb_set_acct_ctrl(user, ACB_WSTRUST, PDB_SET)) {
5450
0
        DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
5451
0
        return NT_STATUS_UNSUCCESSFUL;
5452
0
      }
5453
0
    } else {
5454
0
      if (!pdb_set_acct_ctrl(user, acb_info, PDB_SET)) {
5455
0
        DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
5456
0
        return NT_STATUS_UNSUCCESSFUL;
5457
0
      }
5458
0
    }
5459
0
  } else {
5460
0
    if (!pdb_set_acct_ctrl(user, ACB_NORMAL | ACB_DISABLED, PDB_SET)) {
5461
0
      DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
5462
0
      return NT_STATUS_UNSUCCESSFUL;
5463
0
    }
5464
0
  }
5465
5466
0
  if (!pdb_set_user_sid(user, &user_sid, PDB_SET)) {
5467
0
    DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
5468
0
    return NT_STATUS_UNSUCCESSFUL;
5469
0
  }
5470
5471
0
  init_okay = init_ldap_from_sam(ldap_state, entry, &mods, user, pdb_element_is_set_or_changed);
5472
5473
0
  if (!init_okay) {
5474
0
    DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
5475
0
    ldap_mods_free(mods, true);
5476
0
    return NT_STATUS_UNSUCCESSFUL;
5477
0
  }
5478
5479
0
  if (ldap_state->schema_ver != SCHEMAVER_SAMBASAMACCOUNT) {
5480
0
    DEBUG(1,("ldapsam_create_user: Unsupported schema version\n"));
5481
0
  }
5482
0
  smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_SAMBASAMACCOUNT);
5483
5484
0
  if (add_posix) {
5485
0
    char *escape_name;
5486
5487
0
    DEBUG(3,("ldapsam_create_user: Creating new posix user\n"));
5488
5489
    /* retrieve the Domain Users group gid */
5490
0
    if (!sid_compose(&group_sid, get_global_sam_sid(), DOMAIN_RID_USERS) ||
5491
0
        !sid_to_gid(&group_sid, &gid)) {
5492
0
      DEBUG (0, ("ldapsam_create_user: Unable to get the Domain Users gid: bailing out!\n"));
5493
0
      ldap_mods_free(mods, true);
5494
0
      return NT_STATUS_INVALID_PRIMARY_GROUP;
5495
0
    }
5496
5497
    /* lets allocate a new userid for this user */
5498
0
    if (!winbind_allocate_uid(&uid)) {
5499
0
      DEBUG (0, ("ldapsam_create_user: Unable to allocate a new user id: bailing out!\n"));
5500
0
      ldap_mods_free(mods, true);
5501
0
      return NT_STATUS_UNSUCCESSFUL;
5502
0
    }
5503
5504
5505
0
    if (is_machine) {
5506
      /* TODO: choose a more appropriate default for machines */
5507
0
      homedir = talloc_sub_specified(tmp_ctx,
5508
0
                   lp_template_homedir(),
5509
0
                   "SMB_workstations_home",
5510
0
                   NULL,
5511
0
                   ldap_state->domain_name,
5512
0
                   uid,
5513
0
                   gid);
5514
0
      shell = talloc_strdup(tmp_ctx, "/bin/false");
5515
0
    } else {
5516
0
      homedir = talloc_sub_specified(tmp_ctx,
5517
0
                   lp_template_homedir(),
5518
0
                   name,
5519
0
                   NULL,
5520
0
                   ldap_state->domain_name,
5521
0
                   uid,
5522
0
                   gid);
5523
0
      shell = talloc_sub_specified(tmp_ctx,
5524
0
                 lp_template_shell(),
5525
0
                 name,
5526
0
                 NULL,
5527
0
                 ldap_state->domain_name,
5528
0
                 uid,
5529
0
                 gid);
5530
0
    }
5531
0
    uidstr = talloc_asprintf(tmp_ctx, "%u", (unsigned int)uid);
5532
0
    gidstr = talloc_asprintf(tmp_ctx, "%u", (unsigned int)gid);
5533
5534
0
    escape_name = escape_rdn_val_string_alloc(name);
5535
0
    if (!escape_name) {
5536
0
      DEBUG (0, ("ldapsam_create_user: Out of memory!\n"));
5537
0
      ldap_mods_free(mods, true);
5538
0
      return NT_STATUS_NO_MEMORY;
5539
0
    }
5540
5541
0
    if (is_machine) {
5542
0
      dn = talloc_asprintf(tmp_ctx, "uid=%s,%s", escape_name, lp_ldap_machine_suffix (talloc_tos()));
5543
0
    } else {
5544
0
      dn = talloc_asprintf(tmp_ctx, "uid=%s,%s", escape_name, lp_ldap_user_suffix (talloc_tos()));
5545
0
    }
5546
5547
0
    SAFE_FREE(escape_name);
5548
5549
0
    if (!homedir || !shell || !uidstr || !gidstr || !dn) {
5550
0
      DEBUG (0, ("ldapsam_create_user: Out of memory!\n"));
5551
0
      ldap_mods_free(mods, true);
5552
0
      return NT_STATUS_NO_MEMORY;
5553
0
    }
5554
5555
0
    smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_ACCOUNT);
5556
0
    smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_POSIXACCOUNT);
5557
0
    smbldap_set_mod(&mods, LDAP_MOD_ADD, "cn", name);
5558
0
    smbldap_set_mod(&mods, LDAP_MOD_ADD, "uidNumber", uidstr);
5559
0
    smbldap_set_mod(&mods, LDAP_MOD_ADD, "gidNumber", gidstr);
5560
0
    smbldap_set_mod(&mods, LDAP_MOD_ADD, "homeDirectory", homedir);
5561
0
    smbldap_set_mod(&mods, LDAP_MOD_ADD, "loginShell", shell);
5562
0
  }
5563
5564
0
  if (add_posix) {
5565
0
    rc = smbldap_add(ldap_state->smbldap_state, dn, mods);
5566
0
  } else {
5567
0
    rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
5568
0
  }
5569
5570
0
  ldap_mods_free(mods, true);
5571
5572
0
  if (rc != LDAP_SUCCESS) {
5573
0
    DEBUG(0,("ldapsam_create_user: failed to create a new user [%s] (dn = %s)\n", name ,dn));
5574
0
    return NT_STATUS_UNSUCCESSFUL;
5575
0
  }
5576
5577
0
  DEBUG(2,("ldapsam_create_user: added account [%s] in the LDAP database\n", name));
5578
5579
0
  flush_pwnam_cache();
5580
5581
0
  return NT_STATUS_OK;
5582
0
}
5583
5584
static NTSTATUS ldapsam_delete_user(struct pdb_methods *my_methods, TALLOC_CTX *tmp_ctx, struct samu *sam_acct)
5585
0
{
5586
0
  struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
5587
0
  LDAPMessage *result = NULL;
5588
0
  LDAPMessage *entry = NULL;
5589
0
  int num_result;
5590
0
  const char *dn;
5591
0
  char *filter;
5592
0
  int rc;
5593
5594
0
  DEBUG(0,("ldapsam_delete_user: Attempt to delete user [%s]\n", pdb_get_username(sam_acct)));
5595
5596
0
  filter = talloc_asprintf(tmp_ctx,
5597
0
         "(&(uid=%s)"
5598
0
         "(objectClass="LDAP_OBJ_POSIXACCOUNT")"
5599
0
         "(objectClass="LDAP_OBJ_SAMBASAMACCOUNT"))",
5600
0
         pdb_get_username(sam_acct));
5601
0
  if (filter == NULL) {
5602
0
    return NT_STATUS_NO_MEMORY;
5603
0
  }
5604
5605
0
  rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
5606
0
  if (rc != LDAP_SUCCESS) {
5607
0
    DEBUG(0,("ldapsam_delete_user: user search failed!\n"));
5608
0
    return NT_STATUS_UNSUCCESSFUL;
5609
0
  }
5610
0
  smbldap_talloc_autofree_ldapmsg(tmp_ctx, result);
5611
5612
0
  num_result = ldap_count_entries(priv2ld(ldap_state), result);
5613
5614
0
  if (num_result == 0) {
5615
0
    DEBUG(0,("ldapsam_delete_user: user not found!\n"));
5616
0
    return NT_STATUS_NO_SUCH_USER;
5617
0
  }
5618
5619
0
  if (num_result > 1) {
5620
0
    DEBUG (0, ("ldapsam_delete_user: More than one user with name [%s] ?!\n", pdb_get_username(sam_acct)));
5621
0
    return NT_STATUS_INTERNAL_DB_CORRUPTION;
5622
0
  }
5623
5624
0
  entry = ldap_first_entry(priv2ld(ldap_state), result);
5625
0
  if (!entry) {
5626
0
    return NT_STATUS_UNSUCCESSFUL;
5627
0
  }
5628
5629
  /* it is just a posix account, retrieve the dn for later use */
5630
0
  dn = smbldap_talloc_dn(tmp_ctx, priv2ld(ldap_state), entry);
5631
0
  if (!dn) {
5632
0
    DEBUG(0,("ldapsam_delete_user: Out of memory!\n"));
5633
0
    return NT_STATUS_NO_MEMORY;
5634
0
  }
5635
5636
  /* try to remove memberships first */
5637
0
  {
5638
0
    NTSTATUS status;
5639
0
    struct dom_sid *sids = NULL;
5640
0
    gid_t *gids = NULL;
5641
0
    uint32_t num_groups = 0;
5642
0
    int i;
5643
0
    uint32_t user_rid = pdb_get_user_rid(sam_acct);
5644
5645
0
    status = ldapsam_enum_group_memberships(my_methods,
5646
0
              tmp_ctx,
5647
0
              sam_acct,
5648
0
              &sids,
5649
0
              &gids,
5650
0
              &num_groups);
5651
0
    if (!NT_STATUS_IS_OK(status)) {
5652
0
      goto delete_dn;
5653
0
    }
5654
5655
0
    for (i=0; i < num_groups; i++) {
5656
5657
0
      uint32_t group_rid;
5658
5659
0
      sid_peek_rid(&sids[i], &group_rid);
5660
5661
0
      ldapsam_del_groupmem(my_methods,
5662
0
               tmp_ctx,
5663
0
               group_rid,
5664
0
               user_rid);
5665
0
    }
5666
0
  }
5667
5668
0
 delete_dn:
5669
5670
0
  rc = smbldap_delete(ldap_state->smbldap_state, dn);
5671
0
  if (rc != LDAP_SUCCESS) {
5672
0
    return NT_STATUS_UNSUCCESSFUL;
5673
0
  }
5674
5675
0
  flush_pwnam_cache();
5676
5677
0
  return NT_STATUS_OK;
5678
0
}
5679
5680
/*
5681
 * ldapsam_create_group creates a new
5682
 * posixGroup and sambaGroupMapping object
5683
 * in the ldap groups subtree
5684
 *
5685
 * The gid is allocated by winbindd.
5686
 */
5687
5688
static NTSTATUS ldapsam_create_dom_group(struct pdb_methods *my_methods,
5689
           TALLOC_CTX *tmp_ctx,
5690
           const char *name,
5691
           uint32_t *rid)
5692
0
{
5693
0
  struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
5694
0
  NTSTATUS ret;
5695
0
  LDAPMessage *entry = NULL;
5696
0
  LDAPMessage *result = NULL;
5697
0
  uint32_t num_result;
5698
0
  bool is_new_entry = False;
5699
0
  LDAPMod **mods = NULL;
5700
0
  char *filter;
5701
0
  char *groupname;
5702
0
  const char *grouptype;
5703
0
  char *gidstr;
5704
0
  const char *dn = NULL;
5705
0
  struct dom_sid group_sid;
5706
0
  struct dom_sid_buf buf;
5707
0
  gid_t gid = -1;
5708
0
  int rc;
5709
0
  int error = 0;
5710
5711
0
  groupname = escape_ldap_string(talloc_tos(), name);
5712
0
  filter = talloc_asprintf(tmp_ctx, "(&(cn=%s)(objectClass="LDAP_OBJ_POSIXGROUP"))",
5713
0
         groupname);
5714
0
  TALLOC_FREE(groupname);
5715
5716
0
  rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
5717
0
  if (rc != LDAP_SUCCESS) {
5718
0
    DEBUG(0,("ldapsam_create_group: ldap search failed!\n"));
5719
0
    return NT_STATUS_UNSUCCESSFUL;
5720
0
  }
5721
0
  smbldap_talloc_autofree_ldapmsg(tmp_ctx, result);
5722
5723
0
  num_result = ldap_count_entries(priv2ld(ldap_state), result);
5724
5725
0
  if (num_result > 1) {
5726
0
    DEBUG (0, ("ldapsam_create_group: There exists more than one group with name [%s]: bailing out!\n", name));
5727
0
    return NT_STATUS_INTERNAL_DB_CORRUPTION;
5728
0
  }
5729
5730
0
  if (num_result == 1) {
5731
0
    char *tmp;
5732
    /* check if it is just a posix group.
5733
     * or if there is a sid attached to this entry
5734
     */
5735
5736
0
    entry = ldap_first_entry(priv2ld(ldap_state), result);
5737
0
    if (!entry) {
5738
0
      return NT_STATUS_UNSUCCESSFUL;
5739
0
    }
5740
5741
0
    tmp = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "sambaSID", tmp_ctx);
5742
0
    if (tmp) {
5743
0
      DEBUG (1, ("ldapsam_create_group: The group [%s] already exist!\n", name));
5744
0
      return NT_STATUS_GROUP_EXISTS;
5745
0
    }
5746
5747
    /* it is just a posix group, retrieve the gid and the dn for later use */
5748
0
    tmp = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "gidNumber", tmp_ctx);
5749
0
    if (!tmp) {
5750
0
      DEBUG (1, ("ldapsam_create_group: Couldn't retrieve the gidNumber for [%s]?!?!\n", name));
5751
0
      return NT_STATUS_INTERNAL_DB_CORRUPTION;
5752
0
    }
5753
5754
0
    gid = smb_strtoul(tmp, NULL, 10, &error, SMB_STR_STANDARD);
5755
0
    if (error != 0) {
5756
0
      DBG_ERR("Failed to convert gidNumber\n");
5757
0
      return NT_STATUS_UNSUCCESSFUL;
5758
0
    }
5759
5760
0
    dn = smbldap_talloc_dn(tmp_ctx, priv2ld(ldap_state), entry);
5761
0
    if (!dn) {
5762
0
      DEBUG(0,("ldapsam_create_group: Out of memory!\n"));
5763
0
      return NT_STATUS_NO_MEMORY;
5764
0
    }
5765
0
  }
5766
5767
0
  if (num_result == 0) {
5768
0
    is_new_entry = true;
5769
0
  }
5770
5771
0
  if (!NT_STATUS_IS_OK((ret = ldapsam_new_rid_internal(my_methods, rid)))) {
5772
0
    DEBUG(1, ("ldapsam_create_group: Could not allocate a new RID\n"));
5773
0
    return ret;
5774
0
  }
5775
5776
0
  sid_compose(&group_sid, get_global_sam_sid(), *rid);
5777
5778
0
  grouptype = talloc_asprintf(tmp_ctx, "%d", SID_NAME_DOM_GRP);
5779
5780
0
  if (!grouptype) {
5781
0
    DEBUG(0,("ldapsam_create_group: Out of memory!\n"));
5782
0
    return NT_STATUS_NO_MEMORY;
5783
0
  }
5784
5785
0
  smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_GROUPMAP);
5786
0
  smbldap_set_mod(&mods,
5787
0
      LDAP_MOD_ADD,
5788
0
      "sambaSid",
5789
0
      dom_sid_str_buf(&group_sid, &buf));
5790
0
  smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaGroupType", grouptype);
5791
0
  smbldap_set_mod(&mods, LDAP_MOD_ADD, "displayName", name);
5792
5793
0
  if (is_new_entry) {
5794
0
    char *escape_name;
5795
5796
0
    DEBUG(3,("ldapsam_create_user: Creating new posix group\n"));
5797
5798
    /* lets allocate a new groupid for this group */
5799
0
    if (!winbind_allocate_gid(&gid)) {
5800
0
      DEBUG (0, ("ldapsam_create_group: Unable to allocate a new group id: bailing out!\n"));
5801
0
      return NT_STATUS_UNSUCCESSFUL;
5802
0
    }
5803
5804
0
    gidstr = talloc_asprintf(tmp_ctx, "%u", (unsigned int)gid);
5805
5806
0
    escape_name = escape_rdn_val_string_alloc(name);
5807
0
    if (!escape_name) {
5808
0
      DEBUG (0, ("ldapsam_create_group: Out of memory!\n"));
5809
0
      return NT_STATUS_NO_MEMORY;
5810
0
    }
5811
5812
0
    dn = talloc_asprintf(tmp_ctx, "cn=%s,%s", escape_name, lp_ldap_group_suffix(talloc_tos()));
5813
5814
0
    SAFE_FREE(escape_name);
5815
5816
0
    if (!gidstr || !dn) {
5817
0
      DEBUG (0, ("ldapsam_create_group: Out of memory!\n"));
5818
0
      return NT_STATUS_NO_MEMORY;
5819
0
    }
5820
5821
0
    smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_POSIXGROUP);
5822
0
    smbldap_set_mod(&mods, LDAP_MOD_ADD, "cn", name);
5823
0
    smbldap_set_mod(&mods, LDAP_MOD_ADD, "gidNumber", gidstr);
5824
0
  }
5825
5826
0
  smbldap_talloc_autofree_ldapmod(tmp_ctx, mods);
5827
5828
0
  if (is_new_entry) {
5829
0
    rc = smbldap_add(ldap_state->smbldap_state, dn, mods);
5830
#if 0
5831
    if (rc == LDAP_OBJECT_CLASS_VIOLATION) {
5832
      /* This call may fail with rfc2307bis schema */
5833
      /* Retry adding a structural class */
5834
      smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", "????");
5835
      rc = smbldap_add(ldap_state->smbldap_state, dn, mods);
5836
    }
5837
#endif
5838
0
  } else {
5839
0
    rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
5840
0
  }
5841
5842
0
  if (rc != LDAP_SUCCESS) {
5843
0
    DEBUG(0,("ldapsam_create_group: failed to create a new group [%s] (dn = %s)\n", name ,dn));
5844
0
    return NT_STATUS_UNSUCCESSFUL;
5845
0
  }
5846
5847
0
  DEBUG(2,("ldapsam_create_group: added group [%s] in the LDAP database\n", name));
5848
5849
0
  return NT_STATUS_OK;
5850
0
}
5851
5852
static NTSTATUS ldapsam_delete_dom_group(struct pdb_methods *my_methods, TALLOC_CTX *tmp_ctx, uint32_t rid)
5853
0
{
5854
0
  struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
5855
0
  LDAPMessage *result = NULL;
5856
0
  LDAPMessage *entry = NULL;
5857
0
  int num_result;
5858
0
  const char *dn;
5859
0
  char *gidstr;
5860
0
  char *filter;
5861
0
  struct dom_sid group_sid;
5862
0
  struct dom_sid_buf buf;
5863
0
  int rc;
5864
5865
  /* get the group sid */
5866
0
  sid_compose(&group_sid, get_global_sam_sid(), rid);
5867
5868
0
  filter = talloc_asprintf(tmp_ctx,
5869
0
         "(&(sambaSID=%s)"
5870
0
         "(objectClass="LDAP_OBJ_POSIXGROUP")"
5871
0
         "(objectClass="LDAP_OBJ_GROUPMAP"))",
5872
0
         dom_sid_str_buf(&group_sid, &buf));
5873
0
  if (filter == NULL) {
5874
0
    return NT_STATUS_NO_MEMORY;
5875
0
  }
5876
5877
0
  rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
5878
0
  if (rc != LDAP_SUCCESS) {
5879
0
    DEBUG(1,("ldapsam_delete_dom_group: group search failed!\n"));
5880
0
    return NT_STATUS_UNSUCCESSFUL;
5881
0
  }
5882
0
  smbldap_talloc_autofree_ldapmsg(tmp_ctx, result);
5883
5884
0
  num_result = ldap_count_entries(priv2ld(ldap_state), result);
5885
5886
0
  if (num_result == 0) {
5887
0
    DEBUG(1,("ldapsam_delete_dom_group: group not found!\n"));
5888
0
    return NT_STATUS_NO_SUCH_GROUP;
5889
0
  }
5890
5891
0
  if (num_result > 1) {
5892
0
    DEBUG (0, ("ldapsam_delete_dom_group: More than one group with the same SID ?!\n"));
5893
0
    return NT_STATUS_INTERNAL_DB_CORRUPTION;
5894
0
  }
5895
5896
0
  entry = ldap_first_entry(priv2ld(ldap_state), result);
5897
0
  if (!entry) {
5898
0
    return NT_STATUS_UNSUCCESSFUL;
5899
0
  }
5900
5901
  /* here it is, retrieve the dn for later use */
5902
0
  dn = smbldap_talloc_dn(tmp_ctx, priv2ld(ldap_state), entry);
5903
0
  if (!dn) {
5904
0
    DEBUG(0,("ldapsam_delete_dom_group: Out of memory!\n"));
5905
0
    return NT_STATUS_NO_MEMORY;
5906
0
  }
5907
5908
0
  gidstr = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "gidNumber", tmp_ctx);
5909
0
  if (!gidstr) {
5910
0
    DEBUG (0, ("ldapsam_delete_dom_group: Unable to find the group's gid!\n"));
5911
0
    return NT_STATUS_INTERNAL_DB_CORRUPTION;
5912
0
  }
5913
5914
  /* check no user have this group marked as primary group */
5915
0
  filter = talloc_asprintf(tmp_ctx,
5916
0
         "(&(gidNumber=%s)"
5917
0
         "(objectClass="LDAP_OBJ_POSIXACCOUNT")"
5918
0
         "(objectClass="LDAP_OBJ_SAMBASAMACCOUNT"))",
5919
0
         gidstr);
5920
5921
0
  rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
5922
0
  if (rc != LDAP_SUCCESS) {
5923
0
    DEBUG(1,("ldapsam_delete_dom_group: accounts search failed!\n"));
5924
0
    return NT_STATUS_UNSUCCESSFUL;
5925
0
  }
5926
0
  smbldap_talloc_autofree_ldapmsg(tmp_ctx, result);
5927
5928
0
  num_result = ldap_count_entries(priv2ld(ldap_state), result);
5929
5930
0
  if (num_result != 0) {
5931
0
    DEBUG(3,("ldapsam_delete_dom_group: Can't delete group, it is a primary group for %d users\n", num_result));
5932
0
    return NT_STATUS_MEMBERS_PRIMARY_GROUP;
5933
0
  }
5934
5935
0
  rc = smbldap_delete(ldap_state->smbldap_state, dn);
5936
0
  if (rc != LDAP_SUCCESS) {
5937
0
    return NT_STATUS_UNSUCCESSFUL;
5938
0
  }
5939
5940
0
  return NT_STATUS_OK;
5941
0
}
5942
5943
static NTSTATUS ldapsam_change_groupmem(struct pdb_methods *my_methods,
5944
          TALLOC_CTX *tmp_ctx,
5945
          uint32_t group_rid,
5946
          uint32_t member_rid,
5947
          int modop)
5948
0
{
5949
0
  struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
5950
0
  LDAPMessage *entry = NULL;
5951
0
  LDAPMessage *result = NULL;
5952
0
  uint32_t num_result;
5953
0
  LDAPMod **mods = NULL;
5954
0
  char *filter;
5955
0
  char *uidstr;
5956
0
  const char *dn = NULL;
5957
0
  struct dom_sid group_sid;
5958
0
  struct dom_sid member_sid;
5959
0
  struct dom_sid_buf buf;
5960
0
  int rc;
5961
0
  int error = 0;
5962
5963
0
  switch (modop) {
5964
0
  case LDAP_MOD_ADD:
5965
0
    DEBUG(1,("ldapsam_change_groupmem: add new member(rid=%d) to a domain group(rid=%d)\n", member_rid, group_rid));
5966
0
    break;
5967
0
  case LDAP_MOD_DELETE:
5968
0
    DEBUG(1,("ldapsam_change_groupmem: delete member(rid=%d) from a domain group(rid=%d)\n", member_rid, group_rid));
5969
0
    break;
5970
0
  default:
5971
0
    return NT_STATUS_UNSUCCESSFUL;
5972
0
  }
5973
5974
  /* get member sid  */
5975
0
  sid_compose(&member_sid, get_global_sam_sid(), member_rid);
5976
5977
  /* get the group sid */
5978
0
  sid_compose(&group_sid, get_global_sam_sid(), group_rid);
5979
5980
0
  filter = talloc_asprintf(tmp_ctx,
5981
0
         "(&(sambaSID=%s)"
5982
0
         "(objectClass="LDAP_OBJ_POSIXACCOUNT")"
5983
0
         "(objectClass="LDAP_OBJ_SAMBASAMACCOUNT"))",
5984
0
         dom_sid_str_buf(&member_sid, &buf));
5985
0
  if (filter == NULL) {
5986
0
    return NT_STATUS_NO_MEMORY;
5987
0
  }
5988
5989
  /* get the member uid */
5990
0
  rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
5991
0
  if (rc != LDAP_SUCCESS) {
5992
0
    DEBUG(1,("ldapsam_change_groupmem: member search failed!\n"));
5993
0
    return NT_STATUS_UNSUCCESSFUL;
5994
0
  }
5995
0
  smbldap_talloc_autofree_ldapmsg(tmp_ctx, result);
5996
5997
0
  num_result = ldap_count_entries(priv2ld(ldap_state), result);
5998
5999
0
  if (num_result == 0) {
6000
0
    DEBUG(1,("ldapsam_change_groupmem: member not found!\n"));
6001
0
    return NT_STATUS_NO_SUCH_MEMBER;
6002
0
  }
6003
6004
0
  if (num_result > 1) {
6005
0
    DEBUG (0, ("ldapsam_change_groupmem: More than one account with the same SID ?!\n"));
6006
0
    return NT_STATUS_INTERNAL_DB_CORRUPTION;
6007
0
  }
6008
6009
0
  entry = ldap_first_entry(priv2ld(ldap_state), result);
6010
0
  if (!entry) {
6011
0
    return NT_STATUS_UNSUCCESSFUL;
6012
0
  }
6013
6014
0
  if (modop == LDAP_MOD_DELETE) {
6015
    /* check if we are trying to remove the member from his primary group */
6016
0
    char *gidstr;
6017
0
    gid_t user_gid, group_gid;
6018
6019
0
    gidstr = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "gidNumber", tmp_ctx);
6020
0
    if (!gidstr) {
6021
0
      DEBUG (0, ("ldapsam_change_groupmem: Unable to find the member's gid!\n"));
6022
0
      return NT_STATUS_INTERNAL_DB_CORRUPTION;
6023
0
    }
6024
6025
0
    user_gid = smb_strtoul(gidstr, NULL, 10, &error, SMB_STR_STANDARD);
6026
0
    if (error != 0) {
6027
0
      DBG_ERR("Failed to convert user gid\n");
6028
0
      return NT_STATUS_UNSUCCESSFUL;
6029
0
    }
6030
6031
0
    if (!sid_to_gid(&group_sid, &group_gid)) {
6032
0
      DEBUG (0, ("ldapsam_change_groupmem: Unable to get group gid from SID!\n"));
6033
0
      return NT_STATUS_UNSUCCESSFUL;
6034
0
    }
6035
6036
0
    if (user_gid == group_gid) {
6037
0
      DEBUG (3, ("ldapsam_change_groupmem: can't remove user from its own primary group!\n"));
6038
0
      return NT_STATUS_MEMBERS_PRIMARY_GROUP;
6039
0
    }
6040
0
  }
6041
6042
  /* here it is, retrieve the uid for later use */
6043
0
  uidstr = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "uid", tmp_ctx);
6044
0
  if (!uidstr) {
6045
0
    DEBUG (0, ("ldapsam_change_groupmem: Unable to find the member's name!\n"));
6046
0
    return NT_STATUS_INTERNAL_DB_CORRUPTION;
6047
0
  }
6048
6049
0
  filter = talloc_asprintf(tmp_ctx,
6050
0
         "(&(sambaSID=%s)"
6051
0
         "(objectClass="LDAP_OBJ_POSIXGROUP")"
6052
0
         "(objectClass="LDAP_OBJ_GROUPMAP"))",
6053
0
         dom_sid_str_buf(&group_sid, &buf));
6054
6055
  /* get the group */
6056
0
  rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
6057
0
  if (rc != LDAP_SUCCESS) {
6058
0
    DEBUG(1,("ldapsam_change_groupmem: group search failed!\n"));
6059
0
    return NT_STATUS_UNSUCCESSFUL;
6060
0
  }
6061
0
  smbldap_talloc_autofree_ldapmsg(tmp_ctx, result);
6062
6063
0
  num_result = ldap_count_entries(priv2ld(ldap_state), result);
6064
6065
0
  if (num_result == 0) {
6066
0
    DEBUG(1,("ldapsam_change_groupmem: group not found!\n"));
6067
0
    return NT_STATUS_NO_SUCH_GROUP;
6068
0
  }
6069
6070
0
  if (num_result > 1) {
6071
0
    DEBUG (0, ("ldapsam_change_groupmem: More than one group with the same SID ?!\n"));
6072
0
    return NT_STATUS_INTERNAL_DB_CORRUPTION;
6073
0
  }
6074
6075
0
  entry = ldap_first_entry(priv2ld(ldap_state), result);
6076
0
  if (!entry) {
6077
0
    return NT_STATUS_UNSUCCESSFUL;
6078
0
  }
6079
6080
  /* here it is, retrieve the dn for later use */
6081
0
  dn = smbldap_talloc_dn(tmp_ctx, priv2ld(ldap_state), entry);
6082
0
  if (!dn) {
6083
0
    DEBUG(0,("ldapsam_change_groupmem: Out of memory!\n"));
6084
0
    return NT_STATUS_NO_MEMORY;
6085
0
  }
6086
6087
0
  smbldap_set_mod(&mods, modop, "memberUid", uidstr);
6088
6089
0
  smbldap_talloc_autofree_ldapmod(tmp_ctx, mods);
6090
6091
0
  rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
6092
0
  if (rc != LDAP_SUCCESS) {
6093
0
    if (rc == LDAP_TYPE_OR_VALUE_EXISTS && modop == LDAP_MOD_ADD) {
6094
0
      DEBUG(1,("ldapsam_change_groupmem: member is already in group, add failed!\n"));
6095
0
      return NT_STATUS_MEMBER_IN_GROUP;
6096
0
    }
6097
0
    if (rc == LDAP_NO_SUCH_ATTRIBUTE && modop == LDAP_MOD_DELETE) {
6098
0
      DEBUG(1,("ldapsam_change_groupmem: member is not in group, delete failed!\n"));
6099
0
      return NT_STATUS_MEMBER_NOT_IN_GROUP;
6100
0
    }
6101
0
    return NT_STATUS_UNSUCCESSFUL;
6102
0
  }
6103
6104
0
  return NT_STATUS_OK;
6105
0
}
6106
6107
static NTSTATUS ldapsam_add_groupmem(struct pdb_methods *my_methods,
6108
             TALLOC_CTX *tmp_ctx,
6109
             uint32_t group_rid,
6110
             uint32_t member_rid)
6111
0
{
6112
0
  return ldapsam_change_groupmem(my_methods, tmp_ctx, group_rid, member_rid, LDAP_MOD_ADD);
6113
0
}
6114
static NTSTATUS ldapsam_del_groupmem(struct pdb_methods *my_methods,
6115
             TALLOC_CTX *tmp_ctx,
6116
             uint32_t group_rid,
6117
             uint32_t member_rid)
6118
0
{
6119
0
  return ldapsam_change_groupmem(my_methods, tmp_ctx, group_rid, member_rid, LDAP_MOD_DELETE);
6120
0
}
6121
6122
static NTSTATUS ldapsam_set_primary_group(struct pdb_methods *my_methods,
6123
            TALLOC_CTX *mem_ctx,
6124
            struct samu *sampass)
6125
0
{
6126
0
  struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
6127
0
  LDAPMessage *entry = NULL;
6128
0
  LDAPMessage *result = NULL;
6129
0
  uint32_t num_result;
6130
0
  LDAPMod **mods = NULL;
6131
0
  char *filter;
6132
0
  char *escape_username;
6133
0
  char *gidstr;
6134
0
  char *dn = NULL;
6135
0
  gid_t gid;
6136
0
  int rc;
6137
6138
0
  DEBUG(0,("ldapsam_set_primary_group: Attempt to set primary group for user [%s]\n", pdb_get_username(sampass)));
6139
6140
0
  if (!sid_to_gid(pdb_get_group_sid(sampass), &gid)) {
6141
0
    DEBUG(0,("ldapsam_set_primary_group: failed to retrieve gid from user's group SID!\n"));
6142
0
    return NT_STATUS_UNSUCCESSFUL;
6143
0
  }
6144
0
  gidstr = talloc_asprintf(mem_ctx, "%u", (unsigned int)gid);
6145
0
  if (!gidstr) {
6146
0
    DEBUG(0,("ldapsam_set_primary_group: Out of Memory!\n"));
6147
0
    return NT_STATUS_NO_MEMORY;
6148
0
  }
6149
6150
0
  escape_username = escape_ldap_string(talloc_tos(),
6151
0
               pdb_get_username(sampass));
6152
0
  if (escape_username== NULL) {
6153
0
    return NT_STATUS_NO_MEMORY;
6154
0
  }
6155
6156
0
  filter = talloc_asprintf(mem_ctx,
6157
0
         "(&(uid=%s)"
6158
0
         "(objectClass="LDAP_OBJ_POSIXACCOUNT")"
6159
0
         "(objectClass="LDAP_OBJ_SAMBASAMACCOUNT"))",
6160
0
         escape_username);
6161
6162
0
  TALLOC_FREE(escape_username);
6163
6164
0
  if (filter == NULL) {
6165
0
    return NT_STATUS_NO_MEMORY;
6166
0
  }
6167
6168
0
  rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
6169
0
  if (rc != LDAP_SUCCESS) {
6170
0
    DEBUG(0,("ldapsam_set_primary_group: user search failed!\n"));
6171
0
    return NT_STATUS_UNSUCCESSFUL;
6172
0
  }
6173
0
  smbldap_talloc_autofree_ldapmsg(mem_ctx, result);
6174
6175
0
  num_result = ldap_count_entries(priv2ld(ldap_state), result);
6176
6177
0
  if (num_result == 0) {
6178
0
    DEBUG(0,("ldapsam_set_primary_group: user not found!\n"));
6179
0
    return NT_STATUS_NO_SUCH_USER;
6180
0
  }
6181
6182
0
  if (num_result > 1) {
6183
0
    DEBUG (0, ("ldapsam_set_primary_group: More than one user with name [%s] ?!\n", pdb_get_username(sampass)));
6184
0
    return NT_STATUS_INTERNAL_DB_CORRUPTION;
6185
0
  }
6186
6187
0
  entry = ldap_first_entry(priv2ld(ldap_state), result);
6188
0
  if (!entry) {
6189
0
    return NT_STATUS_UNSUCCESSFUL;
6190
0
  }
6191
6192
  /* retrieve the dn for later use */
6193
0
  dn = smbldap_talloc_dn(mem_ctx, priv2ld(ldap_state), entry);
6194
0
  if (!dn) {
6195
0
    DEBUG(0,("ldapsam_set_primary_group: Out of memory!\n"));
6196
0
    return NT_STATUS_NO_MEMORY;
6197
0
  }
6198
6199
  /* remove the old one, and add the new one, this way we do not risk races */
6200
0
  smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "gidNumber", gidstr);
6201
6202
0
  if (mods == NULL) {
6203
0
    TALLOC_FREE(dn);
6204
0
    return NT_STATUS_OK;
6205
0
  }
6206
6207
0
  rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
6208
0
  TALLOC_FREE(dn);
6209
0
  if (rc != LDAP_SUCCESS) {
6210
0
    DEBUG(0,("ldapsam_set_primary_group: failed to modify [%s] primary group to [%s]\n",
6211
0
       pdb_get_username(sampass), gidstr));
6212
0
    return NT_STATUS_UNSUCCESSFUL;
6213
0
  }
6214
6215
0
  flush_pwnam_cache();
6216
6217
0
  return NT_STATUS_OK;
6218
0
}
6219
6220
6221
/**********************************************************************
6222
 trusted domains functions
6223
 *********************************************************************/
6224
6225
static char *trusteddom_dn(struct ldapsam_privates *ldap_state,
6226
         const char *domain)
6227
0
{
6228
0
  return talloc_asprintf(talloc_tos(), "sambaDomainName=%s,%s", domain,
6229
0
             ldap_state->domain_dn);
6230
0
}
6231
6232
static bool get_trusteddom_pw_int(struct ldapsam_privates *ldap_state,
6233
          TALLOC_CTX *mem_ctx,
6234
          const char *domain, LDAPMessage **entry)
6235
0
{
6236
0
  int rc;
6237
0
  char *filter;
6238
0
  int scope = LDAP_SCOPE_SUBTREE;
6239
0
  const char **attrs = NULL; /* NULL: get all attrs */
6240
0
  int attrsonly = 0; /* 0: return values too */
6241
0
  LDAPMessage *result = NULL;
6242
0
  char *trusted_dn;
6243
0
  uint32_t num_result;
6244
6245
0
  filter = talloc_asprintf(talloc_tos(),
6246
0
         "(&(objectClass="LDAP_OBJ_TRUSTDOM_PASSWORD")(sambaDomainName=%s))",
6247
0
         domain);
6248
6249
0
  trusted_dn = trusteddom_dn(ldap_state, domain);
6250
0
  if (trusted_dn == NULL) {
6251
0
    return False;
6252
0
  }
6253
0
  rc = smbldap_search(ldap_state->smbldap_state, trusted_dn, scope,
6254
0
          filter, attrs, attrsonly, &result);
6255
6256
0
  if (result != NULL) {
6257
0
    smbldap_talloc_autofree_ldapmsg(mem_ctx, result);
6258
0
  }
6259
6260
0
  if (rc == LDAP_NO_SUCH_OBJECT) {
6261
0
    *entry = NULL;
6262
0
    return True;
6263
0
  }
6264
6265
0
  if (rc != LDAP_SUCCESS) {
6266
0
    return False;
6267
0
  }
6268
6269
0
  num_result = ldap_count_entries(priv2ld(ldap_state), result);
6270
6271
0
  if (num_result > 1) {
6272
0
    DEBUG(1, ("ldapsam_get_trusteddom_pw: more than one "
6273
0
        "%s object for domain '%s'?!\n",
6274
0
        LDAP_OBJ_TRUSTDOM_PASSWORD, domain));
6275
0
    return False;
6276
0
  }
6277
6278
0
  if (num_result == 0) {
6279
0
    DEBUG(1, ("ldapsam_get_trusteddom_pw: no "
6280
0
        "%s object for domain %s.\n",
6281
0
        LDAP_OBJ_TRUSTDOM_PASSWORD, domain));
6282
0
    *entry = NULL;
6283
0
  } else {
6284
0
    *entry = ldap_first_entry(priv2ld(ldap_state), result);
6285
0
  }
6286
6287
0
  return True;
6288
0
}
6289
6290
static bool ldapsam_get_trusteddom_pw(struct pdb_methods *methods,
6291
              const char *domain,
6292
              char** pwd,
6293
              struct dom_sid *sid,
6294
                    time_t *pass_last_set_time)
6295
0
{
6296
0
  struct ldapsam_privates *ldap_state =
6297
0
    (struct ldapsam_privates *)methods->private_data;
6298
0
  LDAPMessage *entry = NULL;
6299
6300
0
  DEBUG(10, ("ldapsam_get_trusteddom_pw called for domain %s\n", domain));
6301
6302
0
  if (!get_trusteddom_pw_int(ldap_state, talloc_tos(), domain, &entry) ||
6303
0
      (entry == NULL))
6304
0
  {
6305
0
    return False;
6306
0
  }
6307
6308
  /* password */
6309
0
  if (pwd != NULL) {
6310
0
    char *pwd_str;
6311
0
    pwd_str = smbldap_talloc_single_attribute(priv2ld(ldap_state),
6312
0
        entry, "sambaClearTextPassword", talloc_tos());
6313
0
    if (pwd_str == NULL) {
6314
0
      return False;
6315
0
    }
6316
    /* trusteddom_pw routines do not use talloc yet... */
6317
0
    *pwd = SMB_STRDUP(pwd_str);
6318
0
    if (*pwd == NULL) {
6319
0
      return False;
6320
0
    }
6321
0
  }
6322
6323
  /* last change time */
6324
0
  if (pass_last_set_time != NULL) {
6325
0
    char *time_str;
6326
0
    time_str = smbldap_talloc_single_attribute(priv2ld(ldap_state),
6327
0
        entry, "sambaPwdLastSet", talloc_tos());
6328
0
    if (time_str == NULL) {
6329
0
      return False;
6330
0
    }
6331
0
    *pass_last_set_time = (time_t)atol(time_str);
6332
0
  }
6333
6334
  /* domain sid */
6335
0
  if (sid != NULL) {
6336
0
    char *sid_str;
6337
0
    struct dom_sid dom_sid;
6338
0
    sid_str = smbldap_talloc_single_attribute(priv2ld(ldap_state),
6339
0
                entry, "sambaSID",
6340
0
                talloc_tos());
6341
0
    if (sid_str == NULL) {
6342
0
      return False;
6343
0
    }
6344
0
    if (!string_to_sid(&dom_sid, sid_str)) {
6345
0
      return False;
6346
0
    }
6347
0
    sid_copy(sid, &dom_sid);
6348
0
  }
6349
6350
0
  return True;
6351
0
}
6352
6353
static bool ldapsam_set_trusteddom_pw(struct pdb_methods *methods,
6354
              const char* domain,
6355
              const char* pwd,
6356
              const struct dom_sid *sid)
6357
0
{
6358
0
  struct ldapsam_privates *ldap_state =
6359
0
    (struct ldapsam_privates *)methods->private_data;
6360
0
  LDAPMessage *entry = NULL;
6361
0
  LDAPMod **mods = NULL;
6362
0
  char *prev_pwd = NULL;
6363
0
  char *trusted_dn = NULL;
6364
0
  struct dom_sid_buf buf;
6365
0
  int rc;
6366
6367
0
  DEBUG(10, ("ldapsam_set_trusteddom_pw called for domain %s\n", domain));
6368
6369
  /*
6370
   * get the current entry (if there is one) in order to put the
6371
   * current password into the previous password attribute
6372
   */
6373
0
  if (!get_trusteddom_pw_int(ldap_state, talloc_tos(), domain, &entry)) {
6374
0
    return False;
6375
0
  }
6376
6377
0
  mods = NULL;
6378
0
  smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "objectClass",
6379
0
       LDAP_OBJ_TRUSTDOM_PASSWORD);
6380
0
  smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "sambaDomainName",
6381
0
       domain);
6382
0
  smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "sambaSID",
6383
0
       dom_sid_str_buf(sid, &buf));
6384
0
  smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "sambaPwdLastSet",
6385
0
       talloc_asprintf(talloc_tos(), "%li", (long int)time(NULL)));
6386
0
  smbldap_make_mod(priv2ld(ldap_state), entry, &mods,
6387
0
       "sambaClearTextPassword", pwd);
6388
6389
0
  if (entry != NULL) {
6390
0
    prev_pwd = smbldap_talloc_single_attribute(priv2ld(ldap_state),
6391
0
        entry, "sambaClearTextPassword", talloc_tos());
6392
0
    if (prev_pwd != NULL) {
6393
0
      smbldap_make_mod(priv2ld(ldap_state), entry, &mods,
6394
0
           "sambaPreviousClearTextPassword",
6395
0
           prev_pwd);
6396
0
    }
6397
0
  }
6398
6399
0
  smbldap_talloc_autofree_ldapmod(talloc_tos(), mods);
6400
6401
0
  trusted_dn = trusteddom_dn(ldap_state, domain);
6402
0
  if (trusted_dn == NULL) {
6403
0
    return False;
6404
0
  }
6405
0
  if (entry == NULL) {
6406
0
    rc = smbldap_add(ldap_state->smbldap_state, trusted_dn, mods);
6407
0
  } else {
6408
0
    rc = smbldap_modify(ldap_state->smbldap_state, trusted_dn, mods);
6409
0
  }
6410
6411
0
  if (rc != LDAP_SUCCESS) {
6412
0
    DEBUG(1, ("error writing trusted domain password!\n"));
6413
0
    return False;
6414
0
  }
6415
6416
0
  return True;
6417
0
}
6418
6419
static bool ldapsam_del_trusteddom_pw(struct pdb_methods *methods,
6420
              const char *domain)
6421
0
{
6422
0
  int rc;
6423
0
  struct ldapsam_privates *ldap_state =
6424
0
    (struct ldapsam_privates *)methods->private_data;
6425
0
  LDAPMessage *entry = NULL;
6426
0
  const char *trusted_dn;
6427
6428
0
  if (!get_trusteddom_pw_int(ldap_state, talloc_tos(), domain, &entry)) {
6429
0
    return False;
6430
0
  }
6431
6432
0
  if (entry == NULL) {
6433
0
    DEBUG(5, ("ldapsam_del_trusteddom_pw: no such trusted domain: "
6434
0
        "%s\n", domain));
6435
0
    return True;
6436
0
  }
6437
6438
0
  trusted_dn = smbldap_talloc_dn(talloc_tos(), priv2ld(ldap_state),
6439
0
               entry);
6440
0
  if (trusted_dn == NULL) {
6441
0
    DEBUG(0,("ldapsam_del_trusteddom_pw: Out of memory!\n"));
6442
0
    return False;
6443
0
  }
6444
6445
0
  rc = smbldap_delete(ldap_state->smbldap_state, trusted_dn);
6446
0
  if (rc != LDAP_SUCCESS) {
6447
0
    return False;
6448
0
  }
6449
6450
0
  return True;
6451
0
}
6452
6453
static NTSTATUS ldapsam_enum_trusteddoms(struct pdb_methods *methods,
6454
           TALLOC_CTX *mem_ctx,
6455
           uint32_t *num_domains,
6456
           struct trustdom_info ***domains)
6457
0
{
6458
0
  int rc;
6459
0
  struct ldapsam_privates *ldap_state =
6460
0
    (struct ldapsam_privates *)methods->private_data;
6461
0
  const char *filter;
6462
0
  int scope = LDAP_SCOPE_SUBTREE;
6463
0
  const char *attrs[] = { "sambaDomainName", "sambaSID", NULL };
6464
0
  int attrsonly = 0; /* 0: return values too */
6465
0
  LDAPMessage *result = NULL;
6466
0
  LDAPMessage *entry = NULL;
6467
6468
0
  filter = "(objectClass="LDAP_OBJ_TRUSTDOM_PASSWORD")";
6469
6470
0
  rc = smbldap_search(ldap_state->smbldap_state,
6471
0
          ldap_state->domain_dn,
6472
0
          scope,
6473
0
          filter,
6474
0
          attrs,
6475
0
          attrsonly,
6476
0
          &result);
6477
6478
0
  if (result != NULL) {
6479
0
    smbldap_talloc_autofree_ldapmsg(mem_ctx, result);
6480
0
  }
6481
6482
0
  if (rc != LDAP_SUCCESS) {
6483
0
    return NT_STATUS_UNSUCCESSFUL;
6484
0
  }
6485
6486
0
  *num_domains = 0;
6487
0
  if (!(*domains = talloc_array(mem_ctx, struct trustdom_info *, 1))) {
6488
0
    DEBUG(1, ("talloc failed\n"));
6489
0
    return NT_STATUS_NO_MEMORY;
6490
0
  }
6491
6492
0
  for (entry = ldap_first_entry(priv2ld(ldap_state), result);
6493
0
       entry != NULL;
6494
0
       entry = ldap_next_entry(priv2ld(ldap_state), entry))
6495
0
  {
6496
0
    char *dom_name, *dom_sid_str;
6497
0
    struct trustdom_info *dom_info;
6498
6499
0
    dom_info = talloc(*domains, struct trustdom_info);
6500
0
    if (dom_info == NULL) {
6501
0
      DEBUG(1, ("talloc failed\n"));
6502
0
      return NT_STATUS_NO_MEMORY;
6503
0
    }
6504
6505
0
    dom_name = smbldap_talloc_single_attribute(priv2ld(ldap_state),
6506
0
                 entry,
6507
0
                 "sambaDomainName",
6508
0
                 talloc_tos());
6509
0
    if (dom_name == NULL) {
6510
0
      DEBUG(1, ("talloc failed\n"));
6511
0
      return NT_STATUS_NO_MEMORY;
6512
0
    }
6513
0
    dom_info->name = dom_name;
6514
6515
0
    dom_sid_str = smbldap_talloc_single_attribute(
6516
0
          priv2ld(ldap_state), entry, "sambaSID",
6517
0
          talloc_tos());
6518
0
    if (dom_sid_str == NULL) {
6519
0
      DEBUG(1, ("talloc failed\n"));
6520
0
      return NT_STATUS_NO_MEMORY;
6521
0
    }
6522
0
    if (!string_to_sid(&dom_info->sid, dom_sid_str)) {
6523
0
      DEBUG(1, ("Error calling string_to_sid on SID %s\n",
6524
0
          dom_sid_str));
6525
0
      return NT_STATUS_UNSUCCESSFUL;
6526
0
    }
6527
6528
0
    ADD_TO_ARRAY(*domains, struct trustdom_info *, dom_info,
6529
0
           domains, num_domains);
6530
6531
0
    if (*domains == NULL) {
6532
0
      DEBUG(1, ("talloc failed\n"));
6533
0
      return NT_STATUS_NO_MEMORY;
6534
0
    }
6535
0
  }
6536
6537
0
  DEBUG(5, ("ldapsam_enum_trusteddoms: got %d domains\n", *num_domains));
6538
0
  return NT_STATUS_OK;
6539
0
}
6540
6541
6542
/**********************************************************************
6543
 Housekeeping
6544
 *********************************************************************/
6545
6546
static void free_private_data(void **vp)
6547
0
{
6548
0
  struct ldapsam_privates **ldap_state = (struct ldapsam_privates **)vp;
6549
6550
0
  smbldap_free_struct(&(*ldap_state)->smbldap_state);
6551
6552
0
  if ((*ldap_state)->result != NULL) {
6553
0
    ldap_msgfree((*ldap_state)->result);
6554
0
    (*ldap_state)->result = NULL;
6555
0
  }
6556
0
  if ((*ldap_state)->domain_dn != NULL) {
6557
0
    SAFE_FREE((*ldap_state)->domain_dn);
6558
0
  }
6559
6560
0
  *ldap_state = NULL;
6561
6562
  /* No need to free any further, as it is talloc()ed */
6563
0
}
6564
6565
/*********************************************************************
6566
 Initialise the parts of the pdb_methods structure that are common to
6567
 all pdb_ldap modes
6568
*********************************************************************/
6569
6570
static NTSTATUS pdb_init_ldapsam_common(struct pdb_methods **pdb_method, const char *location)
6571
0
{
6572
0
  NTSTATUS nt_status;
6573
0
  struct ldapsam_privates *ldap_state;
6574
0
  char *bind_dn = NULL;
6575
0
  char *bind_secret = NULL;
6576
6577
0
  if (!NT_STATUS_IS_OK(nt_status = make_pdb_method( pdb_method ))) {
6578
0
    return nt_status;
6579
0
  }
6580
6581
0
  (*pdb_method)->name = "ldapsam";
6582
6583
0
  (*pdb_method)->getsampwnam = ldapsam_getsampwnam;
6584
0
  (*pdb_method)->getsampwsid = ldapsam_getsampwsid;
6585
0
  (*pdb_method)->add_sam_account = ldapsam_add_sam_account;
6586
0
  (*pdb_method)->update_sam_account = ldapsam_update_sam_account;
6587
0
  (*pdb_method)->delete_sam_account = ldapsam_delete_sam_account;
6588
0
  (*pdb_method)->rename_sam_account = ldapsam_rename_sam_account;
6589
6590
0
  (*pdb_method)->getgrsid = ldapsam_getgrsid;
6591
0
  (*pdb_method)->getgrgid = ldapsam_getgrgid;
6592
0
  (*pdb_method)->getgrnam = ldapsam_getgrnam;
6593
0
  (*pdb_method)->add_group_mapping_entry = ldapsam_add_group_mapping_entry;
6594
0
  (*pdb_method)->update_group_mapping_entry = ldapsam_update_group_mapping_entry;
6595
0
  (*pdb_method)->delete_group_mapping_entry = ldapsam_delete_group_mapping_entry;
6596
0
  (*pdb_method)->enum_group_mapping = ldapsam_enum_group_mapping;
6597
6598
0
  (*pdb_method)->get_account_policy = ldapsam_get_account_policy;
6599
0
  (*pdb_method)->set_account_policy = ldapsam_set_account_policy;
6600
6601
0
  (*pdb_method)->get_seq_num = ldapsam_get_seq_num;
6602
6603
0
  (*pdb_method)->capabilities = ldapsam_capabilities;
6604
0
  (*pdb_method)->new_rid = ldapsam_new_rid;
6605
6606
0
  (*pdb_method)->get_trusteddom_pw = ldapsam_get_trusteddom_pw;
6607
0
  (*pdb_method)->set_trusteddom_pw = ldapsam_set_trusteddom_pw;
6608
0
  (*pdb_method)->del_trusteddom_pw = ldapsam_del_trusteddom_pw;
6609
0
  (*pdb_method)->enum_trusteddoms = ldapsam_enum_trusteddoms;
6610
6611
  /* TODO: Setup private data and free */
6612
6613
0
  if ( !(ldap_state = talloc_zero(*pdb_method, struct ldapsam_privates)) ) {
6614
0
    DEBUG(0, ("pdb_init_ldapsam_common: talloc() failed for ldapsam private_data!\n"));
6615
0
    return NT_STATUS_NO_MEMORY;
6616
0
  }
6617
6618
0
  if (!fetch_ldap_pw(&bind_dn, &bind_secret)) {
6619
0
    DEBUG(0, ("pdb_init_ldapsam_common: Failed to retrieve LDAP password from secrets.tdb\n"));
6620
0
    return NT_STATUS_NO_MEMORY;
6621
0
  }
6622
6623
0
  nt_status = smbldap_init(*pdb_method, pdb_get_tevent_context(),
6624
0
         location, false, bind_dn, bind_secret,
6625
0
         &ldap_state->smbldap_state);
6626
0
  BURN_FREE_STR(bind_secret);
6627
0
  SAFE_FREE(bind_dn);
6628
0
  if ( !NT_STATUS_IS_OK(nt_status) ) {
6629
0
    return nt_status;
6630
0
  }
6631
6632
0
  if ( !(ldap_state->domain_name = talloc_strdup(*pdb_method, get_global_sam_name()) ) ) {
6633
0
    return NT_STATUS_NO_MEMORY;
6634
0
  }
6635
6636
0
  (*pdb_method)->private_data = ldap_state;
6637
6638
0
  (*pdb_method)->free_private_data = free_private_data;
6639
6640
0
  return NT_STATUS_OK;
6641
0
}
6642
6643
static bool ldapsam_is_responsible_for_wellknown(struct pdb_methods *m)
6644
0
{
6645
0
  return true;
6646
0
}
6647
6648
/**********************************************************************
6649
 Initialise the normal mode for pdb_ldap
6650
 *********************************************************************/
6651
6652
NTSTATUS pdb_ldapsam_init_common(struct pdb_methods **pdb_method,
6653
         const char *location)
6654
0
{
6655
0
  NTSTATUS nt_status;
6656
0
  struct ldapsam_privates *ldap_state = NULL;
6657
0
  uint32_t alg_rid_base;
6658
0
  char *alg_rid_base_string = NULL;
6659
0
  LDAPMessage *result = NULL;
6660
0
  LDAPMessage *entry = NULL;
6661
0
  struct dom_sid ldap_domain_sid;
6662
0
  struct dom_sid secrets_domain_sid;
6663
0
  char *domain_sid_string = NULL;
6664
0
  char *dn = NULL;
6665
0
  char *uri = talloc_strdup( NULL, location );
6666
6667
0
  trim_char( uri, '\"', '\"' );
6668
0
  nt_status = pdb_init_ldapsam_common(pdb_method, uri);
6669
6670
0
  TALLOC_FREE(uri);
6671
6672
0
  if (!NT_STATUS_IS_OK(nt_status)) {
6673
0
    return nt_status;
6674
0
  }
6675
6676
0
  (*pdb_method)->name = "ldapsam";
6677
6678
0
  (*pdb_method)->add_aliasmem = ldapsam_add_aliasmem;
6679
0
  (*pdb_method)->del_aliasmem = ldapsam_del_aliasmem;
6680
0
  (*pdb_method)->enum_aliasmem = ldapsam_enum_aliasmem;
6681
0
  (*pdb_method)->enum_alias_memberships = ldapsam_alias_memberships;
6682
0
  (*pdb_method)->search_users = ldapsam_search_users;
6683
0
  (*pdb_method)->search_groups = ldapsam_search_groups;
6684
0
  (*pdb_method)->search_aliases = ldapsam_search_aliases;
6685
0
  (*pdb_method)->is_responsible_for_wellknown =
6686
0
          ldapsam_is_responsible_for_wellknown;
6687
6688
0
  if (lp_parm_bool(-1, "ldapsam", "trusted", False)) {
6689
0
    (*pdb_method)->enum_group_members = ldapsam_enum_group_members;
6690
0
    (*pdb_method)->enum_group_memberships =
6691
0
      ldapsam_enum_group_memberships;
6692
0
    (*pdb_method)->lookup_rids = ldapsam_lookup_rids;
6693
0
    (*pdb_method)->sid_to_id = ldapsam_sid_to_id;
6694
0
    (*pdb_method)->id_to_sid = ldapsam_id_to_sid;
6695
6696
0
    if (lp_parm_bool(-1, "ldapsam", "editposix", False)) {
6697
0
      (*pdb_method)->create_user = ldapsam_create_user;
6698
0
      (*pdb_method)->delete_user = ldapsam_delete_user;
6699
0
      (*pdb_method)->create_dom_group = ldapsam_create_dom_group;
6700
0
      (*pdb_method)->delete_dom_group = ldapsam_delete_dom_group;
6701
0
      (*pdb_method)->add_groupmem = ldapsam_add_groupmem;
6702
0
      (*pdb_method)->del_groupmem = ldapsam_del_groupmem;
6703
0
      (*pdb_method)->set_unix_primary_group = ldapsam_set_primary_group;
6704
0
    }
6705
0
  }
6706
6707
0
  ldap_state = (struct ldapsam_privates *)((*pdb_method)->private_data);
6708
0
  ldap_state->schema_ver = SCHEMAVER_SAMBASAMACCOUNT;
6709
6710
  /* Try to setup the Domain Name, Domain SID, algorithmic rid base */
6711
6712
0
  nt_status = smbldap_search_domain_info(ldap_state->smbldap_state,
6713
0
                 &result,
6714
0
                 ldap_state->domain_name, True);
6715
6716
0
  if ( !NT_STATUS_IS_OK(nt_status) ) {
6717
0
    DEBUG(0, ("pdb_init_ldapsam: WARNING: Could not get domain "
6718
0
        "info, nor add one to the domain. "
6719
0
        "We cannot work reliably without it.\n"));
6720
0
    return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
6721
0
  }
6722
6723
  /* Given that the above might fail, everything below this must be
6724
   * optional */
6725
6726
0
  entry = ldap_first_entry(smbldap_get_ldap(ldap_state->smbldap_state),
6727
0
         result);
6728
0
  if (!entry) {
6729
0
    DEBUG(0, ("pdb_init_ldapsam: Could not get domain info "
6730
0
        "entry\n"));
6731
0
    ldap_msgfree(result);
6732
0
    return NT_STATUS_UNSUCCESSFUL;
6733
0
  }
6734
6735
0
  dn = smbldap_talloc_dn(talloc_tos(),
6736
0
             smbldap_get_ldap(ldap_state->smbldap_state),
6737
0
             entry);
6738
0
  if (!dn) {
6739
0
    ldap_msgfree(result);
6740
0
    return NT_STATUS_UNSUCCESSFUL;
6741
0
  }
6742
6743
0
  ldap_state->domain_dn = smb_xstrdup(dn);
6744
0
  TALLOC_FREE(dn);
6745
6746
0
  domain_sid_string = smbldap_talloc_single_attribute(
6747
0
        smbldap_get_ldap(ldap_state->smbldap_state),
6748
0
        entry,
6749
0
        get_userattr_key2string(ldap_state->schema_ver,
6750
0
              LDAP_ATTR_USER_SID),
6751
0
        talloc_tos());
6752
6753
0
  if (domain_sid_string) {
6754
0
    bool found_sid;
6755
0
    if (!string_to_sid(&ldap_domain_sid, domain_sid_string)) {
6756
0
      DEBUG(1, ("pdb_init_ldapsam: SID [%s] could not be "
6757
0
          "read as a valid SID\n", domain_sid_string));
6758
0
      ldap_msgfree(result);
6759
0
      TALLOC_FREE(domain_sid_string);
6760
0
      return NT_STATUS_INVALID_PARAMETER;
6761
0
    }
6762
0
    found_sid = PDB_secrets_fetch_domain_sid(ldap_state->domain_name,
6763
0
                 &secrets_domain_sid);
6764
0
    if (!found_sid || !dom_sid_equal(&secrets_domain_sid,
6765
0
               &ldap_domain_sid)) {
6766
0
      struct dom_sid_buf buf1, buf2;
6767
0
      DEBUG(1, ("pdb_init_ldapsam: Resetting SID for domain "
6768
0
          "%s based on pdb_ldap results %s -> %s\n",
6769
0
          ldap_state->domain_name,
6770
0
          dom_sid_str_buf(&secrets_domain_sid, &buf1),
6771
0
          dom_sid_str_buf(&ldap_domain_sid, &buf2)));
6772
6773
      /* reset secrets.tdb sid */
6774
0
      PDB_secrets_store_domain_sid(ldap_state->domain_name,
6775
0
             &ldap_domain_sid);
6776
0
      DEBUG(1, ("New global sam SID: %s\n",
6777
0
          dom_sid_str_buf(get_global_sam_sid(),
6778
0
              &buf1)));
6779
0
    }
6780
0
    sid_copy(&ldap_state->domain_sid, &ldap_domain_sid);
6781
0
    TALLOC_FREE(domain_sid_string);
6782
0
  }
6783
6784
0
  alg_rid_base_string = smbldap_talloc_single_attribute(
6785
0
        smbldap_get_ldap(ldap_state->smbldap_state),
6786
0
        entry,
6787
0
        get_attr_key2string( dominfo_attr_list,
6788
0
           LDAP_ATTR_ALGORITHMIC_RID_BASE ),
6789
0
        talloc_tos());
6790
0
  if (alg_rid_base_string) {
6791
0
    alg_rid_base = (uint32_t)atol(alg_rid_base_string);
6792
0
    if (alg_rid_base != algorithmic_rid_base()) {
6793
0
      DEBUG(0, ("The value of 'algorithmic RID base' has "
6794
0
          "changed since the LDAP\n"
6795
0
          "database was initialised.  Aborting. \n"));
6796
0
      ldap_msgfree(result);
6797
0
      TALLOC_FREE(alg_rid_base_string);
6798
0
      return NT_STATUS_UNSUCCESSFUL;
6799
0
    }
6800
0
    TALLOC_FREE(alg_rid_base_string);
6801
0
  }
6802
0
  ldap_msgfree(result);
6803
6804
0
  return NT_STATUS_OK;
6805
0
}
6806
6807
NTSTATUS pdb_ldapsam_init(TALLOC_CTX *ctx)
6808
0
{
6809
0
  NTSTATUS nt_status;
6810
6811
0
  nt_status = smb_register_passdb(PASSDB_INTERFACE_VERSION,
6812
0
          "ldapsam",
6813
0
          pdb_ldapsam_init_common);
6814
0
  if (!NT_STATUS_IS_OK(nt_status)) {
6815
0
    return nt_status;
6816
0
  }
6817
6818
  /* Let pdb_nds register backends */
6819
0
  pdb_nds_init(ctx);
6820
6821
0
  return NT_STATUS_OK;
6822
0
}