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@lists.fedorahosted.org > >https://lists.fedorahosted.org/mailman/listinfo/sssd-devel > Thanks! > From e16c0e789ecb6b5c601839bdf58e95b1b24bba2d Mon Sep 17 00:00:00 2001 > From: Pavel Reichl <prei...@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 <prei...@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 <prei...@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@lists.fedorahosted.org > https://lists.fedorahosted.org/mailman/listinfo/sssd-devel _______________________________________________ sssd-devel mailing list sssd-devel@lists.fedorahosted.org https://lists.fedorahosted.org/mailman/listinfo/sssd-devel