static bool tdb_delete_samacct_only( struct samu *sam_pass ) { fstring keystr; fstring name; NTSTATUS status; fstrcpy(name, pdb_get_username(sam_pass)); if (!strlower_m(name)) { return false; } /* set the search key */ fstr_sprintf(keystr, "%s%s", USERPREFIX, name); /* it's outaa here! 8^) */ if ( !tdbsam_open( tdbsam_filename ) ) { DEBUG(0,("tdb_delete_samacct_only: failed to open %s!\n", tdbsam_filename)); return false; } status = dbwrap_delete_bystring(db_sam, keystr); if (!NT_STATUS_IS_OK(status)) { DEBUG(5, ("Error deleting entry from tdb passwd " "database: %s!\n", nt_errstr(status))); return false; } return true; }
static bool tdbsam_new_rid(struct pdb_methods *methods, uint32_t *prid) { uint32_t rid; NTSTATUS status; rid = BASE_RID; /* Default if not set */ if (!tdbsam_open(tdbsam_filename)) { DEBUG(0,("tdbsam_new_rid: failed to open %s!\n", tdbsam_filename)); return false; } status = dbwrap_trans_change_uint32_atomic_bystring( db_sam, NEXT_RID_STRING, &rid, 1); if (!NT_STATUS_IS_OK(status)) { DEBUG(3, ("tdbsam_new_rid: Failed to increase %s: %s\n", NEXT_RID_STRING, nt_errstr(status))); return false; } *prid = rid; return true; }
static NTSTATUS tdbsam_getsampwnam (struct pdb_methods *my_methods, struct samu *user, const char *sname) { TDB_DATA data; fstring keystr; fstring name; NTSTATUS status; if ( !user ) { DEBUG(0,("pdb_getsampwnam: struct samu is NULL.\n")); return NT_STATUS_NO_MEMORY; } /* Data is stored in all lower-case */ fstrcpy(name, sname); if (!strlower_m(name)) { return NT_STATUS_INVALID_PARAMETER; } /* set search key */ fstr_sprintf(keystr, "%s%s", USERPREFIX, name); /* open the database */ if ( !tdbsam_open( tdbsam_filename ) ) { DEBUG(0,("tdbsam_getsampwnam: failed to open %s!\n", tdbsam_filename)); return NT_STATUS_ACCESS_DENIED; } /* get the record */ status = dbwrap_fetch_bystring(db_sam, talloc_tos(), keystr, &data); if (!NT_STATUS_IS_OK(status)) { DEBUG(5,("pdb_getsampwnam (TDB): error fetching database.\n")); DEBUGADD(5, (" Key: %s\n", keystr)); return NT_STATUS_NO_SUCH_USER; } if (data.dsize == 0) { DEBUG(5, ("%s: Got 0-sized record for key %s\n", __func__, keystr)); return NT_STATUS_NO_SUCH_USER; } /* unpack the buffer */ if (!init_samu_from_buffer(user, SAMU_BUFFER_LATEST, data.dptr, data.dsize)) { DEBUG(0,("pdb_getsampwent: Bad struct samu entry returned from TDB!\n")); TALLOC_FREE(data.dptr); return NT_STATUS_NO_MEMORY; } /* success */ TALLOC_FREE(data.dptr); return NT_STATUS_OK; }
static bool tdbsam_new_rid(struct pdb_methods *methods, uint32 *prid) { uint32 rid; rid = BASE_RID; /* Default if not set */ if (!tdbsam_open(tdbsam_filename)) { DEBUG(0,("tdbsam_new_rid: failed to open %s!\n", tdbsam_filename)); return false; } if (dbwrap_change_uint32_atomic(db_sam, NEXT_RID_STRING, &rid, 1) != 0) { DEBUG(3, ("tdbsam_new_rid: Failed to increase %s\n", NEXT_RID_STRING)); return false; } *prid = rid; return true; }
static NTSTATUS tdbsam_getsampwrid (struct pdb_methods *my_methods, struct samu *user, uint32_t rid) { NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; TDB_DATA data; fstring keystr; fstring name; if ( !user ) { DEBUG(0,("pdb_getsampwrid: struct samu is NULL.\n")); return nt_status; } /* set search key */ fstr_sprintf(keystr, "%s%.8x", RIDPREFIX, rid); /* open the database */ if ( !tdbsam_open( tdbsam_filename ) ) { DEBUG(0,("tdbsam_getsampwrid: failed to open %s!\n", tdbsam_filename)); return NT_STATUS_ACCESS_DENIED; } /* get the record */ nt_status = dbwrap_fetch_bystring(db_sam, talloc_tos(), keystr, &data); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(5,("pdb_getsampwrid (TDB): error looking up RID %d by key %s.\n", rid, keystr)); return nt_status; } fstrcpy(name, (const char *)data.dptr); TALLOC_FREE(data.dptr); return tdbsam_getsampwnam (my_methods, user, name); }
/*************************************************************************** Renames a struct samu - check for the posix user/rename user script - Add and lock the new user record - rename the posix user - rewrite the rid->username record - delete the old user - unlock the new user record ***************************************************************************/ static NTSTATUS tdbsam_rename_sam_account(struct pdb_methods *my_methods, struct samu *old_acct, const char *newname) { struct samu *new_acct = NULL; char *rename_script = NULL; int rename_ret; fstring oldname_lower; fstring newname_lower; /* can't do anything without an external script */ if ( !(new_acct = samu_new( talloc_tos() )) ) { return NT_STATUS_NO_MEMORY; } rename_script = lp_rename_user_script(new_acct); if (!rename_script) { TALLOC_FREE(new_acct); return NT_STATUS_NO_MEMORY; } if (!*rename_script) { TALLOC_FREE(new_acct); return NT_STATUS_ACCESS_DENIED; } if ( !pdb_copy_sam_account(new_acct, old_acct) || !pdb_set_username(new_acct, newname, PDB_CHANGED)) { TALLOC_FREE(new_acct); return NT_STATUS_NO_MEMORY; } /* open the database */ if ( !tdbsam_open( tdbsam_filename ) ) { DEBUG(0, ("tdbsam_getsampwnam: failed to open %s!\n", tdbsam_filename)); TALLOC_FREE(new_acct); return NT_STATUS_ACCESS_DENIED; } if (dbwrap_transaction_start(db_sam) != 0) { DEBUG(0, ("Could not start transaction\n")); TALLOC_FREE(new_acct); return NT_STATUS_ACCESS_DENIED; } /* add the new account and lock it */ if ( !tdb_update_samacct_only(new_acct, TDB_INSERT) ) { goto cancel; } /* Rename the posix user. Follow the semantics of _samr_create_user() so that we lower case the posix name but preserve the case in passdb */ fstrcpy( oldname_lower, pdb_get_username(old_acct) ); if (!strlower_m( oldname_lower )) { goto cancel; } fstrcpy( newname_lower, newname ); if (!strlower_m( newname_lower )) { goto cancel; } rename_script = talloc_string_sub2(new_acct, rename_script, "%unew", newname_lower, true, false, true); if (!rename_script) { goto cancel; } rename_script = talloc_string_sub2(new_acct, rename_script, "%uold", oldname_lower, true, false, true); if (!rename_script) { goto cancel; } rename_ret = smbrun(rename_script, NULL, NULL); DEBUG(rename_ret ? 0 : 3,("Running the command `%s' gave %d\n", rename_script, rename_ret)); if (rename_ret != 0) { goto cancel; } smb_nscd_flush_user_cache(); /* rewrite the rid->username record */ if ( !tdb_update_ridrec_only( new_acct, TDB_MODIFY) ) { goto cancel; } tdb_delete_samacct_only( old_acct ); if (dbwrap_transaction_commit(db_sam) != 0) { /* * Ok, we're screwed. We've changed the posix account, but * could not adapt passdb.tdb. Shall we change the posix * account back? */ DEBUG(0, ("transaction_commit failed\n")); TALLOC_FREE(new_acct); return NT_STATUS_INTERNAL_DB_CORRUPTION; } TALLOC_FREE(new_acct ); return NT_STATUS_OK; cancel: if (dbwrap_transaction_cancel(db_sam) != 0) { smb_panic("transaction_cancel failed"); } TALLOC_FREE(new_acct); return NT_STATUS_ACCESS_DENIED; }
static bool tdb_update_sam(struct pdb_methods *my_methods, struct samu* newpwd, int flag) { uint32_t oldrid; uint32_t newrid; if (!(newrid = pdb_get_user_rid(newpwd))) { DEBUG(0,("tdb_update_sam: struct samu (%s) with no RID!\n", pdb_get_username(newpwd))); return False; } oldrid = newrid; /* open the database */ if ( !tdbsam_open( tdbsam_filename ) ) { DEBUG(0,("tdbsam_getsampwnam: failed to open %s!\n", tdbsam_filename)); return False; } if (dbwrap_transaction_start(db_sam) != 0) { DEBUG(0, ("Could not start transaction\n")); return false; } /* If we are updating, we may be changing this users RID. Retrieve the old RID so we can check. */ if (flag == TDB_MODIFY) { struct samu *account = samu_new(talloc_tos()); if (account == NULL) { DEBUG(0,("tdb_update_sam: samu_new() failed\n")); goto cancel; } if (!NT_STATUS_IS_OK(tdbsam_getsampwnam(my_methods, account, pdb_get_username(newpwd)))) { DEBUG(0,("tdb_update_sam: tdbsam_getsampwnam() for %s failed\n", pdb_get_username(newpwd))); TALLOC_FREE(account); goto cancel; } if (!(oldrid = pdb_get_user_rid(account))) { DEBUG(0,("tdb_update_sam: pdb_get_user_rid() failed\n")); TALLOC_FREE(account); goto cancel; } TALLOC_FREE(account); } /* Update the new samu entry. */ if (!tdb_update_samacct_only(newpwd, flag)) { goto cancel; } /* Now take care of the case where the RID changed. We need * to delete the old RID key and add the new. */ if (flag == TDB_MODIFY && newrid != oldrid) { fstring keystr; /* Delete old RID key */ DEBUG(10, ("tdb_update_sam: Deleting key for RID %u\n", oldrid)); fstr_sprintf(keystr, "%s%.8x", RIDPREFIX, oldrid); if (!NT_STATUS_IS_OK(dbwrap_delete_bystring(db_sam, keystr))) { DEBUG(0, ("tdb_update_sam: Can't delete %s\n", keystr)); goto cancel; } /* Insert new RID key */ DEBUG(10, ("tdb_update_sam: Inserting key for RID %u\n", newrid)); if (!tdb_update_ridrec_only(newpwd, TDB_INSERT)) { goto cancel; } } else { DEBUG(10, ("tdb_update_sam: %s key for RID %u\n", flag == TDB_MODIFY ? "Updating" : "Inserting", newrid)); if (!tdb_update_ridrec_only(newpwd, flag)) { goto cancel; } } if (dbwrap_transaction_commit(db_sam) != 0) { DEBUG(0, ("Could not commit transaction\n")); return false; } return true; cancel: if (dbwrap_transaction_cancel(db_sam) != 0) { smb_panic("transaction_cancel failed"); } return false; }
static NTSTATUS tdbsam_delete_sam_account(struct pdb_methods *my_methods, struct samu *sam_pass) { NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; fstring keystr; uint32_t rid; fstring name; /* open the database */ if ( !tdbsam_open( tdbsam_filename ) ) { DEBUG(0,("tdbsam_delete_sam_account: failed to open %s!\n", tdbsam_filename)); return NT_STATUS_ACCESS_DENIED; } fstrcpy(name, pdb_get_username(sam_pass)); if (!strlower_m(name)) { return NT_STATUS_INVALID_PARAMETER; } /* set the search key */ fstr_sprintf(keystr, "%s%s", USERPREFIX, name); rid = pdb_get_user_rid(sam_pass); /* it's outaa here! 8^) */ if (dbwrap_transaction_start(db_sam) != 0) { DEBUG(0, ("Could not start transaction\n")); return NT_STATUS_UNSUCCESSFUL; } nt_status = dbwrap_delete_bystring(db_sam, keystr); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(5, ("Error deleting entry from tdb passwd " "database: %s!\n", nt_errstr(nt_status))); goto cancel; } /* set the search key */ fstr_sprintf(keystr, "%s%.8x", RIDPREFIX, rid); /* it's outaa here! 8^) */ nt_status = dbwrap_delete_bystring(db_sam, keystr); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(5, ("Error deleting entry from tdb rid " "database: %s!\n", nt_errstr(nt_status))); goto cancel; } if (dbwrap_transaction_commit(db_sam) != 0) { DEBUG(0, ("Could not commit transaction\n")); return NT_STATUS_INTERNAL_DB_CORRUPTION; } return NT_STATUS_OK; cancel: if (dbwrap_transaction_cancel(db_sam) != 0) { smb_panic("transaction_cancel failed"); } return nt_status; }