2 * Unix SMB/CIFS implementation.
3 * SMB parameters and setup
4 * Copyright (C) Andrew Tridgell 1992-1998
5 * Copyright (C) Simo Sorce 2000-2002
6 * Copyright (C) Gerald Carter 2000
7 * Copyright (C) Jeremy Allison 2001
8 * Copyright (C) Andrew Bartlett 2002
10 * This program is free software; you can redistribute it and/or modify it under
11 * the terms of the GNU General Public License as published by the Free
12 * Software Foundation; either version 2 of the License, or (at your option)
15 * This program is distributed in the hope that it will be useful, but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
20 * You should have received a copy of the GNU General Public License along with
21 * this program; if not, write to the Free Software Foundation, Inc., 675
22 * Mass Ave, Cambridge, MA 02139, USA.
27 #if 0 /* when made a module use this */
29 static int tdbsam_debug_level
= DBGC_ALL
;
31 #define DBGC_CLASS tdbsam_debug_level
36 #define DBGC_CLASS DBGC_PASSDB
40 #define TDBSAM_VERSION 1 /* Most recent TDBSAM version */
41 #define TDBSAM_VERSION_STRING "INFO/version"
42 #define PASSDB_FILE_NAME "passdb.tdb"
43 #define USERPREFIX "USER_"
44 #define RIDPREFIX "RID_"
45 #define tdbsamver_t int32
47 struct tdbsam_privates
{
48 TDB_CONTEXT
*passwd_tdb
;
50 /* retrive-once info */
51 const char *tdbsam_location
;
55 struct pwent_list
*prev
, *next
;
58 static struct pwent_list
*tdbsam_pwent_list
;
62 * Convert old TDBSAM to the latest version.
63 * @param pdb_tdb A pointer to the opened TDBSAM file which must be converted.
64 * This file must be opened with read/write access.
65 * @param from Current version of the TDBSAM file.
66 * @return True if the conversion has been successful, false otherwise.
69 static BOOL
tdbsam_convert(TDB_CONTEXT
*pdb_tdb
, tdbsamver_t from
)
71 const char * vstring
= TDBSAM_VERSION_STRING
;
72 SAM_ACCOUNT
*user
= NULL
;
73 const char *prefix
= USERPREFIX
;
74 TDB_DATA data
, key
, old_key
;
78 if (pdb_tdb
== NULL
) {
79 DEBUG(0,("tdbsam_convert: Bad TDB Context pointer.\n"));
83 /* handle a Samba upgrade */
84 tdb_lock_bystring(pdb_tdb
, vstring
, 0);
86 if (!NT_STATUS_IS_OK(pdb_init_sam(&user
))) {
87 DEBUG(0,("tdbsam_convert: cannot initialized a SAM_ACCOUNT.\n"));
91 /* Enumerate all records and convert them */
92 key
= tdb_firstkey(pdb_tdb
);
96 /* skip all non-USER entries (eg. RIDs) */
97 while ((key
.dsize
!= 0) && (strncmp(key
.dptr
, prefix
, strlen (prefix
)))) {
99 /* increment to next in line */
100 key
= tdb_nextkey(pdb_tdb
, key
);
101 SAFE_FREE(old_key
.dptr
);
106 /* read from tdbsam */
107 data
= tdb_fetch(pdb_tdb
, key
);
109 DEBUG(0,("tdbsam_convert: database entry not found: %s.\n",key
.dptr
));
113 if (!NT_STATUS_IS_OK(pdb_reset_sam(user
))) {
114 DEBUG(0,("tdbsam_convert: cannot reset SAM_ACCOUNT.\n"));
115 SAFE_FREE(data
.dptr
);
119 /* unpack the buffer from the former format */
120 DEBUG(10,("tdbsam_convert: Try unpacking a record with (key:%s) (version:%d)\n", key
.dptr
, from
));
123 ret
= init_sam_from_buffer_v0(user
, (uint8
*)data
.dptr
, data
.dsize
);
126 ret
= init_sam_from_buffer_v1(user
, (uint8
*)data
.dptr
, data
.dsize
);
129 /* unknown tdbsam version */
133 DEBUG(0,("tdbsam_convert: Bad SAM_ACCOUNT entry returned from TDB (key:%s) (version:%d)\n", key
.dptr
, from
));
134 SAFE_FREE(data
.dptr
);
138 /* pack from the buffer into the new format */
139 DEBUG(10,("tdbsam_convert: Try packing a record (key:%s) (version:%d)\n", key
.dptr
, from
));
140 if ((data
.dsize
=init_buffer_from_sam (&buf
, user
, False
)) == -1) {
141 DEBUG(0,("tdbsam_convert: cannot pack the SAM_ACCOUNT into the new format\n"));
142 SAFE_FREE(data
.dptr
);
145 data
.dptr
= (char *)buf
;
147 /* Store the buffer inside the TDBSAM */
148 if (tdb_store(pdb_tdb
, key
, data
, TDB_MODIFY
) != TDB_SUCCESS
) {
149 DEBUG(0,("tdbsam_convert: cannot store the SAM_ACCOUNT (key:%s) in new format\n",key
.dptr
));
150 SAFE_FREE(data
.dptr
);
154 SAFE_FREE(data
.dptr
);
156 /* increment to next in line */
158 key
= tdb_nextkey(pdb_tdb
, key
);
159 SAFE_FREE(old_key
.dptr
);
166 /* upgrade finished */
167 tdb_store_int32(pdb_tdb
, vstring
, TDBSAM_VERSION
);
168 tdb_unlock_bystring(pdb_tdb
, vstring
);
174 * Open the TDB passwd database, check version and convert it if needed.
175 * @param name filename of the tdbsam file.
176 * @param open_flags file access mode.
177 * @return a TDB_CONTEXT handle on the tdbsam file.
180 static TDB_CONTEXT
* tdbsam_tdbopen (const char *name
, int open_flags
)
182 TDB_CONTEXT
*pdb_tdb
;
185 /* Try to open tdb passwd */
186 if (!(pdb_tdb
= tdb_open_log(name
, 0, TDB_DEFAULT
, open_flags
, 0600)))
189 /* Check the version */
190 version
= (tdbsamver_t
) tdb_fetch_int32(pdb_tdb
,
191 TDBSAM_VERSION_STRING
);
193 version
= 0; /* Version not found, assume version 0 */
195 /* Compare the version */
196 if (version
> TDBSAM_VERSION
) {
197 /* Version more recent than the latest known */
198 DEBUG(0, ("TDBSAM version unknown: %d\n", version
));
202 else if (version
< TDBSAM_VERSION
) {
203 /* Older version, must be converted */
204 DEBUG(1, ("TDBSAM version too old (%d), trying to convert it.\n", version
));
206 /* Reopen the pdb file with read-write access if needed */
207 if (!(open_flags
& O_RDWR
)) {
208 DEBUG(10, ("tdbsam_tdbopen: TDB file opened with read only access, reopen it with read-write access.\n"));
210 pdb_tdb
= tdb_open_log(name
, 0, TDB_DEFAULT
, (open_flags
& 07777770) | O_RDWR
, 0600);
214 if (!tdbsam_convert(pdb_tdb
, version
)){
215 DEBUG(0, ("tdbsam_tdbopen: Error when trying to convert tdbsam: %s\n",name
));
219 DEBUG(1, ("TDBSAM converted successfully.\n"));
222 /* Reopen the pdb file as it must be */
223 if (!(open_flags
& O_RDWR
)) {
225 pdb_tdb
= tdb_open_log(name
, 0, TDB_DEFAULT
, open_flags
, 0600);
232 /*****************************************************************************
233 Utility functions to open the tdb sam database
234 ****************************************************************************/
236 static void tdbsam_tdbclose ( struct tdbsam_privates
*state
)
241 if ( state
->passwd_tdb
) {
242 tdb_close( state
->passwd_tdb
);
243 state
->passwd_tdb
= NULL
;
250 /****************************************************************************
251 creates a list of user keys
252 ****************************************************************************/
254 static int tdbsam_traverse_setpwent(TDB_CONTEXT
*t
, TDB_DATA key
, TDB_DATA data
, void *state
)
256 const char *prefix
= USERPREFIX
;
257 int prefixlen
= strlen (prefix
);
258 struct pwent_list
*ptr
;
260 if ( strncmp(key
.dptr
, prefix
, prefixlen
) == 0 ) {
261 if ( !(ptr
=(struct pwent_list
*)malloc(sizeof(struct pwent_list
))) ) {
262 DEBUG(0,("tdbsam_traverse_setpwent: Failed to malloc new entry for list\n"));
264 /* just return 0 and let the traversal continue */
269 /* save a copy of the key */
271 ptr
->key
.dptr
= memdup( key
.dptr
, key
.dsize
);
272 ptr
->key
.dsize
= key
.dsize
;
274 DLIST_ADD( tdbsam_pwent_list
, ptr
);
282 /***************************************************************
283 Open the TDB passwd database for SAM account enumeration.
284 Save a list of user keys for iteration.
285 ****************************************************************/
287 static NTSTATUS
tdbsam_setsampwent(struct pdb_methods
*my_methods
, BOOL update
)
289 uint32 flags
= update
? (O_RDWR
|O_CREAT
) : O_RDONLY
;
291 struct tdbsam_privates
*tdb_state
= (struct tdbsam_privates
*)my_methods
->private_data
;
293 if ( !(tdb_state
->passwd_tdb
= tdbsam_tdbopen(tdb_state
->tdbsam_location
, flags
)) )
294 return NT_STATUS_UNSUCCESSFUL
;
296 tdb_traverse( tdb_state
->passwd_tdb
, tdbsam_traverse_setpwent
, NULL
);
302 /***************************************************************
303 End enumeration of the TDB passwd list.
304 ****************************************************************/
306 static void tdbsam_endsampwent(struct pdb_methods
*my_methods
)
308 struct tdbsam_privates
*tdb_state
= (struct tdbsam_privates
*)my_methods
->private_data
;
309 struct pwent_list
*ptr
, *ptr_next
;
311 tdbsam_tdbclose( tdb_state
);
313 /* clear out any remaining entries in the list */
315 for ( ptr
=tdbsam_pwent_list
; ptr
; ptr
= ptr_next
) {
316 ptr_next
= ptr
->next
;
317 DLIST_REMOVE( tdbsam_pwent_list
, ptr
);
318 SAFE_FREE( ptr
->key
.dptr
);
322 DEBUG(7, ("endtdbpwent: closed sam database.\n"));
325 /*****************************************************************
326 Get one SAM_ACCOUNT from the TDB (next in line)
327 *****************************************************************/
329 static NTSTATUS
tdbsam_getsampwent(struct pdb_methods
*my_methods
, SAM_ACCOUNT
*user
)
331 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
332 struct tdbsam_privates
*tdb_state
= (struct tdbsam_privates
*)my_methods
->private_data
;
334 struct pwent_list
*pkey
;
337 DEBUG(0,("tdbsam_getsampwent: SAM_ACCOUNT is NULL.\n"));
341 if ( !tdbsam_pwent_list
) {
342 DEBUG(4,("tdbsam_getsampwent: end of list\n"));
343 tdbsam_tdbclose( tdb_state
);
347 if ( !tdb_state
->passwd_tdb
) {
348 if ( !(tdb_state
->passwd_tdb
= tdbsam_tdbopen(tdb_state
->tdbsam_location
, O_RDONLY
)) )
352 /* pull the next entry */
354 pkey
= tdbsam_pwent_list
;
355 DLIST_REMOVE( tdbsam_pwent_list
, pkey
);
357 data
= tdb_fetch(tdb_state
->passwd_tdb
, pkey
->key
);
359 SAFE_FREE( pkey
->key
.dptr
);
363 DEBUG(5,("pdb_getsampwent: database entry not found. Was the user deleted?\n"));
367 if (!init_sam_from_buffer(user
, (unsigned char *)data
.dptr
, data
.dsize
)) {
368 DEBUG(0,("pdb_getsampwent: Bad SAM_ACCOUNT entry returned from TDB!\n"));
371 SAFE_FREE( data
.dptr
);
377 /******************************************************************
378 Lookup a name in the SAM TDB
379 ******************************************************************/
381 static NTSTATUS
tdbsam_getsampwnam (struct pdb_methods
*my_methods
, SAM_ACCOUNT
*user
, const char *sname
)
383 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
384 struct tdbsam_privates
*tdb_state
= (struct tdbsam_privates
*)my_methods
->private_data
;
385 TDB_CONTEXT
*pwd_tdb
;
391 DEBUG(0,("pdb_getsampwnam: SAM_ACCOUNT is NULL.\n"));
395 /* Data is stored in all lower-case */
396 fstrcpy(name
, sname
);
400 slprintf(keystr
, sizeof(keystr
)-1, "%s%s", USERPREFIX
, name
);
402 key
.dsize
= strlen(keystr
) + 1;
404 /* open the accounts TDB */
405 if (!(pwd_tdb
= tdbsam_tdbopen(tdb_state
->tdbsam_location
, O_RDONLY
))) {
407 if (errno
== ENOENT
) {
409 * TDB file doesn't exist, so try to create new one. This is useful to avoid
410 * confusing error msg when adding user account first time
412 if (!(pwd_tdb
= tdbsam_tdbopen(tdb_state
->tdbsam_location
, O_CREAT
))) {
413 DEBUG(0, ("pdb_getsampwnam: TDB passwd (%s) did not exist. File successfully created.\n",
414 tdb_state
->tdbsam_location
));
416 DEBUG(0, ("pdb_getsampwnam: TDB passwd (%s) does not exist. Couldn't create new one. Error was: %s\n",
417 tdb_state
->tdbsam_location
, strerror(errno
)));
420 /* requested user isn't there anyway */
421 nt_status
= NT_STATUS_NO_SUCH_USER
;
424 DEBUG(0, ("pdb_getsampwnam: Unable to open TDB passwd (%s)!\n", tdb_state
->tdbsam_location
));
429 data
= tdb_fetch(pwd_tdb
, key
);
431 DEBUG(5,("pdb_getsampwnam (TDB): error fetching database.\n"));
432 DEBUGADD(5, (" Error: %s\n", tdb_errorstr(pwd_tdb
)));
433 DEBUGADD(5, (" Key: %s\n", keystr
));
438 /* unpack the buffer */
439 if (!init_sam_from_buffer(user
, (unsigned char *)data
.dptr
, data
.dsize
)) {
440 DEBUG(0,("pdb_getsampwent: Bad SAM_ACCOUNT entry returned from TDB!\n"));
441 SAFE_FREE(data
.dptr
);
445 SAFE_FREE(data
.dptr
);
447 /* no further use for database, close it now */
453 /***************************************************************************
455 **************************************************************************/
457 static NTSTATUS
tdbsam_getsampwrid (struct pdb_methods
*my_methods
, SAM_ACCOUNT
*user
, uint32 rid
)
459 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
460 struct tdbsam_privates
*tdb_state
= (struct tdbsam_privates
*)my_methods
->private_data
;
461 TDB_CONTEXT
*pwd_tdb
;
467 DEBUG(0,("pdb_getsampwrid: SAM_ACCOUNT is NULL.\n"));
472 slprintf(keystr
, sizeof(keystr
)-1, "%s%.8x", RIDPREFIX
, rid
);
474 key
.dsize
= strlen (keystr
) + 1;
476 /* open the accounts TDB */
477 if (!(pwd_tdb
= tdbsam_tdbopen(tdb_state
->tdbsam_location
, O_RDONLY
))) {
478 DEBUG(0, ("pdb_getsampwrid: Unable to open TDB rid database!\n"));
483 data
= tdb_fetch (pwd_tdb
, key
);
485 DEBUG(5,("pdb_getsampwrid (TDB): error looking up RID %d by key %s.\n", rid
, keystr
));
486 DEBUGADD(5, (" Error: %s\n", tdb_errorstr(pwd_tdb
)));
492 fstrcpy(name
, data
.dptr
);
493 SAFE_FREE(data
.dptr
);
497 return tdbsam_getsampwnam (my_methods
, user
, name
);
500 static NTSTATUS
tdbsam_getsampwsid(struct pdb_methods
*my_methods
, SAM_ACCOUNT
* user
, const DOM_SID
*sid
)
503 if (!sid_peek_check_rid(get_global_sam_sid(), sid
, &rid
))
504 return NT_STATUS_UNSUCCESSFUL
;
505 return tdbsam_getsampwrid(my_methods
, user
, rid
);
508 /***************************************************************************
510 ****************************************************************************/
512 static NTSTATUS
tdbsam_delete_sam_account(struct pdb_methods
*my_methods
, SAM_ACCOUNT
*sam_pass
)
514 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
515 struct tdbsam_privates
*tdb_state
= (struct tdbsam_privates
*)my_methods
->private_data
;
516 TDB_CONTEXT
*pwd_tdb
;
522 fstrcpy(name
, pdb_get_username(sam_pass
));
526 if (!(pwd_tdb
= tdbsam_tdbopen(tdb_state
->tdbsam_location
, O_RDWR
))) {
527 DEBUG(0, ("Unable to open TDB passwd!"));
531 /* set the search key */
532 slprintf(keystr
, sizeof(keystr
)-1, "%s%s", USERPREFIX
, name
);
534 key
.dsize
= strlen (keystr
) + 1;
536 rid
= pdb_get_user_rid(sam_pass
);
538 /* it's outaa here! 8^) */
539 if (tdb_delete(pwd_tdb
, key
) != TDB_SUCCESS
) {
540 DEBUG(5, ("Error deleting entry from tdb passwd database!\n"));
541 DEBUGADD(5, (" Error: %s\n", tdb_errorstr(pwd_tdb
)));
546 /* delete also the RID key */
548 /* set the search key */
549 slprintf(keystr
, sizeof(keystr
)-1, "%s%.8x", RIDPREFIX
, rid
);
551 key
.dsize
= strlen (keystr
) + 1;
553 /* it's outaa here! 8^) */
554 if (tdb_delete(pwd_tdb
, key
) != TDB_SUCCESS
) {
555 DEBUG(5, ("Error deleting entry from tdb rid database!\n"));
556 DEBUGADD(5, (" Error: %s\n", tdb_errorstr(pwd_tdb
)));
566 /***************************************************************************
568 ****************************************************************************/
570 static BOOL
tdb_update_sam(struct pdb_methods
*my_methods
, SAM_ACCOUNT
* newpwd
, int flag
)
572 struct tdbsam_privates
*tdb_state
= (struct tdbsam_privates
*)my_methods
->private_data
;
573 TDB_CONTEXT
*pwd_tdb
= NULL
;
581 /* invalidate the existing TDB iterator if it is open */
583 if (tdb_state
->passwd_tdb
) {
584 tdb_close(tdb_state
->passwd_tdb
);
585 tdb_state
->passwd_tdb
= NULL
;
588 /* open the account TDB passwd*/
590 pwd_tdb
= tdbsam_tdbopen(tdb_state
->tdbsam_location
, O_RDWR
| O_CREAT
);
593 DEBUG(0, ("tdb_update_sam: Unable to open TDB passwd (%s)!\n",
594 tdb_state
->tdbsam_location
));
598 if (!pdb_get_group_rid(newpwd
)) {
599 DEBUG (0,("tdb_update_sam: Failing to store a SAM_ACCOUNT for [%s] without a primary group RID\n",
600 pdb_get_username(newpwd
)));
605 if ( !(user_rid
= pdb_get_user_rid(newpwd
)) ) {
606 DEBUG(0,("tdb_update_sam: SAM_ACCOUNT (%s) with no RID!\n", pdb_get_username(newpwd
)));
611 /* copy the SAM_ACCOUNT struct into a BYTE buffer for storage */
612 if ((data
.dsize
=init_buffer_from_sam (&buf
, newpwd
, False
)) == -1) {
613 DEBUG(0,("tdb_update_sam: ERROR - Unable to copy SAM_ACCOUNT info BYTE buffer!\n"));
617 data
.dptr
= (char *)buf
;
619 fstrcpy(name
, pdb_get_username(newpwd
));
622 DEBUG(5, ("Storing %saccount %s with RID %d\n", flag
== TDB_INSERT
? "(new) " : "", name
, user_rid
));
624 /* setup the USER index key */
625 slprintf(keystr
, sizeof(keystr
)-1, "%s%s", USERPREFIX
, name
);
627 key
.dsize
= strlen(keystr
) + 1;
629 /* add the account */
630 if (tdb_store(pwd_tdb
, key
, data
, flag
) != TDB_SUCCESS
) {
631 DEBUG(0, ("Unable to modify passwd TDB!"));
632 DEBUGADD(0, (" Error: %s", tdb_errorstr(pwd_tdb
)));
633 DEBUGADD(0, (" occured while storing the main record (%s)\n", keystr
));
639 data
.dsize
= strlen(name
) + 1;
642 /* setup the RID index key */
643 slprintf(keystr
, sizeof(keystr
)-1, "%s%.8x", RIDPREFIX
, user_rid
);
645 key
.dsize
= strlen (keystr
) + 1;
647 /* add the reference */
648 if (tdb_store(pwd_tdb
, key
, data
, flag
) != TDB_SUCCESS
) {
649 DEBUG(0, ("Unable to modify TDB passwd !"));
650 DEBUGADD(0, (" Error: %s\n", tdb_errorstr(pwd_tdb
)));
651 DEBUGADD(0, (" occured while storing the RID index (%s)\n", keystr
));
664 /***************************************************************************
665 Modifies an existing SAM_ACCOUNT
666 ****************************************************************************/
668 static NTSTATUS
tdbsam_update_sam_account (struct pdb_methods
*my_methods
, SAM_ACCOUNT
*newpwd
)
670 if (tdb_update_sam(my_methods
, newpwd
, TDB_MODIFY
))
673 return NT_STATUS_UNSUCCESSFUL
;
676 /***************************************************************************
677 Adds an existing SAM_ACCOUNT
678 ****************************************************************************/
680 static NTSTATUS
tdbsam_add_sam_account (struct pdb_methods
*my_methods
, SAM_ACCOUNT
*newpwd
)
682 if (tdb_update_sam(my_methods
, newpwd
, TDB_INSERT
))
685 return NT_STATUS_UNSUCCESSFUL
;
688 static void free_private_data(void **vp
)
690 struct tdbsam_privates
**tdb_state
= (struct tdbsam_privates
**)vp
;
691 tdbsam_tdbclose(*tdb_state
);
694 /* No need to free any further, as it is talloc()ed */
698 * Start enumerating through trust passwords (machine and
699 * interdomain nt/ads)
701 * @param methods methods belonging in pdb context (module)
702 * @param trust trust password structure
704 * @return nt status of performed operation
707 static NTSTATUS
tdbsam_gettrustpwent(struct pdb_methods
*methods
, SAM_TRUST_PASSWD
*trust
)
709 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
710 struct trust_passwd_data t
;
716 unsigned int max_domains
= 1;
717 char *dom_name
, *dom_pass
;
719 smb_ucs2_t
*uni_dom_name
;
723 if (!methods
) return NT_STATUS_UNSUCCESSFUL
;
726 * NT domain trust passwords
729 /* rewind enumeration when passed NULL pointer as a trust */
735 mem_ctx
= talloc_init("tdbsam_gettrustpwent: trust password enumeration");
737 /* fetch next trusted domain (one at a time) and its full information */
738 nt_status
= secrets_get_trusted_domains(mem_ctx
, &enum_ctx
, max_domains
, &num_domains
,
741 pull_ucs2_talloc(mem_ctx
, &dom_name
, trustdom
[0]->name
);
742 if (secrets_fetch_trusted_domain_password(dom_name
, &dom_pass
, &t
.domain_sid
,
745 t
.uni_name_len
= strnlen_w(trustdom
[0]->name
, 32);
746 strncpy_w(t
.uni_name
, trustdom
[0]->name
, t
.uni_name_len
);
747 safe_strcpy(t
.pass
, dom_pass
, FSTRING_LEN
- 1);
748 t
.flags
= PASS_DOMAIN_TRUST_NT
;
751 talloc_destroy(mem_ctx
);
755 talloc_destroy(mem_ctx
);
756 return NT_STATUS_UNSUCCESSFUL
;
761 * NT machine trust password
764 if (secrets_lock_trust_account_password(lp_workgroup(), True
)) {
765 sec_chan
= get_default_sec_channel();
766 if (secrets_fetch_trust_account_password(lp_workgroup(), mach_pass
, &t
.mod_time
,
769 t
.uni_name_len
= strlen(lp_workgroup());
770 push_ucs2_talloc(mem_ctx
, &uni_dom_name
, lp_workgroup());
771 strncpy_w(t
.uni_name
, uni_dom_name
, t
.uni_name_len
);
772 safe_strcpy(t
.pass
, mach_pass
, FSTRING_LEN
- 1);
773 t
.flags
= PASS_MACHINE_TRUST_NT
;
774 if (!secrets_fetch_domain_sid(lp_workgroup(), &t
.domain_sid
)) {
775 talloc_destroy(mem_ctx
);
776 return NT_STATUS_UNSUCCESSFUL
;
779 talloc_destroy(mem_ctx
);
783 secrets_lock_trust_account_password(lp_workgroup(), False
);
785 talloc_destroy(mem_ctx
);
786 return NT_STATUS_UNSUCCESSFUL
;
790 * ADS machine trust password (TODO)
793 talloc_destroy(mem_ctx
);
798 * Get trust password by trusted party sid
800 * @param methods methods belonging to pdb context (module)
801 * @param trust trust password structure
802 * @param sid trusted party sid
804 * @return nt status of performed operation
807 static NTSTATUS
tdbsam_gettrustpwsid(struct pdb_methods
*methods
, SAM_TRUST_PASSWD
*trust
,
810 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
816 * Add new trust password.
818 * @param methods methods belonging in pdb context (module)
819 * @param trust trust password structure
821 * @return nt status of performed operation
824 static NTSTATUS
tdbsam_add_trust_passwd(struct pdb_methods
*methods
, const SAM_TRUST_PASSWD
*trust
)
826 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
831 struct trust_passwd_data t
= trust
->private;
834 mem_ctx
= talloc_init("tdbsam_add_trust_passwd: storing new trust password");
836 /* convert unicode name to char* (used to form the key) */
837 pull_ucs2_talloc(mem_ctx
, &domain
, t
.uni_name
);
839 /* add nt machine trust password */
840 if (t
.flags
& (PASS_MACHINE_TRUST_NT
| PASS_SERVER_TRUST_NT
)) {
841 sec_chan
= (t
.flags
& PASS_MACHINE_TRUST_NT
) ? SEC_CHAN_WKSTA
: SEC_CHAN_BDC
;
842 status
= secrets_store_machine_password(t
.pass
, domain
, sec_chan
);
844 status
= secrets_store_domain_sid(domain
, &t
.domain_sid
);
846 nt_status
= status
? NT_STATUS_OK
: NT_STATUS_UNSUCCESSFUL
;
848 /* add nt domain trust password */
849 } else if (t
.flags
& PASS_DOMAIN_TRUST_NT
) {
850 status
= secrets_store_trusted_domain_password(domain
, t
.uni_name
, t
.uni_name_len
,
851 t
.pass
, t
.domain_sid
);
852 nt_status
= status
? NT_STATUS_OK
: NT_STATUS_UNSUCCESSFUL
;
854 /* add ads machine trust password (TODO) */
855 } else if (t
.flags
& PASS_MACHINE_TRUST_ADS
) {
858 talloc_destroy(mem_ctx
);
864 * Update trust password.
866 * @param methods methods belonging in pdb context (module)
867 * @param trust trust password structure
869 * @return nt status of performed operation
872 static NTSTATUS
tdbsam_update_trust_passwd(struct pdb_methods
*methods
, const SAM_TRUST_PASSWD
* trust
)
874 NTSTATUS nt_status
= NT_STATUS_NOT_IMPLEMENTED
;
880 * Delete trust password.
882 * @param methods methods belonging in pdb context (module)
883 * @param trust trust password structure
885 * @return nt status of performed operation
888 static NTSTATUS
tdbsam_delete_trust_passwd(struct pdb_methods
*methods
, const SAM_TRUST_PASSWD
* trust
)
890 NTSTATUS nt_status
= NT_STATUS_NOT_IMPLEMENTED
;
895 static NTSTATUS
pdb_init_tdbsam(PDB_CONTEXT
*pdb_context
, PDB_METHODS
**pdb_method
, const char *location
)
898 struct tdbsam_privates
*tdb_state
;
900 if (!NT_STATUS_IS_OK(nt_status
= make_pdb_methods(pdb_context
->mem_ctx
, pdb_method
))) {
904 (*pdb_method
)->name
= "tdbsam";
906 (*pdb_method
)->setsampwent
= tdbsam_setsampwent
;
907 (*pdb_method
)->endsampwent
= tdbsam_endsampwent
;
908 (*pdb_method
)->getsampwent
= tdbsam_getsampwent
;
909 (*pdb_method
)->getsampwnam
= tdbsam_getsampwnam
;
910 (*pdb_method
)->getsampwsid
= tdbsam_getsampwsid
;
911 (*pdb_method
)->add_sam_account
= tdbsam_add_sam_account
;
912 (*pdb_method
)->update_sam_account
= tdbsam_update_sam_account
;
913 (*pdb_method
)->delete_sam_account
= tdbsam_delete_sam_account
;
914 (*pdb_method
)->gettrustpwent
= tdbsam_gettrustpwent
;
915 (*pdb_method
)->gettrustpwsid
= tdbsam_gettrustpwsid
;
916 (*pdb_method
)->add_trust_passwd
= tdbsam_add_trust_passwd
;
917 (*pdb_method
)->update_trust_passwd
= tdbsam_update_trust_passwd
;
918 (*pdb_method
)->delete_trust_passwd
= tdbsam_delete_trust_passwd
;
920 tdb_state
= talloc_zero(pdb_context
->mem_ctx
, sizeof(struct tdbsam_privates
));
923 DEBUG(0, ("talloc() failed for tdbsam private_data!\n"));
924 return NT_STATUS_NO_MEMORY
;
928 tdb_state
->tdbsam_location
= talloc_strdup(pdb_context
->mem_ctx
, location
);
931 get_private_directory(tdbfile
);
932 pstrcat(tdbfile
, "/");
933 pstrcat(tdbfile
, PASSDB_FILE_NAME
);
934 tdb_state
->tdbsam_location
= talloc_strdup(pdb_context
->mem_ctx
, tdbfile
);
937 (*pdb_method
)->private_data
= tdb_state
;
939 (*pdb_method
)->free_private_data
= free_private_data
;
944 NTSTATUS
pdb_tdbsam_init(void)
946 return smb_register_passdb(PASSDB_INTERFACE_VERSION
, "tdbsam", pdb_init_tdbsam
);