source: trunk/server/source3/passdb/pdb_get_set.c@ 751

Last change on this file since 751 was 751, checked in by Silvan Scherrer, 13 years ago

Samba Server: updated trunk to 3.6.9

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