*/
#include "includes.h"
+#include "secrets.h"
+#include "../librpc/gen_ndr/samr.h"
+#include "memcache.h"
+#include "nsswitch/winbind_client.h"
+#include "../libcli/security/security.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_PASSDB
return pdb->get_domain_info(pdb, mem_ctx);
}
+/**
+ * @brief Check if the user account has been locked out and try to unlock it.
+ *
+ * If the user has been automatically locked out and a lockout duration is set,
+ * then check if we can unlock the account and reset the bad password values.
+ *
+ * @param[in] sampass The sam user to check.
+ *
+ * @return True if the function was successfull, false on an error.
+ */
+static bool pdb_try_account_unlock(struct samu *sampass)
+{
+ uint32_t acb_info = pdb_get_acct_ctrl(sampass);
+
+ if (acb_info & (ACB_NORMAL|ACB_AUTOLOCK)) {
+ uint32_t lockout_duration;
+ time_t bad_password_time;
+ time_t now = time(NULL);
+ bool ok;
+
+ ok = pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION,
+ &lockout_duration);
+ if (!ok) {
+ DEBUG(0, ("pdb_try_account_unlock: "
+ "pdb_get_account_policy failed.\n"));
+ return false;
+ }
+
+ if (lockout_duration == (uint32_t) -1 ||
+ lockout_duration == 0) {
+ DEBUG(9, ("pdb_try_account_unlock: No reset duration, "
+ "can't reset autolock\n"));
+ return false;
+ }
+ lockout_duration *= 60;
+
+ bad_password_time = pdb_get_bad_password_time(sampass);
+ if (bad_password_time == (time_t) 0) {
+ DEBUG(2, ("pdb_try_account_unlock: Account %s "
+ "administratively locked out "
+ "with no bad password "
+ "time. Leaving locked out.\n",
+ pdb_get_username(sampass)));
+ return true;
+ }
+
+ if ((bad_password_time +
+ convert_uint32_t_to_time_t(lockout_duration)) < now) {
+ NTSTATUS status;
+
+ pdb_set_acct_ctrl(sampass, acb_info & ~ACB_AUTOLOCK,
+ PDB_CHANGED);
+ pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
+ pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
+
+ become_root();
+ status = pdb_update_sam_account(sampass);
+ unbecome_root();
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("_samr_OpenUser: Couldn't "
+ "update account %s - %s\n",
+ pdb_get_username(sampass),
+ nt_errstr(status)));
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+/**
+ * @brief Get a sam user structure by the given username.
+ *
+ * This functions also checks if the account has been automatically locked out
+ * and unlocks it if a lockout duration time has been defined and the time has
+ * elapsed.
+ *
+ * @param[in] sam_acct The sam user structure to fill.
+ *
+ * @param[in] username The username to look for.
+ *
+ * @return True on success, false on error.
+ */
bool pdb_getsampwnam(struct samu *sam_acct, const char *username)
{
struct pdb_methods *pdb = pdb_get_methods();
struct samu *for_cache;
const struct dom_sid *user_sid;
+ NTSTATUS status;
+ bool ok;
- if (!NT_STATUS_IS_OK(pdb->getsampwnam(pdb, sam_acct, username))) {
- return False;
+ status = pdb->getsampwnam(pdb, sam_acct, username);
+ if (!NT_STATUS_IS_OK(status)) {
+ return false;
+ }
+
+ ok = pdb_try_account_unlock(sam_acct);
+ if (!ok) {
+ DEBUG(1, ("pdb_getsampwnam: Failed to unlock account %s\n",
+ username));
}
for_cache = samu_new(NULL);
NTSTATUS result;
const char *guestname = lp_guestaccount();
- if ( !(pwd = getpwnam_alloc(talloc_autofree_context(), guestname ) ) ) {
+ pwd = getpwnam_alloc(talloc_tos(), guestname);
+ if (pwd == NULL) {
DEBUG(0,("guest_user_info: Unable to locate guest account [%s]!\n",
guestname));
return False;
return NT_STATUS_IS_OK( result );
}
-/**********************************************************************
-**********************************************************************/
-
+/**
+ * @brief Get a sam user structure by the given username.
+ *
+ * This functions also checks if the account has been automatically locked out
+ * and unlocks it if a lockout duration time has been defined and the time has
+ * elapsed.
+ *
+ *
+ * @param[in] sam_acct The sam user structure to fill.
+ *
+ * @param[in] sid The user SDI to look up.
+ *
+ * @return True on success, false on error.
+ */
bool pdb_getsampwsid(struct samu *sam_acct, const struct dom_sid *sid)
{
struct pdb_methods *pdb = pdb_get_methods();
uint32_t rid;
void *cache_data;
+ bool ok = false;
/* hard code the Guest RID of 501 */
struct samu *cache_copy = talloc_get_type_abort(
cache_data, struct samu);
- return pdb_copy_sam_account(sam_acct, cache_copy);
+ ok = pdb_copy_sam_account(sam_acct, cache_copy);
+ } else {
+ ok = NT_STATUS_IS_OK(pdb->getsampwsid(pdb, sam_acct, sid));
+ }
+
+ if (!ok) {
+ return false;
+ }
+
+ ok = pdb_try_account_unlock(sam_acct);
+ if (!ok) {
+ DEBUG(1, ("pdb_getsampwsid: Failed to unlock account %s\n",
+ sam_acct->username));
}
- return NT_STATUS_IS_OK(pdb->getsampwsid(pdb, sam_acct, sid));
+ return true;
}
static NTSTATUS pdb_default_create_user(struct pdb_methods *methods,
}
for (i=0; i<num_groups; i++) {
- if (sid_equal(group_sid, &sids[i])) {
+ if (dom_sid_equal(group_sid, &sids[i])) {
return True;
}
}
{
/* allocate memory for the structure as its own talloc CTX */
- *methods = talloc_zero(talloc_autofree_context(), struct pdb_methods);
+ *methods = talloc_zero(NULL, struct pdb_methods);
if (*methods == NULL) {
return NT_STATUS_NO_MEMORY;
}