The branch, master has been updated
       via  dd8553b s4-kdc: Move kpasswd_make_pwchange_reply() to a helper file
       via  f9de99c s4-kdc: Move kpasswd_make_error_reply() to a helper file
       via  2f36e6d krb5_wrap: Fix smb_krb5_mk_error() with MIT Kerberos
       via  5ae447e testprogs: Test only what the Heimdal kpasswd test should 
test
       via  e528919 testprogs: Make test_passwords.sh a Heimdal kpasswd test
       via  13fdeb0 testprogs: Add a new test_password_settings.sh script
       via  4899ece testprogs: Add a common test_smbclient_expect_failure() 
function
       via  b3e324a heimdal: Fix reauthentication after password change
      from  c855a37 winbindd: Remove unused enum ent_type

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit dd8553b54b7e6fad207ec09cffe039b844493755
Author: Andreas Schneider <[email protected]>
Date:   Wed Sep 7 14:57:59 2016 +0200

    s4-kdc: Move kpasswd_make_pwchange_reply() to a helper file
    
    Signed-off-by: Andreas Schneider <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>
    
    Autobuild-User(master): Jeremy Allison <[email protected]>
    Autobuild-Date(master): Sun Sep 11 06:45:00 CEST 2016 on sn-devel-144

commit f9de99ce9b59d9052d9ebe22332f76f66857476f
Author: Andreas Schneider <[email protected]>
Date:   Wed Sep 7 14:47:31 2016 +0200

    s4-kdc: Move kpasswd_make_error_reply() to a helper file
    
    Signed-off-by: Andreas Schneider <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit 2f36e6d3ec1907b32275a769667cc7b791efd7de
Author: Andreas Schneider <[email protected]>
Date:   Fri Sep 2 11:54:48 2016 +0200

    krb5_wrap: Fix smb_krb5_mk_error() with MIT Kerberos
    
    The server principal is required, so if not set create an obscure one.
    
    Signed-off-by: Andreas Schneider <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit 5ae447e102d5c29688f759ce19bca1689c5924f0
Author: Andreas Schneider <[email protected]>
Date:   Tue Sep 6 09:31:41 2016 +0200

    testprogs: Test only what the Heimdal kpasswd test should test
    
    The test_password_settings.sh test does test using different password
    settings and is not specific to the kpasswd implementation. This
    test tests the kpasswd service.
    
    Signed-off-by: Andreas Schneider <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit e5289191a994af4ad2def422ec57521eb2da2f90
Author: Andreas Schneider <[email protected]>
Date:   Mon Sep 5 15:18:07 2016 +0200

    testprogs: Make test_passwords.sh a Heimdal kpasswd test
    
    Signed-off-by: Andreas Schneider <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit 13fdeb0a98c3e0d00fe227d6fa17d4770bc7468c
Author: Andreas Schneider <[email protected]>
Date:   Tue Sep 6 08:55:43 2016 +0200

    testprogs: Add a new test_password_settings.sh script
    
    This test is not Kerberos implementation specific.
    
    Signed-off-by: Andreas Schneider <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit 4899ece472847a6e207098e4472d0e2515081fe0
Author: Andreas Schneider <[email protected]>
Date:   Tue Sep 6 08:56:47 2016 +0200

    testprogs: Add a common test_smbclient_expect_failure() function
    
    Signed-off-by: Andreas Schneider <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit b3e324aad53a6b4adf0ece58c1b8bd9eed2cd48c
Author: Andreas Schneider <[email protected]>
Date:   Wed Sep 7 17:17:08 2016 +0200

    heimdal: Fix reauthentication after password change
    
    If the KDC requires a password change kinit will ask after the initial
    authentication for a new password. After the password has been changed
    it does reauthentication and for that it needs to use the new password
    we just set.
    
    It is needed for the a new kpasswd service test.
    
    This is already fixed upstream with:
        911c99375741281adae305f6ec3a3317023eba3e
    
    Signed-off-by: Andreas Schneider <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

-----------------------------------------------------------------------

Summary of changes:
 lib/krb5_wrap/krb5_samba.c                         |  52 +++-
 lib/krb5_wrap/krb5_samba.h                         |   2 +
 selftest/knownfail                                 |   1 -
 source4/heimdal/lib/krb5/init_creds_pw.c           |   7 +-
 source4/kdc/kdc-server.c                           |   2 +
 source4/kdc/kpasswd-heimdal.c                      | 114 ++-------
 source4/kdc/kpasswd-helper.c                       | 158 ++++++++++++
 .../kdc/kpasswd-helper.h                           |  23 +-
 source4/kdc/wscript_build                          |   2 +-
 source4/selftest/tests.py                          |   3 +-
 testprogs/blackbox/common_test_fns.inc             |  18 ++
 testprogs/blackbox/test_kpasswd_heimdal.sh         | 217 +++++++++++++++++
 testprogs/blackbox/test_password_settings.sh       | 211 ++++++++++++++++
 testprogs/blackbox/test_passwords.sh               | 265 ---------------------
 14 files changed, 690 insertions(+), 385 deletions(-)
 create mode 100644 source4/kdc/kpasswd-helper.c
 copy libcli/auth/schannel_proto.h => source4/kdc/kpasswd-helper.h (57%)
 create mode 100755 testprogs/blackbox/test_kpasswd_heimdal.sh
 create mode 100755 testprogs/blackbox/test_password_settings.sh
 delete mode 100755 testprogs/blackbox/test_passwords.sh


Changeset truncated at 500 lines:

diff --git a/lib/krb5_wrap/krb5_samba.c b/lib/krb5_wrap/krb5_samba.c
index dcd6185..28884d9 100644
--- a/lib/krb5_wrap/krb5_samba.c
+++ b/lib/krb5_wrap/krb5_samba.c
@@ -206,6 +206,8 @@ krb5_error_code smb_krb5_mk_error(krb5_context context,
                                  krb5_error_code error_code,
                                  const char *e_text,
                                  krb5_data *e_data,
+                                 const krb5_principal client,
+                                 const krb5_principal server,
                                  krb5_data *enc_err)
 {
        krb5_error_code code = EINVAL;
@@ -214,27 +216,59 @@ krb5_error_code smb_krb5_mk_error(krb5_context context,
                             error_code,
                             e_text,
                             e_data,
-                            NULL, /* client */
-                            NULL, /* server */
+                            client,
+                            server,
                             NULL, /* client_time */
                             NULL, /* client_usec */
                             enc_err);
 #else
-       krb5_error dec_err = {
-               .error = error_code,
-       };
+       krb5_principal unspec_server = NULL;
+       krb5_error errpkt;
 
+       errpkt.ctime = 0;
+       errpkt.cusec = 0;
+
+       code = krb5_us_timeofday(context,
+                                &errpkt.stime,
+                                &errpkt.susec);
+       if (code != 0) {
+               return code;
+       }
+
+       errpkt.error = error_code;
+
+       errpkt.text.length = 0;
        if (e_text != NULL) {
-               dec_err.text.length = strlen(e_text);
-               dec_err.text.data = discard_const_p(char, e_text);
+               errpkt.text.length = strlen(e_text);
+               errpkt.text.data = discard_const_p(char, e_text);
        }
+
+       errpkt.e_data.magic = KV5M_DATA;
+       errpkt.e_data.length = 0;
+       errpkt.e_data.data = NULL;
        if (e_data != NULL) {
-               dec_err.e_data = *e_data;
+               errpkt.e_data = *e_data;
+       }
+
+       errpkt.client = client;
+
+       if (server != NULL) {
+               errpkt.server = server;
+       } else {
+               code = smb_krb5_make_principal(context,
+                                              &unspec_server,
+                                              "<unspecified realm>",
+                                              NULL);
+               if (code != 0) {
+                       return code;
+               }
+               errpkt.server = unspec_server;
        }
 
        code = krb5_mk_error(context,
-                            &dec_err,
+                            &errpkt,
                             enc_err);
+       krb5_free_principal(context, unspec_server);
 #endif
        return code;
 }
diff --git a/lib/krb5_wrap/krb5_samba.h b/lib/krb5_wrap/krb5_samba.h
index 64a04b3..71e81ea 100644
--- a/lib/krb5_wrap/krb5_samba.h
+++ b/lib/krb5_wrap/krb5_samba.h
@@ -169,6 +169,8 @@ krb5_error_code smb_krb5_mk_error(krb5_context context,
                                  krb5_error_code error_code,
                                  const char *e_text,
                                  krb5_data *e_data,
+                                 const krb5_principal client,
+                                 const krb5_principal server,
                                  krb5_data *enc_err);
 
 krb5_error_code smb_krb5_get_allowed_etypes(krb5_context context,
diff --git a/selftest/knownfail b/selftest/knownfail
index 2f6a66b..1051518 100644
--- a/selftest/knownfail
+++ b/selftest/knownfail
@@ -142,7 +142,6 @@
 ^samba4.smb2.getinfo.qsec_buffercheck # S4 does not do the BUFFER_TOO_SMALL 
thingy
 ^samba4.ntvfs.cifs.krb5.base.createx_access.createx_access\(.*\)$
 ^samba4.rpc.lsa.forest.trust #Not fully provided by Samba4
-^samba4.blackbox.kinit\(.*\).kinit with user password for expired 
password\(.*\) # We need to work out why this fails only during the pw change
 ^samba4.blackbox.upgradeprovision.alpha13.ldapcmp_sd\(none\) # Due to 
something rewriting the NT ACL on DNS objects
 ^samba4.blackbox.upgradeprovision.alpha13.ldapcmp_full_sd\(none\) # Due to 
something rewriting the NT ACL on DNS objects
 ^samba4.blackbox.upgradeprovision.release-4-0-0.ldapcmp_sd\(none\) # Due to 
something rewriting the NT ACL on DNS objects
diff --git a/source4/heimdal/lib/krb5/init_creds_pw.c 
b/source4/heimdal/lib/krb5/init_creds_pw.c
index b6c0a64..a66ad35 100644
--- a/source4/heimdal/lib/krb5/init_creds_pw.c
+++ b/source4/heimdal/lib/krb5/init_creds_pw.c
@@ -1990,6 +1990,7 @@ krb5_get_init_creds_password(krb5_context context,
 {
     krb5_init_creds_context ctx;
     char buf[BUFSIZ];
+    char buf2[BUFSIZ];
     krb5_error_code ret;
     int chpw = 0;
 
@@ -2041,8 +2042,6 @@ krb5_get_init_creds_password(krb5_context context,
 
 
     if (ret == KRB5KDC_ERR_KEY_EXPIRED && chpw == 0) {
-       char buf2[1024];
-
        /* try to avoid recursion */
        if (in_tkt_service != NULL && strcmp(in_tkt_service, "kadmin/changepw") 
== 0)
           goto out;
@@ -2055,13 +2054,14 @@ krb5_get_init_creds_password(krb5_context context,
                               client,
                               ctx->password,
                               buf2,
-                              sizeof(buf),
+                              sizeof(buf2),
                               prompter,
                               data,
                               options);
        if (ret)
            goto out;
        chpw = 1;
+       password = buf2;
        krb5_init_creds_free(context, ctx);
        goto again;
     }
@@ -2074,6 +2074,7 @@ krb5_get_init_creds_password(krb5_context context,
        krb5_init_creds_free(context, ctx);
 
     memset(buf, 0, sizeof(buf));
+    memset(buf2, 0, sizeof(buf2));
     return ret;
 }
 
diff --git a/source4/kdc/kdc-server.c b/source4/kdc/kdc-server.c
index 7854f49..13e338d 100644
--- a/source4/kdc/kdc-server.c
+++ b/source4/kdc/kdc-server.c
@@ -83,6 +83,8 @@ static NTSTATUS kdc_proxy_unavailable_error(struct kdc_server 
*kdc,
                                 KRB5KDC_ERR_SVC_UNAVAILABLE,
                                 NULL,
                                 NULL,
+                                NULL,
+                                NULL,
                                 &enc_error);
        if (code != 0) {
                DBG_WARNING("Unable to form krb5 error reply\n");
diff --git a/source4/kdc/kpasswd-heimdal.c b/source4/kdc/kpasswd-heimdal.c
index ff2f6af..49fc755 100644
--- a/source4/kdc/kpasswd-heimdal.c
+++ b/source4/kdc/kpasswd-heimdal.c
@@ -33,31 +33,7 @@
 #include "kdc/kdc-glue.h"
 #include "dsdb/common/util.h"
 #include "kdc/kpasswd_glue.h"
-
-/* Return true if there is a valid error packet formed in the error_blob */
-static bool kpasswdd_make_error_reply(struct kdc_server *kdc,
-                                    TALLOC_CTX *mem_ctx,
-                                    uint16_t result_code,
-                                    const char *error_string,
-                                    DATA_BLOB *error_blob)
-{
-       char *error_string_utf8;
-       size_t len;
-
-       DEBUG(result_code ? 3 : 10, ("kpasswdd: %s\n", error_string));
-
-       if (!push_utf8_talloc(mem_ctx, &error_string_utf8, error_string, &len)) 
{
-               return false;
-       }
-
-       *error_blob = data_blob_talloc(mem_ctx, NULL, 2 + len + 1);
-       if (!error_blob->data) {
-               return false;
-       }
-       RSSVAL(error_blob->data, 0, result_code);
-       memcpy(error_blob->data + 2, error_string_utf8, len + 1);
-       return true;
-}
+#include "kdc/kpasswd-helper.h"
 
 /* Return true if there is a valid error packet formed in the error_blob */
 static bool kpasswdd_make_unauth_error_reply(struct kdc_server *kdc,
@@ -70,7 +46,7 @@ static bool kpasswdd_make_unauth_error_reply(struct 
kdc_server *kdc,
        int kret;
        DATA_BLOB error_bytes;
        krb5_data k5_error_bytes, k5_error_blob;
-       ret = kpasswdd_make_error_reply(kdc, mem_ctx, result_code, error_string,
+       ret = kpasswd_make_error_reply(mem_ctx, result_code, error_string,
                                       &error_bytes);
        if (!ret) {
                return false;
@@ -81,6 +57,8 @@ static bool kpasswdd_make_unauth_error_reply(struct 
kdc_server *kdc,
                                 result_code,
                                 NULL,
                                 &k5_error_bytes,
+                                NULL,
+                                NULL,
                                 &k5_error_blob);
        if (kret) {
                return false;
@@ -94,60 +72,6 @@ static bool kpasswdd_make_unauth_error_reply(struct 
kdc_server *kdc,
        return true;
 }
 
-static bool kpasswd_make_pwchange_reply(struct kdc_server *kdc,
-                                       TALLOC_CTX *mem_ctx,
-                                       NTSTATUS status,
-                                       enum samPwdChangeReason reject_reason,
-                                       struct samr_DomInfo1 *dominfo,
-                                       DATA_BLOB *error_blob)
-{
-       if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
-               return kpasswdd_make_error_reply(kdc, mem_ctx,
-                                               KRB5_KPASSWD_ACCESSDENIED,
-                                               "No such user when changing 
password",
-                                               error_blob);
-       }
-       if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
-               return kpasswdd_make_error_reply(kdc, mem_ctx,
-                                               KRB5_KPASSWD_ACCESSDENIED,
-                                               "Not permitted to change 
password",
-                                               error_blob);
-       }
-       if (dominfo && NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) 
{
-               const char *reject_string;
-               switch (reject_reason) {
-               case SAM_PWD_CHANGE_PASSWORD_TOO_SHORT:
-                       reject_string = talloc_asprintf(mem_ctx, "Password too 
short, password must be at least %d characters long.",
-                                                       
dominfo->min_password_length);
-                       break;
-               case SAM_PWD_CHANGE_NOT_COMPLEX:
-                       reject_string = "Password does not meet complexity 
requirements";
-                       break;
-               case SAM_PWD_CHANGE_PWD_IN_HISTORY:
-                       reject_string = talloc_asprintf(mem_ctx, "Password is 
already in password history.  New password must not match any of your %d 
previous passwords.",
-                                                       
dominfo->password_history_length);
-                       break;
-               default:
-                       reject_string = "Password change rejected, password 
changes may not be permitted on this account, or the minimum password age may 
not have elapsed.";
-                       break;
-               }
-               return kpasswdd_make_error_reply(kdc, mem_ctx,
-                                               KRB5_KPASSWD_SOFTERROR,
-                                               reject_string,
-                                               error_blob);
-       }
-       if (!NT_STATUS_IS_OK(status)) {
-               return kpasswdd_make_error_reply(kdc, mem_ctx,
-                                                KRB5_KPASSWD_HARDERROR,
-                                                talloc_asprintf(mem_ctx, 
"failed to set password: %s", nt_errstr(status)),
-                                                error_blob);
-
-       }
-       return kpasswdd_make_error_reply(kdc, mem_ctx, KRB5_KPASSWD_SUCCESS,
-                                       "Password changed",
-                                       error_blob);
-}
-
 /*
    A user password change
 
@@ -177,15 +101,13 @@ static bool kpasswdd_change_password(struct kdc_server 
*kdc,
                                               &error_string,
                                               &result);
        if (!NT_STATUS_IS_OK(status)) {
-               return kpasswdd_make_error_reply(kdc,
-                                                mem_ctx,
+               return kpasswd_make_error_reply(mem_ctx,
                                                 KRB5_KPASSWD_ACCESSDENIED,
                                                 error_string,
                                                 reply);
        }
 
-       return kpasswd_make_pwchange_reply(kdc,
-                                          mem_ctx,
+       return kpasswd_make_pwchange_reply(mem_ctx,
                                           result,
                                           reject_reason,
                                           dominfo,
@@ -205,7 +127,7 @@ static bool kpasswd_process_request(struct kdc_server *kdc,
        if (!NT_STATUS_IS_OK(gensec_session_info(gensec_security,
                                                 mem_ctx,
                                                 &session_info))) {
-               return kpasswdd_make_error_reply(kdc, mem_ctx,
+               return kpasswd_make_error_reply(mem_ctx,
                                                KRB5_KPASSWD_HARDERROR,
                                                "gensec_session_info failed!",
                                                reply);
@@ -249,7 +171,7 @@ static bool kpasswd_process_request(struct kdc_server *kdc,
                ret = decode_ChangePasswdDataMS(input->data, input->length,
                                                &chpw, &len);
                if (ret) {
-                       return kpasswdd_make_error_reply(kdc, mem_ctx,
+                       return kpasswd_make_error_reply(mem_ctx,
                                                        KRB5_KPASSWD_MALFORMED,
                                                        "failed to decode 
password change structure",
                                                        reply);
@@ -269,7 +191,7 @@ static bool kpasswd_process_request(struct kdc_server *kdc,
                if ((chpw.targname && !chpw.targrealm)
                    || (!chpw.targname && chpw.targrealm)) {
                        free_ChangePasswdDataMS(&chpw);
-                       return kpasswdd_make_error_reply(kdc, mem_ctx,
+                       return kpasswd_make_error_reply(mem_ctx,
                                                        KRB5_KPASSWD_MALFORMED,
                                                        "Realm and principal 
must be both present, or neither present",
                                                        reply);
@@ -281,7 +203,7 @@ static bool kpasswd_process_request(struct kdc_server *kdc,
                                                       *chpw.targrealm, 0);
                        if (ret) {
                                free_ChangePasswdDataMS(&chpw);
-                               return kpasswdd_make_error_reply(kdc, mem_ctx,
+                               return kpasswd_make_error_reply(mem_ctx,
                                                                
KRB5_KPASSWD_MALFORMED,
                                                                "failed to get 
principal",
                                                                reply);
@@ -289,7 +211,7 @@ static bool kpasswd_process_request(struct kdc_server *kdc,
                        if (copy_PrincipalName(chpw.targname, 
&principal->name)) {
                                free_ChangePasswdDataMS(&chpw);
                                krb5_free_principal(context, principal);
-                               return kpasswdd_make_error_reply(kdc, mem_ctx,
+                               return kpasswd_make_error_reply(mem_ctx,
                                                                
KRB5_KPASSWD_MALFORMED,
                                                                "failed to 
extract principal to set",
                                                                reply);
@@ -310,7 +232,7 @@ static bool kpasswd_process_request(struct kdc_server *kdc,
 
                        if (krb5_unparse_name_short(context, principal, 
&set_password_on_princ) != 0) {
                                krb5_free_principal(context, principal);
-                               return kpasswdd_make_error_reply(kdc, mem_ctx,
+                               return kpasswd_make_error_reply(mem_ctx,
                                                                 
KRB5_KPASSWD_MALFORMED,
                                                                 
"krb5_unparse_name failed!",
                                                                 reply);
@@ -318,7 +240,7 @@ static bool kpasswd_process_request(struct kdc_server *kdc,
                } else {
                        if (krb5_unparse_name(context, principal, 
&set_password_on_princ) != 0) {
                                krb5_free_principal(context, principal);
-                               return kpasswdd_make_error_reply(kdc, mem_ctx,
+                               return kpasswd_make_error_reply(mem_ctx,
                                                                 
KRB5_KPASSWD_MALFORMED,
                                                                 
"krb5_unparse_name failed!",
                                                                 reply);
@@ -329,7 +251,7 @@ static bool kpasswd_process_request(struct kdc_server *kdc,
                samdb = samdb_connect(mem_ctx, kdc->task->event_ctx, 
kdc->task->lp_ctx, session_info, 0);
                if (!samdb) {
                        free(set_password_on_princ);
-                       return kpasswdd_make_error_reply(kdc, mem_ctx,
+                       return kpasswd_make_error_reply(mem_ctx,
                                                         KRB5_KPASSWD_HARDERROR,
                                                         "Unable to open 
database!",
                                                         reply);
@@ -344,7 +266,7 @@ static bool kpasswd_process_request(struct kdc_server *kdc,
                if (ret != LDB_SUCCESS) {
                        free(set_password_on_princ);
                        status = NT_STATUS_TRANSACTION_ABORTED;
-                       return kpasswd_make_pwchange_reply(kdc, mem_ctx,
+                       return kpasswd_make_pwchange_reply(mem_ctx,
                                                           status,
                                                           
SAM_PWD_CHANGE_NO_ERROR,
                                                           NULL,
@@ -363,7 +285,7 @@ static bool kpasswd_process_request(struct kdc_server *kdc,
                free(set_password_on_princ);
                if (!NT_STATUS_IS_OK(status)) {
                        ldb_transaction_cancel(samdb);
-                       return kpasswd_make_pwchange_reply(kdc, mem_ctx,
+                       return kpasswd_make_pwchange_reply(mem_ctx,
                                                           status,
                                                           
SAM_PWD_CHANGE_NO_ERROR,
                                                           NULL,
@@ -390,14 +312,14 @@ static bool kpasswd_process_request(struct kdc_server 
*kdc,
                } else {
                        ldb_transaction_cancel(samdb);
                }
-               return kpasswd_make_pwchange_reply(kdc, mem_ctx,
+               return kpasswd_make_pwchange_reply(mem_ctx,
                                                   status,
                                                   reject_reason,
                                                   dominfo,
                                                   reply);
        }
        default:
-               return kpasswdd_make_error_reply(kdc, mem_ctx,
+               return kpasswd_make_error_reply(mem_ctx,
                                                 KRB5_KPASSWD_BAD_VERSION,
                                                 talloc_asprintf(mem_ctx,
                                                                 "Protocol 
version %u not supported",
diff --git a/source4/kdc/kpasswd-helper.c b/source4/kdc/kpasswd-helper.c
new file mode 100644
index 0000000..5ecb6e9
--- /dev/null
+++ b/source4/kdc/kpasswd-helper.c
@@ -0,0 +1,158 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   Samba kpasswd implementation
+
+   Copyright (c) 2005      Andrew Bartlett <[email protected]>
+   Copyright (c) 2016      Andreas Schneider <[email protected]>
+
+   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 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "system/kerberos.h"
+#include "librpc/gen_ndr/samr.h"
+#include "kdc/kpasswd-helper.h"
+
+bool kpasswd_make_error_reply(TALLOC_CTX *mem_ctx,
+                             krb5_error_code error_code,
+                             const char *error_string,
+                             DATA_BLOB *error_data)
+{
+       bool ok;
+       char *s;
+       size_t slen;
+
+       if (error_code == 0) {
+               DBG_DEBUG("kpasswd reply - %s\n", error_string);
+       } else {
+               DBG_INFO("kpasswd reply - %s\n", error_string);
+       }
+
+       ok = push_utf8_talloc(mem_ctx, &s, error_string, &slen);
+       if (!ok) {
+               return false;
+       }
+
+       /*
+        * The string 's' has two terminating nul-bytes which are also
+        * reflected by 'slen'. Normally Kerberos doesn't expect that strings
+        * are nul-terminated, but Heimdal does!
+        */
+#ifndef SAMBA4_USES_HEIMDAL
+       if (slen < 2) {
+               return false;
+       }
+       slen -= 2;
+#endif
+       if (2 + slen < slen) {
+               return false;
+       }
+       error_data->length = 2 + slen;
+       error_data->data = talloc_size(mem_ctx, error_data->length);
+       if (error_data->data == NULL) {
+               talloc_free(s);
+               return false;
+       }
+
+       RSSVAL(error_data->data, 0, error_code);
+       memcpy(error_data->data + 2, s, slen);
+
+       talloc_free(s);
+
+       return true;
+}
+
+bool kpasswd_make_pwchange_reply(TALLOC_CTX *mem_ctx,
+                                NTSTATUS status,
+                                enum samPwdChangeReason reject_reason,
+                                struct samr_DomInfo1 *dominfo,
+                                DATA_BLOB *error_blob)
+{
+       const char *reject_string = NULL;
+
+       if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
+               return kpasswd_make_error_reply(mem_ctx,
+                                               KRB5_KPASSWD_ACCESSDENIED,
+                                               "No such user when changing 
password",


-- 
Samba Shared Repository

Reply via email to