Coverage Report

Created: 2026-07-25 07:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/samba/source3/passdb/pdb_get_set.c
Line
Count
Source
1
/*
2
   Unix SMB/CIFS implementation.
3
   struct samu access routines
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) Stefan (metze) Metzmacher  2002
9
10
   This program is free software; you can redistribute it and/or modify
11
   it under the terms of the GNU General Public License as published by
12
   the Free Software Foundation; either version 3 of the License, or
13
   (at your option) any later version.
14
15
   This program is distributed in the hope that it will be useful,
16
   but WITHOUT ANY WARRANTY; without even the implied warranty of
17
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
   GNU General Public License for more details.
19
20
   You should have received a copy of the GNU General Public License
21
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
22
*/
23
24
#include "includes.h"
25
#include "passdb.h"
26
#include "../libcli/auth/libcli_auth.h"
27
#include "../libcli/security/security.h"
28
#include "../lib/util/bitmap.h"
29
30
#undef DBGC_CLASS
31
0
#define DBGC_CLASS DBGC_PASSDB
32
33
/**
34
 * @todo Redefine this to NULL, but this changes the API because
35
 *       much of samba assumes that the pdb_get...() functions
36
 *       return strings.  (ie not null-pointers).
37
 *       See also pdb_fill_default_sam().
38
 */
39
40
0
#define PDB_NOT_QUITE_NULL ""
41
42
/*********************************************************************
43
 Test if a change time is a max value. Copes with old and new values
44
 of max.
45
 ********************************************************************/
46
47
bool pdb_is_password_change_time_max(time_t test_time)
48
0
{
49
0
  if (test_time == get_time_t_max()) {
50
0
    return true;
51
0
  }
52
0
#if (defined(SIZEOF_TIME_T) && (SIZEOF_TIME_T == 8))
53
0
  if (test_time == 0x7FFFFFFFFFFFFFFFLL) {
54
0
    return true;
55
0
  }
56
0
#endif
57
0
  if (test_time == 0x7FFFFFFF) {
58
0
    return true;
59
0
  }
60
0
  return false;
61
0
}
62
63
/*********************************************************************
64
 Return an unchanging version of max password change time - 0x7FFFFFFF.
65
 ********************************************************************/
66
67
static time_t pdb_password_change_time_max(void)
68
0
{
69
0
  return 0x7FFFFFFF;
70
0
}
71
72
/*********************************************************************
73
 Collection of get...() functions for struct samu.
74
 ********************************************************************/
75
76
uint32_t pdb_get_acct_ctrl(const struct samu *sampass)
77
0
{
78
0
  return sampass->acct_ctrl;
79
0
}
80
81
time_t pdb_get_logon_time(const struct samu *sampass)
82
0
{
83
0
  return sampass->logon_time;
84
0
}
85
86
time_t pdb_get_logoff_time(const struct samu *sampass)
87
0
{
88
0
  return sampass->logoff_time;
89
0
}
90
91
time_t pdb_get_kickoff_time(const struct samu *sampass)
92
0
{
93
0
  return sampass->kickoff_time;
94
0
}
95
96
time_t pdb_get_bad_password_time(const struct samu *sampass)
97
0
{
98
0
  return sampass->bad_password_time;
99
0
}
100
101
time_t pdb_get_pass_last_set_time(const struct samu *sampass)
102
0
{
103
0
  return sampass->pass_last_set_time;
104
0
}
105
106
time_t pdb_get_pass_can_change_time(const struct samu *sampass)
107
0
{
108
0
  uint32_t allow;
109
110
  /* if the last set time is zero, it means the user cannot
111
     change their password, and this time must be zero.   jmcd
112
  */
113
0
  if (sampass->pass_last_set_time == 0)
114
0
    return (time_t) 0;
115
116
  /* if the time is max, and the field has been changed,
117
     we're trying to update this real value from the sampass
118
     to indicate that the user cannot change their password.  jmcd
119
  */
120
0
  if (pdb_is_password_change_time_max(sampass->pass_can_change_time) &&
121
0
      IS_SAM_CHANGED(sampass, PDB_CANCHANGETIME))
122
0
    return sampass->pass_can_change_time;
123
124
0
  if (!pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &allow))
125
0
    allow = 0;
126
127
  /* in normal cases, just calculate it from policy */
128
0
  return sampass->pass_last_set_time + allow;
129
0
}
130
131
/* we need this for loading from the backend, so that we don't overwrite
132
   non-changed max times, otherwise the pass_can_change checking won't work */
133
time_t pdb_get_pass_can_change_time_noncalc(const struct samu *sampass)
134
0
{
135
0
  return sampass->pass_can_change_time;
136
0
}
137
138
time_t pdb_get_pass_must_change_time(const struct samu *sampass)
139
0
{
140
0
  uint32_t expire;
141
142
0
  if (sampass->pass_last_set_time == 0)
143
0
    return (time_t) 0;
144
145
0
  if (sampass->acct_ctrl & ACB_PWNOEXP)
146
0
    return pdb_password_change_time_max();
147
148
0
  if (!pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &expire)
149
0
      || expire == (uint32_t)-1 || expire == 0)
150
0
    return get_time_t_max();
151
152
0
  return sampass->pass_last_set_time + expire;
153
0
}
154
155
bool pdb_get_pass_can_change(const struct samu *sampass)
156
0
{
157
0
  if (pdb_is_password_change_time_max(sampass->pass_can_change_time))
158
0
    return False;
159
0
  return True;
160
0
}
161
162
uint16_t pdb_get_logon_divs(const struct samu *sampass)
163
0
{
164
0
  return sampass->logon_divs;
165
0
}
166
167
uint32_t pdb_get_hours_len(const struct samu *sampass)
168
0
{
169
0
  return sampass->hours_len;
170
0
}
171
172
const uint8_t *pdb_get_hours(const struct samu *sampass)
173
0
{
174
0
  return (sampass->hours);
175
0
}
176
177
const uint8_t *pdb_get_nt_passwd(const struct samu *sampass)
178
0
{
179
0
  SMB_ASSERT((!sampass->nt_pw.data)
180
0
       || sampass->nt_pw.length == NT_HASH_LEN);
181
0
  return (uint8_t *)sampass->nt_pw.data;
182
0
}
183
184
const uint8_t *pdb_get_lanman_passwd(const struct samu *sampass)
185
0
{
186
0
  SMB_ASSERT((!sampass->lm_pw.data)
187
0
       || sampass->lm_pw.length == LM_HASH_LEN);
188
0
  return (uint8_t *)sampass->lm_pw.data;
189
0
}
190
191
const uint8_t *pdb_get_pw_history(const struct samu *sampass, uint32_t *current_hist_len)
192
0
{
193
0
  SMB_ASSERT((!sampass->nt_pw_his.data)
194
0
     || ((sampass->nt_pw_his.length % PW_HISTORY_ENTRY_LEN) == 0));
195
0
  *current_hist_len = sampass->nt_pw_his.length / PW_HISTORY_ENTRY_LEN;
196
0
  return (uint8_t *)sampass->nt_pw_his.data;
197
0
}
198
199
/* Return the plaintext password if known.  Most of the time
200
   it isn't, so don't assume anything magic about this function.
201
202
   Used to pass the plaintext to passdb backends that might
203
   want to store more than just the NTLM hashes.
204
*/
205
const char *pdb_get_plaintext_passwd(const struct samu *sampass)
206
0
{
207
0
  return sampass->plaintext_pw;
208
0
}
209
210
const struct dom_sid *pdb_get_user_sid(const struct samu *sampass)
211
0
{
212
0
  return &sampass->user_sid;
213
0
}
214
215
const struct dom_sid *pdb_get_group_sid(struct samu *sampass)
216
0
{
217
0
  NTSTATUS status;
218
219
  /* Return the cached group SID if we have that */
220
0
  if (sampass->group_sid) {
221
0
    return sampass->group_sid;
222
0
  }
223
224
  /* No algorithmic mapping, meaning that we have to figure out the
225
     primary group SID according to group mapping and the user SID must
226
     be a newly allocated one.  We rely on the user's Unix primary gid.
227
     We have no choice but to fail if we can't find it. */
228
0
  status = get_primary_group_sid(sampass,
229
0
          pdb_get_username(sampass),
230
0
          &sampass->unix_pw,
231
0
          &sampass->group_sid);
232
0
  if (!NT_STATUS_IS_OK(status)) {
233
0
    return NULL;
234
0
  }
235
236
0
  return sampass->group_sid;
237
0
}
238
239
/**
240
 * Get flags showing what is initialised in the struct samu
241
 * @param sampass the struct samu in question
242
 * @return the flags indicating the members initialised in the struct.
243
 **/
244
245
enum pdb_value_state pdb_get_init_flags(const struct samu *sampass, enum pdb_elements element)
246
0
{
247
0
  enum pdb_value_state ret = PDB_DEFAULT;
248
249
0
        if (!sampass->change_flags || !sampass->set_flags)
250
0
    return ret;
251
252
0
        if (bitmap_query(sampass->set_flags, element)) {
253
0
    DEBUG(11, ("element %d: SET\n", element));
254
0
    ret = PDB_SET;
255
0
  }
256
257
0
        if (bitmap_query(sampass->change_flags, element)) {
258
0
    DEBUG(11, ("element %d: CHANGED\n", element));
259
0
    ret = PDB_CHANGED;
260
0
  }
261
262
0
  if (ret == PDB_DEFAULT) {
263
0
    DEBUG(11, ("element %d: DEFAULT\n", element));
264
0
  }
265
266
0
        return ret;
267
0
}
268
269
const char *pdb_get_username(const struct samu *sampass)
270
0
{
271
0
  return sampass->username;
272
0
}
273
274
const char *pdb_get_domain(const struct samu *sampass)
275
0
{
276
0
  return sampass->domain;
277
0
}
278
279
const char *pdb_get_nt_username(const struct samu *sampass)
280
0
{
281
0
  return sampass->nt_username;
282
0
}
283
284
const char *pdb_get_fullname(const struct samu *sampass)
285
0
{
286
0
  return sampass->full_name;
287
0
}
288
289
const char *pdb_get_homedir(const struct samu *sampass)
290
0
{
291
0
  return sampass->home_dir;
292
0
}
293
294
const char *pdb_get_dir_drive(const struct samu *sampass)
295
0
{
296
0
  return sampass->dir_drive;
297
0
}
298
299
const char *pdb_get_logon_script(const struct samu *sampass)
300
0
{
301
0
  return sampass->logon_script;
302
0
}
303
304
const char *pdb_get_profile_path(const struct samu *sampass)
305
0
{
306
0
  return sampass->profile_path;
307
0
}
308
309
const char *pdb_get_acct_desc(const struct samu *sampass)
310
0
{
311
0
  return sampass->acct_desc;
312
0
}
313
314
const char *pdb_get_workstations(const struct samu *sampass)
315
0
{
316
0
  return sampass->workstations;
317
0
}
318
319
const char *pdb_get_comment(const struct samu *sampass)
320
0
{
321
0
  return sampass->comment;
322
0
}
323
324
const char *pdb_get_munged_dial(const struct samu *sampass)
325
0
{
326
0
  return sampass->munged_dial;
327
0
}
328
329
uint16_t pdb_get_bad_password_count(const struct samu *sampass)
330
0
{
331
0
  return sampass->bad_password_count;
332
0
}
333
334
uint16_t pdb_get_logon_count(const struct samu *sampass)
335
0
{
336
0
  return sampass->logon_count;
337
0
}
338
339
uint16_t pdb_get_country_code(const struct samu *sampass)
340
0
{
341
0
  return sampass->country_code;
342
0
}
343
344
uint16_t pdb_get_code_page(const struct samu *sampass)
345
0
{
346
0
  return sampass->code_page;
347
0
}
348
349
uint32_t pdb_get_unknown_6(const struct samu *sampass)
350
0
{
351
0
  return sampass->unknown_6;
352
0
}
353
354
void *pdb_get_backend_private_data(const struct samu *sampass, const struct pdb_methods *my_methods)
355
0
{
356
0
  if (my_methods == sampass->backend_private_methods) {
357
0
    return sampass->backend_private_data;
358
0
  } else {
359
0
    return NULL;
360
0
  }
361
0
}
362
363
/*********************************************************************
364
 Collection of set...() functions for struct samu.
365
 ********************************************************************/
366
367
bool pdb_set_acct_ctrl(struct samu *sampass, uint32_t acct_ctrl, enum pdb_value_state flag)
368
0
{
369
0
  sampass->acct_ctrl = acct_ctrl;
370
0
  return pdb_set_init_flags(sampass, PDB_ACCTCTRL, flag);
371
0
}
372
373
bool pdb_set_logon_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
374
0
{
375
0
  sampass->logon_time = mytime;
376
0
  return pdb_set_init_flags(sampass, PDB_LOGONTIME, flag);
377
0
}
378
379
bool pdb_set_logoff_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
380
0
{
381
0
  sampass->logoff_time = mytime;
382
0
  return pdb_set_init_flags(sampass, PDB_LOGOFFTIME, flag);
383
0
}
384
385
bool pdb_set_kickoff_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
386
0
{
387
0
  sampass->kickoff_time = mytime;
388
0
  return pdb_set_init_flags(sampass, PDB_KICKOFFTIME, flag);
389
0
}
390
391
bool pdb_set_bad_password_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
392
0
{
393
0
  sampass->bad_password_time = mytime;
394
0
  return pdb_set_init_flags(sampass, PDB_BAD_PASSWORD_TIME, flag);
395
0
}
396
397
bool pdb_set_pass_can_change_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
398
0
{
399
0
  sampass->pass_can_change_time = mytime;
400
0
  return pdb_set_init_flags(sampass, PDB_CANCHANGETIME, flag);
401
0
}
402
403
bool pdb_set_pass_last_set_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
404
0
{
405
0
  sampass->pass_last_set_time = mytime;
406
0
  return pdb_set_init_flags(sampass, PDB_PASSLASTSET, flag);
407
0
}
408
409
bool pdb_set_hours_len(struct samu *sampass, uint32_t len, enum pdb_value_state flag)
410
0
{
411
0
  sampass->hours_len = len;
412
0
  return pdb_set_init_flags(sampass, PDB_HOURSLEN, flag);
413
0
}
414
415
bool pdb_set_logon_divs(struct samu *sampass, uint16_t hours, enum pdb_value_state flag)
416
0
{
417
0
  sampass->logon_divs = hours;
418
0
  return pdb_set_init_flags(sampass, PDB_LOGONDIVS, flag);
419
0
}
420
421
/**
422
 * Set flags showing what is initialised in the struct samu
423
 * @param sampass the struct samu in question
424
 * @param flag The *new* flag to be set.  Old flags preserved
425
 *             this flag is only added.
426
 **/
427
428
bool pdb_set_init_flags(struct samu *sampass, enum pdb_elements element, enum pdb_value_state value_flag)
429
0
{
430
0
  if (!sampass->set_flags) {
431
0
    if ((sampass->set_flags =
432
0
      bitmap_talloc(sampass,
433
0
          PDB_COUNT))==NULL) {
434
0
      DEBUG(0,("bitmap_talloc failed\n"));
435
0
      return False;
436
0
    }
437
0
  }
438
0
  if (!sampass->change_flags) {
439
0
    if ((sampass->change_flags =
440
0
      bitmap_talloc(sampass,
441
0
          PDB_COUNT))==NULL) {
442
0
      DEBUG(0,("bitmap_talloc failed\n"));
443
0
      return False;
444
0
    }
445
0
  }
446
447
0
  switch(value_flag) {
448
0
  case PDB_CHANGED:
449
0
    if (!bitmap_set(sampass->change_flags, element)) {
450
0
        DEBUG(0,("Can't set flag: %d in change_flags.\n",element));
451
0
        return False;
452
0
      }
453
0
      if (!bitmap_set(sampass->set_flags, element)) {
454
0
        DEBUG(0,("Can't set flag: %d in set_flags.\n",element));
455
0
        return False;
456
0
      }
457
0
      DEBUG(11, ("element %d -> now CHANGED\n", element));
458
0
      break;
459
0
    case PDB_SET:
460
0
      if (!bitmap_clear(sampass->change_flags, element)) {
461
0
        DEBUG(0,("Can't set flag: %d in change_flags.\n",element));
462
0
        return False;
463
0
      }
464
0
      if (!bitmap_set(sampass->set_flags, element)) {
465
0
        DEBUG(0,("Can't set flag: %d in set_flags.\n",element));
466
0
        return False;
467
0
      }
468
0
      DEBUG(11, ("element %d -> now SET\n", element));
469
0
      break;
470
0
    case PDB_DEFAULT:
471
0
    default:
472
0
      if (!bitmap_clear(sampass->change_flags, element)) {
473
0
        DEBUG(0,("Can't set flag: %d in change_flags.\n",element));
474
0
        return False;
475
0
      }
476
0
      if (!bitmap_clear(sampass->set_flags, element)) {
477
0
        DEBUG(0,("Can't set flag: %d in set_flags.\n",element));
478
0
        return False;
479
0
      }
480
0
      DEBUG(11, ("element %d -> now DEFAULT\n", element));
481
0
      break;
482
0
  }
483
484
0
        return True;
485
0
}
486
487
bool pdb_set_user_sid(struct samu *sampass, const struct dom_sid *u_sid, enum pdb_value_state flag)
488
0
{
489
0
  struct dom_sid_buf buf;
490
491
0
  if (!u_sid)
492
0
    return False;
493
494
0
  sid_copy(&sampass->user_sid, u_sid);
495
496
0
  DEBUG(10, ("pdb_set_user_sid: setting user sid %s\n",
497
0
       dom_sid_str_buf(&sampass->user_sid, &buf)));
498
499
0
  return pdb_set_init_flags(sampass, PDB_USERSID, flag);
500
0
}
501
502
bool pdb_set_user_sid_from_string(struct samu *sampass, const char *u_sid, enum pdb_value_state flag)
503
0
{
504
0
  struct dom_sid new_sid;
505
506
0
  if (!u_sid)
507
0
    return False;
508
509
0
  DEBUG(10, ("pdb_set_user_sid_from_string: setting user sid %s\n",
510
0
       u_sid));
511
512
0
  if (!string_to_sid(&new_sid, u_sid)) {
513
0
    DEBUG(1, ("pdb_set_user_sid_from_string: %s isn't a valid SID!\n", u_sid));
514
0
    return False;
515
0
  }
516
517
0
  if (!pdb_set_user_sid(sampass, &new_sid, flag)) {
518
0
    DEBUG(1, ("pdb_set_user_sid_from_string: could not set sid %s on struct samu!\n", u_sid));
519
0
    return False;
520
0
  }
521
522
0
  return True;
523
0
}
524
525
/********************************************************************
526
 We never fill this in from a passdb backend but rather set is
527
 based on the user's primary group membership.  However, the
528
 struct samu* is overloaded and reused in domain memship code
529
 as well and built from the netr_SamInfo3 or PAC so we
530
 have to allow the explicitly setting of a group SID here.
531
********************************************************************/
532
533
bool pdb_set_group_sid(struct samu *sampass, const struct dom_sid *g_sid, enum pdb_value_state flag)
534
0
{
535
0
  gid_t gid;
536
0
  struct dom_sid dug_sid;
537
0
  struct dom_sid_buf buf;
538
539
0
  if (!g_sid)
540
0
    return False;
541
542
0
  if ( !(sampass->group_sid = talloc( sampass, struct dom_sid )) ) {
543
0
    return False;
544
0
  }
545
546
  /* if we cannot resolve the SID to gid, then just ignore it and
547
     store DOMAIN_USERS as the primary groupSID */
548
549
0
  sid_compose(&dug_sid, get_global_sam_sid(), DOMAIN_RID_USERS);
550
551
0
  if (dom_sid_equal(&dug_sid, g_sid)) {
552
0
    sid_copy(sampass->group_sid, &dug_sid);
553
0
  } else if (sid_to_gid( g_sid, &gid ) ) {
554
0
    sid_copy(sampass->group_sid, g_sid);
555
0
  } else {
556
0
    sid_copy(sampass->group_sid, &dug_sid);
557
0
  }
558
559
0
  DEBUG(10, ("pdb_set_group_sid: setting group sid %s\n",
560
0
       dom_sid_str_buf(sampass->group_sid, &buf)));
561
562
0
  return pdb_set_init_flags(sampass, PDB_GROUPSID, flag);
563
0
}
564
565
/*********************************************************************
566
 Set the user's UNIX name.
567
 ********************************************************************/
568
569
bool pdb_set_username(struct samu *sampass, const char *username, enum pdb_value_state flag)
570
0
{
571
0
  if (username) {
572
0
    DEBUG(10, ("pdb_set_username: setting username %s, was %s\n", username,
573
0
      (sampass->username)?(sampass->username):"NULL"));
574
575
0
    sampass->username = talloc_strdup(sampass, username);
576
577
0
    if (!sampass->username) {
578
0
      DEBUG(0, ("pdb_set_username: talloc_strdup() failed!\n"));
579
0
      return False;
580
0
    }
581
0
  } else {
582
0
    sampass->username = PDB_NOT_QUITE_NULL;
583
0
  }
584
585
0
  return pdb_set_init_flags(sampass, PDB_USERNAME, flag);
586
0
}
587
588
/*********************************************************************
589
 Set the domain name.
590
 ********************************************************************/
591
592
bool pdb_set_domain(struct samu *sampass, const char *domain, enum pdb_value_state flag)
593
0
{
594
0
  if (domain) {
595
0
    DEBUG(10, ("pdb_set_domain: setting domain %s, was %s\n", domain,
596
0
      (sampass->domain)?(sampass->domain):"NULL"));
597
598
0
    sampass->domain = talloc_strdup(sampass, domain);
599
600
0
    if (!sampass->domain) {
601
0
      DEBUG(0, ("pdb_set_domain: talloc_strdup() failed!\n"));
602
0
      return False;
603
0
    }
604
0
  } else {
605
0
    sampass->domain = PDB_NOT_QUITE_NULL;
606
0
  }
607
608
0
  return pdb_set_init_flags(sampass, PDB_DOMAIN, flag);
609
0
}
610
611
/*********************************************************************
612
 Set the user's NT name.
613
 ********************************************************************/
614
615
bool pdb_set_nt_username(struct samu *sampass, const char *nt_username, enum pdb_value_state flag)
616
0
{
617
0
  if (nt_username) {
618
0
    DEBUG(10, ("pdb_set_nt_username: setting nt username %s, was %s\n", nt_username,
619
0
      (sampass->nt_username)?(sampass->nt_username):"NULL"));
620
621
0
    sampass->nt_username = talloc_strdup(sampass, nt_username);
622
623
0
    if (!sampass->nt_username) {
624
0
      DEBUG(0, ("pdb_set_nt_username: talloc_strdup() failed!\n"));
625
0
      return False;
626
0
    }
627
0
  } else {
628
0
    sampass->nt_username = PDB_NOT_QUITE_NULL;
629
0
  }
630
631
0
  return pdb_set_init_flags(sampass, PDB_NTUSERNAME, flag);
632
0
}
633
634
/*********************************************************************
635
 Set the user's full name.
636
 ********************************************************************/
637
638
bool pdb_set_fullname(struct samu *sampass, const char *full_name, enum pdb_value_state flag)
639
0
{
640
0
  if (full_name) {
641
0
    DEBUG(10, ("pdb_set_full_name: setting full name %s, was %s\n", full_name,
642
0
      (sampass->full_name)?(sampass->full_name):"NULL"));
643
644
0
    sampass->full_name = talloc_strdup(sampass, full_name);
645
646
0
    if (!sampass->full_name) {
647
0
      DEBUG(0, ("pdb_set_fullname: talloc_strdup() failed!\n"));
648
0
      return False;
649
0
    }
650
0
  } else {
651
0
    sampass->full_name = PDB_NOT_QUITE_NULL;
652
0
  }
653
654
0
  return pdb_set_init_flags(sampass, PDB_FULLNAME, flag);
655
0
}
656
657
/*********************************************************************
658
 Set the user's logon script.
659
 ********************************************************************/
660
661
bool pdb_set_logon_script(struct samu *sampass, const char *logon_script, enum pdb_value_state flag)
662
0
{
663
0
  if (logon_script) {
664
0
    DEBUG(10, ("pdb_set_logon_script: setting logon script %s, was %s\n", logon_script,
665
0
      (sampass->logon_script)?(sampass->logon_script):"NULL"));
666
667
0
    sampass->logon_script = talloc_strdup(sampass, logon_script);
668
669
0
    if (!sampass->logon_script) {
670
0
      DEBUG(0, ("pdb_set_logon_script: talloc_strdup() failed!\n"));
671
0
      return False;
672
0
    }
673
0
  } else {
674
0
    sampass->logon_script = PDB_NOT_QUITE_NULL;
675
0
  }
676
677
0
  return pdb_set_init_flags(sampass, PDB_LOGONSCRIPT, flag);
678
0
}
679
680
/*********************************************************************
681
 Set the user's profile path.
682
 ********************************************************************/
683
684
bool pdb_set_profile_path(struct samu *sampass, const char *profile_path, enum pdb_value_state flag)
685
0
{
686
0
  if (profile_path) {
687
0
    DEBUG(10, ("pdb_set_profile_path: setting profile path %s, was %s\n", profile_path,
688
0
      (sampass->profile_path)?(sampass->profile_path):"NULL"));
689
690
0
    sampass->profile_path = talloc_strdup(sampass, profile_path);
691
692
0
    if (!sampass->profile_path) {
693
0
      DEBUG(0, ("pdb_set_profile_path: talloc_strdup() failed!\n"));
694
0
      return False;
695
0
    }
696
0
  } else {
697
0
    sampass->profile_path = PDB_NOT_QUITE_NULL;
698
0
  }
699
700
0
  return pdb_set_init_flags(sampass, PDB_PROFILE, flag);
701
0
}
702
703
/*********************************************************************
704
 Set the user's directory drive.
705
 ********************************************************************/
706
707
bool pdb_set_dir_drive(struct samu *sampass, const char *dir_drive, enum pdb_value_state flag)
708
0
{
709
0
  if (dir_drive) {
710
0
    DEBUG(10, ("pdb_set_dir_drive: setting dir drive %s, was %s\n", dir_drive,
711
0
      (sampass->dir_drive)?(sampass->dir_drive):"NULL"));
712
713
0
    sampass->dir_drive = talloc_strdup(sampass, dir_drive);
714
715
0
    if (!sampass->dir_drive) {
716
0
      DEBUG(0, ("pdb_set_dir_drive: talloc_strdup() failed!\n"));
717
0
      return False;
718
0
    }
719
720
0
  } else {
721
0
    sampass->dir_drive = PDB_NOT_QUITE_NULL;
722
0
  }
723
724
0
  return pdb_set_init_flags(sampass, PDB_DRIVE, flag);
725
0
}
726
727
/*********************************************************************
728
 Set the user's home directory.
729
 ********************************************************************/
730
731
bool pdb_set_homedir(struct samu *sampass, const char *home_dir, enum pdb_value_state flag)
732
0
{
733
0
  if (home_dir) {
734
0
    DEBUG(10, ("pdb_set_homedir: setting home dir %s, was %s\n", home_dir,
735
0
      (sampass->home_dir)?(sampass->home_dir):"NULL"));
736
737
0
    sampass->home_dir = talloc_strdup(sampass, home_dir);
738
739
0
    if (!sampass->home_dir) {
740
0
      DEBUG(0, ("pdb_set_home_dir: talloc_strdup() failed!\n"));
741
0
      return False;
742
0
    }
743
0
  } else {
744
0
    sampass->home_dir = PDB_NOT_QUITE_NULL;
745
0
  }
746
747
0
  return pdb_set_init_flags(sampass, PDB_SMBHOME, flag);
748
0
}
749
750
/*********************************************************************
751
 Set the user's account description.
752
 ********************************************************************/
753
754
bool pdb_set_acct_desc(struct samu *sampass, const char *acct_desc, enum pdb_value_state flag)
755
0
{
756
0
  if (acct_desc) {
757
0
    sampass->acct_desc = talloc_strdup(sampass, acct_desc);
758
759
0
    if (!sampass->acct_desc) {
760
0
      DEBUG(0, ("pdb_set_acct_desc: talloc_strdup() failed!\n"));
761
0
      return False;
762
0
    }
763
0
  } else {
764
0
    sampass->acct_desc = PDB_NOT_QUITE_NULL;
765
0
  }
766
767
0
  return pdb_set_init_flags(sampass, PDB_ACCTDESC, flag);
768
0
}
769
770
/*********************************************************************
771
 Set the user's workstation allowed list.
772
 ********************************************************************/
773
774
bool pdb_set_workstations(struct samu *sampass, const char *workstations, enum pdb_value_state flag)
775
0
{
776
0
  if (workstations) {
777
0
    DEBUG(10, ("pdb_set_workstations: setting workstations %s, was %s\n", workstations,
778
0
      (sampass->workstations)?(sampass->workstations):"NULL"));
779
780
0
    sampass->workstations = talloc_strdup(sampass, workstations);
781
782
0
    if (!sampass->workstations) {
783
0
      DEBUG(0, ("pdb_set_workstations: talloc_strdup() failed!\n"));
784
0
      return False;
785
0
    }
786
0
  } else {
787
0
    sampass->workstations = PDB_NOT_QUITE_NULL;
788
0
  }
789
790
0
  return pdb_set_init_flags(sampass, PDB_WORKSTATIONS, flag);
791
0
}
792
793
/*********************************************************************
794
 ********************************************************************/
795
796
bool pdb_set_comment(struct samu *sampass, const char *comment, enum pdb_value_state flag)
797
0
{
798
0
  if (comment) {
799
0
    sampass->comment = talloc_strdup(sampass, comment);
800
801
0
    if (!sampass->comment) {
802
0
      DEBUG(0, ("pdb_set_comment: talloc_strdup() failed!\n"));
803
0
      return False;
804
0
    }
805
0
  } else {
806
0
    sampass->comment = PDB_NOT_QUITE_NULL;
807
0
  }
808
809
0
  return pdb_set_init_flags(sampass, PDB_COMMENT, flag);
810
0
}
811
812
/*********************************************************************
813
 Set the user's dial string.
814
 ********************************************************************/
815
816
bool pdb_set_munged_dial(struct samu *sampass, const char *munged_dial, enum pdb_value_state flag)
817
0
{
818
0
  if (munged_dial) {
819
0
    sampass->munged_dial = talloc_strdup(sampass, munged_dial);
820
821
0
    if (!sampass->munged_dial) {
822
0
      DEBUG(0, ("pdb_set_munged_dial: talloc_strdup() failed!\n"));
823
0
      return False;
824
0
    }
825
0
  } else {
826
0
    sampass->munged_dial = PDB_NOT_QUITE_NULL;
827
0
  }
828
829
0
  return pdb_set_init_flags(sampass, PDB_MUNGEDDIAL, flag);
830
0
}
831
832
/*********************************************************************
833
 Set the user's NT hash.
834
 ********************************************************************/
835
836
bool pdb_set_nt_passwd(struct samu *sampass, const uint8_t pwd[NT_HASH_LEN], enum pdb_value_state flag)
837
0
{
838
0
  data_blob_clear_free(&sampass->nt_pw);
839
840
0
       if (pwd) {
841
0
               sampass->nt_pw =
842
0
           data_blob_talloc(sampass, pwd, NT_HASH_LEN);
843
0
       } else {
844
0
               sampass->nt_pw = data_blob_null;
845
0
       }
846
847
0
  return pdb_set_init_flags(sampass, PDB_NTPASSWD, flag);
848
0
}
849
850
/*********************************************************************
851
 Set the user's LM hash.
852
 ********************************************************************/
853
854
bool pdb_set_lanman_passwd(struct samu *sampass, const uint8_t pwd[LM_HASH_LEN], enum pdb_value_state flag)
855
0
{
856
0
  data_blob_clear_free(&sampass->lm_pw);
857
858
  /* on keep the password if we are allowing LANMAN authentication */
859
860
0
  if (pwd && (flag != PDB_CHANGED || lp_lanman_auth())) {
861
0
    sampass->lm_pw = data_blob_talloc(sampass, pwd, LM_HASH_LEN);
862
0
  } else {
863
0
    sampass->lm_pw = data_blob_null;
864
0
  }
865
866
0
  return pdb_set_init_flags(sampass, PDB_LMPASSWD, flag);
867
0
}
868
869
/*********************************************************************
870
 Set the user's password history hash. historyLen is the number of
871
 PW_HISTORY_SALT_LEN+SALTED_MD5_HASH_LEN length
872
 entries to store in the history - this must match the size of the uint8_t array
873
 in pwd.
874
********************************************************************/
875
876
bool pdb_set_pw_history(struct samu *sampass, const uint8_t *pwd, uint32_t historyLen, enum pdb_value_state flag)
877
0
{
878
0
  DATA_BLOB new_nt_pw_his = {};
879
880
0
  if (historyLen && pwd){
881
0
    new_nt_pw_his = data_blob_talloc(sampass,
882
0
             pwd, historyLen*PW_HISTORY_ENTRY_LEN);
883
0
    if (new_nt_pw_his.length == 0) {
884
0
      DEBUG(0, ("pdb_set_pw_history: data_blob_talloc() failed!\n"));
885
0
      return False;
886
0
    }
887
0
  }
888
889
0
  data_blob_clear_free(&sampass->nt_pw_his);
890
0
  sampass->nt_pw_his = new_nt_pw_his;
891
892
0
  return pdb_set_init_flags(sampass, PDB_PWHISTORY, flag);
893
0
}
894
895
/*********************************************************************
896
 Set the user's plaintext password only (base procedure, see helper
897
 below)
898
 ********************************************************************/
899
900
bool pdb_set_plaintext_pw_only(struct samu *sampass, const char *password, enum pdb_value_state flag)
901
0
{
902
0
  BURN_STR(sampass->plaintext_pw);
903
904
0
  if (password != NULL) {
905
0
    sampass->plaintext_pw = talloc_strdup(sampass, password);
906
907
0
    if (!sampass->plaintext_pw) {
908
0
      DEBUG(0, ("pdb_set_unknown_str: talloc_strdup() failed!\n"));
909
0
      return False;
910
0
    }
911
0
  } else {
912
0
    sampass->plaintext_pw = NULL;
913
0
  }
914
915
0
  return pdb_set_init_flags(sampass, PDB_PLAINTEXT_PW, flag);
916
0
}
917
918
bool pdb_set_bad_password_count(struct samu *sampass, uint16_t bad_password_count, enum pdb_value_state flag)
919
0
{
920
0
  sampass->bad_password_count = bad_password_count;
921
0
  return pdb_set_init_flags(sampass, PDB_BAD_PASSWORD_COUNT, flag);
922
0
}
923
924
bool pdb_set_logon_count(struct samu *sampass, uint16_t logon_count, enum pdb_value_state flag)
925
0
{
926
0
  sampass->logon_count = logon_count;
927
0
  return pdb_set_init_flags(sampass, PDB_LOGON_COUNT, flag);
928
0
}
929
930
bool pdb_set_country_code(struct samu *sampass, uint16_t country_code,
931
        enum pdb_value_state flag)
932
0
{
933
0
  sampass->country_code = country_code;
934
0
  return pdb_set_init_flags(sampass, PDB_COUNTRY_CODE, flag);
935
0
}
936
937
bool pdb_set_code_page(struct samu *sampass, uint16_t code_page,
938
           enum pdb_value_state flag)
939
0
{
940
0
  sampass->code_page = code_page;
941
0
  return pdb_set_init_flags(sampass, PDB_CODE_PAGE, flag);
942
0
}
943
944
bool pdb_set_unknown_6(struct samu *sampass, uint32_t unkn, enum pdb_value_state flag)
945
0
{
946
0
  sampass->unknown_6 = unkn;
947
0
  return pdb_set_init_flags(sampass, PDB_UNKNOWN6, flag);
948
0
}
949
950
bool pdb_set_hours(struct samu *sampass, const uint8_t *hours, int hours_len,
951
       enum pdb_value_state flag)
952
0
{
953
0
  if (hours_len > sizeof(sampass->hours)) {
954
0
    return false;
955
0
  }
956
957
0
  if (!hours) {
958
0
    memset ((char *)sampass->hours, 0, hours_len);
959
0
  } else {
960
0
    memcpy (sampass->hours, hours, hours_len);
961
0
  }
962
963
0
  return pdb_set_init_flags(sampass, PDB_HOURS, flag);
964
0
}
965
966
bool pdb_set_backend_private_data(struct samu *sampass, void *private_data,
967
           void (*free_fn)(void **),
968
           const struct pdb_methods *my_methods,
969
           enum pdb_value_state flag)
970
0
{
971
0
  if (sampass->backend_private_data &&
972
0
      sampass->backend_private_data_free_fn) {
973
0
    sampass->backend_private_data_free_fn(
974
0
      &sampass->backend_private_data);
975
0
  }
976
977
0
  sampass->backend_private_data = private_data;
978
0
  sampass->backend_private_data_free_fn = free_fn;
979
0
  sampass->backend_private_methods = my_methods;
980
981
0
  return pdb_set_init_flags(sampass, PDB_BACKEND_PRIVATE_DATA, flag);
982
0
}
983
984
985
/* Helpful interfaces to the above */
986
987
bool pdb_set_pass_can_change(struct samu *sampass, bool canchange)
988
0
{
989
0
  return pdb_set_pass_can_change_time(sampass,
990
0
             canchange ? 0 : pdb_password_change_time_max(),
991
0
             PDB_CHANGED);
992
0
}
993
994
995
/*********************************************************************
996
 Set the user's PLAINTEXT password.  Used as an interface to the above.
997
 Also sets the last change time to NOW.
998
 ********************************************************************/
999
1000
bool pdb_set_plaintext_passwd(struct samu *sampass, const char *plaintext)
1001
0
{
1002
0
  uchar new_lanman_p16[LM_HASH_LEN];
1003
0
  uchar new_nt_p16[NT_HASH_LEN];
1004
0
  bool ok;
1005
1006
0
  if (!plaintext)
1007
0
    return False;
1008
1009
  /* Calculate the MD4 hash (NT compatible) of the password */
1010
0
  E_md4hash(plaintext, new_nt_p16);
1011
1012
0
  if (!pdb_set_nt_passwd (sampass, new_nt_p16, PDB_CHANGED)) {
1013
0
    ZERO_STRUCT(new_nt_p16);
1014
0
    return False;
1015
0
  }
1016
1017
0
  if (!E_deshash(plaintext, new_lanman_p16)) {
1018
    /* E_deshash returns false for 'long' passwords (> 14
1019
       DOS chars).  This allows us to match Win2k, which
1020
       does not store a LM hash for these passwords (which
1021
       would reduce the effective password length to 14 */
1022
1023
0
    if (!pdb_set_lanman_passwd (sampass, NULL, PDB_CHANGED)) {
1024
0
      ZERO_STRUCT(new_nt_p16);
1025
0
      ZERO_STRUCT(new_lanman_p16);
1026
0
      return False;
1027
0
    }
1028
0
  } else {
1029
0
    if (!pdb_set_lanman_passwd (sampass, new_lanman_p16, PDB_CHANGED)) {
1030
0
      ZERO_STRUCT(new_nt_p16);
1031
0
      ZERO_STRUCT(new_lanman_p16);
1032
0
      return False;
1033
0
    }
1034
0
  }
1035
0
  ZERO_STRUCT(new_lanman_p16);
1036
1037
0
  if (!pdb_set_plaintext_pw_only (sampass, plaintext, PDB_CHANGED)) {
1038
0
    ZERO_STRUCT(new_nt_p16);
1039
0
    return False;
1040
0
  }
1041
1042
0
  if (!pdb_set_pass_last_set_time (sampass, time(NULL), PDB_CHANGED)) {
1043
0
    ZERO_STRUCT(new_nt_p16);
1044
0
    return False;
1045
0
  }
1046
1047
0
  ok = pdb_update_history(sampass, new_nt_p16);
1048
0
  ZERO_STRUCT(new_nt_p16);
1049
0
  return ok;
1050
0
}
1051
1052
/*********************************************************************
1053
 Update password history after change
1054
 ********************************************************************/
1055
1056
bool pdb_update_history(struct samu *sampass, const uint8_t new_nt[NT_HASH_LEN])
1057
0
{
1058
0
  uchar *pwhistory;
1059
0
  uint32_t pwHistLen;
1060
0
  uint32_t current_history_len;
1061
0
  const uint8_t *current_history;
1062
1063
0
  if ((pdb_get_acct_ctrl(sampass) & ACB_NORMAL) == 0) {
1064
    /*
1065
     * No password history for non-user accounts
1066
     */
1067
0
    return true;
1068
0
  }
1069
1070
0
  pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
1071
1072
0
  if (pwHistLen == 0) {
1073
    /* Set the history length to zero. */
1074
0
    pdb_set_pw_history(sampass, NULL, 0, PDB_CHANGED);
1075
0
    return true;
1076
0
  }
1077
1078
  /*
1079
   * We need to make sure we don't have a race condition here -
1080
   * the account policy history length can change between when
1081
   * the pw_history was first loaded into the struct samu struct
1082
   * and now.... JRA.
1083
   */
1084
0
  current_history = pdb_get_pw_history(sampass, &current_history_len);
1085
0
  if ((current_history_len != 0) && (current_history == NULL)) {
1086
0
    DEBUG(1, ("pdb_update_history: pwhistory == NULL!\n"));
1087
0
    return false;
1088
0
  }
1089
1090
  /*
1091
   * Ensure we have space for the needed history. This
1092
   * also takes care of an account which did not have
1093
   * any history at all so far, i.e. pwhistory==NULL
1094
   */
1095
0
  pwhistory = talloc_zero_array(
1096
0
      sampass, uchar,
1097
0
      pwHistLen*PW_HISTORY_ENTRY_LEN);
1098
0
  if (!pwhistory) {
1099
0
    return false;
1100
0
  }
1101
1102
0
  memcpy(pwhistory, current_history,
1103
0
         current_history_len*PW_HISTORY_ENTRY_LEN);
1104
1105
  /*
1106
   * Make room for the new password in the history list.
1107
   */
1108
0
  if (pwHistLen > 1) {
1109
0
    memmove(&pwhistory[PW_HISTORY_ENTRY_LEN], pwhistory,
1110
0
      (pwHistLen-1)*PW_HISTORY_ENTRY_LEN );
1111
0
  }
1112
1113
  /*
1114
   * Fill the salt area with 0-s: this indicates that
1115
   * a plain nt hash is stored in the has area.
1116
   * The old format was to store a 16 byte salt and
1117
   * then an md5hash of the nt_hash concatenated with
1118
   * the salt.
1119
   */
1120
0
  memset(pwhistory, 0, PW_HISTORY_SALT_LEN);
1121
1122
  /*
1123
   * Store the plain nt hash in the second 16 bytes.
1124
   * The old format was to store the md5 hash of
1125
   * the salt+newpw.
1126
   */
1127
0
  memcpy(&pwhistory[PW_HISTORY_SALT_LEN], new_nt, SALTED_MD5_HASH_LEN);
1128
1129
0
  pdb_set_pw_history(sampass, pwhistory, pwHistLen, PDB_CHANGED);
1130
1131
0
  return True;
1132
1133
0
}
1134
1135
/* check for any PDB_SET/CHANGED field and fill the appropriate mask bit */
1136
uint32_t pdb_build_fields_present(struct samu *sampass)
1137
0
{
1138
  /* value set to all for testing */
1139
0
  return 0x00ffffff;
1140
0
}
1141
1142
/**********************************************************************
1143
 Helper function to determine for update_sam_account whether
1144
 we need LDAP modification.
1145
*********************************************************************/
1146
1147
bool pdb_element_is_changed(const struct samu *sampass,
1148
          enum pdb_elements element)
1149
0
{
1150
0
  return IS_SAM_CHANGED(sampass, element);
1151
0
}
1152
1153
/**********************************************************************
1154
 Helper function to determine for update_sam_account whether
1155
 we need LDAP modification.
1156
 *********************************************************************/
1157
1158
bool pdb_element_is_set_or_changed(const struct samu *sampass,
1159
           enum pdb_elements element)
1160
0
{
1161
0
  return (IS_SAM_SET(sampass, element) ||
1162
0
    IS_SAM_CHANGED(sampass, element));
1163
0
}