r23682: Old patch I forgot in one of my 3.0.25 trees.
[ira/wip.git] / source3 / smbd / chgpasswd.c
index 011122ee575d820d95b9b816b9cdd8cb08379795..1227163c224d6ac64c3498982aaf37d98fc3e606 100644 (file)
@@ -579,6 +579,11 @@ BOOL check_lanman_password(char *user, uchar * pass1,
        uint32 acct_ctrl;
        const uint8 *lanman_pw;
        BOOL ret;
+
+       if ( !(sampass = samu_new(NULL)) ) {
+               DEBUG(0, ("samu_new() failed!\n"));
+               return False;
+       }
        
        become_root();
        ret = pdb_getsampwnam(sampass, user);
@@ -684,7 +689,7 @@ BOOL change_lanman_password(struct samu *sampass, uchar *pass2)
                return False;   /* We lose the NT hash. Sorry. */
        }
 
-       if (!pdb_set_pass_changed_now  (sampass)) {
+       if (!pdb_set_pass_last_set_time  (sampass, time(NULL), PDB_CHANGED)) {
                TALLOC_FREE(sampass);
                /* Not quite sure what this one qualifies as, but this will do */
                return False; 
@@ -978,8 +983,8 @@ static BOOL check_passwd_history(struct samu *sampass, const char *plaintext)
                return True;
        }
 
-       dump_data(100, (const char *)new_nt_p16, NT_HASH_LEN);
-       dump_data(100, (const char *)pwhistory, PW_HISTORY_ENTRY_LEN*pwHisLen);
+       dump_data(100, new_nt_p16, NT_HASH_LEN);
+       dump_data(100, pwhistory, PW_HISTORY_ENTRY_LEN*pwHisLen);
 
        memset(zero_md5_nt_pw, '\0', SALTED_MD5_HASH_LEN);
        for (i=0; i<pwHisLen; i++) {
@@ -1013,36 +1018,33 @@ static BOOL check_passwd_history(struct samu *sampass, const char *plaintext)
 
 NTSTATUS change_oem_password(struct samu *hnd, char *old_passwd, char *new_passwd, BOOL as_root, uint32 *samr_reject_reason)
 {
-       uint32 min_len, min_age;
+       uint32 min_len;
+       uint32 refuse;
        struct passwd *pass = NULL;
        const char *username = pdb_get_username(hnd);
-       time_t last_change_time = pdb_get_pass_last_set_time(hnd);
        time_t can_change_time = pdb_get_pass_can_change_time(hnd);
 
        if (samr_reject_reason) {
                *samr_reject_reason = Undefined;
        }
 
-       if (pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &min_age)) {
-               /*
-                * Windows calculates the minimum password age check
-                * dynamically, it basically ignores the pwdcanchange
-                * timestamp. Do likewise.
-                */
-               if (last_change_time + min_age > time(NULL)) {
-                       DEBUG(1, ("user %s cannot change password now, must "
-                                 "wait until %s\n", username,
-                                 http_timestring(last_change_time+min_age)));
-                       if (samr_reject_reason) {
-                               *samr_reject_reason = REJECT_REASON_OTHER;
-                       }
-                       return NT_STATUS_ACCOUNT_RESTRICTION;
+       /* check to see if the secdesc has previously been set to disallow */
+       if (!pdb_get_pass_can_change(hnd)) {
+               DEBUG(1, ("user %s does not have permissions to change password\n", username));
+               if (samr_reject_reason) {
+                       *samr_reject_reason = REJECT_REASON_OTHER;
                }
-       } else {
-               if ((can_change_time != 0) && (time(NULL) < can_change_time)) {
-                       DEBUG(1, ("user %s cannot change password now, must "
-                                 "wait until %s\n", username,
-                                 http_timestring(can_change_time)));
+               return NT_STATUS_ACCOUNT_RESTRICTION;
+       }
+
+       /* check to see if it is a Machine account and if the policy
+        * denies machines to change the password. *
+        * Should we deny also SRVTRUST and/or DOMSTRUST ? .SSS. */
+       if (pdb_get_acct_ctrl(hnd) & ACB_WSTRUST) {
+               if (pdb_get_account_policy(AP_REFUSE_MACHINE_PW_CHANGE, &refuse) && refuse) {
+                       DEBUG(1, ("Machine %s cannot change password now, "
+                                 "denied by Refuse Machine Password Change policy\n",
+                                 username));
                        if (samr_reject_reason) {
                                *samr_reject_reason = REJECT_REASON_OTHER;
                        }
@@ -1050,6 +1052,18 @@ NTSTATUS change_oem_password(struct samu *hnd, char *old_passwd, char *new_passw
                }
        }
 
+       /* removed calculation here, becuase passdb now calculates
+          based on policy.  jmcd */
+       if ((can_change_time != 0) && (time(NULL) < can_change_time)) {
+               DEBUG(1, ("user %s cannot change password now, must "
+                         "wait until %s\n", username,
+                         http_timestring(can_change_time)));
+               if (samr_reject_reason) {
+                       *samr_reject_reason = REJECT_REASON_OTHER;
+               }
+               return NT_STATUS_ACCOUNT_RESTRICTION;
+       }
+
        if (pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &min_len) && (str_charnum(new_passwd) < min_len)) {
                DEBUG(1, ("user %s cannot change password - password too short\n", 
                          username));