From 5ac6b21f097b87657c4a3d2a3b4e32d091833d22 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 20 Dec 2005 15:10:41 +0000 Subject: r12398: adding Guenther's account policy migration fix (This used to be commit be32f10609f2274903cb3b2c6b84c9aa62962151) --- source3/lib/account_pol.c | 85 ++++++++++++++++++++++++++++++++++++++++------- source3/passdb/pdb_ldap.c | 29 ++++++++++++---- source3/utils/pdbedit.c | 51 +++++++++++++++++++++++++++- 3 files changed, 145 insertions(+), 20 deletions(-) diff --git a/source3/lib/account_pol.c b/source3/lib/account_pol.c index b02edc5b40..75a1d62ee7 100644 --- a/source3/lib/account_pol.c +++ b/source3/lib/account_pol.c @@ -73,7 +73,7 @@ static const struct ap_table account_policy_names[] = { "Lockout users after bad logon attempts (default: 0 => off)", "sambaLockoutThreshold" }, - {AP_TIME_TO_LOGOUT, "disconnect time", -1, + {AP_TIME_TO_LOGOUT, "disconnect time", (uint32) -1, "Disconnect Users outside logon hours (default: -1 => off, 0 => on)", "sambaForceLogoff" }, @@ -116,8 +116,9 @@ const char *decode_account_policy_name(int field) { int i; for (i=0; account_policy_names[i].string; i++) { - if (field == account_policy_names[i].field) + if (field == account_policy_names[i].field) { return account_policy_names[i].string; + } } return NULL; } @@ -130,8 +131,9 @@ const char *get_account_policy_attr(int field) { int i; for (i=0; account_policy_names[i].field; i++) { - if (field == account_policy_names[i].field) + if (field == account_policy_names[i].field) { return account_policy_names[i].ldap_attr; + } } return NULL; } @@ -144,8 +146,9 @@ const char *account_policy_get_desc(int field) { int i; for (i=0; account_policy_names[i].string; i++) { - if (field == account_policy_names[i].field) + if (field == account_policy_names[i].field) { return account_policy_names[i].description; + } } return NULL; } @@ -158,8 +161,9 @@ int account_policy_name_to_fieldnum(const char *name) { int i; for (i=0; account_policy_names[i].string; i++) { - if (strcmp(name, account_policy_names[i].string) == 0) + if (strcmp(name, account_policy_names[i].string) == 0) { return account_policy_names[i].field; + } } return 0; } @@ -180,8 +184,9 @@ static BOOL account_policy_cache_timestamp(uint32 *value, BOOL update, slprintf(key, sizeof(key)-1, "%s/%s", ap_name, AP_LASTSET); - if (!init_account_policy()) + if (!init_account_policy()) { return False; + } if (!tdb_fetch_uint32(tdb, key, &val) && !update) { DEBUG(10,("failed to get last set timestamp of cache\n")); @@ -253,8 +258,9 @@ BOOL init_account_policy(void) uint32 version; int i; - if (tdb) + if (tdb) { return True; + } tdb = tdb_open_log(lock_path("account_policy.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600); if (!tdb) { @@ -300,23 +306,28 @@ BOOL account_policy_get(int field, uint32 *value) fstring name; uint32 regval; - if (!init_account_policy()) + if (!init_account_policy()) { return False; + } - if (value) + if (value) { *value = 0; + } fstrcpy(name, decode_account_policy_name(field)); if (!*name) { DEBUG(1, ("account_policy_get: Field %d is not a valid account policy type! Cannot get, returning 0.\n", field)); return False; } + if (!tdb_fetch_uint32(tdb, name, ®val)) { DEBUG(1, ("account_policy_get: tdb_fetch_uint32 failed for field %d (%s), returning 0\n", field, name)); return False; } - if (value) + + if (value) { *value = regval; + } DEBUG(10,("account_policy_get: name: %s, val: %d\n", name, regval)); return True; @@ -331,8 +342,9 @@ BOOL account_policy_set(int field, uint32 value) { fstring name; - if (!init_account_policy()) + if (!init_account_policy()) { return False; + } fstrcpy(name, decode_account_policy_name(field)); if (!*name) { @@ -382,6 +394,54 @@ BOOL cache_account_policy_set(int field, uint32 value) return True; } +/***************************************************************************** +Check whether account policies have been migrated to passdb +*****************************************************************************/ + +BOOL account_policy_migrated(BOOL init) +{ + pstring key; + uint32 val; + time_t now; + + slprintf(key, sizeof(key)-1, "AP_MIGRATED_TO_PASSDB"); + + if (!init_account_policy()) { + return False; + } + + if (init) { + now = time(NULL); + + if (!tdb_store_uint32(tdb, key, (uint32)now)) { + DEBUG(1, ("tdb_store_uint32 failed for %s\n", key)); + return False; + } + + return True; + } + + if (!tdb_fetch_uint32(tdb, key, &val)) { + return False; + } + + return True; +} + +/***************************************************************************** + Remove marker that informs that account policies have been migrated to passdb +*****************************************************************************/ + +BOOL remove_account_policy_migrated(void) +{ + if (!init_account_policy()) { + return False; + } + + return tdb_delete_bystring(tdb, "AP_MIGRATED_TO_PASSDB"); +} + + /***************************************************************************** Get an account policy from the cache *****************************************************************************/ @@ -413,8 +473,9 @@ TDB_CONTEXT *get_account_pol_tdb( void ) { if ( !tdb ) { - if ( !init_account_policy() ) + if ( !init_account_policy() ) { return NULL; + } } return tdb; diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index cb0bc8eeb6..0c0128176b 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -3331,7 +3331,7 @@ static NTSTATUS ldapsam_alias_memberships(struct pdb_methods *methods, return NT_STATUS_OK; } -static NTSTATUS ldapsam_set_account_policy(struct pdb_methods *methods, int policy_index, uint32 value) +static NTSTATUS ldapsam_set_account_policy_in_ldap(struct pdb_methods *methods, int policy_index, uint32 value) { NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL; int rc; @@ -3344,7 +3344,7 @@ static NTSTATUS ldapsam_set_account_policy(struct pdb_methods *methods, int poli const char *attrs[2]; - DEBUG(10,("ldapsam_set_account_policy\n")); + DEBUG(10,("ldapsam_set_account_policy_in_ldap\n")); if (!ldap_state->domain_dn) { return NT_STATUS_INVALID_PARAMETER; @@ -3352,7 +3352,7 @@ static NTSTATUS ldapsam_set_account_policy(struct pdb_methods *methods, int poli policy_attr = get_account_policy_attr(policy_index); if (policy_attr == NULL) { - DEBUG(0,("ldapsam_set_account_policy: invalid policy\n")); + DEBUG(0,("ldapsam_set_account_policy_in_ldap: invalid policy\n")); return ntstatus; } @@ -3372,7 +3372,7 @@ static NTSTATUS ldapsam_set_account_policy(struct pdb_methods *methods, int poli ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,&ld_error); - DEBUG(0, ("ldapsam_set_account_policy: Could not set account policy " + DEBUG(0, ("ldapsam_set_account_policy_in_ldap: Could not set account policy " "for %s, error: %s (%s)\n", ldap_state->domain_dn, ldap_err2string(rc), ld_error?ld_error:"unknown")); SAFE_FREE(ld_error); @@ -3380,13 +3380,22 @@ static NTSTATUS ldapsam_set_account_policy(struct pdb_methods *methods, int poli } if (!cache_account_policy_set(policy_index, value)) { - DEBUG(0,("ldapsam_set_account_policy: failed to update local tdb cache\n")); + DEBUG(0,("ldapsam_set_account_policy_in_ldap: failed to update local tdb cache\n")); return ntstatus; } return NT_STATUS_OK; } +static NTSTATUS ldapsam_set_account_policy(struct pdb_methods *methods, int policy_index, uint32 value) +{ + if (!account_policy_migrated(False)) { + return (account_policy_set(policy_index, value)) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; + } + + return ldapsam_set_account_policy_in_ldap(methods, policy_index, value); +} + static NTSTATUS ldapsam_get_account_policy_from_ldap(struct pdb_methods *methods, int policy_index, uint32 *value) { NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL; @@ -3425,7 +3434,7 @@ static NTSTATUS ldapsam_get_account_policy_from_ldap(struct pdb_methods *methods ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,&ld_error); - DEBUG(0, ("ldapsam_get_account_policy_from_ldap: Could not get account policy " + DEBUG(3, ("ldapsam_get_account_policy_from_ldap: Could not get account policy " "for %s, error: %s (%s)\n", ldap_state->domain_dn, ldap_err2string(rc), ld_error?ld_error:"unknown")); SAFE_FREE(ld_error); @@ -3461,6 +3470,8 @@ out: /* wrapper around ldapsam_get_account_policy_from_ldap(), handles tdb as cache + - if user hasn't decided to use account policies inside LDAP just reuse the old tdb values + - if there is a valid cache entry, return that - if there is an LDAP entry, update cache and return - otherwise set to default, update cache and return @@ -3471,6 +3482,10 @@ static NTSTATUS ldapsam_get_account_policy(struct pdb_methods *methods, int poli { NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL; + if (!account_policy_migrated(False)) { + return (account_policy_get(policy_index, value)) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; + } + if (cache_account_policy_get(policy_index, value)) { DEBUG(11,("ldapsam_get_account_policy: got valid value from cache\n")); return NT_STATUS_OK; @@ -3481,7 +3496,7 @@ static NTSTATUS ldapsam_get_account_policy(struct pdb_methods *methods, int poli goto update_cache; } - DEBUG(10,("ldapsam_get_account_policy: failed to retrieve from ldap, returning default.\n")); + DEBUG(10,("ldapsam_get_account_policy: failed to retrieve from ldap\n")); #if 0 /* should we automagically migrate old tdb value here ? */ diff --git a/source3/utils/pdbedit.c b/source3/utils/pdbedit.c index e120b8ec64..9c292bd212 100644 --- a/source3/utils/pdbedit.c +++ b/source3/utils/pdbedit.c @@ -118,6 +118,35 @@ static int export_groups (struct pdb_context *in, struct pdb_context *out) { return 0; } +/********************************************************* + Reset account policies to their default values and remove marker + ********************************************************/ + +static int reinit_account_policies (void) +{ + int i; + + for (i=1; decode_account_policy_name(i) != NULL; i++) { + uint32 policy_value; + if (!account_policy_get_default(i, &policy_value)) { + fprintf(stderr, "Can't get default account policy\n"); + return -1; + } + if (!account_policy_set(i, policy_value)) { + fprintf(stderr, "Can't set account policy in tdb\n"); + return -1; + } + } + + if (!remove_account_policy_migrated()) { + fprintf(stderr, "Can't remove marker from tdb\n"); + return -1; + } + + return 0; +} + + /********************************************************* Add all currently available account policy from tdb to one backend ********************************************************/ @@ -126,13 +155,23 @@ static int export_account_policies (struct pdb_context *in, struct pdb_context * { int i; + if (!account_policy_migrated(True)) { + fprintf(stderr, "Can't set account policy marker in tdb\n"); + return -1; + } + for (i=1; decode_account_policy_name(i) != NULL; i++) { uint32 policy_value; if (NT_STATUS_IS_ERR(in->pdb_get_account_policy(in, i, &policy_value))) { fprintf(stderr, "Can't get account policy from tdb\n"); + remove_account_policy_migrated(); + return -1; + } + if (NT_STATUS_IS_ERR(out->pdb_set_account_policy(out, i, policy_value))) { + fprintf(stderr, "Can't set account policy in passdb\n"); + remove_account_policy_migrated(); return -1; } - out->pdb_set_account_policy(out, i, policy_value); } return 0; @@ -677,6 +716,7 @@ int main (int argc, char **argv) static char *backend_out = NULL; static BOOL transfer_groups = False; static BOOL transfer_account_policies = False; + static BOOL reset_account_policies = False; static BOOL force_initialised_password = False; static char *logon_script = NULL; static char *profile_path = NULL; @@ -721,6 +761,7 @@ int main (int argc, char **argv) {"export", 'e', POPT_ARG_STRING, &backend_out, 0, "export user accounts to this backend", NULL}, {"group", 'g', POPT_ARG_NONE, &transfer_groups, 0, "use -i and -e for groups", NULL}, {"policies", 'y', POPT_ARG_NONE, &transfer_account_policies, 0, "use -i and -e to move account policies between backends", NULL}, + {"policies-reset", 0, POPT_ARG_NONE, &reset_account_policies, 0, "restore default policies", NULL}, {"account-policy", 'P', POPT_ARG_STRING, &account_policy, 0,"value of an account policy (like maximum password age)",NULL}, {"value", 'C', POPT_ARG_LONG, &account_policy_value, 'C',"set the account policy to this value", NULL}, {"account-control", 'c', POPT_ARG_STRING, &account_control, 0, "Values of account control", NULL}, @@ -841,6 +882,14 @@ int main (int argc, char **argv) } } + if (reset_account_policies) { + if (!reinit_account_policies()) { + exit(1); + } + + exit(0); + } + /* import and export operations */ if (((checkparms & BIT_IMPORT) || (checkparms & BIT_EXPORT)) && !(checkparms & ~(BIT_IMPORT +BIT_EXPORT +BIT_USER))) { -- cgit