Package: slapd-smbk5pwd
Version: 2.4.23-7.2
Severity: normal

This overlay goal is to keep syncronized password data stored in a
LDAP tree between samba, unix and kerberos, but it fails to keep
updated the shadowLastChange attribute when a password is changed. 

It works updating sambaPwdLastSet, so it seems that keeping that
information is within its goal, but it do not touch shadowLastChange. 
This means that when used with password aging, an unix password will 
stay expired also if you have just changed it. 

There is a patch, written by Mark A. Ziesemer, that allow to make this
update. This could also solve the similar problem with libpam-ldapd (see
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=619881)

The patch was proposed upstream, received some support by Michael
Michael Ströder but then was refused by Howard Chu. Some history here:

http://blogger.ziesemer.com/2011/01/ldap-authentication-for-samba.html

Reason given is that you should use the nssov overlay, that is not even
packaged in Debian, and ppolicy. I'll try to bring back discussion on
openldap devel list, but in the meantime all people using the classic
shadowAccount objectclass have no working solution, and, if they have
to follow Chu intentions, they are forced to do a massive rework of
their current tree contents.

I reformatted the patch against the overlay source in the current 
squeeze pakage and I'm attaching it to this message. I tested it in
some small installations and it seems to work just fine. 

I'll try to provide also an updated source package but I'm not too
much competent in this area

-- System Information:
Debian Release: 6.0.2
  APT prefers stable-updates
  APT policy: (500, 'stable-updates'), (500, 'stable')
Architecture: i386 (i686)

Kernel: Linux 2.6.32-5-686 (SMP w/1 CPU core)
Locale: LANG=it_IT.UTF-8, LC_CTYPE=it_IT.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash

Versions of packages slapd-smbk5pwd depends on:
ii  libc6      2.11.2-10                     Embedded GNU C Library: Shared lib
ii  libgcrypt1 1.4.5-2                       LGPL Crypto library - runtime libr
ii  libkadm5sr 1.4.0~git20100726.dfsg.1-1+b1 Libraries for Heimdal Kerberos
ii  libkrb5-26 1.4.0~git20100726.dfsg.1-1+b1 Heimdal Kerberos - libraries
ii  libldap-2. 2.4.23-7.2                    OpenLDAP libraries
ii  slapd      2.4.23-7.2                    OpenLDAP server (slapd)

slapd-smbk5pwd recommends no packages.

slapd-smbk5pwd suggests no packages.

-- no debconf information
diff -r -u a/contrib/slapd-modules/README b/contrib/slapd-modules/README
--- a/contrib/slapd-modules/README	2010-04-13 22:22:25.000000000 +0200
+++ b/contrib/slapd-modules/README	2011-08-30 16:17:52.000000000 +0200
@@ -49,8 +49,8 @@
 	Proxy Authorization compatibility with obsolete internet-draft.
 
 smbk5pwd (overlay)
-	Make the PasswordModify Extended Operation update Kerberos
-	keys and Samba password hashes as well as userPassword.
+	Make the PasswordModify Extended Operation update Kerberos keys,
+	Samba password hashes, and shadowLastChange, as well as userPassword.
 
 trace (overlay)
 	Trace overlay invocation.
diff -r -u a/contrib/slapd-modules/smbk5pwd/Makefile b/contrib/slapd-modules/smbk5pwd/Makefile
--- a/contrib/slapd-modules/smbk5pwd/Makefile	2011-08-30 16:10:25.000000000 +0200
+++ b/contrib/slapd-modules/smbk5pwd/Makefile	2011-08-30 16:18:10.000000000 +0200
@@ -16,8 +16,8 @@
 OPT=-g -O2
 CC=gcc
 
-# Omit DO_KRB5 or DO_SAMBA if you don't want to support it.
-DEFS=-DDO_KRB5 -DDO_SAMBA
+# Omit DO_KRB5, DO_SAMBA, or DO_SHADOW if you don't want to support it.
+DEFS=-DDO_KRB5 -DDO_SAMBA -DDO_SHADOW
 
 HEIMDAL_INC=-I/usr/include
 SSL_INC=
diff -r -u a/contrib/slapd-modules/smbk5pwd/README b/contrib/slapd-modules/smbk5pwd/README
--- a/contrib/slapd-modules/smbk5pwd/README	2010-04-13 22:22:30.000000000 +0200
+++ b/contrib/slapd-modules/smbk5pwd/README	2011-08-30 16:18:37.000000000 +0200
@@ -1,6 +1,6 @@
 This directory contains a slapd overlay, smbk5pwd, that extends the
-PasswordModify Extended Operation to update Kerberos keys and Samba
-password hashes for an LDAP user.
+PasswordModify Extended Operation to update Kerberos keys, Samba
+password hashes, and the shadowLastChange attribute for an LDAP user.
 
 The Kerberos support is written for Heimdal using its hdb-ldap backend.
 If a PasswordModify is performed on an entry that has the krb5KDCEntry
@@ -17,6 +17,10 @@
 objectclass, then the sambaLMPassword, sambaNTPassword, and sambaPwdLastSet
 attributes will be updated accordingly.
 
+The Shadow support updates the shadowLastChange attribute to the current
+date if a PasswordModify is performed on an entry that has the
+shadowAccount objectclass.
+
 To use the overlay, add:
 
 	include <path to>/krb5-kdc.schema
@@ -40,8 +44,8 @@
 	smbk5pwd-enable		<module>
 
 can be used to enable only the desired one(s); legal values for <module>
-are "krb5" and "samba", if they are respectively enabled by defining
-DO_KRB5 and DO_SAMBA.
+are "krb5", "samba", and "shadow", if they are respectively enabled by defining
+DO_KRB5, DO_SAMBA, and DO_SHADOW.
 
 The samba module also supports the
 
@@ -60,15 +64,16 @@
 	olcOverlay: {0}smbk5pwd
 	olcSmbK5PwdEnable: krb5
 	olcSmbK5PwdEnable: samba
+	olcSmbK5PwdEnable: shadow
 	olcSmbK5PwdMustChange: 2592000
 
-which enables both krb5 and samba modules with a password expiry time
-of 30 days.
+which enables all the krb5, samba, and shadow modules with a password
+expiry time of 30 days.
 
-The provided Makefile builds both Kerberos and Samba support by default.
-You must edit the Makefile to insure that the correct include and library
-paths are used. You can change the DEFS macro if you only want one or the
-other of Kerberos or Samba support.
+The provided Makefile builds all of Kerberos, Samba, and Shadow support by
+default. You must edit the Makefile to insure that the correct include and
+library paths are used. You can change the DEFS macro if you only want partial
+support.
 
 This overlay is only set up to be built as a dynamically loaded module.
 On most platforms, in order for the module to be usable, all of the 
diff -r -u a/contrib/slapd-modules/smbk5pwd/smbk5pwd.c b/contrib/slapd-modules/smbk5pwd/smbk5pwd.c
--- a/contrib/slapd-modules/smbk5pwd/smbk5pwd.c	2010-04-13 22:22:30.000000000 +0200
+++ b/contrib/slapd-modules/smbk5pwd/smbk5pwd.c	2011-08-30 16:18:20.000000000 +0200
@@ -17,6 +17,7 @@
 /* ACKNOWLEDGEMENTS:
  * Support for table-driven configuration added by Pierangelo Masarati.
  * Support for sambaPwdMustChange and sambaPwdCanChange added by Marco D'Ettorre.
+ * Support for shadowLastChange added by Mark A. Ziesemer <www.ziesemer.com>.
  */
 
 #include <portable.h>
@@ -81,14 +82,21 @@
 static ObjectClass *oc_sambaSamAccount;
 #endif
 
+#ifdef DO_SAMBA
+static AttributeDescription *ad_shadowLastChange;
+static ObjectClass *oc_shadowAccount;
+#endif
+
 /* Per-instance configuration information */
 typedef struct smbk5pwd_t {
 	unsigned	mode;
 #define	SMBK5PWD_F_KRB5		(0x1U)
 #define	SMBK5PWD_F_SAMBA	(0x2U)
+#define SMBK5PWD_F_SHADOW	(0x4U)
 
 #define SMBK5PWD_DO_KRB5(pi)	((pi)->mode & SMBK5PWD_F_KRB5)
 #define SMBK5PWD_DO_SAMBA(pi)	((pi)->mode & SMBK5PWD_F_SAMBA)
+#define SMBK5PWD_DO_SHADOW(pi)	((pi)->mode & SMBK5PWD_F_SHADOW)
 
 #ifdef DO_KRB5
 	/* nothing yet */
@@ -100,6 +108,10 @@
 	/* How many seconds after allowing a password change? */
 	time_t  smb_can_change;
 #endif
+
+#ifdef DO_SHADOW
+	/* nothing yet */
+#endif
 } smbk5pwd_t;
 
 static const unsigned SMBK5PWD_F_ALL	=
@@ -110,6 +122,9 @@
 #ifdef DO_SAMBA
 	| SMBK5PWD_F_SAMBA
 #endif
+#ifdef DO_SHADOW
+	| SMBK5PWD_F_SHADOW
+#endif
 ;
 
 static int smbk5pwd_modules_init( smbk5pwd_t *pi );
@@ -653,6 +668,34 @@
 		}
 	}
 #endif /* DO_SAMBA */
+
+#ifdef DO_SHADOW
+	/* Shadow stuff */
+	if ( SMBK5PWD_DO_SHADOW( pi ) && is_entry_objectclass(e, oc_shadowAccount, 0 ) ) {
+		struct berval *keys;
+	
+		ml = ch_malloc(sizeof(Modifications));
+		ml->sml_next = qpw->rs_mods;
+		qpw->rs_mods = ml;
+
+		keys = ch_malloc( 2 * sizeof(struct berval) );
+		keys[0].bv_val = ch_malloc( LDAP_PVT_INTTYPE_CHARS(long) );
+		keys[0].bv_len = snprintf(keys[0].bv_val,
+			LDAP_PVT_INTTYPE_CHARS(long),
+			"%ld", slap_get_time() / 60 / 60 / 24 );
+		BER_BVZERO( &keys[1] );
+
+		ml->sml_desc = ad_shadowLastChange;
+		ml->sml_op = LDAP_MOD_REPLACE;
+#ifdef SLAP_MOD_INTERNAL
+		ml->sml_flags = SLAP_MOD_INTERNAL;
+#endif
+		ml->sml_numvals = 1;
+		ml->sml_values = keys;
+		ml->sml_nvalues = NULL;
+	}
+#endif /* DO_SHADOW */
+
 	be_entry_release_r( op, e );
 	qpw->rs_new.bv_val[qpw->rs_new.bv_len] = term;
 
@@ -715,6 +758,7 @@
 static slap_verbmasks smbk5pwd_modules[] = {
 	{ BER_BVC( "krb5" ),		SMBK5PWD_F_KRB5	},
 	{ BER_BVC( "samba" ),		SMBK5PWD_F_SAMBA },
+	{ BER_BVC( "shadow" ),		SMBK5PWD_F_SHADOW },
 	{ BER_BVNULL,			-1 }
 };
 
@@ -860,6 +904,16 @@
 		}
 #endif /* ! DO_SAMBA */
 
+#ifndef DO_SHADOW
+		if ( SMBK5PWD_DO_SHADOW( pi ) ) {
+			Debug( LDAP_DEBUG_ANY, "%s: smbk5pwd: "
+			"<%s> module \"%s\" only allowed when compiled with -DDO_SHADOW.\n",
+			c->log, c->argv[ 0 ], c->argv[ rc ] );
+			pi->mode = mode;
+			return 1;
+		}
+#endif /* ! DO_SHADOW */
+
 		{
 			BackendDB	db = *c->be;
 
@@ -882,66 +936,80 @@
 	return rc;
 }
 
+typedef struct smbk5pwd_verify_schema_t {
+	const char  *name;
+	AttributeDescription **adp;
+} smbk5pwd_verify_schema_t;
+
 static int
-smbk5pwd_modules_init( smbk5pwd_t *pi )
+smbk5pwd_modules_verify_schema(const char *ocName, ObjectClass **oc, smbk5pwd_verify_schema_t *ad)
 {
-	static struct {
-		const char		*name;
-		AttributeDescription	**adp;
+	int i, rc;
+
+
+	*oc = oc_find( ocName );
+	if ( !*oc ) {
+		Debug( LDAP_DEBUG_ANY, "smbk5pwd: "
+			"unable to find \"%s\" objectClass.\n",
+			ocName, 0, 0 );
+		return -1;
+	}
+
+	for ( i = 0; ad[ i ].name != NULL; i++ ) {
+		const char *text;
+
+		*(ad[ i ].adp) = NULL;
+
+		rc = slap_str2ad( ad[ i ].name, ad[ i ].adp, &text );
+		if ( rc != LDAP_SUCCESS ) {
+			Debug( LDAP_DEBUG_ANY, "smbk5pwd: "
+				"unable to find \"%s\" attributeType: %s (%d).\n",
+				ad[ i ].name, text, rc );
+			*oc = NULL;
+			return rc;
+		}
 	}
+}
+
+static int
+smbk5pwd_modules_init( smbk5pwd_t *pi )
+{
+
 #ifdef DO_KRB5
-	krb5_ad[] = {
+	smbk5pwd_verify_schema_t krb5_ad[] = {
 		{ "krb5Key",			&ad_krb5Key },
 		{ "krb5KeyVersionNumber",	&ad_krb5KeyVersionNumber },
 		{ "krb5PrincipalName",		&ad_krb5PrincipalName },
 		{ "krb5ValidEnd",		&ad_krb5ValidEnd },
 		{ NULL }
-	},
+	};
 #endif /* DO_KRB5 */
 #ifdef DO_SAMBA
-	samba_ad[] = {
+	smbk5pwd_verify_schema_t samba_ad[] = {
 		{ "sambaLMPassword",		&ad_sambaLMPassword },
 		{ "sambaNTPassword",		&ad_sambaNTPassword },
 		{ "sambaPwdLastSet",		&ad_sambaPwdLastSet },
 		{ "sambaPwdMustChange",		&ad_sambaPwdMustChange },
 		{ "sambaPwdCanChange",		&ad_sambaPwdCanChange },
 		{ NULL }
-	},
+	};
 #endif /* DO_SAMBA */
-	dummy_ad;
 
-	/* this is to silence the unused var warning */
-	dummy_ad.name = NULL;
+#ifdef DO_SHADOW
+	smbk5pwd_verify_schema_t shadow_ad[] = {
+		{ "shadowLastChange",  &ad_shadowLastChange },
+		{ NULL }
+	};
+#endif /* DO_SHADOW */
 
 #ifdef DO_KRB5
 	if ( SMBK5PWD_DO_KRB5( pi ) && oc_krb5KDCEntry == NULL ) {
 		krb5_error_code	ret;
 		extern HDB 	*_kadm5_s_get_db(void *);
 
-		int		i, rc;
-
-		/* Make sure all of our necessary schema items are loaded */
-		oc_krb5KDCEntry = oc_find( "krb5KDCEntry" );
-		if ( !oc_krb5KDCEntry ) {
-			Debug( LDAP_DEBUG_ANY, "smbk5pwd: "
-				"unable to find \"krb5KDCEntry\" objectClass.\n",
-				0, 0, 0 );
-			return -1;
-		}
-
-		for ( i = 0; krb5_ad[ i ].name != NULL; i++ ) {
-			const char	*text;
-
-			*(krb5_ad[ i ].adp) = NULL;
-
-			rc = slap_str2ad( krb5_ad[ i ].name, krb5_ad[ i ].adp, &text );
-			if ( rc != LDAP_SUCCESS ) {
-				Debug( LDAP_DEBUG_ANY, "smbk5pwd: "
-					"unable to find \"%s\" attributeType: %s (%d).\n",
-					krb5_ad[ i ].name, text, rc );
-				oc_krb5KDCEntry = NULL;
-				return rc;
-			}
+		int rc = smbk5pwd_modules_verify_schema("krb5KDCEntry", &oc_krb5KDCEntry, krb5_ad);
+		if ( rc != LDAP_SUCCESS ) {
+			return rc;
 		}
 
 		/* Initialize Kerberos context */
@@ -980,32 +1048,21 @@
 
 #ifdef DO_SAMBA
 	if ( SMBK5PWD_DO_SAMBA( pi ) && oc_sambaSamAccount == NULL ) {
-		int		i, rc;
-
-		oc_sambaSamAccount = oc_find( "sambaSamAccount" );
-		if ( !oc_sambaSamAccount ) {
-			Debug( LDAP_DEBUG_ANY, "smbk5pwd: "
-				"unable to find \"sambaSamAccount\" objectClass.\n",
-				0, 0, 0 );
-			return -1;
+		int rc = smbk5pwd_modules_verify_schema("sambaSamAccount", &oc_sambaSamAccount, samba_ad);
+		if ( rc != LDAP_SUCCESS ) {
+			return rc;
 		}
+	}
+#endif /* DO_SAMBA */
 
-		for ( i = 0; samba_ad[ i ].name != NULL; i++ ) {
-			const char	*text;
-
-			*(samba_ad[ i ].adp) = NULL;
-
-			rc = slap_str2ad( samba_ad[ i ].name, samba_ad[ i ].adp, &text );
-			if ( rc != LDAP_SUCCESS ) {
-				Debug( LDAP_DEBUG_ANY, "smbk5pwd: "
-					"unable to find \"%s\" attributeType: %s (%d).\n",
-					samba_ad[ i ].name, text, rc );
-				oc_sambaSamAccount = NULL;
-				return rc;
-			}
+#ifdef DO_SHADOW
+	if ( SMBK5PWD_DO_SHADOW( pi ) && oc_shadowAccount == NULL ) {
+		int rc = smbk5pwd_modules_verify_schema("shadowAccount", &oc_shadowAccount, shadow_ad);
+		if ( rc != LDAP_SUCCESS ) {
+			return rc;
 		}
 	}
-#endif /* DO_SAMBA */
+#endif /* DO_SHADOW */
 
 	return 0;
 }

Reply via email to