[INI] Patches for ding-libs: Merging config sections, handling metadata, remaining Coverity issues...
by Dmitri Pal
Please see the attached patches. I tried to split the patches logically
into manageable sets.
Unfortunately I made a minor mistake and I am afraid I will do something
wrong to fix it.
I merged two wrong patches. Fortunately it was three liner with 1 liner
so it is not a big of the deal but I am really scared that I will do
something wrong and loose the work I have done.
So I hope it is Ok to send it as is.
0001--INI-Making-Coverity-happy.patch <- this is the patch I submitted
earlier that I merged by mistake. I was supposed to merge it with patch
25 but picked the wrong one instead.
Patch 25 addresses the real issue found by Coverity as mentioned in
Stephen's review mail but it did not apply cleanly since it relies on
some code from the patches in the middle.
0002--INI-Adding-missing-function-declararion.patch <- this is the
patch that was rejected from the second set sent earlier. Fixed
according to review comment.
0003--BUILD-Allow-trace-per-component.patch <- This patch allows tracing
per component
The following set of patches introduces the merging of sections during
the reading of the file:
0004--INI-New-error-codes-and-messages.patch
0005--INI-New-merge-flags.patch
0006--INI-Add-new-vars-to-parse-structure.patch
0007--INI-Add-save_error-function.patch
0008--INI-Change-parse_error-to-use-save_error.patch
0009--INI-Preparing-for-merging-sections.patch
0010--INI-Enhance-value-processing.patch
0011--INI-Use-section-line-number.patch
0012--INI-Refactor-section-processing.patch
0013--INI-Return-error-in-DETECT-mode.patch
0014--INI-New-test-files-for-section-merge.patch
0015--INI-Test-DETECT-mode-and-use-new-file.patch
0016--INI-Test-for-all-section-merge-modes.patch
Patches related porting of the meta data from old way of doing things to
the new way of doing things:
0017--INI-Separate-close-and-destroy.patch
0018--INI-Function-to-reopen-file.patch
0019--INI-Metadata-collection-is-gone.patch
0020--INI-Check-access-function.patch
0021--INI-Avoid-double-free.patch <- patch related to 17 (missed check)
0022--INI-Function-to-check-for-changes.patch
0023--INI-Tests-for-access-and-changes.patch
0024--INI-Rename-error-print-function.patch <- rename error printing
function for consistency with new interface
0025--INI-Initialize-variables-in-loops.patch <- Coverity issue
addressed. Related to patch 0001.
0026--INI-Exposing-functions.patch <- Make some internal functions reusable
There is also patch 27. It is a piece of new functionality. It is a
preview. Please see the comment before reviewing it.
Do I need to split it into multiple patches or it is Ok as is? It is
pretty big but all changes are in one file and logically related.
The UNIT test is missing so I am not claiming it actually works as
expected.
--
Thank you,
Dmitri Pal
Sr. Engineering Manager IPA project,
Red Hat Inc.
-------------------------------
Looking to carve out IT costs?
www.redhat.com/carveoutcosts/
12 years, 1 month
[PATCH] Add support for ADS pwdLastSet
by Pierre Carrier
Documented on http://msdn.microsoft.com/en-us/library/cc220785(v=prot.10).aspx
Introduced in nss_ldap 208:
* add support for native Active Directory password
policy attributes (enabled if shadowLastChange is
mapped to pwdLastSet)
---
src/config/SSSDConfig.py | 1 +
src/config/etc/sssd.api.d/sssd-ldap.conf | 1 +
src/man/sssd-ldap.5.xml | 15 ++++++++++
src/providers/ldap/ldap_auth.c | 9 +++++-
src/providers/ldap/ldap_common.c | 43 ++++++++++++++++++++++++++++++
src/providers/ldap/ldap_common.h | 1 +
src/providers/ldap/sdap.h | 1 +
7 files changed, 70 insertions(+), 1 deletions(-)
diff --git a/src/config/SSSDConfig.py b/src/config/SSSDConfig.py
index 5135174..992e1f4 100644
--- a/src/config/SSSDConfig.py
+++ b/src/config/SSSDConfig.py
@@ -167,6 +167,7 @@ option_strings = {
'ldap_user_modify_timestamp' : _('Modification time attribute'),
#replaced by ldap_entry_usn# 'ldap_user_entry_usn' : _('entryUSN attribute'),
'ldap_user_shadow_last_change' : _('shadowLastChange attribute'),
+ 'ldap_user_ads_last_change' : _('pwdLastSet attribute'),
'ldap_user_shadow_min' : _('shadowMin attribute'),
'ldap_user_shadow_max' : _('shadowMax attribute'),
'ldap_user_shadow_warning' : _('shadowWarning attribute'),
diff --git a/src/config/etc/sssd.api.d/sssd-ldap.conf b/src/config/etc/sssd.api.d/sssd-ldap.conf
index 5fd0cfb..6700df9 100644
--- a/src/config/etc/sssd.api.d/sssd-ldap.conf
+++ b/src/config/etc/sssd.api.d/sssd-ldap.conf
@@ -51,6 +51,7 @@ ldap_user_member_of = str, None, false
ldap_user_modify_timestamp = str, None, false
ldap_user_entry_usn = str, None, false
ldap_user_shadow_last_change = str, None, false
+ldap_user_ads_last_change = str, None, false
ldap_user_shadow_min = str, None, false
ldap_user_shadow_max = str, None, false
ldap_user_shadow_warning = str, None, false
diff --git a/src/man/sssd-ldap.5.xml b/src/man/sssd-ldap.5.xml
index 2a39732..0db3ce7 100644
--- a/src/man/sssd-ldap.5.xml
+++ b/src/man/sssd-ldap.5.xml
@@ -313,6 +313,21 @@
</varlistentry>
<varlistentry>
+ <term>ldap_user_ads_last_change (string)</term>
+ <listitem>
+ <para>
+ When using ldap_pwd_policy=shadow, this parameter
+ contains the name of an LDAP attribute corresponding
+ to pwdLastSet in Active Directory server, fell back to
+ when ldap_user_shadow_last_change was not available.
+ </para>
+ <para>
+ Default: pwdLastSet
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>ldap_user_shadow_min (string)</term>
<listitem>
<para>
diff --git a/src/providers/ldap/ldap_auth.c b/src/providers/ldap/ldap_auth.c
index e45d5b3..5ebd72c 100644
--- a/src/providers/ldap/ldap_auth.c
+++ b/src/providers/ldap/ldap_auth.c
@@ -286,7 +286,8 @@ static errno_t find_password_expiration_attributes(TALLOC_CTX *mem_ctx,
return EINVAL;
}
} else if (strcasecmp(pwd_policy, PWD_POL_OPT_SHADOW) == 0) {
- mark = ldb_msg_find_attr_as_string(msg, SYSDB_SHADOWPW_LASTCHANGE, NULL);
+ mark = ldb_msg_find_attr_as_string(msg, SYSDB_SHADOWPW_LASTCHANGE, NULL) |
+ ldb_msg_find_attr_as_string(msg, SYSDB_SHADOWPW_ADS_LASTCHANGE, NULL);
if (mark != NULL) {
DEBUG(9, ("Found shadow password expiration attributes.\n"))
spwd = talloc_zero(mem_ctx, struct spwd);
@@ -297,6 +298,12 @@ static errno_t find_password_expiration_attributes(TALLOC_CTX *mem_ctx,
val = ldb_msg_find_attr_as_string(msg, SYSDB_SHADOWPW_LASTCHANGE, NULL);
ret = string_to_shadowpw_days(val, &spwd->sp_lstchg);
+
+ /* Fallback to pwdLastSet for ADS */
+ if (ret != EOK) {
+ val = ldb_msg_find_attr_as_string(msg, SYSDB_SHADOWPW_ADS_LASTCHANGE, NULL);
+ ret = ads_pwdlastset_to_shadowpw_days(val, &spwd->sp_lstchg);
+ }
if (ret != EOK) goto shadow_fail;
val = ldb_msg_find_attr_as_string(msg, SYSDB_SHADOWPW_MIN, NULL);
diff --git a/src/providers/ldap/ldap_common.c b/src/providers/ldap/ldap_common.c
index 9eb9cc3..22c9bb7 100644
--- a/src/providers/ldap/ldap_common.c
+++ b/src/providers/ldap/ldap_common.c
@@ -163,6 +163,7 @@ struct sdap_attr_map rfc2307bis_user_map[] = {
{ "ldap_user_modify_timestamp", "modifyTimestamp", SYSDB_ORIG_MODSTAMP, NULL },
{ "ldap_user_entry_usn", NULL, SYSDB_USN, NULL },
{ "ldap_user_shadow_last_change", "shadowLastChange", SYSDB_SHADOWPW_LASTCHANGE, NULL },
+ { "ldap_user_ads_last_change", "pwdLastSet", SYSDB_SHADOWPW_ADS_LASTCHANGE, NULL },
{ "ldap_user_shadow_min", "shadowMin", SYSDB_SHADOWPW_MIN, NULL },
{ "ldap_user_shadow_max", "shadowMax", SYSDB_SHADOWPW_MAX, NULL },
{ "ldap_user_shadow_warning", "shadowWarning", SYSDB_SHADOWPW_WARNING, NULL },
@@ -878,6 +879,48 @@ errno_t string_to_shadowpw_days(const char *s, long *d)
return EOK;
}
+errno_t ads_pwdlastset_to_shadowpw_days(const char *s, long *d)
+{
+ long long ll;
+ long days;
+ char *endptr;
+
+ if (s == NULL || *s == '\0') {
+ *d = -1;
+ return EOK;
+ }
+
+ errno = 0;
+ ll = strtoll(s, &endptr, 10);
+ if (errno != 0) {
+ DEBUG(1, ("strtoll failed [%d][%s].\n", errno, strerror(errno)));
+ return errno;
+ }
+
+ if (*endptr != '\0') {
+ DEBUG(1, ("Input string [%s] is invalid.\n", s));
+ return EINVAL;
+ }
+
+ /* Magic value for password reset */
+ if (ll = 0LL) {
+ DEBUG(9, ("Magic pwdLastSet date 0, password change forced.\n"));
+ *d = 0L;
+ return EOK;
+ }
+
+ days = ll / 864000000000LL - 134774LL;
+
+ if (days < 0L) {
+ DEBUG(1, ("Date is before Jan 1, 1970 [%d].\n", ll));
+ return EINVAL;
+ }
+
+ *d = days;
+
+ return EOK;
+}
+
errno_t get_sysdb_attr_name(TALLOC_CTX *mem_ctx,
struct sdap_attr_map *map,
size_t map_size,
diff --git a/src/providers/ldap/ldap_common.h b/src/providers/ldap/ldap_common.h
index 9146da5..cf301de 100644
--- a/src/providers/ldap/ldap_common.h
+++ b/src/providers/ldap/ldap_common.h
@@ -146,6 +146,7 @@ int setup_child(struct sdap_id_ctx *ctx);
errno_t string_to_shadowpw_days(const char *s, long *d);
+errno_t ads_pwdlastset_to_shadowpw_days(const char *s, long *d);
errno_t get_sysdb_attr_name(TALLOC_CTX *mem_ctx,
struct sdap_attr_map *map,
diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h
index 32dc344..fdd5b7a 100644
--- a/src/providers/ldap/sdap.h
+++ b/src/providers/ldap/sdap.h
@@ -115,6 +115,7 @@ struct sdap_ppolicy_data {
};
#define SYSDB_SHADOWPW_LASTCHANGE "shadowLastChange"
+#define SYSDB_SHADOWPW_ADS_LASTCHANGE "pwdLastSet"
#define SYSDB_SHADOWPW_MIN "shadowMin"
#define SYSDB_SHADOWPW_MAX "shadowMax"
#define SYSDB_SHADOWPW_WARNING "shadowWarning"
--
1.7.4.4
12 years, 8 months
[PATCH 029-032] Refactoring of sdap_async_accounts
by Jan Zelený
So here it is, a set of patches splitting file sdap_async_accounts and making
some subsequent changes. If anyone has other ideas what could be changed, let
me know.
I was in favor of splitting the file into 3, as Simo suggested:
sdap_async_users.c
sdap_async_groups.c
sdap_async_initgroups.c
This way three basic operations are separated, but they are not separated too
much (otherwise a _common.c file would have to be present, since some routines
are shared by code paths in different schemas).
Thanks
Jan
12 years, 9 months
[PATCHES] Sysdb refactoring
by Jan Zelený
I'm sending several patches with the sysdb refactoring. Originally, I was
planning one more step - to change return type from int to errno_t where it
was convenient. If someone wants to do it, feel free. Otherwise I'm going to
make the patch myself in couple days.
When reviewing, please note that patches 40-43 have to be tested together. The
same applies for patches 44-46.
Jan
12 years, 9 months
Shell overrides
by John Hodrien
I've just been playing with the allowed_shells stuff. I'm using a very large
LDAP tree. It contains mostly good data, but has some users shells set to
/bin/sh and /bin/csh. For these users I want to override the shell to
something more sane (like /bin/bash). But I don't want to actually remove
those shells from systems, as I want them to be available for local accounts
and scripts.
So on the client I have local accounts that make use of /bin/sh and /bin/csh
and an /etc/shells of:
/bin/sh
/bin/bash
/sbin/nologin
/bin/tcsh
/bin/csh
If I don't edit /etc/shells it'll use those shells, which isn't what I want.
If I remove it from /etc/shells, and set allowed_shells to an approved list,
it'll switch their shell to nologin.
Is there a way I can deal with this using the current setup? I couldn't see a
way.
I was wondering about adding a new config option to allow you to mark certain
shells as being vetoed, such that the fallback shell is used instead. Is this
in any way sane?
Ignoring the trimmings, the meat of it is just:
diff -ur sssd-1.5.11.orig/src/responder/nss/nsssrv_cmd.c sssd-1.5.11/src/responder/nss/nsssrv_cmd.c
--- sssd-1.5.11.orig/src/responder/nss/nsssrv_cmd.c 2011-07-05 18:41:13.000000000 +0100
+++ sssd-1.5.11/src/responder/nss/nsssrv_cmd.c 2011-07-28 15:46:10.787877792 +0100
@@ -314,7 +314,18 @@
user_shell = ldb_msg_find_attr_as_string(msg, SYSDB_SHELL, NULL);
if (!user_shell) return NULL;
- if (!nctx->allowed_shells) return talloc_strdup(mem_ctx, user_shell);
+ if (!nctx->allowed_shells && !nctx->vetoed_shells) return talloc_strdup(mem_ctx, user_shell);
+
+ if (nctx->vetoed_shells)
+ {
+ for (i=0; nctx->vetoed_shells[i]; i++) {
+ if (strcmp(nctx->vetoed_shells[i], user_shell) == 0) {
+ DEBUG(5, ("The shell '%s' is vetoed. "
+ "Using fallback\n", user_shell));
+ return talloc_strdup(mem_ctx, nctx->shell_fallback);
+ }
+ }
+ }
By all means tell me I'm mad and there are much better ways of achieving what
I'm trying to do. I'm new to sssd, but it looks like it offers a whole raft
of advantages over nss_ldap (which I'm currently using) that makes it look
irresistable.
Thanks,
jh
12 years, 10 months
[PATCHES] HBAC access control rewrite
by Stephen Gallagher
While attempting to extract the SSSD's HBAC rule evaluation into a
common library, I discovered several shortcomings. Some were related to
extracting the library, others were related to the rule evaluation
itself.
Related to extracting the library, I needed for the code to be able to
identify and resolve without having direct access to LDAP or the LDB.
This meant I could not rely on the memberOf objects to be valid.
As for the rule evaluation, I discovered that we were only caching for
offline use those remote hosts that had previously attempted to log in.
This meant that if the IPA server was unreachable, valid users would be
unable to log in from some valid machines.
After careful consideration (and a few false starts), I decided that a
total rewrite was necessary. So here it is.
The major changes are these:
1) We have moved to always performing a full enumeration of known IPA
hosts and HBAC services. This actually results in a net reduction in
round-trips to the LDAP server, which was a primary bottleneck.
Additionally, this means that we also have a full understanding when
offline as to whether a remote host is permitted access or not.
2) I've added a configurable timeout for hbac rule refreshes to the LDAP
server. Previously, if we were online, EVERY pam_account() request would
result in at least one LDAP round-trip. By default, we'll only refresh
the HBAC rules every five seconds now.
3) I broke the acquisition and processing of the rules, hosts and
services into separate C files, as ipa_access.c was getting to be much
to large to manage.
The overall view of the code (when online) is this:
A request comes in, we call to LDAP to get, in order, the set of known
hosts, the set of known PAM services and then finally the set of
*enabled* rules with the current ipa_hostname as the targethost.
And now, the patches:
Patch 0001: The new standalone evaluator library. It's very simple at
the moment (but it will become much more complex in the near future when
timerule evaluation is added). Jakub, Rob and I agreed on the interface
and Jakub is creating Python bindings for it.
Patch 0002: This is the meat of the new IPA access backend. All of the
helper functions necessary for looking up, storing and converting the
hosts, rules and services are in this patch.
Patch 0003: This is not really a patch as much as it is a trash can. I
split this from Patch 0004 to make the latter more reviewable. Patch
0003 contains only the deletions of the old access provider
implementation.
Patch 0004: Adds the new IPA access provider, taking advantage of the
helper functions from Patch 0002.
Patch 0005: Adds a refresh timeout to reduce round-trips to IPA while
online.
12 years, 10 months
[PATCH] Provide python bindings for the HBAC evaluator library
by Jakub Hrozek
Hi,
the attached patch provides a new python module "pyhbac" that implements
python bindings for the HBAC evaluator library.
The patch depends on Stephen's last patches which are on review as of
now, but the test suite passed, so I think the bindings can be reviewed
in parallel.
"make check" loads the built python module from tree by doing some
sys.path magic. If you'd like to experiment with the module yourself,
you must either install it or set PYTHONPATH to $SSSD_BUILD_DIR/.libs
12 years, 10 months
[PATCH] Coverity issues in python HBAC bindings
by Jakub Hrozek
[PATCH 1/2] Remove dead code from python HBAC bindings
As Coverity noticed, we check for s != NULL in both if and else branches.
[PATCH 2/2] Handle allocation error in python HBAC bindings
This is kinda embarrassing, but the body of a NULL check was completely
missing.
12 years, 10 months