summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNathan Kinder <nkinder@redhat.com>2009-12-01 16:27:23 -0800
committerNathan Kinder <nkinder@redhat.com>2009-12-01 16:27:23 -0800
commitf9ec9a62b8e386c7918b0b9ea628023ed9bd505e (patch)
tree09668c16a0389abdd05567936ad799472c8768bd
parent16e255be98bbb8b3bcfb080c632add7f048cfd44 (diff)
downloadds-f9ec9a62b8e386c7918b0b9ea628023ed9bd505e.tar.gz
ds-f9ec9a62b8e386c7918b0b9ea628023ed9bd505e.tar.xz
ds-f9ec9a62b8e386c7918b0b9ea628023ed9bd505e.zip
Bug 195302 - Allow fine-grained password storage scheme to be set
This patch makes the server use the password storage scheme set in the appropriate fine-grained password policy (if it is set). The previous code was always using the global storage scheme. This fix was based off of a fix contributed by Ulf Weltman of Hewlett Packard.
-rw-r--r--ldap/servers/slapd/add.c10
-rw-r--r--ldap/servers/slapd/modify.c10
-rw-r--r--ldap/servers/slapd/pw.c100
-rw-r--r--ldap/servers/slapd/pw.h9
-rw-r--r--ldap/servers/slapd/slap.h9
-rw-r--r--ldap/servers/slapd/slapi-plugin.h11
6 files changed, 117 insertions, 32 deletions
diff --git a/ldap/servers/slapd/add.c b/ldap/servers/slapd/add.c
index df683a90..1a1f8673 100644
--- a/ldap/servers/slapd/add.c
+++ b/ldap/servers/slapd/add.c
@@ -32,8 +32,14 @@
*
*
* Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
- * Copyright (C) 2005 Red Hat, Inc.
+ * Copyright (C) 2009 Red Hat, Inc.
+ * Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
* All rights reserved.
+ *
+ * Contributors:
+ * Hewlett-Packard Development Company, L.P.
+ * Bugfix for bug #195302
+ *
* END COPYRIGHT BLOCK **/
#ifdef HAVE_CONFIG_H
@@ -512,7 +518,7 @@ static void op_shared_add (Slapi_PBlock *pb)
Slapi_Value **vals= NULL;
valuearray_add_valuearray(&unhashed_password_vals, present_values, 0);
valuearray_add_valuearray(&vals, present_values, 0);
- pw_encodevals(vals);
+ pw_encodevals_ext(pb, slapi_entry_get_sdn (e), vals);
add_password_attrs(pb, operation, e);
slapi_entry_attr_replace_sv(e, SLAPI_USERPWD_ATTR, vals);
valuearray_free(&vals);
diff --git a/ldap/servers/slapd/modify.c b/ldap/servers/slapd/modify.c
index 1eac8489..40646b2b 100644
--- a/ldap/servers/slapd/modify.c
+++ b/ldap/servers/slapd/modify.c
@@ -32,8 +32,14 @@
*
*
* Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
- * Copyright (C) 2005 Red Hat, Inc.
+ * Copyright (C) 2009 Red Hat, Inc.
+ * Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
* All rights reserved.
+ *
+ * Contributors:
+ * Hewlett-Packard Development Company, L.P.
+ * Bugfix for bug #195302
+ *
* END COPYRIGHT BLOCK **/
#ifdef HAVE_CONFIG_H
@@ -712,7 +718,7 @@ static void op_shared_modify (Slapi_PBlock *pb, int pw_change, char *old_pw)
valuearray_init_bervalarray(pw_mod->mod_bvalues, &va);
/* encode password */
- pw_encodevals(va);
+ pw_encodevals_ext(pb, &sdn, va);
/* remove current clear value of userpassword */
ber_bvecfree(pw_mod->mod_bvalues);
diff --git a/ldap/servers/slapd/pw.c b/ldap/servers/slapd/pw.c
index cafdfd68..09bb96c7 100644
--- a/ldap/servers/slapd/pw.c
+++ b/ldap/servers/slapd/pw.c
@@ -32,8 +32,14 @@
*
*
* Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
- * Copyright (C) 2005 Red Hat, Inc.
+ * Copyright (C) 2009 Red Hat, Inc.
+ * Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
* All rights reserved.
+ *
+ * Contributors:
+ * Hewlett-Packard Development Company, L.P.
+ * Bugfix for bug #195302
+ *
* END COPYRIGHT BLOCK **/
#ifdef HAVE_CONFIG_H
@@ -177,17 +183,23 @@ int slapi_is_encoded (char *value)
char* slapi_encode (char *value, char *alg)
{
+ return( slapi_encode_ext( NULL, NULL, value, alg ) );
+}
+
+char* slapi_encode_ext (Slapi_PBlock *pb, const Slapi_DN *sdn, char *value, char *alg)
+{
struct pw_scheme *enc_scheme = NULL;
+ char *(*pws_enc) ( char *pwd ) = NULL;
char *hashedval = NULL;
- int need_to_free = 0;
+ passwdPolicy *pwpolicy=NULL;
- if (alg == NULL) /* use server encoding scheme */
+ if (alg == NULL) /* use local scheme, or global if we can't fetch local */
{
- slapdFrontendConfig_t * slapdFrontendConfig = getFrontendConfig();
-
- enc_scheme = slapdFrontendConfig->pw_storagescheme;
+ pwpolicy = new_passwdPolicy(pb, (char*)slapi_sdn_get_ndn(sdn) );
+ pws_enc = pwpolicy->pw_storagescheme->pws_enc;
+ delete_passwdPolicy(&pwpolicy);
- if (enc_scheme == NULL)
+ if (pws_enc == NULL)
{
slapi_log_error( SLAPI_LOG_FATAL, NULL,
"slapi_encode: no server scheme\n" );
@@ -212,12 +224,11 @@ char* slapi_encode (char *value, char *alg)
}
return NULL;
}
- need_to_free = 1;
+ pws_enc = enc_scheme->pws_enc;
+ free_pw_scheme(enc_scheme);
}
- hashedval = enc_scheme->pws_enc(value);
- if (need_to_free)
- free_pw_scheme(enc_scheme);
+ hashedval = (*pws_enc)(value);
return hashedval;
}
@@ -318,18 +329,39 @@ pw_val2scheme( char *val, char **valpwdp, int first_is_default )
int
pw_encodevals( Slapi_Value **vals )
{
+ return( pw_encodevals_ext( NULL, NULL, vals ) );
+}
+
+/*
+ * Same as pw_encodevals, except if a pb and sdn are passed in, we will try
+ * to check the password scheme specified by local password policy.
+ */
+int
+pw_encodevals_ext( Slapi_PBlock *pb, const Slapi_DN *sdn, Slapi_Value **vals )
+{
int i;
- slapdFrontendConfig_t * slapdFrontendConfig = getFrontendConfig();
+ passwdPolicy *pwpolicy=NULL;
+ char *dn;
+ char *(*pws_enc) ( char *pwd ) = NULL;
+ if ( vals == NULL ) {
+ return( 0 );
+ }
+
+ /* new_passwdPolicy gives us a local policy if sdn and pb are set and
+ can be used to find a local policy, else we get the global policy */
+ pwpolicy = new_passwdPolicy(pb, (char*)slapi_sdn_get_ndn(sdn) );
+ pws_enc = pwpolicy->pw_storagescheme->pws_enc;
+ delete_passwdPolicy(&pwpolicy);
- if ( vals == NULL || slapdFrontendConfig->pw_storagescheme == NULL ||
- slapdFrontendConfig->pw_storagescheme->pws_enc == NULL ) {
+ /* Password scheme encryption function was not found */
+ if ( pws_enc == NULL ) {
return( 0 );
}
for ( i = 0; vals[ i ] != NULL; ++i ) {
- struct pw_scheme *pwsp;
- char *enc = NULL;
+ struct pw_scheme *pwsp = NULL;
+ char *enc = NULL;
if ( (pwsp=pw_val2scheme( (char*)slapi_value_get_string(vals[ i ]), NULL, 0)) != NULL ) { /* JCM Innards */
/* If the value already specifies clear storage, call the
* clear storage plug-in */
@@ -340,14 +372,14 @@ pw_encodevals( Slapi_Value **vals )
continue; /* don't touch pre-encoded values */
}
}
- if ((!enc) && (( enc = (*slapdFrontendConfig->pw_storagescheme->pws_enc)( (char*)slapi_value_get_string(vals[ i ]) )) /* JCM Innards */
- == NULL )) {
- free_pw_scheme( pwsp );
+ free_pw_scheme( pwsp );
+
+ if ((!enc) && (( enc = (*pws_enc)( (char*)slapi_value_get_string(vals[ i ]) )) == NULL )) {
return( -1 );
}
+
slapi_value_free(&vals[ i ]);
vals[ i ] = slapi_value_new_string_passin(enc);
- free_pw_scheme( pwsp );
}
return( 0 );
@@ -1460,6 +1492,7 @@ new_passwdPolicy(Slapi_PBlock *pb, char *dn)
int attr_free_flags = 0;
int rc=0;
passwdPolicy *pwdpolicy = NULL;
+ struct pw_scheme *pwdscheme = NULL;
Slapi_Attr *attr;
char *attr_name;
Slapi_Value **sval;
@@ -1471,10 +1504,12 @@ new_passwdPolicy(Slapi_PBlock *pb, char *dn)
slapdFrontendConfig = getFrontendConfig();
pwdpolicy = (passwdPolicy *)slapi_ch_calloc(1, sizeof(passwdPolicy));
- slapi_pblock_get( pb, SLAPI_OPERATION, &op);
- slapi_pblock_get( pb, SLAPI_OPERATION_TYPE, &optype );
+ if (pb) {
+ slapi_pblock_get( pb, SLAPI_OPERATION, &op);
+ slapi_pblock_get( pb, SLAPI_OPERATION_TYPE, &optype );
+ }
- if (dn && (slapdFrontendConfig->pwpolicy_local == 1)) {
+ if (pb && dn && (slapdFrontendConfig->pwpolicy_local == 1)) {
/* If we're doing an add, COS does not apply yet so we check
parents for the pwdpolicysubentry. We look only for virtual
attributes, because real ones are for single-target policy. */
@@ -1701,13 +1736,20 @@ new_passwdPolicy(Slapi_PBlock *pb, char *dn)
pwdpolicy->pw_gracelimit = slapi_value_get_int(*sval);
}
}
+ else
+ if (!strcasecmp(attr_name, "passwordstoragescheme")) {
+ if ((sval = attr_get_present_values(attr))) {
+ pwdpolicy->pw_storagescheme =
+ pw_name2scheme((char*)slapi_value_get_string(*sval));
+ }
+ }
} /* end of for() loop */
if (pw_entry) {
slapi_entry_free(pw_entry);
}
return pwdpolicy;
- } else if ( e ) {
+ } else if ( e ) {
slapi_entry_free( e );
}
}
@@ -1718,6 +1760,11 @@ done:
*/
*pwdpolicy = slapdFrontendConfig->pw_policy;
+ pwdscheme = (struct pw_scheme *)slapi_ch_calloc(1, sizeof(struct pw_scheme));
+ *pwdscheme = *slapdFrontendConfig->pw_storagescheme;
+ pwdscheme->pws_name = strdup( slapdFrontendConfig->pw_storagescheme->pws_name );
+ pwdpolicy->pw_storagescheme = pwdscheme;
+
return pwdpolicy;
} /* End of new_passwdPolicy() */
@@ -1725,7 +1772,10 @@ done:
void
delete_passwdPolicy( passwdPolicy **pwpolicy)
{
- slapi_ch_free((void **)pwpolicy);
+ if (pwpolicy && *pwpolicy) {
+ free_pw_scheme( (*(*pwpolicy)).pw_storagescheme );
+ slapi_ch_free((void **)pwpolicy);
+ }
}
/*
diff --git a/ldap/servers/slapd/pw.h b/ldap/servers/slapd/pw.h
index 5f5eb1be..38c7fafe 100644
--- a/ldap/servers/slapd/pw.h
+++ b/ldap/servers/slapd/pw.h
@@ -32,8 +32,14 @@
*
*
* Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
- * Copyright (C) 2005 Red Hat, Inc.
+ * Copyright (C) 2009 Red Hat, Inc.
+ * Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
* All rights reserved.
+ *
+ * Contributors:
+ * Hewlett-Packard Development Company, L.P.
+ * Bugfix for bug #195302
+ *
* END COPYRIGHT BLOCK **/
#ifdef HAVE_CONFIG_H
@@ -76,6 +82,7 @@ struct pw_scheme {
struct pw_scheme *pw_name2scheme( char *name );
struct pw_scheme *pw_val2scheme( char *val, char **valpwdp, int first_is_default );
int pw_encodevals( Slapi_Value **vals );
+int pw_encodevals_ext( Slapi_PBlock *pb, const Slapi_DN *sdn, Slapi_Value **vals );
int checkPrefix(char *cipher, char *schemaName, char **encrypt);
struct passwordpolicyarray *new_passwdPolicy ( Slapi_PBlock *pb, char *dn );
void delete_passwdPolicy( struct passwordpolicyarray **pwpolicy);
diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
index 58603507..0e37c85e 100644
--- a/ldap/servers/slapd/slap.h
+++ b/ldap/servers/slapd/slap.h
@@ -32,8 +32,14 @@
*
*
* Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
- * Copyright (C) 2005 Red Hat, Inc.
+ * Copyright (C) 2009 Red Hat, Inc.
+ * Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
* All rights reserved.
+ *
+ * Contributors:
+ * Hewlett-Packard Development Company, L.P.
+ * Bugfix for bug #195302
+ *
* END COPYRIGHT BLOCK **/
#ifdef HAVE_CONFIG_H
@@ -1874,6 +1880,7 @@ typedef struct passwordpolicyarray {
long pw_lockduration;
long pw_resetfailurecount;
int pw_gracelimit;
+ struct pw_scheme *pw_storagescheme;
} passwdPolicy;
typedef struct _slapdFrontendConfig {
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
index 1d545a0a..09f18e7c 100644
--- a/ldap/servers/slapd/slapi-plugin.h
+++ b/ldap/servers/slapd/slapi-plugin.h
@@ -32,8 +32,14 @@
*
*
* Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
- * Copyright (C) 2005 Red Hat, Inc.
+ * Copyright (C) 2009 Red Hat, Inc.
+ * Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
* All rights reserved.
+ *
+ * Contributors:
+ * Hewlett-Packard Development Company, L.P.
+ * Bugfix for bug #195302
+ *
* END COPYRIGHT BLOCK */
#ifdef HAVE_CONFIG_H
@@ -2274,6 +2280,9 @@ int slapi_pw_find_sv( Slapi_Value **vals, const Slapi_Value *v );
int slapi_is_encoded(char *value);
/* encode value with the specified algorithm */
char* slapi_encode(char *value, char *alg);
+/* encode value with the specified algorithm, or with local algorithm if pb
+ * and sdn are specified instead, or global algorithm if pb and sdn are null */
+char* slapi_encode_ext(Slapi_PBlock *pb, const Slapi_DN *sdn, char *value, char *alg);
/* UTF8 related */