On 06/23/2014 07:05 PM, Martin Jansa wrote:
On Fri, Jun 13, 2014 at 01:11:28PM +0200, Martin Jansa wrote:
On Fri, Jun 13, 2014 at 02:12:54PM +0800, Chong Lu wrote:
Samba 3.x before 3.6.23, 4.0.x before 4.0.16, and 4.1.x before 4.1.6
does not enforce the password-guessing protection mechanism for all
interfaces, which makes it easier for remote attackers to obtain access
via brute-force ChangePasswordUser2 (1) SAMR or (2) RAP attempts.

http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2013-4496
As you care about samba, would you mind sending fix for autodetecting
talloc?

see
http://lists.openembedded.org/pipermail/openembedded-core/2014-June/093414.html
I've merged this changes (as I don't want to block security fixes), but
please fix autodetecting talloc.
OK, I will send a patch to fix this issue.

Best Regards
Chong
Signed-off-by: Yue Tao <yue....@windriver.com>
Signed-off-by: Chong Lu <chong...@windriver.com>
---
  .../samba/samba/samba-3.6.22-CVE-2013-4496.patch   |  966 ++++++++++++++++++++
  meta-oe/recipes-connectivity/samba/samba_3.6.8.bb  |    1 +
  2 files changed, 967 insertions(+)
  create mode 100644 
meta-oe/recipes-connectivity/samba/samba/samba-3.6.22-CVE-2013-4496.patch

diff --git 
a/meta-oe/recipes-connectivity/samba/samba/samba-3.6.22-CVE-2013-4496.patch 
b/meta-oe/recipes-connectivity/samba/samba/samba-3.6.22-CVE-2013-4496.patch
new file mode 100644
index 0000000..c190a6c
--- /dev/null
+++ b/meta-oe/recipes-connectivity/samba/samba/samba-3.6.22-CVE-2013-4496.patch
@@ -0,0 +1,966 @@
+Upstream-Status: Backport
+
+From 25066eb31d6608075b5993b0d19b3e0843cdadeb Mon Sep 17 00:00:00 2001
+From: Andrew Bartlett <abart...@samba.org>
+Date: Fri, 1 Nov 2013 14:55:44 +1300
+Subject: [PATCH 1/3] CVE-2013-4496:s3-samr: Block attempts to crack passwords
+ via repeated password changes
+
+Bug: https://bugzilla.samba.org/show_bug.cgi?id=10245
+
+Signed-off-by: Andrew Bartlett <abart...@samba.org>
+Signed-off-by: Stefan Metzmacher <me...@samba.org>
+Signed-off-by: Jeremy Allison <j...@samba.org>
+Reviewed-by: Stefan Metzmacher <me...@samba.org>
+Reviewed-by: Jeremy Allison <j...@samba.org>
+Reviewed-by: Andreas Schneider <a...@samba.org>
+---
+ source3/rpc_server/samr/srv_samr_chgpasswd.c |   55 ++++++++++++++++
+ source3/rpc_server/samr/srv_samr_nt.c        |   90 +++++++++++++++++++++-----
+ 2 files changed, 129 insertions(+), 16 deletions(-)
+
+diff --git a/source3/rpc_server/samr/srv_samr_chgpasswd.c 
b/source3/rpc_server/samr/srv_samr_chgpasswd.c
+index 0b4b25b..59905be 100644
+--- a/source3/rpc_server/samr/srv_samr_chgpasswd.c
++++ b/source3/rpc_server/samr/srv_samr_chgpasswd.c
+@@ -1106,6 +1106,8 @@ NTSTATUS pass_oem_change(char *user, const char *rhost,
+       struct samu *sampass = NULL;
+       NTSTATUS nt_status;
+       bool ret = false;
++      bool updated_badpw = false;
++      NTSTATUS update_login_attempts_status;
+
+       if (!(sampass = samu_new(NULL))) {
+               return NT_STATUS_NO_MEMORY;
+@@ -1121,6 +1123,13 @@ NTSTATUS pass_oem_change(char *user, const char *rhost,
+               return NT_STATUS_NO_SUCH_USER;
+       }
+
++      /* Quit if the account was locked out. */
++      if (pdb_get_acct_ctrl(sampass) & ACB_AUTOLOCK) {
++              DEBUG(3,("check_sam_security: Account for user %s was locked 
out.\n", user));
++              TALLOC_FREE(sampass);
++              return NT_STATUS_ACCOUNT_LOCKED_OUT;
++      }
++
+       nt_status = check_oem_password(user,
+                                      password_encrypted_with_lm_hash,
+                                      old_lm_hash_encrypted,
+@@ -1129,6 +1138,52 @@ NTSTATUS pass_oem_change(char *user, const char *rhost,
+                                      sampass,
+                                      &new_passwd);
+
++      /*
++       * Notify passdb backend of login success/failure. If not
++       * NT_STATUS_OK the backend doesn't like the login
++       */
++      update_login_attempts_status = pdb_update_login_attempts(sampass,
++                                              NT_STATUS_IS_OK(nt_status));
++
++      if (!NT_STATUS_IS_OK(nt_status)) {
++              bool increment_bad_pw_count = false;
++
++              if (NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD) &&
++                  (pdb_get_acct_ctrl(sampass) & ACB_NORMAL) &&
++                  NT_STATUS_IS_OK(update_login_attempts_status))
++              {
++                      increment_bad_pw_count = true;
++              }
++
++              if (increment_bad_pw_count) {
++                      pdb_increment_bad_password_count(sampass);
++                      updated_badpw = true;
++              } else {
++                      pdb_update_bad_password_count(sampass,
++                                                    &updated_badpw);
++              }
++      } else {
++
++              if ((pdb_get_acct_ctrl(sampass) & ACB_NORMAL) &&
++                  (pdb_get_bad_password_count(sampass) > 0)){
++                      pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
++                      pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
++                      updated_badpw = true;
++              }
++      }
++
++      if (updated_badpw) {
++              NTSTATUS update_status;
++              become_root();
++              update_status = pdb_update_sam_account(sampass);
++              unbecome_root();
++
++              if (!NT_STATUS_IS_OK(update_status)) {
++                      DEBUG(1, ("Failed to modify entry: %s\n",
++                                nt_errstr(update_status)));
++              }
++      }
++
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               TALLOC_FREE(sampass);
+               return nt_status;
+diff --git a/source3/rpc_server/samr/srv_samr_nt.c 
b/source3/rpc_server/samr/srv_samr_nt.c
+index 78ef1ba..3241b97 100644
+--- a/source3/rpc_server/samr/srv_samr_nt.c
++++ b/source3/rpc_server/samr/srv_samr_nt.c
+@@ -1715,9 +1715,11 @@ NTSTATUS _samr_ChangePasswordUser(struct pipes_struct 
*p,
+       NTSTATUS status;
+       bool ret = false;
+       struct samr_user_info *uinfo;
+-      struct samu *pwd;
++      struct samu *pwd = NULL;
+       struct samr_Password new_lmPwdHash, new_ntPwdHash, checkHash;
+       struct samr_Password lm_pwd, nt_pwd;
++      bool updated_badpw = false;
++      NTSTATUS update_login_attempts_status;
+
+       uinfo = policy_handle_find(p, r->in.user_handle,
+                                  SAMR_USER_ACCESS_SET_PASSWORD, NULL,
+@@ -1729,6 +1731,15 @@ NTSTATUS _samr_ChangePasswordUser(struct pipes_struct 
*p,
+       DEBUG(5,("_samr_ChangePasswordUser: sid:%s\n",
+                 sid_string_dbg(&uinfo->sid)));
+
++      /* basic sanity checking on parameters.  Do this before any database 
ops */
++      if (!r->in.lm_present || !r->in.nt_present ||
++          !r->in.old_lm_crypted || !r->in.new_lm_crypted ||
++          !r->in.old_nt_crypted || !r->in.new_nt_crypted) {
++              /* we should really handle a change with lm not
++                 present */
++              return NT_STATUS_INVALID_PARAMETER_MIX;
++      }
++
+       if (!(pwd = samu_new(NULL))) {
+               return NT_STATUS_NO_MEMORY;
+       }
+@@ -1742,6 +1753,14 @@ NTSTATUS _samr_ChangePasswordUser(struct pipes_struct 
*p,
+               return NT_STATUS_WRONG_PASSWORD;
+       }
+
++      /* Quit if the account was locked out. */
++      if (pdb_get_acct_ctrl(pwd) & ACB_AUTOLOCK) {
++              DEBUG(3, ("Account for user %s was locked out.\n",
++                        pdb_get_username(pwd)));
++              status = NT_STATUS_ACCOUNT_LOCKED_OUT;
++              goto out;
++      }
++
+       {
+               const uint8_t *lm_pass, *nt_pass;
+
+@@ -1750,29 +1769,19 @@ NTSTATUS _samr_ChangePasswordUser(struct pipes_struct 
*p,
+
+               if (!lm_pass || !nt_pass) {
+                       status = NT_STATUS_WRONG_PASSWORD;
+-                      goto out;
++                      goto update_login;
+               }
+
+               memcpy(&lm_pwd.hash, lm_pass, sizeof(lm_pwd.hash));
+               memcpy(&nt_pwd.hash, nt_pass, sizeof(nt_pwd.hash));
+       }
+
+-      /* basic sanity checking on parameters.  Do this before any database 
ops */
+-      if (!r->in.lm_present || !r->in.nt_present ||
+-          !r->in.old_lm_crypted || !r->in.new_lm_crypted ||
+-          !r->in.old_nt_crypted || !r->in.new_nt_crypted) {
+-              /* we should really handle a change with lm not
+-                 present */
+-              status = NT_STATUS_INVALID_PARAMETER_MIX;
+-              goto out;
+-      }
+-
+       /* decrypt and check the new lm hash */
+       D_P16(lm_pwd.hash, r->in.new_lm_crypted->hash, new_lmPwdHash.hash);
+       D_P16(new_lmPwdHash.hash, r->in.old_lm_crypted->hash, checkHash.hash);
+       if (memcmp(checkHash.hash, lm_pwd.hash, 16) != 0) {
+               status = NT_STATUS_WRONG_PASSWORD;
+-              goto out;
++              goto update_login;
+       }
+
+       /* decrypt and check the new nt hash */
+@@ -1780,7 +1789,7 @@ NTSTATUS _samr_ChangePasswordUser(struct pipes_struct *p,
+       D_P16(new_ntPwdHash.hash, r->in.old_nt_crypted->hash, checkHash.hash);
+       if (memcmp(checkHash.hash, nt_pwd.hash, 16) != 0) {
+               status = NT_STATUS_WRONG_PASSWORD;
+-              goto out;
++              goto update_login;
+       }
+
+       /* The NT Cross is not required by Win2k3 R2, but if present
+@@ -1789,7 +1798,7 @@ NTSTATUS _samr_ChangePasswordUser(struct pipes_struct *p,
+               D_P16(lm_pwd.hash, r->in.nt_cross->hash, checkHash.hash);
+               if (memcmp(checkHash.hash, new_ntPwdHash.hash, 16) != 0) {
+                       status = NT_STATUS_WRONG_PASSWORD;
+-                      goto out;
++                      goto update_login;
+               }
+       }
+
+@@ -1799,7 +1808,7 @@ NTSTATUS _samr_ChangePasswordUser(struct pipes_struct *p,
+               D_P16(nt_pwd.hash, r->in.lm_cross->hash, checkHash.hash);
+               if (memcmp(checkHash.hash, new_lmPwdHash.hash, 16) != 0) {
+                       status = NT_STATUS_WRONG_PASSWORD;
+-                      goto out;
++                      goto update_login;
+               }
+       }
+
+@@ -1810,6 +1819,55 @@ NTSTATUS _samr_ChangePasswordUser(struct pipes_struct 
*p,
+       }
+
+       status = pdb_update_sam_account(pwd);
++
++update_login:
++
++      /*
++       * Notify passdb backend of login success/failure. If not
++       * NT_STATUS_OK the backend doesn't like the login
++       */
++      update_login_attempts_status = pdb_update_login_attempts(pwd,
++                                              NT_STATUS_IS_OK(status));
++
++      if (!NT_STATUS_IS_OK(status)) {
++              bool increment_bad_pw_count = false;
++
++              if (NT_STATUS_EQUAL(status,NT_STATUS_WRONG_PASSWORD) &&
++                  (pdb_get_acct_ctrl(pwd) & ACB_NORMAL) &&
++                  NT_STATUS_IS_OK(update_login_attempts_status))
++              {
++                      increment_bad_pw_count = true;
++              }
++
++              if (increment_bad_pw_count) {
++                      pdb_increment_bad_password_count(pwd);
++                      updated_badpw = true;
++              } else {
++                      pdb_update_bad_password_count(pwd,
++                                                    &updated_badpw);
++              }
++      } else {
++
++              if ((pdb_get_acct_ctrl(pwd) & ACB_NORMAL) &&
++                  (pdb_get_bad_password_count(pwd) > 0)){
++                      pdb_set_bad_password_count(pwd, 0, PDB_CHANGED);
++                      pdb_set_bad_password_time(pwd, 0, PDB_CHANGED);
++                      updated_badpw = true;
++              }
++      }
++
++      if (updated_badpw) {
++              NTSTATUS update_status;
++              become_root();
++              update_status = pdb_update_sam_account(pwd);
++              unbecome_root();
++
++              if (!NT_STATUS_IS_OK(update_status)) {
++                      DEBUG(1, ("Failed to modify entry: %s\n",
++                                nt_errstr(update_status)));
++              }
++      }
++
+  out:
+       TALLOC_FREE(pwd);
+
+--
+1.7.9.5
+
+
+From 059da248cf69a3b0ef29836f49367b938fb1cbda Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <me...@samba.org>
+Date: Tue, 5 Nov 2013 14:04:20 +0100
+Subject: [PATCH 2/3] CVE-2013-4496:s3:auth: fix memory leak in the
+ ACCOUNT_LOCKED_OUT case.
+
+Bug: https://bugzilla.samba.org/show_bug.cgi?id=10245
+
+Signed-off-by: Stefan Metzmacher <me...@samba.org>
+Reviewed-by: Jeremy Allison <j...@samba.org>
+Signed-off-by: Andrew Bartlett <abart...@samba.org>
+Reviewed-by: Andreas Schneider <a...@samba.org>
+---
+ source3/auth/check_samsec.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/source3/auth/check_samsec.c b/source3/auth/check_samsec.c
+index f918dc0..e2c42d6 100644
+--- a/source3/auth/check_samsec.c
++++ b/source3/auth/check_samsec.c
+@@ -408,6 +408,7 @@ NTSTATUS check_sam_security(const DATA_BLOB *challenge,
+       /* Quit if the account was locked out. */
+       if (pdb_get_acct_ctrl(sampass) & ACB_AUTOLOCK) {
+               DEBUG(3,("check_sam_security: Account for user %s was locked 
out.\n", username));
++              TALLOC_FREE(sampass);
+               return NT_STATUS_ACCOUNT_LOCKED_OUT;
+       }
+
+--
+1.7.9.5
+
+
+From 27f982ef33a1238ae48d7a38d608dd23ebde61ae Mon Sep 17 00:00:00 2001
+From: Andrew Bartlett <abart...@samba.org>
+Date: Tue, 5 Nov 2013 16:16:46 +1300
+Subject: [PATCH 3/3] CVE-2013-4496:samr: Remove ChangePasswordUser
+
+This old password change mechanism does not provide the plaintext to
+validate against password complexity, and it is not used by modern
+clients.
+
+The missing features in both implementations (by design) were:
+
+ - the password complexity checks (no plaintext)
+ - the minimum password length (no plaintext)
+
+Additionally, the source3 version did not check:
+
+ - the minimum password age
+ - pdb_get_pass_can_change() which checks the security
+   descriptor for the 'user cannot change password' setting.
+ - the password history
+ - the output of the 'passwd program' if 'unix passwd sync = yes'.
+
+Finally, the mechanism was almost useless, as it was incorrectly
+only made available to administrative users with permission
+to reset the password.  It is removed here so that it is not
+mistakenly reinstated in the future.
+
+Andrew Bartlett
+
+Bug: https://bugzilla.samba.org/show_bug.cgi?id=10245
+
+Signed-off-by: Andrew Bartlett <abart...@samba.org>
+Reviewed-by: Andreas Schneider <a...@samba.org>
+Reviewed-by: Stefan Metzmacher <me...@samba.org>
+---
+ source3/rpc_server/samr/srv_samr_nt.c   |  169 +-------------------
+ source3/smbd/lanman.c                   |  254 -------------------------------
+ source4/rpc_server/samr/samr_password.c |  126 +--------------
+ source4/torture/rpc/samr.c              |   12 +-
+ 4 files changed, 24 insertions(+), 537 deletions(-)
+
+diff --git a/source3/rpc_server/samr/srv_samr_nt.c 
b/source3/rpc_server/samr/srv_samr_nt.c
+index 3241b97..2519a3f 100644
+--- a/source3/rpc_server/samr/srv_samr_nt.c
++++ b/source3/rpc_server/samr/srv_samr_nt.c
+@@ -1706,172 +1706,19 @@ NTSTATUS _samr_LookupNames(struct pipes_struct *p,
+ }
+
+ /****************************************************************
+- _samr_ChangePasswordUser
++ _samr_ChangePasswordUser.
++
++ So old it is just not worth implementing
++ because it does not supply a plaintext and so we can't do password
++ complexity checking and cannot update other services that use a
++ plaintext password via passwd chat/pam password change/ldap password
++ sync.
+ ****************************************************************/
+
+ NTSTATUS _samr_ChangePasswordUser(struct pipes_struct *p,
+                                 struct samr_ChangePasswordUser *r)
+ {
+-      NTSTATUS status;
+-      bool ret = false;
+-      struct samr_user_info *uinfo;
+-      struct samu *pwd = NULL;
+-      struct samr_Password new_lmPwdHash, new_ntPwdHash, checkHash;
+-      struct samr_Password lm_pwd, nt_pwd;
+-      bool updated_badpw = false;
+-      NTSTATUS update_login_attempts_status;
+-
+-      uinfo = policy_handle_find(p, r->in.user_handle,
+-                                 SAMR_USER_ACCESS_SET_PASSWORD, NULL,
+-                                 struct samr_user_info, &status);
+-      if (!NT_STATUS_IS_OK(status)) {
+-              return status;
+-      }
+-
+-      DEBUG(5,("_samr_ChangePasswordUser: sid:%s\n",
+-                sid_string_dbg(&uinfo->sid)));
+-
+-      /* basic sanity checking on parameters.  Do this before any database 
ops */
+-      if (!r->in.lm_present || !r->in.nt_present ||
+-          !r->in.old_lm_crypted || !r->in.new_lm_crypted ||
+-          !r->in.old_nt_crypted || !r->in.new_nt_crypted) {
+-              /* we should really handle a change with lm not
+-                 present */
+-              return NT_STATUS_INVALID_PARAMETER_MIX;
+-      }
+-
+-      if (!(pwd = samu_new(NULL))) {
+-              return NT_STATUS_NO_MEMORY;
+-      }
+-
+-      become_root();
+-      ret = pdb_getsampwsid(pwd, &uinfo->sid);
+-      unbecome_root();
+-
+-      if (!ret) {
+-              TALLOC_FREE(pwd);
+-              return NT_STATUS_WRONG_PASSWORD;
+-      }
+-
+-      /* Quit if the account was locked out. */
+-      if (pdb_get_acct_ctrl(pwd) & ACB_AUTOLOCK) {
+-              DEBUG(3, ("Account for user %s was locked out.\n",
+-                        pdb_get_username(pwd)));
+-              status = NT_STATUS_ACCOUNT_LOCKED_OUT;
+-              goto out;
+-      }
+-
+-      {
+-              const uint8_t *lm_pass, *nt_pass;
+-
+-              lm_pass = pdb_get_lanman_passwd(pwd);
+-              nt_pass = pdb_get_nt_passwd(pwd);
+-
+-              if (!lm_pass || !nt_pass) {
+-                      status = NT_STATUS_WRONG_PASSWORD;
+-                      goto update_login;
+-              }
+-
+-              memcpy(&lm_pwd.hash, lm_pass, sizeof(lm_pwd.hash));
+-              memcpy(&nt_pwd.hash, nt_pass, sizeof(nt_pwd.hash));
+-      }
+-
+-      /* decrypt and check the new lm hash */
+-      D_P16(lm_pwd.hash, r->in.new_lm_crypted->hash, new_lmPwdHash.hash);
+-      D_P16(new_lmPwdHash.hash, r->in.old_lm_crypted->hash, checkHash.hash);
+-      if (memcmp(checkHash.hash, lm_pwd.hash, 16) != 0) {
+-              status = NT_STATUS_WRONG_PASSWORD;
+-              goto update_login;
+-      }
+-
+-      /* decrypt and check the new nt hash */
+-      D_P16(nt_pwd.hash, r->in.new_nt_crypted->hash, new_ntPwdHash.hash);
+-      D_P16(new_ntPwdHash.hash, r->in.old_nt_crypted->hash, checkHash.hash);
+-      if (memcmp(checkHash.hash, nt_pwd.hash, 16) != 0) {
+-              status = NT_STATUS_WRONG_PASSWORD;
+-              goto update_login;
+-      }
+-
+-      /* The NT Cross is not required by Win2k3 R2, but if present
+-         check the nt cross hash */
+-      if (r->in.cross1_present && r->in.nt_cross) {
+-              D_P16(lm_pwd.hash, r->in.nt_cross->hash, checkHash.hash);
+-              if (memcmp(checkHash.hash, new_ntPwdHash.hash, 16) != 0) {
+-                      status = NT_STATUS_WRONG_PASSWORD;
+-                      goto update_login;
+-              }
+-      }
+-
+-      /* The LM Cross is not required by Win2k3 R2, but if present
+-         check the lm cross hash */
+-      if (r->in.cross2_present && r->in.lm_cross) {
+-              D_P16(nt_pwd.hash, r->in.lm_cross->hash, checkHash.hash);
+-              if (memcmp(checkHash.hash, new_lmPwdHash.hash, 16) != 0) {
+-                      status = NT_STATUS_WRONG_PASSWORD;
+-                      goto update_login;
+-              }
+-      }
+-
+-      if (!pdb_set_nt_passwd(pwd, new_ntPwdHash.hash, PDB_CHANGED) ||
+-          !pdb_set_lanman_passwd(pwd, new_lmPwdHash.hash, PDB_CHANGED)) {
+-              status = NT_STATUS_ACCESS_DENIED;
+-              goto out;
+-      }
+-
+-      status = pdb_update_sam_account(pwd);
+-
+-update_login:
+-
+-      /*
+-       * Notify passdb backend of login success/failure. If not
+-       * NT_STATUS_OK the backend doesn't like the login
+-       */
+-      update_login_attempts_status = pdb_update_login_attempts(pwd,
+-                                              NT_STATUS_IS_OK(status));
+-
+-      if (!NT_STATUS_IS_OK(status)) {
+-              bool increment_bad_pw_count = false;
+-
+-              if (NT_STATUS_EQUAL(status,NT_STATUS_WRONG_PASSWORD) &&
+-                  (pdb_get_acct_ctrl(pwd) & ACB_NORMAL) &&
+-                  NT_STATUS_IS_OK(update_login_attempts_status))
+-              {
+-                      increment_bad_pw_count = true;
+-              }
+-
+-              if (increment_bad_pw_count) {
+-                      pdb_increment_bad_password_count(pwd);
+-                      updated_badpw = true;
+-              } else {
+-                      pdb_update_bad_password_count(pwd,
+-                                                    &updated_badpw);
+-              }
+-      } else {
+-
+-              if ((pdb_get_acct_ctrl(pwd) & ACB_NORMAL) &&
+-                  (pdb_get_bad_password_count(pwd) > 0)){
+-                      pdb_set_bad_password_count(pwd, 0, PDB_CHANGED);
+-                      pdb_set_bad_password_time(pwd, 0, PDB_CHANGED);
+-                      updated_badpw = true;
+-              }
+-      }
+-
+-      if (updated_badpw) {
+-              NTSTATUS update_status;
+-              become_root();
+-              update_status = pdb_update_sam_account(pwd);
+-              unbecome_root();
+-
+-              if (!NT_STATUS_IS_OK(update_status)) {
+-                      DEBUG(1, ("Failed to modify entry: %s\n",
+-                                nt_errstr(update_status)));
+-              }
+-      }
+-
+- out:
+-      TALLOC_FREE(pwd);
+-
+-      return status;
++      return NT_STATUS_NOT_IMPLEMENTED;
+ }
+
+ /*******************************************************************
+diff --git a/source3/smbd/lanman.c b/source3/smbd/lanman.c
+index aef12df..3b4ec65 100644
+--- a/source3/smbd/lanman.c
++++ b/source3/smbd/lanman.c
+@@ -2947,259 +2947,6 @@ static bool api_NetRemoteTOD(struct 
smbd_server_connection *sconn,
+ }
+
+ /****************************************************************************
+- Set the user password.
+-*****************************************************************************/
+-
+-static bool api_SetUserPassword(struct smbd_server_connection *sconn,
+-                              connection_struct *conn,uint16 vuid,
+-                              char *param, int tpscnt,
+-                              char *data, int tdscnt,
+-                              int mdrcnt,int mprcnt,
+-                              char **rdata,char **rparam,
+-                              int *rdata_len,int *rparam_len)
+-{
+-      char *np = get_safe_str_ptr(param,tpscnt,param,2);
+-      char *p = NULL;
+-      fstring user;
+-      fstring pass1,pass2;
+-      TALLOC_CTX *mem_ctx = talloc_tos();
+-      NTSTATUS status, result;
+-      struct rpc_pipe_client *cli = NULL;
+-      struct policy_handle connect_handle, domain_handle, user_handle;
+-      struct lsa_String domain_name;
+-      struct dom_sid2 *domain_sid;
+-      struct lsa_String names;
+-      struct samr_Ids rids;
+-      struct samr_Ids types;
+-      struct samr_Password old_lm_hash;
+-      struct samr_Password new_lm_hash;
+-      int errcode = NERR_badpass;
+-      uint32_t rid;
+-      int encrypted;
+-      int min_pwd_length;
+-      struct dcerpc_binding_handle *b = NULL;
+-
+-      /* Skip 2 strings. */
+-      p = skip_string(param,tpscnt,np);
+-      p = skip_string(param,tpscnt,p);
+-
+-      if (!np || !p) {
+-              return False;
+-      }
+-
+-      /* Do we have a string ? */
+-      if (skip_string(param,tpscnt,p) == NULL) {
+-              return False;
+-      }
+-      pull_ascii_fstring(user,p);
+-
+-      p = skip_string(param,tpscnt,p);
+-      if (!p) {
+-              return False;
+-      }
+-
+-      memset(pass1,'\0',sizeof(pass1));
+-      memset(pass2,'\0',sizeof(pass2));
+-      /*
+-       * We use 31 here not 32 as we're checking
+-       * the last byte we want to access is safe.
+-       */
+-      if (!is_offset_safe(param,tpscnt,p,31)) {
+-              return False;
+-      }
+-      memcpy(pass1,p,16);
+-      memcpy(pass2,p+16,16);
+-
+-      encrypted = get_safe_SVAL(param,tpscnt,p+32,0,-1);
+-      if (encrypted == -1) {
+-              errcode = W_ERROR_V(WERR_INVALID_PARAM);
+-              goto out;
+-      }
+-
+-      min_pwd_length = get_safe_SVAL(param,tpscnt,p+34,0,-1);
+-      if (min_pwd_length == -1) {
+-              errcode = W_ERROR_V(WERR_INVALID_PARAM);
+-              goto out;
+-      }
+-
+-      *rparam_len = 4;
+-      *rparam = smb_realloc_limit(*rparam,*rparam_len);
+-      if (!*rparam) {
+-              return False;
+-      }
+-
+-      *rdata_len = 0;
+-
+-      DEBUG(3,("Set password for <%s> (encrypted: %d, min_pwd_length: %d)\n",
+-              user, encrypted, min_pwd_length));
+-
+-      ZERO_STRUCT(connect_handle);
+-      ZERO_STRUCT(domain_handle);
+-      ZERO_STRUCT(user_handle);
+-
+-      status = rpc_pipe_open_interface(mem_ctx, &ndr_table_samr.syntax_id,
+-                                      conn->session_info,
+-                                      &conn->sconn->client_id,
+-                                      conn->sconn->msg_ctx,
+-                                      &cli);
+-      if (!NT_STATUS_IS_OK(status)) {
+-              DEBUG(0,("api_SetUserPassword: could not connect to samr: %s\n",
+-                        nt_errstr(status)));
+-              errcode = W_ERROR_V(ntstatus_to_werror(status));
+-              goto out;
+-      }
+-
+-      b = cli->binding_handle;
+-
+-      status = dcerpc_samr_Connect2(b, mem_ctx,
+-                                    global_myname(),
+-                                    SAMR_ACCESS_CONNECT_TO_SERVER |
+-                                    SAMR_ACCESS_ENUM_DOMAINS |
+-                                    SAMR_ACCESS_LOOKUP_DOMAIN,
+-                                    &connect_handle,
+-                                    &result);
+-      if (!NT_STATUS_IS_OK(status)) {
+-              errcode = W_ERROR_V(ntstatus_to_werror(status));
+-              goto out;
+-      }
+-      if (!NT_STATUS_IS_OK(result)) {
+-              errcode = W_ERROR_V(ntstatus_to_werror(result));
+-              goto out;
+-      }
+-
+-      init_lsa_String(&domain_name, get_global_sam_name());
+-
+-      status = dcerpc_samr_LookupDomain(b, mem_ctx,
+-                                        &connect_handle,
+-                                        &domain_name,
+-                                        &domain_sid,
+-                                        &result);
+-      if (!NT_STATUS_IS_OK(status)) {
+-              errcode = W_ERROR_V(ntstatus_to_werror(status));
+-              goto out;
+-      }
+-      if (!NT_STATUS_IS_OK(result)) {
+-              errcode = W_ERROR_V(ntstatus_to_werror(result));
+-              goto out;
+-      }
+-
+-      status = dcerpc_samr_OpenDomain(b, mem_ctx,
+-                                      &connect_handle,
+-                                      SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
+-                                      domain_sid,
+-                                      &domain_handle,
+-                                      &result);
+-      if (!NT_STATUS_IS_OK(status)) {
+-              errcode = W_ERROR_V(ntstatus_to_werror(status));
+-              goto out;
+-      }
+-      if (!NT_STATUS_IS_OK(result)) {
+-              errcode = W_ERROR_V(ntstatus_to_werror(result));
+-              goto out;
+-      }
+-
+-      init_lsa_String(&names, user);
+-
+-      status = dcerpc_samr_LookupNames(b, mem_ctx,
+-                                       &domain_handle,
+-                                       1,
+-                                       &names,
+-                                       &rids,
+-                                       &types,
+-                                       &result);
+-      if (!NT_STATUS_IS_OK(status)) {
+-              errcode = W_ERROR_V(ntstatus_to_werror(status));
+-              goto out;
+-      }
+-      if (!NT_STATUS_IS_OK(result)) {
+-              errcode = W_ERROR_V(ntstatus_to_werror(result));
+-              goto out;
+-      }
+-
+-      if (rids.count != 1) {
+-              errcode = W_ERROR_V(WERR_NO_SUCH_USER);
+-              goto out;
+-      }
+-      if (rids.count != types.count) {
+-              errcode = W_ERROR_V(WERR_INVALID_PARAM);
+-              goto out;
+-      }
+-      if (types.ids[0] != SID_NAME_USER) {
+-              errcode = W_ERROR_V(WERR_INVALID_PARAM);
+-              goto out;
+-      }
+-
+-      rid = rids.ids[0];
+-
+-      status = dcerpc_samr_OpenUser(b, mem_ctx,
+-                                    &domain_handle,
+-                                    SAMR_USER_ACCESS_CHANGE_PASSWORD,
+-                                    rid,
+-                                    &user_handle,
+-                                    &result);
+-      if (!NT_STATUS_IS_OK(status)) {
+-              errcode = W_ERROR_V(ntstatus_to_werror(status));
+-              goto out;
+-      }
+-      if (!NT_STATUS_IS_OK(result)) {
+-              errcode = W_ERROR_V(ntstatus_to_werror(result));
+-              goto out;
+-      }
+-
+-      if (encrypted == 0) {
+-              E_deshash(pass1, old_lm_hash.hash);
+-              E_deshash(pass2, new_lm_hash.hash);
+-      } else {
+-              ZERO_STRUCT(old_lm_hash);
+-              ZERO_STRUCT(new_lm_hash);
+-              memcpy(old_lm_hash.hash, pass1, MIN(strlen(pass1), 16));
+-              memcpy(new_lm_hash.hash, pass1, MIN(strlen(pass2), 16));
+-      }
+-
+-      status = dcerpc_samr_ChangePasswordUser(b, mem_ctx,
+-                                              &user_handle,
+-                                              true, /* lm_present */
+-                                              &old_lm_hash,
+-                                              &new_lm_hash,
+-                                              false, /* nt_present */
+-                                              NULL, /* old_nt_crypted */
+-                                              NULL, /* new_nt_crypted */
+-                                              false, /* cross1_present */
+-                                              NULL, /* nt_cross */
+-                                              false, /* cross2_present */
+-                                              NULL, /* lm_cross */
+-                                              &result);
+-      if (!NT_STATUS_IS_OK(status)) {
+-              errcode = W_ERROR_V(ntstatus_to_werror(status));
+-              goto out;
+-      }
+-      if (!NT_STATUS_IS_OK(result)) {
+-              errcode = W_ERROR_V(ntstatus_to_werror(result));
+-              goto out;
+-      }
+-
+-      errcode = NERR_Success;
+- out:
+-
+-      if (b && is_valid_policy_hnd(&user_handle)) {
+-              dcerpc_samr_Close(b, mem_ctx, &user_handle, &result);
+-      }
+-      if (b && is_valid_policy_hnd(&domain_handle)) {
+-              dcerpc_samr_Close(b, mem_ctx, &domain_handle, &result);
+-      }
+-      if (b && is_valid_policy_hnd(&connect_handle)) {
+-              dcerpc_samr_Close(b, mem_ctx, &connect_handle, &result);
+-      }
+-
+-      memset((char *)pass1,'\0',sizeof(fstring));
+-      memset((char *)pass2,'\0',sizeof(fstring));
+-
+-      SSVAL(*rparam,0,errcode);
+-      SSVAL(*rparam,2,0);             /* converter word */
+-      return(True);
+-}
+-
+-/****************************************************************************
+   Set the user password (SamOEM version - gets plaintext).
+ ****************************************************************************/
+
+@@ -5790,7 +5537,6 @@ static const struct {
+       {"NetServerEnum2",    RAP_NetServerEnum2,     api_RNetServerEnum2}, /* 
anon OK */
+       {"NetServerEnum3",    RAP_NetServerEnum3,     api_RNetServerEnum3}, /* 
anon OK */
+       {"WAccessGetUserPerms",RAP_WAccessGetUserPerms,api_WAccessGetUserPerms},
+-      {"SetUserPassword",   RAP_WUserPasswordSet2,  api_SetUserPassword},
+       {"WWkstaUserLogon",   RAP_WWkstaUserLogon,    api_WWkstaUserLogon},
+       {"PrintJobInfo",      RAP_WPrintJobSetInfo,   api_PrintJobInfo},
+       {"WPrintDriverEnum",  RAP_WPrintDriverEnum,   api_WPrintDriverEnum},
+diff --git a/source4/rpc_server/samr/samr_password.c 
b/source4/rpc_server/samr/samr_password.c
+index ee13a11..e618740 100644
+--- a/source4/rpc_server/samr/samr_password.c
++++ b/source4/rpc_server/samr/samr_password.c
+@@ -32,131 +32,17 @@
+
+ /*
+   samr_ChangePasswordUser
++
++  So old it is just not worth implementing
++  because it does not supply a plaintext and so we can't do password
++  complexity checking and cannot update all the other password hashes.
++
+ */
+ NTSTATUS dcesrv_samr_ChangePasswordUser(struct dcesrv_call_state *dce_call,
+                                       TALLOC_CTX *mem_ctx,
+                                       struct samr_ChangePasswordUser *r)
+ {
+-      struct dcesrv_handle *h;
+-      struct samr_account_state *a_state;
+-      struct ldb_context *sam_ctx;
+-      struct ldb_message **res;
+-      int ret;
+-      struct samr_Password new_lmPwdHash, new_ntPwdHash, checkHash;
+-      struct samr_Password *lm_pwd, *nt_pwd;
+-      NTSTATUS status = NT_STATUS_OK;
+-      const char * const attrs[] = { "dBCSPwd", "unicodePwd" , NULL };
+-
+-      DCESRV_PULL_HANDLE(h, r->in.user_handle, SAMR_HANDLE_USER);
+-
+-      a_state = h->data;
+-
+-      /* basic sanity checking on parameters.  Do this before any database 
ops */
+-      if (!r->in.lm_present || !r->in.nt_present ||
+-          !r->in.old_lm_crypted || !r->in.new_lm_crypted ||
+-          !r->in.old_nt_crypted || !r->in.new_nt_crypted) {
+-              /* we should really handle a change with lm not
+-                 present */
+-              return NT_STATUS_INVALID_PARAMETER_MIX;
+-      }
+-
+-      /* Connect to a SAMDB with system privileges for fetching the old pw
+-       * hashes. */
+-      sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx,
+-                              dce_call->conn->dce_ctx->lp_ctx,
+-                              
system_session(dce_call->conn->dce_ctx->lp_ctx), 0);
+-      if (sam_ctx == NULL) {
+-              return NT_STATUS_INVALID_SYSTEM_SERVICE;
+-      }
+-
+-      /* fetch the old hashes */
+-      ret = gendb_search_dn(sam_ctx, mem_ctx,
+-                            a_state->account_dn, &res, attrs);
+-      if (ret != 1) {
+-              return NT_STATUS_WRONG_PASSWORD;
+-      }
+-
+-      status = samdb_result_passwords(mem_ctx,
+-                                      dce_call->conn->dce_ctx->lp_ctx,
+-                                      res[0], &lm_pwd, &nt_pwd);
+-      if (!NT_STATUS_IS_OK(status) || !nt_pwd) {
+-              return NT_STATUS_WRONG_PASSWORD;
+-      }
+-
+-      /* decrypt and check the new lm hash */
+-      if (lm_pwd) {
+-              D_P16(lm_pwd->hash, r->in.new_lm_crypted->hash, 
new_lmPwdHash.hash);
+-              D_P16(new_lmPwdHash.hash, r->in.old_lm_crypted->hash, 
checkHash.hash);
+-              if (memcmp(checkHash.hash, lm_pwd, 16) != 0) {
+-                      return NT_STATUS_WRONG_PASSWORD;
+-              }
+-      }
+-
+-      /* decrypt and check the new nt hash */
+-      D_P16(nt_pwd->hash, r->in.new_nt_crypted->hash, new_ntPwdHash.hash);
+-      D_P16(new_ntPwdHash.hash, r->in.old_nt_crypted->hash, checkHash.hash);
+-      if (memcmp(checkHash.hash, nt_pwd, 16) != 0) {
+-              return NT_STATUS_WRONG_PASSWORD;
+-      }
+-
+-      /* The NT Cross is not required by Win2k3 R2, but if present
+-         check the nt cross hash */
+-      if (r->in.cross1_present && r->in.nt_cross && lm_pwd) {
+-              D_P16(lm_pwd->hash, r->in.nt_cross->hash, checkHash.hash);
+-              if (memcmp(checkHash.hash, new_ntPwdHash.hash, 16) != 0) {
+-                      return NT_STATUS_WRONG_PASSWORD;
+-              }
+-      }
+-
+-      /* The LM Cross is not required by Win2k3 R2, but if present
+-         check the lm cross hash */
+-      if (r->in.cross2_present && r->in.lm_cross && lm_pwd) {
+-              D_P16(nt_pwd->hash, r->in.lm_cross->hash, checkHash.hash);
+-              if (memcmp(checkHash.hash, new_lmPwdHash.hash, 16) != 0) {
+-                      return NT_STATUS_WRONG_PASSWORD;
+-              }
+-      }
+-
+-      /* Start a SAM with user privileges for the password change */
+-      sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx,
+-                              dce_call->conn->dce_ctx->lp_ctx,
+-                              dce_call->conn->auth_state.session_info, 0);
+-      if (sam_ctx == NULL) {
+-              return NT_STATUS_INVALID_SYSTEM_SERVICE;
+-      }
+-
+-      /* Start transaction */
+-      ret = ldb_transaction_start(sam_ctx);
+-      if (ret != LDB_SUCCESS) {
+-              DEBUG(1, ("Failed to start transaction: %s\n", 
ldb_errstring(sam_ctx)));
+-              return NT_STATUS_TRANSACTION_ABORTED;
+-      }
+-
+-      /* Performs the password modification. We pass the old hashes read out
+-       * from the database since they were already checked against the user-
+-       * provided ones. */
+-      status = samdb_set_password(sam_ctx, mem_ctx,
+-                                  a_state->account_dn,
+-                                  a_state->domain_state->domain_dn,
+-                                  NULL, &new_lmPwdHash, &new_ntPwdHash,
+-                                  lm_pwd, nt_pwd, /* this is a user password 
change */
+-                                  NULL,
+-                                  NULL);
+-      if (!NT_STATUS_IS_OK(status)) {
+-              ldb_transaction_cancel(sam_ctx);
+-              return status;
+-      }
+-
+-      /* And this confirms it in a transaction commit */
+-      ret = ldb_transaction_commit(sam_ctx);
+-      if (ret != LDB_SUCCESS) {
+-              DEBUG(1,("Failed to commit transaction to change password on %s: 
%s\n",
+-                       ldb_dn_get_linearized(a_state->account_dn),
+-                       ldb_errstring(sam_ctx)));
+-              return NT_STATUS_TRANSACTION_ABORTED;
+-      }
+-
+-      return NT_STATUS_OK;
++      return NT_STATUS_NOT_IMPLEMENTED;
+ }
+
+ /*
+diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c
+index 7d9a1e2..adfc5d4 100644
+--- a/source4/torture/rpc/samr.c
++++ b/source4/torture/rpc/samr.c
+@@ -1728,8 +1728,16 @@ static bool test_ChangePasswordUser(struct 
dcerpc_binding_handle *b,
+
+       torture_assert_ntstatus_ok(tctx, dcerpc_samr_ChangePasswordUser_r(b, tctx, 
&r),
+               "ChangePasswordUser failed");
+-      torture_assert_ntstatus_equal(tctx, r.out.result, 
NT_STATUS_WRONG_PASSWORD,
+-              "ChangePasswordUser failed: expected NT_STATUS_WRONG_PASSWORD 
because we broke the LM hash");
++
++      /* Do not proceed if this call has been removed */
++      if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
++              return true;
++      }
++
++      if (!NT_STATUS_EQUAL(r.out.result, NT_STATUS_PASSWORD_RESTRICTION)) {
++              torture_assert_ntstatus_equal(tctx, r.out.result, 
NT_STATUS_WRONG_PASSWORD,
++                      "ChangePasswordUser failed: expected 
NT_STATUS_WRONG_PASSWORD because we broke the LM hash");
++      }
+
+       /* Unbreak the LM hash */
+       hash1.hash[0]--;
+--
+1.7.9.5
+
diff --git a/meta-oe/recipes-connectivity/samba/samba_3.6.8.bb 
b/meta-oe/recipes-connectivity/samba/samba_3.6.8.bb
index 20b609d..f80e41e 100644
--- a/meta-oe/recipes-connectivity/samba/samba_3.6.8.bb
+++ b/meta-oe/recipes-connectivity/samba/samba_3.6.8.bb
@@ -30,6 +30,7 @@ SRC_URI += "\
      file://configure-disable-getaddrinfo-cross.patch;patchdir=.. \
      file://configure-disable-core_pattern-cross-check.patch;patchdir=.. \
      file://configure-libunwind.patch;patchdir=.. \
+    file://samba-3.6.22-CVE-2013-4496.patch;patchdir=.. \
  "
  SRC_URI[md5sum] = "fbb245863eeef2fffe172df779a217be"
  SRC_URI[sha256sum] = 
"4f5a171a8d902c6b4f822ed875c51eb8339196d9ccf0ecd7f6521c966b3514de"
--
1.7.9.5

--
_______________________________________________
Openembedded-devel mailing list
Openembedded-devel@lists.openembedded.org
http://lists.openembedded.org/mailman/listinfo/openembedded-devel
--
Martin 'JaMa' Jansa     jabber: martin.ja...@gmail.com





--
_______________________________________________
Openembedded-devel mailing list
Openembedded-devel@lists.openembedded.org
http://lists.openembedded.org/mailman/listinfo/openembedded-devel

Reply via email to