r12398: adding Guenther's account policy migration fix
authorGerald Carter <jerry@samba.org>
Tue, 20 Dec 2005 15:10:41 +0000 (15:10 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 16:05:54 +0000 (11:05 -0500)
(This used to be commit be32f10609f2274903cb3b2c6b84c9aa62962151)

source3/lib/account_pol.c
source3/passdb/pdb_ldap.c
source3/utils/pdbedit.c

index b02edc5b40102e0f8fc64db1447d5986e6511043..75a1d62ee795f260b7e2635d33ae8b726fa16a43 100644 (file)
@@ -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, &regval)) {
                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;
index cb0bc8eeb68c122932bcb14b6c5fa8f437dfda90..0c0128176b79f5d49e81c9401ec914238f8e3ada 100644 (file)
@@ -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 ? */
index e120b8ec6407a3f2e10106327580c5313c1459ca..9c292bd212ab91c89d7a63c6d36a9822805376fb 100644 (file)
@@ -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))) {