source: vendor/current/source3/passdb/pdb_get_set.c@ 594

Last change on this file since 594 was 414, checked in by Herwig Bauernfeind, 16 years ago

Samba 3.5.0: Initial import

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