⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ppolicy.c

📁 ldap服务器源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* $OpenLDAP: pkg/ldap/servers/slapd/overlays/ppolicy.c,v 1.31.2.29 2007/02/08 12:31:24 hyc Exp $ *//* This work is part of OpenLDAP Software <http://www.openldap.org/>. * * Copyright 2004-2007 The OpenLDAP Foundation. * Portions Copyright 2004-2005 Howard Chu, Symas Corporation. * Portions Copyright 2004 Hewlett-Packard Company. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted only as authorized by the OpenLDAP * Public License. * * A copy of this license is available in the file LICENSE in the * top-level directory of the distribution or, alternatively, at * <http://www.OpenLDAP.org/license.html>. *//* ACKNOWLEDGEMENTS: * This work was developed by Howard Chu for inclusion in * OpenLDAP Software, based on prior work by Neil Dunbar (HP). * This work was sponsored by the Hewlett-Packard Company. */#include "portable.h"/* This file implements "Password Policy for LDAP Directories", * based on draft behera-ldap-password-policy-09 */#ifdef SLAPD_OVER_PPOLICY#include <ldap.h>#include "lutil.h"#include "slap.h"#if SLAPD_MODULES#define LIBLTDL_DLL_IMPORT	/* Win32: don't re-export libltdl's symbols */#include <ltdl.h>#endif#include <ac/errno.h>#include <ac/time.h>#include <ac/string.h>#include <ac/ctype.h>#include "config.h"#ifndef MODULE_NAME_SZ#define MODULE_NAME_SZ 256#endif/* Per-instance configuration information */typedef struct pp_info {	struct berval def_policy;	/* DN of default policy subentry */	int use_lockout;		/* send AccountLocked result? */	int hash_passwords;		/* transparently hash cleartext pwds */} pp_info;/* Our per-connection info - note, it is not per-instance, it is  * used by all instances */typedef struct pw_conn {	struct berval dn;	/* DN of restricted user */} pw_conn;static pw_conn *pwcons;static int ppolicy_cid;typedef struct pass_policy {	AttributeDescription *ad; /* attribute to which the policy applies */	int pwdMinAge; /* minimum time (seconds) until passwd can change */	int pwdMaxAge; /* time in seconds until pwd will expire after change */	int pwdInHistory; /* number of previous passwords kept */	int pwdCheckQuality; /* 0 = don't check quality, 1 = check if possible,						   2 = check mandatory; fail if not possible */	int pwdMinLength; /* minimum number of chars in password */	int pwdExpireWarning; /* number of seconds that warning controls are							sent before a password expires */	int pwdGraceAuthNLimit; /* number of times you can log in with an							expired password */	int pwdLockout; /* 0 = do not lockout passwords, 1 = lock them out */	int pwdLockoutDuration; /* time in seconds a password is locked out for */	int pwdMaxFailure; /* number of failed binds allowed before lockout */	int pwdFailureCountInterval; /* number of seconds before failure									counts are zeroed */	int pwdMustChange; /* 0 = users can use admin set password							1 = users must change password after admin set */	int pwdAllowUserChange; /* 0 = users cannot change their passwords								1 = users can change them */	int pwdSafeModify; /* 0 = old password doesn't need to come								with password change request							1 = password change must supply existing pwd */	char pwdCheckModule[MODULE_NAME_SZ]; /* name of module to dynamically										    load to check password */} PassPolicy;typedef struct pw_hist {	time_t t;	/* timestamp of history entry */	struct berval pw;	/* old password hash */	struct berval bv;	/* text of entire entry */	struct pw_hist *next;} pw_hist;/* Operational attributes */static AttributeDescription *ad_pwdChangedTime, *ad_pwdAccountLockedTime,	*ad_pwdFailureTime, *ad_pwdHistory, *ad_pwdGraceUseTime, *ad_pwdReset,	*ad_pwdPolicySubentry;static struct schema_info {	char *def;	AttributeDescription **ad;} pwd_OpSchema[] = {	{	"( 1.3.6.1.4.1.42.2.27.8.1.16 "		"NAME ( 'pwdChangedTime' ) "		"DESC 'The time the password was last changed' "		"EQUALITY generalizedTimeMatch "		"ORDERING generalizedTimeOrderingMatch "		"SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 "		"SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )",		&ad_pwdChangedTime },	{	"( 1.3.6.1.4.1.42.2.27.8.1.17 "		"NAME ( 'pwdAccountLockedTime' ) "		"DESC 'The time an user account was locked' "		"EQUALITY generalizedTimeMatch "		"ORDERING generalizedTimeOrderingMatch "		"SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 "		"SINGLE-VALUE "#if 0		/* Not until MANAGEDIT control is released */		"NO-USER-MODIFICATION "#endif		"USAGE directoryOperation )",		&ad_pwdAccountLockedTime },	{	"( 1.3.6.1.4.1.42.2.27.8.1.19 "		"NAME ( 'pwdFailureTime' ) "		"DESC 'The timestamps of the last consecutive authentication failures' "		"EQUALITY generalizedTimeMatch "		"ORDERING generalizedTimeOrderingMatch "		"SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 "		"NO-USER-MODIFICATION USAGE directoryOperation )",		&ad_pwdFailureTime },	{	"( 1.3.6.1.4.1.42.2.27.8.1.20 "		"NAME ( 'pwdHistory' ) "		"DESC 'The history of users passwords' "		"EQUALITY octetStringMatch "		"SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 "		"NO-USER-MODIFICATION USAGE directoryOperation )",		&ad_pwdHistory },	{	"( 1.3.6.1.4.1.42.2.27.8.1.21 "		"NAME ( 'pwdGraceUseTime' ) "		"DESC 'The timestamps of the grace login once the password has expired' "		"EQUALITY generalizedTimeMatch "		"SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 "		"NO-USER-MODIFICATION USAGE directoryOperation )",		&ad_pwdGraceUseTime }, 	{	"( 1.3.6.1.4.1.42.2.27.8.1.22 "		"NAME ( 'pwdReset' ) "		"DESC 'The indication that the password has been reset' "		"EQUALITY booleanMatch "		"SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 "		"SINGLE-VALUE USAGE directoryOperation )",		&ad_pwdReset },	{	"( 1.3.6.1.4.1.42.2.27.8.1.23 "		"NAME ( 'pwdPolicySubentry' ) "		"DESC 'The pwdPolicy subentry in effect for this object' "		"EQUALITY distinguishedNameMatch "		"SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 "		"SINGLE-VALUE "#if 0		/* Not until MANAGEDIT control is released */		"NO-USER-MODIFICATION "#endif		"USAGE directoryOperation )",		&ad_pwdPolicySubentry },	{ NULL, NULL }};/* User attributes */static AttributeDescription *ad_pwdMinAge, *ad_pwdMaxAge, *ad_pwdInHistory,	*ad_pwdCheckQuality, *ad_pwdMinLength, *ad_pwdMaxFailure, 	*ad_pwdGraceAuthNLimit, *ad_pwdExpireWarning, *ad_pwdLockoutDuration,	*ad_pwdFailureCountInterval, *ad_pwdCheckModule, *ad_pwdLockout,	*ad_pwdMustChange, *ad_pwdAllowUserChange, *ad_pwdSafeModify,	*ad_pwdAttribute;#define TAB(name)	{ #name, &ad_##name }static struct schema_info pwd_UsSchema[] = {	TAB(pwdAttribute),	TAB(pwdMinAge),	TAB(pwdMaxAge),	TAB(pwdInHistory),	TAB(pwdCheckQuality),	TAB(pwdMinLength),	TAB(pwdMaxFailure),	TAB(pwdGraceAuthNLimit),	TAB(pwdExpireWarning),	TAB(pwdLockout),	TAB(pwdLockoutDuration),	TAB(pwdFailureCountInterval),	TAB(pwdCheckModule),	TAB(pwdMustChange),	TAB(pwdAllowUserChange),	TAB(pwdSafeModify),	{ NULL, NULL }};static ldap_pvt_thread_mutex_t chk_syntax_mutex;enum {	PPOLICY_DEFAULT = 1,	PPOLICY_HASH_CLEARTEXT,	PPOLICY_USE_LOCKOUT};static ConfigDriver ppolicy_cf_default;static ConfigTable ppolicycfg[] = {	{ "ppolicy_default", "policyDN", 2, 2, 0,	  ARG_DN|ARG_MAGIC|PPOLICY_DEFAULT, ppolicy_cf_default,	  "( OLcfgOvAt:12.1 NAME 'olcPPolicyDefault' "	  "DESC 'DN of a pwdPolicy object for uncustomized objects' "	  "SYNTAX OMsDN SINGLE-VALUE )", NULL, NULL },	{ "ppolicy_hash_cleartext", "on|off", 1, 2, 0,	  ARG_ON_OFF|ARG_OFFSET|PPOLICY_HASH_CLEARTEXT,	  (void *)offsetof(pp_info,hash_passwords),	  "( OLcfgOvAt:12.2 NAME 'olcPPolicyHashCleartext' "	  "DESC 'Hash passwords on add or modify' "	  "SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },	{ "ppolicy_use_lockout", "on|off", 1, 2, 0,	  ARG_ON_OFF|ARG_OFFSET|PPOLICY_USE_LOCKOUT,	  (void *)offsetof(pp_info,use_lockout),	  "( OLcfgOvAt:12.3 NAME 'olcPPolicyUseLockout' "	  "DESC 'Warn clients with AccountLocked' "	  "SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },	{ NULL, NULL, 0, 0, 0, ARG_IGNORED }};static ConfigOCs ppolicyocs[] = {	{ "( OLcfgOvOc:12.1 "	  "NAME 'olcPPolicyConfig' "	  "DESC 'Password Policy configuration' "	  "SUP olcOverlayConfig "	  "MAY ( olcPPolicyDefault $ olcPPolicyHashCleartext $ "	  "olcPPolicyUseLockout ) )",	  Cft_Overlay, ppolicycfg },	{ NULL, 0, NULL }};static intppolicy_cf_default( ConfigArgs *c ){	slap_overinst *on = (slap_overinst *)c->bi;	pp_info *pi = (pp_info *)on->on_bi.bi_private;	BackendDB *be = (BackendDB *)c->be;	const char *text;	int rc = ARG_BAD_CONF;	assert ( c->type == PPOLICY_DEFAULT );	Debug(LDAP_DEBUG_TRACE, "==> ppolicy_cf_default\n", 0, 0, 0);	switch ( c->op ) {	case SLAP_CONFIG_EMIT:		Debug(LDAP_DEBUG_TRACE, "==> ppolicy_cf_default emit\n", 0, 0, 0);		rc = 0;		if ( !BER_BVISEMPTY( &pi->def_policy )) {			rc = value_add_one( &c->rvalue_vals,					    &pi->def_policy );			if ( rc ) return rc;			rc = value_add_one( &c->rvalue_nvals,					    &pi->def_policy );		}		break;	case LDAP_MOD_DELETE:		Debug(LDAP_DEBUG_TRACE, "==> ppolicy_cf_default delete\n", 0, 0, 0);		if ( pi->def_policy.bv_val ) {			ber_memfree ( pi->def_policy.bv_val );			pi->def_policy.bv_val = NULL;		}		pi->def_policy.bv_len = 0;		rc = 0;		break;	case SLAP_CONFIG_ADD:		/* fallthrough to LDAP_MOD_ADD */	case LDAP_MOD_ADD:		Debug(LDAP_DEBUG_TRACE, "==> ppolicy_cf_default add\n", 0, 0, 0);		if ( pi->def_policy.bv_val )			ber_memfree ( pi->def_policy.bv_val );		pi->def_policy = c->value_ndn;		rc = 0;		break;	default:		abort ();	}	return rc;}static time_tparse_time( char *atm ){	struct lutil_tm tm;	struct lutil_timet tt;	time_t ret = (time_t)-1;	if ( lutil_parsetime( atm, &tm ) == 0) {		lutil_tm2time( &tm, &tt );		ret = tt.tt_sec;	}	return ret;}static intaccount_locked( Operation *op, Entry *e,		PassPolicy *pp, Modifications **mod ) {	Attribute       *la;	assert(mod != NULL);	if ( (la = attr_find( e->e_attrs, ad_pwdAccountLockedTime )) != NULL ) {		BerVarray vals = la->a_nvals;		/*		 * there is a lockout stamp - we now need to know if it's		 * a valid one.		 */		if (vals[0].bv_val != NULL) {			time_t then, now;			Modifications *m;			if (!pp->pwdLockoutDuration)				return 1;			if ((then = parse_time( vals[0].bv_val )) == (time_t)0)				return 1;			now = slap_get_time();			if (now < then + pp->pwdLockoutDuration)				return 1;			m = ch_calloc( sizeof(Modifications), 1 );			m->sml_op = LDAP_MOD_DELETE;			m->sml_flags = 0;			m->sml_type = ad_pwdAccountLockedTime->ad_cname;			m->sml_desc = ad_pwdAccountLockedTime;			m->sml_next = *mod;			*mod = m;		}	}	return 0;}/* IMPLICIT TAGS, all context-specific */#define PPOLICY_WARNING 0xa0L	/* constructed + 0 */#define PPOLICY_ERROR 0x81L		/* primitive + 1 */ #define PPOLICY_EXPIRE 0x80L	/* primitive + 0 */#define PPOLICY_GRACE  0x81L	/* primitive + 1 */static LDAPControl *create_passcontrol( int exptime, int grace, LDAPPasswordPolicyError err ){	char berbuf[LBER_ELEMENT_SIZEOF], bb2[LBER_ELEMENT_SIZEOF];	BerElement *ber = (BerElement *)berbuf, *b2 = (BerElement *)bb2;	LDAPControl *c;	struct berval bv;	c = ch_calloc( sizeof( LDAPControl ), 1 );	if ( c == NULL ) {		return NULL;	}	c->ldctl_oid = LDAP_CONTROL_PASSWORDPOLICYRESPONSE;	c->ldctl_iscritical = 0;	BER_BVZERO( &c->ldctl_value );	ber_init2( ber, NULL, LBER_USE_DER );	ber_printf( ber, "{" /*}*/ );	if ( exptime >= 0 ) {		ber_init2( b2, NULL, LBER_USE_DER );		ber_printf( b2, "ti", PPOLICY_EXPIRE, exptime );		ber_flatten2( b2, &bv, 1 );		(void)ber_free_buf(b2);		ber_printf( ber, "tO", PPOLICY_WARNING, &bv );		ch_free( bv.bv_val );	} else if ( grace > 0 ) {		ber_init2( b2, NULL, LBER_USE_DER );		ber_printf( b2, "ti", PPOLICY_GRACE, grace );		ber_flatten2( b2, &bv, 1 );		(void)ber_free_buf(b2);		ber_printf( ber, "tO", PPOLICY_WARNING, &bv );		ch_free( bv.bv_val );	}	if (err != PP_noError ) {		ber_printf( ber, "te", PPOLICY_ERROR, err );	}	ber_printf( ber, /*{*/ "N}" );	if (ber_flatten2( ber, &(c->ldctl_value), 1 ) == LBER_DEFAULT) {		ch_free(c);		c = NULL;	}	(void)ber_free_buf(ber);	return c;}static LDAPControl **add_passcontrol( Operation *op, SlapReply *rs, LDAPControl *ctrl ){	LDAPControl **ctrls, **oldctrls = rs->sr_ctrls;	int n;	n = 0;	if ( oldctrls ) {		for ( ; oldctrls[n]; n++ )			;	}	n += 2;	ctrls = op->o_tmpcalloc( sizeof( LDAPControl * ), n, op->o_tmpmemctx );	n = 0;	if ( oldctrls ) {		for ( ; oldctrls[n]; n++ ) {			ctrls[n] = oldctrls[n];		}	}	ctrls[n] = ctrl;	ctrls[n+1] = NULL;	rs->sr_ctrls = ctrls;	return oldctrls;}static voidppolicy_get( Operation *op, Entry *e, PassPolicy *pp ){	slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;	pp_info *pi = on->on_bi.bi_private;	Attribute *a;	BerVarray vals;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -