[SCM] Samba Shared Repository - branch master updated

Andrew Bartlett abartlet at samba.org
Fri Apr 16 10:28:01 UTC 2021


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 <philipp.gesang at intra2net.com>
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 <philipp.gesang at intra2net.com>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    
    Autobuild-User(master): Andrew Bartlett <abartlet at samba.org>
    Autobuild-Date(master): Fri Apr 16 10:27:41 UTC 2021 on sn-devel-184

commit 8ff6ad7454d9da1dff91c8b827c54008e83cc150
Author: Philipp Gesang <philipp.gesang at intra2net.com>
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 <philipp.gesang at intra2net.com>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 254af19ba89b4c42e5f45ec731e6577d2fcc6736
Author: Volker Lendecke <vl at samba.org>
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 <vl at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit f852fb4cd4e2bcd676a9ea104c5bf00979771eed
Author: Volker Lendecke <vl at samba.org>
Date:   Thu Apr 15 10:04:21 2021 +0200

    auth4: Make auth_sam pseudo-async
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit a6f42ab8a778b9863990da3112c2e868cd006303
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Apr 14 21:59:55 2021 +0200

    auth4: Make auth_unix pseudo-async
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 43a1e42815718591faa8d526319b96d089a758fa
Author: Volker Lendecke <vl at samba.org>
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 <vl at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 759573136876ef2b1b1c7484f99570d7de957e0d
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Apr 14 21:48:32 2021 +0200

    auth4: Make auth_anonymous pseudo-async
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

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

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



More information about the samba-cvs mailing list