On Tue, Feb 24, 2015 at 04:44:28PM +0100, Pavel Reichl wrote:
On 02/23/2015 11:47 AM, Sumit Bose wrote:
>On Fri, Feb 20, 2015 at 02:44:45PM +0100, Pavel Reichl wrote:
>>On 02/20/2015 02:33 PM, Lukas Slebodnik wrote:
>>>On (20/02/15 14:23), Pavel Reichl wrote:
>>>>On 02/19/2015 06:16 PM, Sumit Bose wrote:
>>>>>On Tue, Feb 17, 2015 at 10:56:43PM +0100, Pavel Reichl wrote:
>>>>>>Hello,
>>>>>>
>>>>>>please see attached patches resolving
...
>>index
9f2e9ac34add13e40d316374094024afdcc4ae31..4e3f3510250b19b5f397125fa3e3a376e0d3701f 100644
>>--- a/src/man/sssd-ldap.5.xml
>>+++ b/src/man/sssd-ldap.5.xml
>>@@ -1959,6 +1959,18 @@ ldap_access_filter = (employeeType=admin)
>> ldap_account_expire_policy
>> </para>
>> <para>
>>+ <emphasis>pwd_expire_policy</emphasis>:
>>+ This option is useful if users are interested in
>>+ seeing password expiration warning when
authenticating
>>+ using different method then passwords - for example
>>+ SSH keys.
>It's not about seeing a warning but about denying access based on an
>expired password. I think you should be more clear here.
I'm sorry I wasn'T clear either. I meant to say 'it's not only about a
warning'. So you should mention both, the user will see a warning if the
password is about to expire and will be rejected if the password is
expired as with password authentication
>
>>+ </para>
>>+ <para>
>>+ Please note that 'access_provider = ldap'
must
>>+ be set for this feature to work. Also
'ldap_pwd_policy'
>>+ must be set to appropriate password policy.
>>+ </para>
...
>>+ return ret;
>I think you have to modify the return code here to match the access
>control expectations. check_pwexpire_policy() will e.g. return
>ERR_PASSWORD_EXPIRED but the access control code expects
>ERR_ACCESS_DENIED. As a result I see the following in the logs:
In attached patch I modified sdap_access_done() instead:
static void sdap_access_done(struct tevent_req *req)
case ERR_ACCOUNT_EXPIRED:
pam_status = PAM_ACCT_EXPIRED;
break;
+ case ERR_PASSWORD_EXPIRED:
+ pam_status = PAM_PERM_DENIED;
+ break;
default:
DEBUG(SSSDBG_CRIT_FAILURE, "Error retrieving access check
result.\n");
pam_status = PAM_SYSTEM_ERR;
If you are OK with this approach would setting pam_status to
PAM_AUTHTOK_EXPIRED be more appropriate?
That's a good point and it made me re-read to original tickets again. I
was under the impression that they ask for rejecting access as well, but
it looks thy only ask for a warning. Nevertheless I think it is a good
idea to reject access and it relates a bit to #2534 as well.
Nevertheless even if we reject your comment above made me think who we
should react is the password is expired, just reject or ask for a new
password as it would have been with password authentication.
As a result I wonder if it would make sense to add 3 options:
- pwd_expire_policy_reject: will warn and reject,
pam_status = PAM_PERM_DENIED
- pwd_expire_policy_warn: will only warn,
pam_status = PAM_SUCCESS
- pwd_expire_policy_renew: will warn and ask for new password
pam_status = PAM_NEW_AUTHTOK_REQD
What do you think?
bye,
Sumit
>
>(Mon Feb 23 11:00:07 2015) [sssd[be[ipa.devel]]]
[find_password_expiration_attributes] (0x4000): Found Kerberos password expiration
attributes.
>(Mon Feb 23 11:00:07 2015) [sssd[be[ipa.devel]]] [check_pwexpire_kerberos] (0x4000):
Time info: tzname[0] [CET] tzname[1] [CEST] timezone [-3600] daylight [1] now [1424685607]
expire_time [1
>421771276].
>(Mon Feb 23 11:00:07 2015) [sssd[be[ipa.devel]]] [check_pwexpire_kerberos] (0x0100):
Kerberos password expired.
>(Mon Feb 23 11:00:07 2015) [sssd[be[ipa.devel]]] [perform_pwexpire_policy] (0x0080):
check_pwexpire_policy returned 1432158224:[Password Expired]
>.(Mon Feb 23 11:00:07 2015) [sssd[be[ipa.devel]]] [sdap_access_done] (0x0020): Error
retrieving access check result.
>(Mon Feb 23 11:00:07 2015) [sssd[be[ipa.devel]]] [be_pam_handler_callback] (0x0100):
Backend returned: (3, 4, <NULL>) [Internal Error (Systemfehler)]
>(Mon Feb 23 11:00:07 2015) [sssd[be[ipa.devel]]] [be_pam_handler_callback] (0x0100):
Sending result [4][ipa.devel]
>(Mon Feb 23 11:00:07 2015) [sssd[be[ipa.devel]]] [be_pam_handler_callback] (0x0100):
Sent result [4][ipa.devel]
>(Mon Feb 23 11:00:13 2015) [sssd[be[ipa.devel]]] [sbus_dispatch] (0x4000): dbus conn:
0xb830ff80
>(Mon Feb 23 11:00:13 2015) [sssd[be[ipa.devel]]] [sbus_dispatch] (0x4000):
Dispatching.
>
>So, access is denied, but with a generic system error.
>
>bye,
>Sumit
>_______________________________________________
>sssd-devel mailing list
>sssd-devel(a)lists.fedorahosted.org
>https://lists.fedorahosted.org/mailman/listinfo/sssd-devel
Thanks!
From e16c0e789ecb6b5c601839bdf58e95b1b24bba2d Mon Sep 17 00:00:00
2001
From: Pavel Reichl <preichl(a)redhat.com>
Date: Mon, 16 Feb 2015 18:56:25 -0500
Subject: [PATCH 1/2] SDAP: refactor pwexpire policy
Move part of pwexpire policy code to a separate function.
Relates to:
https://fedorahosted.org/sssd/ticket/2167
---
Makefile.am | 1 +
src/providers/ldap/ldap_auth.c | 76 ++++++++++++++++++++++++------------------
src/providers/ldap/ldap_auth.h | 46 +++++++++++++++++++++++++
3 files changed, 91 insertions(+), 32 deletions(-)
create mode 100644 src/providers/ldap/ldap_auth.h
diff --git a/Makefile.am b/Makefile.am
index 70278550fd22b820528f9613d30e11a723ea6c5c..35e3b39027f1163078a61a0528df2306367d6187
100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -562,6 +562,7 @@ dist_noinst_HEADERS = \
src/providers/ldap/sdap_autofs.h \
src/providers/ldap/sdap_id_op.h \
src/providers/ldap/ldap_opts.h \
+ src/providers/ldap/ldap_auth.h \
src/providers/ldap/sdap_range.h \
src/providers/ldap/sdap_users.h \
src/providers/ldap/sdap_dyndns.h \
diff --git a/src/providers/ldap/ldap_auth.c b/src/providers/ldap/ldap_auth.c
index 5a40c1359f138c42eb915e873fe21a50ab038e81..4035aaf58c23291eb8115ef320758ba7666ed4e2
100644
--- a/src/providers/ldap/ldap_auth.c
+++ b/src/providers/ldap/ldap_auth.c
@@ -46,16 +46,10 @@
#include "providers/ldap/ldap_common.h"
#include "providers/ldap/sdap_async.h"
#include "providers/ldap/sdap_async_private.h"
+#include "providers/ldap/ldap_auth.h"
#define LDAP_PWEXPIRE_WARNING_TIME 0
-enum pwexpire {
- PWEXPIRE_NONE = 0,
- PWEXPIRE_LDAP_PASSWORD_POLICY,
- PWEXPIRE_KERBEROS,
- PWEXPIRE_SHADOW
-};
-
static errno_t add_expired_warning(struct pam_data *pd, long exp_time)
{
int ret;
@@ -248,10 +242,41 @@ done:
return ret;
}
-static errno_t find_password_expiration_attributes(TALLOC_CTX *mem_ctx,
- const struct ldb_message *msg,
- struct dp_option *opts,
- enum pwexpire *type, void **data)
+errno_t check_pwexpire_policy(enum pwexpire pw_expire_type,
+ void *pw_expire_data,
+ struct pam_data *pd,
+ int pwd_expiration_warning)
+{
+ errno_t ret;
+
+ switch (pw_expire_type) {
+ case PWEXPIRE_SHADOW:
+ ret = check_pwexpire_shadow(pw_expire_data, time(NULL), pd);
+ break;
+ case PWEXPIRE_KERBEROS:
+ ret = check_pwexpire_kerberos(pw_expire_data, time(NULL), pd,
+ pwd_expiration_warning);
+ break;
+ case PWEXPIRE_LDAP_PASSWORD_POLICY:
+ ret = check_pwexpire_ldap(pd, pw_expire_data,
+ pwd_expiration_warning);
+ break;
+ case PWEXPIRE_NONE:
+ ret = EOK;
+ break;
+ default:
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unknown password expiration type.\n");
+ ret = EINVAL;
+ }
+
+ return ret;
+}
+
+static errno_t
+find_password_expiration_attributes(TALLOC_CTX *mem_ctx,
+ const struct ldb_message *msg,
+ struct dp_option *opts,
+ enum pwexpire *type, void **data)
{
const char *mark;
const char *val;
@@ -492,7 +517,7 @@ static int get_user_dn_recv(TALLOC_CTX *mem_ctx, struct tevent_req
*req,
return EOK;
}
-static int get_user_dn(TALLOC_CTX *memctx,
+int get_user_dn(TALLOC_CTX *memctx,
struct sss_domain_info *domain,
struct sdap_options *opts,
const char *username,
@@ -998,7 +1023,7 @@ static void sdap_auth4chpass_done(struct tevent_req *req)
case PWEXPIRE_NONE:
break;
default:
- DEBUG(SSSDBG_CRIT_FAILURE, "Unknow pasword expiration type.\n");
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unknown password expiration
type.\n");
state->pd->pam_status = PAM_SYSTEM_ERR;
goto done;
}
@@ -1247,25 +1272,12 @@ static void sdap_pam_auth_done(struct tevent_req *req)
talloc_zfree(req);
if (ret == EOK) {
- switch (pw_expire_type) {
- case PWEXPIRE_SHADOW:
- ret = check_pwexpire_shadow(pw_expire_data, time(NULL), state->pd);
- break;
- case PWEXPIRE_KERBEROS:
- ret = check_pwexpire_kerberos(pw_expire_data, time(NULL),
- state->pd,
-
be_ctx->domain->pwd_expiration_warning);
- break;
- case PWEXPIRE_LDAP_PASSWORD_POLICY:
- ret = check_pwexpire_ldap(state->pd, pw_expire_data,
- be_ctx->domain->pwd_expiration_warning);
- break;
- case PWEXPIRE_NONE:
- break;
- default:
- DEBUG(SSSDBG_CRIT_FAILURE, "Unknow pasword expiration type.\n");
- state->pd->pam_status = PAM_SYSTEM_ERR;
- goto done;
+ ret = check_pwexpire_policy(pw_expire_type, pw_expire_data, state->pd,
+ be_ctx->domain->pwd_expiration_warning);
+ if (ret == EINVAL) {
+ /* Unknown password expiration type. */
+ state->pd->pam_status = PAM_SYSTEM_ERR;
+ goto done;
}
}
diff --git a/src/providers/ldap/ldap_auth.h b/src/providers/ldap/ldap_auth.h
new file mode 100644
index 0000000000000000000000000000000000000000..5fbddd7087dc65ab8bd1df5fb57492d2fc26d0bb
--- /dev/null
+++ b/src/providers/ldap/ldap_auth.h
@@ -0,0 +1,46 @@
+/*
+ SSSD
+
+ Copyright (C) Pavel Reichl <preichl(a)redhat.com> 2015
+
+ 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/>.
+*/
+
+#ifndef _LDAP_AUTH_H_
+#define _LDAP_AUTH_H_
+
+#include "config.h"
+
+enum pwexpire {
+ PWEXPIRE_NONE = 0,
+ PWEXPIRE_LDAP_PASSWORD_POLICY,
+ PWEXPIRE_KERBEROS,
+ PWEXPIRE_SHADOW
+};
+
+int get_user_dn(TALLOC_CTX *memctx,
+ struct sss_domain_info *domain,
+ struct sdap_options *opts,
+ const char *username,
+ char **user_dn,
+ enum pwexpire *user_pw_expire_type,
+ void **user_pw_expire_data);
+
+errno_t check_pwexpire_policy(enum pwexpire pw_expire_type,
+ void *pw_expire_data,
+ struct pam_data *pd,
+ errno_t checkb);
+
+
+#endif /* _LDAP_AUTH_H_ */
--
2.1.0
From b9fb0b1c204b6b448e88b5d9fd0dbe2cee7469fa Mon Sep 17 00:00:00
2001
From: Pavel Reichl <preichl(a)redhat.com>
Date: Wed, 18 Feb 2015 01:03:40 -0500
Subject: [PATCH 2/2] SDAP: enable change phase of pw expire policy check
Implement new option which does checking password expiration policy
in accounting phase.
This allows SSSD to issue shadow expiration warning even if alternate
authentication method is used.
Resolves:
https://fedorahosted.org/sssd/ticket/2167
---
src/man/sssd-ldap.5.xml | 12 +++++++++++
src/providers/ldap/ldap_access.c | 3 +++
src/providers/ldap/ldap_auth.c | 1 +
src/providers/ldap/ldap_init.c | 3 +++
src/providers/ldap/sdap_access.c | 43 +++++++++++++++++++++++++++++++++++++++-
src/providers/ldap/sdap_access.h | 2 ++
6 files changed, 63 insertions(+), 1 deletion(-)
diff --git a/src/man/sssd-ldap.5.xml b/src/man/sssd-ldap.5.xml
index 9f2e9ac34add13e40d316374094024afdcc4ae31..78136b675003c51454cffc6988c698ca683d9509
100644
--- a/src/man/sssd-ldap.5.xml
+++ b/src/man/sssd-ldap.5.xml
@@ -1959,6 +1959,18 @@ ldap_access_filter = (employeeType=admin)
ldap_account_expire_policy
</para>
<para>
+ <emphasis>pwd_expire_policy</emphasis>:
+ This option is useful if users are interested in
+ denying access in case that password is expired and
+ authentication is based on using different method then
+ passwords - for example SSH keys.
+ </para>
+ <para>
+ Please note that 'access_provider = ldap' must
+ be set for this feature to work. Also
'ldap_pwd_policy'
+ must be set to appropriate password policy.
+ </para>
+ <para>
<emphasis>authorized_service</emphasis>: use
the authorizedService attribute to determine
access
diff --git a/src/providers/ldap/ldap_access.c b/src/providers/ldap/ldap_access.c
index 1913cd9a92342cc985d5c098f224c4fe8c58d465..958b89b020a727be3bbee428cf786d54af48298e
100644
--- a/src/providers/ldap/ldap_access.c
+++ b/src/providers/ldap/ldap_access.c
@@ -96,6 +96,9 @@ static void sdap_access_done(struct tevent_req *req)
case ERR_ACCOUNT_EXPIRED:
pam_status = PAM_ACCT_EXPIRED;
break;
+ case ERR_PASSWORD_EXPIRED:
+ pam_status = PAM_PERM_DENIED;
+ break;
default:
DEBUG(SSSDBG_CRIT_FAILURE, "Error retrieving access check
result.\n");
pam_status = PAM_SYSTEM_ERR;
diff --git a/src/providers/ldap/ldap_auth.c b/src/providers/ldap/ldap_auth.c
index 4035aaf58c23291eb8115ef320758ba7666ed4e2..bdcc4505dc82cf3ca4bec9ce71ec6a9c28dd54e8
100644
--- a/src/providers/ldap/ldap_auth.c
+++ b/src/providers/ldap/ldap_auth.c
@@ -47,6 +47,7 @@
#include "providers/ldap/sdap_async.h"
#include "providers/ldap/sdap_async_private.h"
#include "providers/ldap/ldap_auth.h"
+#include "providers/ldap/sdap_access.h"
#define LDAP_PWEXPIRE_WARNING_TIME 0
diff --git a/src/providers/ldap/ldap_init.c b/src/providers/ldap/ldap_init.c
index 44333a9a3a45de16aaaf83fecaea4817cebc90d4..3b8db83300c43e5e5397cdf0c880a1d82effb4c2
100644
--- a/src/providers/ldap/ldap_init.c
+++ b/src/providers/ldap/ldap_init.c
@@ -423,6 +423,9 @@ int sssm_ldap_access_init(struct be_ctx *bectx,
access_ctx->access_rule[c] = LDAP_ACCESS_HOST;
} else if (strcasecmp(order_list[c], LDAP_ACCESS_LOCK_NAME) == 0) {
access_ctx->access_rule[c] = LDAP_ACCESS_LOCKOUT;
+ } else if (strcasecmp(order_list[c],
+ LDAP_ACCESS_EXPIRE_POLICY_NAME) == 0) {
+ access_ctx->access_rule[c] = LDAP_ACCESS_EXPIRE_POLICY;
} else {
DEBUG(SSSDBG_CRIT_FAILURE,
"Unexpected access rule name [%s].\n", order_list[c]);
diff --git a/src/providers/ldap/sdap_access.c b/src/providers/ldap/sdap_access.c
index a6c882cae634f080b200fe75f51867e39192bcd9..b38b958f27c7ca8d463e789f14c96b5b2f11ad77
100644
--- a/src/providers/ldap/sdap_access.c
+++ b/src/providers/ldap/sdap_access.c
@@ -39,10 +39,16 @@
#include "providers/ldap/sdap_async.h"
#include "providers/data_provider.h"
#include "providers/dp_backend.h"
+#include "providers/ldap/ldap_auth.h"
#define PERMANENTLY_LOCKED_ACCOUNT "000001010000Z"
#define MALFORMED_FILTER "Malformed access control filter [%s]\n"
+static errno_t perform_pwexpire_policy(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *domain,
+ struct pam_data *pd,
+ struct sdap_options *opts);
+
static errno_t sdap_save_user_cache_bool(struct sss_domain_info *domain,
const char *username,
const char *attr_name,
@@ -237,6 +243,11 @@ static errno_t sdap_access_check_next_rule(struct
sdap_access_req_ctx *state,
state->pd, state->user_entry);
break;
+ case LDAP_ACCESS_EXPIRE_POLICY:
+ ret = perform_pwexpire_policy(state, state->domain, state->pd,
+ state->access_ctx->id_ctx->opts);
+ break;
+
case LDAP_ACCESS_SERVICE:
ret = sdap_access_service( state->pd, state->user_entry);
break;
@@ -651,7 +662,6 @@ static errno_t sdap_account_expired_nds(struct pam_data *pd,
return EOK;
}
-
static errno_t sdap_account_expired(struct sdap_access_ctx *access_ctx,
struct pam_data *pd,
struct ldb_message *user_entry)
@@ -702,6 +712,37 @@ static errno_t sdap_account_expired(struct sdap_access_ctx
*access_ctx,
return ret;
}
+static errno_t perform_pwexpire_policy(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *domain,
+ struct pam_data *pd,
+ struct sdap_options *opts)
+{
+ enum pwexpire pw_expire_type;
+ void *pw_expire_data;
+ errno_t ret;
+ char *dn;
+
+ ret = get_user_dn(mem_ctx, domain, opts, pd->user, &dn, &pw_expire_type,
+ &pw_expire_data);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_MINOR_FAILURE, "get_user_dn returned %d:[%s].\n",
+ ret, sss_strerror(ret));
+ goto done;
+ }
+
+ ret = check_pwexpire_policy(pw_expire_type, pw_expire_data, pd,
+ domain->pwd_expiration_warning);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ "check_pwexpire_policy returned %d:[%s].\n",
+ ret, sss_strerror(ret));
+ goto done;
+ }
+
+done:
+ return ret;
+}
+
struct sdap_access_filter_req_ctx {
const char *username;
const char *filter;
diff --git a/src/providers/ldap/sdap_access.h b/src/providers/ldap/sdap_access.h
index f085e619961198b887d65ed5ee0bc5cdd90d1b20..825fcffbc5fcd9413c9aa0dd79a8b87bd57d4dbc
100644
--- a/src/providers/ldap/sdap_access.h
+++ b/src/providers/ldap/sdap_access.h
@@ -39,6 +39,7 @@
#define LDAP_ACCESS_FILTER_NAME "filter"
#define LDAP_ACCESS_EXPIRE_NAME "expire"
+#define LDAP_ACCESS_EXPIRE_POLICY_NAME "pwd_expire_policy"
#define LDAP_ACCESS_SERVICE_NAME "authorized_service"
#define LDAP_ACCESS_HOST_NAME "host"
#define LDAP_ACCESS_LOCK_NAME "lockout"
@@ -57,6 +58,7 @@ enum ldap_access_rule {
LDAP_ACCESS_SERVICE,
LDAP_ACCESS_HOST,
LDAP_ACCESS_LOCKOUT,
+ LDAP_ACCESS_EXPIRE_POLICY,
LDAP_ACCESS_LAST
};
--
2.1.0
_______________________________________________
sssd-devel mailing list
sssd-devel(a)lists.fedorahosted.org
https://lists.fedorahosted.org/mailman/listinfo/sssd-devel