RIP BOOL. Convert BOOL -> bool. I found a few interesting
[nivanova/samba-autobuild/.git] / source3 / smbd / chgpasswd.c
index 8df824a323e1f311ae5ee4b8816f27c2a52a0110..fb6e6c0f09125bb9180b3da48c824aee5dc938d6 100644 (file)
@@ -6,7 +6,7 @@
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
@@ -15,8 +15,7 @@
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 /* These comments regard the code to change the user's unix password: */
@@ -120,7 +119,7 @@ static int findpty(char **slave)
 }
 
 static int dochild(int master, const char *slavedev, const struct passwd *pass,
-                  const char *passwordprogram, BOOL as_root)
+                  const char *passwordprogram, bool as_root)
 {
        int slave;
        struct termios stermios;
@@ -234,14 +233,14 @@ static int expect(int master, char *issue, char *expected)
 {
        pstring buffer;
        int attempts, timeout, nread, len;
-       BOOL match = False;
+       bool match = False;
 
        for (attempts = 0; attempts < 2; attempts++) {
                if (!strequal(issue, ".")) {
                        if (lp_passwd_chat_debug())
                                DEBUG(100, ("expect: sending [%s]\n", issue));
 
-                       if ((len = write(master, issue, strlen(issue))) != strlen(issue)) {
+                       if ((len = sys_write(master, issue, strlen(issue))) != strlen(issue)) {
                                DEBUG(2,("expect: (short) write returned %d\n", len ));
                                return False;
                        }
@@ -332,14 +331,14 @@ static int talktochild(int master, const char *seq)
        return (count > 0);
 }
 
-static BOOL chat_with_program(char *passwordprogram, const struct passwd *pass,
-                             char *chatsequence, BOOL as_root)
+static bool chat_with_program(char *passwordprogram, const struct passwd *pass,
+                             char *chatsequence, bool as_root)
 {
        char *slavedev;
        int master;
        pid_t pid, wpid;
        int wstat;
-       BOOL chstat = False;
+       bool chstat = False;
 
        if (pass == NULL) {
                DEBUG(0, ("chat_with_program: user doesn't exist in the UNIX password database.\n"));
@@ -415,9 +414,10 @@ while we were waiting\n", WTERMSIG(wstat)));
                /* CHILD */
 
                /*
-                * Lose any oplock capabilities.
+                * Lose any elevated privileges.
                 */
-               oplock_set_capability(False, False);
+               drop_effective_capability(KERNEL_OPLOCK_CAPABILITY);
+               drop_effective_capability(DMAPI_ACCESS_CAPABILITY);
 
                /* make sure it doesn't freeze */
                alarm(20);
@@ -446,8 +446,8 @@ while we were waiting\n", WTERMSIG(wstat)));
        return (chstat);
 }
 
-BOOL chgpasswd(const char *name, const struct passwd *pass, 
-              const char *oldpass, const char *newpass, BOOL as_root)
+bool chgpasswd(const char *name, const struct passwd *pass, 
+              const char *oldpass, const char *newpass, bool as_root)
 {
        pstring passwordprogram;
        pstring chatsequence;
@@ -496,7 +496,7 @@ BOOL chgpasswd(const char *name, const struct passwd *pass,
        
 #ifdef WITH_PAM
        if (lp_pam_password_change()) {
-               BOOL ret;
+               bool ret;
 
                if (as_root)
                        become_root();
@@ -557,8 +557,8 @@ the string %%u, and the given string %s does not.\n", passwordprogram ));
 
 #else /* ALLOW_CHANGE_PASSWORD */
 
-BOOL chgpasswd(const char *name, const struct passwd *pass, 
-              const char *oldpass, const char *newpass, BOOL as_root)
+bool chgpasswd(const char *name, const struct passwd *pass, 
+              const char *oldpass, const char *newpass, bool as_root)
 {
        DEBUG(0, ("chgpasswd: Unix Password changing not compiled in (user=%s)\n", name));
        return (False);
@@ -569,15 +569,20 @@ BOOL chgpasswd(const char *name, const struct passwd *pass,
  Code to check the lanman hashed password.
 ************************************************************/
 
-BOOL check_lanman_password(char *user, uchar * pass1,
+bool check_lanman_password(char *user, uchar * pass1,
                           uchar * pass2, struct samu **hnd)
 {
        uchar unenc_new_pw[16];
        uchar unenc_old_pw[16];
        struct samu *sampass = NULL;
-       uint16 acct_ctrl;
+       uint32 acct_ctrl;
        const uint8 *lanman_pw;
-       BOOL ret;
+       bool ret;
+
+       if ( !(sampass = samu_new(NULL)) ) {
+               DEBUG(0, ("samu_new() failed!\n"));
+               return False;
+       }
        
        become_root();
        ret = pdb_getsampwnam(sampass, user);
@@ -636,12 +641,12 @@ BOOL check_lanman_password(char *user, uchar * pass1,
  is correct before calling. JRA.
 ************************************************************/
 
-BOOL change_lanman_password(struct samu *sampass, uchar *pass2)
+bool change_lanman_password(struct samu *sampass, uchar *pass2)
 {
        static uchar null_pw[16];
        uchar unenc_new_pw[16];
-       BOOL ret;
-       uint16 acct_ctrl;
+       bool ret;
+       uint32 acct_ctrl;
        const uint8 *pwd;
 
        if (sampass == NULL) {
@@ -683,7 +688,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; 
@@ -755,16 +760,16 @@ static NTSTATUS check_oem_password(const char *user,
        uint8 *password_encrypted;
        const uint8 *encryption_key;
        const uint8 *lanman_pw, *nt_pw;
-       uint16 acct_ctrl;
+       uint32 acct_ctrl;
        uint32 new_pw_len;
        uchar new_nt_hash[16];
        uchar new_lm_hash[16];
        uchar verifier[16];
        char no_pw[2];
-       BOOL ret;
+       bool ret;
 
-       BOOL nt_pass_set = (password_encrypted_with_nt_hash && old_nt_hash_encrypted);
-       BOOL lm_pass_set = (password_encrypted_with_lm_hash && old_lm_hash_encrypted);
+       bool nt_pass_set = (password_encrypted_with_nt_hash && old_nt_hash_encrypted);
+       bool lm_pass_set = (password_encrypted_with_lm_hash && old_lm_hash_encrypted);
 
        *hnd = NULL;
 
@@ -943,13 +948,13 @@ static NTSTATUS check_oem_password(const char *user,
  found in the history list.
 ************************************************************/
 
-static BOOL check_passwd_history(struct samu *sampass, const char *plaintext)
+static bool check_passwd_history(struct samu *sampass, const char *plaintext)
 {
        uchar new_nt_p16[NT_HASH_LEN];
        uchar zero_md5_nt_pw[SALTED_MD5_HASH_LEN];
        const uint8 *nt_pw;
        const uint8 *pwhistory;
-       BOOL found = False;
+       bool found = False;
        int i;
        uint32 pwHisLen, curr_pwHisLen;
 
@@ -977,8 +982,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++) {
@@ -1010,38 +1015,35 @@ static BOOL check_passwd_history(struct samu *sampass, const char *plaintext)
  is correct before calling. JRA.
 ************************************************************/
 
-NTSTATUS change_oem_password(struct samu *hnd, char *old_passwd, char *new_passwd, BOOL as_root, uint32 *samr_reject_reason)
+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;
                        }
@@ -1049,6 +1051,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));