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;
53 static BOOL pwent_initialized;
55 /* GLOBAL TDB SAM CONTEXT */
57 static TDB_CONTEXT *tdbsam;
58 static int ref_count = 0;
59 static pstring tdbsam_filename;
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(int32 from)
71 const char *vstring = TDBSAM_VERSION_STRING;
72 const char *prefix = USERPREFIX;
73 TDB_DATA data, key, old_key;
77 /* handle a Samba upgrade */
78 tdb_lock_bystring(tdbsam, vstring, 0);
80 /* Enumerate all records and convert them */
81 key = tdb_firstkey(tdbsam);
85 /* skip all non-USER entries (eg. RIDs) */
86 while ((key.dsize != 0) && (strncmp(key.dptr, prefix, strlen (prefix)))) {
88 /* increment to next in line */
89 key = tdb_nextkey(tdbsam, key);
90 SAFE_FREE(old_key.dptr);
94 struct samu *user = NULL;
96 /* read from tdbsam */
97 data = tdb_fetch(tdbsam, key);
99 DEBUG(0,("tdbsam_convert: database entry not found: %s.\n",key.dptr));
103 /* unpack the buffer from the former format */
104 pdb_init_sam( &user );
105 DEBUG(10,("tdbsam_convert: Try unpacking a record with (key:%s) (version:%d)\n", key.dptr, from));
108 ret = init_sam_from_buffer_v0(user, (uint8 *)data.dptr, data.dsize);
111 ret = init_sam_from_buffer_v1(user, (uint8 *)data.dptr, data.dsize);
114 ret = init_sam_from_buffer_v2(user, (uint8 *)data.dptr, data.dsize);
117 /* unknown tdbsam version */
121 DEBUG(0,("tdbsam_convert: Bad struct samu entry returned from TDB (key:%s) (version:%d)\n", key.dptr, from));
122 SAFE_FREE(data.dptr);
127 /* We're finished with the old data. */
128 SAFE_FREE(data.dptr);
130 /* pack from the buffer into the new format */
132 DEBUG(10,("tdbsam_convert: Try packing a record (key:%s) (version:%d)\n", key.dptr, from));
133 data.dsize = init_buffer_from_sam (&buf, user, False);
136 if ( data.dsize == -1 ) {
137 DEBUG(0,("tdbsam_convert: cannot pack the struct samu into the new format\n"));
140 data.dptr = (char *)buf;
142 /* Store the buffer inside the TDBSAM */
143 if (tdb_store(tdbsam, key, data, TDB_MODIFY) != TDB_SUCCESS) {
144 DEBUG(0,("tdbsam_convert: cannot store the struct samu (key:%s) in new format\n",key.dptr));
145 SAFE_FREE(data.dptr);
149 SAFE_FREE(data.dptr);
151 /* increment to next in line */
153 key = tdb_nextkey(tdbsam, key);
154 SAFE_FREE(old_key.dptr);
160 /* upgrade finished */
161 tdb_store_int32(tdbsam, vstring, TDBSAM_VERSION);
162 tdb_unlock_bystring(tdbsam, vstring);
167 /*********************************************************************
168 Open the tdbsam file based on the absolute path specified.
169 Uses a reference count to allow multiple open calls.
170 *********************************************************************/
172 static BOOL tdbsam_open( const char *name )
176 /* check if we are already open */
180 DEBUG(8,("tdbsam_open: Incrementing open reference count. Ref count is now %d\n",
185 SMB_ASSERT( ref_count == 0 );
187 /* Try to open tdb passwd. Create a new one if necessary */
189 if (!(tdbsam = tdb_open_log(name, 0, TDB_DEFAULT, O_CREAT|O_RDWR, 0600))) {
190 DEBUG(0, ("tdbsam_open: Failed to open/create TDB passwd [%s]\n", name));
194 /* Check the version */
195 version = tdb_fetch_int32( tdbsam, TDBSAM_VERSION_STRING );
198 version = 0; /* Version not found, assume version 0 */
200 /* Compare the version */
201 if (version > TDBSAM_VERSION) {
202 /* Version more recent than the latest known */
203 DEBUG(0, ("tdbsam_open: unknown version => %d\n", version));
209 if ( version < TDBSAM_VERSION ) {
210 DEBUG(1, ("tdbsam_open: Converting version %d database to version %d.\n",
211 version, TDBSAM_VERSION));
213 if ( !tdbsam_convert(version) ) {
214 DEBUG(0, ("tdbsam_open: Error when trying to convert tdbsam [%s]\n",name));
219 DEBUG(3, ("TDBSAM converted successfully.\n"));
222 /* set the initial reference count */
226 DEBUG(4,("tdbsam_open: successfully opened %s\n", name ));
231 /****************************************************************************
232 wrapper atound tdb_close() to handle the reference count
233 ****************************************************************************/
235 void tdbsam_close( void )
239 DEBUG(8,("tdbsam_close: Reference count is now %d.\n", ref_count));
241 SMB_ASSERT(ref_count >= 0 );
243 if ( ref_count == 0 ) {
251 /****************************************************************************
252 creates a list of user keys
253 ****************************************************************************/
255 static int tdbsam_traverse_setpwent(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
257 const char *prefix = USERPREFIX;
258 int prefixlen = strlen (prefix);
259 struct pwent_list *ptr;
261 if ( strncmp(key.dptr, prefix, prefixlen) == 0 ) {
262 if ( !(ptr=SMB_MALLOC_P(struct pwent_list)) ) {
263 DEBUG(0,("tdbsam_traverse_setpwent: Failed to malloc new entry for list\n"));
265 /* just return 0 and let the traversal continue */
270 /* save a copy of the key */
272 ptr->key.dptr = memdup( key.dptr, key.dsize );
273 ptr->key.dsize = key.dsize;
275 DLIST_ADD( tdbsam_pwent_list, ptr );
283 /***************************************************************
284 Open the TDB passwd database for SAM account enumeration.
285 Save a list of user keys for iteration.
286 ****************************************************************/
288 static NTSTATUS tdbsam_setsampwent(struct pdb_methods *my_methods, BOOL update, uint16 acb_mask)
290 if ( !tdbsam_open( tdbsam_filename ) ) {
291 DEBUG(0,("tdbsam_getsampwnam: failed to open %s!\n", tdbsam_filename));
292 return NT_STATUS_ACCESS_DENIED;
295 tdb_traverse( tdbsam, tdbsam_traverse_setpwent, NULL );
296 pwent_initialized = True;
302 /***************************************************************
303 End enumeration of the TDB passwd list.
304 ****************************************************************/
306 static void tdbsam_endsampwent(struct pdb_methods *my_methods)
308 struct pwent_list *ptr, *ptr_next;
310 /* close the tdb only if we have a valid pwent state */
312 if ( pwent_initialized ) {
313 DEBUG(7, ("endtdbpwent: closed sam database.\n"));
317 /* clear out any remaining entries in the list */
319 for ( ptr=tdbsam_pwent_list; ptr; ptr = ptr_next ) {
320 ptr_next = ptr->next;
321 DLIST_REMOVE( tdbsam_pwent_list, ptr );
322 SAFE_FREE( ptr->key.dptr);
326 pwent_initialized = False;
329 /*****************************************************************
330 Get one struct samu from the TDB (next in line)
331 *****************************************************************/
333 static NTSTATUS tdbsam_getsampwent(struct pdb_methods *my_methods, struct samu *user)
335 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
337 struct pwent_list *pkey;
340 DEBUG(0,("tdbsam_getsampwent: struct samu is NULL.\n"));
344 if ( !tdbsam_pwent_list ) {
345 DEBUG(4,("tdbsam_getsampwent: end of list\n"));
349 /* pull the next entry */
351 pkey = tdbsam_pwent_list;
352 DLIST_REMOVE( tdbsam_pwent_list, pkey );
354 data = tdb_fetch(tdbsam, pkey->key);
356 SAFE_FREE( pkey->key.dptr);
360 DEBUG(5,("pdb_getsampwent: database entry not found. Was the user deleted?\n"));
364 if ( !init_sam_from_buffer(user, (unsigned char *)data.dptr, data.dsize) ) {
365 DEBUG(0,("pdb_getsampwent: Bad struct samu entry returned from TDB!\n"));
368 SAFE_FREE( data.dptr );
373 /******************************************************************
374 Lookup a name in the SAM TDB
375 ******************************************************************/
377 static NTSTATUS tdbsam_getsampwnam (struct pdb_methods *my_methods, struct samu *user, const char *sname)
385 DEBUG(0,("pdb_getsampwnam: struct samu is NULL.\n"));
386 return NT_STATUS_NO_MEMORY;
389 /* Data is stored in all lower-case */
390 fstrcpy(name, sname);
394 slprintf(keystr, sizeof(keystr)-1, "%s%s", USERPREFIX, name);
396 key.dsize = strlen(keystr) + 1;
398 /* open the database */
400 if ( !tdbsam_open( tdbsam_filename ) ) {
401 DEBUG(0,("tdbsam_getsampwnam: failed to open %s!\n", tdbsam_filename));
402 return NT_STATUS_ACCESS_DENIED;
407 data = tdb_fetch(tdbsam, key);
409 DEBUG(5,("pdb_getsampwnam (TDB): error fetching database.\n"));
410 DEBUGADD(5, (" Error: %s\n", tdb_errorstr(tdbsam)));
411 DEBUGADD(5, (" Key: %s\n", keystr));
412 result = NT_STATUS_NO_SUCH_USER;
416 /* unpack the buffer */
418 if (!init_sam_from_buffer(user, (unsigned char *)data.dptr, data.dsize)) {
419 DEBUG(0,("pdb_getsampwent: Bad struct samu entry returned from TDB!\n"));
420 SAFE_FREE(data.dptr);
421 result = NT_STATUS_NO_MEMORY;
425 result = NT_STATUS_OK;
428 SAFE_FREE(data.dptr);
434 /***************************************************************************
436 **************************************************************************/
438 static NTSTATUS tdbsam_getsampwrid (struct pdb_methods *my_methods, struct samu *user, uint32 rid)
440 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
446 DEBUG(0,("pdb_getsampwrid: struct samu is NULL.\n"));
452 slprintf(keystr, sizeof(keystr)-1, "%s%.8x", RIDPREFIX, rid);
454 key.dsize = strlen (keystr) + 1;
456 /* open the database */
458 if ( !tdbsam_open( tdbsam_filename ) ) {
459 DEBUG(0,("tdbsam_getsampwnam: failed to open %s!\n", tdbsam_filename));
460 return NT_STATUS_ACCESS_DENIED;
465 data = tdb_fetch (tdbsam, key);
467 DEBUG(5,("pdb_getsampwrid (TDB): error looking up RID %d by key %s.\n", rid, keystr));
468 DEBUGADD(5, (" Error: %s\n", tdb_errorstr(tdbsam)));
469 nt_status = NT_STATUS_UNSUCCESSFUL;
473 fstrcpy(name, data.dptr);
474 SAFE_FREE(data.dptr);
476 nt_status = tdbsam_getsampwnam (my_methods, user, name);
486 static NTSTATUS tdbsam_getsampwsid(struct pdb_methods *my_methods, struct samu * user, const DOM_SID *sid)
490 if ( !sid_peek_check_rid(get_global_sam_sid(), sid, &rid) )
491 return NT_STATUS_UNSUCCESSFUL;
493 return tdbsam_getsampwrid(my_methods, user, rid);
496 static BOOL tdb_delete_samacct_only( struct samu *sam_pass )
502 fstrcpy(name, pdb_get_username(sam_pass));
505 /* set the search key */
507 slprintf(keystr, sizeof(keystr)-1, "%s%s", USERPREFIX, name);
509 key.dsize = strlen (keystr) + 1;
511 /* it's outaa here! 8^) */
513 if (tdb_delete(tdbsam, key) != TDB_SUCCESS) {
514 DEBUG(5, ("Error deleting entry from tdb passwd database!\n"));
515 DEBUGADD(5, (" Error: %s\n", tdb_errorstr(tdbsam)));
522 /***************************************************************************
523 Delete a struct samu records for the username and RID key
524 ****************************************************************************/
526 static NTSTATUS tdbsam_delete_sam_account(struct pdb_methods *my_methods, struct samu *sam_pass)
528 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
534 /* make sure we have an open handle to the tdb. Should have happened
535 at module initialization time */
538 DEBUG(0,("tdbsam_getsampwrid: tdbsam not open!\n"));
539 return NT_STATUS_NO_SUCH_USER;
542 fstrcpy(name, pdb_get_username(sam_pass));
545 /* set the search key */
547 slprintf(keystr, sizeof(keystr)-1, "%s%s", USERPREFIX, name);
549 key.dsize = strlen (keystr) + 1;
551 rid = pdb_get_user_rid(sam_pass);
553 /* open the database */
555 if ( !tdbsam_open( tdbsam_filename ) ) {
556 DEBUG(0,("tdbsam_getsampwnam: failed to open %s!\n", tdbsam_filename));
557 return NT_STATUS_ACCESS_DENIED;
560 /* it's outaa here! 8^) */
562 if ( tdb_delete(tdbsam, key) != TDB_SUCCESS ) {
563 DEBUG(5, ("Error deleting entry from tdb passwd database!\n"));
564 DEBUGADD(5, (" Error: %s\n", tdb_errorstr(tdbsam)));
565 nt_status = NT_STATUS_UNSUCCESSFUL;
569 /* set the search key */
571 slprintf(keystr, sizeof(keystr)-1, "%s%.8x", RIDPREFIX, rid);
573 key.dsize = strlen (keystr) + 1;
575 /* it's outaa here! 8^) */
577 if ( tdb_delete(tdbsam, key) != TDB_SUCCESS ) {
578 DEBUG(5, ("Error deleting entry from tdb rid database!\n"));
579 DEBUGADD(5, (" Error: %s\n", tdb_errorstr(tdbsam)));
580 nt_status = NT_STATUS_UNSUCCESSFUL;
584 nt_status = NT_STATUS_OK;
593 /***************************************************************************
594 Update the TDB SAM account record only
595 Assumes that the tdbsam is already open
596 ****************************************************************************/
597 static BOOL tdb_update_samacct_only( struct samu* newpwd, int flag )
605 /* copy the struct samu struct into a BYTE buffer for storage */
607 if ( (data.dsize=init_buffer_from_sam (&buf, newpwd, False)) == -1 ) {
608 DEBUG(0,("tdb_update_sam: ERROR - Unable to copy struct samu info BYTE buffer!\n"));
612 data.dptr = (char *)buf;
614 fstrcpy(name, pdb_get_username(newpwd));
617 DEBUG(5, ("Storing %saccount %s with RID %d\n",
618 flag == TDB_INSERT ? "(new) " : "", name,
619 pdb_get_user_rid(newpwd)));
621 /* setup the USER index key */
622 slprintf(keystr, sizeof(keystr)-1, "%s%s", USERPREFIX, name);
624 key.dsize = strlen(keystr) + 1;
626 /* add the account */
628 if ( tdb_store(tdbsam, key, data, flag) != TDB_SUCCESS ) {
629 DEBUG(0, ("Unable to modify passwd TDB!"));
630 DEBUGADD(0, (" Error: %s", tdb_errorstr(tdbsam)));
631 DEBUGADD(0, (" occured while storing the main record (%s)\n",
644 /***************************************************************************
645 Update the TDB SAM RID record only
646 Assumes that the tdbsam is already open
647 ****************************************************************************/
648 static BOOL tdb_update_ridrec_only( struct samu* newpwd, int flag )
654 fstrcpy(name, pdb_get_username(newpwd));
658 data.dsize = strlen(name) + 1;
661 /* setup the RID index key */
662 slprintf(keystr, sizeof(keystr)-1, "%s%.8x", RIDPREFIX, pdb_get_user_rid(newpwd));
664 key.dsize = strlen (keystr) + 1;
666 /* add the reference */
667 if (tdb_store(tdbsam, key, data, flag) != TDB_SUCCESS) {
668 DEBUG(0, ("Unable to modify TDB passwd !"));
669 DEBUGADD(0, (" Error: %s\n", tdb_errorstr(tdbsam)));
670 DEBUGADD(0, (" occured while storing the RID index (%s)\n", keystr));
678 /***************************************************************************
680 ****************************************************************************/
682 static BOOL tdb_update_sam(struct pdb_methods *my_methods, struct samu* newpwd, int flag)
687 /* invalidate the existing TDB iterator if it is open */
689 tdbsam_endsampwent( my_methods );
691 if ( !pdb_get_group_rid(newpwd) ) {
692 DEBUG (0,("tdb_update_sam: Failing to store a struct samu for [%s] "
693 "without a primary group RID\n", pdb_get_username(newpwd)));
697 if ( !(user_rid = pdb_get_user_rid(newpwd)) ) {
698 DEBUG(0,("tdb_update_sam: struct samu (%s) with no RID!\n", pdb_get_username(newpwd)));
702 /* open the database */
704 if ( !tdbsam_open( tdbsam_filename ) ) {
705 DEBUG(0,("tdbsam_getsampwnam: failed to open %s!\n", tdbsam_filename));
709 if ( !tdb_update_samacct_only(newpwd, flag) || !tdb_update_ridrec_only(newpwd, flag)) {
720 /***************************************************************************
721 Modifies an existing struct samu
722 ****************************************************************************/
724 static NTSTATUS tdbsam_update_sam_account (struct pdb_methods *my_methods, struct samu *newpwd)
726 if ( !tdb_update_sam(my_methods, newpwd, TDB_MODIFY) )
727 return NT_STATUS_UNSUCCESSFUL;
732 /***************************************************************************
733 Adds an existing struct samu
734 ****************************************************************************/
736 static NTSTATUS tdbsam_add_sam_account (struct pdb_methods *my_methods, struct samu *newpwd)
738 if ( !tdb_update_sam(my_methods, newpwd, TDB_INSERT) )
739 return NT_STATUS_UNSUCCESSFUL;
744 /***************************************************************************
745 Renames a struct samu
746 - check for the posix user/rename user script
747 - Add and lock the new user record
748 - rename the posix user
749 - rewrite the rid->username record
750 - delete the old user
751 - unlock the new user record
752 ***************************************************************************/
753 static NTSTATUS tdbsam_rename_sam_account(struct pdb_methods *my_methods,
754 struct samu *old_acct,
757 struct samu *new_acct = NULL;
758 pstring rename_script;
759 BOOL interim_account = False;
762 /* make sure we have an open handle to the tdb. Should have happened
763 at module initialization time */
766 DEBUG(0,("tdbsam_getsampwrid: tdbsam not open!\n"));
767 return NT_STATUS_NO_SUCH_USER;
770 /* can't do anything without an external script */
772 pstrcpy(rename_script, lp_renameuser_script() );
773 if ( ! *rename_script )
774 return NT_STATUS_ACCESS_DENIED;
776 /* invalidate the existing TDB iterator if it is open */
778 tdbsam_endsampwent( my_methods );
780 if ( !pdb_copy_sam_account(old_acct, &new_acct)
781 || !pdb_set_username(new_acct, newname, PDB_CHANGED))
783 TALLOC_FREE(new_acct );
784 return NT_STATUS_NO_MEMORY;
787 /* open the database */
789 if ( !tdbsam_open( tdbsam_filename ) ) {
790 DEBUG(0,("tdbsam_getsampwnam: failed to open %s!\n", tdbsam_filename));
791 TALLOC_FREE(new_acct );
792 return NT_STATUS_ACCESS_DENIED;
795 /* add the new account and lock it */
797 if ( !tdb_update_samacct_only(new_acct, TDB_INSERT) )
802 interim_account = True;
804 if ( tdb_lock_bystring(tdbsam, newname, 30) == -1 ) {
808 /* rename the posix user */
810 pstring_sub(rename_script, "%unew", newname);
811 pstring_sub(rename_script, "%uold", pdb_get_username(old_acct));
812 rename_ret = smbrun(rename_script, NULL);
814 DEBUG(rename_ret ? 0 : 3,("Running the command `%s' gave %d\n", rename_script, rename_ret));
819 /* rewrite the rid->username record */
821 if ( !tdb_update_ridrec_only( new_acct, TDB_MODIFY) )
823 interim_account = False;
824 tdb_unlock_bystring( tdbsam, newname );
826 tdb_delete_samacct_only( old_acct );
830 TALLOC_FREE(new_acct );
835 if (interim_account) {
836 tdb_unlock_bystring(tdbsam, newname);
837 tdb_delete_samacct_only(new_acct);
843 TALLOC_FREE(new_acct);
845 return NT_STATUS_ACCESS_DENIED;
848 static BOOL tdbsam_rid_algorithm(struct pdb_methods *methods)
854 * Historically, winbind was responsible for allocating RIDs, so the next RID
855 * value was stored in winbindd_idmap.tdb. It has been moved to passdb now,
856 * but for compatibility reasons we still keep the the next RID counter in
857 * winbindd_idmap.tdb.
860 /*****************************************************************************
861 Initialise idmap database. For now (Dec 2005) this is a copy of the code in
862 sam/idmap_tdb.c. Maybe at a later stage we can remove that capability from
863 winbind completely and store the RID counter in passdb.tdb.
865 Dont' fully initialize with the HWM values, if it's new, we're only
866 interested in the RID counter.
867 *****************************************************************************/
869 static BOOL init_idmap_tdb(TDB_CONTEXT *tdb)
873 if (tdb_lock_bystring(tdb, "IDMAP_VERSION", 0) != 0) {
874 DEBUG(0, ("Could not lock IDMAP_VERSION\n"));
878 version = tdb_fetch_int32(tdb, "IDMAP_VERSION");
881 /* No key found, must be a new db */
882 if (tdb_store_int32(tdb, "IDMAP_VERSION",
883 IDMAP_VERSION) != 0) {
884 DEBUG(0, ("Could not store IDMAP_VERSION\n"));
885 tdb_unlock_bystring(tdb, "IDMAP_VERSION");
888 version = IDMAP_VERSION;
891 if (version != IDMAP_VERSION) {
892 DEBUG(0, ("Expected IDMAP_VERSION=%d, found %d. Please "
893 "start winbind once\n", IDMAP_VERSION, version));
894 tdb_unlock_bystring(tdb, "IDMAP_VERSION");
898 tdb_unlock_bystring(tdb, "IDMAP_VERSION");
902 static BOOL tdbsam_new_rid(struct pdb_methods *methods, uint32 *prid)
908 tdb = tdb_open_log(lock_path("winbindd_idmap.tdb"), 0,
909 TDB_DEFAULT, O_RDWR | O_CREAT, 0644);
912 DEBUG(1, ("Could not open idmap: %s\n", strerror(errno)));
916 if (!init_idmap_tdb(tdb)) {
917 DEBUG(1, ("Could not init idmap\n"));
921 rid = BASE_RID; /* Default if not set */
923 if (!tdb_change_uint32_atomic(tdb, "RID_COUNTER", &rid, 1)) {
924 DEBUG(3, ("tdbsam_new_rid: Failed to increase RID_COUNTER\n"));
932 if ((tdb != NULL) && (tdb_close(tdb) != 0)) {
933 smb_panic("tdb_close(idmap_tdb) failed\n");
939 /*********************************************************************
940 Initialize the tdb sam backend. Setup the dispath table of methods,
942 *********************************************************************/
944 static NTSTATUS pdb_init_tdbsam(struct pdb_methods **pdb_method, const char *location)
948 const char *pfile = location;
950 if (!NT_STATUS_IS_OK(nt_status = make_pdb_method( pdb_method ))) {
954 (*pdb_method)->name = "tdbsam";
956 (*pdb_method)->setsampwent = tdbsam_setsampwent;
957 (*pdb_method)->endsampwent = tdbsam_endsampwent;
958 (*pdb_method)->getsampwent = tdbsam_getsampwent;
959 (*pdb_method)->getsampwnam = tdbsam_getsampwnam;
960 (*pdb_method)->getsampwsid = tdbsam_getsampwsid;
961 (*pdb_method)->add_sam_account = tdbsam_add_sam_account;
962 (*pdb_method)->update_sam_account = tdbsam_update_sam_account;
963 (*pdb_method)->delete_sam_account = tdbsam_delete_sam_account;
964 (*pdb_method)->rename_sam_account = tdbsam_rename_sam_account;
966 (*pdb_method)->rid_algorithm = tdbsam_rid_algorithm;
967 (*pdb_method)->new_rid = tdbsam_new_rid;
969 /* save the path for later */
972 pstr_sprintf( tdbfile, "%s/%s", lp_private_dir(), PASSDB_FILE_NAME );
975 pstrcpy( tdbsam_filename, pfile );
977 /* no private data */
979 (*pdb_method)->private_data = NULL;
980 (*pdb_method)->free_private_data = NULL;
985 NTSTATUS pdb_tdbsam_init(void)
987 return smb_register_passdb(PASSDB_INTERFACE_VERSION, "tdbsam", pdb_init_tdbsam);