2 * Unix SMB/CIFS implementation.
3 * SMB parameters and setup
4 * Copyright (C) Andrew Tridgell 1992-1998
5 * Copyright (C) Simo Sorce 2000-2003
6 * Copyright (C) Gerald Carter 2000-2006
7 * Copyright (C) Jeremy Allison 2001
8 * Copyright (C) Andrew Bartlett 2002
9 * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2005
11 * This program is free software; you can redistribute it and/or modify it under
12 * the terms of the GNU General Public License as published by the Free
13 * Software Foundation; either version 2 of the License, or (at your option)
16 * This program is distributed in the hope that it will be useful, but WITHOUT
17 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
21 * You should have received a copy of the GNU General Public License along with
22 * this program; if not, write to the Free Software Foundation, Inc., 675
23 * Mass Ave, Cambridge, MA 02139, USA.
28 #if 0 /* when made a module use this */
30 static int tdbsam_debug_level = DBGC_ALL;
32 #define DBGC_CLASS tdbsam_debug_level
37 #define DBGC_CLASS DBGC_PASSDB
41 #define TDBSAM_VERSION 2 /* Most recent TDBSAM version */
42 #define TDBSAM_VERSION_STRING "INFO/version"
43 #define PASSDB_FILE_NAME "passdb.tdb"
44 #define USERPREFIX "USER_"
45 #define RIDPREFIX "RID_"
46 #define PRIVPREFIX "PRIV_"
49 struct pwent_list *prev, *next;
52 static struct pwent_list *tdbsam_pwent_list;
54 /* GLOBAL TDB SAM CONTEXT */
56 static TDB_CONTEXT *tdbsam;
57 static int ref_count = 0;
58 static pstring tdbsam_filename;
61 * Convert old TDBSAM to the latest version.
62 * @param pdb_tdb A pointer to the opened TDBSAM file which must be converted.
63 * This file must be opened with read/write access.
64 * @param from Current version of the TDBSAM file.
65 * @return True if the conversion has been successful, false otherwise.
68 static BOOL tdbsam_convert(int32 from)
70 const char *vstring = TDBSAM_VERSION_STRING;
71 const char *prefix = USERPREFIX;
72 TDB_DATA data, key, old_key;
76 /* handle a Samba upgrade */
77 tdb_lock_bystring(tdbsam, vstring, 0);
79 /* Enumerate all records and convert them */
80 key = tdb_firstkey(tdbsam);
84 /* skip all non-USER entries (eg. RIDs) */
85 while ((key.dsize != 0) && (strncmp(key.dptr, prefix, strlen (prefix)))) {
87 /* increment to next in line */
88 key = tdb_nextkey(tdbsam, key);
89 SAFE_FREE(old_key.dptr);
93 struct samu *user = NULL;
95 /* read from tdbsam */
96 data = tdb_fetch(tdbsam, key);
98 DEBUG(0,("tdbsam_convert: database entry not found: %s.\n",key.dptr));
102 /* unpack the buffer from the former format */
103 pdb_init_sam( &user );
104 DEBUG(10,("tdbsam_convert: Try unpacking a record with (key:%s) (version:%d)\n", key.dptr, from));
107 ret = init_sam_from_buffer_v0(user, (uint8 *)data.dptr, data.dsize);
110 ret = init_sam_from_buffer_v1(user, (uint8 *)data.dptr, data.dsize);
113 ret = init_sam_from_buffer_v2(user, (uint8 *)data.dptr, data.dsize);
116 /* unknown tdbsam version */
120 DEBUG(0,("tdbsam_convert: Bad struct samu entry returned from TDB (key:%s) (version:%d)\n", key.dptr, from));
121 SAFE_FREE(data.dptr);
126 /* We're finished with the old data. */
127 SAFE_FREE(data.dptr);
129 /* pack from the buffer into the new format */
131 DEBUG(10,("tdbsam_convert: Try packing a record (key:%s) (version:%d)\n", key.dptr, from));
132 data.dsize = init_buffer_from_sam (&buf, user, False);
135 if ( data.dsize == -1 ) {
136 DEBUG(0,("tdbsam_convert: cannot pack the struct samu into the new format\n"));
139 data.dptr = (char *)buf;
141 /* Store the buffer inside the TDBSAM */
142 if (tdb_store(tdbsam, key, data, TDB_MODIFY) != TDB_SUCCESS) {
143 DEBUG(0,("tdbsam_convert: cannot store the struct samu (key:%s) in new format\n",key.dptr));
144 SAFE_FREE(data.dptr);
148 SAFE_FREE(data.dptr);
150 /* increment to next in line */
152 key = tdb_nextkey(tdbsam, key);
153 SAFE_FREE(old_key.dptr);
159 /* upgrade finished */
160 tdb_store_int32(tdbsam, vstring, TDBSAM_VERSION);
161 tdb_unlock_bystring(tdbsam, vstring);
166 /*********************************************************************
167 Open the tdbsam file based on the absolute path specified.
168 Uses a reference count to allow multiple open calls.
169 *********************************************************************/
171 static BOOL tdbsam_open( const char *name )
175 /* check if we are already open */
179 DEBUG(8,("tdbsam_open: Incrementing open reference count. Ref count is now %d\n",
184 SMB_ASSERT( ref_count == 0 );
186 /* Try to open tdb passwd. Create a new one if necessary */
188 if (!(tdbsam = tdb_open_log(name, 0, TDB_DEFAULT, O_CREAT|O_RDWR, 0600))) {
189 DEBUG(0, ("tdbsam_open: Failed to open/create TDB passwd [%s]\n", name));
193 /* Check the version */
194 version = tdb_fetch_int32( tdbsam, TDBSAM_VERSION_STRING );
197 version = 0; /* Version not found, assume version 0 */
199 /* Compare the version */
200 if (version > TDBSAM_VERSION) {
201 /* Version more recent than the latest known */
202 DEBUG(0, ("tdbsam_open: unknown version => %d\n", version));
208 if ( version < TDBSAM_VERSION ) {
209 DEBUG(1, ("tdbsam_open: Converting version %d database to version %d.\n",
210 version, TDBSAM_VERSION));
212 if ( !tdbsam_convert(version) ) {
213 DEBUG(0, ("tdbsam_open: Error when trying to convert tdbsam [%s]\n",name));
218 DEBUG(3, ("TDBSAM converted successfully.\n"));
221 /* set the initial reference count */
225 DEBUG(4,("tdbsam_open: successfully opened %s\n", name ));
230 /****************************************************************************
231 wrapper atound tdb_close() to handle the reference count
232 ****************************************************************************/
234 void tdbsam_close( void )
238 DEBUG(8,("tdbsam_close: Reference count is now %d.\n", ref_count));
240 SMB_ASSERT(ref_count >= 0 );
242 if ( ref_count == 0 ) {
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=SMB_MALLOC_P(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, uint16 acb_mask)
289 if ( !tdbsam_open( tdbsam_filename ) ) {
290 DEBUG(0,("tdbsam_getsampwnam: failed to open %s!\n", tdbsam_filename));
291 return NT_STATUS_ACCESS_DENIED;
294 tdb_traverse( tdbsam, tdbsam_traverse_setpwent, NULL );
300 /***************************************************************
301 End enumeration of the TDB passwd list.
302 ****************************************************************/
304 static void tdbsam_endsampwent(struct pdb_methods *my_methods)
306 struct pwent_list *ptr, *ptr_next;
308 /* clear out any remaining entries in the list */
310 for ( ptr=tdbsam_pwent_list; ptr; ptr = ptr_next ) {
311 ptr_next = ptr->next;
312 DLIST_REMOVE( tdbsam_pwent_list, ptr );
313 SAFE_FREE( ptr->key.dptr);
317 DEBUG(7, ("endtdbpwent: closed sam database.\n"));
322 /*****************************************************************
323 Get one struct samu from the TDB (next in line)
324 *****************************************************************/
326 static NTSTATUS tdbsam_getsampwent(struct pdb_methods *my_methods, struct samu *user)
328 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
330 struct pwent_list *pkey;
333 DEBUG(0,("tdbsam_getsampwent: struct samu is NULL.\n"));
337 if ( !tdbsam_pwent_list ) {
338 DEBUG(4,("tdbsam_getsampwent: end of list\n"));
342 /* pull the next entry */
344 pkey = tdbsam_pwent_list;
345 DLIST_REMOVE( tdbsam_pwent_list, pkey );
347 data = tdb_fetch(tdbsam, pkey->key);
349 SAFE_FREE( pkey->key.dptr);
353 DEBUG(5,("pdb_getsampwent: database entry not found. Was the user deleted?\n"));
357 if ( !init_sam_from_buffer(user, (unsigned char *)data.dptr, data.dsize) ) {
358 DEBUG(0,("pdb_getsampwent: Bad struct samu entry returned from TDB!\n"));
361 SAFE_FREE( data.dptr );
366 /******************************************************************
367 Lookup a name in the SAM TDB
368 ******************************************************************/
370 static NTSTATUS tdbsam_getsampwnam (struct pdb_methods *my_methods, struct samu *user, const char *sname)
378 DEBUG(0,("pdb_getsampwnam: struct samu is NULL.\n"));
379 return NT_STATUS_NO_MEMORY;
382 /* Data is stored in all lower-case */
383 fstrcpy(name, sname);
387 slprintf(keystr, sizeof(keystr)-1, "%s%s", USERPREFIX, name);
389 key.dsize = strlen(keystr) + 1;
391 /* open the database */
393 if ( !tdbsam_open( tdbsam_filename ) ) {
394 DEBUG(0,("tdbsam_getsampwnam: failed to open %s!\n", tdbsam_filename));
395 return NT_STATUS_ACCESS_DENIED;
400 data = tdb_fetch(tdbsam, key);
402 DEBUG(5,("pdb_getsampwnam (TDB): error fetching database.\n"));
403 DEBUGADD(5, (" Error: %s\n", tdb_errorstr(tdbsam)));
404 DEBUGADD(5, (" Key: %s\n", keystr));
405 result = NT_STATUS_NO_SUCH_USER;
409 /* unpack the buffer */
411 if (!init_sam_from_buffer(user, (unsigned char *)data.dptr, data.dsize)) {
412 DEBUG(0,("pdb_getsampwent: Bad struct samu entry returned from TDB!\n"));
413 SAFE_FREE(data.dptr);
414 result = NT_STATUS_NO_MEMORY;
418 result = NT_STATUS_OK;
421 SAFE_FREE(data.dptr);
427 /***************************************************************************
429 **************************************************************************/
431 static NTSTATUS tdbsam_getsampwrid (struct pdb_methods *my_methods, struct samu *user, uint32 rid)
433 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
439 DEBUG(0,("pdb_getsampwrid: struct samu is NULL.\n"));
445 slprintf(keystr, sizeof(keystr)-1, "%s%.8x", RIDPREFIX, rid);
447 key.dsize = strlen (keystr) + 1;
449 /* open the database */
451 if ( !tdbsam_open( tdbsam_filename ) ) {
452 DEBUG(0,("tdbsam_getsampwnam: failed to open %s!\n", tdbsam_filename));
453 return NT_STATUS_ACCESS_DENIED;
458 data = tdb_fetch (tdbsam, key);
460 DEBUG(5,("pdb_getsampwrid (TDB): error looking up RID %d by key %s.\n", rid, keystr));
461 DEBUGADD(5, (" Error: %s\n", tdb_errorstr(tdbsam)));
462 nt_status = NT_STATUS_UNSUCCESSFUL;
466 fstrcpy(name, data.dptr);
467 SAFE_FREE(data.dptr);
469 nt_status = tdbsam_getsampwnam (my_methods, user, name);
479 static NTSTATUS tdbsam_getsampwsid(struct pdb_methods *my_methods, struct samu * user, const DOM_SID *sid)
483 if ( !sid_peek_check_rid(get_global_sam_sid(), sid, &rid) )
484 return NT_STATUS_UNSUCCESSFUL;
486 return tdbsam_getsampwrid(my_methods, user, rid);
489 static BOOL tdb_delete_samacct_only( struct samu *sam_pass )
495 fstrcpy(name, pdb_get_username(sam_pass));
498 /* set the search key */
500 slprintf(keystr, sizeof(keystr)-1, "%s%s", USERPREFIX, name);
502 key.dsize = strlen (keystr) + 1;
504 /* it's outaa here! 8^) */
506 if (tdb_delete(tdbsam, key) != TDB_SUCCESS) {
507 DEBUG(5, ("Error deleting entry from tdb passwd database!\n"));
508 DEBUGADD(5, (" Error: %s\n", tdb_errorstr(tdbsam)));
515 /***************************************************************************
516 Delete a struct samu records for the username and RID key
517 ****************************************************************************/
519 static NTSTATUS tdbsam_delete_sam_account(struct pdb_methods *my_methods, struct samu *sam_pass)
521 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
527 /* make sure we have an open handle to the tdb. Should have happened
528 at module initialization time */
531 DEBUG(0,("tdbsam_getsampwrid: tdbsam not open!\n"));
532 return NT_STATUS_NO_SUCH_USER;
535 fstrcpy(name, pdb_get_username(sam_pass));
538 /* set the search key */
540 slprintf(keystr, sizeof(keystr)-1, "%s%s", USERPREFIX, name);
542 key.dsize = strlen (keystr) + 1;
544 rid = pdb_get_user_rid(sam_pass);
546 /* open the database */
548 if ( !tdbsam_open( tdbsam_filename ) ) {
549 DEBUG(0,("tdbsam_getsampwnam: failed to open %s!\n", tdbsam_filename));
550 return NT_STATUS_ACCESS_DENIED;
553 /* it's outaa here! 8^) */
555 if ( tdb_delete(tdbsam, key) != TDB_SUCCESS ) {
556 DEBUG(5, ("Error deleting entry from tdb passwd database!\n"));
557 DEBUGADD(5, (" Error: %s\n", tdb_errorstr(tdbsam)));
558 nt_status = NT_STATUS_UNSUCCESSFUL;
562 /* set the search key */
564 slprintf(keystr, sizeof(keystr)-1, "%s%.8x", RIDPREFIX, rid);
566 key.dsize = strlen (keystr) + 1;
568 /* it's outaa here! 8^) */
570 if ( tdb_delete(tdbsam, key) != TDB_SUCCESS ) {
571 DEBUG(5, ("Error deleting entry from tdb rid database!\n"));
572 DEBUGADD(5, (" Error: %s\n", tdb_errorstr(tdbsam)));
573 nt_status = NT_STATUS_UNSUCCESSFUL;
577 nt_status = NT_STATUS_OK;
586 /***************************************************************************
587 Update the TDB SAM account record only
588 Assumes that the tdbsam is already open
589 ****************************************************************************/
590 static BOOL tdb_update_samacct_only( struct samu* newpwd, int flag )
598 /* copy the struct samu struct into a BYTE buffer for storage */
600 if ( (data.dsize=init_buffer_from_sam (&buf, newpwd, False)) == -1 ) {
601 DEBUG(0,("tdb_update_sam: ERROR - Unable to copy struct samu info BYTE buffer!\n"));
605 data.dptr = (char *)buf;
607 fstrcpy(name, pdb_get_username(newpwd));
610 DEBUG(5, ("Storing %saccount %s with RID %d\n",
611 flag == TDB_INSERT ? "(new) " : "", name,
612 pdb_get_user_rid(newpwd)));
614 /* setup the USER index key */
615 slprintf(keystr, sizeof(keystr)-1, "%s%s", USERPREFIX, name);
617 key.dsize = strlen(keystr) + 1;
619 /* add the account */
621 if ( tdb_store(tdbsam, key, data, flag) != TDB_SUCCESS ) {
622 DEBUG(0, ("Unable to modify passwd TDB!"));
623 DEBUGADD(0, (" Error: %s", tdb_errorstr(tdbsam)));
624 DEBUGADD(0, (" occured while storing the main record (%s)\n",
637 /***************************************************************************
638 Update the TDB SAM RID record only
639 Assumes that the tdbsam is already open
640 ****************************************************************************/
641 static BOOL tdb_update_ridrec_only( struct samu* newpwd, int flag )
647 fstrcpy(name, pdb_get_username(newpwd));
651 data.dsize = strlen(name) + 1;
654 /* setup the RID index key */
655 slprintf(keystr, sizeof(keystr)-1, "%s%.8x", RIDPREFIX, pdb_get_user_rid(newpwd));
657 key.dsize = strlen (keystr) + 1;
659 /* add the reference */
660 if (tdb_store(tdbsam, key, data, flag) != TDB_SUCCESS) {
661 DEBUG(0, ("Unable to modify TDB passwd !"));
662 DEBUGADD(0, (" Error: %s\n", tdb_errorstr(tdbsam)));
663 DEBUGADD(0, (" occured while storing the RID index (%s)\n", keystr));
671 /***************************************************************************
673 ****************************************************************************/
675 static BOOL tdb_update_sam(struct pdb_methods *my_methods, struct samu* newpwd, int flag)
680 /* invalidate the existing TDB iterator if it is open */
682 tdbsam_endsampwent( my_methods );
684 if ( !pdb_get_group_rid(newpwd) ) {
685 DEBUG (0,("tdb_update_sam: Failing to store a struct samu for [%s] "
686 "without a primary group RID\n", pdb_get_username(newpwd)));
690 if ( !(user_rid = pdb_get_user_rid(newpwd)) ) {
691 DEBUG(0,("tdb_update_sam: struct samu (%s) with no RID!\n", pdb_get_username(newpwd)));
695 /* open the database */
697 if ( !tdbsam_open( tdbsam_filename ) ) {
698 DEBUG(0,("tdbsam_getsampwnam: failed to open %s!\n", tdbsam_filename));
702 if ( !tdb_update_samacct_only(newpwd, flag) || !tdb_update_ridrec_only(newpwd, flag)) {
713 /***************************************************************************
714 Modifies an existing struct samu
715 ****************************************************************************/
717 static NTSTATUS tdbsam_update_sam_account (struct pdb_methods *my_methods, struct samu *newpwd)
719 if ( !tdb_update_sam(my_methods, newpwd, TDB_MODIFY) )
720 return NT_STATUS_UNSUCCESSFUL;
725 /***************************************************************************
726 Adds an existing struct samu
727 ****************************************************************************/
729 static NTSTATUS tdbsam_add_sam_account (struct pdb_methods *my_methods, struct samu *newpwd)
731 if ( !tdb_update_sam(my_methods, newpwd, TDB_INSERT) )
732 return NT_STATUS_UNSUCCESSFUL;
737 /***************************************************************************
738 Renames a struct samu
739 - check for the posix user/rename user script
740 - Add and lock the new user record
741 - rename the posix user
742 - rewrite the rid->username record
743 - delete the old user
744 - unlock the new user record
745 ***************************************************************************/
746 static NTSTATUS tdbsam_rename_sam_account(struct pdb_methods *my_methods,
747 struct samu *old_acct,
750 struct samu *new_acct = NULL;
751 pstring rename_script;
752 BOOL interim_account = False;
755 /* make sure we have an open handle to the tdb. Should have happened
756 at module initialization time */
759 DEBUG(0,("tdbsam_getsampwrid: tdbsam not open!\n"));
760 return NT_STATUS_NO_SUCH_USER;
763 /* can't do anything without an external script */
765 pstrcpy(rename_script, lp_renameuser_script() );
766 if ( ! *rename_script )
767 return NT_STATUS_ACCESS_DENIED;
769 /* invalidate the existing TDB iterator if it is open */
771 tdbsam_endsampwent( my_methods );
773 if ( !pdb_copy_sam_account(old_acct, &new_acct)
774 || !pdb_set_username(new_acct, newname, PDB_CHANGED))
776 TALLOC_FREE(new_acct );
777 return NT_STATUS_NO_MEMORY;
780 /* open the database */
782 if ( !tdbsam_open( tdbsam_filename ) ) {
783 DEBUG(0,("tdbsam_getsampwnam: failed to open %s!\n", tdbsam_filename));
784 TALLOC_FREE(new_acct );
785 return NT_STATUS_ACCESS_DENIED;
788 /* add the new account and lock it */
790 if ( !tdb_update_samacct_only(new_acct, TDB_INSERT) )
795 interim_account = True;
797 if ( tdb_lock_bystring(tdbsam, newname, 30) == -1 ) {
801 /* rename the posix user */
803 pstring_sub(rename_script, "%unew", newname);
804 pstring_sub(rename_script, "%uold", pdb_get_username(old_acct));
805 rename_ret = smbrun(rename_script, NULL);
807 DEBUG(rename_ret ? 0 : 3,("Running the command `%s' gave %d\n", rename_script, rename_ret));
812 /* rewrite the rid->username record */
814 if ( !tdb_update_ridrec_only( new_acct, TDB_MODIFY) )
816 interim_account = False;
817 tdb_unlock_bystring( tdbsam, newname );
819 tdb_delete_samacct_only( old_acct );
823 TALLOC_FREE(new_acct );
828 if (interim_account) {
829 tdb_unlock_bystring(tdbsam, newname);
830 tdb_delete_samacct_only(new_acct);
836 TALLOC_FREE(new_acct);
838 return NT_STATUS_ACCESS_DENIED;
841 static BOOL tdbsam_rid_algorithm(struct pdb_methods *methods)
847 * Historically, winbind was responsible for allocating RIDs, so the next RID
848 * value was stored in winbindd_idmap.tdb. It has been moved to passdb now,
849 * but for compatibility reasons we still keep the the next RID counter in
850 * winbindd_idmap.tdb.
853 /*****************************************************************************
854 Initialise idmap database. For now (Dec 2005) this is a copy of the code in
855 sam/idmap_tdb.c. Maybe at a later stage we can remove that capability from
856 winbind completely and store the RID counter in passdb.tdb.
858 Dont' fully initialize with the HWM values, if it's new, we're only
859 interested in the RID counter.
860 *****************************************************************************/
862 static BOOL init_idmap_tdb(TDB_CONTEXT *tdb)
866 if (tdb_lock_bystring(tdb, "IDMAP_VERSION", 0) != 0) {
867 DEBUG(0, ("Could not lock IDMAP_VERSION\n"));
871 version = tdb_fetch_int32(tdb, "IDMAP_VERSION");
874 /* No key found, must be a new db */
875 if (tdb_store_int32(tdb, "IDMAP_VERSION",
876 IDMAP_VERSION) != 0) {
877 DEBUG(0, ("Could not store IDMAP_VERSION\n"));
878 tdb_unlock_bystring(tdb, "IDMAP_VERSION");
881 version = IDMAP_VERSION;
884 if (version != IDMAP_VERSION) {
885 DEBUG(0, ("Expected IDMAP_VERSION=%d, found %d. Please "
886 "start winbind once\n", IDMAP_VERSION, version));
887 tdb_unlock_bystring(tdb, "IDMAP_VERSION");
891 tdb_unlock_bystring(tdb, "IDMAP_VERSION");
895 static BOOL tdbsam_new_rid(struct pdb_methods *methods, uint32 *prid)
901 tdb = tdb_open_log(lock_path("winbindd_idmap.tdb"), 0,
902 TDB_DEFAULT, O_RDWR | O_CREAT, 0644);
905 DEBUG(1, ("Could not open idmap: %s\n", strerror(errno)));
909 if (!init_idmap_tdb(tdb)) {
910 DEBUG(1, ("Could not init idmap\n"));
914 rid = BASE_RID; /* Default if not set */
916 if (!tdb_change_uint32_atomic(tdb, "RID_COUNTER", &rid, 1)) {
917 DEBUG(3, ("tdbsam_new_rid: Failed to increase RID_COUNTER\n"));
925 if ((tdb != NULL) && (tdb_close(tdb) != 0)) {
926 smb_panic("tdb_close(idmap_tdb) failed\n");
932 /*********************************************************************
933 Initialize the tdb sam backend. Setup the dispath table of methods,
935 *********************************************************************/
937 static NTSTATUS pdb_init_tdbsam(struct pdb_methods **pdb_method, const char *location)
941 const char *pfile = location;
943 if (!NT_STATUS_IS_OK(nt_status = make_pdb_method( pdb_method ))) {
947 (*pdb_method)->name = "tdbsam";
949 (*pdb_method)->setsampwent = tdbsam_setsampwent;
950 (*pdb_method)->endsampwent = tdbsam_endsampwent;
951 (*pdb_method)->getsampwent = tdbsam_getsampwent;
952 (*pdb_method)->getsampwnam = tdbsam_getsampwnam;
953 (*pdb_method)->getsampwsid = tdbsam_getsampwsid;
954 (*pdb_method)->add_sam_account = tdbsam_add_sam_account;
955 (*pdb_method)->update_sam_account = tdbsam_update_sam_account;
956 (*pdb_method)->delete_sam_account = tdbsam_delete_sam_account;
957 (*pdb_method)->rename_sam_account = tdbsam_rename_sam_account;
959 (*pdb_method)->rid_algorithm = tdbsam_rid_algorithm;
960 (*pdb_method)->new_rid = tdbsam_new_rid;
962 /* save the path for later */
965 pstr_sprintf( tdbfile, "%s/%s", lp_private_dir(), PASSDB_FILE_NAME );
968 pstrcpy( tdbsam_filename, pfile );
970 /* no private data */
972 (*pdb_method)->private_data = NULL;
973 (*pdb_method)->free_private_data = NULL;
978 NTSTATUS pdb_tdbsam_init(void)
980 return smb_register_passdb(PASSDB_INTERFACE_VERSION, "tdbsam", pdb_init_tdbsam);