Coverage Report

Created: 2026-04-01 06:26

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/samba/source3/passdb/passdb.c
Line
Count
Source
1
/*
2
   Unix SMB/CIFS implementation.
3
   Password and authentication handling
4
   Copyright (C) Jeremy Allison     1996-2001
5
   Copyright (C) Luke Kenneth Casson Leighton   1996-1998
6
   Copyright (C) Gerald (Jerry) Carter    2000-2006
7
   Copyright (C) Andrew Bartlett    2001-2002
8
   Copyright (C) Simo Sorce     2003
9
   Copyright (C) Volker Lendecke    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
#include "includes.h"
26
#include "passdb.h"
27
#include "system/passwd.h"
28
#include "../libcli/auth/libcli_auth.h"
29
#include "secrets.h"
30
#include "../libcli/security/security.h"
31
#include "../lib/util/util_pw.h"
32
#include "util_tdb.h"
33
#include "auth/credentials/credentials.h"
34
#include "lib/param/param.h"
35
#include "lib/util/string_wrappers.h"
36
#include "source3/lib/substitute.h"
37
38
#undef DBGC_CLASS
39
0
#define DBGC_CLASS DBGC_PASSDB
40
41
/**********************************************************************
42
***********************************************************************/
43
44
static int samu_destroy(struct samu *user)
45
0
{
46
0
  data_blob_clear_free( &user->lm_pw );
47
0
  data_blob_clear_free( &user->nt_pw );
48
49
0
  if ( user->plaintext_pw )
50
0
    BURN_STR(user->plaintext_pw);
51
52
0
  return 0;
53
0
}
54
55
/**********************************************************************
56
 generate a new struct samuser
57
***********************************************************************/
58
59
struct samu *samu_new( TALLOC_CTX *ctx )
60
0
{
61
0
  struct samu *user;
62
63
0
  if ( !(user = talloc_zero( ctx, struct samu )) ) {
64
0
    DEBUG(0,("samuser_new: Talloc failed!\n"));
65
0
    return NULL;
66
0
  }
67
68
0
  talloc_set_destructor( user, samu_destroy );
69
70
  /* no initial methods */
71
72
0
  user->methods = NULL;
73
74
        /* Don't change these timestamp settings without a good reason.
75
           They are important for NT member server compatibility. */
76
77
0
  user->logon_time            = (time_t)0;
78
0
  user->pass_last_set_time    = (time_t)0;
79
0
  user->pass_can_change_time  = (time_t)0;
80
0
  user->logoff_time           = get_time_t_max();
81
0
  user->kickoff_time          = get_time_t_max();
82
0
  user->fields_present        = 0x00ffffff;
83
0
  user->logon_divs = 168;   /* hours per week */
84
0
  user->hours_len = 21;     /* 21 times 8 bits = 168 */
85
0
  memset(user->hours, 0xff, user->hours_len); /* available at all hours */
86
0
  user->bad_password_count = 0;
87
0
  user->logon_count = 0;
88
0
  user->unknown_6 = 0x000004ec; /* don't know */
89
90
  /* Some parts of samba strlen their pdb_get...() returns,
91
     so this keeps the interface unchanged for now. */
92
93
0
  user->username = "";
94
0
  user->domain = "";
95
0
  user->nt_username = "";
96
0
  user->full_name = "";
97
0
  user->home_dir = "";
98
0
  user->logon_script = "";
99
0
  user->profile_path = "";
100
0
  user->acct_desc = "";
101
0
  user->workstations = "";
102
0
  user->comment = "";
103
0
  user->munged_dial = "";
104
105
0
  user->plaintext_pw = NULL;
106
107
  /* Unless we know otherwise have a Account Control Bit
108
     value of 'normal user'.  This helps User Manager, which
109
     asks for a filtered list of users. */
110
111
0
  user->acct_ctrl = ACB_NORMAL;
112
113
0
  return user;
114
0
}
115
116
static int count_commas(const char *str)
117
0
{
118
0
  int num_commas = 0;
119
0
  const char *comma = str;
120
121
0
  while ((comma = strchr(comma, ',')) != NULL) {
122
0
    comma += 1;
123
0
    num_commas += 1;
124
0
  }
125
0
  return num_commas;
126
0
}
127
128
/*********************************************************************
129
 Initialize a struct samu from a struct passwd including the user
130
 and group SIDs.  The *user structure is filled out with the Unix
131
 attributes and a user SID.
132
*********************************************************************/
133
134
static NTSTATUS samu_set_unix_internal(struct pdb_methods *methods,
135
               struct samu *user, const struct passwd *pwd, bool create)
136
0
{
137
0
  const char *guest_account = lp_guest_account();
138
0
  const char *domain = lp_netbios_name();
139
0
  char *fullname;
140
0
  uint32_t urid;
141
0
  bool ok;
142
143
0
  if ( !pwd ) {
144
0
    return NT_STATUS_NO_SUCH_USER;
145
0
  }
146
147
  /* Basic properties based upon the Unix account information */
148
149
0
  ok = pdb_set_username(user, pwd->pw_name, PDB_SET);
150
0
  if (!ok) {
151
0
    return NT_STATUS_NO_MEMORY;
152
0
  }
153
154
0
  fullname = NULL;
155
156
0
  if (count_commas(pwd->pw_gecos) == 3) {
157
    /*
158
     * Heuristic: This seems to be a gecos field that has been
159
     * edited by chfn(1). Only use the part before the first
160
     * comma. Fixes bug 5198.
161
     */
162
0
    fullname = talloc_strndup(
163
0
      talloc_tos(), pwd->pw_gecos,
164
0
      strchr(pwd->pw_gecos, ',') - pwd->pw_gecos);
165
0
    if (fullname == NULL) {
166
0
      return NT_STATUS_NO_MEMORY;
167
0
    }
168
0
  }
169
170
0
  if (fullname != NULL) {
171
0
    ok = pdb_set_fullname(user, fullname, PDB_SET);
172
0
  } else {
173
0
    ok = pdb_set_fullname(user, pwd->pw_gecos, PDB_SET);
174
0
  }
175
0
  TALLOC_FREE(fullname);
176
177
0
  if (!ok) {
178
0
    return NT_STATUS_NO_MEMORY;
179
0
  }
180
181
0
  ok = pdb_set_domain(user, get_global_sam_name(), PDB_DEFAULT);
182
0
  if (!ok) {
183
0
    return NT_STATUS_NO_MEMORY;
184
0
  }
185
#if 0
186
  /* This can lead to a primary group of S-1-22-2-XX which
187
     will be rejected by other parts of the Samba code.
188
     Rely on pdb_get_group_sid() to "Do The Right Thing" (TM)
189
     --jerry */
190
191
  gid_to_sid(&group_sid, pwd->pw_gid);
192
  pdb_set_group_sid(user, &group_sid, PDB_SET);
193
#endif
194
195
  /* save the password structure for later use */
196
197
0
  user->unix_pw = tcopy_passwd( user, pwd );
198
0
  if (user->unix_pw == NULL) {
199
0
    return NT_STATUS_NO_MEMORY;
200
0
  }
201
202
  /* Special case for the guest account which must have a RID of 501 */
203
204
0
  if ( strequal( pwd->pw_name, guest_account ) ) {
205
0
    if ( !pdb_set_user_sid_from_rid(user, DOMAIN_RID_GUEST, PDB_DEFAULT)) {
206
0
      return NT_STATUS_NO_SUCH_USER;
207
0
    }
208
0
    return NT_STATUS_OK;
209
0
  }
210
211
  /* Non-guest accounts...Check for a workstation or user account */
212
213
0
  if (pwd->pw_name[strlen(pwd->pw_name)-1] == '$') {
214
    /* workstation */
215
216
0
    if (!pdb_set_acct_ctrl(user, ACB_WSTRUST, PDB_DEFAULT)) {
217
0
      DEBUG(1, ("Failed to set 'workstation account' flags for user %s.\n",
218
0
        pwd->pw_name));
219
0
      return NT_STATUS_INVALID_COMPUTER_NAME;
220
0
    }
221
0
  }
222
0
  else {
223
    /* user */
224
225
0
    if (!pdb_set_acct_ctrl(user, ACB_NORMAL, PDB_DEFAULT)) {
226
0
      DEBUG(1, ("Failed to set 'normal account' flags for user %s.\n",
227
0
        pwd->pw_name));
228
0
      return NT_STATUS_INVALID_ACCOUNT_NAME;
229
0
    }
230
231
    /* set some basic attributes */
232
233
0
    ok = pdb_set_profile_path(
234
0
      user,
235
0
      talloc_sub_specified(
236
0
        user,
237
0
        lp_logon_path(),
238
0
        pwd->pw_name,
239
0
        NULL,
240
0
        domain,
241
0
        pwd->pw_uid,
242
0
        pwd->pw_gid),
243
0
      PDB_DEFAULT);
244
0
    ok &= pdb_set_homedir(
245
0
      user,
246
0
      talloc_sub_specified(
247
0
        user,
248
0
        lp_logon_home(),
249
0
        pwd->pw_name,
250
0
        NULL,
251
0
        domain,
252
0
        pwd->pw_uid,
253
0
        pwd->pw_gid),
254
0
      PDB_DEFAULT);
255
0
    ok &= pdb_set_dir_drive(
256
0
      user,
257
0
      talloc_sub_specified(
258
0
        user,
259
0
        lp_logon_drive(),
260
0
        pwd->pw_name,
261
0
        NULL,
262
0
        domain,
263
0
        pwd->pw_uid,
264
0
        pwd->pw_gid),
265
0
      PDB_DEFAULT);
266
0
    ok &= pdb_set_logon_script(
267
0
      user,
268
0
      talloc_sub_specified(
269
0
        user,
270
0
        lp_logon_script(),
271
0
        pwd->pw_name,
272
0
        NULL,
273
0
        domain,
274
0
        pwd->pw_uid,
275
0
        pwd->pw_gid),
276
0
      PDB_DEFAULT);
277
0
    if (!ok) {
278
0
      return NT_STATUS_NO_MEMORY;
279
0
    }
280
0
  }
281
282
  /* Now deal with the user SID.  If we have a backend that can generate
283
     RIDs, then do so.  But sometimes the caller just wanted a structure
284
     initialized and will fill in these fields later (such as from a
285
     netr_SamInfo3 structure) */
286
287
0
  if ( create && (methods->capabilities(methods) & PDB_CAP_STORE_RIDS)) {
288
0
    uint32_t user_rid;
289
0
    struct dom_sid user_sid;
290
291
0
    if ( !methods->new_rid(methods, &user_rid) ) {
292
0
      DEBUG(3, ("Could not allocate a new RID\n"));
293
0
      return NT_STATUS_ACCESS_DENIED;
294
0
    }
295
296
0
    sid_compose(&user_sid, get_global_sam_sid(), user_rid);
297
298
0
    if ( !pdb_set_user_sid(user, &user_sid, PDB_SET) ) {
299
0
      DEBUG(3, ("pdb_set_user_sid failed\n"));
300
0
      return NT_STATUS_INTERNAL_ERROR;
301
0
    }
302
303
0
    return NT_STATUS_OK;
304
0
  }
305
306
  /* generate a SID for the user with the RID algorithm */
307
308
0
  urid = algorithmic_pdb_uid_to_user_rid( user->unix_pw->pw_uid );
309
310
0
  if ( !pdb_set_user_sid_from_rid( user, urid, PDB_SET) ) {
311
0
    return NT_STATUS_INTERNAL_ERROR;
312
0
  }
313
314
0
  return NT_STATUS_OK;
315
0
}
316
317
/********************************************************************
318
 Set the Unix user attributes
319
********************************************************************/
320
321
NTSTATUS samu_set_unix(struct samu *user, const struct passwd *pwd)
322
0
{
323
0
  return samu_set_unix_internal( NULL, user, pwd, False );
324
0
}
325
326
NTSTATUS samu_alloc_rid_unix(struct pdb_methods *methods,
327
           struct samu *user, const struct passwd *pwd)
328
0
{
329
0
  return samu_set_unix_internal( methods, user, pwd, True );
330
0
}
331
332
/**********************************************************
333
 Encode the account control bits into a string.
334
 length = length of string to encode into (including terminating
335
 null). length *MUST BE MORE THAN 2* !
336
 **********************************************************/
337
338
char *pdb_encode_acct_ctrl(uint32_t acct_ctrl, size_t length)
339
0
{
340
0
  fstring acct_str;
341
0
  char *result;
342
343
0
  size_t i = 0;
344
345
0
  SMB_ASSERT(length <= sizeof(acct_str));
346
347
0
  acct_str[i++] = '[';
348
349
0
  if (acct_ctrl & ACB_PWNOTREQ ) acct_str[i++] = 'N';
350
0
  if (acct_ctrl & ACB_DISABLED ) acct_str[i++] = 'D';
351
0
  if (acct_ctrl & ACB_HOMDIRREQ) acct_str[i++] = 'H';
352
0
  if (acct_ctrl & ACB_TEMPDUP  ) acct_str[i++] = 'T';
353
0
  if (acct_ctrl & ACB_NORMAL   ) acct_str[i++] = 'U';
354
0
  if (acct_ctrl & ACB_MNS      ) acct_str[i++] = 'M';
355
0
  if (acct_ctrl & ACB_WSTRUST  ) acct_str[i++] = 'W';
356
0
  if (acct_ctrl & ACB_SVRTRUST ) acct_str[i++] = 'S';
357
0
  if (acct_ctrl & ACB_AUTOLOCK ) acct_str[i++] = 'L';
358
0
  if (acct_ctrl & ACB_PWNOEXP  ) acct_str[i++] = 'X';
359
0
  if (acct_ctrl & ACB_DOMTRUST ) acct_str[i++] = 'I';
360
361
0
  for ( ; i < length - 2 ; i++ )
362
0
    acct_str[i] = ' ';
363
364
0
  i = length - 2;
365
0
  acct_str[i++] = ']';
366
0
  acct_str[i++] = '\0';
367
368
0
  result = talloc_strdup(talloc_tos(), acct_str);
369
0
  SMB_ASSERT(result != NULL);
370
0
  return result;
371
0
}
372
373
/**********************************************************
374
 Decode the account control bits from a string.
375
 **********************************************************/
376
377
uint32_t pdb_decode_acct_ctrl(const char *p)
378
0
{
379
0
  uint32_t acct_ctrl = 0;
380
0
  bool finished = false;
381
382
  /*
383
   * Check if the account type bits have been encoded after the
384
   * NT password (in the form [NDHTUWSLXI]).
385
   */
386
387
0
  if (*p != '[')
388
0
    return 0;
389
390
0
  for (p++; *p && !finished; p++) {
391
0
    switch (*p) {
392
0
      case 'N': { acct_ctrl |= ACB_PWNOTREQ ; break; /* 'N'o password. */ }
393
0
      case 'D': { acct_ctrl |= ACB_DISABLED ; break; /* 'D'isabled. */ }
394
0
      case 'H': { acct_ctrl |= ACB_HOMDIRREQ; break; /* 'H'omedir required. */ }
395
0
      case 'T': { acct_ctrl |= ACB_TEMPDUP  ; break; /* 'T'emp account. */ }
396
0
      case 'U': { acct_ctrl |= ACB_NORMAL   ; break; /* 'U'ser account (normal). */ }
397
0
      case 'M': { acct_ctrl |= ACB_MNS      ; break; /* 'M'NS logon user account. What is this ? */ }
398
0
      case 'W': { acct_ctrl |= ACB_WSTRUST  ; break; /* 'W'orkstation account. */ }
399
0
      case 'S': { acct_ctrl |= ACB_SVRTRUST ; break; /* 'S'erver account. */ }
400
0
      case 'L': { acct_ctrl |= ACB_AUTOLOCK ; break; /* 'L'ocked account. */ }
401
0
      case 'X': { acct_ctrl |= ACB_PWNOEXP  ; break; /* No 'X'piry on password */ }
402
0
      case 'I': { acct_ctrl |= ACB_DOMTRUST ; break; /* 'I'nterdomain trust account. */ }
403
0
            case ' ': { break; }
404
0
      case ':':
405
0
      case '\n':
406
0
      case '\0':
407
0
      case ']':
408
0
      default:  { finished = true; }
409
0
    }
410
0
  }
411
412
0
  return acct_ctrl;
413
0
}
414
415
/*************************************************************
416
 Routine to set 32 hex password characters from a 16 byte array.
417
**************************************************************/
418
419
void pdb_sethexpwd(char p[33], const unsigned char *pwd, uint32_t acct_ctrl)
420
0
{
421
0
  if (pwd != NULL) {
422
0
    hex_encode_buf(p, pwd, 16);
423
0
  } else {
424
0
    if (acct_ctrl & ACB_PWNOTREQ)
425
0
      strlcpy(p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 33);
426
0
    else
427
0
      strlcpy(p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 33);
428
0
  }
429
0
}
430
431
/*************************************************************
432
 Routine to get the 32 hex characters and turn them
433
 into a 16 byte array.
434
**************************************************************/
435
436
bool pdb_gethexpwd(const char *p, unsigned char *pwd)
437
0
{
438
0
  int i;
439
440
0
  if (!p)
441
0
    return false;
442
443
0
  for (i = 0; i < 32; i += 2) {
444
0
    bool ok = hex_byte(p + i, &pwd[i / 2]);
445
0
    if (!ok) {
446
0
      return false;
447
0
    }
448
0
  }
449
0
  return true;
450
0
}
451
452
/*************************************************************
453
 Routine to set 42 hex hours characters from a 21 byte array.
454
**************************************************************/
455
456
void pdb_sethexhours(char *p, const unsigned char *hours)
457
0
{
458
0
  if (hours != NULL) {
459
0
    hex_encode_buf(p, hours, 21);
460
0
  } else {
461
0
    strlcpy(p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 44);
462
0
  }
463
0
}
464
465
/*************************************************************
466
 Routine to get the 42 hex characters and turn them
467
 into a 21 byte array.
468
**************************************************************/
469
470
bool pdb_gethexhours(const char *p, unsigned char *hours)
471
0
{
472
0
  int i;
473
474
0
  if (!p) {
475
0
    return (False);
476
0
  }
477
478
0
  for (i = 0; i < 42; i += 2) {
479
0
    bool ok = hex_byte(p, (uint8_t *)&hours[i / 2]);
480
0
    if (!ok) {
481
0
      return false;
482
0
    }
483
0
  }
484
0
  return (True);
485
0
}
486
487
/********************************************************************
488
********************************************************************/
489
490
int algorithmic_rid_base(void)
491
0
{
492
0
  int rid_offset;
493
494
0
  rid_offset = lp_algorithmic_rid_base();
495
496
0
  if (rid_offset < BASE_RID) {
497
    /* Try to prevent admin foot-shooting, we can't put algorithmic
498
       rids below 1000, that's the 'well known RIDs' on NT */
499
0
    DEBUG(0, ("'algorithmic rid base' must be equal to or above %ld\n", BASE_RID));
500
0
    rid_offset = BASE_RID;
501
0
  }
502
0
  if (rid_offset & 1) {
503
0
    DEBUG(0, ("algorithmic rid base must be even\n"));
504
0
    rid_offset += 1;
505
0
  }
506
0
  return rid_offset;
507
0
}
508
509
/*******************************************************************
510
 Converts NT user RID to a UNIX uid.
511
 ********************************************************************/
512
513
uid_t algorithmic_pdb_user_rid_to_uid(uint32_t user_rid)
514
0
{
515
0
  int rid_offset = algorithmic_rid_base();
516
0
  return (uid_t)(((user_rid & (~USER_RID_TYPE)) - rid_offset)/RID_MULTIPLIER);
517
0
}
518
519
uid_t max_algorithmic_uid(void)
520
0
{
521
0
  return algorithmic_pdb_user_rid_to_uid(0xfffffffe);
522
0
}
523
524
/*******************************************************************
525
 converts UNIX uid to an NT User RID.
526
 ********************************************************************/
527
528
uint32_t algorithmic_pdb_uid_to_user_rid(uid_t uid)
529
0
{
530
0
  int rid_offset = algorithmic_rid_base();
531
0
  return (((((uint32_t)uid)*RID_MULTIPLIER) + rid_offset) | USER_RID_TYPE);
532
0
}
533
534
/*******************************************************************
535
 Converts NT group RID to a UNIX gid.
536
 ********************************************************************/
537
538
gid_t pdb_group_rid_to_gid(uint32_t group_rid)
539
0
{
540
0
  int rid_offset = algorithmic_rid_base();
541
0
  return (gid_t)(((group_rid & (~GROUP_RID_TYPE))- rid_offset)/RID_MULTIPLIER);
542
0
}
543
544
gid_t max_algorithmic_gid(void)
545
0
{
546
0
  return pdb_group_rid_to_gid(0xffffffff);
547
0
}
548
549
/*******************************************************************
550
 converts NT Group RID to a UNIX uid.
551
552
 warning: you must not call that function only
553
 you must do a call to the group mapping first.
554
 there is not anymore a direct link between the gid and the rid.
555
 ********************************************************************/
556
557
uint32_t algorithmic_pdb_gid_to_group_rid(gid_t gid)
558
0
{
559
0
  int rid_offset = algorithmic_rid_base();
560
0
  return (((((uint32_t)gid)*RID_MULTIPLIER) + rid_offset) | GROUP_RID_TYPE);
561
0
}
562
563
/*******************************************************************
564
 Decides if a RID is a well known RID.
565
 ********************************************************************/
566
567
static bool rid_is_well_known(uint32_t rid)
568
0
{
569
  /* Not using rid_offset here, because this is the actual
570
     NT fixed value (1000) */
571
572
0
  return (rid < BASE_RID);
573
0
}
574
575
/*******************************************************************
576
 Decides if a RID is a user or group RID.
577
 ********************************************************************/
578
579
bool algorithmic_pdb_rid_is_user(uint32_t rid)
580
0
{
581
0
  if ( rid_is_well_known(rid) ) {
582
    /*
583
     * The only well known user RIDs are DOMAIN_RID_ADMINISTRATOR
584
     * and DOMAIN_RID_GUEST.
585
     */
586
0
    if(rid == DOMAIN_RID_ADMINISTRATOR || rid == DOMAIN_RID_GUEST)
587
0
      return True;
588
0
  } else if((rid & RID_TYPE_MASK) == USER_RID_TYPE) {
589
0
    return True;
590
0
  }
591
0
  return False;
592
0
}
593
594
/*******************************************************************
595
 Convert a name into a SID. Used in the lookup name rpc.
596
 ********************************************************************/
597
598
bool lookup_global_sam_name(const char *name, int flags, uint32_t *rid,
599
          enum lsa_SidType *type)
600
0
{
601
0
  GROUP_MAP *map;
602
0
  bool ret;
603
604
  /* Windows treats "MACHINE\None" as a special name for
605
     rid 513 on non-DCs.  You cannot create a user or group
606
     name "None" on Windows.  You will get an error that
607
     the group already exists. */
608
609
0
  if ( strequal( name, "None" ) ) {
610
0
    *rid = DOMAIN_RID_USERS;
611
0
    *type = SID_NAME_DOM_GRP;
612
613
0
    return True;
614
0
  }
615
616
  /* LOOKUP_NAME_GROUP is a hack to allow valid users = @foo to work
617
   * correctly in the case where foo also exists as a user. If the flag
618
   * is set, don't look for users at all. */
619
620
0
  if ((flags & LOOKUP_NAME_GROUP) == 0) {
621
0
    struct samu *sam_account = NULL;
622
0
    struct dom_sid user_sid;
623
624
0
    if ( !(sam_account = samu_new( NULL )) ) {
625
0
      return False;
626
0
    }
627
628
0
    become_root();
629
0
    ret =  pdb_getsampwnam(sam_account, name);
630
0
    unbecome_root();
631
632
0
    if (ret) {
633
0
      sid_copy(&user_sid, pdb_get_user_sid(sam_account));
634
0
    }
635
636
0
    TALLOC_FREE(sam_account);
637
638
0
    if (ret) {
639
0
      if (!sid_check_is_in_our_sam(&user_sid)) {
640
0
        struct dom_sid_buf buf;
641
0
        DBG_ERR("User %s with invalid SID %s"
642
0
          " in passdb\n",
643
0
          name,
644
0
          dom_sid_str_buf(&user_sid, &buf));
645
0
        return False;
646
0
      }
647
648
0
      sid_peek_rid(&user_sid, rid);
649
0
      *type = SID_NAME_USER;
650
0
      return True;
651
0
    }
652
0
  }
653
654
  /*
655
   * Maybe it is a group ?
656
   */
657
658
0
  map = talloc_zero(NULL, GROUP_MAP);
659
0
  if (!map) {
660
0
    return false;
661
0
  }
662
663
0
  become_root();
664
0
  ret = pdb_getgrnam(map, name);
665
0
  unbecome_root();
666
667
0
  if (!ret) {
668
0
    TALLOC_FREE(map);
669
0
    return False;
670
0
  }
671
672
  /* BUILTIN groups are looked up elsewhere */
673
0
  if (!sid_check_is_in_our_sam(&map->sid)) {
674
0
    struct dom_sid_buf buf;
675
0
    DEBUG(10, ("Found group %s (%s) not in our domain -- "
676
0
         "ignoring.\n",
677
0
         name,
678
0
         dom_sid_str_buf(&map->sid, &buf)));
679
0
    TALLOC_FREE(map);
680
0
    return False;
681
0
  }
682
683
  /* yes it's a mapped group */
684
0
  sid_peek_rid(&map->sid, rid);
685
0
  *type = map->sid_name_use;
686
0
  TALLOC_FREE(map);
687
0
  return True;
688
0
}
689
690
/*************************************************************
691
 Change a password entry in the local passdb backend.
692
693
 Assumptions:
694
  - always called as root
695
  - ignores the account type except when adding a new account
696
  - will create/delete the unix account if the relative
697
    add/delete user script is configured
698
699
 *************************************************************/
700
701
NTSTATUS local_password_change(const char *user_name,
702
        int local_flags,
703
        const char *new_passwd,
704
        char **pp_err_str,
705
        char **pp_msg_str)
706
0
{
707
0
  TALLOC_CTX *tosctx;
708
0
  struct samu *sam_pass;
709
0
  uint32_t acb;
710
0
  uint32_t rid;
711
0
  NTSTATUS result;
712
0
  bool user_exists;
713
0
  int ret = -1;
714
715
0
  *pp_err_str = NULL;
716
0
  *pp_msg_str = NULL;
717
718
0
  tosctx = talloc_tos();
719
720
0
  sam_pass = samu_new(tosctx);
721
0
  if (!sam_pass) {
722
0
    result = NT_STATUS_NO_MEMORY;
723
0
    goto done;
724
0
  }
725
726
  /* Get the smb passwd entry for this user */
727
0
  user_exists = pdb_getsampwnam(sam_pass, user_name);
728
729
  /* Check delete first, we don't need to do anything else if we
730
   * are going to delete the account */
731
0
  if (user_exists && (local_flags & LOCAL_DELETE_USER)) {
732
733
0
    result = pdb_delete_user(tosctx, sam_pass);
734
0
    if (!NT_STATUS_IS_OK(result)) {
735
0
      ret = asprintf(pp_err_str,
736
0
          "Failed to delete entry for user %s.\n",
737
0
          user_name);
738
0
      if (ret < 0) {
739
0
        *pp_err_str = NULL;
740
0
      }
741
0
      result = NT_STATUS_UNSUCCESSFUL;
742
0
    } else {
743
0
      ret = asprintf(pp_msg_str,
744
0
          "Deleted user %s.\n",
745
0
          user_name);
746
0
      if (ret < 0) {
747
0
        *pp_msg_str = NULL;
748
0
      }
749
0
    }
750
0
    goto done;
751
0
  }
752
753
0
  if (user_exists && (local_flags & LOCAL_ADD_USER)) {
754
    /* the entry already existed */
755
0
    local_flags &= ~LOCAL_ADD_USER;
756
0
  }
757
758
0
  if (!user_exists && !(local_flags & LOCAL_ADD_USER)) {
759
0
    ret = asprintf(pp_err_str,
760
0
        "Failed to find entry for user %s.\n",
761
0
        user_name);
762
0
    if (ret < 0) {
763
0
      *pp_err_str = NULL;
764
0
    }
765
0
    result = NT_STATUS_NO_SUCH_USER;
766
0
    goto done;
767
0
  }
768
769
  /* First thing add the new user if we are required to do so */
770
0
  if (local_flags & LOCAL_ADD_USER) {
771
772
0
    if (local_flags & LOCAL_TRUST_ACCOUNT) {
773
0
      acb = ACB_WSTRUST;
774
0
    } else if (local_flags & LOCAL_INTERDOM_ACCOUNT) {
775
0
      acb = ACB_DOMTRUST;
776
0
    } else {
777
0
      acb = ACB_NORMAL;
778
0
    }
779
780
0
    result = pdb_create_user(tosctx, user_name, acb, &rid);
781
0
    if (!NT_STATUS_IS_OK(result)) {
782
0
      ret = asprintf(pp_err_str,
783
0
          "Failed to add entry for user %s.\n",
784
0
          user_name);
785
0
      if (ret < 0) {
786
0
        *pp_err_str = NULL;
787
0
      }
788
0
      result = NT_STATUS_UNSUCCESSFUL;
789
0
      goto done;
790
0
    }
791
792
0
    sam_pass = samu_new(tosctx);
793
0
    if (!sam_pass) {
794
0
      result = NT_STATUS_NO_MEMORY;
795
0
      goto done;
796
0
    }
797
798
    /* Now get back the smb passwd entry for this new user */
799
0
    user_exists = pdb_getsampwnam(sam_pass, user_name);
800
0
    if (!user_exists) {
801
0
      ret = asprintf(pp_err_str,
802
0
          "Failed to add entry for user %s.\n",
803
0
          user_name);
804
0
      if (ret < 0) {
805
0
        *pp_err_str = NULL;
806
0
      }
807
0
      result = NT_STATUS_UNSUCCESSFUL;
808
0
      goto done;
809
0
    }
810
0
  }
811
812
0
  acb = pdb_get_acct_ctrl(sam_pass);
813
814
  /*
815
   * We are root - just write the new password
816
   * and the valid last change time.
817
   */
818
0
  if ((local_flags & LOCAL_SET_NO_PASSWORD) && !(acb & ACB_PWNOTREQ)) {
819
0
    acb |= ACB_PWNOTREQ;
820
0
    if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) {
821
0
      ret = asprintf(pp_err_str,
822
0
          "Failed to set 'no password required' "
823
0
          "flag for user %s.\n", user_name);
824
0
      if (ret < 0) {
825
0
        *pp_err_str = NULL;
826
0
      }
827
0
      result = NT_STATUS_UNSUCCESSFUL;
828
0
      goto done;
829
0
    }
830
0
  }
831
832
0
  if (local_flags & LOCAL_SET_PASSWORD) {
833
    /*
834
     * If we're dealing with setting a completely empty user account
835
     * ie. One with a password of 'XXXX', but not set disabled (like
836
     * an account created from scratch) then if the old password was
837
     * 'XX's then getsmbpwent will have set the ACB_DISABLED flag.
838
     * We remove that as we're giving this user their first password
839
     * and the decision hasn't really been made to disable them (ie.
840
     * don't create them disabled). JRA.
841
     */
842
0
    if ((pdb_get_lanman_passwd(sam_pass) == NULL) &&
843
0
        (acb & ACB_DISABLED)) {
844
0
      acb &= (~ACB_DISABLED);
845
0
      if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) {
846
0
        ret = asprintf(pp_err_str,
847
0
            "Failed to unset 'disabled' "
848
0
            "flag for user %s.\n",
849
0
            user_name);
850
0
        if (ret < 0) {
851
0
          *pp_err_str = NULL;
852
0
        }
853
0
        result = NT_STATUS_UNSUCCESSFUL;
854
0
        goto done;
855
0
      }
856
0
    }
857
858
0
    acb &= (~ACB_PWNOTREQ);
859
0
    if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) {
860
0
      ret = asprintf(pp_err_str,
861
0
          "Failed to unset 'no password required'"
862
0
          " flag for user %s.\n", user_name);
863
0
      if (ret < 0) {
864
0
        *pp_err_str = NULL;
865
0
      }
866
0
      result = NT_STATUS_UNSUCCESSFUL;
867
0
      goto done;
868
0
    }
869
870
0
    if (!pdb_set_plaintext_passwd(sam_pass, new_passwd)) {
871
0
      ret = asprintf(pp_err_str,
872
0
          "Failed to set password for "
873
0
          "user %s.\n", user_name);
874
0
        if (ret < 0) {
875
0
        *pp_err_str = NULL;
876
0
      }
877
0
      result = NT_STATUS_UNSUCCESSFUL;
878
0
      goto done;
879
0
    }
880
0
  }
881
882
0
  if ((local_flags & LOCAL_DISABLE_USER) && !(acb & ACB_DISABLED)) {
883
0
    acb |= ACB_DISABLED;
884
0
    if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) {
885
0
      ret = asprintf(pp_err_str,
886
0
          "Failed to set 'disabled' flag for "
887
0
          "user %s.\n", user_name);
888
0
      if (ret < 0) {
889
0
        *pp_err_str = NULL;
890
0
      }
891
0
      result = NT_STATUS_UNSUCCESSFUL;
892
0
      goto done;
893
0
    }
894
0
  }
895
896
0
  if ((local_flags & LOCAL_ENABLE_USER) && (acb & ACB_DISABLED)) {
897
0
    acb &= (~ACB_DISABLED);
898
0
    if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) {
899
0
      ret = asprintf(pp_err_str,
900
0
          "Failed to unset 'disabled' flag for "
901
0
          "user %s.\n", user_name);
902
0
      if (ret < 0) {
903
0
        *pp_err_str = NULL;
904
0
      }
905
0
      result = NT_STATUS_UNSUCCESSFUL;
906
0
      goto done;
907
0
    }
908
0
  }
909
910
  /* now commit changes if any */
911
0
  result = pdb_update_sam_account(sam_pass);
912
0
  if (!NT_STATUS_IS_OK(result)) {
913
0
    ret = asprintf(pp_err_str,
914
0
        "Failed to modify entry for user %s.\n",
915
0
        user_name);
916
0
    if (ret < 0) {
917
0
      *pp_err_str = NULL;
918
0
    }
919
0
    goto done;
920
0
  }
921
922
0
  if (local_flags & LOCAL_ADD_USER) {
923
0
    ret = asprintf(pp_msg_str, "Added user %s.\n", user_name);
924
0
  } else if (local_flags & LOCAL_DISABLE_USER) {
925
0
    ret = asprintf(pp_msg_str, "Disabled user %s.\n", user_name);
926
0
  } else if (local_flags & LOCAL_ENABLE_USER) {
927
0
    ret = asprintf(pp_msg_str, "Enabled user %s.\n", user_name);
928
0
  } else if (local_flags & LOCAL_SET_NO_PASSWORD) {
929
0
    ret = asprintf(pp_msg_str,
930
0
        "User %s password set to none.\n", user_name);
931
0
  }
932
933
0
  if (ret < 0) {
934
0
    *pp_msg_str = NULL;
935
0
  }
936
937
0
  result = NT_STATUS_OK;
938
939
0
done:
940
0
  TALLOC_FREE(sam_pass);
941
0
  return result;
942
0
}
943
944
/**********************************************************************
945
 Marshall/unmarshall struct samu structs.
946
 *********************************************************************/
947
948
0
#define SAMU_BUFFER_FORMAT_V0       "ddddddBBBBBBBBBBBBddBBwdwdBwwd"
949
0
#define SAMU_BUFFER_FORMAT_V1       "dddddddBBBBBBBBBBBBddBBwdwdBwwd"
950
0
#define SAMU_BUFFER_FORMAT_V2       "dddddddBBBBBBBBBBBBddBBBwwdBwwd"
951
0
#define SAMU_BUFFER_FORMAT_V3       "dddddddBBBBBBBBBBBBddBBBdwdBwwd"
952
/* nothing changed between V3 and V4 */
953
954
/*********************************************************************
955
*********************************************************************/
956
957
static bool init_samu_from_buffer_v0(struct samu *sampass, uint8_t *buf, uint32_t buflen)
958
0
{
959
960
  /* times are stored as 32bit integer
961
     take care on system with 64bit wide time_t
962
     --SSS */
963
0
  uint32_t  logon_time,
964
0
    logoff_time,
965
0
    kickoff_time,
966
0
    pass_last_set_time,
967
0
    pass_can_change_time,
968
0
    pass_must_change_time;
969
0
  char *username = NULL;
970
0
  char *domain = NULL;
971
0
  char *nt_username = NULL;
972
0
  char *dir_drive = NULL;
973
0
  char *unknown_str = NULL;
974
0
  char *munged_dial = NULL;
975
0
  char *fullname = NULL;
976
0
  char *homedir = NULL;
977
0
  char *logon_script = NULL;
978
0
  char *profile_path = NULL;
979
0
  char *acct_desc = NULL;
980
0
  char *workstations = NULL;
981
0
  uint32_t  username_len, domain_len, nt_username_len,
982
0
    dir_drive_len, unknown_str_len, munged_dial_len,
983
0
    fullname_len, homedir_len, logon_script_len,
984
0
    profile_path_len, acct_desc_len, workstations_len;
985
986
0
  uint32_t  user_rid, group_rid, remove_me, hours_len, unknown_6;
987
0
  uint16_t  acct_ctrl, logon_divs;
988
0
  uint16_t  bad_password_count, logon_count;
989
0
  uint8_t *hours = NULL;
990
0
  uint8_t *lm_pw_ptr = NULL, *nt_pw_ptr = NULL;
991
0
  uint32_t    len = 0;
992
0
  uint32_t    lm_pw_len, nt_pw_len, hourslen;
993
0
  bool ret = True;
994
995
0
  if(sampass == NULL || buf == NULL) {
996
0
    DEBUG(0, ("init_samu_from_buffer_v0: NULL parameters found!\n"));
997
0
    return False;
998
0
  }
999
1000
/* SAMU_BUFFER_FORMAT_V0       "ddddddBBBBBBBBBBBBddBBwdwdBwwd" */
1001
1002
  /* unpack the buffer into variables */
1003
0
  len = tdb_unpack (buf, buflen, SAMU_BUFFER_FORMAT_V0,
1004
0
    &logon_time,            /* d */
1005
0
    &logoff_time,           /* d */
1006
0
    &kickoff_time,            /* d */
1007
0
    &pass_last_set_time,          /* d */
1008
0
    &pass_can_change_time,          /* d */
1009
0
    &pass_must_change_time,         /* d */
1010
0
    &username_len, &username,       /* B */
1011
0
    &domain_len, &domain,         /* B */
1012
0
    &nt_username_len, &nt_username,       /* B */
1013
0
    &fullname_len, &fullname,       /* B */
1014
0
    &homedir_len, &homedir,         /* B */
1015
0
    &dir_drive_len, &dir_drive,       /* B */
1016
0
    &logon_script_len, &logon_script,     /* B */
1017
0
    &profile_path_len, &profile_path,     /* B */
1018
0
    &acct_desc_len, &acct_desc,       /* B */
1019
0
    &workstations_len, &workstations,     /* B */
1020
0
    &unknown_str_len, &unknown_str,       /* B */
1021
0
    &munged_dial_len, &munged_dial,       /* B */
1022
0
    &user_rid,            /* d */
1023
0
    &group_rid,           /* d */
1024
0
    &lm_pw_len, &lm_pw_ptr,         /* B */
1025
0
    &nt_pw_len, &nt_pw_ptr,         /* B */
1026
0
    &acct_ctrl,           /* w */
1027
0
    &remove_me, /* remove on the next TDB_FORMAT upgrade */ /* d */
1028
0
    &logon_divs,            /* w */
1029
0
    &hours_len,           /* d */
1030
0
    &hourslen, &hours,          /* B */
1031
0
    &bad_password_count,          /* w */
1032
0
    &logon_count,           /* w */
1033
0
    &unknown_6);            /* d */
1034
1035
0
  if (len == (uint32_t) -1)  {
1036
0
    ret = False;
1037
0
    goto done;
1038
0
  }
1039
1040
0
  pdb_set_logon_time(sampass, logon_time, PDB_SET);
1041
0
  pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
1042
0
  pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
1043
0
  pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
1044
0
  pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
1045
1046
0
  pdb_set_username(sampass, username, PDB_SET);
1047
0
  pdb_set_domain(sampass, domain, PDB_SET);
1048
0
  pdb_set_nt_username(sampass, nt_username, PDB_SET);
1049
0
  pdb_set_fullname(sampass, fullname, PDB_SET);
1050
1051
0
  if (homedir) {
1052
0
    pdb_set_homedir(sampass, homedir, PDB_SET);
1053
0
  }
1054
0
  else {
1055
0
    pdb_set_homedir(sampass,
1056
0
      talloc_sub_basic(sampass, username, domain,
1057
0
           lp_logon_home()),
1058
0
      PDB_DEFAULT);
1059
0
  }
1060
1061
0
  if (dir_drive)
1062
0
    pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1063
0
  else {
1064
0
    pdb_set_dir_drive(sampass,
1065
0
      talloc_sub_basic(sampass, username, domain,
1066
0
           lp_logon_drive()),
1067
0
      PDB_DEFAULT);
1068
0
  }
1069
1070
0
  if (logon_script)
1071
0
    pdb_set_logon_script(sampass, logon_script, PDB_SET);
1072
0
  else {
1073
0
    pdb_set_logon_script(sampass,
1074
0
      talloc_sub_basic(sampass, username, domain,
1075
0
           lp_logon_script()),
1076
0
      PDB_DEFAULT);
1077
0
  }
1078
1079
0
  if (profile_path) {
1080
0
    pdb_set_profile_path(sampass, profile_path, PDB_SET);
1081
0
  } else {
1082
0
    pdb_set_profile_path(sampass,
1083
0
      talloc_sub_basic(sampass, username, domain,
1084
0
           lp_logon_path()),
1085
0
      PDB_DEFAULT);
1086
0
  }
1087
1088
0
  pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1089
0
  pdb_set_workstations(sampass, workstations, PDB_SET);
1090
0
  pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1091
1092
0
  if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1093
0
    if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1094
0
      ret = False;
1095
0
      goto done;
1096
0
    }
1097
0
  }
1098
1099
0
  if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1100
0
    if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1101
0
      ret = False;
1102
0
      goto done;
1103
0
    }
1104
0
  }
1105
1106
0
  pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1107
0
  pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1108
0
  pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
1109
0
  pdb_set_hours_len(sampass, hours_len, PDB_SET);
1110
0
  pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1111
0
  pdb_set_logon_count(sampass, logon_count, PDB_SET);
1112
0
  pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1113
0
  pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1114
0
  pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1115
0
  pdb_set_hours(sampass, hours, hours_len, PDB_SET);
1116
1117
0
done:
1118
1119
0
  SAFE_FREE(username);
1120
0
  SAFE_FREE(domain);
1121
0
  SAFE_FREE(nt_username);
1122
0
  SAFE_FREE(fullname);
1123
0
  SAFE_FREE(homedir);
1124
0
  SAFE_FREE(dir_drive);
1125
0
  SAFE_FREE(logon_script);
1126
0
  SAFE_FREE(profile_path);
1127
0
  SAFE_FREE(acct_desc);
1128
0
  SAFE_FREE(workstations);
1129
0
  SAFE_FREE(munged_dial);
1130
0
  SAFE_FREE(unknown_str);
1131
0
  SAFE_FREE(lm_pw_ptr);
1132
0
  SAFE_FREE(nt_pw_ptr);
1133
0
  SAFE_FREE(hours);
1134
1135
0
  return ret;
1136
0
}
1137
1138
/*********************************************************************
1139
*********************************************************************/
1140
1141
static bool init_samu_from_buffer_v1(struct samu *sampass, uint8_t *buf, uint32_t buflen)
1142
0
{
1143
1144
  /* times are stored as 32bit integer
1145
     take care on system with 64bit wide time_t
1146
     --SSS */
1147
0
  uint32_t  logon_time,
1148
0
    logoff_time,
1149
0
    kickoff_time,
1150
0
    bad_password_time,
1151
0
    pass_last_set_time,
1152
0
    pass_can_change_time,
1153
0
    pass_must_change_time;
1154
0
  char *username = NULL;
1155
0
  char *domain = NULL;
1156
0
  char *nt_username = NULL;
1157
0
  char *dir_drive = NULL;
1158
0
  char *unknown_str = NULL;
1159
0
  char *munged_dial = NULL;
1160
0
  char *fullname = NULL;
1161
0
  char *homedir = NULL;
1162
0
  char *logon_script = NULL;
1163
0
  char *profile_path = NULL;
1164
0
  char *acct_desc = NULL;
1165
0
  char *workstations = NULL;
1166
0
  uint32_t  username_len, domain_len, nt_username_len,
1167
0
    dir_drive_len, unknown_str_len, munged_dial_len,
1168
0
    fullname_len, homedir_len, logon_script_len,
1169
0
    profile_path_len, acct_desc_len, workstations_len;
1170
1171
0
  uint32_t  user_rid, group_rid, remove_me, hours_len, unknown_6;
1172
0
  uint16_t  acct_ctrl, logon_divs;
1173
0
  uint16_t  bad_password_count, logon_count;
1174
0
  uint8_t *hours = NULL;
1175
0
  uint8_t *lm_pw_ptr = NULL, *nt_pw_ptr = NULL;
1176
0
  uint32_t    len = 0;
1177
0
  uint32_t    lm_pw_len, nt_pw_len, hourslen;
1178
0
  bool ret = True;
1179
1180
0
  if(sampass == NULL || buf == NULL) {
1181
0
    DEBUG(0, ("init_samu_from_buffer_v1: NULL parameters found!\n"));
1182
0
    return False;
1183
0
  }
1184
1185
/* SAMU_BUFFER_FORMAT_V1       "dddddddBBBBBBBBBBBBddBBwdwdBwwd" */
1186
1187
  /* unpack the buffer into variables */
1188
0
  len = tdb_unpack (buf, buflen, SAMU_BUFFER_FORMAT_V1,
1189
0
    &logon_time,            /* d */
1190
0
    &logoff_time,           /* d */
1191
0
    &kickoff_time,            /* d */
1192
    /* Change from V0 is addition of bad_password_time field. */
1193
0
    &bad_password_time,         /* d */
1194
0
    &pass_last_set_time,          /* d */
1195
0
    &pass_can_change_time,          /* d */
1196
0
    &pass_must_change_time,         /* d */
1197
0
    &username_len, &username,       /* B */
1198
0
    &domain_len, &domain,         /* B */
1199
0
    &nt_username_len, &nt_username,       /* B */
1200
0
    &fullname_len, &fullname,       /* B */
1201
0
    &homedir_len, &homedir,         /* B */
1202
0
    &dir_drive_len, &dir_drive,       /* B */
1203
0
    &logon_script_len, &logon_script,     /* B */
1204
0
    &profile_path_len, &profile_path,     /* B */
1205
0
    &acct_desc_len, &acct_desc,       /* B */
1206
0
    &workstations_len, &workstations,     /* B */
1207
0
    &unknown_str_len, &unknown_str,       /* B */
1208
0
    &munged_dial_len, &munged_dial,       /* B */
1209
0
    &user_rid,            /* d */
1210
0
    &group_rid,           /* d */
1211
0
    &lm_pw_len, &lm_pw_ptr,         /* B */
1212
0
    &nt_pw_len, &nt_pw_ptr,         /* B */
1213
0
    &acct_ctrl,           /* w */
1214
0
    &remove_me,           /* d */
1215
0
    &logon_divs,            /* w */
1216
0
    &hours_len,           /* d */
1217
0
    &hourslen, &hours,          /* B */
1218
0
    &bad_password_count,          /* w */
1219
0
    &logon_count,           /* w */
1220
0
    &unknown_6);            /* d */
1221
1222
0
  if (len == (uint32_t) -1)  {
1223
0
    ret = False;
1224
0
    goto done;
1225
0
  }
1226
1227
0
  pdb_set_logon_time(sampass, logon_time, PDB_SET);
1228
0
  pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
1229
0
  pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
1230
1231
  /* Change from V0 is addition of bad_password_time field. */
1232
0
  pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
1233
0
  pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
1234
0
  pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
1235
1236
0
  pdb_set_username(sampass, username, PDB_SET);
1237
0
  pdb_set_domain(sampass, domain, PDB_SET);
1238
0
  pdb_set_nt_username(sampass, nt_username, PDB_SET);
1239
0
  pdb_set_fullname(sampass, fullname, PDB_SET);
1240
1241
0
  if (homedir) {
1242
0
    pdb_set_homedir(sampass, homedir, PDB_SET);
1243
0
  }
1244
0
  else {
1245
0
    pdb_set_homedir(sampass,
1246
0
      talloc_sub_basic(sampass, username, domain,
1247
0
           lp_logon_home()),
1248
0
      PDB_DEFAULT);
1249
0
  }
1250
1251
0
  if (dir_drive)
1252
0
    pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1253
0
  else {
1254
0
    pdb_set_dir_drive(sampass,
1255
0
      talloc_sub_basic(sampass, username, domain,
1256
0
           lp_logon_drive()),
1257
0
      PDB_DEFAULT);
1258
0
  }
1259
1260
0
  if (logon_script)
1261
0
    pdb_set_logon_script(sampass, logon_script, PDB_SET);
1262
0
  else {
1263
0
    pdb_set_logon_script(sampass,
1264
0
      talloc_sub_basic(sampass, username, domain,
1265
0
           lp_logon_script()),
1266
0
      PDB_DEFAULT);
1267
0
  }
1268
1269
0
  if (profile_path) {
1270
0
    pdb_set_profile_path(sampass, profile_path, PDB_SET);
1271
0
  } else {
1272
0
    pdb_set_profile_path(sampass,
1273
0
      talloc_sub_basic(sampass, username, domain,
1274
0
           lp_logon_path()),
1275
0
      PDB_DEFAULT);
1276
0
  }
1277
1278
0
  pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1279
0
  pdb_set_workstations(sampass, workstations, PDB_SET);
1280
0
  pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1281
1282
0
  if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1283
0
    if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1284
0
      ret = False;
1285
0
      goto done;
1286
0
    }
1287
0
  }
1288
1289
0
  if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1290
0
    if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1291
0
      ret = False;
1292
0
      goto done;
1293
0
    }
1294
0
  }
1295
1296
0
  pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1297
1298
0
  pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1299
0
  pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
1300
0
  pdb_set_hours_len(sampass, hours_len, PDB_SET);
1301
0
  pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1302
0
  pdb_set_logon_count(sampass, logon_count, PDB_SET);
1303
0
  pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1304
0
  pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1305
0
  pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1306
0
  pdb_set_hours(sampass, hours, hours_len, PDB_SET);
1307
1308
0
done:
1309
1310
0
  SAFE_FREE(username);
1311
0
  SAFE_FREE(domain);
1312
0
  SAFE_FREE(nt_username);
1313
0
  SAFE_FREE(fullname);
1314
0
  SAFE_FREE(homedir);
1315
0
  SAFE_FREE(dir_drive);
1316
0
  SAFE_FREE(logon_script);
1317
0
  SAFE_FREE(profile_path);
1318
0
  SAFE_FREE(acct_desc);
1319
0
  SAFE_FREE(workstations);
1320
0
  SAFE_FREE(munged_dial);
1321
0
  SAFE_FREE(unknown_str);
1322
0
  SAFE_FREE(lm_pw_ptr);
1323
0
  SAFE_FREE(nt_pw_ptr);
1324
0
  SAFE_FREE(hours);
1325
1326
0
  return ret;
1327
0
}
1328
1329
static bool init_samu_from_buffer_v2(struct samu *sampass, uint8_t *buf, uint32_t buflen)
1330
0
{
1331
1332
  /* times are stored as 32bit integer
1333
     take care on system with 64bit wide time_t
1334
     --SSS */
1335
0
  uint32_t  logon_time,
1336
0
    logoff_time,
1337
0
    kickoff_time,
1338
0
    bad_password_time,
1339
0
    pass_last_set_time,
1340
0
    pass_can_change_time,
1341
0
    pass_must_change_time;
1342
0
  char *username = NULL;
1343
0
  char *domain = NULL;
1344
0
  char *nt_username = NULL;
1345
0
  char *dir_drive = NULL;
1346
0
  char *unknown_str = NULL;
1347
0
  char *munged_dial = NULL;
1348
0
  char *fullname = NULL;
1349
0
  char *homedir = NULL;
1350
0
  char *logon_script = NULL;
1351
0
  char *profile_path = NULL;
1352
0
  char *acct_desc = NULL;
1353
0
  char *workstations = NULL;
1354
0
  uint32_t  username_len, domain_len, nt_username_len,
1355
0
    dir_drive_len, unknown_str_len, munged_dial_len,
1356
0
    fullname_len, homedir_len, logon_script_len,
1357
0
    profile_path_len, acct_desc_len, workstations_len;
1358
1359
0
  uint32_t  user_rid, group_rid, hours_len, unknown_6;
1360
0
  uint16_t  acct_ctrl, logon_divs;
1361
0
  uint16_t  bad_password_count, logon_count;
1362
0
  uint8_t *hours = NULL;
1363
0
  uint8_t *lm_pw_ptr = NULL, *nt_pw_ptr = NULL, *nt_pw_hist_ptr = NULL;
1364
0
  uint32_t    len = 0;
1365
0
  uint32_t    lm_pw_len, nt_pw_len, nt_pw_hist_len, hourslen;
1366
0
  uint32_t pwHistLen = 0;
1367
0
  bool ret = True;
1368
0
  fstring tmp_string;
1369
0
  bool expand_explicit = lp_passdb_expand_explicit();
1370
1371
0
  if(sampass == NULL || buf == NULL) {
1372
0
    DEBUG(0, ("init_samu_from_buffer_v2: NULL parameters found!\n"));
1373
0
    return False;
1374
0
  }
1375
1376
/* SAMU_BUFFER_FORMAT_V2       "dddddddBBBBBBBBBBBBddBBBwwdBwwd" */
1377
1378
  /* unpack the buffer into variables */
1379
0
  len = tdb_unpack (buf, buflen, SAMU_BUFFER_FORMAT_V2,
1380
0
    &logon_time,            /* d */
1381
0
    &logoff_time,           /* d */
1382
0
    &kickoff_time,            /* d */
1383
0
    &bad_password_time,         /* d */
1384
0
    &pass_last_set_time,          /* d */
1385
0
    &pass_can_change_time,          /* d */
1386
0
    &pass_must_change_time,         /* d */
1387
0
    &username_len, &username,       /* B */
1388
0
    &domain_len, &domain,         /* B */
1389
0
    &nt_username_len, &nt_username,       /* B */
1390
0
    &fullname_len, &fullname,       /* B */
1391
0
    &homedir_len, &homedir,         /* B */
1392
0
    &dir_drive_len, &dir_drive,       /* B */
1393
0
    &logon_script_len, &logon_script,     /* B */
1394
0
    &profile_path_len, &profile_path,     /* B */
1395
0
    &acct_desc_len, &acct_desc,       /* B */
1396
0
    &workstations_len, &workstations,     /* B */
1397
0
    &unknown_str_len, &unknown_str,       /* B */
1398
0
    &munged_dial_len, &munged_dial,       /* B */
1399
0
    &user_rid,            /* d */
1400
0
    &group_rid,           /* d */
1401
0
    &lm_pw_len, &lm_pw_ptr,         /* B */
1402
0
    &nt_pw_len, &nt_pw_ptr,         /* B */
1403
    /* Change from V1 is addition of password history field. */
1404
0
    &nt_pw_hist_len, &nt_pw_hist_ptr,     /* B */
1405
0
    &acct_ctrl,           /* w */
1406
    /* Also "remove_me" field was removed. */
1407
0
    &logon_divs,            /* w */
1408
0
    &hours_len,           /* d */
1409
0
    &hourslen, &hours,          /* B */
1410
0
    &bad_password_count,          /* w */
1411
0
    &logon_count,           /* w */
1412
0
    &unknown_6);            /* d */
1413
1414
0
  if (len == (uint32_t) -1)  {
1415
0
    ret = False;
1416
0
    goto done;
1417
0
  }
1418
1419
0
  pdb_set_logon_time(sampass, logon_time, PDB_SET);
1420
0
  pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
1421
0
  pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
1422
0
  pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
1423
0
  pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
1424
0
  pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
1425
1426
0
  pdb_set_username(sampass, username, PDB_SET);
1427
0
  pdb_set_domain(sampass, domain, PDB_SET);
1428
0
  pdb_set_nt_username(sampass, nt_username, PDB_SET);
1429
0
  pdb_set_fullname(sampass, fullname, PDB_SET);
1430
1431
0
  if (homedir) {
1432
0
    fstrcpy( tmp_string, homedir );
1433
0
    if (expand_explicit) {
1434
0
      standard_sub_basic( username, domain, tmp_string,
1435
0
              sizeof(tmp_string) );
1436
0
    }
1437
0
    pdb_set_homedir(sampass, tmp_string, PDB_SET);
1438
0
  }
1439
0
  else {
1440
0
    pdb_set_homedir(sampass,
1441
0
      talloc_sub_basic(sampass, username, domain,
1442
0
           lp_logon_home()),
1443
0
      PDB_DEFAULT);
1444
0
  }
1445
1446
0
  if (dir_drive)
1447
0
    pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1448
0
  else
1449
0
    pdb_set_dir_drive(sampass, lp_logon_drive(), PDB_DEFAULT );
1450
1451
0
  if (logon_script) {
1452
0
    fstrcpy( tmp_string, logon_script );
1453
0
    if (expand_explicit) {
1454
0
      standard_sub_basic( username, domain, tmp_string,
1455
0
              sizeof(tmp_string) );
1456
0
    }
1457
0
    pdb_set_logon_script(sampass, tmp_string, PDB_SET);
1458
0
  }
1459
0
  else {
1460
0
    pdb_set_logon_script(sampass,
1461
0
      talloc_sub_basic(sampass, username, domain,
1462
0
           lp_logon_script()),
1463
0
      PDB_DEFAULT);
1464
0
  }
1465
1466
0
  if (profile_path) {
1467
0
    fstrcpy( tmp_string, profile_path );
1468
0
    if (expand_explicit) {
1469
0
      standard_sub_basic( username, domain, tmp_string,
1470
0
              sizeof(tmp_string) );
1471
0
    }
1472
0
    pdb_set_profile_path(sampass, tmp_string, PDB_SET);
1473
0
  }
1474
0
  else {
1475
0
    pdb_set_profile_path(sampass,
1476
0
      talloc_sub_basic(sampass, username, domain,
1477
0
           lp_logon_path()),
1478
0
      PDB_DEFAULT);
1479
0
  }
1480
1481
0
  pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1482
0
  pdb_set_workstations(sampass, workstations, PDB_SET);
1483
0
  pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1484
1485
0
  if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1486
0
    if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1487
0
      ret = False;
1488
0
      goto done;
1489
0
    }
1490
0
  }
1491
1492
0
  if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1493
0
    if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1494
0
      ret = False;
1495
0
      goto done;
1496
0
    }
1497
0
  }
1498
1499
  /* Change from V1 is addition of password history field. */
1500
0
  pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
1501
0
  if (pwHistLen) {
1502
0
    uint8_t *pw_hist = SMB_MALLOC_ARRAY(uint8_t, pwHistLen * PW_HISTORY_ENTRY_LEN);
1503
0
    if (!pw_hist) {
1504
0
      ret = False;
1505
0
      goto done;
1506
0
    }
1507
0
    memset(pw_hist, '\0', pwHistLen * PW_HISTORY_ENTRY_LEN);
1508
0
    if (nt_pw_hist_ptr && nt_pw_hist_len) {
1509
0
      int i;
1510
0
      SMB_ASSERT((nt_pw_hist_len % PW_HISTORY_ENTRY_LEN) == 0);
1511
0
      nt_pw_hist_len /= PW_HISTORY_ENTRY_LEN;
1512
0
      for (i = 0; (i < pwHistLen) && (i < nt_pw_hist_len); i++) {
1513
0
        memcpy(&pw_hist[i*PW_HISTORY_ENTRY_LEN],
1514
0
          &nt_pw_hist_ptr[i*PW_HISTORY_ENTRY_LEN],
1515
0
          PW_HISTORY_ENTRY_LEN);
1516
0
      }
1517
0
    }
1518
0
    if (!pdb_set_pw_history(sampass, pw_hist, pwHistLen, PDB_SET)) {
1519
0
      SAFE_FREE(pw_hist);
1520
0
      ret = False;
1521
0
      goto done;
1522
0
    }
1523
0
    SAFE_FREE(pw_hist);
1524
0
  } else {
1525
0
    pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1526
0
  }
1527
1528
0
  pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1529
0
  pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
1530
0
  pdb_set_hours_len(sampass, hours_len, PDB_SET);
1531
0
  pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1532
0
  pdb_set_logon_count(sampass, logon_count, PDB_SET);
1533
0
  pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1534
0
  pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1535
0
  pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1536
0
  pdb_set_hours(sampass, hours, hours_len, PDB_SET);
1537
1538
0
done:
1539
1540
0
  SAFE_FREE(username);
1541
0
  SAFE_FREE(domain);
1542
0
  SAFE_FREE(nt_username);
1543
0
  SAFE_FREE(fullname);
1544
0
  SAFE_FREE(homedir);
1545
0
  SAFE_FREE(dir_drive);
1546
0
  SAFE_FREE(logon_script);
1547
0
  SAFE_FREE(profile_path);
1548
0
  SAFE_FREE(acct_desc);
1549
0
  SAFE_FREE(workstations);
1550
0
  SAFE_FREE(munged_dial);
1551
0
  SAFE_FREE(unknown_str);
1552
0
  SAFE_FREE(lm_pw_ptr);
1553
0
  SAFE_FREE(nt_pw_ptr);
1554
0
  SAFE_FREE(nt_pw_hist_ptr);
1555
0
  SAFE_FREE(hours);
1556
1557
0
  return ret;
1558
0
}
1559
1560
/*********************************************************************
1561
*********************************************************************/
1562
1563
static bool init_samu_from_buffer_v3(struct samu *sampass, uint8_t *buf, uint32_t buflen)
1564
0
{
1565
1566
  /* times are stored as 32bit integer
1567
     take care on system with 64bit wide time_t
1568
     --SSS */
1569
0
  uint32_t  logon_time,
1570
0
    logoff_time,
1571
0
    kickoff_time,
1572
0
    bad_password_time,
1573
0
    pass_last_set_time,
1574
0
    pass_can_change_time,
1575
0
    pass_must_change_time;
1576
0
  char *username = NULL;
1577
0
  char *domain = NULL;
1578
0
  char *nt_username = NULL;
1579
0
  char *dir_drive = NULL;
1580
0
  char *comment = NULL;
1581
0
  char *munged_dial = NULL;
1582
0
  char *fullname = NULL;
1583
0
  char *homedir = NULL;
1584
0
  char *logon_script = NULL;
1585
0
  char *profile_path = NULL;
1586
0
  char *acct_desc = NULL;
1587
0
  char *workstations = NULL;
1588
0
  uint32_t  username_len, domain_len, nt_username_len,
1589
0
    dir_drive_len, comment_len, munged_dial_len,
1590
0
    fullname_len, homedir_len, logon_script_len,
1591
0
    profile_path_len, acct_desc_len, workstations_len;
1592
1593
0
  uint32_t  user_rid, group_rid, hours_len, unknown_6, acct_ctrl;
1594
0
  uint16_t  logon_divs;
1595
0
  uint16_t  bad_password_count, logon_count;
1596
0
  uint8_t *hours = NULL;
1597
0
  uint8_t *lm_pw_ptr = NULL, *nt_pw_ptr = NULL, *nt_pw_hist_ptr = NULL;
1598
0
  uint32_t    len = 0;
1599
0
  uint32_t    lm_pw_len, nt_pw_len, nt_pw_hist_len, hourslen;
1600
0
  uint32_t pwHistLen = 0;
1601
0
  bool ret = True;
1602
0
  fstring tmp_string;
1603
0
  bool expand_explicit = lp_passdb_expand_explicit();
1604
1605
0
  if(sampass == NULL || buf == NULL) {
1606
0
    DEBUG(0, ("init_samu_from_buffer_v3: NULL parameters found!\n"));
1607
0
    return False;
1608
0
  }
1609
1610
/* SAMU_BUFFER_FORMAT_V3       "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */
1611
1612
  /* unpack the buffer into variables */
1613
0
  len = tdb_unpack (buf, buflen, SAMU_BUFFER_FORMAT_V3,
1614
0
    &logon_time,            /* d */
1615
0
    &logoff_time,           /* d */
1616
0
    &kickoff_time,            /* d */
1617
0
    &bad_password_time,         /* d */
1618
0
    &pass_last_set_time,          /* d */
1619
0
    &pass_can_change_time,          /* d */
1620
0
    &pass_must_change_time,         /* d */
1621
0
    &username_len, &username,       /* B */
1622
0
    &domain_len, &domain,         /* B */
1623
0
    &nt_username_len, &nt_username,       /* B */
1624
0
    &fullname_len, &fullname,       /* B */
1625
0
    &homedir_len, &homedir,         /* B */
1626
0
    &dir_drive_len, &dir_drive,       /* B */
1627
0
    &logon_script_len, &logon_script,     /* B */
1628
0
    &profile_path_len, &profile_path,     /* B */
1629
0
    &acct_desc_len, &acct_desc,       /* B */
1630
0
    &workstations_len, &workstations,     /* B */
1631
0
    &comment_len, &comment,         /* B */
1632
0
    &munged_dial_len, &munged_dial,       /* B */
1633
0
    &user_rid,            /* d */
1634
0
    &group_rid,           /* d */
1635
0
    &lm_pw_len, &lm_pw_ptr,         /* B */
1636
0
    &nt_pw_len, &nt_pw_ptr,         /* B */
1637
    /* Change from V1 is addition of password history field. */
1638
0
    &nt_pw_hist_len, &nt_pw_hist_ptr,     /* B */
1639
    /* Change from V2 is the uint32_t acb_mask */
1640
0
    &acct_ctrl,           /* d */
1641
    /* Also "remove_me" field was removed. */
1642
0
    &logon_divs,            /* w */
1643
0
    &hours_len,           /* d */
1644
0
    &hourslen, &hours,          /* B */
1645
0
    &bad_password_count,          /* w */
1646
0
    &logon_count,           /* w */
1647
0
    &unknown_6);            /* d */
1648
1649
0
  if (len == (uint32_t) -1)  {
1650
0
    ret = False;
1651
0
    goto done;
1652
0
  }
1653
1654
0
  pdb_set_logon_time(sampass, convert_uint32_t_to_time_t(logon_time), PDB_SET);
1655
0
  pdb_set_logoff_time(sampass, convert_uint32_t_to_time_t(logoff_time), PDB_SET);
1656
0
  pdb_set_kickoff_time(sampass, convert_uint32_t_to_time_t(kickoff_time), PDB_SET);
1657
0
  pdb_set_bad_password_time(sampass, convert_uint32_t_to_time_t(bad_password_time), PDB_SET);
1658
0
  pdb_set_pass_can_change_time(sampass, convert_uint32_t_to_time_t(pass_can_change_time), PDB_SET);
1659
0
  pdb_set_pass_last_set_time(sampass, convert_uint32_t_to_time_t(pass_last_set_time), PDB_SET);
1660
1661
0
  pdb_set_username(sampass, username, PDB_SET);
1662
0
  pdb_set_domain(sampass, domain, PDB_SET);
1663
0
  pdb_set_nt_username(sampass, nt_username, PDB_SET);
1664
0
  pdb_set_fullname(sampass, fullname, PDB_SET);
1665
1666
0
  if (homedir) {
1667
0
    fstrcpy( tmp_string, homedir );
1668
0
    if (expand_explicit) {
1669
0
      standard_sub_basic( username, domain, tmp_string,
1670
0
              sizeof(tmp_string) );
1671
0
    }
1672
0
    pdb_set_homedir(sampass, tmp_string, PDB_SET);
1673
0
  }
1674
0
  else {
1675
0
    pdb_set_homedir(sampass,
1676
0
      talloc_sub_basic(sampass, username, domain,
1677
0
           lp_logon_home()),
1678
0
      PDB_DEFAULT);
1679
0
  }
1680
1681
0
  if (dir_drive)
1682
0
    pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1683
0
  else
1684
0
    pdb_set_dir_drive(sampass, lp_logon_drive(), PDB_DEFAULT );
1685
1686
0
  if (logon_script) {
1687
0
    fstrcpy( tmp_string, logon_script );
1688
0
    if (expand_explicit) {
1689
0
      standard_sub_basic( username, domain, tmp_string,
1690
0
              sizeof(tmp_string) );
1691
0
    }
1692
0
    pdb_set_logon_script(sampass, tmp_string, PDB_SET);
1693
0
  }
1694
0
  else {
1695
0
    pdb_set_logon_script(sampass,
1696
0
      talloc_sub_basic(sampass, username, domain,
1697
0
           lp_logon_script()),
1698
0
      PDB_DEFAULT);
1699
0
  }
1700
1701
0
  if (profile_path) {
1702
0
    fstrcpy( tmp_string, profile_path );
1703
0
    if (expand_explicit) {
1704
0
      standard_sub_basic( username, domain, tmp_string,
1705
0
              sizeof(tmp_string) );
1706
0
    }
1707
0
    pdb_set_profile_path(sampass, tmp_string, PDB_SET);
1708
0
  }
1709
0
  else {
1710
0
    pdb_set_profile_path(sampass,
1711
0
      talloc_sub_basic(sampass, username, domain, lp_logon_path()),
1712
0
      PDB_DEFAULT);
1713
0
  }
1714
1715
0
  pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1716
0
  pdb_set_comment(sampass, comment, PDB_SET);
1717
0
  pdb_set_workstations(sampass, workstations, PDB_SET);
1718
0
  pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1719
1720
0
  if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
1721
0
    if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
1722
0
      ret = False;
1723
0
      goto done;
1724
0
    }
1725
0
  }
1726
1727
0
  if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
1728
0
    if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
1729
0
      ret = False;
1730
0
      goto done;
1731
0
    }
1732
0
  }
1733
1734
0
  pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
1735
0
  if (pwHistLen) {
1736
0
    uint8_t *pw_hist = (uint8_t *)SMB_MALLOC(pwHistLen * PW_HISTORY_ENTRY_LEN);
1737
0
    if (!pw_hist) {
1738
0
      ret = False;
1739
0
      goto done;
1740
0
    }
1741
0
    memset(pw_hist, '\0', pwHistLen * PW_HISTORY_ENTRY_LEN);
1742
0
    if (nt_pw_hist_ptr && nt_pw_hist_len) {
1743
0
      int i;
1744
0
      SMB_ASSERT((nt_pw_hist_len % PW_HISTORY_ENTRY_LEN) == 0);
1745
0
      nt_pw_hist_len /= PW_HISTORY_ENTRY_LEN;
1746
0
      for (i = 0; (i < pwHistLen) && (i < nt_pw_hist_len); i++) {
1747
0
        memcpy(&pw_hist[i*PW_HISTORY_ENTRY_LEN],
1748
0
          &nt_pw_hist_ptr[i*PW_HISTORY_ENTRY_LEN],
1749
0
          PW_HISTORY_ENTRY_LEN);
1750
0
      }
1751
0
    }
1752
0
    if (!pdb_set_pw_history(sampass, pw_hist, pwHistLen, PDB_SET)) {
1753
0
      SAFE_FREE(pw_hist);
1754
0
      ret = False;
1755
0
      goto done;
1756
0
    }
1757
0
    SAFE_FREE(pw_hist);
1758
0
  } else {
1759
0
    pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
1760
0
  }
1761
1762
0
  pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1763
0
  pdb_set_hours_len(sampass, hours_len, PDB_SET);
1764
0
  pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
1765
0
  pdb_set_logon_count(sampass, logon_count, PDB_SET);
1766
0
  pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
1767
  /* Change from V2 is the uint32_t acct_ctrl */
1768
0
  pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1769
0
  pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1770
0
  pdb_set_hours(sampass, hours, hours_len, PDB_SET);
1771
1772
0
done:
1773
1774
0
  SAFE_FREE(username);
1775
0
  SAFE_FREE(domain);
1776
0
  SAFE_FREE(nt_username);
1777
0
  SAFE_FREE(fullname);
1778
0
  SAFE_FREE(homedir);
1779
0
  SAFE_FREE(dir_drive);
1780
0
  SAFE_FREE(logon_script);
1781
0
  SAFE_FREE(profile_path);
1782
0
  SAFE_FREE(acct_desc);
1783
0
  SAFE_FREE(workstations);
1784
0
  SAFE_FREE(munged_dial);
1785
0
  SAFE_FREE(comment);
1786
0
  SAFE_FREE(lm_pw_ptr);
1787
0
  SAFE_FREE(nt_pw_ptr);
1788
0
  SAFE_FREE(nt_pw_hist_ptr);
1789
0
  SAFE_FREE(hours);
1790
1791
0
  return ret;
1792
0
}
1793
1794
/*********************************************************************
1795
*********************************************************************/
1796
1797
static uint32_t init_buffer_from_samu_v3 (uint8_t **buf, struct samu *sampass, bool size_only)
1798
0
{
1799
0
  size_t len, buflen;
1800
1801
  /* times are stored as 32bit integer
1802
     take care on system with 64bit wide time_t
1803
     --SSS */
1804
0
  uint32_t  logon_time,
1805
0
    logoff_time,
1806
0
    kickoff_time,
1807
0
    bad_password_time,
1808
0
    pass_last_set_time,
1809
0
    pass_can_change_time,
1810
0
    pass_must_change_time;
1811
1812
0
  uint32_t  user_rid, group_rid;
1813
1814
0
  const char *username;
1815
0
  const char *domain;
1816
0
  const char *nt_username;
1817
0
  const char *dir_drive;
1818
0
  const char *comment;
1819
0
  const char *munged_dial;
1820
0
  const char *fullname;
1821
0
  const char *homedir;
1822
0
  const char *logon_script;
1823
0
  const char *profile_path;
1824
0
  const char *acct_desc;
1825
0
  const char *workstations;
1826
0
  uint32_t  username_len, domain_len, nt_username_len,
1827
0
    dir_drive_len, comment_len, munged_dial_len,
1828
0
    fullname_len, homedir_len, logon_script_len,
1829
0
    profile_path_len, acct_desc_len, workstations_len;
1830
1831
0
  const uint8_t *lm_pw;
1832
0
  const uint8_t *nt_pw;
1833
0
  const uint8_t *nt_pw_hist;
1834
0
  uint32_t  lm_pw_len = 16;
1835
0
  uint32_t  nt_pw_len = 16;
1836
0
  uint32_t  nt_pw_hist_len;
1837
0
  uint32_t pwHistLen = 0;
1838
1839
0
  *buf = NULL;
1840
0
  buflen = 0;
1841
1842
0
  logon_time = convert_time_t_to_uint32_t(pdb_get_logon_time(sampass));
1843
0
  logoff_time = convert_time_t_to_uint32_t(pdb_get_logoff_time(sampass));
1844
0
  kickoff_time = convert_time_t_to_uint32_t(pdb_get_kickoff_time(sampass));
1845
0
  bad_password_time = convert_time_t_to_uint32_t(pdb_get_bad_password_time(sampass));
1846
0
  pass_can_change_time = convert_time_t_to_uint32_t(pdb_get_pass_can_change_time_noncalc(sampass));
1847
0
  pass_must_change_time = convert_time_t_to_uint32_t(pdb_get_pass_must_change_time(sampass));
1848
0
  pass_last_set_time = convert_time_t_to_uint32_t(pdb_get_pass_last_set_time(sampass));
1849
1850
0
  user_rid = pdb_get_user_rid(sampass);
1851
0
  group_rid = pdb_get_group_rid(sampass);
1852
1853
0
  username = pdb_get_username(sampass);
1854
0
  if (username) {
1855
0
    username_len = strlen(username) +1;
1856
0
  } else {
1857
0
    username_len = 0;
1858
0
  }
1859
1860
0
  domain = pdb_get_domain(sampass);
1861
0
  if (domain) {
1862
0
    domain_len = strlen(domain) +1;
1863
0
  } else {
1864
0
    domain_len = 0;
1865
0
  }
1866
1867
0
  nt_username = pdb_get_nt_username(sampass);
1868
0
  if (nt_username) {
1869
0
    nt_username_len = strlen(nt_username) +1;
1870
0
  } else {
1871
0
    nt_username_len = 0;
1872
0
  }
1873
1874
0
  fullname = pdb_get_fullname(sampass);
1875
0
  if (fullname) {
1876
0
    fullname_len = strlen(fullname) +1;
1877
0
  } else {
1878
0
    fullname_len = 0;
1879
0
  }
1880
1881
  /*
1882
   * Only updates fields which have been set (not defaults from smb.conf)
1883
   */
1884
1885
0
  if (!IS_SAM_DEFAULT(sampass, PDB_DRIVE)) {
1886
0
    dir_drive = pdb_get_dir_drive(sampass);
1887
0
  } else {
1888
0
    dir_drive = NULL;
1889
0
  }
1890
0
  if (dir_drive) {
1891
0
    dir_drive_len = strlen(dir_drive) +1;
1892
0
  } else {
1893
0
    dir_drive_len = 0;
1894
0
  }
1895
1896
0
  if (!IS_SAM_DEFAULT(sampass, PDB_SMBHOME)) {
1897
0
    homedir = pdb_get_homedir(sampass);
1898
0
  } else {
1899
0
    homedir = NULL;
1900
0
  }
1901
0
  if (homedir) {
1902
0
    homedir_len = strlen(homedir) +1;
1903
0
  } else {
1904
0
    homedir_len = 0;
1905
0
  }
1906
1907
0
  if (!IS_SAM_DEFAULT(sampass, PDB_LOGONSCRIPT)) {
1908
0
    logon_script = pdb_get_logon_script(sampass);
1909
0
  } else {
1910
0
    logon_script = NULL;
1911
0
  }
1912
0
  if (logon_script) {
1913
0
    logon_script_len = strlen(logon_script) +1;
1914
0
  } else {
1915
0
    logon_script_len = 0;
1916
0
  }
1917
1918
0
  if (!IS_SAM_DEFAULT(sampass, PDB_PROFILE)) {
1919
0
    profile_path = pdb_get_profile_path(sampass);
1920
0
  } else {
1921
0
    profile_path = NULL;
1922
0
  }
1923
0
  if (profile_path) {
1924
0
    profile_path_len = strlen(profile_path) +1;
1925
0
  } else {
1926
0
    profile_path_len = 0;
1927
0
  }
1928
1929
0
  lm_pw = pdb_get_lanman_passwd(sampass);
1930
0
  if (!lm_pw) {
1931
0
    lm_pw_len = 0;
1932
0
  }
1933
1934
0
  nt_pw = pdb_get_nt_passwd(sampass);
1935
0
  if (!nt_pw) {
1936
0
    nt_pw_len = 0;
1937
0
  }
1938
1939
0
  pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
1940
0
  nt_pw_hist =  pdb_get_pw_history(sampass, &nt_pw_hist_len);
1941
0
  if (pwHistLen && nt_pw_hist && nt_pw_hist_len) {
1942
0
    nt_pw_hist_len *= PW_HISTORY_ENTRY_LEN;
1943
0
  } else {
1944
0
    nt_pw_hist_len = 0;
1945
0
  }
1946
1947
0
  acct_desc = pdb_get_acct_desc(sampass);
1948
0
  if (acct_desc) {
1949
0
    acct_desc_len = strlen(acct_desc) +1;
1950
0
  } else {
1951
0
    acct_desc_len = 0;
1952
0
  }
1953
1954
0
  workstations = pdb_get_workstations(sampass);
1955
0
  if (workstations) {
1956
0
    workstations_len = strlen(workstations) +1;
1957
0
  } else {
1958
0
    workstations_len = 0;
1959
0
  }
1960
1961
0
  comment = pdb_get_comment(sampass);
1962
0
  if (comment) {
1963
0
    comment_len = strlen(comment) +1;
1964
0
  } else {
1965
0
    comment_len = 0;
1966
0
  }
1967
1968
0
  munged_dial = pdb_get_munged_dial(sampass);
1969
0
  if (munged_dial) {
1970
0
    munged_dial_len = strlen(munged_dial) +1;
1971
0
  } else {
1972
0
    munged_dial_len = 0;
1973
0
  }
1974
1975
/* SAMU_BUFFER_FORMAT_V3       "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */
1976
1977
  /* one time to get the size needed */
1978
0
  len = tdb_pack(NULL, 0,  SAMU_BUFFER_FORMAT_V3,
1979
0
    logon_time,       /* d */
1980
0
    logoff_time,        /* d */
1981
0
    kickoff_time,       /* d */
1982
0
    bad_password_time,      /* d */
1983
0
    pass_last_set_time,     /* d */
1984
0
    pass_can_change_time,     /* d */
1985
0
    pass_must_change_time,      /* d */
1986
0
    username_len, username,     /* B */
1987
0
    domain_len, domain,     /* B */
1988
0
    nt_username_len, nt_username,   /* B */
1989
0
    fullname_len, fullname,     /* B */
1990
0
    homedir_len, homedir,     /* B */
1991
0
    dir_drive_len, dir_drive,   /* B */
1992
0
    logon_script_len, logon_script,   /* B */
1993
0
    profile_path_len, profile_path,   /* B */
1994
0
    acct_desc_len, acct_desc,   /* B */
1995
0
    workstations_len, workstations,   /* B */
1996
0
    comment_len, comment,     /* B */
1997
0
    munged_dial_len, munged_dial,   /* B */
1998
0
    user_rid,       /* d */
1999
0
    group_rid,        /* d */
2000
0
    lm_pw_len, lm_pw,     /* B */
2001
0
    nt_pw_len, nt_pw,     /* B */
2002
0
    nt_pw_hist_len, nt_pw_hist,   /* B */
2003
0
    pdb_get_acct_ctrl(sampass),   /* d */
2004
0
    pdb_get_logon_divs(sampass),    /* w */
2005
0
    pdb_get_hours_len(sampass),   /* d */
2006
0
    MAX_HOURS_LEN, pdb_get_hours(sampass), /* B */
2007
0
    pdb_get_bad_password_count(sampass),  /* w */
2008
0
    pdb_get_logon_count(sampass),   /* w */
2009
0
    pdb_get_unknown_6(sampass));    /* d */
2010
2011
0
  if (size_only) {
2012
0
    return buflen;
2013
0
  }
2014
2015
  /* malloc the space needed */
2016
0
  if ( (*buf=(uint8_t*)SMB_MALLOC(len)) == NULL) {
2017
0
    DEBUG(0,("init_buffer_from_samu_v3: Unable to malloc() memory for buffer!\n"));
2018
0
    return (-1);
2019
0
  }
2020
2021
  /* now for the real call to tdb_pack() */
2022
0
  buflen = tdb_pack(*buf, len,  SAMU_BUFFER_FORMAT_V3,
2023
0
    logon_time,       /* d */
2024
0
    logoff_time,        /* d */
2025
0
    kickoff_time,       /* d */
2026
0
    bad_password_time,      /* d */
2027
0
    pass_last_set_time,     /* d */
2028
0
    pass_can_change_time,     /* d */
2029
0
    pass_must_change_time,      /* d */
2030
0
    username_len, username,     /* B */
2031
0
    domain_len, domain,     /* B */
2032
0
    nt_username_len, nt_username,   /* B */
2033
0
    fullname_len, fullname,     /* B */
2034
0
    homedir_len, homedir,     /* B */
2035
0
    dir_drive_len, dir_drive,   /* B */
2036
0
    logon_script_len, logon_script,   /* B */
2037
0
    profile_path_len, profile_path,   /* B */
2038
0
    acct_desc_len, acct_desc,   /* B */
2039
0
    workstations_len, workstations,   /* B */
2040
0
    comment_len, comment,     /* B */
2041
0
    munged_dial_len, munged_dial,   /* B */
2042
0
    user_rid,       /* d */
2043
0
    group_rid,        /* d */
2044
0
    lm_pw_len, lm_pw,     /* B */
2045
0
    nt_pw_len, nt_pw,     /* B */
2046
0
    nt_pw_hist_len, nt_pw_hist,   /* B */
2047
0
    pdb_get_acct_ctrl(sampass),   /* d */
2048
0
    pdb_get_logon_divs(sampass),    /* w */
2049
0
    pdb_get_hours_len(sampass),   /* d */
2050
0
    MAX_HOURS_LEN, pdb_get_hours(sampass), /* B */
2051
0
    pdb_get_bad_password_count(sampass),  /* w */
2052
0
    pdb_get_logon_count(sampass),   /* w */
2053
0
    pdb_get_unknown_6(sampass));    /* d */
2054
2055
  /* check to make sure we got it correct */
2056
0
  if (buflen != len) {
2057
0
    DEBUG(0, ("init_buffer_from_samu_v3: something odd is going on here: bufflen (%lu) != len (%lu) in tdb_pack operations!\n",
2058
0
        (unsigned long)buflen, (unsigned long)len));
2059
    /* error */
2060
0
    SAFE_FREE (*buf);
2061
0
    return (-1);
2062
0
  }
2063
2064
0
  return (buflen);
2065
0
}
2066
2067
static bool init_samu_from_buffer_v4(struct samu *sampass, uint8_t *buf, uint32_t buflen)
2068
0
{
2069
  /* nothing changed between V3 and V4 */
2070
0
  return init_samu_from_buffer_v3(sampass, buf, buflen);
2071
0
}
2072
2073
static uint32_t init_buffer_from_samu_v4(uint8_t **buf, struct samu *sampass, bool size_only)
2074
0
{
2075
  /* nothing changed between V3 and V4 */
2076
0
  return init_buffer_from_samu_v3(buf, sampass, size_only);
2077
0
}
2078
2079
/**********************************************************************
2080
 Initialize a struct samu struct from a BYTE buffer of size len
2081
 *********************************************************************/
2082
2083
bool init_samu_from_buffer(struct samu *sampass, uint32_t level,
2084
         uint8_t *buf, uint32_t buflen)
2085
0
{
2086
0
  switch (level) {
2087
0
  case SAMU_BUFFER_V0:
2088
0
    return init_samu_from_buffer_v0(sampass, buf, buflen);
2089
0
  case SAMU_BUFFER_V1:
2090
0
    return init_samu_from_buffer_v1(sampass, buf, buflen);
2091
0
  case SAMU_BUFFER_V2:
2092
0
    return init_samu_from_buffer_v2(sampass, buf, buflen);
2093
0
  case SAMU_BUFFER_V3:
2094
0
    return init_samu_from_buffer_v3(sampass, buf, buflen);
2095
0
  case SAMU_BUFFER_V4:
2096
0
    return init_samu_from_buffer_v4(sampass, buf, buflen);
2097
0
  }
2098
2099
0
  return false;
2100
0
}
2101
2102
/**********************************************************************
2103
 Initialize a BYTE buffer from a struct samu struct
2104
 *********************************************************************/
2105
2106
uint32_t init_buffer_from_samu (uint8_t **buf, struct samu *sampass, bool size_only)
2107
0
{
2108
0
  return init_buffer_from_samu_v4(buf, sampass, size_only);
2109
0
}
2110
2111
/*********************************************************************
2112
*********************************************************************/
2113
2114
bool pdb_copy_sam_account(struct samu *dst, struct samu *src )
2115
0
{
2116
0
  uint8_t *buf = NULL;
2117
0
  int len;
2118
2119
0
  len = init_buffer_from_samu(&buf, src, False);
2120
0
  if (len == -1 || !buf) {
2121
0
    SAFE_FREE(buf);
2122
0
    return False;
2123
0
  }
2124
2125
0
  if (!init_samu_from_buffer( dst, SAMU_BUFFER_LATEST, buf, len )) {
2126
0
    free(buf);
2127
0
    return False;
2128
0
  }
2129
2130
0
  dst->methods = src->methods;
2131
2132
0
  if ( src->unix_pw ) {
2133
0
    dst->unix_pw = tcopy_passwd( dst, src->unix_pw );
2134
0
    if (!dst->unix_pw) {
2135
0
      free(buf);
2136
0
      return False;
2137
0
    }
2138
0
  }
2139
2140
0
  if (src->group_sid) {
2141
0
    pdb_set_group_sid(dst, src->group_sid, PDB_SET);
2142
0
  }
2143
2144
0
  free(buf);
2145
0
  return True;
2146
0
}
2147
2148
/*********************************************************************
2149
 Update the bad password count checking the PDB_POLICY_RESET_COUNT_TIME
2150
*********************************************************************/
2151
2152
bool pdb_update_bad_password_count(struct samu *sampass, bool *updated)
2153
0
{
2154
0
  time_t LastBadPassword;
2155
0
  uint16_t BadPasswordCount;
2156
0
  uint32_t resettime;
2157
0
  bool res;
2158
2159
0
  BadPasswordCount = pdb_get_bad_password_count(sampass);
2160
0
  if (!BadPasswordCount) {
2161
0
    DEBUG(9, ("No bad password attempts.\n"));
2162
0
    return True;
2163
0
  }
2164
2165
0
  become_root();
2166
0
  res = pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &resettime);
2167
0
  unbecome_root();
2168
2169
0
  if (!res) {
2170
0
    DEBUG(0, ("pdb_update_bad_password_count: pdb_get_account_policy failed.\n"));
2171
0
    return False;
2172
0
  }
2173
2174
  /* First, check if there is a reset time to compare */
2175
0
  if ((resettime == (uint32_t) -1) || (resettime == 0)) {
2176
0
    DEBUG(9, ("No reset time, can't reset bad pw count\n"));
2177
0
    return True;
2178
0
  }
2179
2180
0
  LastBadPassword = pdb_get_bad_password_time(sampass);
2181
0
  DBG_INFO("LastBadPassword=%" PRIu64 ", resettime=%d, "
2182
0
     "current time=%" PRIu64 ".\n",
2183
0
     (uint64_t)LastBadPassword,
2184
0
     resettime,
2185
0
     (uint64_t)time(NULL));
2186
0
  if (time(NULL) > (LastBadPassword + convert_uint32_t_to_time_t(resettime)*60)){
2187
0
    pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
2188
0
    pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
2189
0
    if (updated) {
2190
0
      *updated = True;
2191
0
    }
2192
0
  }
2193
2194
0
  return True;
2195
0
}
2196
2197
/*********************************************************************
2198
 Update the ACB_AUTOLOCK flag checking the PDB_POLICY_LOCK_ACCOUNT_DURATION
2199
*********************************************************************/
2200
2201
bool pdb_update_autolock_flag(struct samu *sampass, bool *updated)
2202
0
{
2203
0
  uint32_t duration;
2204
0
  time_t LastBadPassword;
2205
0
  bool res;
2206
2207
0
  if (!(pdb_get_acct_ctrl(sampass) & ACB_AUTOLOCK)) {
2208
0
    DEBUG(9, ("pdb_update_autolock_flag: Account %s not autolocked, no check needed\n",
2209
0
      pdb_get_username(sampass)));
2210
0
    return True;
2211
0
  }
2212
2213
0
  become_root();
2214
0
  res = pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &duration);
2215
0
  unbecome_root();
2216
2217
0
  if (!res) {
2218
0
    DEBUG(0, ("pdb_update_autolock_flag: pdb_get_account_policy failed.\n"));
2219
0
    return False;
2220
0
  }
2221
2222
  /* First, check if there is a duration to compare */
2223
0
  if ((duration == (uint32_t) -1)  || (duration == 0)) {
2224
0
    DEBUG(9, ("pdb_update_autolock_flag: No reset duration, can't reset autolock\n"));
2225
0
    return True;
2226
0
  }
2227
2228
0
  LastBadPassword = pdb_get_bad_password_time(sampass);
2229
0
  DEBUG(7, ("pdb_update_autolock_flag: Account %s, LastBadPassword=%ju, duration=%d, current time =%ju.\n",
2230
0
      pdb_get_username(sampass), (uintmax_t)LastBadPassword, duration*60, (uintmax_t)time(NULL)));
2231
2232
0
  if (LastBadPassword == (time_t)0) {
2233
0
    DEBUG(1,("pdb_update_autolock_flag: Account %s "
2234
0
       "administratively locked out with no bad password "
2235
0
       "time. Leaving locked out.\n",
2236
0
       pdb_get_username(sampass) ));
2237
0
    return True;
2238
0
  }
2239
2240
0
  if ((time(NULL) > (LastBadPassword + convert_uint32_t_to_time_t(duration) * 60))) {
2241
0
    pdb_set_acct_ctrl(sampass,
2242
0
          pdb_get_acct_ctrl(sampass) & ~ACB_AUTOLOCK,
2243
0
          PDB_CHANGED);
2244
0
    pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
2245
0
    pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
2246
0
    if (updated) {
2247
0
      *updated = True;
2248
0
    }
2249
0
  }
2250
2251
0
  return True;
2252
0
}
2253
2254
/*********************************************************************
2255
 Increment the bad_password_count
2256
*********************************************************************/
2257
2258
bool pdb_increment_bad_password_count(struct samu *sampass)
2259
0
{
2260
0
  uint32_t account_policy_lockout;
2261
0
  bool autolock_updated = False, badpw_updated = False;
2262
0
  bool ret;
2263
2264
  /* Retrieve the account lockout policy */
2265
0
  become_root();
2266
0
  ret = pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_lockout);
2267
0
  unbecome_root();
2268
0
  if ( !ret ) {
2269
0
    DEBUG(0, ("pdb_increment_bad_password_count: pdb_get_account_policy failed.\n"));
2270
0
    return False;
2271
0
  }
2272
2273
  /* If there is no policy, we don't need to continue checking */
2274
0
  if (!account_policy_lockout) {
2275
0
    DEBUG(9, ("No lockout policy, don't track bad passwords\n"));
2276
0
    return True;
2277
0
  }
2278
2279
  /* Check if the autolock needs to be cleared */
2280
0
  if (!pdb_update_autolock_flag(sampass, &autolock_updated))
2281
0
    return False;
2282
2283
  /* Check if the badpw count needs to be reset */
2284
0
  if (!pdb_update_bad_password_count(sampass, &badpw_updated))
2285
0
    return False;
2286
2287
  /*
2288
    Ok, now we can assume that any resetting that needs to be
2289
    done has been done, and just get on with incrementing
2290
    and autolocking if necessary
2291
  */
2292
2293
0
  pdb_set_bad_password_count(sampass,
2294
0
           pdb_get_bad_password_count(sampass)+1,
2295
0
           PDB_CHANGED);
2296
0
  pdb_set_bad_password_time(sampass, time(NULL), PDB_CHANGED);
2297
2298
2299
0
  if (pdb_get_bad_password_count(sampass) < account_policy_lockout)
2300
0
    return True;
2301
2302
0
  if (!pdb_set_acct_ctrl(sampass,
2303
0
             pdb_get_acct_ctrl(sampass) | ACB_AUTOLOCK,
2304
0
             PDB_CHANGED)) {
2305
0
    DEBUG(1, ("pdb_increment_bad_password_count:failed to set 'autolock' flag. \n"));
2306
0
    return False;
2307
0
  }
2308
2309
0
  return True;
2310
0
}
2311
2312
bool is_dc_trusted_domain_situation(const char *domain_name)
2313
0
{
2314
0
  return IS_DC && !strequal(domain_name, lp_workgroup());
2315
0
}
2316
2317
/*******************************************************************
2318
 Wrapper around retrieving the clear text trust account password.
2319
 appropriate account name is stored in account_name.
2320
 Caller must free password, but not account_name.
2321
*******************************************************************/
2322
2323
static bool get_trust_pw_clear2(const char *domain,
2324
        const char **account_name,
2325
        enum netr_SchannelType *channel,
2326
        char **cur_pw,
2327
        time_t *_last_set_time,
2328
        char **prev_pw)
2329
0
{
2330
0
  char *pwd;
2331
0
  time_t last_set_time;
2332
2333
0
  if (cur_pw != NULL) {
2334
0
    *cur_pw = NULL;
2335
0
  }
2336
0
  if (_last_set_time != NULL) {
2337
0
    *_last_set_time = 0;
2338
0
  }
2339
0
  if (prev_pw != NULL) {
2340
0
    *prev_pw = NULL;
2341
0
  }
2342
2343
  /* if we are a DC and this is not our domain, then lookup an account
2344
   * for the domain trust */
2345
2346
0
  if (is_dc_trusted_domain_situation(domain)) {
2347
0
    if (!lp_allow_trusted_domains()) {
2348
0
      return false;
2349
0
    }
2350
2351
0
    if (!pdb_get_trusteddom_pw(domain, cur_pw, NULL,
2352
0
             &last_set_time))
2353
0
    {
2354
0
      DEBUG(0, ("get_trust_pw: could not fetch trust "
2355
0
        "account password for trusted domain %s\n",
2356
0
        domain));
2357
0
      return false;
2358
0
    }
2359
2360
0
    if (channel != NULL) {
2361
0
      *channel = SEC_CHAN_DOMAIN;
2362
0
    }
2363
2364
0
    if (account_name != NULL) {
2365
0
      *account_name = lp_workgroup();
2366
0
    }
2367
2368
0
    if (_last_set_time != NULL) {
2369
0
      *_last_set_time = last_set_time;
2370
0
    }
2371
2372
0
    return true;
2373
0
  }
2374
2375
  /*
2376
   * Since we can only be member of one single domain, we are now
2377
   * in a member situation:
2378
   *
2379
   *  -  Either we are a DC (selfjoined) and the domain is our
2380
   *     own domain.
2381
   *  -  Or we are on a member and the domain is our own or some
2382
   *     other (potentially trusted) domain.
2383
   *
2384
   * In both cases, we can only get the machine account password
2385
   * for our own domain to connect to our own dc. (For a member,
2386
   * request to trusted domains are performed through our dc.)
2387
   *
2388
   * So we simply use our own domain name to retrieve the
2389
   * machine account password and ignore the request domain here.
2390
   */
2391
2392
0
  pwd = secrets_fetch_machine_password(lp_workgroup(), &last_set_time, channel);
2393
2394
0
  if (pwd != NULL) {
2395
0
    struct timeval expire;
2396
2397
0
    *cur_pw = pwd;
2398
2399
0
    if (account_name != NULL) {
2400
0
      *account_name = lp_netbios_name();
2401
0
    }
2402
2403
0
    if (_last_set_time != NULL) {
2404
0
      *_last_set_time = last_set_time;
2405
0
    }
2406
2407
0
    if (prev_pw == NULL) {
2408
0
      return true;
2409
0
    }
2410
2411
0
    ZERO_STRUCT(expire);
2412
0
    expire.tv_sec = lp_machine_password_timeout();
2413
0
    expire.tv_sec /= 2;
2414
0
    expire.tv_sec += last_set_time;
2415
0
    if (timeval_expired(&expire)) {
2416
0
      return true;
2417
0
    }
2418
2419
0
    pwd = secrets_fetch_prev_machine_password(lp_workgroup());
2420
0
    if (pwd != NULL) {
2421
0
      *prev_pw = pwd;
2422
0
    }
2423
2424
0
    return true;
2425
0
  }
2426
2427
0
  DEBUG(5, ("get_trust_pw_clear2: could not fetch clear text trust "
2428
0
      "account password for domain %s\n", domain));
2429
0
  return false;
2430
0
}
2431
2432
bool get_trust_pw_clear(const char *domain, char **ret_pwd,
2433
      const char **account_name,
2434
      enum netr_SchannelType *channel)
2435
0
{
2436
0
  return get_trust_pw_clear2(domain,
2437
0
           account_name,
2438
0
           channel,
2439
0
           ret_pwd,
2440
0
           NULL,
2441
0
           NULL);
2442
0
}
2443
2444
/*******************************************************************
2445
 Wrapper around retrieving the trust account password.
2446
 appropriate account name is stored in account_name.
2447
*******************************************************************/
2448
2449
static bool get_trust_pw_hash2(const char *domain,
2450
             const char **account_name,
2451
             enum netr_SchannelType *channel,
2452
             struct samr_Password *current_nt_hash,
2453
             time_t *last_set_time,
2454
             struct samr_Password **_previous_nt_hash)
2455
0
{
2456
0
  char *cur_pw = NULL;
2457
0
  char *prev_pw = NULL;
2458
0
  char **_prev_pw = NULL;
2459
0
  bool ok;
2460
2461
0
  if (_previous_nt_hash != NULL) {
2462
0
    *_previous_nt_hash = NULL;
2463
0
    _prev_pw = &prev_pw;
2464
0
  }
2465
2466
0
  ok = get_trust_pw_clear2(domain, account_name, channel,
2467
0
         &cur_pw, last_set_time, _prev_pw);
2468
0
  if (ok) {
2469
0
    struct samr_Password *previous_nt_hash = NULL;
2470
2471
0
    E_md4hash(cur_pw, current_nt_hash->hash);
2472
0
    BURN_FREE_STR(cur_pw);
2473
2474
0
    if (prev_pw == NULL) {
2475
0
      return true;
2476
0
    }
2477
2478
0
    previous_nt_hash = SMB_MALLOC_P(struct samr_Password);
2479
0
    if (previous_nt_hash == NULL) {
2480
0
      return false;
2481
0
    }
2482
2483
0
    E_md4hash(prev_pw, previous_nt_hash->hash);
2484
0
    BURN_FREE_STR(prev_pw);
2485
2486
0
    *_previous_nt_hash = previous_nt_hash;
2487
0
    return true;
2488
0
  } else if (is_dc_trusted_domain_situation(domain)) {
2489
0
    return false;
2490
0
  }
2491
2492
  /* as a fallback, try to get the hashed pwd directly from the tdb... */
2493
2494
0
  if (secrets_fetch_trust_account_password_legacy(domain,
2495
0
              current_nt_hash->hash,
2496
0
              last_set_time,
2497
0
              channel))
2498
0
  {
2499
0
    if (account_name != NULL) {
2500
0
      *account_name = lp_netbios_name();
2501
0
    }
2502
2503
0
    return true;
2504
0
  }
2505
2506
0
  DEBUG(5, ("get_trust_pw_hash: could not fetch trust account "
2507
0
    "password for domain %s\n", domain));
2508
0
  return False;
2509
0
}
2510
2511
bool get_trust_pw_hash(const char *domain, uint8_t ret_pwd[16],
2512
           const char **account_name,
2513
           enum netr_SchannelType *channel)
2514
0
{
2515
0
  struct samr_Password current_nt_hash;
2516
0
  bool ok;
2517
2518
0
  ok = get_trust_pw_hash2(domain, account_name, channel,
2519
0
        &current_nt_hash, NULL, NULL);
2520
0
  if (!ok) {
2521
0
    return false;
2522
0
  }
2523
2524
0
  memcpy(ret_pwd, current_nt_hash.hash, sizeof(current_nt_hash.hash));
2525
0
  return true;
2526
0
}
2527
2528
NTSTATUS pdb_get_trust_credentials(const char *netbios_domain,
2529
           const char *dns_domain, /* optional */
2530
           TALLOC_CTX *mem_ctx,
2531
           struct cli_credentials **_creds)
2532
0
{
2533
0
  TALLOC_CTX *frame = talloc_stackframe();
2534
0
  NTSTATUS status;
2535
0
  struct loadparm_context *lp_ctx;
2536
0
  enum netr_SchannelType channel;
2537
0
  time_t last_set_time;
2538
0
  const char *_account_name;
2539
0
  const char *account_name;
2540
0
  char *cur_pw = NULL;
2541
0
  char *prev_pw = NULL;
2542
0
  struct samr_Password cur_nt_hash;
2543
0
  struct cli_credentials *creds = NULL;
2544
0
  bool ok;
2545
2546
  /*
2547
   * If this is our primary trust relationship, use the common
2548
   * code to read the secrets.ldb or secrets.tdb file.
2549
   */
2550
0
  if (strequal(netbios_domain, lp_workgroup())) {
2551
0
    struct db_context *db_ctx = secrets_db_ctx();
2552
0
    if (db_ctx == NULL) {
2553
0
      DEBUG(1, ("failed to open secrets.tdb to obtain our trust credentials for %s\n",
2554
0
          netbios_domain));
2555
0
      status = NT_STATUS_INTERNAL_ERROR;
2556
0
      goto fail;
2557
0
    }
2558
2559
0
    lp_ctx = loadparm_init_s3(frame, loadparm_s3_helpers());
2560
0
    if (lp_ctx == NULL) {
2561
0
      DEBUG(1, ("loadparm_init_s3 failed\n"));
2562
0
      status = NT_STATUS_INTERNAL_ERROR;
2563
0
      goto fail;
2564
0
    }
2565
2566
0
    creds = cli_credentials_init(mem_ctx);
2567
0
    if (creds == NULL) {
2568
0
      status = NT_STATUS_NO_MEMORY;
2569
0
      goto fail;
2570
0
    }
2571
2572
0
    ok = cli_credentials_set_conf(creds, lp_ctx);
2573
0
    if (!ok) {
2574
0
      status = NT_STATUS_INTERNAL_ERROR;
2575
0
      goto fail;
2576
0
    }
2577
2578
0
    ok = cli_credentials_set_domain(creds, netbios_domain, CRED_SPECIFIED);
2579
0
    if (!ok) {
2580
0
      status = NT_STATUS_NO_MEMORY;
2581
0
      goto fail;
2582
0
    }
2583
2584
0
    status = cli_credentials_set_machine_account_db_ctx(creds,
2585
0
                    lp_ctx,
2586
0
                    db_ctx);
2587
0
    if (!NT_STATUS_IS_OK(status)) {
2588
0
      goto fail;
2589
0
    }
2590
0
    goto done;
2591
0
  } else if (!IS_DC) {
2592
0
    DEBUG(1, ("Refusing to get trust account info for %s, "
2593
0
        "which is not our primary domain %s, "
2594
0
        "as we are not a DC\n",
2595
0
        netbios_domain, lp_workgroup()));
2596
0
    status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2597
0
    goto fail;
2598
0
  }
2599
2600
0
  status = pdb_get_trusteddom_creds(netbios_domain, mem_ctx, &creds);
2601
0
  if (NT_STATUS_IS_OK(status)) {
2602
0
    goto done;
2603
0
  }
2604
0
  if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
2605
0
    goto fail;
2606
0
  }
2607
2608
0
  ok = get_trust_pw_clear2(netbios_domain,
2609
0
         &_account_name,
2610
0
         &channel,
2611
0
         &cur_pw,
2612
0
         &last_set_time,
2613
0
         &prev_pw);
2614
0
  if (!ok) {
2615
0
    ok = get_trust_pw_hash2(netbios_domain,
2616
0
          &_account_name,
2617
0
          &channel,
2618
0
          &cur_nt_hash,
2619
0
          &last_set_time,
2620
0
          NULL);
2621
0
    if (!ok) {
2622
0
      DEBUG(1, ("get_trust_pw_*2 failed for domain[%s]\n",
2623
0
          netbios_domain));
2624
0
      status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2625
0
      goto fail;
2626
0
    }
2627
0
  }
2628
2629
0
  account_name = talloc_asprintf(frame, "%s$", _account_name);
2630
0
  if (account_name == NULL) {
2631
0
    status = NT_STATUS_NO_MEMORY;
2632
0
    goto fail;
2633
0
  }
2634
2635
0
  lp_ctx = loadparm_init_s3(frame, loadparm_s3_helpers());
2636
0
  if (lp_ctx == NULL) {
2637
0
    DEBUG(1, ("loadparm_init_s3 failed\n"));
2638
0
    status = NT_STATUS_INTERNAL_ERROR;
2639
0
    goto fail;
2640
0
  }
2641
2642
0
  creds = cli_credentials_init(mem_ctx);
2643
0
  if (creds == NULL) {
2644
0
    status = NT_STATUS_NO_MEMORY;
2645
0
    goto fail;
2646
0
  }
2647
2648
0
  ok = cli_credentials_set_conf(creds, lp_ctx);
2649
0
  if (!ok) {
2650
0
    status = NT_STATUS_INTERNAL_ERROR;
2651
0
    goto fail;
2652
0
  }
2653
2654
0
  cli_credentials_set_secure_channel_type(creds, channel);
2655
0
  cli_credentials_set_password_last_changed_time(creds, last_set_time);
2656
2657
0
  ok = cli_credentials_set_domain(creds, netbios_domain, CRED_SPECIFIED);
2658
0
  if (!ok) {
2659
0
    status = NT_STATUS_NO_MEMORY;
2660
0
    goto fail;
2661
0
  }
2662
2663
0
  if (dns_domain != NULL) {
2664
0
    ok = cli_credentials_set_realm(creds, dns_domain, CRED_SPECIFIED);
2665
0
    if (!ok) {
2666
0
      status = NT_STATUS_NO_MEMORY;
2667
0
      goto fail;
2668
0
    }
2669
2670
    /*
2671
     * It's not possible to use NTLMSSP with a domain trust account.
2672
     */
2673
0
    cli_credentials_set_kerberos_state(creds,
2674
0
               CRED_USE_KERBEROS_REQUIRED,
2675
0
               CRED_SPECIFIED);
2676
0
  } else {
2677
    /*
2678
     * We can't use kerberos against an NT4 domain.
2679
     *
2680
     * We should have a mode that also disallows NTLMSSP here,
2681
     * as only NETLOGON SCHANNEL is possible.
2682
     */
2683
0
    cli_credentials_set_kerberos_state(creds,
2684
0
               CRED_USE_KERBEROS_DISABLED,
2685
0
               CRED_SPECIFIED);
2686
0
  }
2687
2688
0
  ok = cli_credentials_set_username(creds, account_name, CRED_SPECIFIED);
2689
0
  if (!ok) {
2690
0
    status = NT_STATUS_NO_MEMORY;
2691
0
    goto fail;
2692
0
  }
2693
2694
0
  if (cur_pw == NULL) {
2695
0
    ok = cli_credentials_set_nt_hash(creds, &cur_nt_hash, CRED_SPECIFIED);
2696
0
    if (!ok) {
2697
0
      status = NT_STATUS_NO_MEMORY;
2698
0
      goto fail;
2699
0
    }
2700
    /*
2701
     * We currently can't do kerberos just with an NTHASH.
2702
     */
2703
0
    cli_credentials_set_kerberos_state(creds,
2704
0
               CRED_USE_KERBEROS_DISABLED,
2705
0
               CRED_SPECIFIED);
2706
0
    goto done;
2707
0
  }
2708
2709
0
  ok = cli_credentials_set_password(creds, cur_pw, CRED_SPECIFIED);
2710
0
  if (!ok) {
2711
0
    status = NT_STATUS_NO_MEMORY;
2712
0
    goto fail;
2713
0
  }
2714
2715
0
  if (prev_pw != NULL) {
2716
0
    ok = cli_credentials_set_old_password(creds, prev_pw, CRED_SPECIFIED);
2717
0
    if (!ok) {
2718
0
      status = NT_STATUS_NO_MEMORY;
2719
0
      goto fail;
2720
0
    }
2721
0
  }
2722
2723
0
 done:
2724
0
  *_creds = creds;
2725
0
  creds = NULL;
2726
0
  status = NT_STATUS_OK;
2727
0
 fail:
2728
0
  TALLOC_FREE(creds);
2729
0
  SAFE_FREE(cur_pw);
2730
0
  SAFE_FREE(prev_pw);
2731
  TALLOC_FREE(frame);
2732
0
  return status;
2733
0
}