[Patches] export SAMBA_CPS_{ACCOUNT, USER_PRINCIPAL, FULL}_NAME to check password script
Stefan Metzmacher
metze at samba.org
Sat Feb 9 21:51:53 UTC 2019
Am 07.02.19 um 10:24 schrieb Stefan Metzmacher via samba-technical:
> Am 06.02.19 um 21:37 schrieb Stefan Metzmacher via samba-technical:
>> Hi,
>>
>> when the check password script is executed in the AD DC it won't get any
>> information of the user and only the new password on stdin.
>>
>> In the NT4 DC is may get '%u' substituted with the account name.
>>
>> As the check password script is executed with /bin/sh -c
>> and on the AD DC also as root (without substituting %u),
>> Andrew asked to avoid adding %u.
>>
>> The easiest solution (that won't break existing setups)
>> we come up with is to export environment variables:
>> SAMBA_CPS_ACCOUNT_NAME (always)
>> SAMBA_CPS_USER_PRINCIPAL_NAME (if available)
>> SAMBA_CPS_FULL_NAME (if available)
>>
>> As a side effect this patchset also fixes the check password script
>> tests on FreeBSD (with less 'sed' features).
>>
>> Please review and push:-)
>>
>> See https://gitlab.com/samba-team/samba/merge_requests/203
>
> I just realized that I better check the return value of the
> setenv() calls, I'll upload a new patchset soon.
Here's the updated patchset.
Please review and push:-)
Thanks!
metze
-------------- next part --------------
From 0d36971fcf7b4bf96ab4b3549855aa2fcec72dee Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Tue, 5 Feb 2019 15:30:36 +0100
Subject: [PATCH 1/6] selftest: make check password script more portable
We should not rely on Linux specific sed options.
grep -q also works on FreeBSD (tested on FreeBSD 12).
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
selftest/checkpassword_arg1.sh | 15 +++++++++++++++
selftest/target/Samba4.pm | 2 +-
2 files changed, 16 insertions(+), 1 deletion(-)
create mode 100755 selftest/checkpassword_arg1.sh
diff --git a/selftest/checkpassword_arg1.sh b/selftest/checkpassword_arg1.sh
new file mode 100755
index 000000000000..9cb28ef198cf
--- /dev/null
+++ b/selftest/checkpassword_arg1.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+#
+
+set -e
+set -u
+
+INVALIDPW="$1"
+NEWPW=`cat -`
+
+echo -n "${NEWPW}" | grep -q "^${INVALIDPW}\$" && {
+ echo "Found invalid password" >&1
+ exit 1
+}
+
+exit 0
diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm
index 33c66848c562..d8e066f6f447 100755
--- a/selftest/target/Samba4.pm
+++ b/selftest/target/Samba4.pm
@@ -2173,7 +2173,7 @@ sub provision_chgdcpass($$)
# (and also removes the default AD complexity checks)
my $unacceptable_password = "widk3Dsle32jxdBdskldsk55klASKQ";
my $extra_smb_conf = "
- check password script = sed -e '/$unacceptable_password/{;q1}; /$unacceptable_password/!{q0}'
+ check password script = $self->{srcdir}/selftest/checkpassword_arg1.sh ${unacceptable_password}
allow dcerpc auth level connect:lsarpc = yes
dcesrv:max auth states = 8
";
--
2.17.1
From 7ac8421db65b861de928eef04e9f76cc859312ac Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Tue, 22 Jan 2019 10:31:52 +0100
Subject: [PATCH 2/6] tests/user_check_password_script: add a test do disallow
the username as password
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
.../samba_tool/user_check_password_script.py | 34 ++++++++++++++-----
selftest/checkpassword_arg1.sh | 6 ++++
.../knownfail.d/user_check_password_script | 1 +
3 files changed, 32 insertions(+), 9 deletions(-)
create mode 100644 selftest/knownfail.d/user_check_password_script
diff --git a/python/samba/tests/samba_tool/user_check_password_script.py b/python/samba/tests/samba_tool/user_check_password_script.py
index aaf791aff9ef..06afbade6bd5 100644
--- a/python/samba/tests/samba_tool/user_check_password_script.py
+++ b/python/samba/tests/samba_tool/user_check_password_script.py
@@ -42,20 +42,16 @@ class UserCheckPwdTestCase(SambaToolCmdTest):
super(UserCheckPwdTestCase, self).tearDown()
self.samdb.set_minPwdAge(self.old_min_pwd_age)
- def test_checkpassword(self):
- # Add
- user = self._randomUser()
- bad_password = os.environ["UNACCEPTABLE_PASSWORD"]
- good_password = bad_password[:-1]
+ def _test_checkpassword(self, user, bad_password, good_password, desc):
(result, out, err) = self.runsubcmd("user", "add", user["name"], bad_password,
"-H", "ldap://%s" % os.environ["DC_SERVER"],
"-U%s%%%s" % (os.environ["DC_USERNAME"], os.environ["DC_PASSWORD"]))
- self.assertCmdFail(result, "Should fail adding a user with bad password.")
+ self.assertCmdFail(result, "Should fail adding a user with %s password." % desc)
(result, out, err) = self.runsubcmd("user", "delete", user["name"],
"-H", "ldap://%s" % os.environ["DC_SERVER"],
"-U%s%%%s" % (os.environ["DC_USERNAME"], os.environ["DC_PASSWORD"]))
- self.assertCmdSuccess(result, out, err, "Should delete user with bad password.")
+ self.assertCmdSuccess(result, out, err, "Should delete user with %s password." % desc)
(result, out, err) = self.runsubcmd("user", "add", user["name"], good_password,
"-H", "ldap://%s" % os.environ["DC_SERVER"],
@@ -67,7 +63,7 @@ class UserCheckPwdTestCase(SambaToolCmdTest):
"--newpassword=%s" % bad_password,
"-H", "ldap://%s" % os.environ["DC_SERVER"],
"-U%s%%%s" % (os.environ["DC_USERNAME"], os.environ["DC_PASSWORD"]))
- self.assertCmdFail(result, "Should fail setting a user's password to a bad one.")
+ self.assertCmdFail(result, "Should fail setting a user's password to a %s password." % desc)
(result, out, err) = self.runsubcmd("user", "setpassword", user["name"],
"--newpassword=%s" % good_password,
@@ -81,7 +77,7 @@ class UserCheckPwdTestCase(SambaToolCmdTest):
"--newpassword=%s" % bad_password,
"--ipaddress", os.environ["DC_SERVER_IP"],
"-U%s%%%s" % (user["name"], good_password))
- self.assertCmdFail(result, "A user setting their own password to a bad one should fail.")
+ self.assertCmdFail(result, "A user setting their own password to a %s password should fail." % desc)
(result, out, err) = self.runsubcmd("user", "password",
"--newpassword=%s" % good_password + 'XYZ',
@@ -89,6 +85,26 @@ class UserCheckPwdTestCase(SambaToolCmdTest):
"-U%s%%%s" % (user["name"], good_password))
self.assertCmdSuccess(result, out, err, "A user setting their own password to a good one should succeed.")
+ def test_checkpassword_unacceptable(self):
+ # Add
+ user = self._randomUser()
+ bad_password = os.environ["UNACCEPTABLE_PASSWORD"]
+ good_password = bad_password[:-1]
+ return self._test_checkpassword(user,
+ bad_password,
+ good_password,
+ "unacceptable")
+
+ def test_checkpassword_username(self):
+ # Add
+ user = self._randomUser()
+ bad_password = user["name"]
+ good_password = bad_password[:-1]
+ return self._test_checkpassword(user,
+ bad_password,
+ good_password,
+ "username")
+
def _randomUser(self, base={}):
"""create a user with random attribute values, you can specify base attributes"""
user = {
diff --git a/selftest/checkpassword_arg1.sh b/selftest/checkpassword_arg1.sh
index 9cb28ef198cf..8bb2aad972b1 100755
--- a/selftest/checkpassword_arg1.sh
+++ b/selftest/checkpassword_arg1.sh
@@ -4,6 +4,7 @@
set -e
set -u
+ACCOUNT_NAME="${SAMBA_CPS_ACCOUNT_NAME-}"
INVALIDPW="$1"
NEWPW=`cat -`
@@ -12,4 +13,9 @@ echo -n "${NEWPW}" | grep -q "^${INVALIDPW}\$" && {
exit 1
}
+echo -n "${NEWPW}" | grep -q "^${ACCOUNT_NAME}\$" && {
+ echo "Password includes ACCOUNT_NAME" >&1
+ exit 1
+}
+
exit 0
diff --git a/selftest/knownfail.d/user_check_password_script b/selftest/knownfail.d/user_check_password_script
new file mode 100644
index 000000000000..7d6e0823a651
--- /dev/null
+++ b/selftest/knownfail.d/user_check_password_script
@@ -0,0 +1 @@
+^samba.tests.samba_tool.user_check_password_script.*samba.tests.samba_tool.user_check_password_script.UserCheckPwdTestCase.test_checkpassword_username
--
2.17.1
From b42dbd23638ba6618cd11e264ad8c0be5d282918 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Tue, 22 Jan 2019 11:33:23 +0100
Subject: [PATCH 3/6] s4:dsdb:util: export
SAMBA_CPS_{ACCOUNT,USER_PRINCIPAL,FULL}_NAME for check password script
This allows the check password script to reject the username and other
things.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
.../knownfail.d/user_check_password_script | 1 -
source4/dsdb/common/util.c | 34 +++++++++++++++++++
.../dsdb/samdb/ldb_modules/password_hash.c | 7 ++++
source4/rpc_server/samr/dcesrv_samr.c | 9 +++++
4 files changed, 50 insertions(+), 1 deletion(-)
delete mode 100644 selftest/knownfail.d/user_check_password_script
diff --git a/selftest/knownfail.d/user_check_password_script b/selftest/knownfail.d/user_check_password_script
deleted file mode 100644
index 7d6e0823a651..000000000000
--- a/selftest/knownfail.d/user_check_password_script
+++ /dev/null
@@ -1 +0,0 @@
-^samba.tests.samba_tool.user_check_password_script.*samba.tests.samba_tool.user_check_password_script.UserCheckPwdTestCase.test_checkpassword_username
diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c
index 3ac21d0e43ce..45f0ffc83552 100644
--- a/source4/dsdb/common/util.c
+++ b/source4/dsdb/common/util.c
@@ -2083,6 +2083,9 @@ static void pwd_timeout_debug(struct tevent_context *unused1,
*/
enum samr_ValidationStatus samdb_check_password(TALLOC_CTX *mem_ctx,
struct loadparm_context *lp_ctx,
+ const char *account_name,
+ const char *user_principal_name,
+ const char *full_name,
const DATA_BLOB *utf8_blob,
const uint32_t pwdProperties,
const uint32_t minPwdLength)
@@ -2129,9 +2132,40 @@ enum samr_ValidationStatus samdb_check_password(TALLOC_CTX *mem_ctx,
tevent_timeval_current_ofs(1, 0),
pwd_timeout_debug, NULL);
+ check_ret = setenv("SAMBA_CPS_ACCOUNT_NAME", account_name, 1);
+ if (check_ret != 0) {
+ TALLOC_FREE(password_script);
+ TALLOC_FREE(event_ctx);
+ return SAMR_VALIDATION_STATUS_PASSWORD_FILTER_ERROR;
+ }
+ if (user_principal_name != NULL) {
+ check_ret = setenv("SAMBA_CPS_USER_PRINCIPAL_NAME",
+ user_principal_name, 1);
+ } else {
+ unsetenv("SAMBA_CPS_USER_PRINCIPAL_NAME");
+ }
+ if (check_ret != 0) {
+ TALLOC_FREE(password_script);
+ TALLOC_FREE(event_ctx);
+ return SAMR_VALIDATION_STATUS_PASSWORD_FILTER_ERROR;
+ }
+ if (full_name != NULL) {
+ check_ret = setenv("SAMBA_CPS_FULL_NAME", full_name, 1);
+ } else {
+ unsetenv("SAMBA_CPS_FULL_NAME");
+ }
+ if (check_ret != 0) {
+ TALLOC_FREE(password_script);
+ TALLOC_FREE(event_ctx);
+ return SAMR_VALIDATION_STATUS_PASSWORD_FILTER_ERROR;
+ }
+
req = samba_runcmd_send(event_ctx, event_ctx,
tevent_timeval_current_ofs(10, 0),
100, 100, cmd, NULL);
+ unsetenv("SAMBA_CPS_ACCOUNT_NAME");
+ unsetenv("SAMBA_CPS_USER_PRINCIPAL_NAME");
+ unsetenv("SAMBA_CPS_FULL_NAME");
if (req == NULL) {
TALLOC_FREE(password_script);
TALLOC_FREE(event_ctx);
diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c
index 5f5710330044..51fd70b7c1db 100644
--- a/source4/dsdb/samdb/ldb_modules/password_hash.c
+++ b/source4/dsdb/samdb/ldb_modules/password_hash.c
@@ -130,6 +130,7 @@ struct setup_password_fields_io {
NTTIME pwdLastSet;
const char *sAMAccountName;
const char *user_principal_name;
+ const char *displayName; /* full name */
bool is_krbtgt;
uint32_t restrictions;
struct dom_sid *account_sid;
@@ -2716,6 +2717,9 @@ static int check_password_restrictions(struct setup_password_fields_io *io, WERR
if (io->n.cleartext_utf8 != NULL) {
enum samr_ValidationStatus vstat;
vstat = samdb_check_password(io->ac, lp_ctx,
+ io->u.sAMAccountName,
+ io->u.user_principal_name,
+ io->u.displayName,
io->n.cleartext_utf8,
io->ac->status->domain_data.pwdProperties,
io->ac->status->domain_data.minPwdLength);
@@ -3191,6 +3195,8 @@ static int setup_io(struct ph_context *ac,
"sAMAccountName", NULL);
io->u.user_principal_name = ldb_msg_find_attr_as_string(info_msg,
"userPrincipalName", NULL);
+ io->u.displayName = ldb_msg_find_attr_as_string(info_msg,
+ "displayName", NULL);
/* Ensure it has an objectSID too */
io->u.account_sid = samdb_result_dom_sid(ac, info_msg, "objectSid");
@@ -4707,6 +4713,7 @@ static int password_hash_mod_search_self(struct ph_context *ac)
"sAMAccountName",
"objectSid",
"userPrincipalName",
+ "displayName",
"supplementalCredentials",
"lmPwdHistory",
"ntPwdHistory",
diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c
index 51fed4da62b3..84400284f42c 100644
--- a/source4/rpc_server/samr/dcesrv_samr.c
+++ b/source4/rpc_server/samr/dcesrv_samr.c
@@ -4871,6 +4871,7 @@ static NTSTATUS dcesrv_samr_ValidatePassword(struct dcesrv_call_state *dce_call,
{
struct samr_GetDomPwInfo r2;
struct samr_PwInfo pwInfo;
+ const char *account = NULL;
DATA_BLOB password;
enum samr_ValidationStatus res;
NTSTATUS status;
@@ -4905,20 +4906,28 @@ static NTSTATUS dcesrv_samr_ValidatePassword(struct dcesrv_call_state *dce_call,
return NT_STATUS_NOT_SUPPORTED;
break;
case NetValidatePasswordChange:
+ account = r->in.req->req2.account.string;
password = data_blob_const(r->in.req->req2.password.string,
r->in.req->req2.password.length);
res = samdb_check_password(mem_ctx,
dce_call->conn->dce_ctx->lp_ctx,
+ account,
+ NULL, /* userPrincipalName */
+ NULL, /* displayName/full_name */
&password,
pwInfo.password_properties,
pwInfo.min_password_length);
(*r->out.rep)->ctr2.status = res;
break;
case NetValidatePasswordReset:
+ account = r->in.req->req3.account.string;
password = data_blob_const(r->in.req->req3.password.string,
r->in.req->req3.password.length);
res = samdb_check_password(mem_ctx,
dce_call->conn->dce_ctx->lp_ctx,
+ account,
+ NULL, /* userPrincipalName */
+ NULL, /* displayName/full_name */
&password,
pwInfo.password_properties,
pwInfo.min_password_length);
--
2.17.1
From 004e9d76d23112b4158451a6a7b511cbd530e8dd Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Tue, 5 Feb 2019 16:15:15 +0100
Subject: [PATCH 4/6] selftest: require SAMBA_CPS_ACCOUNT_NAME in
checkpassword_arg1.sh
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
selftest/checkpassword_arg1.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/selftest/checkpassword_arg1.sh b/selftest/checkpassword_arg1.sh
index 8bb2aad972b1..42e1b5e7df5a 100755
--- a/selftest/checkpassword_arg1.sh
+++ b/selftest/checkpassword_arg1.sh
@@ -4,7 +4,7 @@
set -e
set -u
-ACCOUNT_NAME="${SAMBA_CPS_ACCOUNT_NAME-}"
+ACCOUNT_NAME="${SAMBA_CPS_ACCOUNT_NAME}"
INVALIDPW="$1"
NEWPW=`cat -`
--
2.17.1
From 6f9783ba77e09955773857fee520a796aed430fe Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Sat, 2 Feb 2019 13:19:31 +0100
Subject: [PATCH 5/6] s3:srv_samr_chgpasswd: export
SAMBA_CPS_{ACCOUNT,USER_PRINCIPAL,FULL}_NAME for check password script
This is keep compatibility with the AD DC usage.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
source3/rpc_server/samr/srv_samr_chgpasswd.c | 23 +++++++++++++++++++-
source3/rpc_server/samr/srv_samr_nt.c | 2 ++
source3/rpc_server/samr/srv_samr_util.h | 1 +
3 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/source3/rpc_server/samr/srv_samr_chgpasswd.c b/source3/rpc_server/samr/srv_samr_chgpasswd.c
index 87a3f32ff134..3749edbb0445 100644
--- a/source3/rpc_server/samr/srv_samr_chgpasswd.c
+++ b/source3/rpc_server/samr/srv_samr_chgpasswd.c
@@ -941,6 +941,7 @@ static bool check_passwd_history(struct samu *sampass, const char *plaintext)
************************************************************/
NTSTATUS check_password_complexity(const char *username,
+ const char *fullname,
const char *password,
enum samPwdChangeReason *samr_reject_reason)
{
@@ -960,7 +961,23 @@ NTSTATUS check_password_complexity(const char *username,
return NT_STATUS_PASSWORD_RESTRICTION;
}
+ check_ret = setenv("SAMBA_CPS_ACCOUNT_NAME", username, 1);
+ if (check_ret != 0) {
+ return map_nt_error_from_unix_common(errno);
+ }
+ unsetenv("SAMBA_CPS_USER_PRINCIPAL_NAME");
+ if (fullname != NULL) {
+ check_ret = setenv("SAMBA_CPS_FULL_NAME", fullname, 1);
+ } else {
+ unsetenv("SAMBA_CPS_FULL_NAME");
+ }
+ if (check_ret != 0) {
+ return map_nt_error_from_unix_common(errno);
+ }
check_ret = smbrunsecret(cmd, password);
+ unsetenv("SAMBA_CPS_ACCOUNT_NAME");
+ unsetenv("SAMBA_CPS_USER_PRINCIPAL_NAME");
+ unsetenv("SAMBA_CPS_FULL_NAME");
DEBUG(5,("check_password_complexity: check password script (%s) "
"returned [%d]\n", cmd, check_ret));
TALLOC_FREE(cmd);
@@ -995,6 +1012,7 @@ static NTSTATUS change_oem_password(struct samu *hnd, const char *rhost,
TALLOC_CTX *tosctx = talloc_tos();
struct passwd *pass = NULL;
const char *username = pdb_get_username(hnd);
+ const char *fullname = pdb_get_fullname(hnd);
time_t can_change_time = pdb_get_pass_can_change_time(hnd);
NTSTATUS status;
@@ -1062,7 +1080,10 @@ static NTSTATUS change_oem_password(struct samu *hnd, const char *rhost,
return NT_STATUS_ACCESS_DENIED;
}
- status = check_password_complexity(username, new_passwd, samr_reject_reason);
+ status = check_password_complexity(username,
+ fullname,
+ new_passwd,
+ samr_reject_reason);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(pass);
return status;
diff --git a/source3/rpc_server/samr/srv_samr_nt.c b/source3/rpc_server/samr/srv_samr_nt.c
index 70a2efa4ca63..124d6d38cd70 100644
--- a/source3/rpc_server/samr/srv_samr_nt.c
+++ b/source3/rpc_server/samr/srv_samr_nt.c
@@ -6725,6 +6725,7 @@ static enum samr_ValidationStatus samr_ValidatePassword_Change(TALLOC_CTX *mem_c
}
if (dom_pw_info->password_properties & DOMAIN_PASSWORD_COMPLEX) {
status = check_password_complexity(req->account.string,
+ NULL, /* full_name */
req->password.string,
NULL);
if (!NT_STATUS_IS_OK(status)) {
@@ -6755,6 +6756,7 @@ static enum samr_ValidationStatus samr_ValidatePassword_Reset(TALLOC_CTX *mem_ct
}
if (dom_pw_info->password_properties & DOMAIN_PASSWORD_COMPLEX) {
status = check_password_complexity(req->account.string,
+ NULL, /* full_name */
req->password.string,
NULL);
if (!NT_STATUS_IS_OK(status)) {
diff --git a/source3/rpc_server/samr/srv_samr_util.h b/source3/rpc_server/samr/srv_samr_util.h
index f992e2b90826..c0c4808f330e 100644
--- a/source3/rpc_server/samr/srv_samr_util.h
+++ b/source3/rpc_server/samr/srv_samr_util.h
@@ -75,5 +75,6 @@ NTSTATUS pass_oem_change(char *user, const char *rhost,
const uchar old_nt_hash_encrypted[16],
enum samPwdChangeReason *reject_reason);
NTSTATUS check_password_complexity(const char *username,
+ const char *fullname,
const char *password,
enum samPwdChangeReason *samr_reject_reason);
--
2.17.1
From c8864004ecf311b58ad6661307a0b87a02233769 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Mon, 4 Feb 2019 15:40:16 +0100
Subject: [PATCH 6/6] docs-xml/smbdotconf: document export of
SAMBA_CPS_{ACCOUNT,USER_PRINCIPAL,FULL}_NAME for check password script
Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
.../smbdotconf/security/checkpasswordscript.xml | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/docs-xml/smbdotconf/security/checkpasswordscript.xml b/docs-xml/smbdotconf/security/checkpasswordscript.xml
index 54f1096802b9..1e9031fda42b 100644
--- a/docs-xml/smbdotconf/security/checkpasswordscript.xml
+++ b/docs-xml/smbdotconf/security/checkpasswordscript.xml
@@ -15,6 +15,23 @@
<citerefentry><refentrytitle>samba</refentrytitle> <manvolnum>8</manvolnum>
</citerefentry> without any substitutions.</para>
+ <para>Note that starting with Samba 4.11 the following environment variables are exported to the script:</para>
+
+ <itemizedlist>
+ <listitem><para>
+ SAMBA_CPS_ACCOUNT_NAME is always present and contains the sAMAccountName of user,
+ the is the same as the %u substitutions in the none AD DC case.
+ </para></listitem>
+
+ <listitem><para>
+ SAMBA_CPS_USER_PRINCIPAL_NAME is optional in the AD DC case if the userPrincipalName is present.
+ </para></listitem>
+
+ <listitem><para>
+ SAMBA_CPS_FULL_NAME is optional if the displayName is present.
+ </para></listitem>
+ </itemizedlist>
+
<para>Note: In the example directory is a sample program called <command moreinfo="none">crackcheck</command>
that uses cracklib to check the password quality.</para>
--
2.17.1
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
URL: <http://lists.samba.org/pipermail/samba-technical/attachments/20190209/742fcc5a/signature.sig>
More information about the samba-technical
mailing list