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

📄 ppolicy.c

📁 ldap服务器源码
💻 C
📖 第 1 页 / 共 5 页
字号:
			rs->sr_err = LDAP_CONSTRAINT_VIOLATION;			rs->sr_text = "Password is not being changed from existing value";			pErr = PP_passwordInHistory;			goto return_results;		}			if (pp.pwdInHistory < 1) goto do_modify;			/*		 * Iterate through the password history, and fail on any		 * password matches.		 */		at = *pa;		at.a_vals = cr;		cr[1].bv_val = NULL;		for(p=tl; p; p=p->next) {			cr[0] = p->pw;			/* FIXME: no access checking? */			rc = slap_passwd_check( op, NULL, &at, bv, &txt );						if (rc != LDAP_SUCCESS) continue;						rs->sr_err = LDAP_CONSTRAINT_VIOLATION;			rs->sr_text = "Password is in history of old passwords";			pErr = PP_passwordInHistory;			goto return_results;		}	}do_modify:	if (pwmod) {		struct berval timestamp;		char timebuf[ LDAP_LUTIL_GENTIME_BUFSIZE ];		time_t now = slap_get_time();		/* If the conn is restricted, set a callback to clear it		 * if the pwmod succeeds		 */		if (!BER_BVISEMPTY( &pwcons[op->o_conn->c_conn_idx].dn )) {			slap_callback *sc = op->o_tmpcalloc( 1, sizeof( slap_callback ),				op->o_tmpmemctx );			sc->sc_next = op->o_callback;			/* Must use sc_response to insure we reset on success, before			 * the client sees the response. Must use sc_cleanup to insure			 * that it gets cleaned up if sc_response is not called.			 */			sc->sc_response = ppolicy_mod_cb;			sc->sc_cleanup = ppolicy_mod_cb;			op->o_callback = sc;		}		/*		 * keep the necessary pwd.. operational attributes		 * up to date.		 */		timestamp.bv_val = timebuf;		timestamp.bv_len = sizeof(timebuf);		slap_timestamp( &now, &timestamp );		mods = (Modifications *) ch_calloc( sizeof( Modifications ), 1 );		mods->sml_desc = ad_pwdChangedTime;		if (pwmop != LDAP_MOD_DELETE) {			mods->sml_op = LDAP_MOD_REPLACE;			mods->sml_values = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );			ber_dupbv( &mods->sml_values[0], &timestamp );			BER_BVZERO( &mods->sml_values[1] );			assert( !BER_BVISNULL( &mods->sml_values[0] ) );		} else {			mods->sml_op = LDAP_MOD_DELETE;		}		mods->sml_flags = SLAP_MOD_INTERNAL;		mods->sml_next = NULL;		modtail->sml_next = mods;		modtail = mods;		if (attr_find(e->e_attrs, ad_pwdGraceUseTime )) {			mods = (Modifications *) ch_calloc( sizeof( Modifications ), 1 );			mods->sml_op = LDAP_MOD_DELETE;			mods->sml_desc = ad_pwdGraceUseTime;			mods->sml_flags = SLAP_MOD_INTERNAL;			mods->sml_next = NULL;			modtail->sml_next = mods;			modtail = mods;		}		if (attr_find(e->e_attrs, ad_pwdAccountLockedTime )) {			mods = (Modifications *) ch_calloc( sizeof( Modifications ), 1 );			mods->sml_op = LDAP_MOD_DELETE;			mods->sml_desc = ad_pwdAccountLockedTime;			mods->sml_flags = SLAP_MOD_INTERNAL;			mods->sml_next = NULL;			modtail->sml_next = mods;			modtail = mods;		}		if (attr_find(e->e_attrs, ad_pwdFailureTime )) {			mods = (Modifications *) ch_calloc( sizeof( Modifications ), 1 );			mods->sml_op = LDAP_MOD_DELETE;			mods->sml_desc = ad_pwdFailureTime;			mods->sml_flags = SLAP_MOD_INTERNAL;			mods->sml_next = NULL;			modtail->sml_next = mods;			modtail = mods;		}		/* Delete the pwdReset attribute, since it's being reset */		if ((zapReset) && (attr_find(e->e_attrs, ad_pwdReset ))) {			mods = (Modifications *) ch_calloc( sizeof( Modifications ), 1 );			mods->sml_op = LDAP_MOD_DELETE;			mods->sml_desc = ad_pwdReset;			mods->sml_flags = SLAP_MOD_INTERNAL;			mods->sml_next = NULL;			modtail->sml_next = mods;			modtail = mods;		}		if (pp.pwdInHistory > 0) {			if (hsize >= pp.pwdInHistory) {				/*				 * We use the >= operator, since we are going to add				 * the existing password attribute value into the				 * history - thus the cardinality of history values is				 * about to rise by one.				 *				 * If this would push it over the limit of history				 * values (remembering - the password policy could have				 * changed since the password was last altered), we must				 * delete at least 1 value from the pwdHistory list.				 *				 * In fact, we delete '(#pwdHistory attrs - max pwd				 * history length) + 1' values, starting with the oldest.				 * This is easily evaluated, since the linked list is				 * created in ascending time order.				 */				mods = (Modifications *) ch_calloc( sizeof( Modifications ), 1 );				mods->sml_op = LDAP_MOD_DELETE;				mods->sml_flags = SLAP_MOD_INTERNAL;				mods->sml_desc = ad_pwdHistory;				mods->sml_values = ch_calloc( sizeof( struct berval ),					hsize - pp.pwdInHistory + 2 );				BER_BVZERO( &mods->sml_values[ hsize - pp.pwdInHistory + 1 ] );				for(i=0,p=tl; i < (hsize - pp.pwdInHistory + 1); i++, p=p->next) {					BER_BVZERO( &mods->sml_values[i] );					ber_dupbv( &(mods->sml_values[i]), &p->bv );				}				mods->sml_next = NULL;				modtail->sml_next = mods;				modtail = mods;			}			free_pwd_history_list( &tl );			/*			 * Now add the existing password into the history list.			 * This will be executed even if the operation is to delete			 * the password entirely.			 *			 * This isn't in the spec explicitly, but it seems to make			 * sense that the password history list is the list of all			 * previous passwords - even if they were deleted. Thus, if			 * someone tries to add a historical password at some future			 * point, it will fail.			 */			if ((pa = attr_find( e->e_attrs, pp.ad )) != NULL) {				mods = (Modifications *) ch_malloc( sizeof( Modifications ) );				mods->sml_op = LDAP_MOD_ADD;				mods->sml_flags = SLAP_MOD_INTERNAL;				mods->sml_type.bv_val = NULL;				mods->sml_desc = ad_pwdHistory;				mods->sml_nvalues = NULL;				mods->sml_values = ch_calloc( sizeof( struct berval ), 2 );				mods->sml_values[ 1 ].bv_val = NULL;				mods->sml_values[ 1 ].bv_len = 0;				make_pwd_history_value( timebuf, &mods->sml_values[0], pa );				mods->sml_next = NULL;				modtail->sml_next = mods;				modtail = mods;			} else {				Debug( LDAP_DEBUG_TRACE,				"ppolicy_modify: password attr lookup failed\n", 0, 0, 0 );			}		}		/*		 * Controversial bit here. If the new password isn't hashed		 * (ie, is cleartext), we probably should hash it according		 * to the default hash. The reason for this is that we want		 * to use the policy if possible, but if we hash the password		 * before, then we're going to run into trouble when it		 * comes time to check the password.		 *		 * Now, the right thing to do is to use the extended password		 * modify operation, but not all software can do this,		 * therefore it makes sense to hash the new password, now		 * we know it passes the policy requirements.		 *		 * Of course, if the password is already hashed, then we		 * leave it alone.		 */		if ((pi->hash_passwords) && (addmod) && !newpw.bv_val && 			(password_scheme( &(addmod->sml_values[0]), NULL ) != LDAP_SUCCESS))		{			struct berval hpw, bv;						slap_passwd_hash( &(addmod->sml_values[0]), &hpw, &txt );			if (hpw.bv_val == NULL) {					/*					 * hashing didn't work. Emit an error.					 */				rs->sr_err = LDAP_OTHER;				rs->sr_text = txt;				goto return_results;			}			bv = addmod->sml_values[0];				/* clear and discard the clear password */			memset(bv.bv_val, 0, bv.bv_len);			ber_memfree(bv.bv_val);			addmod->sml_values[0] = hpw;		}	}	op->o_bd->bd_info = (BackendInfo *)on->on_info;	be_entry_release_r( op, e );	return SLAP_CB_CONTINUE;return_results:	free_pwd_history_list( &tl );	op->o_bd->bd_info = (BackendInfo *)on->on_info;	be_entry_release_r( op, e );	if ( send_ctrl ) {		LDAPControl *ctrl = NULL;		ctrl = create_passcontrol( -1, -1, pErr );		oldctrls = add_passcontrol( op, rs, ctrl );	}	send_ldap_result( op, rs );	if ( send_ctrl ) {		ctrls_cleanup( op, rs, oldctrls );	}	return rs->sr_err;}static intppolicy_parseCtrl(	Operation *op,	SlapReply *rs,	LDAPControl *ctrl ){	if ( ctrl->ldctl_value.bv_len ) {		rs->sr_text = "passwordPolicyRequest control value not empty";		return LDAP_PROTOCOL_ERROR;	}	op->o_ctrlflag[ppolicy_cid] = ctrl->ldctl_iscritical		? SLAP_CONTROL_CRITICAL		: SLAP_CONTROL_NONCRITICAL;	return LDAP_SUCCESS;}static intattrPretty(	Syntax *syntax,	struct berval *val,	struct berval *out,	void *ctx ){	AttributeDescription *ad = NULL;	const char *err;	int code;	code = slap_bv2ad( val, &ad, &err );	if ( !code ) {		ber_dupbv_x( out, &ad->ad_type->sat_cname, ctx );	}	return code;}static intattrNormalize(	slap_mask_t use,	Syntax *syntax,	MatchingRule *mr,	struct berval *val,	struct berval *out,	void *ctx ){	AttributeDescription *ad = NULL;	const char *err;	int code;	code = slap_bv2ad( val, &ad, &err );	if ( !code ) {		ber_str2bv_x( ad->ad_type->sat_oid, 0, 1, out, ctx );	}	return code;}static intppolicy_db_init(	BackendDB *be){	slap_overinst *on = (slap_overinst *) be->bd_info;	/* Has User Schema been initialized yet? */	if ( !pwd_UsSchema[0].ad[0] ) {		const char *err;		int i, code;		for (i=0; pwd_UsSchema[i].def; i++) {			code = slap_str2ad( pwd_UsSchema[i].def, pwd_UsSchema[i].ad, &err );			if ( code ) {				fprintf( stderr, "User Schema Load failed %d: %s\n", code, err );				return code;			}		}		{			Syntax *syn;			MatchingRule *mr;			syn = ch_malloc( sizeof( Syntax ));			*syn = *ad_pwdAttribute->ad_type->sat_syntax;			syn->ssyn_pretty = attrPretty;			ad_pwdAttribute->ad_type->sat_syntax = syn;			mr = ch_malloc( sizeof( MatchingRule ));			*mr = *ad_pwdAttribute->ad_type->sat_equality;			mr->smr_normalize = attrNormalize;			ad_pwdAttribute->ad_type->sat_equality = mr;		}	}	on->on_bi.bi_private = ch_calloc( sizeof(pp_info), 1 );	if ( dtblsize && !pwcons )		pwcons = ch_calloc(sizeof(pw_conn), dtblsize );	return 0;}static intppolicy_db_open(    BackendDB *be){	return overlay_register_control( be, LDAP_CONTROL_PASSWORDPOLICYREQUEST );}static intppolicy_close(	BackendDB *be){	slap_overinst *on = (slap_overinst *) be->bd_info;	pp_info *pi = on->on_bi.bi_private;		free( pwcons );	free( pi->def_policy.bv_val );	free( pi );	return 0;}static char *extops[] = {	LDAP_EXOP_MODIFY_PASSWD,	NULL};static slap_overinst ppolicy;int ppolicy_initialize(){	LDAPAttributeType *at;	const char *err;	int i, code;	for (i=0; pwd_OpSchema[i].def; i++) {		at = ldap_str2attributetype( pwd_OpSchema[i].def, &code, &err,			LDAP_SCHEMA_ALLOW_ALL );		if ( !at ) {			fprintf( stderr, "AttributeType Load failed %s %s\n",				ldap_scherr2str(code), err );			return code;		}		code = at_add( at, 0, NULL, &err );		if ( !code ) {			slap_str2ad( at->at_names[0], pwd_OpSchema[i].ad, &err );		}		ldap_memfree( at );		if ( code ) {			fprintf( stderr, "AttributeType Load failed %s %s\n",				scherr2str(code), err );			return code;		}		/* Allow Manager to set these as needed */		if ( is_at_no_user_mod( (*pwd_OpSchema[i].ad)->ad_type )) {			(*pwd_OpSchema[i].ad)->ad_type->sat_flags |=				SLAP_AT_MANAGEABLE;		}	}	code = register_supported_control( LDAP_CONTROL_PASSWORDPOLICYREQUEST,		SLAP_CTRL_ADD|SLAP_CTRL_BIND|SLAP_CTRL_MODIFY|SLAP_CTRL_HIDE, extops,		ppolicy_parseCtrl, &ppolicy_cid );	if ( code != LDAP_SUCCESS ) {		fprintf( stderr, "Failed to register control %d\n", code );		return code;	}	ldap_pvt_thread_mutex_init( &chk_syntax_mutex );	ppolicy.on_bi.bi_type = "ppolicy";	ppolicy.on_bi.bi_db_init = ppolicy_db_init;	ppolicy.on_bi.bi_db_open = ppolicy_db_open;	ppolicy.on_bi.bi_db_close = ppolicy_close;	ppolicy.on_bi.bi_op_add = ppolicy_add;	ppolicy.on_bi.bi_op_bind = ppolicy_bind;	ppolicy.on_bi.bi_op_compare = ppolicy_restrict;	ppolicy.on_bi.bi_op_delete = ppolicy_restrict;	ppolicy.on_bi.bi_op_modify = ppolicy_modify;	ppolicy.on_bi.bi_op_search = ppolicy_restrict;	ppolicy.on_bi.bi_connection_destroy = ppolicy_connection_destroy;	ppolicy.on_bi.bi_cf_ocs = ppolicyocs;	code = config_register_schema( ppolicycfg, ppolicyocs );	if ( code ) return code;	return overlay_register( &ppolicy );}#if SLAPD_OVER_PPOLICY == SLAPD_MOD_DYNAMICint init_module(int argc, char *argv[]) {	return ppolicy_initialize();}#endif#endif	/* defined(SLAPD_OVER_PPOLICY) */

⌨️ 快捷键说明

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