Esempio n. 1
0
int
Ldap_get_filter_list( BerElement *ber, char *text )
{
	//Filter		**new;
	int		err;
	ber_tag_t	tag;
	ber_len_t	len;
	char		*last;
	char 		textbuf[128];
	//new=f;
	for ( tag = ber_first_element( ber, &len, &last );
		tag != LBER_DEFAULT;
		tag = ber_next_element( ber, &len, last ) )
			{
				err = Ldap_get_filter( ber, text);
				if ( err != LDAP_SUCCESS )
				{
					printf("Ldap_get_Filter_list Error \n\n");
					//new = &(*new)->f_next;
					return( err );
				}	
			}
	//printf("Debug: 1 time get_list OK!\n");
	return( LDAP_SUCCESS );
}	
Esempio n. 2
0
/***********************************************************************
 *      ber_first_element     (WLDAP32.@)
 *
 * Return the tag of the first element in a set or sequence.
 *
 * PARAMS
 *  berelement [I] Pointer to a berelement structure.
 *  len        [O] Receives the length of the first element.
 *  opaque     [O] Receives a pointer to a cookie.
 *
 * RETURNS
 *  Success: Tag of the first element.
 *  Failure: LBER_DEFAULT (no more data).
 *
 * NOTES
 *  len and cookie should be passed to ber_next_element.
 */
ULONG CDECL WLDAP32_ber_first_element( BerElement *berelement, ULONG *len, CHAR **opaque )
{
#ifdef HAVE_LDAP
    return ber_first_element( berelement, len, opaque );
#else
    return LBER_ERROR;
#endif
}
Esempio n. 3
0
static int count_key(BerElement *ber)
{
	char *end;
	ber_len_t len;
	ber_tag_t tag;
	int count = 0;

	/* Server Side Sort Control is a SEQUENCE of SEQUENCE */
	for ( tag = ber_first_element( ber, &len, &end );
		  tag == LBER_SEQUENCE;
		  tag = ber_next_element( ber, &len, end ))
	{
		tag = ber_skip_tag( ber, &len );
		ber_skip_data( ber, len );
		++count;
	}
	ber_rewind( ber );

	return count;
}
Esempio n. 4
0
	int  checkModReq(BerElement *ber)
	{
		/*
	 * Parse the modify request.  It looks like this:
	 *
	 *	ModifyRequest := [APPLICATION 6] SEQUENCE {
	 *		name	DistinguishedName,
	 *		mods	SEQUENCE OF SEQUENCE {
	 *			operation	ENUMERATED {
	 *				add	(0),
	 *				delete	(1),
	 *				replace	(2)
	 *			},
	 *			modification	SEQUENCE {
	 *				type	AttributeType,
	 *				values	SET OF AttributeValue
	 *			}
	 *		}
	 *	}
	 */
	
		struct berval dn = BER_BVNULL;
		char		textbuf[ SLAP_TEXT_BUFLEN ];
		size_t		textlen = sizeof( textbuf );
		ber_tag_t	tag;
		ber_len_t	len;
		char		*last;
		int rc;

		rc = LDAP_SUCCESS;
		
		
				/* get the name */
		if ( ber_scanf( ber, "{m", /*}*/ &dn ) == LBER_ERROR ) {
			printf(">>Error<< MOD DN Decode Error.\n");
			return -1;
		}
	
		printf("|-MOD DN:\t%s\n", dn.bv_val);
		
		for ( tag = ber_first_element( ber, &len, &last );
			tag != LBER_DEFAULT;
			tag = ber_next_element( ber, &len, last ) ){
			
			ber_int_t mop;
			Modifications tmp, *mod;

			tmp.sml_nvalues = NULL;

			if ( ber_scanf( ber, "{e{m[W]}}", &mop,
			    &tmp.sml_type, &tmp.sml_values ) == LBER_ERROR )
				{
					printf(">>Error<< MOD Attr list Decode Error\n");
					return -1;
				}
				
			printf("|--Mod Type:\t%s\n", LdapModTypeStr[mop]);
				if(tmp.sml_values == NULL){
					//Delete would be with a value
					printf("|---%s\n", tmp.sml_type.bv_val);
				}else{
					printf("|---%s:\t%s\n", tmp.sml_type.bv_val, tmp.sml_values->bv_val);
				}
		}
		return rc;
	}
Esempio n. 5
0
static int
ldap_build_entry(
		Operation	*op,
		LDAPMessage	*e,
		Entry		*ent,
		struct berval	*bdn )
{
	struct berval	a;
	BerElement	ber = *ldap_get_message_ber( e );
	Attribute	*attr, **attrp;
	const char	*text;
	int		last;
	char *lastb;
	ber_len_t len;

	/* safe assumptions ... */
	assert( ent != NULL );
	BER_BVZERO( &ent->e_bv );

	if ( ber_scanf( &ber, "{m", bdn ) == LBER_ERROR ) {
		return LDAP_DECODING_ERROR;
	}

	/*
	 * Note: this may fail if the target host(s) schema differs
	 * from the one known to the meta, and a DN with unknown
	 * attributes is returned.
	 * 
	 * FIXME: should we log anything, or delegate to dnNormalize?
	 */
	/* Note: if the distinguished values or the naming attributes
	 * change, should we massage them as well?
	 */
	if ( dnPrettyNormal( NULL, bdn, &ent->e_name, &ent->e_nname,
		op->o_tmpmemctx ) != LDAP_SUCCESS )
	{
		return LDAP_INVALID_DN_SYNTAX;
	}

	ent->e_attrs = NULL;
	if ( ber_first_element( &ber, &len, &lastb ) != LBER_SEQUENCE ) {
		return LDAP_SUCCESS;
	}

	attrp = &ent->e_attrs;
	while ( ber_next_element( &ber, &len, lastb ) == LBER_SEQUENCE &&
		ber_scanf( &ber, "{m", &a ) != LBER_ERROR ) {
		int				i;
		slap_syntax_validate_func	*validate;
		slap_syntax_transform_func	*pretty;

		attr = attr_alloc( NULL );
		if ( attr == NULL ) {
			return LDAP_OTHER;
		}
		if ( slap_bv2ad( &a, &attr->a_desc, &text ) 
				!= LDAP_SUCCESS )
		{
			if ( slap_bv2undef_ad( &a, &attr->a_desc, &text,
				SLAP_AD_PROXIED ) != LDAP_SUCCESS )
			{
				Debug( LDAP_DEBUG_ANY, 
					"%s ldap_build_entry: "
					"slap_bv2undef_ad(%s): %s\n",
					op->o_log_prefix, a.bv_val, text );

				( void )ber_scanf( &ber, "x" /* [W] */ );
				attr_free( attr );
				continue;
			}
		}

		/* no subschemaSubentry */
		if ( attr->a_desc == slap_schema.si_ad_subschemaSubentry
			|| attr->a_desc == slap_schema.si_ad_entryDN )
		{

			/* 
			 * We eat target's subschemaSubentry because
			 * a search for this value is likely not
			 * to resolve to the appropriate backend;
			 * later, the local subschemaSubentry is
			 * added.
			 *
			 * We also eat entryDN because the frontend
			 * will reattach it without checking if already
			 * present...
			 */
			( void )ber_scanf( &ber, "x" /* [W] */ );
			attr_free( attr );
			continue;
		}
		
		if ( ber_scanf( &ber, "[W]", &attr->a_vals ) == LBER_ERROR
				|| attr->a_vals == NULL )
		{
			/*
			 * Note: attr->a_vals can be null when using
			 * values result filter
			 */
			attr->a_vals = (struct berval *)&slap_dummy_bv;
		}

		validate = attr->a_desc->ad_type->sat_syntax->ssyn_validate;
		pretty = attr->a_desc->ad_type->sat_syntax->ssyn_pretty;

		if ( !validate && !pretty ) {
			attr->a_nvals = NULL;
			attr_free( attr );
			goto next_attr;
		}

		for ( i = 0; !BER_BVISNULL( &attr->a_vals[i] ); i++ ) ;
		last = i;

		/*
		 * check that each value is valid per syntax
		 * and pretty if appropriate
		 */
		for ( i = 0; i<last; i++ ) {
			struct berval	pval;
			int		rc;

			if ( pretty ) {
				rc = ordered_value_pretty( attr->a_desc,
					&attr->a_vals[i], &pval, NULL );

			} else {
				rc = ordered_value_validate( attr->a_desc,
					&attr->a_vals[i], 0 );
			}

			if ( rc != LDAP_SUCCESS ) {
				ObjectClass *oc;

				/* check if, by chance, it's an undefined objectClass */
				if ( attr->a_desc == slap_schema.si_ad_objectClass &&
						( oc = oc_bvfind_undef( &attr->a_vals[i] ) ) != NULL )
				{
					ber_dupbv( &pval, &oc->soc_cname );
					rc = LDAP_SUCCESS;

				} else {
					ber_memfree( attr->a_vals[i].bv_val );
					if ( --last == i ) {
						BER_BVZERO( &attr->a_vals[i] );
						break;
					}
					attr->a_vals[i] = attr->a_vals[last];
					BER_BVZERO( &attr->a_vals[last] );
					i--;
				}
			}

			if ( rc == LDAP_SUCCESS && pretty ) {
				ber_memfree( attr->a_vals[i].bv_val );
				attr->a_vals[i] = pval;
			}
		}
		attr->a_numvals = last = i;
		if ( last == 0 && attr->a_vals != &slap_dummy_bv ) {
			attr->a_nvals = NULL;
			attr_free( attr );
			goto next_attr;
		}

		if ( last && attr->a_desc->ad_type->sat_equality &&
				attr->a_desc->ad_type->sat_equality->smr_normalize )
		{
			attr->a_nvals = ch_malloc( ( last + 1 )*sizeof( struct berval ) );
			for ( i = 0; i < last; i++ ) {
				int		rc;

				rc = ordered_value_normalize(
					SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
					attr->a_desc,
					attr->a_desc->ad_type->sat_equality,
					&attr->a_vals[i], &attr->a_nvals[i],
					NULL );

				if ( rc != LDAP_SUCCESS ) {
					ber_memfree( attr->a_vals[i].bv_val );
					if ( --last == i ) {
						BER_BVZERO( &attr->a_vals[i] );
						break;
					}
					attr->a_vals[i] = attr->a_vals[last];
					BER_BVZERO( &attr->a_vals[last] );
					i--;
				}
			}
			BER_BVZERO( &attr->a_nvals[i] );
			if ( last == 0 ) {
				attr_free( attr );
				goto next_attr;
			}

		} else {
			attr->a_nvals = attr->a_vals;
		}

		attr->a_numvals = last;

		/* Handle sorted vals, strip dups but keep the attr */
		if ( attr->a_desc->ad_type->sat_flags & SLAP_AT_SORTED_VAL ) {
			while ( attr->a_numvals > 1 ) {
				int rc = slap_sort_vals( (Modifications *)attr, &text, &i, op->o_tmpmemctx );
				if ( rc != LDAP_TYPE_OR_VALUE_EXISTS )
					break;

				/* Strip duplicate values */
				if ( attr->a_nvals != attr->a_vals )
					ber_memfree( attr->a_nvals[i].bv_val );
				ber_memfree( attr->a_vals[i].bv_val );
				attr->a_numvals--;

				assert( i >= 0 );
				if ( (unsigned)i < attr->a_numvals ) {
					attr->a_vals[i] = attr->a_vals[attr->a_numvals];
					if ( attr->a_nvals != attr->a_vals )
						attr->a_nvals[i] = attr->a_nvals[attr->a_numvals];
				}
				BER_BVZERO(&attr->a_vals[attr->a_numvals]);
				if ( attr->a_nvals != attr->a_vals )
					BER_BVZERO(&attr->a_nvals[attr->a_numvals]);
			}
			attr->a_flags |= SLAP_ATTR_SORTED_VALS;
		}

		*attrp = attr;
		attrp = &attr->a_next;

next_attr:;
	}

	return LDAP_SUCCESS;
}
Esempio n. 6
0
static int
cldap_parsemsg( LDAP *ld, int msgid, BerElement *ber,
	LDAPMessage **res, char *base )
{
    unsigned int	tag, len;
    int		      rc;
    size_t        baselen, slen;
    char		      *dn, *p, *cookie;
    LDAPMessage	*chain, *prev, *ldm;
    struct berval	*bv;

    rc = LDAP_DECODING_ERROR;	/* pessimistic */
    ldm = chain = prev = NULLMSG;
    baselen = ( base == NULL ) ? 0 : strlen( base );
    bv = NULL;

    for ( tag = ber_first_element( ber, &len, &cookie );
	    tag != LBER_DEFAULT && rc != LDAP_SUCCESS;
	    tag = ber_next_element( ber, &len, cookie )) {
	if (( ldm = (LDAPMessage *)calloc( 1, sizeof(LDAPMessage)))
		== NULL || ( ldm->lm_ber = alloc_ber_with_options( ld ))
		== NULLBER ) {
	    rc = LDAP_NO_MEMORY;
	    break;	/* return w/error*/
	}
	ldm->lm_msgid = msgid;
	ldm->lm_msgtype = tag;

	if ( tag == LDAP_RES_SEARCH_RESULT ) {
	    Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 125, "cldap_parsemsg got search result\n"),
		    0, 0, 0 );

	    if ( ber_get_stringal( ber, &bv ) == LBER_DEFAULT ) {
		break;	/* return w/error */
	    }

	    if ( ber_printf( ldm->lm_ber, "to", tag, bv->bv_val,
		    bv->bv_len ) == -1 ) {
		break;	/* return w/error */
	    }
	    ber_bvfree( bv );
	    bv = NULL;
	    rc = LDAP_SUCCESS;

	} else if ( tag == LDAP_RES_SEARCH_ENTRY ) {
	    if ( ber_scanf( ber, "{aO", &dn, &bv ) == LBER_ERROR ) {
		break;	/* return w/error */
	    }
	    Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 126, "cldap_parsemsg entry %s\n"), dn, 0, 0 );
	    if ( dn != NULL && *(dn + ( slen = strlen(dn)) - 1) == '*' &&
		    baselen > 0 ) {
		/*
		 * substitute original searchbase for trailing '*'
		 */
		if (( p = (char *)malloc( slen + baselen )) == NULL ) {
		    rc = LDAP_NO_MEMORY;
		    free( dn );
		    break;	/* return w/error */
		}
		strcpy( p, dn );
		strcpy( p + slen - 1, base );
		free( dn );
		dn = p;
	    }

	    if ( ber_printf( ldm->lm_ber, "t{so}", tag, dn, bv->bv_val,
		    bv->bv_len ) == -1 ) {
		break;	/* return w/error */
	    }
	    free( dn );
	    ber_bvfree( bv );
	    bv = NULL;
		
	} else {
	    Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 127, "cldap_parsemsg got unknown tag %d\n"),
		    tag, 0, 0 );
	    rc = LDAP_PROTOCOL_ERROR;
	    break;	/* return w/error */
	}

	/* Reset message ber so we can read from it later.  Gack! */
	ldm->lm_ber->ber_end = ldm->lm_ber->ber_ptr;
	ldm->lm_ber->ber_ptr = ldm->lm_ber->ber_buf;

#ifdef LDAP_DEBUG
	if ( ldap_debug & LDAP_DEBUG_PACKETS ) {
	    fprintf( stderr, "cldap_parsemsg add message id %d type %d:\n",
		    ldm->lm_msgid, ldm->lm_msgtype  );
	    ber_dump( ldm->lm_ber, 1 );
	}
#endif /* LDAP_DEBUG */

#ifndef NO_CACHE
	    if ( ld->ld_cache != NULL ) {
		add_result_to_cache( ld, ldm );
	    }
#endif /* NO_CACHE */

	if ( chain == NULL ) {
	    chain = ldm;
	} else {
	    prev->lm_chain = ldm;
	}
	prev = ldm;
	ldm = NULL;
    }

    /* dispose of any leftovers */
    if ( ldm != NULL ) {
	if ( ldm->lm_ber != NULLBER ) {
	    ber_free( ldm->lm_ber, 1 );
	}
	free( ldm );
    }
    if ( bv != NULL ) {
	ber_bvfree( bv );
    }

    /* return chain, calling result2error if we got anything at all */
    *res = chain;
    return(( *res == NULLMSG ) ? rc : ldap_result2error( ld, *res, 0 ));
}
Esempio n. 7
0
int checkADDReq(BerElement *ber)
{
	/*
	 * Parse the add request.  It looks like this:
	 *
	 *	AddRequest := [APPLICATION 14] SEQUENCE {
	 *		name	DistinguishedName,
	 *		attrs	SEQUENCE OF SEQUENCE {
	 *			type	AttributeType,
	 *			values	SET OF AttributeValue
	 *		}
	 *	}
	 */
	BerElement	*ber1 = ber;
	char		*last;
	struct berval	dn = BER_BVNULL;
	ber_len_t	len;
	ber_tag_t	tag;
	Modifications	*modlist = NULL;
	Modifications	**modtail = &modlist;
	Modifications	tmp;
	char		textbuf[ SLAP_TEXT_BUFLEN ];
	size_t		textlen = sizeof( textbuf );	
	int		rc = 0;
	int		freevals = 1;
	
		/* get the name */
	if ( ber_scanf( ber, "{m", /*}*/ &dn ) == LBER_ERROR ) {
		printf(">>Error<< ADD DN Decode Error.\n");
		return -1;
	}
	printf("|-ADD DN:\t%s\n", dn.bv_val);
	printf("|-ADD Attributes list:\n");
	/* get the attrs */
	for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT;
	    tag = ber_next_element( ber, &len, last ) )
		{
			Modifications *mod;
			ber_tag_t rtag;

			tmp.sml_nvalues = NULL;
			
			rtag = ber_scanf( ber, "{m{W}}", &tmp.sml_type, &tmp.sml_values );

			if ( rtag == LBER_ERROR ) {
				printf(">>Error<< ADD Attribute Decode Error.\n");
				return -1;
				
			}

			if ( tmp.sml_values == NULL ) {
				printf("Ber decode ADD opt No value found.\n");
				return -1;
			}
			if(tmp.sml_values == NULL){
					printf("|---%s\n", tmp.sml_type.bv_val);
				}else{
					printf("|--%s:\t%s\n", tmp.sml_type.bv_val, tmp.sml_values->bv_val );
				}
		}
}
Esempio n. 8
0
/*
 * Get an annotated value from the BerElement. Returns 0 on
 * success, -1 on failure.
 */
static int
my_ber_scanf_value(BerElement *ber, Slapi_Value **value, PRBool *deleted)
{
	struct berval *attrval = NULL;
	ber_len_t len = -1;
	ber_tag_t tag;
	CSN *csn = NULL;
	char csnstring[CSN_STRSIZE + 1];
	CSNType csntype;
	char *lasti;

	PR_ASSERT(ber && value && deleted);

	if (NULL == ber && NULL == value)
	{
		slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "my_ber_scanf_value BAD 1\n");
		goto loser;
	}

	*value = NULL;

	/* Each value is a sequence */
	if (ber_scanf(ber, "{O", &attrval) == LBER_ERROR)
	{
		slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "my_ber_scanf_value BAD 2\n");
		goto loser;
	}
	/* Allocate and fill in the attribute value */
	if ((*value = slapi_value_new_berval(attrval)) == NULL)
	{
		slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "my_ber_scanf_value BAD 3\n");
		goto loser;
	}

    /* check if this is a deleted value */
    if (ber_peek_tag(ber, &len) == LBER_BOOLEAN)
    {
        if (ber_scanf(ber, "b", deleted) == LBER_ERROR)
		{
			slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "my_ber_scanf_value BAD 4\n");
			goto loser;
		}
    }
        
    else /* default is present value */
    {
        *deleted = PR_FALSE;
    }

	/* Read the sequence of CSNs */
    for (tag = ber_first_element(ber, &len, &lasti);
		tag != LBER_ERROR && tag != LBER_END_OF_SEQORSET;
		tag = ber_next_element(ber, &len, lasti))
	{
		ber_int_t csntype_tmp;
		/* Each CSN is in a sequence that includes a csntype and CSN */
		len = CSN_STRSIZE;
		if (ber_scanf(ber, "{es}", &csntype_tmp, csnstring, &len) == LBER_ERROR)
		{
			slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "my_ber_scanf_value BAD 7 - bval is %s\n", attrval->bv_val);
			goto loser;
		}
		switch (csntype_tmp)
		{
		case CSN_TYPE_VALUE_UPDATED_ON_WIRE:
			csntype = CSN_TYPE_VALUE_UPDATED;
			break;
		case CSN_TYPE_VALUE_DELETED_ON_WIRE:
			csntype = CSN_TYPE_VALUE_DELETED;
			break;
		case CSN_TYPE_VALUE_DISTINGUISHED_ON_WIRE:
			csntype = CSN_TYPE_VALUE_DISTINGUISHED;
			break;
		default:
			slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "Error: preposterous CSN type "
				"%d received during total update.\n", csntype_tmp);
			goto loser;
		}
		csn = csn_new_by_string(csnstring);
		if (csn == NULL)
		{
			slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "my_ber_scanf_value BAD 8\n");
			goto loser;
		}
		value_add_csn(*value, csntype, csn);
        csn_free (&csn);
	}

	if (ber_scanf(ber, "}") == LBER_ERROR) /* End of annotated attribute value seq */
	{
		slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "my_ber_scanf_value BAD 10\n");
		goto loser;
	}
	
    if (attrval)
        ber_bvfree(attrval); 
	return 0;

loser:
	/* Free any stuff we allocated */
	if (csn)
        csn_free (&csn);
    if (attrval)
        ber_bvfree(attrval); 
    if (value)
    {
        slapi_value_free (value);
    }
   
	return -1;
}
Esempio n. 9
0
/* Convert a structured DN from an X.509 certificate into an LDAPV3 DN.
 * x509_name must be raw DER. If func is non-NULL, the
 * constructed DN will use numeric OIDs to identify attributeTypes,
 * and the func() will be invoked to rewrite the DN with the given
 * flags.
 *
 * Otherwise the DN will use shortNames from a hardcoded table.
 */
int
ldap_X509dn2bv( void *x509_name, struct berval *bv, LDAPDN_rewrite_func *func,
	unsigned flags )
{
	LDAPDN	newDN;
	LDAPRDN	newRDN;
	LDAPAVA *newAVA, *baseAVA;
	BerElementBuffer berbuf;
	BerElement *ber = (BerElement *)&berbuf;
	char oids[8192], *oidptr = oids, *oidbuf = NULL;
	void *ptrs[2048];
	char *dn_end, *rdn_end;
	int i, navas, nrdns, rc = LDAP_SUCCESS;
	size_t dnsize, oidrem = sizeof(oids), oidsize = 0;
	int csize;
	ber_tag_t tag;
	ber_len_t len;
	oid_name *oidname;

	struct berval	Oid, Val, oid2, *in = x509_name;

	assert( bv != NULL );

	bv->bv_len = 0;
	bv->bv_val = NULL;

	navas = 0;
	nrdns = 0;

	/* A DN is a SEQUENCE of RDNs. An RDN is a SET of AVAs.
	 * An AVA is a SEQUENCE of attr and value.
	 * Count the number of AVAs and RDNs
	 */
	ber_init2( ber, in, LBER_USE_DER );
	tag = ber_peek_tag( ber, &len );
	if ( tag != LBER_SEQUENCE )
		return LDAP_DECODING_ERROR;

	for ( tag = ber_first_element( ber, &len, &dn_end );
		tag == LBER_SET;
		tag = ber_next_element( ber, &len, dn_end )) {
		nrdns++;
		for ( tag = ber_first_element( ber, &len, &rdn_end );
			tag == LBER_SEQUENCE;
			tag = ber_next_element( ber, &len, rdn_end )) {
			tag = ber_skip_tag( ber, &len );
			ber_skip_data( ber, len );
			navas++;
		}
	}

	/* Allocate the DN/RDN/AVA stuff as a single block */    
	dnsize = sizeof(LDAPRDN) * (nrdns+1);
	dnsize += sizeof(LDAPAVA *) * (navas+nrdns);
	dnsize += sizeof(LDAPAVA) * navas;
	if (dnsize > sizeof(ptrs)) {
		newDN = (LDAPDN)LDAP_MALLOC( dnsize );
		if ( newDN == NULL )
			return LDAP_NO_MEMORY;
	} else {
		newDN = (LDAPDN)(char *)ptrs;
	}
	
	newDN[nrdns] = NULL;
	newRDN = (LDAPRDN)(newDN + nrdns+1);
	newAVA = (LDAPAVA *)(newRDN + navas + nrdns);
	baseAVA = newAVA;

	/* Rewind and start extracting */
	ber_rewind( ber );

	tag = ber_first_element( ber, &len, &dn_end );
	for ( i = nrdns - 1; i >= 0; i-- ) {
		newDN[i] = newRDN;

		for ( tag = ber_first_element( ber, &len, &rdn_end );
			tag == LBER_SEQUENCE;
			tag = ber_next_element( ber, &len, rdn_end )) {

			*newRDN++ = newAVA;
			tag = ber_skip_tag( ber, &len );
			tag = ber_get_stringbv( ber, &Oid, LBER_BV_NOTERM );
			if ( tag != LBER_TAG_OID ) {
				rc = LDAP_DECODING_ERROR;
				goto nomem;
			}

			oid2.bv_val = oidptr;
			oid2.bv_len = oidrem;
			if ( ber_decode_oid( &Oid, &oid2 ) < 0 ) {
				rc = LDAP_DECODING_ERROR;
				goto nomem;
			}
			oidname = find_oid( &oid2 );
			if ( !oidname ) {
				newAVA->la_attr = oid2;
				oidptr += oid2.bv_len + 1;
				oidrem -= oid2.bv_len + 1;

				/* Running out of OID buffer space? */
				if (oidrem < 128) {
					if ( oidsize == 0 ) {
						oidsize = sizeof(oids) * 2;
						oidrem = oidsize;
						oidbuf = LDAP_MALLOC( oidsize );
						if ( oidbuf == NULL ) goto nomem;
						oidptr = oidbuf;
					} else {
						char *old = oidbuf;
						oidbuf = LDAP_REALLOC( oidbuf, oidsize*2 );
						if ( oidbuf == NULL ) goto nomem;
						/* Buffer moved! Fix AVA pointers */
						if ( old != oidbuf ) {
							LDAPAVA *a;
							long dif = oidbuf - old;

							for (a=baseAVA; a<=newAVA; a++){
								if (a->la_attr.bv_val >= old &&
									a->la_attr.bv_val <= (old + oidsize))
									a->la_attr.bv_val += dif;
							}
						}
						oidptr = oidbuf + oidsize - oidrem;
						oidrem += oidsize;
						oidsize *= 2;
					}
				}
			} else {
				if ( func ) {
					newAVA->la_attr = oidname->oid;
				} else {
					newAVA->la_attr = oidname->name;
				}
			}
			newAVA->la_private = NULL;
			newAVA->la_flags = LDAP_AVA_STRING;
			tag = ber_get_stringbv( ber, &Val, LBER_BV_NOTERM );
			switch(tag) {
			case LBER_TAG_UNIVERSAL:
				/* This uses 32-bit ISO 10646-1 */
				csize = 4; goto to_utf8;
			case LBER_TAG_BMP:
				/* This uses 16-bit ISO 10646-1 */
				csize = 2; goto to_utf8;
			case LBER_TAG_TELETEX:
				/* This uses 8-bit, assume ISO 8859-1 */
				csize = 1;
to_utf8:		rc = ldap_ucs_to_utf8s( &Val, csize, &newAVA->la_value );
				newAVA->la_flags |= LDAP_AVA_NONPRINTABLE;
allocd:
				newAVA->la_flags |= LDAP_AVA_FREE_VALUE;
				if (rc != LDAP_SUCCESS) goto nomem;
				break;
			case LBER_TAG_UTF8:
				newAVA->la_flags |= LDAP_AVA_NONPRINTABLE;
				/* This is already in UTF-8 encoding */
			case LBER_TAG_IA5:
			case LBER_TAG_PRINTABLE:
				/* These are always 7-bit strings */
				newAVA->la_value = Val;
				break;
			case LBER_BITSTRING:
				/* X.690 bitString value converted to RFC4517 Bit String */
				rc = der_to_ldap_BitString( &Val, &newAVA->la_value );
				goto allocd;
			default:
				/* Not a string type at all */
				newAVA->la_flags = 0;
				newAVA->la_value = Val;
				break;
			}
			newAVA++;
		}
		*newRDN++ = NULL;
		tag = ber_next_element( ber, &len, dn_end );
	}
		
	if ( func ) {
		rc = func( newDN, flags, NULL );
		if ( rc != LDAP_SUCCESS )
			goto nomem;
	}

	rc = ldap_dn2bv_x( newDN, bv, LDAP_DN_FORMAT_LDAPV3, NULL );

nomem:
	for (;baseAVA < newAVA; baseAVA++) {
		if (baseAVA->la_flags & LDAP_AVA_FREE_ATTR)
			LDAP_FREE( baseAVA->la_attr.bv_val );
		if (baseAVA->la_flags & LDAP_AVA_FREE_VALUE)
			LDAP_FREE( baseAVA->la_value.bv_val );
	}

	if ( oidsize != 0 )
		LDAP_FREE( oidbuf );
	if ( newDN != (LDAPDN)(char *) ptrs )
		LDAP_FREE( newDN );
	return rc;
}
Esempio n. 10
0
int ldap_pvt_get_controls(
	BerElement *ber,
	LDAPControl ***ctrls )
{
	int nctrls;
	ber_tag_t tag;
	ber_len_t len;
	char *opaque;

	assert( ber != NULL );

	if( ctrls == NULL ) {
		return LDAP_SUCCESS;
	}
	*ctrls = NULL;

	len = ber_pvt_ber_remaining( ber );

	if( len == 0) {
		/* no controls */
		return LDAP_SUCCESS;
	}

	if(( tag = ber_peek_tag( ber, &len )) != LDAP_TAG_CONTROLS ) {
		if( tag == LBER_ERROR ) {
			/* decoding error */
			return LDAP_DECODING_ERROR;
		}

		/* ignore unexpected input */
		return LDAP_SUCCESS;
	}

	/* set through each element */
	nctrls = 0;
	*ctrls = LDAP_MALLOC( 1 * sizeof(LDAPControl *) );

	if( *ctrls == NULL ) {
		return LDAP_NO_MEMORY;
	}

	*ctrls[nctrls] = NULL;

	for( tag = ber_first_element( ber, &len, &opaque );
		tag != LBER_ERROR;
		tag = ber_next_element( ber, &len, opaque ) )
	{
		LDAPControl *tctrl;
		LDAPControl **tctrls;

		tctrl = LDAP_CALLOC( 1, sizeof(LDAPControl) );

		/* allocate pointer space for current controls (nctrls)
		 * + this control + extra NULL
		 */
		tctrls = (tctrl == NULL) ? NULL :
			LDAP_REALLOC(*ctrls, (nctrls+2) * sizeof(LDAPControl *));

		if( tctrls == NULL ) {
			/* one of the above allocation failed */

			if( tctrl != NULL ) {
				LDAP_FREE( tctrl );
			}

			ldap_controls_free(*ctrls);
			*ctrls = NULL;

			return LDAP_NO_MEMORY;
		}


		tctrls[nctrls++] = tctrl;
		tctrls[nctrls] = NULL;

		tag = ber_scanf( ber, "{a" /*}*/, &tctrl->ldctl_oid );

		if( tag == LBER_ERROR ) {
			*ctrls = NULL;
			ldap_controls_free( tctrls );
			return LDAP_DECODING_ERROR;
		}

		tag = ber_peek_tag( ber, &len );

		if( tag == LBER_BOOLEAN ) {
			ber_int_t crit;
			tag = ber_scanf( ber, "b", &crit );
			tctrl->ldctl_iscritical = crit ? (char) 0 : (char) ~0;
			tag = ber_peek_tag( ber, &len );
		}

		if( tag == LBER_OCTETSTRING ) {
			tag = ber_scanf( ber, "o", &tctrl->ldctl_value );
		} else {
			BER_BVZERO( &tctrl->ldctl_value );
		}

		*ctrls = tctrls;
	}
		
	return LDAP_SUCCESS;
}
Esempio n. 11
0
static int 
my_ber_scanf_attr (BerElement *ber, Slapi_Attr **attr, PRBool *deleted)
{
    char *attrtype = NULL;
    CSN *attr_deletion_csn = NULL;
    PRBool val_deleted;
    char *lasti;
    ber_len_t len;
    ber_tag_t tag;
    char *str = NULL;
    int rc;
    Slapi_Value *value = NULL;

    if (attr == NULL)
    {
        goto loser;
    }

    PR_ASSERT (ber && attr && deleted);

    /* allocate the attribute */
    *attr = slapi_attr_new ();
    if (*attr == NULL)
    {
        goto loser;
    }

	if (ber_scanf(ber, "{a", &attrtype) == LBER_ERROR) /* Begin sequence for this attr */
	{
		goto loser;
	}


    slapi_attr_init(*attr, attrtype);
    slapi_ch_free ((void **)&attrtype);

	/* The attribute deletion CSN is next and is optional? */
    if (ber_peek_tag(ber, &len) == LBER_OCTETSTRING)
    {
	    if (ber_scanf(ber, "a", &str) == LBER_ERROR)
	    {
		    goto loser;
	    }
	    attr_deletion_csn = csn_new_by_string(str);
	    slapi_ch_free((void **)&str);
    }

    if (attr_deletion_csn)
	{
		rc = attr_set_deletion_csn(*attr, attr_deletion_csn);
        csn_free (&attr_deletion_csn);
        if (rc != 0)
        {
            goto loser;
        }
	}

	/* The "attribute deleted" flag is next, and is optional */
	if (ber_peek_tag(ber, &len) == LBER_BOOLEAN)
	{
		if (ber_scanf(ber, "b", deleted) == LBER_DEFAULT)
		{
			goto loser;
		}
	} 
    else /* default is present */
    {
		*deleted = PR_FALSE;
	}
	
    /* loop over the list of attribute values */
	for (tag = ber_first_element(ber, &len, &lasti);
		tag != LBER_ERROR && tag != LBER_END_OF_SEQORSET;
		tag = ber_next_element(ber, &len, lasti))
	{

		value = NULL;		
		if (my_ber_scanf_value(ber, &value, &val_deleted) == -1)
		{
			goto loser;
		}

        if (val_deleted)
        {
			/* Add the value to the attribute */
			if (attr_add_deleted_value(*attr, value) == -1) /* attr has ownership of value */
			{
				goto loser;
			}
        }
        else
        {
            /* Add the value to the attribute */
			if (slapi_attr_add_value(*attr, value) == -1) /* attr has ownership of value */
			{
				goto loser;
			}
        }
		if (value)
			slapi_value_free(&value);
	}	

	if (ber_scanf(ber, "}") == LBER_ERROR) /* End sequence for this attribute */
	{
		goto loser;
	}

    return 0;
loser:
    if (attr && *attr)
        slapi_attr_free (attr);
    if (value)
        slapi_value_free (&value);

    slapi_ch_free_string(&attrtype);
    slapi_ch_free_string(&str);

    return -1;    
}
Esempio n. 12
0
int
ParseRequestControls(
   VDIR_OPERATION *    op,
   VDIR_LDAP_RESULT *  lr
   )
{
    int                     retVal = LDAP_SUCCESS;
    ber_tag_t               tag = LBER_ERROR;
    ber_len_t               len = 0;
    char *                  endOfCtrlsMarker = NULL;
    VDIR_LDAP_CONTROL **    control = &(op->reqControls);
    BerValue                lberBervType = {0};
    BerValue                lberBervCtlValue = {0};
    PSTR                    pszLocalErrorMsg = NULL;

    VMDIR_LOG_DEBUG( LDAP_DEBUG_TRACE, "ParseRequestControls: Begin." );

    *control = NULL;

#ifndef _WIN32
    if (ber_pvt_ber_remaining(op->ber) != 0)
#else
    if (LBER_DEFAULT != ber_peek_tag (op->ber, &len))
#endif
    {
        if (ber_peek_tag( op->ber, &len ) != LDAP_TAG_CONTROLS )
        {
            lr->errCode = LDAP_PROTOCOL_ERROR;
            retVal = LDAP_NOTICE_OF_DISCONNECT;
            BAIL_ON_VMDIR_ERROR_WITH_MSG(   retVal, (pszLocalErrorMsg),
                           "ParseRequestControls: Request controls expected, but something else is there in the PDU.");
        }

        // Get controls. ber_first_element => skip the sequence header, set the cursor at the 1st control in the SEQ of SEQ
        for( tag = ber_first_element( op->ber, &len, &endOfCtrlsMarker ); tag != LBER_ERROR;
             tag = ber_next_element( op->ber, &len, endOfCtrlsMarker ) )
        {
            // m => in-place
            if (ber_scanf( op->ber, "{m", &lberBervType ) == LBER_ERROR)
            {
                lr->errCode = LDAP_PROTOCOL_ERROR;
                retVal = LDAP_NOTICE_OF_DISCONNECT;
                BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg),
                                              "ParseRequestControls Error in reading control type from the PDU.");
            }
            if ( VmDirLogGetMask() & LDAP_DEBUG_ARGS)
            {
                VMDIR_LOG_INFO( LDAP_DEBUG_ARGS, "    Request Control: %s", lberBervType.bv_val );
            }
            if (VmDirAllocateMemory( sizeof( VDIR_LDAP_CONTROL), (PVOID *)control ) != 0)
            {
                retVal = lr->errCode = LDAP_OPERATIONS_ERROR;
                BAIL_ON_VMDIR_ERROR_WITH_MSG(   retVal, (pszLocalErrorMsg),
                                                "ParseRequestControls: VmDirAllocateMemory failed");
            }
            // type points into in-place ber and does NOT own its content
            (*control)->type = lberBervType.bv_val;
            (*control)->criticality = FALSE;
            tag = ber_peek_tag( op->ber, &len );

            if (tag == LBER_BOOLEAN)
            {
                ber_int_t criticality;
                if (ber_scanf( op->ber, "b", &criticality) == LBER_ERROR)
                {
                    lr->errCode = LDAP_PROTOCOL_ERROR;
                    retVal = LDAP_NOTICE_OF_DISCONNECT;
                    BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg),
                                            "ParseRequestControls: Error in reading control criticality from the PDU.");
                }
                if (criticality)
                {
                    (*control)->criticality = TRUE;
                }
                tag = ber_peek_tag( op->ber, &len );
            }

            if (tag == LBER_OCTETSTRING)
            {
                if (ber_scanf( op->ber, "m", &lberBervCtlValue) == LBER_ERROR)
                {
                    lr->errCode = LDAP_PROTOCOL_ERROR;
                    retVal = LDAP_NOTICE_OF_DISCONNECT;
                    BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg),
                                             "ParseRequestControls: ber_scanf failed while parsing the control value.");
                }
            }

            // SJ-TBD: Make sure that the control appears only once in the request, and it is present only in a search
            // request
            if (VmDirStringCompareA( (*control)->type, LDAP_CONTROL_SYNC, TRUE ) == 0)
            {
                if (VmDirdGetRunMode() != VMDIR_RUNMODE_NORMAL)
                {
                    // Why block out-bound replication when catching up during restore mode?
                    //
                    // Reason: Partners have high-water-mark (lastLocalUsn) corresponding to this replica that is being
                    // restored. If out-bound replication is not blocked while restore/catching-up is going on, originating
                    // or replicated updates (if this replica is the only partner) made between the current-local-usn and
                    // high-water-marks, that partners remember, will not get replicated out (even if the invocationId
                    // has been fixed/changed).

                    retVal = lr->errCode = LDAP_UNWILLING_TO_PERFORM;
                    BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg),
                                 "ParseRequestControls: Server not in normal mode, not allowing outward replication.");
                }

                if ((retVal = ParseSyncRequestControlVal( op, &lberBervCtlValue, &((*control)->value.syncReqCtrlVal),
                                                          lr)) != LDAP_SUCCESS)
                {
                    BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg),
                                                  "ParseRequestControls: ParseSyncRequestControlVal failed.");
                }
                op->syncReqCtrl = *control;
            }
            if (VmDirStringCompareA( (*control)->type, VDIR_LDAP_CONTROL_SHOW_DELETED_OBJECTS, TRUE ) == 0)
            {
                op->showDeletedObjectsCtrl = *control;
            }

            if (VmDirStringCompareA( (*control)->type, VDIR_LDAP_CONTROL_SHOW_MASTER_KEY, TRUE ) == 0)
            {
                op->showMasterKeyCtrl = *control;
            }

            if (VmDirStringCompareA((*control)->type, LDAP_CONTROL_CONSISTENT_WRITE, TRUE ) == 0)
            {
                op->strongConsistencyWriteCtrl = *control;
            }

            if (VmDirStringCompareA((*control)->type, VDIR_LDAP_CONTROL_MANAGEDDSAIT, TRUE ) == 0)
            {
                op->manageDsaITCtrl = *control;
            }

            if (VmDirStringCompareA( (*control)->type, LDAP_CONTROL_PAGEDRESULTS, TRUE ) == 0)
            {
                retVal = _ParsePagedResultControlVal( op,
                                                &lberBervCtlValue,
                                                &((*control)->value.pagedResultCtrlVal),
                                                lr);
                if (retVal != LDAP_SUCCESS)
                {
                    BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg),
                                                  "ParseRequestControls: _ParsePagedResultControlVal failed.");
                }
                op->showPagedResultsCtrl = *control;
            }

            if (VmDirStringCompareA( (*control)->type, LDAP_CONTROL_CONDITIONAL_WRITE, TRUE ) == 0)
            {
                retVal = _ParseCondWriteControlVal(
                            op,
                            &lberBervCtlValue,
                            &((*control)->value.condWriteCtrlVal),
                            lr);
                if (retVal != LDAP_SUCCESS)
                {
                    BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg),
                                                  "ParseRequestControls: _ParseConditionalWriteControlVal failed.");
                }
                op->pCondWriteCtrl = *control;
            }

            if (VmDirStringCompareA( (*control)->type, LDAP_APPEND_ENTRIES_CONTROL, TRUE ) == 0)
            {
                retVal = _ParseAppendEntriesControlVal( op,
                                                &lberBervCtlValue,
                                                &((*control)->value.appendEntriesCtrlVal),
                                                lr);
                if (retVal != LDAP_SUCCESS)
                {
                    BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg),
                                                  "ParseRequestControls: _ParseAppendEntriesControlVal failed.");
                }
                op->appendEntriesCtrl = *control;
            }

            if (VmDirStringCompareA( (*control)->type, LDAP_REQUEST_VOTE_CONTROL, TRUE ) == 0)
            {
                retVal = _ParseRequestVoteControlVal( op,
                                                &lberBervCtlValue,
                                                &((*control)->value.requestVoteCtrlVal),
                                                lr);
                if (retVal != LDAP_SUCCESS)
                {
                    BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg),
                                                  "ParseRequestControls: _ParseRequestVoteControlVal failed.");
                }
                op->requestVoteCtrl = *control;
            }

            if (VmDirStringCompareA( (*control)->type, VMDIR_LDAP_CONTROL_TXN_SPEC, TRUE ) == 0)
            {
                retVal = VmDirAllocateMemory(lberBervCtlValue.bv_len+1, (PVOID*)&((*control)->value.txnSpecCtrlVal).pszTxnId);
                BAIL_ON_VMDIR_ERROR(retVal);
                VmDirStringNCpyA(((*control)->value.txnSpecCtrlVal).pszTxnId, lberBervCtlValue.bv_len+1,
                                 lberBervCtlValue.bv_val, lberBervCtlValue.bv_len);
                op->txnSpecCtrl = *control;
                op->pBECtx->pszTxnId = (op->txnSpecCtrl->value.txnSpecCtrlVal).pszTxnId;
            }

            if ( ber_scanf( op->ber, "}") == LBER_ERROR ) // end of control
            {
                lr->errCode = LDAP_PROTOCOL_ERROR;
                retVal = LDAP_NOTICE_OF_DISCONNECT;
                BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg),
                                              "ParseRequestControls: ber_scanf failed while parsing the end of control");

            }
            control = &((*control)->next);
        }

        retVal = LDAP_SUCCESS;
    }

cleanup:
    VMDIR_LOG_DEBUG( LDAP_DEBUG_TRACE, "ParseRequestControls: End." );
    VMDIR_SAFE_FREE_MEMORY(pszLocalErrorMsg);

    return retVal;

error:
    DeleteControls(&(op->reqControls));

    if (pszLocalErrorMsg)
    {
        VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, pszLocalErrorMsg);
        VMDIR_APPEND_ERROR_MSG(lr->pszErrMsg, pszLocalErrorMsg);
    }

    goto cleanup;
}
Esempio n. 13
0
int
Ldap_get_ssa(BerElement *ber,struct berval *type, struct berval *value )
{
	ber_tag_t	tag;
	ber_len_t	len;
	char		*last;
	int	rc;
	struct berval desc, nvalue;
	

	if ( ber_scanf( ber, "{m" /*}*/, type ) == LBER_ERROR ) {
		return LBER_ERROR;
	}

	for ( tag = ber_first_element( ber, &len, &last );
		tag != LBER_DEFAULT;
		tag = ber_next_element( ber, &len, last ) )
		{

			if ( ber_scanf( ber, "m", value ) == LBER_ERROR ) {
				printf("| Filter-Decode Substring Error\n");
				return LBER_ERROR;
			
			}

			if ( value->bv_val == NULL || value->bv_len == 0 ) {
				rc = LBER_ERROR;
				printf("| Filter-Decode Substring Error\n");
				return rc;
			
			} 
#ifdef DEBUG			
			printf("Debug: tag =%X\n");
#endif
			switch ( tag ) {
				case LDAP_SUBSTRING_INITIAL:
#ifdef DEBUG				
					printf("Filter- Initial:value-%s\n", value->bv_val);
#endif				
					rc=LDAP_SUBSTRING_INITIAL;
					break;

				case LDAP_SUBSTRING_ANY:
#ifdef DEBUG
					printf("Filter- ANY:value-%s\n", value->bv_val);
#endif				
					rc=LDAP_SUBSTRING_ANY;
					break;

				case LDAP_SUBSTRING_FINAL:
#ifdef DEBUG
					printf("Filter- FINAL:value-%s\n", value->bv_val);
#endif				
					rc=LDAP_SUBSTRING_FINAL;
					break;

				default:
					rc = LBER_ERROR;
					printf("| Filter-Decode Substring Error\n");
					return rc;
			
			}
		}
		return rc /* LDAP_SUBSTR OPT : ANY INITIAL FINAL ERROR */ ;				
}
Esempio n. 14
0
DWORD
LwKrb5FindPac(
    krb5_context ctx,
    const krb5_ticket *pTgsTicket,
    const krb5_keyblock *serviceKey,
    OUT PVOID* ppchLogonInfo,
    OUT size_t* psLogonInfo
    )
{
    DWORD dwError = LW_ERROR_SUCCESS;
    //Do not free
    struct berval bv = {0};
    struct berval contents = {0};
    //Do not free
    krb5_authdata **ppCur = NULL;
    //Do not free associated buffer
    BerElement *ber = NULL;
    ber_tag_t tag = 0;
    ber_len_t len = 0;
    // Do not free
    char *cookie = NULL;
    int adType;
    ber_tag_t seqTag, context0Tag, context1Tag;
    char* pchLogonInfo = NULL;
    size_t sLogonInfo = 0;
    
    ber = ber_alloc_t(0);
    
    if (pTgsTicket && pTgsTicket->enc_part2)
    {
        ppCur = pTgsTicket->enc_part2->authorization_data;
    }

    while (ppCur && (*ppCur != NULL))
    {
        if (ppCur[0]->ad_type == AD_IF_RELEVANT_TYPE)
        {
            // This auth data contains a DER encoded sequence of more
            // auth data. One of them could be a pac.
            bv.bv_len = ppCur[0]->length;
            bv.bv_val = (char *)ppCur[0]->contents;
            ber_init2(ber, &bv, 0);

            tag = ber_first_element(ber, &len, &cookie);
            while (tag != LBER_ERROR)
            {
                // Free does nothing if pointer is NULL
                ber_memfree(contents.bv_val);
                contents.bv_val = NULL;

                tag = ber_scanf(ber,
                        "t{t[i]t[",
                        &seqTag,
                        &context0Tag,
                        &adType,
                        &context1Tag);
                if (tag == LBER_ERROR)
                {
                    // This auth data is invalid. Skip it and try
                    // the next one
                    break;
                }
                tag = ber_scanf(ber,
                        "o]}",
                        &contents);
                if (tag == LBER_ERROR)
                {
                    // This auth data is invalid. Skip it and try
                    // the next one
                    break;
                }

                if (adType == AD_WIN2K_PAC)
                {
                    dwError = LwKrb5VerifyPac(
                        ctx,
                        pTgsTicket,
                        &contents,
                        serviceKey,
                        &pchLogonInfo,
                        &sLogonInfo);
                    if (dwError == LW_ERROR_INVALID_MESSAGE)
                    {
                        dwError = LW_ERROR_SUCCESS;
                        continue;
                    }
                    BAIL_ON_LW_ERROR(dwError);
                    // Found a good PAC !
                    goto end_search;
                }

                //returns LBER_ERROR when there are no more elements left.
                tag = ber_next_element(ber, &len, cookie);
            }
        }

        ppCur++;
    }
end_search:

    *ppchLogonInfo = pchLogonInfo;
    *psLogonInfo = sLogonInfo;

cleanup:
    if (contents.bv_val != NULL)
    {
        ber_memfree(contents.bv_val);
    }
    if (ber != NULL)
    {
        ber_free(ber, 0);
    }

    return dwError;

error:
    LW_SAFE_FREE_MEMORY(pchLogonInfo);
    *ppchLogonInfo = NULL;
    goto cleanup;
}
Esempio n. 15
0
int
do_add( Connection *conn, Operation *op )
{
	BerElement	*ber = op->o_ber;
	char		*last;
	struct berval dn = { 0, NULL };
	ber_len_t	len;
	ber_tag_t	tag;
	Entry		*e;
	Backend		*be;
	Modifications	*modlist = NULL;
	Modifications	**modtail = &modlist;
	Modifications	tmp;
	const char *text;
	int			rc = LDAP_SUCCESS;
	int	manageDSAit;
#ifdef LDAP_SLAPI
	Slapi_PBlock	*pb = NULL;
#endif /* LDAP_SLAPI */

#ifdef NEW_LOGGING
	LDAP_LOG( OPERATION, ENTRY, "do_add: conn %d enter\n", conn->c_connid,0,0 );
#else
	Debug( LDAP_DEBUG_TRACE, "do_add\n", 0, 0, 0 );
#endif
	/*
	 * Parse the add request.  It looks like this:
	 *
	 *	AddRequest := [APPLICATION 14] SEQUENCE {
	 *		name	DistinguishedName,
	 *		attrs	SEQUENCE OF SEQUENCE {
	 *			type	AttributeType,
	 *			values	SET OF AttributeValue
	 *		}
	 *	}
	 */

	/* get the name */
	if ( ber_scanf( ber, "{m", /*}*/ &dn ) == LBER_ERROR ) {
#ifdef NEW_LOGGING
		LDAP_LOG( OPERATION, ERR, 
			"do_add: conn %d ber_scanf failed\n", conn->c_connid,0,0 );
#else
		Debug( LDAP_DEBUG_ANY, "do_add: ber_scanf failed\n", 0, 0, 0 );
#endif
		send_ldap_disconnect( conn, op,
			LDAP_PROTOCOL_ERROR, "decoding error" );
		return -1;
	}

	e = (Entry *) ch_calloc( 1, sizeof(Entry) );

	rc = dnPrettyNormal( NULL, &dn, &e->e_name, &e->e_nname );

	if( rc != LDAP_SUCCESS ) {
#ifdef NEW_LOGGING
		LDAP_LOG( OPERATION, ERR, 
			"do_add: conn %d invalid dn (%s)\n", conn->c_connid, dn.bv_val, 0 );
#else
		Debug( LDAP_DEBUG_ANY, "do_add: invalid dn (%s)\n", dn.bv_val, 0, 0 );
#endif
		send_ldap_result( conn, op, rc = LDAP_INVALID_DN_SYNTAX, NULL,
			    "invalid DN", NULL, NULL );
		goto done;
	}

#ifdef NEW_LOGGING
	LDAP_LOG( OPERATION, ARGS, 
		"do_add: conn %d  dn (%s)\n", conn->c_connid, e->e_dn, 0 );
#else
	Debug( LDAP_DEBUG_ARGS, "do_add: dn (%s)\n", e->e_dn, 0, 0 );
#endif

	/* get the attrs */
	for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT;
	    tag = ber_next_element( ber, &len, last ) )
	{
		Modifications *mod;
		ber_tag_t rtag;

		rtag = ber_scanf( ber, "{m{W}}", &tmp.sml_type, &tmp.sml_bvalues );

		if ( rtag == LBER_ERROR ) {
#ifdef NEW_LOGGING
			LDAP_LOG( OPERATION, ERR, 
				   "do_add: conn %d	 decoding error \n", conn->c_connid, 0, 0 );
#else
			Debug( LDAP_DEBUG_ANY, "do_add: decoding error\n", 0, 0, 0 );
#endif
			send_ldap_disconnect( conn, op,
				LDAP_PROTOCOL_ERROR, "decoding error" );
			rc = -1;
			goto done;
		}

		if ( tmp.sml_bvalues == NULL ) {
#ifdef NEW_LOGGING
			LDAP_LOG( OPERATION, INFO, 
				"do_add: conn %d	 no values for type %s\n",
				conn->c_connid, tmp.sml_type.bv_val, 0 );
#else
			Debug( LDAP_DEBUG_ANY, "no values for type %s\n",
				tmp.sml_type.bv_val, 0, 0 );
#endif
			send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR,
				NULL, "no values for attribute type", NULL, NULL );
			goto done;
		}
		mod  = (Modifications *) ch_malloc( sizeof(Modifications) );
		
		mod->sml_op = LDAP_MOD_ADD;
		mod->sml_next = NULL;
		mod->sml_desc = NULL;
		mod->sml_type = tmp.sml_type;
		mod->sml_bvalues = tmp.sml_bvalues;

		*modtail = mod;
		modtail = &mod->sml_next;
	}

	if ( ber_scanf( ber, /*{*/ "}") == LBER_ERROR ) {
#ifdef NEW_LOGGING
		LDAP_LOG( OPERATION, ERR, 
			"do_add: conn %d ber_scanf failed\n", conn->c_connid, 0, 0 );
#else
		Debug( LDAP_DEBUG_ANY, "do_add: ber_scanf failed\n", 0, 0, 0 );
#endif
		send_ldap_disconnect( conn, op,
			LDAP_PROTOCOL_ERROR, "decoding error" );
		rc = -1;
		goto done;
	}

	if( (rc = get_ctrls( conn, op, 1 )) != LDAP_SUCCESS ) {
#ifdef NEW_LOGGING
		LDAP_LOG( OPERATION, INFO, 
			"do_add: conn %d get_ctrls failed\n", conn->c_connid, 0, 0 );
#else
		Debug( LDAP_DEBUG_ANY, "do_add: get_ctrls failed\n", 0, 0, 0 );
#endif
		goto done;
	} 

	if ( modlist == NULL ) {
		send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR,
			NULL, "no attributes provided", NULL, NULL );
		goto done;
	}

	Statslog( LDAP_DEBUG_STATS, "conn=%lu op=%lu ADD dn=\"%s\"\n",
	    op->o_connid, op->o_opid, e->e_dn, 0, 0 );

	if( e->e_nname.bv_len == 0 ) {
		/* protocolError may be a more appropriate error */
		send_ldap_result( conn, op, rc = LDAP_ALREADY_EXISTS,
			NULL, "root DSE already exists",
			NULL, NULL );
		goto done;

	} else if ( bvmatch( &e->e_nname, &global_schemandn ) ) {
		send_ldap_result( conn, op, rc = LDAP_ALREADY_EXISTS,
			NULL, "subschema subentry already exists",
			NULL, NULL );
		goto done;
	}

	manageDSAit = get_manageDSAit( op );

	/*
	 * We could be serving multiple database backends.  Select the
	 * appropriate one, or send a referral to our "referral server"
	 * if we don't hold it.
	 */
	be = select_backend( &e->e_nname, manageDSAit, 0 );
	if ( be == NULL ) {
		BerVarray ref = referral_rewrite( default_referral,
			NULL, &e->e_name, LDAP_SCOPE_DEFAULT );
		if ( ref == NULL ) ref = default_referral;
		if ( ref != NULL ) {
			send_ldap_result( conn, op, rc = LDAP_REFERRAL,
				NULL, NULL, ref, NULL );

			if ( ref != default_referral ) ber_bvarray_free( ref );
		} else {
			send_ldap_result( conn, op,
					rc = LDAP_UNWILLING_TO_PERFORM,
					NULL, "referral missing", NULL, NULL );
		}
		goto done;
	}

	/* check restrictions */
	rc = backend_check_restrictions( be, conn, op, NULL, &text ) ;
	if( rc != LDAP_SUCCESS ) {
		send_ldap_result( conn, op, rc,
			NULL, text, NULL, NULL );
		goto done;
	}

	/* check for referrals */
	rc = backend_check_referrals( be, conn, op, &e->e_name, &e->e_nname );
	if ( rc != LDAP_SUCCESS ) {
		goto done;
	}

#ifdef LDAP_SLAPI
	pb = initAddPlugin( be, conn, op, &dn, e, manageDSAit );
#endif /* LDAP_SLAPI */

	/*
	 * do the add if 1 && (2 || 3)
	 * 1) there is an add function implemented in this backend;
	 * 2) this backend is master for what it holds;
	 * 3) it's a replica and the dn supplied is the updatedn.
	 */
	if ( be->be_add ) {
		/* do the update here */
		int repl_user = be_isupdate(be, &op->o_ndn );
#ifndef SLAPD_MULTIMASTER
		if ( !be->be_update_ndn.bv_len || repl_user )
#endif
		{
			int update = be->be_update_ndn.bv_len;
			char textbuf[SLAP_TEXT_BUFLEN];
			size_t textlen = sizeof textbuf;

			rc = slap_mods_check( modlist, update, &text,
				textbuf, textlen );

			if( rc != LDAP_SUCCESS ) {
				send_ldap_result( conn, op, rc,
					NULL, text, NULL, NULL );
				goto done;
			}

			if ( !repl_user ) {
				for( modtail = &modlist;
					*modtail != NULL;
					modtail = &(*modtail)->sml_next )
				{
					assert( (*modtail)->sml_op == LDAP_MOD_ADD );
					assert( (*modtail)->sml_desc != NULL );
				}
				rc = slap_mods_opattrs( be, op, modlist, modtail, &text,
					textbuf, textlen );
				if( rc != LDAP_SUCCESS ) {
					send_ldap_result( conn, op, rc,
						NULL, text, NULL, NULL );
					goto done;
				}
			}

			rc = slap_mods2entry( modlist, &e, repl_user, &text,
				textbuf, textlen );
			if( rc != LDAP_SUCCESS ) {
				send_ldap_result( conn, op, rc,
					NULL, text, NULL, NULL );
				goto done;
			}

#ifdef LDAP_SLAPI
			/*
			 * Call the preoperation plugin here, because the entry
			 * will actually contain something.
			 */
			rc = doPreAddPluginFNs( be, pb );
			if ( rc != LDAP_SUCCESS ) {
				/* plugin will have sent result */
				goto done;
			}
#endif /* LDAP_SLAPI */

			if ( (*be->be_add)( be, conn, op, e ) == 0 ) {
#ifdef SLAPD_MULTIMASTER
				if ( !repl_user )
#endif
				{
					replog( be, op, &e->e_name, &e->e_nname, e );
				}
				be_entry_release_w( be, conn, op, e );
				e = NULL;
			}

#ifndef SLAPD_MULTIMASTER
		} else {
			BerVarray defref;
			BerVarray ref;
#ifdef LDAP_SLAPI
			/*
			 * SLAPI_ADD_ENTRY will be empty, but this may be acceptable
			 * on replicas (for now, it involves the minimum code intrusion).
			 */
			rc = doPreAddPluginFNs( be, pb );
			if ( rc != LDAP_SUCCESS ) {
				/* plugin will have sent result */
				goto done;
			}
#endif /* LDAP_SLAPI */

			defref = be->be_update_refs
				? be->be_update_refs : default_referral;

			if ( defref ) {
				ref = referral_rewrite( defref,
					NULL, &e->e_name, LDAP_SCOPE_DEFAULT );

				send_ldap_result( conn, op, rc = LDAP_REFERRAL,
						NULL, NULL,
						ref ? ref : defref, NULL );

				if ( ref ) ber_bvarray_free( ref );
			} else {
				send_ldap_result( conn, op,
						rc = LDAP_UNWILLING_TO_PERFORM,
						NULL, "referral missing",
						NULL, NULL );
			}
#endif /* SLAPD_MULTIMASTER */
		}
	} else {
#ifdef LDAP_SLAPI
	    rc = doPreAddPluginFNs( be, pb );
	    if ( rc != LDAP_SUCCESS ) {
		/* plugin will have sent result */
		goto done;
	    }
#endif
#ifdef NEW_LOGGING
	    LDAP_LOG( OPERATION, INFO, 
		       "do_add: conn %d	 no backend support\n", conn->c_connid, 0, 0 );
#else
	    Debug( LDAP_DEBUG_ARGS, "	 do_add: no backend support\n", 0, 0, 0 );
#endif
	    send_ldap_result( conn, op, rc = LDAP_UNWILLING_TO_PERFORM,
			      NULL, "operation not supported within namingContext", NULL, NULL );
	}

#ifdef LDAP_SLAPI
	doPostAddPluginFNs( be, pb );
#endif /* LDAP_SLAPI */

done:
	if( modlist != NULL ) {
		slap_mods_free( modlist );
	}
	if( e != NULL ) {
		entry_free( e );
	}

	return rc;
}
Esempio n. 16
0
/*
 * Pull controls out of "ber" (if any present) and return them in "controlsp."
 * Returns an LDAP error code.
 */
int
nsldapi_get_controls( BerElement *ber, LDAPControl ***controlsp )
{
	LDAPControl		*newctrl;
	ber_tag_t		tag;
	ber_len_t		len;
	int			rc, maxcontrols, curcontrols;
	char			*last;

	/*
	 * Each LDAPMessage can have a set of controls appended
	 * to it. Controls are used to extend the functionality
	 * of an LDAP operation (e.g., add an attribute size limit
	 * to the search operation). These controls look like this:
	 *
	 *	Controls ::= SEQUENCE OF Control
	 *
	 *	Control ::= SEQUENCE {
	 *		controlType	LDAPOID,
	 *		criticality	BOOLEAN DEFAULT FALSE,
	 *		controlValue	OCTET STRING
	 *	}
	 */
	LDAPDebug( LDAP_DEBUG_TRACE, "=> nsldapi_get_controls\n", 0, 0, 0 );

	*controlsp = NULL;

	/*
         * check to see if controls were included
	 */
	if ( ber_get_option( ber, LBER_OPT_REMAINING_BYTES, &len ) != 0 ) {
		return( LDAP_DECODING_ERROR );	/* unexpected error */
	}
	if ( len == 0 ) {
		LDAPDebug( LDAP_DEBUG_TRACE,
		    "<= nsldapi_get_controls no controls\n", 0, 0, 0 );
		return( LDAP_SUCCESS );			/* no controls */
	}
	if (( tag = ber_peek_tag( ber, &len )) != LDAP_TAG_CONTROLS ) {
		if ( tag == LBER_ERROR ) {
			LDAPDebug( LDAP_DEBUG_TRACE,
			    "<= nsldapi_get_controls LDAP_PROTOCOL_ERROR\n",
			    0, 0, 0 );
			return( LDAP_DECODING_ERROR );	/* decoding error */
		}
		/*
		 * We found something other than controls.  This should never
		 * happen in LDAPv3, but we don't treat this is a hard error --
		 * we just ignore the extra stuff.
		 */
		LDAPDebug( LDAP_DEBUG_TRACE,
		    "<= nsldapi_get_controls ignoring unrecognized data in message (tag 0x%x)\n",
		    tag, 0, 0 );
		return( LDAP_SUCCESS );
	}

	maxcontrols = curcontrols = 0;
	for ( tag = ber_first_element( ber, &len, &last );
	    tag != LBER_ERROR && tag != LBER_END_OF_SEQORSET;
	    tag = ber_next_element( ber, &len, last ) ) {
		if ( curcontrols >= maxcontrols - 1 ) {
#define CONTROL_GRABSIZE	5
			maxcontrols += CONTROL_GRABSIZE;
			*controlsp = (struct ldapcontrol **)NSLDAPI_REALLOC(
			    (char *)*controlsp, maxcontrols *
			    sizeof(struct ldapcontrol *) );
			if ( *controlsp == NULL ) {
			    rc = LDAP_NO_MEMORY;
			    goto free_and_return;
			}
		}
		if (( newctrl = (struct ldapcontrol *)NSLDAPI_CALLOC( 1,
		    sizeof(LDAPControl))) == NULL ) {
			rc = LDAP_NO_MEMORY;
			goto free_and_return;
		}
		
		(*controlsp)[curcontrols++] = newctrl;
		(*controlsp)[curcontrols] = NULL;

		if ( ber_scanf( ber, "{a", &newctrl->ldctl_oid )
		    == LBER_ERROR ) {
			rc = LDAP_DECODING_ERROR;
			goto free_and_return;
		}

		/* the criticality is optional */
		if ( ber_peek_tag( ber, &len ) == LBER_BOOLEAN ) {
			int		aint;

			if ( ber_scanf( ber, "b", &aint ) == LBER_ERROR ) {
				rc = LDAP_DECODING_ERROR;
				goto free_and_return;
			}
			newctrl->ldctl_iscritical = (char)aint;	/* XXX lossy cast */
		} else {
			/* absent is synonomous with FALSE */
			newctrl->ldctl_iscritical = 0;
		}

		/* the control value is optional */
		if ( ber_peek_tag( ber, &len ) == LBER_OCTETSTRING ) {
			if ( ber_scanf( ber, "o", &newctrl->ldctl_value )
			    == LBER_ERROR ) {
				rc = LDAP_DECODING_ERROR;
				goto free_and_return;
			}
		} else {
			(newctrl->ldctl_value).bv_val = NULL;
			(newctrl->ldctl_value).bv_len = 0;
		}

	}

	if ( tag == LBER_ERROR ) {
		rc = LDAP_DECODING_ERROR;
		goto free_and_return;
	}

	LDAPDebug( LDAP_DEBUG_TRACE,
	    "<= nsldapi_get_controls found %d controls\n", curcontrols, 0, 0 );
	return( LDAP_SUCCESS );

free_and_return:;
	ldap_controls_free( *controlsp );
	*controlsp = NULL;
	LDAPDebug( LDAP_DEBUG_TRACE,
	    "<= nsldapi_get_controls error 0x%x\n", rc, 0, 0 );
	return( rc );
}
Esempio n. 17
0
int
ldap_parse_derefresponse_control(
	LDAP		*ld,
	LDAPControl	*ctrl,
	LDAPDerefRes	**drp2 )
{
	BerElement *ber;
	ber_tag_t tag;
	ber_len_t len;
	char *last;
	LDAPDerefRes *drhead = NULL, **drp;

	if ( ld == NULL || ctrl == NULL || drp2 == NULL ) {
		if ( ld )
			ld->ld_errno = LDAP_PARAM_ERROR;
		return LDAP_PARAM_ERROR;
	}

	/* Create a BerElement from the berval returned in the control. */
	ber = ber_init( &ctrl->ldctl_value );

	if ( ber == NULL ) {
		ld->ld_errno = LDAP_NO_MEMORY;
		return ld->ld_errno;
	}

	/* Extract the count and cookie from the control. */
	drp = &drhead;
	for ( tag = ber_first_element( ber, &len, &last );
		tag != LBER_DEFAULT;
		tag = ber_next_element( ber, &len, last ) )
	{
		LDAPDerefRes *dr;
		LDAPDerefVal **dvp;
		char *last2;

		dr = LDAP_CALLOC( 1, sizeof(LDAPDerefRes) );
		dvp = &dr->attrVals;

		tag = ber_scanf( ber, "{ao", &dr->derefAttr, &dr->derefVal );
		if ( tag == LBER_ERROR ) {
			goto done;
		}

		tag = ber_peek_tag( ber, &len );
		if ( tag == (LBER_CONSTRUCTED|LBER_CLASS_CONTEXT) ) {
			for ( tag = ber_first_element( ber, &len, &last2 );
				tag != LBER_DEFAULT;
				tag = ber_next_element( ber, &len, last2 ) )
			{
				LDAPDerefVal *dv;

				dv = LDAP_CALLOC( 1, sizeof(LDAPDerefVal) );

				tag = ber_scanf( ber, "{a[W]}", &dv->type, &dv->vals );
				if ( tag == LBER_ERROR ) {
					goto done;
				}

				*dvp = dv;
				dvp = &dv->next;
			}
		}

		tag = ber_scanf( ber, "}" );
		if ( tag == LBER_ERROR ) {
			goto done;
		}

		*drp = dr;
		drp = &dr->next;
	}

	tag = 0;

done:;
        ber_free( ber, 1 );

	if ( tag == LBER_ERROR ) {
		if ( drhead != NULL ) {
			ldap_derefresponse_free( drhead );
		}

		*drp2 = NULL;
		ld->ld_errno = LDAP_DECODING_ERROR;

	} else {
		*drp2 = drhead;
		ld->ld_errno = LDAP_SUCCESS;
	}

	return ld->ld_errno;
}
Esempio n. 18
0
/*
 * Extract the payload from a total update extended operation,
 * decode it, and produce a Slapi_Entry structure representing a new
 * entry to be added to the local database.
 */
static int
decode_total_update_extop(Slapi_PBlock *pb, Slapi_Entry **ep)
{
	BerElement *tmp_bere = NULL;
	Slapi_Entry *e = NULL;
	Slapi_Attr *attr = NULL;
	char *str = NULL;
	struct berval *extop_value = NULL;
	char *extop_oid = NULL;
	ber_len_t len;
	char *lasto;
	ber_tag_t tag;
	int rc;
	PRBool deleted;
	
	PR_ASSERT(NULL != pb);
	PR_ASSERT(NULL != ep);

	slapi_pblock_get(pb, SLAPI_EXT_OP_REQ_OID, &extop_oid);
	slapi_pblock_get(pb, SLAPI_EXT_OP_REQ_VALUE, &extop_value);

	if ((NULL == extop_oid) || 
		((strcmp(extop_oid, REPL_NSDS50_REPLICATION_ENTRY_REQUEST_OID) != 0) && 
		 (strcmp(extop_oid, REPL_NSDS71_REPLICATION_ENTRY_REQUEST_OID) != 0)) ||
		!BV_HAS_DATA(extop_value))
	{
		/* Bogus */
		goto loser;
	}

	if ((tmp_bere = ber_init(extop_value)) == NULL)
	{
		goto loser;
	}

	if ((e = slapi_entry_alloc()) == NULL)
	{
		goto loser;
	}

	if (ber_scanf(tmp_bere, "{") == LBER_ERROR) /* Begin outer sequence */
	{
		goto loser;
	}

	/* The entry's uniqueid is first */
	if (ber_scanf(tmp_bere, "a", &str) == LBER_ERROR)
	{
		goto loser;
	}
	slapi_entry_set_uniqueid(e, str);
	str = NULL;	/* Slapi_Entry now owns the uniqueid */

	/* The entry's DN is next */
	if (ber_scanf(tmp_bere, "a", &str) == LBER_ERROR)
	{
		goto loser;
	}
	slapi_entry_set_dn(e, str);
	str = NULL; /* Slapi_Entry now owns the dn */

	/* Get the attributes */
	for ( tag = ber_first_element( tmp_bere, &len, &lasto );
		tag != LBER_ERROR && tag != LBER_END_OF_SEQORSET;
		tag = ber_next_element( tmp_bere, &len, lasto ) )
	{

        if (my_ber_scanf_attr (tmp_bere, &attr, &deleted) != 0)
        {
            goto loser;
        }
		
	    /* Add the attribute to the entry */
        if (deleted)
            entry_add_deleted_attribute_wsi(e, attr); /* entry now owns attr */
        else
		    entry_add_present_attribute_wsi(e, attr); /* entry now owns attr */
        attr = NULL;
	}

    if (ber_scanf(tmp_bere, "}") == LBER_ERROR) /* End sequence for this entry */
	{
		goto loser;
	}

	/* Check for ldapsubentries and tombstone entries to set flags properly */
	slapi_entry_attr_find(e, "objectclass", &attr);
	if (attr != NULL) {
		struct berval bv;
		bv.bv_val = "ldapsubentry";
		bv.bv_len = strlen(bv.bv_val);
		if (slapi_attr_value_find(attr, &bv) == 0) {
			slapi_entry_set_flag(e, SLAPI_ENTRY_LDAPSUBENTRY);
		}
		bv.bv_val = SLAPI_ATTR_VALUE_TOMBSTONE;
		bv.bv_len = strlen(bv.bv_val);
		if (slapi_attr_value_find(attr, &bv) == 0) {
			slapi_entry_set_flag(e, SLAPI_ENTRY_FLAG_TOMBSTONE);
		}
	}
	
	/* If we get here, the entry is properly constructed. Return it. */

	rc = 0;
	*ep = e;
	goto free_and_return;

loser:
	rc = -1;
	/* slapi_ch_free accepts NULL pointer */
	slapi_ch_free((void **)&str);

    if (attr != NULL)
    {
        slapi_attr_free (&attr);
    }
    
    if (NULL != e)
    {
        slapi_entry_free (e);
    }
	*ep = NULL;
	slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "Error: could not decode extended "
		"operation containing entry for total update.\n");

free_and_return:
    if (NULL != tmp_bere)
	{
		ber_free(tmp_bere, 1); 
		tmp_bere = NULL;
	}
	return rc;
}
Esempio n. 19
0
File: vc.c Progetto: Joywar/openldap
int ldap_parse_verify_credentials(
	LDAP *ld,
	LDAPMessage *res,
	int * code,
	char ** diagmsg,
    struct berval **cookie,
	struct berval **screds,
	LDAPControl ***ctrls)
{
	int rc;
	char *retoid = NULL;
	struct berval *retdata = NULL;

	assert(ld != NULL);
	assert(LDAP_VALID(ld));
	assert(res != NULL);
	assert(code != NULL);
	assert(diagmsg != NULL);

	rc = ldap_parse_extended_result(ld, res, &retoid, &retdata, 0);

	if( rc != LDAP_SUCCESS ) {
		ldap_perror(ld, "ldap_parse_verify_credentials");
		return rc;
	}

	if (retdata) {
		ber_tag_t tag;
		ber_len_t len;
		ber_int_t i;
		BerElement * ber = ber_init(retdata);
		struct berval diagmsg_bv = BER_BVNULL;
		if (!ber) {
		    rc = ld->ld_errno = LDAP_NO_MEMORY;
			goto done;
		}

		ber_scanf(ber, "{im" /*"}"*/, &i, &diagmsg_bv);
		if ( diagmsg != NULL ) {
			*diagmsg = LDAP_MALLOC( diagmsg_bv.bv_len + 1 );
			AC_MEMCPY( *diagmsg, diagmsg_bv.bv_val, diagmsg_bv.bv_len );
			(*diagmsg)[diagmsg_bv.bv_len] = '\0';
		}
		*code = i;

		tag = ber_peek_tag(ber, &len);
		if (tag == LDAP_TAG_EXOP_VERIFY_CREDENTIALS_COOKIE) {
			ber_scanf(ber, "O", cookie);
		    tag = ber_peek_tag(ber, &len);
		}

		if (tag == LDAP_TAG_EXOP_VERIFY_CREDENTIALS_SCREDS) {
			ber_scanf(ber, "O", screds);
		    tag = ber_peek_tag(ber, &len);
		}

		if (tag == LDAP_TAG_EXOP_VERIFY_CREDENTIALS_CONTROLS) {
		    int nctrls = 0;
			char * opaque;

		    *ctrls = LDAP_MALLOC(1 * sizeof(LDAPControl *));

			if (!*ctrls) {
				rc = LDAP_NO_MEMORY;
				goto done;
			}

			*ctrls[nctrls] = NULL;

			for(tag = ber_first_element(ber, &len, &opaque);
				tag != LBER_ERROR;
				tag = ber_next_element(ber, &len, opaque))
		    {
				LDAPControl *tctrl;
				LDAPControl **tctrls;

				tctrl = LDAP_CALLOC(1, sizeof(LDAPControl));

				/* allocate pointer space for current controls (nctrls)
				 * + this control + extra NULL
				 */
				tctrls = !tctrl ? NULL : LDAP_REALLOC(*ctrls, (nctrls+2) * sizeof(LDAPControl *));

				if (!tctrls) {
					/* allocation failure */
					if (tctrl) LDAP_FREE(tctrl);
					ldap_controls_free(*ctrls);
					*ctrls = NULL;
				    rc = LDAP_NO_MEMORY;
				    goto done;
				}

				tctrls[nctrls++] = tctrl;
				tctrls[nctrls] = NULL;

				tag = ber_scanf(ber, "{a" /*"}"*/, &tctrl->ldctl_oid);
				if (tag == LBER_ERROR) {
					*ctrls = NULL;
					ldap_controls_free(tctrls);
					rc = LDAP_DECODING_ERROR;
					goto done;
				}

				tag = ber_peek_tag(ber, &len);
				if (tag == LBER_BOOLEAN) {
					ber_int_t crit;
					tag = ber_scanf(ber, "b", &crit);
					tctrl->ldctl_iscritical = crit ? (char) 0 : (char) ~0;
				    tag = ber_peek_tag(ber, &len);
				}

			    if (tag == LBER_OCTETSTRING) {
                    tag = ber_scanf( ber, "o", &tctrl->ldctl_value );
                } else {
                    BER_BVZERO( &tctrl->ldctl_value );
                }

                *ctrls = tctrls;
			}
	    }

	    ber_free(ber, 1);
    }

done:
	ber_bvfree(retdata);
	ber_memfree(retoid);
	return rc;
}
Esempio n. 20
0
File: add.c Progetto: Firstyear/ds
/* This function is called to process operation that come over external connections */
void
do_add( Slapi_PBlock *pb )
{
	Slapi_Operation *operation;
	BerElement		*ber;
	char			*last;
	ber_len_t		len = LBER_ERROR;
	ber_tag_t		tag;
	Slapi_Entry		*e = NULL;
	int			err;
	int			rc;
	PRBool  searchsubentry=PR_TRUE;

	slapi_log_err(SLAPI_LOG_TRACE, "do_add", "==>\n");

	slapi_pblock_get( pb, SLAPI_OPERATION, &operation);
    ber = operation->o_ber;

	/* count the add request */
	slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsAddEntryOps);

	/*
	 * Parse the add request.  It looks like this:
	 *
	 *	AddRequest := [APPLICATION 14] SEQUENCE {
	 *		name	DistinguishedName,
	 *		attrs	SEQUENCE OF SEQUENCE {
	 *			type	AttributeType,
	 *			values	SET OF AttributeValue
	 *		}
	 *	}
	 */
	/* get the name */
	{
		char *rawdn = NULL;
		Slapi_DN mysdn;
		if ( ber_scanf( ber, "{a", &rawdn ) == LBER_ERROR ) {
			slapi_ch_free_string(&rawdn);
			slapi_log_err(SLAPI_LOG_ERR, "do_add",
				"ber_scanf failed (op=Add; params=DN)\n");
			op_shared_log_error_access (pb, "ADD", "???", "decoding error");
			send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL,
				"decoding error", 0, NULL );
			return;
		}
		/* Check if we should be performing strict validation. */
		if (config_get_dn_validate_strict()) {
			/* check that the dn is formatted correctly */
			rc = slapi_dn_syntax_check(pb, rawdn, 1);
			if (rc) { /* syntax check failed */
				op_shared_log_error_access(pb, "ADD", rawdn?rawdn:"",
										   "strict: invalid dn");
				send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, 
								 NULL, "invalid dn", 0, NULL);
				slapi_ch_free_string(&rawdn);
				return;
			}
		}
		slapi_sdn_init_dn_passin(&mysdn, rawdn);
		if (rawdn && (strlen(rawdn) > 0) &&
		    (NULL == slapi_sdn_get_dn(&mysdn))) {
			/* normalization failed */
			op_shared_log_error_access(pb, "ADD", rawdn, "invalid dn");
			send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, NULL,
			                 "invalid dn", 0, NULL);
			slapi_sdn_done(&mysdn);
			return;
		}
		e = slapi_entry_alloc();
		/* Responsibility for DN is passed to the Entry. */
		slapi_entry_init_ext(e, &mysdn, NULL);
		slapi_sdn_done(&mysdn);
	}
	slapi_log_err(SLAPI_LOG_ARGS, "do_add", "dn (%s)\n", (char *)slapi_entry_get_dn_const(e));

	/* get the attrs */
	for ( tag = ber_first_element( ber, &len, &last );
	      tag != LBER_DEFAULT && tag != LBER_END_OF_SEQORSET;
	      tag = ber_next_element( ber, &len, last ) ) {
		char *type = NULL, *normtype = NULL;
		struct berval	**vals = NULL;
		len = -1; /* reset - not used in loop */
		if ( ber_scanf( ber, "{a{V}}", &type, &vals ) == LBER_ERROR ) {
			op_shared_log_error_access (pb, "ADD", slapi_sdn_get_dn (slapi_entry_get_sdn_const(e)), "decoding error");
			send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL,
			    "decoding error", 0, NULL );
            slapi_ch_free_string(&type);
            ber_bvecfree( vals );
			goto free_and_return;
		}

		if ( vals == NULL ) {
			slapi_log_err(SLAPI_LOG_ERR, "do_add - no values for type %s\n", type, 0, 0 );
			op_shared_log_error_access (pb, "ADD", slapi_sdn_get_dn (slapi_entry_get_sdn_const(e)), "null value");
			send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL, NULL,
			    0, NULL );
            slapi_ch_free_string(&type);
			goto free_and_return;
		}

		normtype = slapi_attr_syntax_normalize(type);
		if ( !normtype || !*normtype ) {
			char ebuf[SLAPI_DSE_RETURNTEXT_SIZE];
			rc = LDAP_INVALID_SYNTAX;
			slapi_create_errormsg(ebuf, sizeof(ebuf), "invalid type '%s'", type);
			op_shared_log_error_access (pb, "ADD", slapi_sdn_get_dn (slapi_entry_get_sdn_const(e)), ebuf);
			send_ldap_result( pb, rc, NULL, ebuf, 0, NULL );
            slapi_ch_free_string(&type);
			slapi_ch_free( (void**)&normtype );
			ber_bvecfree( vals );
			goto free_and_return;
		}
		slapi_ch_free_string(&type);
	
       /* for now we just ignore attributes that client is not allowed
          to modify so not to break existing clients */
		if (op_shared_is_allowed_attr (normtype, pb->pb_conn->c_isreplication_session)){		
			if (( rc = slapi_entry_add_values( e, normtype, vals ))
				!= LDAP_SUCCESS ) {
				slapi_log_access( LDAP_DEBUG_STATS, 
					"conn=%" NSPRIu64 " op=%d ADD dn=\"%s\", add values for type %s failed\n",
					pb->pb_conn->c_connid, operation->o_opid,
					slapi_entry_get_dn_const(e), normtype );
				send_ldap_result( pb, rc, NULL, NULL, 0, NULL );

				slapi_ch_free( (void**)&normtype );
				ber_bvecfree( vals );
				goto free_and_return;
			}

			/* if this is uniqueid attribute, set uniqueid field of the entry */
			if (strcasecmp (normtype, SLAPI_ATTR_UNIQUEID) == 0)
			{
				e->e_uniqueid = slapi_ch_strdup (vals[0]->bv_val);
			}
			if(searchsubentry) searchsubentry=check_oc_subentry(e,vals,normtype);
		}

		slapi_ch_free( (void**)&normtype );
		ber_bvecfree( vals );
	}

	/* Ensure that created attributes are not used in the RDN. */
	if (check_rdn_for_created_attrs(e)) {
		op_shared_log_error_access (pb, "ADD", slapi_sdn_get_dn(slapi_entry_get_sdn_const(e)), "invalid DN");
		send_ldap_result( pb, LDAP_INVALID_DN_SYNTAX, NULL, "illegal attribute in RDN", 0, NULL );
		goto free_and_return;
	}

    /* len, is ber_len_t, which is uint. Can't be -1. May be better to remove (len != 0) check */
	if ( (tag != LBER_END_OF_SEQORSET) && (len != -1) ) {
		op_shared_log_error_access (pb, "ADD", slapi_sdn_get_dn (slapi_entry_get_sdn_const(e)), "decoding error");
		send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL,
		    "decoding error", 0, NULL );
		goto free_and_return;
	}

	/*
	 * in LDAPv3 there can be optional control extensions on
	 * the end of an LDAPMessage. we need to read them in and
	 * pass them to the backend.
	 */
	if ( (err = get_ldapmessage_controls( pb, ber, NULL )) != 0 ) {
		op_shared_log_error_access (pb, "ADD", slapi_sdn_get_dn (slapi_entry_get_sdn_const(e)), 
								    "failed to decode LDAP controls");
		send_ldap_result( pb, err, NULL, NULL, 0, NULL );
		goto free_and_return;
	}

	slapi_pblock_set( pb, SLAPI_REQUESTOR_ISROOT, &operation->o_isroot );
	slapi_pblock_set( pb, SLAPI_ADD_ENTRY, e );

        if (pb->pb_conn->c_flags & CONN_FLAG_IMPORT) {
            /* this add is actually part of a bulk import -- punt */
            handle_fast_add(pb, e);
        } else {
            op_shared_add ( pb );
        }

	/* make sure that we don't free entry if it is successfully added */
	e = NULL;

free_and_return:;
	if (e)
		slapi_entry_free (e);

}
Esempio n. 21
0
int
slap_parse_modlist(
	Operation *op,
	SlapReply *rs,
	BerElement *ber,
	req_modify_s *ms )
{
	ber_tag_t	tag;
	ber_len_t	len;
	char		*last;
	Modifications	**modtail = &ms->rs_mods.rs_modlist;

	ms->rs_mods.rs_modlist = NULL;
	ms->rs_increment = 0;

	rs->sr_err = LDAP_SUCCESS;

	/* collect modifications & save for later */
	for ( tag = ber_first_element( ber, &len, &last );
		tag != LBER_DEFAULT;
		tag = ber_next_element( ber, &len, last ) )
	{
		ber_int_t mop;
		Modifications tmp, *mod;

		tmp.sml_nvalues = NULL;

		if ( ber_scanf( ber, "{e{m[W]}}", &mop,
		    &tmp.sml_type, &tmp.sml_values ) == LBER_ERROR )
		{
			rs->sr_text = "decoding modlist error";
			rs->sr_err = LDAP_PROTOCOL_ERROR;
			goto done;
		}

		mod = (Modifications *) ch_malloc( sizeof(Modifications) );
		mod->sml_op = mop;
		mod->sml_flags = 0;
		mod->sml_type = tmp.sml_type;
		mod->sml_values = tmp.sml_values;
		mod->sml_nvalues = NULL;
		mod->sml_desc = NULL;
		mod->sml_next = NULL;
		*modtail = mod;

		switch( mop ) {
		case LDAP_MOD_ADD:
			if ( mod->sml_values == NULL ) {
				rs->sr_text = "modify/add operation requires values";
				rs->sr_err = LDAP_PROTOCOL_ERROR;
				goto done;
			}

			/* fall through */

		case LDAP_MOD_DELETE:
		case LDAP_MOD_REPLACE:
			break;

		case LDAP_MOD_INCREMENT:
			if( op->o_protocol >= LDAP_VERSION3 ) {
				ms->rs_increment++;
				if ( mod->sml_values == NULL ) {
					rs->sr_text = "modify/increment operation requires value";
					rs->sr_err = LDAP_PROTOCOL_ERROR;
					goto done;
				}

				if ( !BER_BVISNULL( &mod->sml_values[ 1 ] ) ) {
					rs->sr_text = "modify/increment operation requires single value";
					rs->sr_err = LDAP_PROTOCOL_ERROR;
					goto done;
				}

				break;
			}
			/* fall thru */

		default:
			rs->sr_text = "unrecognized modify operation";
			rs->sr_err = LDAP_PROTOCOL_ERROR;
			goto done;
		}

		modtail = &mod->sml_next;
	}
	*modtail = NULL;

done:
	if ( rs->sr_err != LDAP_SUCCESS ) {
		slap_mods_free( ms->rs_mods.rs_modlist, 1 );
		ms->rs_mods.rs_modlist = NULL;
		ms->rs_increment = 0;
	}

	return rs->sr_err;
}
Esempio n. 22
0
int
ldap_parse_passwordpolicy_control(
	LDAP           *ld,
	LDAPControl    *ctrl,
	ber_int_t      *expirep,
	ber_int_t      *gracep,
	LDAPPasswordPolicyError *errorp )
{
	BerElement  *ber;
	int exp = -1, grace = -1;
	ber_tag_t tag;
	ber_len_t berLen;
        char *last;
	int err = PP_noError;
        
	assert( ld != NULL );
	assert( LDAP_VALID( ld ) );
	assert( ctrl != NULL );

	/* Create a BerElement from the berval returned in the control. */
	ber = ber_init(&ctrl->ldctl_value);

	if (ber == NULL) {
		ld->ld_errno = LDAP_NO_MEMORY;
		return(ld->ld_errno);
	}

	tag = ber_peek_tag( ber, &berLen );
	if (tag != LBER_SEQUENCE) goto exit;

	for( tag = ber_first_element( ber, &berLen, &last );
		tag != LBER_DEFAULT;
		tag = ber_next_element( ber, &berLen, last ) )
	{
		switch (tag) {
		case PPOLICY_WARNING:
			ber_skip_tag(ber, &berLen );
			tag = ber_peek_tag( ber, &berLen );
			switch( tag ) {
			case PPOLICY_EXPIRE:
				if (ber_get_int( ber, &exp ) == LBER_DEFAULT) goto exit;
				break;
			case PPOLICY_GRACE:
				if (ber_get_int( ber, &grace ) == LBER_DEFAULT) goto exit;
				break;
			default:
				goto exit;
			}
			break;
		case PPOLICY_ERROR:
			if (ber_get_enum( ber, &err ) == LBER_DEFAULT) goto exit;
			break;
		default:
			goto exit;
		}
	}

	ber_free(ber, 1);

	/* Return data to the caller for items that were requested. */
	if (expirep) *expirep = exp;
	if (gracep) *gracep = grace;
	if (errorp) *errorp = err;
        
	ld->ld_errno = LDAP_SUCCESS;
	return(ld->ld_errno);

  exit:
	ber_free(ber, 1);
	ld->ld_errno = LDAP_DECODING_ERROR;
	return(ld->ld_errno);
}
Esempio n. 23
0
static int
deref_parseCtrl (
	Operation *op,
	SlapReply *rs,
	LDAPControl *ctrl )
{
	ber_tag_t tag;
	BerElementBuffer berbuf;
	BerElement *ber = (BerElement *)&berbuf;
	ber_len_t len;
	char *last;
	DerefSpec *dshead = NULL, **dsp = &dshead;
	BerVarray attributes = NULL;

	if ( op->o_deref != SLAP_CONTROL_NONE ) {
		rs->sr_text = "Dereference control specified multiple times";
		return LDAP_PROTOCOL_ERROR;
	}

	if ( BER_BVISNULL( &ctrl->ldctl_value ) ) {
		rs->sr_text = "Dereference control value is absent";
		return LDAP_PROTOCOL_ERROR;
	}

	if ( BER_BVISEMPTY( &ctrl->ldctl_value ) ) {
		rs->sr_text = "Dereference control value is empty";
		return LDAP_PROTOCOL_ERROR;
	}

	ber_init2( ber, &ctrl->ldctl_value, 0 );

	for ( tag = ber_first_element( ber, &len, &last );
		tag != LBER_DEFAULT;
		tag = ber_next_element( ber, &len, last ) )
	{
		struct berval derefAttr;
		DerefSpec *ds, *dstmp;
		const char *text;
		int rc;
		ber_len_t cnt = sizeof(struct berval);
		ber_len_t off = 0;

		if ( ber_scanf( ber, "{m{M}}", &derefAttr, &attributes, &cnt, off ) == LBER_ERROR
			|| !cnt )
		{
			rs->sr_text = "Dereference control: derefSpec decoding error";
			rs->sr_err = LDAP_PROTOCOL_ERROR;
			goto done;
		}

		ds = (DerefSpec *)op->o_tmpcalloc( 1,
			sizeof(DerefSpec) + sizeof(AttributeDescription *)*(cnt + 1),
			op->o_tmpmemctx );
		ds->ds_attributes = (AttributeDescription **)&ds[ 1 ];
		ds->ds_nattrs = cnt;

		rc = slap_bv2ad( &derefAttr, &ds->ds_derefAttr, &text );
		if ( rc != LDAP_SUCCESS ) {
			rs->sr_text = "Dereference control: derefAttr decoding error";
			rs->sr_err = LDAP_PROTOCOL_ERROR;
			goto done;
		}

		for ( dstmp = dshead; dstmp && dstmp != ds; dstmp = dstmp->ds_next ) {
			if ( dstmp->ds_derefAttr == ds->ds_derefAttr ) {
				rs->sr_text = "Dereference control: derefAttr must be unique within control";
				rs->sr_err = LDAP_PROTOCOL_ERROR;
				goto done;
			}
		}

		if ( !( ds->ds_derefAttr->ad_type->sat_syntax->ssyn_flags & SLAP_SYNTAX_DN )) {
			if ( ctrl->ldctl_iscritical ) {
				rs->sr_text = "Dereference control: derefAttr syntax not distinguishedName";
				rs->sr_err = LDAP_PROTOCOL_ERROR;
				goto done;
			}

			rs->sr_err = LDAP_SUCCESS;
			goto justcleanup;
		}

		for ( cnt = 0; !BER_BVISNULL( &attributes[ cnt ] ); cnt++ ) {
			rc = slap_bv2ad( &attributes[ cnt ], &ds->ds_attributes[ cnt ], &text );
			if ( rc != LDAP_SUCCESS ) {
				rs->sr_text = "Dereference control: attribute decoding error";
				rs->sr_err = LDAP_PROTOCOL_ERROR;
				goto done;
			}
		}

		ber_memfree_x( attributes, op->o_tmpmemctx );
		attributes = NULL;

		*dsp = ds;
		dsp = &ds->ds_next;
	}

	op->o_ctrlderef = (void *)dshead;

	op->o_deref = ctrl->ldctl_iscritical
		? SLAP_CONTROL_CRITICAL
		: SLAP_CONTROL_NONCRITICAL;

	rs->sr_err = LDAP_SUCCESS;

done:;
	if ( rs->sr_err != LDAP_SUCCESS ) {
justcleanup:;
		for ( ; dshead; ) {
			DerefSpec *dsnext = dshead->ds_next;
			op->o_tmpfree( dshead, op->o_tmpmemctx );
			dshead = dsnext;
		}
	}

	if ( attributes != NULL ) {
		ber_memfree_x( attributes, op->o_tmpmemctx );
	}

	return rs->sr_err;
}
int ldap_parse_passwordpolicy_control(LDAP UNUSED(*ld), LDAPControl *ctrl,
                                      ber_int_t *expirep, ber_int_t *gracep,
                                      LDAPPasswordPolicyError UNUSED(*errorp))
{
  BerElement *ber;
  ber_tag_t tag;
  ber_len_t berLen;
  char *last;
#ifdef HAVE_BER_GET_ENUM
  int err = PP_noError;
#endif /* HAVE_BER_GET_ENUM */
  /* get a BerElement from the control */
  ber = ber_init(&ctrl->ldctl_value);
  if (ber == NULL)
    return LDAP_LOCAL_ERROR;
  /* go over tags */
  for(tag = ber_first_element(ber, &berLen, &last); tag != LBER_DEFAULT; tag = ber_next_element(ber, &berLen, last))
  {
    switch (tag)
    {
      case PPOLICY_WARNING:
        ber_skip_tag(ber, &berLen);
        tag = ber_peek_tag(ber, &berLen);
        switch (tag)
        {
          case PPOLICY_EXPIRE:
            if (ber_get_int(ber, expirep) == LBER_DEFAULT)
            {
              ber_free(ber, 1);
              return LDAP_DECODING_ERROR;
            }
            break;
          case PPOLICY_GRACE:
            if (ber_get_int(ber, gracep) == LBER_DEFAULT)
            {
              ber_free(ber, 1);
              return LDAP_DECODING_ERROR;
            }
            break;
          default:
            ber_free(ber, 1);
            return LDAP_DECODING_ERROR;
        }
        break;
#ifdef HAVE_BER_GET_ENUM
      case PPOLICY_ERROR:
        if (ber_get_enum(ber, &err) == LBER_DEFAULT)
        {
          ber_free(ber, 1);
          return LDAP_DECODING_ERROR;
        }
        break;
#endif /* HAVE_BER_GET_ENUM */
      default:
        ber_free(ber, 1);
        return LDAP_DECODING_ERROR;
    }
  }
  ber_free(ber, 1);
  return LDAP_SUCCESS;
}