예제 #1
0
파일: search.c 프로젝트: dago/openldap
int
ldap_pvt_search(
	LDAP *ld,
	LDAP_CONST char *base,
	int scope,
	LDAP_CONST char *filter,
	char **attrs,
	int attrsonly,
	LDAPControl **sctrls,
	LDAPControl **cctrls,
	struct timeval *timeout,
	int sizelimit,
	int deref,
	int *msgidp )
{
	int rc;
	BerElement	*ber;
	int timelimit;
	ber_int_t id;

	Debug( LDAP_DEBUG_TRACE, "ldap_search_ext\n", 0, 0, 0 );

	assert( ld != NULL );
	assert( LDAP_VALID( ld ) );

	/* check client controls */
	rc = ldap_int_client_controls( ld, cctrls );
	if( rc != LDAP_SUCCESS ) return rc;

	/*
	 * if timeout is provided, both tv_sec and tv_usec must
	 * not be zero
	 */
	if( timeout != NULL ) {
		if( timeout->tv_sec == 0 && timeout->tv_usec == 0 ) {
			return LDAP_PARAM_ERROR;
		}

		/* timelimit must be non-zero if timeout is provided */
		timelimit = timeout->tv_sec != 0 ? timeout->tv_sec : 1;

	} else {
		/* no timeout, no timelimit */
		timelimit = -1;
	}

	ber = ldap_build_search_req( ld, base, scope, filter, attrs,
	    attrsonly, sctrls, cctrls, timelimit, sizelimit, deref, &id ); 

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


	/* send the message */
	*msgidp = ldap_send_initial_request( ld, LDAP_REQ_SEARCH, base, ber, id );

	if( *msgidp < 0 )
		return ld->ld_errno;

	return LDAP_SUCCESS;
}
예제 #2
0
int
ldap_parse_vlvresponse_control(
    LDAP *ld,
    LDAPControl *ctrl,
    ber_int_t *target_posp,
    ber_int_t *list_countp,
    struct berval  **contextp,
    ber_int_t *errcodep )
{
    BerElement  *ber;
    ber_int_t pos, count, err;
    ber_tag_t tag, berTag;
    ber_len_t berLen;

    assert( ld != NULL );
    assert( LDAP_VALID( ld ) );

    if (contextp) {
        *contextp = NULL;	 /* Make sure we return a NULL if error occurs. */
    }

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

    if (strcmp(LDAP_CONTROL_VLVRESPONSE, ctrl->ldctl_oid) != 0) {
        /* Not VLV Response control */
        ld->ld_errno = LDAP_CONTROL_NOT_FOUND;
        return(ld->ld_errno);
    }

    /* 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 data returned in the control. */
    tag = ber_scanf(ber, "{iie" /*}*/, &pos, &count, &err);

    if( tag == LBER_ERROR) {
        ber_free(ber, 1);
        ld->ld_errno = LDAP_DECODING_ERROR;
        return(ld->ld_errno);
    }


    /* Since the context is the last item encoded, if caller doesn't want
       it returned, don't decode it. */
    if (contextp) {
        if (LDAP_VLVCONTEXT_IDENTIFIER == ber_peek_tag(ber, &berLen)) {
            tag = ber_scanf(ber, "tO", &berTag, contextp);

            if( tag == LBER_ERROR) {
                ber_free(ber, 1);
                ld->ld_errno = LDAP_DECODING_ERROR;
                return(ld->ld_errno);
            }
        }
    }

    ber_free(ber, 1);

    /* Return data to the caller for items that were requested. */
    if (target_posp) *target_posp = pos;
    if (list_countp) *list_countp = count;
    if (errcodep) *errcodep = err;

    ld->ld_errno = LDAP_SUCCESS;
    return(ld->ld_errno);
}
예제 #3
0
int
ldap_create_deref_control_value(
	LDAP		*ld,
	LDAPDerefSpec	*ds,
	struct berval	*value )
{
	BerElement	*ber = NULL;
	ber_tag_t	tag;
	int		i;

	if ( ld == NULL || value == NULL || ds == NULL )
	{
		if ( ld )
			ld->ld_errno = LDAP_PARAM_ERROR;
		return LDAP_PARAM_ERROR;
	}

	assert( LDAP_VALID( ld ) );

	value->bv_val = NULL;
	value->bv_len = 0;
	ld->ld_errno = LDAP_SUCCESS;

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

	tag = ber_printf( ber, "{" /*}*/ );
	if ( tag == LBER_ERROR ) {
		ld->ld_errno = LDAP_ENCODING_ERROR;
		goto done;
	}

	for ( i = 0; ds[i].derefAttr != NULL; i++ ) {
		int j;

		tag = ber_printf( ber, "{s{" /*}}*/ , ds[i].derefAttr );
		if ( tag == LBER_ERROR ) {
			ld->ld_errno = LDAP_ENCODING_ERROR;
			goto done;
		}

		for ( j = 0; ds[i].attributes[j] != NULL; j++ ) {
			tag = ber_printf( ber, "s", ds[i].attributes[ j ] );
			if ( tag == LBER_ERROR ) {
				ld->ld_errno = LDAP_ENCODING_ERROR;
				goto done;
			}
		}

		tag = ber_printf( ber, /*{{*/ "}N}" );
		if ( tag == LBER_ERROR ) {
			ld->ld_errno = LDAP_ENCODING_ERROR;
			goto done;
		}
	}

	tag = ber_printf( ber, /*{*/ "}" );
	if ( tag == LBER_ERROR ) {
		ld->ld_errno = LDAP_ENCODING_ERROR;
		goto done;
	}

	if ( ber_flatten2( ber, value, 1 ) == -1 ) {
		ld->ld_errno = LDAP_NO_MEMORY;
	}

done:;
	if ( ber != NULL ) {
		ber_free( ber, 1 );
	}

	return ld->ld_errno;
}
예제 #4
0
int
ldap_passwd( LDAP *ld,
	struct berval	*user,
	struct berval	*oldpw,
	struct berval	*newpw,
	LDAPControl		**sctrls,
	LDAPControl		**cctrls,
	int				*msgidp )
{
	int rc;
	struct berval bv = BER_BVNULL;
	BerElement *ber = NULL;

	assert( ld != NULL );
	assert( LDAP_VALID( ld ) );
	assert( msgidp != NULL );

	if( user != NULL || oldpw != NULL || newpw != NULL ) {
		/* build change password control */
		ber = ber_alloc_t( LBER_USE_DER );

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

		ber_printf( ber, "{" /*}*/ );

		if( user != NULL ) {
			ber_printf( ber, "tO",
				LDAP_TAG_EXOP_MODIFY_PASSWD_ID, user );
		}

		if( oldpw != NULL ) {
			ber_printf( ber, "tO",
				LDAP_TAG_EXOP_MODIFY_PASSWD_OLD, oldpw );
		}

		if( newpw != NULL ) {
			ber_printf( ber, "tO",
				LDAP_TAG_EXOP_MODIFY_PASSWD_NEW, newpw );
		}

		ber_printf( ber, /*{*/ "N}" );

		rc = ber_flatten2( ber, &bv, 0 );

		if( rc < 0 ) {
			ld->ld_errno = LDAP_ENCODING_ERROR;
			return ld->ld_errno;
		}

	}
	
	rc = ldap_extended_operation( ld, LDAP_EXOP_MODIFY_PASSWD,
		bv.bv_val ? &bv : NULL, sctrls, cctrls, msgidp );

	ber_free( ber, 1 );

	return rc;
}
예제 #5
0
파일: sortctrl.c 프로젝트: benegon/openldap
int
ldap_create_sort_control_value(
	LDAP *ld,
	LDAPSortKey **keyList,
	struct berval *value )
{
	int		i;
	BerElement	*ber = NULL;
	ber_tag_t	tag;

	assert( ld != NULL );
	assert( LDAP_VALID( ld ) );

	if ( ld == NULL ) return LDAP_PARAM_ERROR;
	if ( keyList == NULL || value == NULL ) {
		ld->ld_errno = LDAP_PARAM_ERROR;
		return LDAP_PARAM_ERROR;
	}

	value->bv_val = NULL;
	value->bv_len = 0;
	ld->ld_errno = LDAP_SUCCESS;

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

	tag = ber_printf( ber, "{" /*}*/ );
	if ( tag == LBER_ERROR ) {
		goto error_return;
	}

	for ( i = 0; keyList[i] != NULL; i++ ) {
		tag = ber_printf( ber, "{s" /*}*/, keyList[i]->attributeType );
		if ( tag == LBER_ERROR ) {
			goto error_return;
		}

		if ( keyList[i]->orderingRule != NULL ) {
			tag = ber_printf( ber, "ts",
				LDAP_MATCHRULE_IDENTIFIER,
				keyList[i]->orderingRule );

			if ( tag == LBER_ERROR ) {
				goto error_return;
			}
		}

		if ( keyList[i]->reverseOrder ) {
			tag = ber_printf( ber, "tb",
				LDAP_REVERSEORDER_IDENTIFIER,
				keyList[i]->reverseOrder );

			if ( tag == LBER_ERROR ) {
				goto error_return;
			}
		}

		tag = ber_printf( ber, /*{*/ "N}" );
		if ( tag == LBER_ERROR ) {
			goto error_return;
		}
	}

	tag = ber_printf( ber, /*{*/ "N}" );
	if ( tag == LBER_ERROR ) {
		goto error_return;
	}

	if ( ber_flatten2( ber, value, 1 ) == -1 ) {
		ld->ld_errno = LDAP_NO_MEMORY;
	}

	if ( 0 ) {
error_return:;
		ld->ld_errno =  LDAP_ENCODING_ERROR;
	}

	if ( ber != NULL ) {
		ber_free( ber, 1 );
	}

	return ld->ld_errno;
}
예제 #6
0
int
ldap_parse_reference( 
	LDAP            *ld,    
	LDAPMessage     *ref,
	char            ***referralsp,
	LDAPControl     ***serverctrls,
	int             freeit)
{
	BerElement be;
	char **refs = NULL;
	int rc;

	assert( ld != NULL );
	assert( LDAP_VALID( ld ) );
	assert( ref !=  NULL );

	if( ref->lm_msgtype != LDAP_RES_SEARCH_REFERENCE ) {
		return LDAP_PARAM_ERROR;
	}

	/* make a private copy of BerElement */
	AC_MEMCPY(&be, ref->lm_ber, sizeof(be));
	
	if ( ber_scanf( &be, "{v" /*}*/, &refs ) == LBER_ERROR ) {
		rc = LDAP_DECODING_ERROR;
		goto free_and_return;
	}

	if ( serverctrls == NULL ) {
		rc = LDAP_SUCCESS;
		goto free_and_return;
	}

	if ( ber_scanf( &be, /*{*/ "}" ) == LBER_ERROR ) {
		rc = LDAP_DECODING_ERROR;
		goto free_and_return;
	}

	rc = ldap_pvt_get_controls( &be, serverctrls );

free_and_return:

	if( referralsp != NULL ) {
		/* provide references regradless of return code */
		*referralsp = refs;

	} else {
		LDAP_VFREE( refs );
	}

	if( freeit ) {
		ldap_msgfree( ref );
	}

	if( rc != LDAP_SUCCESS ) {
		ld->ld_errno = rc;

		if( ld->ld_matched != NULL ) {
			LDAP_FREE( ld->ld_matched );
			ld->ld_matched = NULL;
		}

		if( ld->ld_error != NULL ) {
			LDAP_FREE( ld->ld_error );
			ld->ld_error = NULL;
		}
	}

	return rc;
}
예제 #7
0
파일: sasl.c 프로젝트: ystk/debian-openldap
int
ldap_sasl_bind(
	LDAP			*ld,
	LDAP_CONST char	*dn,
	LDAP_CONST char	*mechanism,
	struct berval	*cred,
	LDAPControl		**sctrls,
	LDAPControl		**cctrls,
	int				*msgidp )
{
	BerElement	*ber;
	int rc;
	ber_int_t id;

	Debug( LDAP_DEBUG_TRACE, "ldap_sasl_bind\n", 0, 0, 0 );

	assert( ld != NULL );
	assert( LDAP_VALID( ld ) );
	assert( msgidp != NULL );

	/* check client controls */
	rc = ldap_int_client_controls( ld, cctrls );
	if( rc != LDAP_SUCCESS ) return rc;

	if( mechanism == LDAP_SASL_SIMPLE ) {
		if( dn == NULL && cred != NULL && cred->bv_len ) {
			/* use default binddn */
			dn = ld->ld_defbinddn;
		}

	} else if( ld->ld_version < LDAP_VERSION3 ) {
		ld->ld_errno = LDAP_NOT_SUPPORTED;
		return ld->ld_errno;
	}

	if ( dn == NULL ) {
		dn = "";
	}

	/* create a message to send */
	if ( (ber = ldap_alloc_ber_with_options( ld )) == NULL ) {
		ld->ld_errno = LDAP_NO_MEMORY;
		return ld->ld_errno;
	}

	assert( LBER_VALID( ber ) );

	LDAP_NEXT_MSGID( ld, id );
	if( mechanism == LDAP_SASL_SIMPLE ) {
		/* simple bind */
		rc = ber_printf( ber, "{it{istON}" /*}*/,
			id, LDAP_REQ_BIND,
			ld->ld_version, dn, LDAP_AUTH_SIMPLE,
			cred );
		
	} else if ( cred == NULL || cred->bv_val == NULL ) {
		/* SASL bind w/o credentials */
		rc = ber_printf( ber, "{it{ist{sN}N}" /*}*/,
			id, LDAP_REQ_BIND,
			ld->ld_version, dn, LDAP_AUTH_SASL,
			mechanism );

	} else {
		/* SASL bind w/ credentials */
		rc = ber_printf( ber, "{it{ist{sON}N}" /*}*/,
			id, LDAP_REQ_BIND,
			ld->ld_version, dn, LDAP_AUTH_SASL,
			mechanism, cred );
	}

	if( rc == -1 ) {
		ld->ld_errno = LDAP_ENCODING_ERROR;
		ber_free( ber, 1 );
		return( -1 );
	}

	/* Put Server Controls */
	if( ldap_int_put_controls( ld, sctrls, ber ) != LDAP_SUCCESS ) {
		ber_free( ber, 1 );
		return ld->ld_errno;
	}

	if ( ber_printf( ber, /*{*/ "N}" ) == -1 ) {
		ld->ld_errno = LDAP_ENCODING_ERROR;
		ber_free( ber, 1 );
		return ld->ld_errno;
	}


	/* send the message */
	*msgidp = ldap_send_initial_request( ld, LDAP_REQ_BIND, dn, ber, id );

	if(*msgidp < 0)
		return ld->ld_errno;

	return LDAP_SUCCESS;
}
예제 #8
0
int
ldap_set_option(
	LDAP	*ld,
	int		option,
	LDAP_CONST void	*invalue)
{
	struct ldapoptions *lo;
	int *dbglvl = NULL;
	int rc = LDAP_OPT_ERROR;

	/* Get pointer to global option structure */
	lo = LDAP_INT_GLOBAL_OPT();
	if (lo == NULL)	{
		return LDAP_NO_MEMORY;
	}

	/*
	 * The architecture to turn on debugging has a chicken and egg
	 * problem. Thus, we introduce a fix here.
	 */

	if (option == LDAP_OPT_DEBUG_LEVEL) {
		dbglvl = (int *) invalue;
	}

	if( lo->ldo_valid != LDAP_INITIALIZED ) {
		ldap_int_initialize(lo, dbglvl);
	}

	if(ld != NULL) {
		assert( LDAP_VALID( ld ) );

		if( !LDAP_VALID( ld ) ) {
			return LDAP_OPT_ERROR;
		}

		lo = &ld->ld_options;
	}

	LDAP_MUTEX_LOCK( &lo->ldo_mutex );

	switch ( option ) {

	/* options with boolean values */
	case LDAP_OPT_REFERRALS:
		if(invalue == LDAP_OPT_OFF) {
			LDAP_BOOL_CLR(lo, LDAP_BOOL_REFERRALS);
		} else {
			LDAP_BOOL_SET(lo, LDAP_BOOL_REFERRALS);
		}
		rc = LDAP_OPT_SUCCESS;
		break;

	case LDAP_OPT_RESTART:
		if(invalue == LDAP_OPT_OFF) {
			LDAP_BOOL_CLR(lo, LDAP_BOOL_RESTART);
		} else {
			LDAP_BOOL_SET(lo, LDAP_BOOL_RESTART);
		}
		rc = LDAP_OPT_SUCCESS;
		break;

	case LDAP_OPT_CONNECT_ASYNC:
		if(invalue == LDAP_OPT_OFF) {
			LDAP_BOOL_CLR(lo, LDAP_BOOL_CONNECT_ASYNC);
		} else {
			LDAP_BOOL_SET(lo, LDAP_BOOL_CONNECT_ASYNC);
		}
		rc = LDAP_OPT_SUCCESS;
		break;

	/* options which can withstand invalue == NULL */
	case LDAP_OPT_SERVER_CONTROLS: {
			LDAPControl *const *controls =
				(LDAPControl *const *) invalue;

			if( lo->ldo_sctrls )
				ldap_controls_free( lo->ldo_sctrls );

			if( controls == NULL || *controls == NULL ) {
				lo->ldo_sctrls = NULL;
				rc = LDAP_OPT_SUCCESS;
				break;
			}
				
			lo->ldo_sctrls = ldap_controls_dup( controls );

			if(lo->ldo_sctrls == NULL) {
				/* memory allocation error ? */
				break;	/* LDAP_OPT_ERROR */
			}
		}
		rc = LDAP_OPT_SUCCESS;
		break;

	case LDAP_OPT_CLIENT_CONTROLS: {
			LDAPControl *const *controls =
				(LDAPControl *const *) invalue;

			if( lo->ldo_cctrls )
				ldap_controls_free( lo->ldo_cctrls );

			if( controls == NULL || *controls == NULL ) {
				lo->ldo_cctrls = NULL;
				rc = LDAP_OPT_SUCCESS;
				break;
			}
				
			lo->ldo_cctrls = ldap_controls_dup( controls );

			if(lo->ldo_cctrls == NULL) {
				/* memory allocation error ? */
				break;	/* LDAP_OPT_ERROR */
			}
		}
		rc = LDAP_OPT_SUCCESS;
		break;


	case LDAP_OPT_HOST_NAME: {
			const char *host = (const char *) invalue;
			LDAPURLDesc *ludlist = NULL;
			rc = LDAP_OPT_SUCCESS;

			if(host != NULL) {
				rc = ldap_url_parsehosts( &ludlist, host,
					lo->ldo_defport ? lo->ldo_defport : LDAP_PORT );

			} else if(ld == NULL) {
				/*
				 * must want global default returned
				 * to initial condition.
				 */
				rc = ldap_url_parselist_ext(&ludlist, "ldap://localhost/", NULL,
					LDAP_PVT_URL_PARSE_NOEMPTY_HOST
					| LDAP_PVT_URL_PARSE_DEF_PORT );

			} else {
				/*
				 * must want the session default
				 *   updated to the current global default
				 */
				ludlist = ldap_url_duplist(
					ldap_int_global_options.ldo_defludp);
				if (ludlist == NULL)
					rc = LDAP_NO_MEMORY;
			}

			if (rc == LDAP_OPT_SUCCESS) {
				if (lo->ldo_defludp != NULL)
					ldap_free_urllist(lo->ldo_defludp);
				lo->ldo_defludp = ludlist;
			}
			break;
		}

	case LDAP_OPT_URI: {
			const char *urls = (const char *) invalue;
			LDAPURLDesc *ludlist = NULL;
			rc = LDAP_OPT_SUCCESS;

			if(urls != NULL) {
				rc = ldap_url_parselist_ext(&ludlist, urls, NULL,
					LDAP_PVT_URL_PARSE_NOEMPTY_HOST
					| LDAP_PVT_URL_PARSE_DEF_PORT );
			} else if(ld == NULL) {
				/*
				 * must want global default returned
				 * to initial condition.
				 */
				rc = ldap_url_parselist_ext(&ludlist, "ldap://localhost/", NULL,
					LDAP_PVT_URL_PARSE_NOEMPTY_HOST
					| LDAP_PVT_URL_PARSE_DEF_PORT );

			} else {
				/*
				 * must want the session default
				 *   updated to the current global default
				 */
				ludlist = ldap_url_duplist(
					ldap_int_global_options.ldo_defludp);
				if (ludlist == NULL)
					rc = LDAP_URL_ERR_MEM;
			}

			switch (rc) {
			case LDAP_URL_SUCCESS:		/* Success */
				rc = LDAP_SUCCESS;
				break;

			case LDAP_URL_ERR_MEM:		/* can't allocate memory space */
				rc = LDAP_NO_MEMORY;
				break;

			case LDAP_URL_ERR_PARAM:	/* parameter is bad */
			case LDAP_URL_ERR_BADSCHEME:	/* URL doesn't begin with "ldap[si]://" */
			case LDAP_URL_ERR_BADENCLOSURE:	/* URL is missing trailing ">" */
			case LDAP_URL_ERR_BADURL:	/* URL is bad */
			case LDAP_URL_ERR_BADHOST:	/* host port is bad */
			case LDAP_URL_ERR_BADATTRS:	/* bad (or missing) attributes */
			case LDAP_URL_ERR_BADSCOPE:	/* scope string is invalid (or missing) */
			case LDAP_URL_ERR_BADFILTER:	/* bad or missing filter */
			case LDAP_URL_ERR_BADEXTS:	/* bad or missing extensions */
				rc = LDAP_PARAM_ERROR;
				break;
			}

			if (rc == LDAP_SUCCESS) {
				if (lo->ldo_defludp != NULL)
					ldap_free_urllist(lo->ldo_defludp);
				lo->ldo_defludp = ludlist;
			}
			break;
		}

	case LDAP_OPT_DEFBASE: {
			const char *newbase = (const char *) invalue;
			char *defbase = NULL;

			if ( newbase != NULL ) {
				defbase = LDAP_STRDUP( newbase );
				if ( defbase == NULL ) {
					rc = LDAP_NO_MEMORY;
					break;
				}

			} else if ( ld != NULL ) {
				defbase = LDAP_STRDUP( ldap_int_global_options.ldo_defbase );
				if ( defbase == NULL ) {
					rc = LDAP_NO_MEMORY;
					break;
				}
			}
			
			if ( lo->ldo_defbase != NULL )
				LDAP_FREE( lo->ldo_defbase );
			lo->ldo_defbase = defbase;
		}
		rc = LDAP_OPT_SUCCESS;
		break;

	case LDAP_OPT_DIAGNOSTIC_MESSAGE: {
			const char *err = (const char *) invalue;

			if(ld == NULL) {
				/* need a struct ldap */
				break;	/* LDAP_OPT_ERROR */
			}

			if( ld->ld_error ) {
				LDAP_FREE(ld->ld_error);
				ld->ld_error = NULL;
			}

			if ( err ) {
				ld->ld_error = LDAP_STRDUP(err);
			}
		}
		rc = LDAP_OPT_SUCCESS;
		break;

	case LDAP_OPT_MATCHED_DN: {
			const char *matched = (const char *) invalue;

			if (ld == NULL) {
				/* need a struct ldap */
				break;	/* LDAP_OPT_ERROR */
			}

			if( ld->ld_matched ) {
				LDAP_FREE(ld->ld_matched);
				ld->ld_matched = NULL;
			}

			if ( matched ) {
				ld->ld_matched = LDAP_STRDUP( matched );
			}
		}
		rc = LDAP_OPT_SUCCESS;
		break;

	case LDAP_OPT_REFERRAL_URLS: {
			char *const *referrals = (char *const *) invalue;
			
			if(ld == NULL) {
				/* need a struct ldap */
				break;	/* LDAP_OPT_ERROR */
			}

			if( ld->ld_referrals ) {
				LDAP_VFREE(ld->ld_referrals);
			}

			if ( referrals ) {
				ld->ld_referrals = ldap_value_dup(referrals);
			}
		}
		rc = LDAP_OPT_SUCCESS;
		break;

	/* Only accessed from inside this function by ldap_set_rebind_proc() */
	case LDAP_OPT_REBIND_PROC: {
			lo->ldo_rebind_proc = (LDAP_REBIND_PROC *)invalue;		
		}
		rc = LDAP_OPT_SUCCESS;
		break;
	case LDAP_OPT_REBIND_PARAMS: {
			lo->ldo_rebind_params = (void *)invalue;		
		}
		rc = LDAP_OPT_SUCCESS;
		break;

	/* Only accessed from inside this function by ldap_set_nextref_proc() */
	case LDAP_OPT_NEXTREF_PROC: {
			lo->ldo_nextref_proc = (LDAP_NEXTREF_PROC *)invalue;		
		}
		rc = LDAP_OPT_SUCCESS;
		break;
	case LDAP_OPT_NEXTREF_PARAMS: {
			lo->ldo_nextref_params = (void *)invalue;		
		}
		rc = LDAP_OPT_SUCCESS;
		break;

	/* Only accessed from inside this function by ldap_set_urllist_proc() */
	case LDAP_OPT_URLLIST_PROC: {
			lo->ldo_urllist_proc = (LDAP_URLLIST_PROC *)invalue;		
		}
		rc = LDAP_OPT_SUCCESS;
		break;
	case LDAP_OPT_URLLIST_PARAMS: {
			lo->ldo_urllist_params = (void *)invalue;		
		}
		rc = LDAP_OPT_SUCCESS;
		break;

	/* read-only options */
	case LDAP_OPT_API_INFO:
	case LDAP_OPT_DESC:
	case LDAP_OPT_SOCKBUF:
	case LDAP_OPT_API_FEATURE_INFO:
		break;	/* LDAP_OPT_ERROR */

	/* options which cannot withstand invalue == NULL */
	case LDAP_OPT_DEREF:
	case LDAP_OPT_SIZELIMIT:
	case LDAP_OPT_TIMELIMIT:
	case LDAP_OPT_PROTOCOL_VERSION:
	case LDAP_OPT_RESULT_CODE:
	case LDAP_OPT_DEBUG_LEVEL:
	case LDAP_OPT_TIMEOUT:
	case LDAP_OPT_NETWORK_TIMEOUT:
	case LDAP_OPT_CONNECT_CB:
	case LDAP_OPT_X_KEEPALIVE_IDLE:
	case LDAP_OPT_X_KEEPALIVE_PROBES :
	case LDAP_OPT_X_KEEPALIVE_INTERVAL :
		if(invalue == NULL) {
			/* no place to set from */
			LDAP_MUTEX_UNLOCK( &lo->ldo_mutex );
			return ( LDAP_OPT_ERROR );
		}
		break;

	default:
#ifdef HAVE_TLS
		if ( ldap_pvt_tls_set_option( ld, option, (void *)invalue ) == 0 ) {
			LDAP_MUTEX_UNLOCK( &lo->ldo_mutex );
			return ( LDAP_OPT_SUCCESS );
		}
#endif
#ifdef HAVE_CYRUS_SASL
		if ( ldap_int_sasl_set_option( ld, option, (void *)invalue ) == 0 ) {
			LDAP_MUTEX_UNLOCK( &lo->ldo_mutex );
			return ( LDAP_OPT_SUCCESS );
		}
#endif
#ifdef HAVE_GSSAPI
		if ( ldap_int_gssapi_set_option( ld, option, (void *)invalue ) == 0 ) {
			LDAP_MUTEX_UNLOCK( &lo->ldo_mutex );
			return ( LDAP_OPT_SUCCESS );
		}
#endif
		/* bad param */
		break;	/* LDAP_OPT_ERROR */
	}

	/* options which cannot withstand invalue == NULL */

	switch(option) {
	case LDAP_OPT_DEREF:
		/* FIXME: check value for protocol compliance? */
		lo->ldo_deref = * (const int *) invalue;
		rc = LDAP_OPT_SUCCESS;
		break;

	case LDAP_OPT_SIZELIMIT:
		/* FIXME: check value for protocol compliance? */
		lo->ldo_sizelimit = * (const int *) invalue;
		rc = LDAP_OPT_SUCCESS;
		break;

	case LDAP_OPT_TIMELIMIT:
		/* FIXME: check value for protocol compliance? */
		lo->ldo_timelimit = * (const int *) invalue;
		rc = LDAP_OPT_SUCCESS;
		break;

	case LDAP_OPT_TIMEOUT: {
			const struct timeval *tv = 
				(const struct timeval *) invalue;

			lo->ldo_tm_api = *tv;
		}
		rc = LDAP_OPT_SUCCESS;
		break;

	case LDAP_OPT_NETWORK_TIMEOUT: {
			const struct timeval *tv = 
				(const struct timeval *) invalue;

			lo->ldo_tm_net = *tv;
		}
		rc = LDAP_OPT_SUCCESS;
		break;

	case LDAP_OPT_PROTOCOL_VERSION: {
			int vers = * (const int *) invalue;
			if (vers < LDAP_VERSION_MIN || vers > LDAP_VERSION_MAX) {
				/* not supported */
				break;
			}
			lo->ldo_version = vers;
		}
		rc = LDAP_OPT_SUCCESS;
		break;

	case LDAP_OPT_RESULT_CODE: {
			int err = * (const int *) invalue;

			if(ld == NULL) {
				/* need a struct ldap */
				break;
			}

			ld->ld_errno = err;
		}
		rc = LDAP_OPT_SUCCESS;
		break;

	case LDAP_OPT_DEBUG_LEVEL:
		lo->ldo_debug = * (const int *) invalue;
		rc = LDAP_OPT_SUCCESS;
		break;

	case LDAP_OPT_CONNECT_CB:
		{
			/* setting pushes the callback */
			ldaplist *ll;
			ll = LDAP_MALLOC( sizeof( *ll ));
			ll->ll_data = (void *)invalue;
			ll->ll_next = lo->ldo_conn_cbs;
			lo->ldo_conn_cbs = ll;
		}
		rc = LDAP_OPT_SUCCESS;
		break;
	case LDAP_OPT_X_KEEPALIVE_IDLE:
		lo->ldo_keepalive_idle = * (const int *) invalue;
		rc = LDAP_OPT_SUCCESS;
		break;
	case LDAP_OPT_X_KEEPALIVE_PROBES :
		lo->ldo_keepalive_probes = * (const int *) invalue;
		rc = LDAP_OPT_SUCCESS;
		break;
	case LDAP_OPT_X_KEEPALIVE_INTERVAL :
		lo->ldo_keepalive_interval = * (const int *) invalue;
		rc = LDAP_OPT_SUCCESS;
		break;
	
	}
	LDAP_MUTEX_UNLOCK( &lo->ldo_mutex );
	return ( rc );
}
예제 #9
0
char *
ldap_first_attribute( LDAP *ld, LDAPMessage *entry, BerElement **berout )
{
	int rc;
	ber_tag_t tag;
	ber_len_t len = 0;
	char *attr;
	BerElement *ber;

	Debug( LDAP_DEBUG_TRACE, "ldap_first_attribute\n", 0, 0, 0 );

	assert( ld != NULL );
	assert( LDAP_VALID( ld ) );
	assert( entry != NULL );
	assert( berout != NULL );

	*berout = NULL;

	ber = ldap_alloc_ber_with_options( ld );
	if( ber == NULL ) {
		return NULL;
	}

	*ber = *entry->lm_ber;

	/* 
	 * Skip past the sequence, dn, sequence of sequence leaving
	 * us at the first attribute.
	 */

	tag = ber_scanf( ber, "{xl{" /*}}*/, &len );
	if( tag == LBER_ERROR ) {
		ld->ld_errno = LDAP_DECODING_ERROR;
		ber_free( ber, 0 );
		return NULL;
	}

	/* set the length to avoid overrun */
	rc = ber_set_option( ber, LBER_OPT_REMAINING_BYTES, &len );
	if( rc != LBER_OPT_SUCCESS ) {
		ld->ld_errno = LDAP_LOCAL_ERROR;
		ber_free( ber, 0 );
		return NULL;
	}

	if ( ber_pvt_ber_remaining( ber ) == 0 ) {
		assert( len == 0 );
		ber_free( ber, 0 );
		return NULL;
	}
	assert( len != 0 );

	/* snatch the first attribute */
	tag = ber_scanf( ber, "{ax}", &attr );
	if( tag == LBER_ERROR ) {
		ld->ld_errno = LDAP_DECODING_ERROR;
		ber_free( ber, 0 );
		return NULL;
	}

	*berout = ber;
	return attr;
}
예제 #10
0
파일: sasl.c 프로젝트: ystk/debian-openldap
int
ldap_parse_sasl_bind_result(
	LDAP			*ld,
	LDAPMessage		*res,
	struct berval	**servercredp,
	int				freeit )
{
	ber_int_t errcode;
	struct berval* scred;

	ber_tag_t tag;
	BerElement	*ber;

	Debug( LDAP_DEBUG_TRACE, "ldap_parse_sasl_bind_result\n", 0, 0, 0 );

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

	if( servercredp != NULL ) {
		if( ld->ld_version < LDAP_VERSION2 ) {
			return LDAP_NOT_SUPPORTED;
		}
		*servercredp = NULL;
	}

	if( res->lm_msgtype != LDAP_RES_BIND ) {
		ld->ld_errno = LDAP_PARAM_ERROR;
		return ld->ld_errno;
	}

	scred = NULL;

	if ( ld->ld_error ) {
		LDAP_FREE( ld->ld_error );
		ld->ld_error = NULL;
	}
	if ( ld->ld_matched ) {
		LDAP_FREE( ld->ld_matched );
		ld->ld_matched = NULL;
	}

	/* parse results */

	ber = ber_dup( res->lm_ber );

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

	if ( ld->ld_version < LDAP_VERSION2 ) {
		tag = ber_scanf( ber, "{iA}",
			&errcode, &ld->ld_error );

		if( tag == LBER_ERROR ) {
			ber_free( ber, 0 );
			ld->ld_errno = LDAP_DECODING_ERROR;
			return ld->ld_errno;
		}

	} else {
		ber_len_t len;

		tag = ber_scanf( ber, "{eAA" /*}*/,
			&errcode, &ld->ld_matched, &ld->ld_error );

		if( tag == LBER_ERROR ) {
			ber_free( ber, 0 );
			ld->ld_errno = LDAP_DECODING_ERROR;
			return ld->ld_errno;
		}

		tag = ber_peek_tag(ber, &len);

		if( tag == LDAP_TAG_REFERRAL ) {
			/* skip 'em */
			if( ber_scanf( ber, "x" ) == LBER_ERROR ) {
				ber_free( ber, 0 );
				ld->ld_errno = LDAP_DECODING_ERROR;
				return ld->ld_errno;
			}

			tag = ber_peek_tag(ber, &len);
		}

		if( tag == LDAP_TAG_SASL_RES_CREDS ) {
			if( ber_scanf( ber, "O", &scred ) == LBER_ERROR ) {
				ber_free( ber, 0 );
				ld->ld_errno = LDAP_DECODING_ERROR;
				return ld->ld_errno;
			}
		}
	}

	ber_free( ber, 0 );

	if ( servercredp != NULL ) {
		*servercredp = scred;

	} else if ( scred != NULL ) {
		ber_bvfree( scred );
	}

	ld->ld_errno = errcode;

	if ( freeit ) {
		ldap_msgfree( res );
	}

	return( LDAP_SUCCESS );
}
예제 #11
0
파일: vc.c 프로젝트: Distrotech/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;
		}

		rc = LDAP_DECODING_ERROR;

		if (ber_scanf(ber, "{im" /*"}"*/, &i, &diagmsg_bv) == LBER_ERROR) {
			goto ber_done;
		}
		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) {
			if (ber_scanf(ber, "O", cookie) == LBER_ERROR)
				goto ber_done;
			tag = ber_peek_tag(ber, &len);
		}

		if (tag == LDAP_TAG_EXOP_VERIFY_CREDENTIALS_SCREDS) {
			if (ber_scanf(ber, "O", screds) == LBER_ERROR)
				goto ber_done;
			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 ber_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 ber_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);
					goto ber_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;
			}
	    }

		rc = LDAP_SUCCESS;

	ber_done:
	    ber_free(ber, 1);
    }

done:
	ber_bvfree(retdata);
	ber_memfree(retoid);
	return rc;
}
예제 #12
0
파일: vc.c 프로젝트: Distrotech/openldap
int
ldap_verify_credentials(LDAP *ld,
	struct berval	*cookie,
	LDAP_CONST char *dn,
	LDAP_CONST char *mechanism,
	struct berval	*cred,
    LDAPControl		**vcctrls,
	LDAPControl		**sctrls,
	LDAPControl		**cctrls,
	int				*msgidp)
{
	int rc;
	BerElement *ber;
	struct berval reqdata;

	assert(ld != NULL);
	assert(LDAP_VALID(ld));
	assert(msgidp != NULL);

	ber = ber_alloc_t(LBER_USE_DER);
	if (dn == NULL) dn = "";

	if (mechanism == LDAP_SASL_SIMPLE) {
		assert(!cookie);

		rc = ber_printf(ber, "{stO" /*"}"*/,
			dn, LDAP_AUTH_SIMPLE, cred);

	} else {
		if (!cred || BER_BVISNULL(cred)) {
			if (cookie) {
				rc = ber_printf(ber, "{tOst{sN}" /*"}"*/,
					LDAP_TAG_EXOP_VERIFY_CREDENTIALS_COOKIE, cookie,
					dn, LDAP_AUTH_SASL, mechanism);
			} else {
				rc = ber_printf(ber, "{st{sN}N" /*"}"*/,
					dn, LDAP_AUTH_SASL, mechanism);
			}
		} else {
			if (cookie) {
				rc = ber_printf(ber, "{tOst{sON}" /*"}"*/,
					LDAP_TAG_EXOP_VERIFY_CREDENTIALS_COOKIE, cookie,
					dn, LDAP_AUTH_SASL, mechanism, cred);
			} else {
				rc = ber_printf(ber, "{st{sON}" /*"}"*/,
					dn, LDAP_AUTH_SASL, mechanism, cred);
			}
		}
	}

	if (rc < 0) {
		rc = ld->ld_errno = LDAP_ENCODING_ERROR;
		goto done;
	}

	if (vcctrls && *vcctrls) {
		LDAPControl *const *c;

		rc = ber_printf(ber, "t{" /*"}"*/, LDAP_TAG_EXOP_VERIFY_CREDENTIALS_CONTROLS);

		for (c=vcctrls; *c; c++) {
			rc = ldap_pvt_put_control(*c, ber);
			if (rc != LDAP_SUCCESS) {
				rc = ld->ld_errno = LDAP_ENCODING_ERROR;
				goto done;
			}
		}

		rc = ber_printf(ber, /*"{{"*/ "}N}");

	} else {
		rc = ber_printf(ber, /*"{"*/ "N}");
	}

	if (rc < 0) {
		rc = ld->ld_errno = LDAP_ENCODING_ERROR;
		goto done;
	}


	rc = ber_flatten2(ber, &reqdata, 0);
	if (rc < 0) {
		rc = ld->ld_errno = LDAP_ENCODING_ERROR;
		goto done;
	}

	rc = ldap_extended_operation(ld, LDAP_EXOP_VERIFY_CREDENTIALS,
		&reqdata, sctrls, cctrls, msgidp);

done:
	ber_free(ber, 1);
	return rc;
}
예제 #13
0
파일: error.c 프로젝트: vmware/lightwave
/*
 * Parse LDAPResult Messages:
 *
 *   LDAPResult ::= SEQUENCE {
 *     resultCode      ENUMERATED,
 *     matchedDN       LDAPDN,
 *     errorMessage    LDAPString,
 *     referral        [3] Referral OPTIONAL }
 *
 * including Bind results:
 *
 *   BindResponse ::= [APPLICATION 1] SEQUENCE {
 *     COMPONENTS OF LDAPResult,
 *     serverSaslCreds  [7] OCTET STRING OPTIONAL }
 *
 * and ExtendedOp results:
 *
 *   ExtendedResponse ::= [APPLICATION 24] SEQUENCE {
 *     COMPONENTS OF LDAPResult,
 *     responseName     [10] LDAPOID OPTIONAL,
 *     response         [11] OCTET STRING OPTIONAL }
 *
 */
int
ldap_parse_result(
	LDAP			*ld,
	LDAPMessage		*r,
	int				*errcodep,
	char			**matcheddnp,
	char			**errmsgp,
	char			***referralsp,
	LDAPControl		***serverctrls,
	int				freeit )
{
	LDAPMessage	*lm;
	ber_int_t errcode = LDAP_SUCCESS;

	ber_tag_t tag;
	BerElement	*ber;

	Debug( LDAP_DEBUG_TRACE, "ldap_parse_result\n", 0, 0, 0 );

	assert( ld != NULL );
	assert( LDAP_VALID( ld ) );
	assert( r != NULL );

	if(errcodep != NULL) *errcodep = LDAP_SUCCESS;
	if(matcheddnp != NULL) *matcheddnp = NULL;
	if(errmsgp != NULL) *errmsgp = NULL;
	if(referralsp != NULL) *referralsp = NULL;
	if(serverctrls != NULL) *serverctrls = NULL;

	LDAP_MUTEX_LOCK( &ld->ld_res_mutex );
	/* Find the result, last msg in chain... */
	lm = r->lm_chain_tail;
	/* FIXME: either this is not possible (assert?)
	 * or it should be handled */
	if ( lm != NULL ) {
		switch ( lm->lm_msgtype ) {
		case LDAP_RES_SEARCH_ENTRY:
		case LDAP_RES_SEARCH_REFERENCE:
		case LDAP_RES_INTERMEDIATE:
			lm = NULL;
			break;

		default:
			break;
		}
	}

	if( lm == NULL ) {
		errcode = ld->ld_errno = LDAP_NO_RESULTS_RETURNED;
		LDAP_MUTEX_UNLOCK( &ld->ld_res_mutex );
	    goto done;
	}

	if ( ld->ld_error ) {
		LDAP_FREE( ld->ld_error );
		ld->ld_error = NULL;
	}
	if ( ld->ld_matched ) {
		LDAP_FREE( ld->ld_matched );
		ld->ld_matched = NULL;
	}
	if ( ld->ld_referrals ) {
		LDAP_VFREE( ld->ld_referrals );
		ld->ld_referrals = NULL;
	}

	/* parse results */

	ber = ber_dup( lm->lm_ber );

	if ( ld->ld_version < LDAP_VERSION2 ) {
		tag = ber_scanf( ber, "{iA}",
			&ld->ld_errno, &ld->ld_error );

	} else {
		ber_len_t len;

		tag = ber_scanf( ber, "{iAA" /*}*/,
			&ld->ld_errno, &ld->ld_matched, &ld->ld_error );

		if( tag != LBER_ERROR ) {
			/* peek for referrals */
			if( ber_peek_tag(ber, &len) == LDAP_TAG_REFERRAL ) {
				tag = ber_scanf( ber, "v", &ld->ld_referrals );
			}
		}

		/* need to clean out misc items */
		if( tag != LBER_ERROR ) {
			if( lm->lm_msgtype == LDAP_RES_BIND ) {
				/* look for sasl result credentials */
				if ( ber_peek_tag( ber, &len ) == LDAP_TAG_SASL_RES_CREDS ) {
					/* skip 'em */
					tag = ber_scanf( ber, "x" );
				}

			} else if( lm->lm_msgtype == LDAP_RES_EXTENDED ) {
				/* look for exop result oid or value */
				if ( ber_peek_tag( ber, &len ) == LDAP_TAG_EXOP_RES_OID ) {
					/* skip 'em */
					tag = ber_scanf( ber, "x" );
				}

				if ( tag != LBER_ERROR &&
					ber_peek_tag( ber, &len ) == LDAP_TAG_EXOP_RES_VALUE )
				{
					/* skip 'em */
					tag = ber_scanf( ber, "x" );
				}
			}
		}

		if( tag != LBER_ERROR ) {
			int rc = ldap_pvt_get_controls( ber, serverctrls );

			if( rc != LDAP_SUCCESS ) {
				tag = LBER_ERROR;
			}
		}

		if( tag != LBER_ERROR ) {
			tag = ber_scanf( ber, /*{*/"}" );
		}
	}

	if ( tag == LBER_ERROR ) {
		ld->ld_errno = errcode = LDAP_DECODING_ERROR;
	}

	if( ber != NULL ) {
		ber_free( ber, 0 );
	}

	/* return */
	if( errcodep != NULL ) {
		*errcodep = ld->ld_errno;
	}
	if ( errcode == LDAP_SUCCESS ) {
		if( matcheddnp != NULL ) {
			if ( ld->ld_matched )
			{
				*matcheddnp = LDAP_STRDUP( ld->ld_matched );
			}
		}
		if( errmsgp != NULL ) {
			if ( ld->ld_error )
			{
				*errmsgp = LDAP_STRDUP( ld->ld_error );
			}
		}

		if( referralsp != NULL) {
			*referralsp = ldap_value_dup( ld->ld_referrals );
		}
	}
	LDAP_MUTEX_UNLOCK( &ld->ld_res_mutex );

done:
	if ( freeit ) {
		ldap_msgfree( r );
	}

	return errcode;
}
예제 #14
0
int
ldap_create_vlv_control_value(
    LDAP *ld,
    LDAPVLVInfo *vlvinfop,
    struct berval *value )
{
    ber_tag_t tag;
    BerElement *ber;

    if ( ld == NULL || vlvinfop == NULL || value == NULL ) {
        if ( ld )
            ld->ld_errno = LDAP_PARAM_ERROR;
        return LDAP_PARAM_ERROR;
    }

    assert( LDAP_VALID( ld ) );

    value->bv_val = NULL;
    value->bv_len = 0;
    ld->ld_errno = LDAP_SUCCESS;

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

    tag = ber_printf( ber, "{ii" /*}*/,
                      vlvinfop->ldvlv_before_count,
                      vlvinfop->ldvlv_after_count );
    if ( tag == LBER_ERROR ) {
        goto error_return;
    }

    if ( vlvinfop->ldvlv_attrvalue == NULL ) {
        tag = ber_printf( ber, "t{iiN}",
                          LDAP_VLVBYINDEX_IDENTIFIER,
                          vlvinfop->ldvlv_offset,
                          vlvinfop->ldvlv_count );
        if ( tag == LBER_ERROR ) {
            goto error_return;
        }

    } else {
        tag = ber_printf( ber, "tO",
                          LDAP_VLVBYVALUE_IDENTIFIER,
                          vlvinfop->ldvlv_attrvalue );
        if ( tag == LBER_ERROR ) {
            goto error_return;
        }
    }

    if ( vlvinfop->ldvlv_context ) {
        tag = ber_printf( ber, "tO",
                          LDAP_VLVCONTEXT_IDENTIFIER,
                          vlvinfop->ldvlv_context );
        if ( tag == LBER_ERROR ) {
            goto error_return;
        }
    }

    tag = ber_printf( ber, /*{*/ "N}" );
    if ( tag == LBER_ERROR ) {
        goto error_return;
    }

    if ( ber_flatten2( ber, value, 1 ) == -1 ) {
        ld->ld_errno = LDAP_NO_MEMORY;
    }

    if ( 0 ) {
error_return:
        ;
        ld->ld_errno = LDAP_ENCODING_ERROR;
    }

    if ( ber != NULL ) {
        ber_free( ber, 1 );
    }

    return ld->ld_errno;
}
예제 #15
0
/* Parse an extended result */
int
ldap_parse_extended_result (
	LDAP			*ld,
	LDAPMessage		*res,
	char			**retoidp,
	struct berval	**retdatap,
	int				freeit )
{
	BerElement *ber;
	ber_tag_t rc;
	ber_tag_t tag;
	ber_len_t len;
	struct berval *resdata;
	ber_int_t errcode;
	char *resoid;

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

	Debug( LDAP_DEBUG_TRACE, "ldap_parse_extended_result\n" );

	if( ld->ld_version < LDAP_VERSION3 ) {
		ld->ld_errno = LDAP_NOT_SUPPORTED;
		return ld->ld_errno;
	}

	if( res->lm_msgtype != LDAP_RES_EXTENDED ) {
		ld->ld_errno = LDAP_PARAM_ERROR;
		return ld->ld_errno;
	}

	if( retoidp != NULL ) *retoidp = NULL;
	if( retdatap != NULL ) *retdatap = NULL;

	if ( ld->ld_error ) {
		LDAP_FREE( ld->ld_error );
		ld->ld_error = NULL;
	}

	if ( ld->ld_matched ) {
		LDAP_FREE( ld->ld_matched );
		ld->ld_matched = NULL;
	}

	ber = ber_dup( res->lm_ber );

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

	rc = ber_scanf( ber, "{eAA" /*}*/, &errcode,
		&ld->ld_matched, &ld->ld_error );

	if( rc == LBER_ERROR ) {
		ld->ld_errno = LDAP_DECODING_ERROR;
		ber_free( ber, 0 );
		return ld->ld_errno;
	}

	resoid = NULL;
	resdata = NULL;

	tag = ber_peek_tag( ber, &len );

	if( tag == LDAP_TAG_REFERRAL ) {
		/* skip over referral */
		if( ber_scanf( ber, "x" ) == LBER_ERROR ) {
			ld->ld_errno = LDAP_DECODING_ERROR;
			ber_free( ber, 0 );
			return ld->ld_errno;
		}

		tag = ber_peek_tag( ber, &len );
	}

	if( tag == LDAP_TAG_EXOP_RES_OID ) {
		/* we have a resoid */
		if( ber_scanf( ber, "a", &resoid ) == LBER_ERROR ) {
			ld->ld_errno = LDAP_DECODING_ERROR;
			ber_free( ber, 0 );
			return ld->ld_errno;
		}

		assert( resoid[ 0 ] != '\0' );

		tag = ber_peek_tag( ber, &len );
	}

	if( tag == LDAP_TAG_EXOP_RES_VALUE ) {
		/* we have a resdata */
		if( ber_scanf( ber, "O", &resdata ) == LBER_ERROR ) {
			ld->ld_errno = LDAP_DECODING_ERROR;
			ber_free( ber, 0 );
			if( resoid != NULL ) LDAP_FREE( resoid );
			return ld->ld_errno;
		}
	}

	ber_free( ber, 0 );

	if( retoidp != NULL ) {
		*retoidp = resoid;
	} else {
		LDAP_FREE( resoid );
	}

	if( retdatap != NULL ) {
		*retdatap = resdata;
	} else {
		ber_bvfree( resdata );
	}

	ld->ld_errno = errcode;

	if( freeit ) {
		ldap_msgfree( res );
	}

	return LDAP_SUCCESS;
}
예제 #16
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);
}
예제 #17
0
/* Parse an extended partial */
int
ldap_parse_intermediate (
	LDAP			*ld,
	LDAPMessage		*res,
	char			**retoidp,
	struct berval	**retdatap,
	LDAPControl		***serverctrls,
	int				freeit )
{
	BerElement *ber;
	ber_tag_t tag;
	ber_len_t len;
	struct berval *resdata;
	char *resoid;

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

	Debug( LDAP_DEBUG_TRACE, "ldap_parse_intermediate\n" );

	if( ld->ld_version < LDAP_VERSION3 ) {
		ld->ld_errno = LDAP_NOT_SUPPORTED;
		return ld->ld_errno;
	}

	if( res->lm_msgtype != LDAP_RES_INTERMEDIATE ) {
		ld->ld_errno = LDAP_PARAM_ERROR;
		return ld->ld_errno;
	}

	if( retoidp != NULL ) *retoidp = NULL;
	if( retdatap != NULL ) *retdatap = NULL;
	if( serverctrls != NULL ) *serverctrls = NULL;

	ber = ber_dup( res->lm_ber );

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

	tag = ber_scanf( ber, "{" /*}*/ );

	if( tag == LBER_ERROR ) {
		ld->ld_errno = LDAP_DECODING_ERROR;
		ber_free( ber, 0 );
		return ld->ld_errno;
	}

	resoid = NULL;
	resdata = NULL;

	tag = ber_peek_tag( ber, &len );

	/*
	 * NOTE: accept intermediate and extended response tag values
	 * as older versions of slapd(8) incorrectly used extended
	 * response tags.
	 * Should be removed when 2.2 is moved to Historic.
	 */
	if( tag == LDAP_TAG_IM_RES_OID || tag == LDAP_TAG_EXOP_RES_OID ) {
		/* we have a resoid */
		if( ber_scanf( ber, "a", &resoid ) == LBER_ERROR ) {
			ld->ld_errno = LDAP_DECODING_ERROR;
			ber_free( ber, 0 );
			return ld->ld_errno;
		}

		assert( resoid[ 0 ] != '\0' );

		tag = ber_peek_tag( ber, &len );
	}

	if( tag == LDAP_TAG_IM_RES_VALUE || tag == LDAP_TAG_EXOP_RES_VALUE ) {
		/* we have a resdata */
		if( ber_scanf( ber, "O", &resdata ) == LBER_ERROR ) {
			ld->ld_errno = LDAP_DECODING_ERROR;
			ber_free( ber, 0 );
			if( resoid != NULL ) LDAP_FREE( resoid );
			return ld->ld_errno;
		}
	}

	if ( serverctrls == NULL ) {
		ld->ld_errno = LDAP_SUCCESS;
		goto free_and_return;
	}

	if ( ber_scanf( ber, /*{*/ "}" ) == LBER_ERROR ) {
		ld->ld_errno = LDAP_DECODING_ERROR;
		goto free_and_return;
	}

	ld->ld_errno = ldap_pvt_get_controls( ber, serverctrls );

free_and_return:
	ber_free( ber, 0 );

	if( retoidp != NULL ) {
		*retoidp = resoid;
	} else {
		LDAP_FREE( resoid );
	}

	if( retdatap != NULL ) {
		*retdatap = resdata;
	} else {
		ber_bvfree( resdata );
	}

	if( freeit ) {
		ldap_msgfree( res );
	}

	return ld->ld_errno;
}
예제 #18
0
int
ldap_get_option(
	LDAP	*ld,
	int		option,
	void	*outvalue)
{
	struct ldapoptions *lo;
	int rc = LDAP_OPT_ERROR;

	/* Get pointer to global option structure */
	lo = LDAP_INT_GLOBAL_OPT();   
	if (NULL == lo)	{
		return LDAP_NO_MEMORY;
	}

	if( lo->ldo_valid != LDAP_INITIALIZED ) {
		ldap_int_initialize(lo, NULL);
	}

	if(ld != NULL) {
		assert( LDAP_VALID( ld ) );

		if( !LDAP_VALID( ld ) ) {
			return LDAP_OPT_ERROR;
		}

		lo = &ld->ld_options;
	}

	if(outvalue == NULL) {
		/* no place to get to */
		return LDAP_OPT_ERROR;
	}

	LDAP_MUTEX_LOCK( &lo->ldo_mutex );

	switch(option) {
	case LDAP_OPT_API_INFO: {
			struct ldapapiinfo *info = (struct ldapapiinfo *) outvalue;

			if(info == NULL) {
				/* outvalue must point to an apiinfo structure */
				break;	/* LDAP_OPT_ERROR */
			}

			if(info->ldapai_info_version != LDAP_API_INFO_VERSION) {
				/* api info version mismatch */
				info->ldapai_info_version = LDAP_API_INFO_VERSION;
				break;	/* LDAP_OPT_ERROR */
			}

			info->ldapai_api_version = LDAP_API_VERSION;
			info->ldapai_protocol_version = LDAP_VERSION_MAX;

			if(features[0].ldapaif_name == NULL) {
				info->ldapai_extensions = NULL;
			} else {
				int i;
				info->ldapai_extensions = LDAP_MALLOC(sizeof(char *) *
					sizeof(features)/sizeof(LDAPAPIFeatureInfo));

				for(i=0; features[i].ldapaif_name != NULL; i++) {
					info->ldapai_extensions[i] =
						LDAP_STRDUP(features[i].ldapaif_name);
				}

				info->ldapai_extensions[i] = NULL;
			}

			info->ldapai_vendor_name = LDAP_STRDUP(LDAP_VENDOR_NAME);
			info->ldapai_vendor_version = LDAP_VENDOR_VERSION;

			rc = LDAP_OPT_SUCCESS;
			break;
		} break;

	case LDAP_OPT_DESC:
		if( ld == NULL || ld->ld_sb == NULL ) {
			/* bad param */
			break;
		} 

		ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_GET_FD, outvalue );
		rc = LDAP_OPT_SUCCESS;
		break;

	case LDAP_OPT_SOCKBUF:
		if( ld == NULL ) break;
		*(Sockbuf **)outvalue = ld->ld_sb;
		rc = LDAP_OPT_SUCCESS;
		break;

	case LDAP_OPT_TIMEOUT:
		/* the caller has to free outvalue ! */
		if ( lo->ldo_tm_api.tv_sec < 0 ) {
			*(void **)outvalue = NULL;
		} else if ( ldap_int_timeval_dup( outvalue, &lo->ldo_tm_api ) != 0 ) {
			break;	/* LDAP_OPT_ERROR */
		}
		rc = LDAP_OPT_SUCCESS;
		break;
		
	case LDAP_OPT_NETWORK_TIMEOUT:
		/* the caller has to free outvalue ! */
		if ( lo->ldo_tm_net.tv_sec < 0 ) {
			*(void **)outvalue = NULL;
		} else if ( ldap_int_timeval_dup( outvalue, &lo->ldo_tm_net ) != 0 ) {
			break;	/* LDAP_OPT_ERROR */
		}
		rc = LDAP_OPT_SUCCESS;
		break;

	case LDAP_OPT_DEREF:
		* (int *) outvalue = lo->ldo_deref;
		rc = LDAP_OPT_SUCCESS;
		break;

	case LDAP_OPT_SIZELIMIT:
		* (int *) outvalue = lo->ldo_sizelimit;
		rc = LDAP_OPT_SUCCESS;
		break;

	case LDAP_OPT_TIMELIMIT:
		* (int *) outvalue = lo->ldo_timelimit;
		rc = LDAP_OPT_SUCCESS;
		break;

	case LDAP_OPT_REFERRALS:
		* (int *) outvalue = (int) LDAP_BOOL_GET(lo, LDAP_BOOL_REFERRALS);
		rc = LDAP_OPT_SUCCESS;
		break;
		
	case LDAP_OPT_RESTART:
		* (int *) outvalue = (int) LDAP_BOOL_GET(lo, LDAP_BOOL_RESTART);
		rc = LDAP_OPT_SUCCESS;
		break;

	case LDAP_OPT_PROTOCOL_VERSION:
		* (int *) outvalue = lo->ldo_version;
		rc = LDAP_OPT_SUCCESS;
		break;

	case LDAP_OPT_SERVER_CONTROLS:
		* (LDAPControl ***) outvalue =
			ldap_controls_dup( lo->ldo_sctrls );
		rc = LDAP_OPT_SUCCESS;
		break;

	case LDAP_OPT_CLIENT_CONTROLS:
		* (LDAPControl ***) outvalue =
			ldap_controls_dup( lo->ldo_cctrls );
		rc = LDAP_OPT_SUCCESS;
		break;

	case LDAP_OPT_HOST_NAME:
		* (char **) outvalue = ldap_url_list2hosts(lo->ldo_defludp);
		rc = LDAP_OPT_SUCCESS;
		break;

	case LDAP_OPT_URI:
		* (char **) outvalue = ldap_url_list2urls(lo->ldo_defludp);
		rc = LDAP_OPT_SUCCESS;
		break;

	case LDAP_OPT_DEFBASE:
		if( lo->ldo_defbase == NULL ) {
			* (char **) outvalue = NULL;
		} else {
			* (char **) outvalue = LDAP_STRDUP(lo->ldo_defbase);
		}
		rc = LDAP_OPT_SUCCESS;
		break;

	case LDAP_OPT_CONNECT_ASYNC:
		* (int *) outvalue = (int) LDAP_BOOL_GET(lo, LDAP_BOOL_CONNECT_ASYNC);
		rc = LDAP_OPT_SUCCESS;
		break;

	case LDAP_OPT_CONNECT_CB:
		{
			/* Getting deletes the specified callback */
			ldaplist **ll = &lo->ldo_conn_cbs;
			for (;*ll;ll = &(*ll)->ll_next) {
				if ((*ll)->ll_data == outvalue) {
					ldaplist *lc = *ll;
					*ll = lc->ll_next;
					LDAP_FREE(lc);
					break;
				}
			}
		}
		rc = LDAP_OPT_SUCCESS;
		break;

	case LDAP_OPT_RESULT_CODE:
		if(ld == NULL) {
			/* bad param */
			break;
		} 
		* (int *) outvalue = ld->ld_errno;
		rc = LDAP_OPT_SUCCESS;
		break;

	case LDAP_OPT_DIAGNOSTIC_MESSAGE:
		if(ld == NULL) {
			/* bad param */
			break;
		} 

		if( ld->ld_error == NULL ) {
			* (char **) outvalue = NULL;
		} else {
			* (char **) outvalue = LDAP_STRDUP(ld->ld_error);
		}
		rc = LDAP_OPT_SUCCESS;
		break;

	case LDAP_OPT_MATCHED_DN:
		if(ld == NULL) {
			/* bad param */
			break;
		} 

		if( ld->ld_matched == NULL ) {
			* (char **) outvalue = NULL;
		} else {
			* (char **) outvalue = LDAP_STRDUP( ld->ld_matched );
		}
		rc = LDAP_OPT_SUCCESS;
		break;

	case LDAP_OPT_REFERRAL_URLS:
		if(ld == NULL) {
			/* bad param */
			break;
		} 

		if( ld->ld_referrals == NULL ) {
			* (char ***) outvalue = NULL;
		} else {
			* (char ***) outvalue = ldap_value_dup(ld->ld_referrals);
		}
		rc = LDAP_OPT_SUCCESS;
		break;

	case LDAP_OPT_API_FEATURE_INFO: {
			LDAPAPIFeatureInfo *info = (LDAPAPIFeatureInfo *) outvalue;
			int i;

			if(info == NULL)
				break;	/* LDAP_OPT_ERROR */

			if(info->ldapaif_info_version != LDAP_FEATURE_INFO_VERSION) {
				/* api info version mismatch */
				info->ldapaif_info_version = LDAP_FEATURE_INFO_VERSION;
				break;	/* LDAP_OPT_ERROR */
			}

			if(info->ldapaif_name == NULL)
				break;	/* LDAP_OPT_ERROR */

			for(i=0; features[i].ldapaif_name != NULL; i++) {
				if(!strcmp(info->ldapaif_name, features[i].ldapaif_name)) {
					info->ldapaif_version =
						features[i].ldapaif_version;
					rc = LDAP_OPT_SUCCESS;
					break;
				}
			}
		}
		break;

	case LDAP_OPT_DEBUG_LEVEL:
		* (int *) outvalue = lo->ldo_debug;
		rc = LDAP_OPT_SUCCESS;
		break;
	
	case LDAP_OPT_SESSION_REFCNT:
		if(ld == NULL) {
			/* bad param */
			break;
		} 
		LDAP_MUTEX_LOCK( &ld->ld_ldcmutex );
		* (int *) outvalue = ld->ld_ldcrefcnt;
		LDAP_MUTEX_UNLOCK( &ld->ld_ldcmutex );
		rc = LDAP_OPT_SUCCESS;
		break;

	case LDAP_OPT_X_KEEPALIVE_IDLE:
		* (int *) outvalue = lo->ldo_keepalive_idle;
		rc = LDAP_OPT_SUCCESS;
		break;

	case LDAP_OPT_X_KEEPALIVE_PROBES:
		* (int *) outvalue = lo->ldo_keepalive_probes;
		rc = LDAP_OPT_SUCCESS;
		break;

	case LDAP_OPT_X_KEEPALIVE_INTERVAL:
		* (int *) outvalue = lo->ldo_keepalive_interval;
		rc = LDAP_OPT_SUCCESS;
		break;

	default:
#ifdef HAVE_TLS
		if ( ldap_pvt_tls_get_option( ld, option, outvalue ) == 0 ) {
			rc = LDAP_OPT_SUCCESS;
			break;
		}
#endif
#ifdef HAVE_CYRUS_SASL
		if ( ldap_int_sasl_get_option( ld, option, outvalue ) == 0 ) {
			rc = LDAP_OPT_SUCCESS;
			break;
		}
#endif
#ifdef HAVE_GSSAPI
		if ( ldap_int_gssapi_get_option( ld, option, outvalue ) == 0 ) {
			rc = LDAP_OPT_SUCCESS;
			break;
		}
#endif
		/* bad param */
		break;
	}

	LDAP_MUTEX_UNLOCK( &lo->ldo_mutex );
	return ( rc );
}
예제 #19
0
int
ldap_extended_operation(
	LDAP			*ld,
	LDAP_CONST char	*reqoid,
	struct berval	*reqdata,
	LDAPControl		**sctrls,
	LDAPControl		**cctrls,
	int				*msgidp )
{
	BerElement *ber;
	int rc;
	ber_int_t id;

	Debug( LDAP_DEBUG_TRACE, "ldap_extended_operation\n" );

	assert( ld != NULL );
	assert( LDAP_VALID( ld ) );
	assert( reqoid != NULL && *reqoid != '\0' );
	assert( msgidp != NULL );

	/* must be version 3 (or greater) */
	if ( ld->ld_version < LDAP_VERSION3 ) {
		ld->ld_errno = LDAP_NOT_SUPPORTED;
		return( ld->ld_errno );
	}

	/* create a message to send */
	if ( (ber = ldap_alloc_ber_with_options( ld )) == NULL ) {
		ld->ld_errno = LDAP_NO_MEMORY;
		return( ld->ld_errno );
	}

	LDAP_NEXT_MSGID( ld, id );
	if ( reqdata != NULL ) {
		rc = ber_printf( ber, "{it{tstON}", /* '}' */
			id, LDAP_REQ_EXTENDED,
			LDAP_TAG_EXOP_REQ_OID, reqoid,
			LDAP_TAG_EXOP_REQ_VALUE, reqdata );

	} else {
		rc = ber_printf( ber, "{it{tsN}", /* '}' */
			id, LDAP_REQ_EXTENDED,
			LDAP_TAG_EXOP_REQ_OID, reqoid );
	}

	if( rc == -1 ) {
		ld->ld_errno = LDAP_ENCODING_ERROR;
		ber_free( ber, 1 );
		return( ld->ld_errno );
	}

	/* Put Server Controls */
	if( ldap_int_put_controls( ld, sctrls, ber ) != LDAP_SUCCESS ) {
		ber_free( ber, 1 );
		return ld->ld_errno;
	}

	if ( ber_printf( ber, /*{*/ "N}" ) == -1 ) {
		ld->ld_errno = LDAP_ENCODING_ERROR;
		ber_free( ber, 1 );
		return( ld->ld_errno );
	}

	/* send the message */
	*msgidp = ldap_send_initial_request( ld, LDAP_REQ_EXTENDED, NULL, ber, id );

	return( *msgidp < 0 ? ld->ld_errno : LDAP_SUCCESS );
}
예제 #20
0
파일: sortctrl.c 프로젝트: benegon/openldap
int
ldap_parse_sortresponse_control(
	LDAP *ld,
	LDAPControl *ctrl,
	ber_int_t *returnCode,
	char **attribute )
{
	BerElement *ber;
	ber_tag_t tag, berTag;
	ber_len_t berLen;

	assert( ld != NULL );
	assert( LDAP_VALID( ld ) );

	if (ld == NULL) {
		return LDAP_PARAM_ERROR;
	}

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

	if (attribute) {
		*attribute = NULL;
	}

	if ( strcmp(LDAP_CONTROL_SORTRESPONSE, ctrl->ldctl_oid) != 0 ) {
		/* Not sort result control */
		ld->ld_errno = LDAP_CONTROL_NOT_FOUND;
		return(ld->ld_errno);
	}

	/* 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 result code from the control. */
	tag = ber_scanf(ber, "{e" /*}*/, returnCode);

	if( tag == LBER_ERROR ) {
		ber_free(ber, 1);
		ld->ld_errno = LDAP_DECODING_ERROR;
		return(ld->ld_errno);
	}

	/* If caller wants the attribute name, and if it's present in the control,
	   extract the attribute name which caused the error. */
	if (attribute && (LDAP_ATTRTYPES_IDENTIFIER == ber_peek_tag(ber, &berLen)))
	{
		tag = ber_scanf(ber, "ta", &berTag, attribute);

		if (tag == LBER_ERROR ) {
			ber_free(ber, 1);
			ld->ld_errno = LDAP_DECODING_ERROR;
			return(ld->ld_errno);
		}
	}

	ber_free(ber,1);

	ld->ld_errno = LDAP_SUCCESS;
	return(ld->ld_errno);
}
예제 #21
0
파일: tls2.c 프로젝트: Distrotech/openldap
int
ldap_pvt_tls_set_option( LDAP *ld, int option, void *arg )
{
	struct ldapoptions *lo;

	if( ld != NULL ) {
		assert( LDAP_VALID( ld ) );

		if( !LDAP_VALID( ld ) ) {
			return LDAP_OPT_ERROR;
		}

		lo = &ld->ld_options;

	} else {
		/* Get pointer to global option structure */
		lo = LDAP_INT_GLOBAL_OPT();   
		if ( lo == NULL ) {
			return LDAP_NO_MEMORY;
		}
	}

	switch( option ) {
	case LDAP_OPT_X_TLS:
		if ( !arg ) return -1;

		switch( *(int *) arg ) {
		case LDAP_OPT_X_TLS_NEVER:
		case LDAP_OPT_X_TLS_DEMAND:
		case LDAP_OPT_X_TLS_ALLOW:
		case LDAP_OPT_X_TLS_TRY:
		case LDAP_OPT_X_TLS_HARD:
			if (lo != NULL) {
				lo->ldo_tls_mode = *(int *)arg;
			}

			return 0;
		}
		return -1;

	case LDAP_OPT_X_TLS_CTX:
		if ( lo->ldo_tls_ctx )
			ldap_pvt_tls_ctx_free( lo->ldo_tls_ctx );
		lo->ldo_tls_ctx = arg;
		tls_ctx_ref( lo->ldo_tls_ctx );
		return 0;
	case LDAP_OPT_X_TLS_CONNECT_CB:
		lo->ldo_tls_connect_cb = (LDAP_TLS_CONNECT_CB *)arg;
		return 0;
	case LDAP_OPT_X_TLS_CONNECT_ARG:
		lo->ldo_tls_connect_arg = arg;
		return 0;
	case LDAP_OPT_X_TLS_CACERTFILE:
		if ( lo->ldo_tls_cacertfile ) LDAP_FREE( lo->ldo_tls_cacertfile );
		lo->ldo_tls_cacertfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
		return 0;
	case LDAP_OPT_X_TLS_CACERTDIR:
		if ( lo->ldo_tls_cacertdir ) LDAP_FREE( lo->ldo_tls_cacertdir );
		lo->ldo_tls_cacertdir = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
		return 0;
	case LDAP_OPT_X_TLS_CERTFILE:
		if ( lo->ldo_tls_certfile ) LDAP_FREE( lo->ldo_tls_certfile );
		lo->ldo_tls_certfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
		return 0;
	case LDAP_OPT_X_TLS_KEYFILE:
		if ( lo->ldo_tls_keyfile ) LDAP_FREE( lo->ldo_tls_keyfile );
		lo->ldo_tls_keyfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
		return 0;
	case LDAP_OPT_X_TLS_DHFILE:
		if ( lo->ldo_tls_dhfile ) LDAP_FREE( lo->ldo_tls_dhfile );
		lo->ldo_tls_dhfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
		return 0;
	case LDAP_OPT_X_TLS_ECNAME:
		if ( lo->ldo_tls_ecname ) LDAP_FREE( lo->ldo_tls_ecname );
		lo->ldo_tls_ecname = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
		return 0;
	case LDAP_OPT_X_TLS_CRLFILE:	/* GnuTLS only */
		if ( lo->ldo_tls_crlfile ) LDAP_FREE( lo->ldo_tls_crlfile );
		lo->ldo_tls_crlfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
		return 0;
	case LDAP_OPT_X_TLS_REQUIRE_CERT:
		if ( !arg ) return -1;
		switch( *(int *) arg ) {
		case LDAP_OPT_X_TLS_NEVER:
		case LDAP_OPT_X_TLS_DEMAND:
		case LDAP_OPT_X_TLS_ALLOW:
		case LDAP_OPT_X_TLS_TRY:
		case LDAP_OPT_X_TLS_HARD:
			lo->ldo_tls_require_cert = * (int *) arg;
			return 0;
		}
		return -1;
#ifdef HAVE_OPENSSL_CRL
	case LDAP_OPT_X_TLS_CRLCHECK:	/* OpenSSL only */
		if ( !arg ) return -1;
		switch( *(int *) arg ) {
		case LDAP_OPT_X_TLS_CRL_NONE:
		case LDAP_OPT_X_TLS_CRL_PEER:
		case LDAP_OPT_X_TLS_CRL_ALL:
			lo->ldo_tls_crlcheck = * (int *) arg;
			return 0;
		}
		return -1;
#endif
	case LDAP_OPT_X_TLS_CIPHER_SUITE:
		if ( lo->ldo_tls_ciphersuite ) LDAP_FREE( lo->ldo_tls_ciphersuite );
		lo->ldo_tls_ciphersuite = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
		return 0;

	case LDAP_OPT_X_TLS_PROTOCOL_MIN:
		if ( !arg ) return -1;
		lo->ldo_tls_protocol_min = *(int *)arg;
		return 0;
	case LDAP_OPT_X_TLS_RANDOM_FILE:
		if ( ld != NULL )
			return -1;
		if ( lo->ldo_tls_randfile ) LDAP_FREE (lo->ldo_tls_randfile );
		lo->ldo_tls_randfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
		break;
	case LDAP_OPT_X_TLS_NEWCTX:
		if ( !arg ) return -1;
		if ( lo->ldo_tls_ctx )
			ldap_pvt_tls_ctx_free( lo->ldo_tls_ctx );
		lo->ldo_tls_ctx = NULL;
		return ldap_int_tls_init_ctx( lo, *(int *)arg );
	default:
		return -1;
	}
	return 0;
}
예제 #22
0
파일: tls2.c 프로젝트: RevanthPar/openldap
int
ldap_pvt_tls_get_option( LDAP *ld, int option, void *arg )
{
	struct ldapoptions *lo;

	if( option == LDAP_OPT_X_TLS_PACKAGE ) {
		*(char **)arg = LDAP_STRDUP( tls_imp->ti_name );
		return 0;
	}

	if( ld != NULL ) {
		assert( LDAP_VALID( ld ) );

		if( !LDAP_VALID( ld ) ) {
			return LDAP_OPT_ERROR;
		}

		lo = &ld->ld_options;

	} else {
		/* Get pointer to global option structure */
		lo = LDAP_INT_GLOBAL_OPT();   
		if ( lo == NULL ) {
			return LDAP_NO_MEMORY;
		}
	}

	switch( option ) {
	case LDAP_OPT_X_TLS:
		*(int *)arg = lo->ldo_tls_mode;
		break;
	case LDAP_OPT_X_TLS_CTX:
		*(void **)arg = lo->ldo_tls_ctx;
		if ( lo->ldo_tls_ctx ) {
			tls_ctx_ref( lo->ldo_tls_ctx );
		}
		break;
	case LDAP_OPT_X_TLS_CACERTFILE:
		*(char **)arg = lo->ldo_tls_cacertfile ?
			LDAP_STRDUP( lo->ldo_tls_cacertfile ) : NULL;
		break;
	case LDAP_OPT_X_TLS_CACERTDIR:
		*(char **)arg = lo->ldo_tls_cacertdir ?
			LDAP_STRDUP( lo->ldo_tls_cacertdir ) : NULL;
		break;
	case LDAP_OPT_X_TLS_CERTFILE:
		*(char **)arg = lo->ldo_tls_certfile ?
			LDAP_STRDUP( lo->ldo_tls_certfile ) : NULL;
		break;
	case LDAP_OPT_X_TLS_KEYFILE:
		*(char **)arg = lo->ldo_tls_keyfile ?
			LDAP_STRDUP( lo->ldo_tls_keyfile ) : NULL;
		break;
	case LDAP_OPT_X_TLS_DHFILE:
		*(char **)arg = lo->ldo_tls_dhfile ?
			LDAP_STRDUP( lo->ldo_tls_dhfile ) : NULL;
		break;
	case LDAP_OPT_X_TLS_CRLFILE:	/* GnuTLS only */
		*(char **)arg = lo->ldo_tls_crlfile ?
			LDAP_STRDUP( lo->ldo_tls_crlfile ) : NULL;
		break;
	case LDAP_OPT_X_TLS_REQUIRE_CERT:
		*(int *)arg = lo->ldo_tls_require_cert;
		break;
#ifdef HAVE_OPENSSL_CRL
	case LDAP_OPT_X_TLS_CRLCHECK:	/* OpenSSL only */
		*(int *)arg = lo->ldo_tls_crlcheck;
		break;
#endif
	case LDAP_OPT_X_TLS_CIPHER_SUITE:
		*(char **)arg = lo->ldo_tls_ciphersuite ?
			LDAP_STRDUP( lo->ldo_tls_ciphersuite ) : NULL;
		break;
	case LDAP_OPT_X_TLS_PROTOCOL_MIN:
		*(int *)arg = lo->ldo_tls_protocol_min;
		break;
	case LDAP_OPT_X_TLS_RANDOM_FILE:
		*(char **)arg = lo->ldo_tls_randfile ?
			LDAP_STRDUP( lo->ldo_tls_randfile ) : NULL;
		break;
	case LDAP_OPT_X_TLS_SSL_CTX: {
		void *retval = 0;
		if ( ld != NULL ) {
			LDAPConn *conn = ld->ld_defconn;
			if ( conn != NULL ) {
				Sockbuf *sb = conn->lconn_sb;
				retval = ldap_pvt_tls_sb_ctx( sb );
			}
		}
		*(void **)arg = retval;
		break;
	}
	case LDAP_OPT_X_TLS_CONNECT_CB:
		*(LDAP_TLS_CONNECT_CB **)arg = lo->ldo_tls_connect_cb;
		break;
	case LDAP_OPT_X_TLS_CONNECT_ARG:
		*(void **)arg = lo->ldo_tls_connect_arg;
		break;
	default:
		return -1;
	}
	return 0;
}
예제 #23
0
파일: add.c 프로젝트: ystk/debian-openldap
/*
 * ldap_add_ext - initiate an ldap extended add operation.  Parameters:
 *
 *	ld		LDAP descriptor
 *	dn		DN of the entry to add
 *	mods		List of attributes for the entry.  This is a null-
 *			terminated array of pointers to LDAPMod structures.
 *			only the type and values in the structures need be
 *			filled in.
 *	sctrl	Server Controls
 *	cctrl	Client Controls
 *	msgidp	Message ID pointer
 *
 * Example:
 *	LDAPMod	*attrs[] = { 
 *			{ 0, "cn", { "babs jensen", "babs", 0 } },
 *			{ 0, "sn", { "jensen", 0 } },
 *			{ 0, "objectClass", { "person", 0 } },
 *			0
 *		}
 *	rc = ldap_add_ext( ld, dn, attrs, NULL, NULL, &msgid );
 */
int
ldap_add_ext(
	LDAP *ld,
	LDAP_CONST char *dn,
	LDAPMod **attrs,
	LDAPControl **sctrls,
	LDAPControl **cctrls,
	int	*msgidp )
{
	BerElement	*ber;
	int		i, rc;
	ber_int_t	id;

	Debug( LDAP_DEBUG_TRACE, "ldap_add_ext\n", 0, 0, 0 );
	assert( ld != NULL );
	assert( LDAP_VALID( ld ) );
	assert( dn != NULL );
	assert( msgidp != NULL );

	/* check client controls */
	rc = ldap_int_client_controls( ld, cctrls );
	if( rc != LDAP_SUCCESS ) return rc;

	/* create a message to send */
	if ( (ber = ldap_alloc_ber_with_options( ld )) == NULL ) {
		ld->ld_errno = LDAP_NO_MEMORY;
		return ld->ld_errno;
	}

	LDAP_NEXT_MSGID(ld, id);
	rc = ber_printf( ber, "{it{s{", /* '}}}' */
		id, LDAP_REQ_ADD, dn );

	if ( rc == -1 ) {
		ld->ld_errno = LDAP_ENCODING_ERROR;
		ber_free( ber, 1 );
		return ld->ld_errno;
	}

	/* allow attrs to be NULL ("touch"; should fail...) */
	if ( attrs ) {
		/* for each attribute in the entry... */
		for ( i = 0; attrs[i] != NULL; i++ ) {
			if ( ( attrs[i]->mod_op & LDAP_MOD_BVALUES) != 0 ) {
				int j;

				if ( attrs[i]->mod_bvalues == NULL ) {
					ld->ld_errno = LDAP_PARAM_ERROR;
					ber_free( ber, 1 );
					return ld->ld_errno;
				}

				for ( j = 0; attrs[i]->mod_bvalues[ j ] != NULL; j++ ) {
					if ( attrs[i]->mod_bvalues[ j ]->bv_val == NULL ) {
						ld->ld_errno = LDAP_PARAM_ERROR;
						ber_free( ber, 1 );
						return ld->ld_errno;
					}
				}

				rc = ber_printf( ber, "{s[V]N}", attrs[i]->mod_type,
				    attrs[i]->mod_bvalues );

			} else {
				if ( attrs[i]->mod_values == NULL ) {
					ld->ld_errno = LDAP_PARAM_ERROR;
					ber_free( ber, 1 );
					return ld->ld_errno;
				}

				rc = ber_printf( ber, "{s[v]N}", attrs[i]->mod_type,
				    attrs[i]->mod_values );
			}
			if ( rc == -1 ) {
				ld->ld_errno = LDAP_ENCODING_ERROR;
				ber_free( ber, 1 );
				return ld->ld_errno;
			}
		}
	}

	if ( ber_printf( ber, /*{{*/ "N}N}" ) == -1 ) {
		ld->ld_errno = LDAP_ENCODING_ERROR;
		ber_free( ber, 1 );
		return ld->ld_errno;
	}

	/* Put Server Controls */
	if( ldap_int_put_controls( ld, sctrls, ber ) != LDAP_SUCCESS ) {
		ber_free( ber, 1 );
		return ld->ld_errno;
	}

	if ( ber_printf( ber, /*{*/ "N}" ) == -1 ) {
		ld->ld_errno = LDAP_ENCODING_ERROR;
		ber_free( ber, 1 );
		return ld->ld_errno;
	}

	/* send the message */
	*msgidp = ldap_send_initial_request( ld, LDAP_REQ_ADD, dn, ber, id );

	if(*msgidp < 0)
		return ld->ld_errno;

	return LDAP_SUCCESS;
}