示例#1
0
文件: null.c 项目: bagel/openldap-ga
static int
null_back_bind( Operation *op, SlapReply *rs )
{
	struct null_info *ni = (struct null_info *) op->o_bd->be_private;

	if ( ni->ni_bind_allowed || be_isroot_pw( op ) ) {
		/* front end will send result on success (0) */
		return LDAP_SUCCESS;
	}

	rs->sr_err = LDAP_INVALID_CREDENTIALS;
	send_ldap_result( op, rs );

	return rs->sr_err;
}
示例#2
0
int
monitor_back_bind( Operation *op, SlapReply *rs )
{
	Debug(LDAP_DEBUG_ARGS, "==> monitor_back_bind: dn: %s\n", 
			op->o_req_dn.bv_val, 0, 0 );

	if ( be_isroot_pw( op ) ) {
		return LDAP_SUCCESS;
	}

	rs->sr_err = LDAP_INVALID_CREDENTIALS;
	send_ldap_result( op, rs );

	return rs->sr_err;
}
示例#3
0
static int
retcode_op_func( Operation *op, SlapReply *rs )
{
	slap_overinst	*on = (slap_overinst *)op->o_bd->bd_info;
	retcode_t	*rd = (retcode_t *)on->on_bi.bi_private;

	retcode_item_t	*rdi;
	struct berval		nrdn, npdn;

	slap_callback		*cb = NULL;

	/* sleep as required */
	retcode_sleep( rd->rd_sleep );

	if ( !dnIsSuffix( &op->o_req_ndn, &rd->rd_npdn ) ) {
		if ( RETCODE_INDIR( rd ) ) {
			switch ( op->o_tag ) {
			case LDAP_REQ_ADD:
				return retcode_op_add( op, rs );

			case LDAP_REQ_BIND:
				/* skip if rootdn */
				/* FIXME: better give the db a chance? */
				if ( be_isroot_pw( op ) ) {
					return LDAP_SUCCESS;
				}
				return retcode_op_internal( op, rs );

			case LDAP_REQ_SEARCH:
				if ( op->ors_scope == LDAP_SCOPE_BASE ) {
					rs->sr_err = retcode_op_internal( op, rs );
					switch ( rs->sr_err ) {
					case SLAP_CB_CONTINUE:
						if ( rs->sr_nentries == 0 ) {
							break;
						}
						rs->sr_err = LDAP_SUCCESS;
						/* fallthru */

					default:
						send_ldap_result( op, rs );
						break;
					}
					return rs->sr_err;
				}
				break;

			case LDAP_REQ_MODIFY:
			case LDAP_REQ_DELETE:
			case LDAP_REQ_MODRDN:
			case LDAP_REQ_COMPARE:
				return retcode_op_internal( op, rs );
			}
		}

		return SLAP_CB_CONTINUE;
	}

	if ( op->o_tag == LDAP_REQ_SEARCH
			&& op->ors_scope != LDAP_SCOPE_BASE
			&& op->o_req_ndn.bv_len == rd->rd_npdn.bv_len )
	{
		return retcode_send_onelevel( op, rs );
	}

	dnParent( &op->o_req_ndn, &npdn );
	if ( npdn.bv_len != rd->rd_npdn.bv_len ) {
		rs->sr_err = LDAP_NO_SUCH_OBJECT;
		rs->sr_matched = rd->rd_pdn.bv_val;
		send_ldap_result( op, rs );
		rs->sr_matched = NULL;
		return rs->sr_err;
	}

	dnRdn( &op->o_req_ndn, &nrdn );

	for ( rdi = rd->rd_item; rdi != NULL; rdi = rdi->rdi_next ) {
		struct berval	rdi_nrdn;

		dnRdn( &rdi->rdi_ndn, &rdi_nrdn );
		if ( dn_match( &nrdn, &rdi_nrdn ) ) {
			break;
		}
	}

	if ( rdi != NULL && rdi->rdi_mask != SN_DG_OP_ALL ) {
		retcode_op_e	o_tag = SN_DG_OP_NONE;

		switch ( op->o_tag ) {
		case LDAP_REQ_ADD:
			o_tag = SN_DG_OP_ADD;
			break;

		case LDAP_REQ_BIND:
			o_tag = SN_DG_OP_BIND;
			break;

		case LDAP_REQ_COMPARE:
			o_tag = SN_DG_OP_COMPARE;
			break;

		case LDAP_REQ_DELETE:
			o_tag = SN_DG_OP_DELETE;
			break;

		case LDAP_REQ_MODIFY:
			o_tag = SN_DG_OP_MODIFY;
			break;

		case LDAP_REQ_MODRDN:
			o_tag = SN_DG_OP_RENAME;
			break;

		case LDAP_REQ_SEARCH:
			o_tag = SN_DG_OP_SEARCH;
			break;

		case LDAP_REQ_EXTENDED:
			o_tag = SN_DG_EXTENDED;
			break;

		default:
			/* Should not happen */
			break;
		}

		if ( !( o_tag & rdi->rdi_mask ) ) {
			return SLAP_CB_CONTINUE;
		}
	}

	if ( rdi == NULL ) {
		rs->sr_matched = rd->rd_pdn.bv_val;
		rs->sr_err = LDAP_NO_SUCH_OBJECT;
		rs->sr_text = "retcode not found";

	} else {
		if ( rdi->rdi_flags & RDI_PRE_DISCONNECT ) {
			return rs->sr_err = SLAPD_DISCONNECT;
		}

		rs->sr_err = rdi->rdi_err;
		rs->sr_text = rdi->rdi_text.bv_val;
		rs->sr_matched = rdi->rdi_matched.bv_val;

		/* FIXME: we only honor the rdi_ref field in case rdi_err
		 * is LDAP_REFERRAL otherwise send_ldap_result() bails out */
		if ( rs->sr_err == LDAP_REFERRAL ) {
			BerVarray	ref;

			if ( rdi->rdi_ref != NULL ) {
				ref = rdi->rdi_ref;
			} else {
				ref = default_referral;
			}

			if ( ref != NULL ) {
				rs->sr_ref = referral_rewrite( ref,
					NULL, &op->o_req_dn, LDAP_SCOPE_DEFAULT );

			} else {
				rs->sr_err = LDAP_OTHER;
				rs->sr_text = "bad referral object";
			}
		}

		retcode_sleep( rdi->rdi_sleeptime );
	}

	switch ( op->o_tag ) {
	case LDAP_REQ_EXTENDED:
		if ( rdi == NULL ) {
			break;
		}
		cb = ( slap_callback * )ch_malloc( sizeof( slap_callback ) );
		memset( cb, 0, sizeof( slap_callback ) );
		cb->sc_cleanup = retcode_cleanup_cb;
		op->o_callback = cb;
		break;

	default:
		if ( rdi && !BER_BVISNULL( &rdi->rdi_unsolicited_oid ) ) {
			ber_int_t	msgid = op->o_msgid;

			/* RFC 4511 unsolicited response */

			op->o_msgid = 0;
			if ( strcmp( rdi->rdi_unsolicited_oid.bv_val, "0" ) == 0 ) {
				send_ldap_result( op, rs );

			} else {
				ber_tag_t	tag = op->o_tag;

				op->o_tag = LDAP_REQ_EXTENDED;
				rs->sr_rspoid = rdi->rdi_unsolicited_oid.bv_val;
				if ( !BER_BVISNULL( &rdi->rdi_unsolicited_data ) ) {
					rs->sr_rspdata = &rdi->rdi_unsolicited_data;
				}
				send_ldap_extended( op, rs );
				rs->sr_rspoid = NULL;
				rs->sr_rspdata = NULL;
				op->o_tag = tag;

			}
			op->o_msgid = msgid;

		} else {
			send_ldap_result( op, rs );
		}

		if ( rs->sr_ref != NULL ) {
			ber_bvarray_free( rs->sr_ref );
			rs->sr_ref = NULL;
		}
		rs->sr_matched = NULL;
		rs->sr_text = NULL;

		if ( rdi && rdi->rdi_flags & RDI_POST_DISCONNECT ) {
			return rs->sr_err = SLAPD_DISCONNECT;
		}
		break;
	}

	return rs->sr_err;
}
示例#4
0
int
ldbm_back_bind(
    Backend		*be,
    Connection		*conn,
    Operation		*op,
    struct berval	*dn,
    struct berval	*ndn,
    int			method,
    struct berval	*cred,
    struct berval	*edn
)
{
	struct ldbminfo	*li = (struct ldbminfo *) be->be_private;
	Entry		*e;
	Attribute	*a;
	int		rc;
	Entry		*matched;
#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
	char		krbname[MAX_K_NAME_SZ + 1];
	AttributeDescription *krbattr = slap_schema.si_ad_krbName;
	AUTH_DAT	ad;
#endif

	AttributeDescription *password = slap_schema.si_ad_userPassword;

#ifdef NEW_LOGGING
	LDAP_LOG( BACK_LDBM, ENTRY, 
		"ldbm_back_bind: dn: %s.\n", dn->bv_val, 0, 0 );
#else
	Debug(LDAP_DEBUG_ARGS, "==> ldbm_back_bind: dn: %s\n", dn->bv_val, 0, 0);
#endif

	dn = ndn;

	/* grab giant lock for reading */
	ldap_pvt_thread_rdwr_rlock(&li->li_giant_rwlock);

	/* get entry with reader lock */
	if ( (e = dn2entry_r( be, dn, &matched )) == NULL ) {
		char *matched_dn = NULL;
		BerVarray refs = NULL;

		if( matched != NULL ) {
			matched_dn = ch_strdup( matched->e_dn );

			refs = is_entry_referral( matched )
				? get_entry_referrals( be, conn, op, matched )
				: NULL;

			cache_return_entry_r( &li->li_cache, matched );

		} else {
			refs = referral_rewrite( default_referral,
				NULL, dn, LDAP_SCOPE_DEFAULT );
		}

		ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock);

		/* allow noauth binds */
		rc = 1;
		if ( method == LDAP_AUTH_SIMPLE ) {
			if ( be_isroot_pw( be, conn, dn, cred ) ) {
				ber_dupbv( edn, be_root_dn( be ) );
				rc = 0; /* front end will send result */

			} else if ( refs != NULL ) {
				send_ldap_result( conn, op, LDAP_REFERRAL,
					matched_dn, NULL, refs, NULL );

			} else {
				send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
					NULL, NULL, NULL, NULL );
			}

		} else if ( refs != NULL ) {
			send_ldap_result( conn, op, LDAP_REFERRAL,
				matched_dn, NULL, refs, NULL );

		} else {
			send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
				NULL, NULL, NULL, NULL );
		}

		if ( refs ) ber_bvarray_free( refs );
		if ( matched_dn ) free( matched_dn );
		return( rc );
	}

	ber_dupbv( edn, &e->e_name );

	/* check for deleted */

	if ( is_entry_alias( e ) ) {
		/* entry is an alias, don't allow bind */
#ifdef NEW_LOGGING
		LDAP_LOG( BACK_LDBM, INFO, 
			"ldbm_back_bind: entry (%s) is an alias.\n", e->e_dn, 0, 0 );
#else
		Debug( LDAP_DEBUG_TRACE, "entry is alias\n", 0,
		    0, 0 );
#endif


		send_ldap_result( conn, op, LDAP_ALIAS_PROBLEM,
		    NULL, "entry is alias", NULL, NULL );

		rc = 1;
		goto return_results;
	}

	if ( is_entry_referral( e ) ) {
		/* entry is a referral, don't allow bind */
		BerVarray refs = get_entry_referrals( be,
			conn, op, e );

#ifdef NEW_LOGGING
		LDAP_LOG( BACK_LDBM, INFO, 
			   "ldbm_back_bind: entry(%s) is a referral.\n", e->e_dn, 0, 0 );
#else
		Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0,
		    0, 0 );
#endif


		if( refs != NULL ) {
			send_ldap_result( conn, op, LDAP_REFERRAL,
				e->e_dn, NULL, refs, NULL );

		} else {
			send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
				NULL, NULL, NULL, NULL );
		}

		ber_bvarray_free( refs );

		rc = 1;
		goto return_results;
	}

	switch ( method ) {
	case LDAP_AUTH_SIMPLE:
		/* check for root dn/passwd */
		if ( be_isroot_pw( be, conn, dn, cred ) ) {
			/* front end will send result */
			if(edn->bv_val != NULL) free( edn->bv_val );
			ber_dupbv( edn, be_root_dn( be ) );
			rc = 0;
			goto return_results;
		}

		if ( ! access_allowed( be, conn, op, e,
			password, NULL, ACL_AUTH, NULL ) )
		{
			send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
				NULL, NULL, NULL, NULL );
			rc = 1;
			goto return_results;
		}

		if ( (a = attr_find( e->e_attrs, password )) == NULL ) {
			send_ldap_result( conn, op, LDAP_INAPPROPRIATE_AUTH,
			    NULL, NULL, NULL, NULL );

			/* stop front end from sending result */
			rc = 1;
			goto return_results;
		}

		if ( slap_passwd_check( conn, a, cred ) != 0 ) {
			send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
				NULL, NULL, NULL, NULL );
			/* stop front end from sending result */
			rc = 1;
			goto return_results;
		}

		rc = 0;
		break;

#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
	case LDAP_AUTH_KRBV41:
		if ( krbv4_ldap_auth( be, cred, &ad ) != LDAP_SUCCESS ) {
			send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
			    NULL, NULL, NULL, NULL );
			rc = 1;
			goto return_results;
		}

		if ( ! access_allowed( be, conn, op, e,
			krbattr, NULL, ACL_AUTH, NULL ) )
		{
			send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
				NULL, NULL, NULL, NULL );
			rc = 1;
			goto return_results;
		}

		sprintf( krbname, "%s%s%s@%s", ad.pname, *ad.pinst ? "."
		    : "", ad.pinst, ad.prealm );

		if ( (a = attr_find( e->e_attrs, krbattr )) == NULL ) {
			/*
			 * no krbname values present:  check against DN
			 */
			if ( strcasecmp( dn->bv_val, krbname ) == 0 ) {
				rc = 0;
				break;
			}
			send_ldap_result( conn, op, LDAP_INAPPROPRIATE_AUTH,
			    NULL, NULL, NULL, NULL );
			rc = 1;
			goto return_results;

		} else {	/* look for krbname match */
			struct berval	krbval;

			krbval.bv_val = krbname;
			krbval.bv_len = strlen( krbname );

			if ( value_find( a->a_desc, a->a_vals, &krbval ) != 0 ) {
				send_ldap_result( conn, op,
				    LDAP_INVALID_CREDENTIALS,
					NULL, NULL, NULL, NULL );
				rc = 1;
				goto return_results;
			}
		}
		rc = 0;
		break;

	case LDAP_AUTH_KRBV42:
		send_ldap_result( conn, op, LDAP_UNWILLING_TO_PERFORM,
			NULL, "Kerberos bind step 2 not supported",
			NULL, NULL );
		/* stop front end from sending result */
		rc = LDAP_UNWILLING_TO_PERFORM;
		goto return_results;
#endif

	default:
		send_ldap_result( conn, op, LDAP_STRONG_AUTH_NOT_SUPPORTED,
		    NULL, "authentication method not supported", NULL, NULL );
		rc = 1;
		goto return_results;
	}

return_results:;
	/* free entry and reader lock */
	cache_return_entry_r( &li->li_cache, e );
	ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock);

	/* front end will send result on success (rc==0) */
	return( rc );
}