The branch, master has been updated
       via  8e3b369c055 allow tests to be run against a PAM-less build
       via  8ff6ad7454d lib/util: fix timespec normalization
       via  254af19ba89 auth4: Remove sync check_password from auth_operations
       via  f852fb4cd4e auth4: Make auth_sam pseudo-async
       via  a6f42ab8a77 auth4: Make auth_unix pseudo-async
       via  43a1e428157 auth4: Make auth_developer pseudo-async
       via  75957313687 auth4: Make auth_anonymous pseudo-async
      from  bfb9cd8b9b3 waf: Check correctly if gnutls has been compiled with 
fips mode support

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


- Log -----------------------------------------------------------------
commit 8e3b369c0550383499af4b4ebb09513ef0e0635c
Author: Philipp Gesang <[email protected]>
Date:   Wed Apr 14 08:35:40 2021 +0200

    allow tests to be run against a PAM-less build
    
    Indexing the config hash table fails for PAM related values:
    
        Traceback (most recent call last):
          File "/src/samba/samba/selftest/tests.py", line 49, in <module>
            pam_set_items_so_path = config_hash["PAM_SET_ITEMS_SO_PATH"]
        KeyError: 'PAM_SET_ITEMS_SO_PATH'
        Error creating recipe from python3 /src/samba/samba/selftest/tests.py| 
at /src/samba/samba/selftest/selftest.pl line 645.
    
    which prevents the test suite from running when built
    --without-pam. Access those values using the get() method
    instead.
    
    Signed-off-by: Philipp Gesang <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Andrew Bartlett <[email protected]>
    
    Autobuild-User(master): Andrew Bartlett <[email protected]>
    Autobuild-Date(master): Fri Apr 16 10:27:41 UTC 2021 on sn-devel-184

commit 8ff6ad7454d9da1dff91c8b827c54008e83cc150
Author: Philipp Gesang <[email protected]>
Date:   Thu Jan 17 11:06:26 2019 +0100

    lib/util: fix timespec normalization
    
    When fixing up timespec structs, negative values for the ns part
    should be taken into account. Also, the range for a valid ns part
    is [0, 1000000000), not [0, 1000000000].
    
    Signed-off-by: Philipp Gesang <[email protected]>
    Reviewed-by: Douglas Bagnall <[email protected]>
    Reviewed-by: Andrew Bartlett <[email protected]>

commit 254af19ba89b4c42e5f45ec731e6577d2fcc6736
Author: Volker Lendecke <[email protected]>
Date:   Wed Apr 14 22:24:44 2021 +0200

    auth4: Remove sync check_password from auth_operations
    
    Remove complexity in the data structures, and pushes the async-ness
    one level down.
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Andrew Bartlett <[email protected]>

commit f852fb4cd4e2bcd676a9ea104c5bf00979771eed
Author: Volker Lendecke <[email protected]>
Date:   Thu Apr 15 10:04:21 2021 +0200

    auth4: Make auth_sam pseudo-async
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Andrew Bartlett <[email protected]>

commit a6f42ab8a778b9863990da3112c2e868cd006303
Author: Volker Lendecke <[email protected]>
Date:   Wed Apr 14 21:59:55 2021 +0200

    auth4: Make auth_unix pseudo-async
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Andrew Bartlett <[email protected]>

commit 43a1e42815718591faa8d526319b96d089a758fa
Author: Volker Lendecke <[email protected]>
Date:   Wed Apr 14 22:22:18 2021 +0200

    auth4: Make auth_developer pseudo-async
    
    This is a simpler approach to really just wrap the code.
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Andrew Bartlett <[email protected]>

commit 759573136876ef2b1b1c7484f99570d7de957e0d
Author: Volker Lendecke <[email protected]>
Date:   Wed Apr 14 21:48:32 2021 +0200

    auth4: Make auth_anonymous pseudo-async
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Andrew Bartlett <[email protected]>

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

Summary of changes:
 lib/util/tests/time.c              | 53 ++++++++++++++++++++++++
 lib/util/time.c                    | 53 ++++++++++++++++++++----
 lib/util/time.h                    |  1 +
 selftest/tests.py                  |  4 +-
 source4/auth/auth.h                |  4 --
 source4/auth/ntlm/auth.c           | 44 ++------------------
 source4/auth/ntlm/auth_anonymous.c | 66 +++++++++++++++++++++++++----
 source4/auth/ntlm/auth_developer.c | 61 ++++++++++++++++++++++++++-
 source4/auth/ntlm/auth_sam.c       | 69 ++++++++++++++++++++++++++++++-
 source4/auth/ntlm/auth_unix.c      | 85 ++++++++++++++++++++++++++------------
 source4/auth/ntlm/wscript_build    |  4 +-
 11 files changed, 350 insertions(+), 94 deletions(-)


Changeset truncated at 500 lines:

diff --git a/lib/util/tests/time.c b/lib/util/tests/time.c
index fce0eef5e2e..039f7f4ccf8 100644
--- a/lib/util/tests/time.c
+++ b/lib/util/tests/time.c
@@ -82,6 +82,57 @@ static bool test_timestring(struct torture_context *tctx)
        return true;
 }
 
+static bool test_normalize_timespec(struct torture_context *tctx)
+{
+       const struct {
+               time_t in_s; long in_ns;
+               time_t out_s; long out_ns;
+       } data [] = {
+                 { 0, 0, 0, 0 }
+               , { 1, 0, 1, 0 }
+               , { -1, 0, -1, 0 }
+               , { 0, 1000000000, 1, 0 }
+               , { 0, 2000000000, 2, 0 }
+               , { 0, 1000000001, 1, 1 }
+               , { 0, 2000000001, 2, 1 }
+               , { 0, -1000000000, -1, 0 }
+               , { 0, -2000000000, -2, 0 }
+               , { 0, -1000000001, -2, 999999999 }
+               , { 0, -2000000001, -3, 999999999 }
+               , { 0, -1, -1, 999999999 }
+               , { 1, -1, 0, 999999999 }
+               , { -1, -1, -2, 999999999 }
+               , { 0, 999999999, 0, 999999999 }
+               , { 0, 1999999999, 1, 999999999 }
+               , { 0, 2999999999, 2, 999999999 }
+               , { 0, -999999999, -1, 1 }
+               , { 0, -1999999999, -2, 1 }
+               , { 0, -2999999999, -3, 1 }
+               , { LONG_MAX, 1000000001, LONG_MAX, 999999999 } /* overflow */
+               , { LONG_MAX,  999999999, LONG_MAX, 999999999 } /* harmless */
+               , { LONG_MAX, -1, LONG_MAX-1, 999999999 } /* -1 */
+               , { LONG_MIN, -1000000001, LONG_MIN, 0 } /* overflow */
+               , { LONG_MIN, 0, LONG_MIN, 0 } /* harmless */
+               , { LONG_MIN, 1000000000, LONG_MIN+1, 0 } /* +1 */
+       };
+       int i;
+
+       for (i = 0; i < sizeof(data) / sizeof(data[0]); ++i) {
+               struct timespec ts = (struct timespec)
+                                  { .tv_sec  = data[i].in_s
+                                  , .tv_nsec = data[i].in_ns };
+
+               normalize_timespec(&ts);
+
+               torture_assert_int_equal(tctx, ts.tv_sec, data[i].out_s,
+                                        "mismatch in tv_sec");
+               torture_assert_int_equal(tctx, ts.tv_nsec, data[i].out_ns,
+                                        "mismatch in tv_nsec");
+       }
+
+       return true;
+}
+
 struct torture_suite *torture_local_util_time(TALLOC_CTX *mem_ctx)
 {
        struct torture_suite *suite = torture_suite_create(mem_ctx, "time");
@@ -92,6 +143,8 @@ struct torture_suite *torture_local_util_time(TALLOC_CTX 
*mem_ctx)
                                                                  
test_http_timestring);
        torture_suite_add_simple_test(suite, "timestring", 
                                                                  
test_timestring);
+       torture_suite_add_simple_test(suite, "normalize_timespec",
+                                     test_normalize_timespec);
 
        return suite;
 }
diff --git a/lib/util/time.c b/lib/util/time.c
index e8b58e87268..53bf194fe0b 100644
--- a/lib/util/time.c
+++ b/lib/util/time.c
@@ -43,6 +43,7 @@
 #endif
 
 
+#define NSEC_PER_SEC 1000000000
 
 /**
  External access to time_t_min and time_t_max.
@@ -92,10 +93,7 @@ _PUBLIC_ time_t time_mono(time_t *t)
 time_t convert_timespec_to_time_t(struct timespec ts)
 {
        /* Ensure tv_nsec is less than 1sec. */
-       while (ts.tv_nsec > 1000000000) {
-               ts.tv_sec += 1;
-               ts.tv_nsec -= 1000000000;
-       }
+       normalize_timespec(&ts);
 
        /* 1 ns == 1,000,000,000 - one thousand millionths of a second.
           increment if it's greater than 500 millionth of a second. */
@@ -1015,10 +1013,7 @@ void round_timespec_to_usec(struct timespec *ts)
 {
        struct timeval tv = convert_timespec_to_timeval(*ts);
        *ts = convert_timeval_to_timespec(tv);
-       while (ts->tv_nsec > 1000000000) {
-               ts->tv_sec += 1;
-               ts->tv_nsec -= 1000000000;
-       }
+       normalize_timespec(ts);
 }
 
 /****************************************************************************
@@ -1462,3 +1457,45 @@ struct timespec get_ctimespec(const struct stat *pst)
        ret.tv_nsec = get_ctimensec(pst);
        return ret;
 }
+
+/****************************************************************************
+ Deal with nanoseconds overflow.
+****************************************************************************/
+
+void normalize_timespec(struct timespec *ts)
+{
+       lldiv_t dres;
+
+       /* most likely case: nsec is valid */
+       if ((unsigned long)ts->tv_nsec < NSEC_PER_SEC) {
+               return;
+       }
+
+       dres = lldiv(ts->tv_nsec, NSEC_PER_SEC);
+
+       /* if the operation would result in overflow, max out values and bail */
+       if (dres.quot > 0) {
+               if ((int64_t)LONG_MAX - dres.quot < ts->tv_sec) {
+                       ts->tv_sec = LONG_MAX;
+                       ts->tv_nsec = NSEC_PER_SEC - 1;
+                       return;
+               }
+       } else {
+               if ((int64_t)LONG_MIN - dres.quot > ts->tv_sec) {
+                       ts->tv_sec = LONG_MIN;
+                       ts->tv_nsec = 0;
+                       return;
+               }
+       }
+
+       ts->tv_nsec = dres.rem;
+       ts->tv_sec += dres.quot;
+
+       /* if the ns part was positive or a multiple of -1000000000, we're done 
*/
+       if (ts->tv_nsec > 0 || dres.rem == 0) {
+               return;
+       }
+
+       ts->tv_nsec += NSEC_PER_SEC;
+       --ts->tv_sec;
+}
diff --git a/lib/util/time.h b/lib/util/time.h
index 04945b5f25f..6726f39c7cc 100644
--- a/lib/util/time.h
+++ b/lib/util/time.h
@@ -360,6 +360,7 @@ void round_timespec_to_sec(struct timespec *ts);
 void round_timespec_to_usec(struct timespec *ts);
 void round_timespec_to_nttime(struct timespec *ts);
 NTTIME unix_timespec_to_nt_time(struct timespec ts);
+void normalize_timespec(struct timespec *ts);
 
 /*
  * Functions supporting the full range of time_t and struct timespec values,
diff --git a/selftest/tests.py b/selftest/tests.py
index 9685a744d0d..69a833dc1ff 100644
--- a/selftest/tests.py
+++ b/selftest/tests.py
@@ -45,8 +45,8 @@ finally:
 have_man_pages_support = ("XSLTPROC_MANPAGES" in config_hash)
 with_pam = ("WITH_PAM" in config_hash)
 with_elasticsearch_backend = ("HAVE_SPOTLIGHT_BACKEND_ES" in config_hash)
-pam_wrapper_so_path = config_hash["LIBPAM_WRAPPER_SO_PATH"]
-pam_set_items_so_path = config_hash["PAM_SET_ITEMS_SO_PATH"]
+pam_wrapper_so_path = config_hash.get("LIBPAM_WRAPPER_SO_PATH")
+pam_set_items_so_path = config_hash.get("PAM_SET_ITEMS_SO_PATH")
 
 planpythontestsuite("none", "samba.tests.source")
 if have_man_pages_support:
diff --git a/source4/auth/auth.h b/source4/auth/auth.h
index 51895c9259f..3f9fb1ae3cb 100644
--- a/source4/auth/auth.h
+++ b/source4/auth/auth.h
@@ -61,10 +61,6 @@ struct auth_operations {
 
        /* Given the user supplied info, check a password */
 
-       NTSTATUS (*check_password)(struct auth_method_context *ctx, TALLOC_CTX 
*mem_ctx,
-                                  const struct auth_usersupplied_info 
*user_info,
-                                  struct auth_user_info_dc **interim_info,
-                                  bool *authoritative);
        struct tevent_req *(*check_password_send)(TALLOC_CTX *mem_ctx,
                                struct tevent_context *ev,
                                struct auth_method_context *ctx,
diff --git a/source4/auth/ntlm/auth.c b/source4/auth/ntlm/auth.c
index 75cf12c5742..e54eb7719f5 100644
--- a/source4/auth/ntlm/auth.c
+++ b/source4/auth/ntlm/auth.c
@@ -332,7 +332,6 @@ static void auth_check_password_next(struct tevent_req *req)
        struct auth_check_password_state *state =
                tevent_req_data(req, struct auth_check_password_state);
        struct tevent_req *subreq = NULL;
-       bool authoritative = true;
        NTSTATUS status;
 
        if (state->method == NULL) {
@@ -357,47 +356,12 @@ static void auth_check_password_next(struct tevent_req 
*req)
                return;
        }
 
-       if (state->method->ops->check_password_send != NULL) {
-               subreq = state->method->ops->check_password_send(state,
-                                                                state->ev,
-                                                                state->method,
-                                                                
state->user_info);
-               if (tevent_req_nomem(subreq, req)) {
-                       return;
-               }
-               tevent_req_set_callback(subreq,
-                                       auth_check_password_done,
-                                       req);
-               return;
-       }
-
-       if (state->method->ops->check_password == NULL) {
-               tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
-               return;
-       }
-
-       status = state->method->ops->check_password(state->method,
-                                                   state,
-                                                   state->user_info,
-                                                   &state->user_info_dc,
-                                                   &authoritative);
-       if (!authoritative ||
-           NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
-               DEBUG(11,("auth_check_password_send: "
-                         "%s passes to the next method\n",
-                         state->method->ops->name));
-               state->method = state->method->next;
-               auth_check_password_next(req);
-               return;
-       }
-
-       /* the backend has handled the request */
-
-       if (tevent_req_nterror(req, status)) {
+       subreq = state->method->ops->check_password_send(
+               state, state->ev, state->method, state->user_info);
+       if (tevent_req_nomem(subreq, req)) {
                return;
        }
-
-       tevent_req_done(req);
+       tevent_req_set_callback(subreq, auth_check_password_done, req);
 }
 
 static void auth_check_password_done(struct tevent_req *subreq)
diff --git a/source4/auth/ntlm/auth_anonymous.c 
b/source4/auth/ntlm/auth_anonymous.c
index 83aeb431f5f..a25aacaa137 100644
--- a/source4/auth/ntlm/auth_anonymous.c
+++ b/source4/auth/ntlm/auth_anonymous.c
@@ -20,9 +20,11 @@
 */
 
 #include "includes.h"
+#include <tevent.h>
 #include "auth/auth.h"
 #include "auth/ntlm/auth_proto.h"
 #include "param/param.h"
+#include "lib/util/tevent_ntstatus.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_AUTH
@@ -84,19 +86,65 @@ static NTSTATUS anonymous_want_check(struct 
auth_method_context *ctx,
  * anonymou logons to be dealt with in one place.  Non-anonymou logons 'fail'
  * and pass onto the next module.
  **/
-static NTSTATUS anonymous_check_password(struct auth_method_context *ctx,
-                                        TALLOC_CTX *mem_ctx,
-                                        const struct auth_usersupplied_info 
*user_info, 
-                                        struct auth_user_info_dc 
**_user_info_dc,
-                                        bool *authoritative)
+
+struct anonymous_check_password_state {
+       struct auth_user_info_dc *user_info_dc;
+};
+
+static struct tevent_req *anonymous_check_password_send(
+       TALLOC_CTX *mem_ctx,
+       struct tevent_context *ev,
+       struct auth_method_context *ctx,
+       const struct auth_usersupplied_info *user_info)
+{
+       struct tevent_req *req = NULL;
+       struct anonymous_check_password_state *state = NULL;
+       NTSTATUS status;
+
+       req = tevent_req_create(
+               mem_ctx,
+               &state,
+               struct anonymous_check_password_state);
+       if (req == NULL) {
+               return NULL;
+       }
+
+       status = auth_anonymous_user_info_dc(
+               state,
+               lpcfg_netbios_name(ctx->auth_ctx->lp_ctx),
+               &state->user_info_dc);
+       if (tevent_req_nterror(req, status)) {
+               return tevent_req_post(req, ev);
+       }
+       tevent_req_done(req);
+       return tevent_req_post(req, ev);
+}
+
+static NTSTATUS anonymous_check_password_recv(
+       struct tevent_req *req,
+       TALLOC_CTX *mem_ctx,
+       struct auth_user_info_dc **interim_info,
+       bool *authoritative)
 {
-       return auth_anonymous_user_info_dc(mem_ctx, 
lpcfg_netbios_name(ctx->auth_ctx->lp_ctx), _user_info_dc);
+       struct anonymous_check_password_state *state = tevent_req_data(
+               req, struct anonymous_check_password_state);
+       NTSTATUS status;
+
+       if (tevent_req_is_nterror(req, &status)) {
+               tevent_req_received(req);
+               return status;
+       }
+       *interim_info = talloc_move(mem_ctx, &state->user_info_dc);
+       tevent_req_received(req);
+       return NT_STATUS_OK;
 }
 
+
 static const struct auth_operations anonymous_auth_ops = {
-       .name           = "anonymous",
-       .want_check     = anonymous_want_check,
-       .check_password = anonymous_check_password
+       .name                   = "anonymous",
+       .want_check             = anonymous_want_check,
+       .check_password_send    = anonymous_check_password_send,
+       .check_password_recv    = anonymous_check_password_recv,
 };
 
 _PUBLIC_ NTSTATUS auth4_anonymous_init(TALLOC_CTX *ctx)
diff --git a/source4/auth/ntlm/auth_developer.c 
b/source4/auth/ntlm/auth_developer.c
index 209786b63b2..1823989c68d 100644
--- a/source4/auth/ntlm/auth_developer.c
+++ b/source4/auth/ntlm/auth_developer.c
@@ -20,9 +20,11 @@
 */
 
 #include "includes.h"
+#include <tevent.h>
 #include "auth/auth.h"
 #include "auth/ntlm/auth_proto.h"
 #include "libcli/security/security.h"
+#include "lib/util/tevent_ntstatus.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_AUTH
@@ -137,10 +139,67 @@ static NTSTATUS name_to_ntstatus_check_password(struct 
auth_method_context *ctx,
        return nt_status;
 }
 
+struct name_to_ntstatus_check_password_state {
+       struct auth_user_info_dc *user_info_dc;
+       bool authoritative;
+};
+
+static struct tevent_req *name_to_ntstatus_check_password_send(
+       TALLOC_CTX *mem_ctx,
+       struct tevent_context *ev,
+       struct auth_method_context *ctx,
+       const struct auth_usersupplied_info *user_info)
+{
+       struct tevent_req *req = NULL;
+       struct name_to_ntstatus_check_password_state *state = NULL;
+       NTSTATUS status;
+
+       req = tevent_req_create(
+               mem_ctx,
+               &state,
+               struct name_to_ntstatus_check_password_state);
+       if (req == NULL) {
+               return NULL;
+       }
+
+       status = name_to_ntstatus_check_password(
+               ctx,
+               state,
+               user_info,
+               &state->user_info_dc,
+               &state->authoritative);
+       if (tevent_req_nterror(req, status)) {
+               return tevent_req_post(req, ev);
+       }
+       tevent_req_done(req);
+       return tevent_req_post(req, ev);
+}
+
+static NTSTATUS name_to_ntstatus_check_password_recv(
+       struct tevent_req *req,
+       TALLOC_CTX *mem_ctx,
+       struct auth_user_info_dc **interim_info,
+       bool *authoritative)
+{
+       struct name_to_ntstatus_check_password_state *state = tevent_req_data(
+               req, struct name_to_ntstatus_check_password_state);
+       NTSTATUS status;
+
+       if (tevent_req_is_nterror(req, &status)) {
+               tevent_req_received(req);
+               return status;
+       }
+       *interim_info = talloc_move(mem_ctx, &state->user_info_dc);
+       *authoritative = state->authoritative;
+       tevent_req_received(req);
+       return NT_STATUS_OK;
+}
+
 static const struct auth_operations name_to_ntstatus_auth_ops = {
        .name           = "name_to_ntstatus",
        .want_check     = name_to_ntstatus_want_check,
-       .check_password = name_to_ntstatus_check_password
+       .check_password_send    = name_to_ntstatus_check_password_send,
+       .check_password_recv    = name_to_ntstatus_check_password_recv,
 };
 
 _PUBLIC_ NTSTATUS auth4_developer_init(TALLOC_CTX *ctx)
diff --git a/source4/auth/ntlm/auth_sam.c b/source4/auth/ntlm/auth_sam.c
index c5b27171937..a521bc94bc4 100644
--- a/source4/auth/ntlm/auth_sam.c
+++ b/source4/auth/ntlm/auth_sam.c
@@ -36,6 +36,7 @@
 #include "lib/messaging/irpc.h"
 #include "libcli/auth/libcli_auth.h"
 #include "libds/common/roles.h"
+#include "lib/util/tevent_ntstatus.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_AUTH
@@ -733,6 +734,68 @@ static NTSTATUS authsam_check_password_internals(struct 
auth_method_context *ctx
        return NT_STATUS_OK;
 }
 
+struct authsam_check_password_state {
+       struct auth_user_info_dc *user_info_dc;
+       bool authoritative;
+};
+
+static struct tevent_req *authsam_check_password_send(
+       TALLOC_CTX *mem_ctx,
+       struct tevent_context *ev,
+       struct auth_method_context *ctx,
+       const struct auth_usersupplied_info *user_info)
+{
+       struct tevent_req *req = NULL;
+       struct authsam_check_password_state *state = NULL;
+       NTSTATUS status;
+
+       req = tevent_req_create(
+               mem_ctx, &state, struct authsam_check_password_state);
+       if (req == NULL) {
+               return NULL;
+       }
+       /*
+        * authsam_check_password_internals() sets this to false in
+        * the rodc case, otherwise it leaves it untouched. Default to
+        * "we're authoritative".
+        */
+       state->authoritative = true;
+
+       status = authsam_check_password_internals(
+               ctx,
+               state,
+               user_info,
+               &state->user_info_dc,
+               &state->authoritative);
+       if (tevent_req_nterror(req, status)) {
+               return tevent_req_post(req, ev);
+       }
+
+       tevent_req_done(req);
+       return tevent_req_post(req, ev);
+}
+
+static NTSTATUS authsam_check_password_recv(
+       struct tevent_req *req,
+       TALLOC_CTX *mem_ctx,
+       struct auth_user_info_dc **interim_info,
+       bool *authoritative)
+{
+       struct authsam_check_password_state *state = tevent_req_data(
+               req, struct authsam_check_password_state);


-- 
Samba Shared Repository

Reply via email to