Beispiel #1
0
int
do_search(
    Operation	*op,	/* info about the op to which we're responding */
    SlapReply	*rs	/* all the response data we'll send */ )
{
	struct berval base = BER_BVNULL;
	ber_len_t	siz, off, i;

	Debug( LDAP_DEBUG_TRACE, "%s do_search\n",
		op->o_log_prefix, 0, 0 );
	/*
	 * Parse the search request.  It looks like this:
	 *
	 *	SearchRequest := [APPLICATION 3] SEQUENCE {
	 *		baseObject	DistinguishedName,
	 *		scope		ENUMERATED {
	 *			baseObject	(0),
	 *			singleLevel	(1),
	 *			wholeSubtree (2),
	 *          subordinate (3)  -- OpenLDAP extension
	 *		},
	 *		derefAliases	ENUMERATED {
	 *			neverDerefaliases	(0),
	 *			derefInSearching	(1),
	 *			derefFindingBaseObj	(2),
	 *			alwaysDerefAliases	(3)
	 *		},
	 *		sizelimit	INTEGER (0 .. 65535),
	 *		timelimit	INTEGER (0 .. 65535),
	 *		attrsOnly	BOOLEAN,
	 *		filter		Filter,
	 *		attributes	SEQUENCE OF AttributeType
	 *	}
	 */

	/* baseObject, scope, derefAliases, sizelimit, timelimit, attrsOnly */
	if ( ber_scanf( op->o_ber, "{miiiib" /*}*/,
		&base, &op->ors_scope, &op->ors_deref, &op->ors_slimit,
	    &op->ors_tlimit, &op->ors_attrsonly ) == LBER_ERROR )
	{
		send_ldap_discon( op, rs, LDAP_PROTOCOL_ERROR, "decoding error" );
		rs->sr_err = SLAPD_DISCONNECT;
		goto return_results;
	}

	if ( op->ors_tlimit < 0 || op->ors_tlimit > SLAP_MAX_LIMIT ) {
		send_ldap_error( op, rs, LDAP_PROTOCOL_ERROR, "invalid time limit" );
		goto return_results;
	}

	if ( op->ors_slimit < 0 || op->ors_slimit > SLAP_MAX_LIMIT ) {
		send_ldap_error( op, rs, LDAP_PROTOCOL_ERROR, "invalid size limit" );
		goto return_results;
	}

	switch( op->ors_scope ) {
	case LDAP_SCOPE_BASE:
	case LDAP_SCOPE_ONELEVEL:
	case LDAP_SCOPE_SUBTREE:
	case LDAP_SCOPE_SUBORDINATE:
		break;
	default:
		send_ldap_error( op, rs, LDAP_PROTOCOL_ERROR, "invalid scope" );
		goto return_results;
	}

	switch( op->ors_deref ) {
	case LDAP_DEREF_NEVER:
	case LDAP_DEREF_FINDING:
	case LDAP_DEREF_SEARCHING:
	case LDAP_DEREF_ALWAYS:
		break;
	default:
		send_ldap_error( op, rs, LDAP_PROTOCOL_ERROR, "invalid deref" );
		goto return_results;
	}

	rs->sr_err = dnPrettyNormal( NULL, &base, &op->o_req_dn, &op->o_req_ndn, op->o_tmpmemctx );
	if( rs->sr_err != LDAP_SUCCESS ) {
		Debug( LDAP_DEBUG_ANY, "%s do_search: invalid dn: \"%s\"\n",
			op->o_log_prefix, base.bv_val, 0 );
		send_ldap_error( op, rs, LDAP_INVALID_DN_SYNTAX, "invalid DN" );
		goto return_results;
	}

	Debug( LDAP_DEBUG_ARGS, "SRCH \"%s\" %d %d",
		base.bv_val, op->ors_scope, op->ors_deref );
	Debug( LDAP_DEBUG_ARGS, "    %d %d %d\n",
		op->ors_slimit, op->ors_tlimit, op->ors_attrsonly);

	/* filter - returns a "normalized" version */
	rs->sr_err = get_filter( op, op->o_ber, &op->ors_filter, &rs->sr_text );
	if( rs->sr_err != LDAP_SUCCESS ) {
		if( rs->sr_err == SLAPD_DISCONNECT ) {
			rs->sr_err = LDAP_PROTOCOL_ERROR;
			send_ldap_disconnect( op, rs );
			rs->sr_err = SLAPD_DISCONNECT;
		} else {
			send_ldap_result( op, rs );
		}
		goto return_results;
	}
	filter2bv_x( op, op->ors_filter, &op->ors_filterstr );
	
	Debug( LDAP_DEBUG_ARGS, "    filter: %s\n",
		!BER_BVISEMPTY( &op->ors_filterstr ) ? op->ors_filterstr.bv_val : "empty", 0, 0 );

	/* attributes */
	siz = sizeof(AttributeName);
	off = offsetof(AttributeName,an_name);
	if ( ber_scanf( op->o_ber, "{M}}", &op->ors_attrs, &siz, off ) == LBER_ERROR ) {
		send_ldap_discon( op, rs, LDAP_PROTOCOL_ERROR, "decoding attrs error" );
		rs->sr_err = SLAPD_DISCONNECT;
		goto return_results;
	}
	for ( i=0; i<siz; i++ ) {
		const char *dummy;	/* ignore msgs from bv2ad */
		op->ors_attrs[i].an_desc = NULL;
		op->ors_attrs[i].an_oc = NULL;
		op->ors_attrs[i].an_flags = 0;
		if ( slap_bv2ad( &op->ors_attrs[i].an_name,
			&op->ors_attrs[i].an_desc, &dummy ) != LDAP_SUCCESS )
		{
			if ( slap_bv2undef_ad( &op->ors_attrs[i].an_name,
				&op->ors_attrs[i].an_desc, &dummy,
				SLAP_AD_PROXIED|SLAP_AD_NOINSERT ) )
			{
				struct berval *bv = &op->ors_attrs[i].an_name;

				/* RFC 4511 LDAPv3: All User Attributes */
				if ( bvmatch( bv, slap_bv_all_user_attrs ) ) {
					continue;
				}

				/* RFC 3673 LDAPv3: All Operational Attributes */
				if ( bvmatch( bv, slap_bv_all_operational_attrs ) ) {
					continue;
				}

				/* RFC 4529 LDAP: Requesting Attributes by Object Class */
				if ( bv->bv_len > 1 && bv->bv_val[0] == '@' ) {
					/* FIXME: check if remaining is valid oc name? */
					continue;
				}

				/* add more "exceptions" to RFC 4511 4.5.1.8. */

				/* invalid attribute description? remove */
				if ( ad_keystring( bv ) ) {
					/* NOTE: parsed in-place, don't modify;
					 * rather add "1.1", which must be ignored */
					BER_BVSTR( &op->ors_attrs[i].an_name, LDAP_NO_ATTRS );
				}

				/* otherwise leave in place... */
			}
		}
	}

	if( get_ctrls( op, rs, 1 ) != LDAP_SUCCESS ) {
		Debug( LDAP_DEBUG_ANY, "%s do_search: get_ctrls failed\n",
			op->o_log_prefix, 0, 0 );
		goto return_results;
	}

	Debug( LDAP_DEBUG_ARGS, "    attrs:", 0, 0, 0 );

	if ( siz != 0 ) {
		for ( i = 0; i<siz; i++ ) {
			Debug( LDAP_DEBUG_ARGS, " %s", op->ors_attrs[i].an_name.bv_val, 0, 0 );
		}
	}

	Debug( LDAP_DEBUG_ARGS, "\n", 0, 0, 0 );

	if ( StatslogTest( LDAP_DEBUG_STATS ) ) {
		char abuf[BUFSIZ/2], *ptr = abuf;
		unsigned len = 0, alen;

		sprintf(abuf, "scope=%d deref=%d", op->ors_scope, op->ors_deref);
		Statslog( LDAP_DEBUG_STATS,
		        "%s SRCH base=\"%s\" %s filter=\"%s\"\n",
		        op->o_log_prefix, op->o_req_dn.bv_val, abuf,
		        op->ors_filterstr.bv_val, 0 );

		for ( i = 0; i<siz; i++ ) {
			alen = op->ors_attrs[i].an_name.bv_len;
			if (alen >= sizeof(abuf)) {
				alen = sizeof(abuf)-1;
			}
			if (len && (len + 1 + alen >= sizeof(abuf))) {
				Statslog( LDAP_DEBUG_STATS, "%s SRCH attr=%s\n",
				    op->o_log_prefix, abuf, 0, 0, 0 );
				len = 0;
				ptr = abuf;
			}
			if (len) {
				*ptr++ = ' ';
				len++;
			}
			ptr = lutil_strncopy(ptr, op->ors_attrs[i].an_name.bv_val, alen);
			len += alen;
			*ptr = '\0';
		}
		if (len) {
			Statslog( LDAP_DEBUG_STATS, "%s SRCH attr=%s\n",
	    			op->o_log_prefix, abuf, 0, 0, 0 );
		}
	}

	op->o_bd = frontendDB;
	rs->sr_err = frontendDB->be_search( op, rs );

return_results:;
	if ( !BER_BVISNULL( &op->o_req_dn ) ) {
		slap_sl_free( op->o_req_dn.bv_val, op->o_tmpmemctx );
	}
	if ( !BER_BVISNULL( &op->o_req_ndn ) ) {
		slap_sl_free( op->o_req_ndn.bv_val, op->o_tmpmemctx );
	}
	if ( !BER_BVISNULL( &op->ors_filterstr ) ) {
		op->o_tmpfree( op->ors_filterstr.bv_val, op->o_tmpmemctx );
	}
	if ( op->ors_filter != NULL) {
		filter_free_x( op, op->ors_filter, 1 );
	}
	if ( op->ors_attrs != NULL ) {
		op->o_tmpfree( op->ors_attrs, op->o_tmpmemctx );
	}

	return rs->sr_err;
}
Beispiel #2
0
static int open_mixers(px_mixer *Px, UINT deviceIn, UINT deviceOut)
{
   PxInfo*info;
   MMRESULT res;

   if (deviceIn == UINT_MAX && deviceOut == UINT_MAX) {
      return FALSE;
   }

   if (!initialize(Px)) {
      return FALSE;
   }

   info = (PxInfo *) Px->info;
   info->hInputMixer = NULL;
   info->hOutputMixer = NULL;
   info->numInputs = 0;
   info->muxID = 0;
   info->speakerID = 0;
   info->waveID = 0;

   if (deviceIn != UINT_MAX) {
      res = mixerOpen((LPHMIXER) &info->hInputMixer,
                      deviceIn,
                      0,
                      0,
                      MIXER_OBJECTF_MIXER);
      if (res != MMSYSERR_NOERROR) {
         return cleanup(Px);
      }

      info->muxID = find_ctrl(info->hInputMixer,
                              MIXERLINE_COMPONENTTYPE_DST_WAVEIN,
                              MIXERCONTROL_CONTROLTYPE_MUX);
      if (info->muxID == -1) {
         info->muxID = find_ctrl(info->hInputMixer,
                                 MIXERLINE_COMPONENTTYPE_DST_WAVEIN,
                                 MIXERCONTROL_CONTROLTYPE_MIXER);
      }

      info->numInputs = get_ctrls(info->hInputMixer,
                                  MIXERLINE_COMPONENTTYPE_DST_WAVEIN,
                                  &info->src);

      if (info->numInputs == 0) {
         return cleanup(Px);
      }
   }

   if (deviceOut != UINT_MAX) {
      res = mixerOpen((LPHMIXER) &info->hOutputMixer,
                      deviceOut,
                      0,
                      0,
                      MIXER_OBJECTF_MIXER);
      if (res != MMSYSERR_NOERROR) {
         return cleanup(Px);
      }

      info->speakerID = find_ctrl(info->hOutputMixer,
                                  MIXERLINE_COMPONENTTYPE_DST_SPEAKERS,
                                  MIXERCONTROL_CONTROLTYPE_VOLUME);

      info->waveID = find_ctrl(info->hOutputMixer,
                               MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT,
                               MIXERCONTROL_CONTROLTYPE_VOLUME);

      info->numOutputs = get_ctrls(info->hOutputMixer,
                                   MIXERLINE_COMPONENTTYPE_DST_SPEAKERS,
                                   &info->dst);

      if (info->numOutputs == 0) {
         return cleanup(Px);
      }
   }

   return TRUE;
}
Beispiel #3
0
int
do_bind(
    Operation	*op,
    SlapReply	*rs )
{
	BerElement *ber = op->o_ber;
	ber_int_t version;
	ber_tag_t method;
	struct berval mech = BER_BVNULL;
	struct berval dn = BER_BVNULL;
	ber_tag_t tag;
	Backend *be = NULL;

	Debug( LDAP_DEBUG_TRACE, "%s do_bind\n",
		op->o_log_prefix );

	/*
	 * Force the connection to "anonymous" until bind succeeds.
	 */
	ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex );
	if ( op->o_conn->c_sasl_bind_in_progress ) {
		be = op->o_conn->c_authz_backend;
	}
	if ( !BER_BVISEMPTY( &op->o_conn->c_dn ) ) {
		/* log authorization identity demotion */
		Statslog( LDAP_DEBUG_STATS,
			"%s BIND anonymous mech=implicit ssf=0\n",
			op->o_log_prefix );
	}
	connection2anonymous( op->o_conn );
	if ( op->o_conn->c_sasl_bind_in_progress ) {
		op->o_conn->c_authz_backend = be;
	}
	ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );
	if ( !BER_BVISNULL( &op->o_dn ) ) {
		/* NOTE: temporarily wasting few bytes
		 * (until bind is completed), but saving
		 * a couple of ch_free() and ch_strdup("") */
		op->o_dn.bv_val[0] = '\0';
		op->o_dn.bv_len = 0;
	}
	if ( !BER_BVISNULL( &op->o_ndn ) ) {
		op->o_ndn.bv_val[0] = '\0';
		op->o_ndn.bv_len = 0;
	}

	/*
	 * Parse the bind request.  It looks like this:
	 *
	 *	BindRequest ::= SEQUENCE {
	 *		version		INTEGER,		 -- version
	 *		name		DistinguishedName,	 -- dn
	 *		authentication	CHOICE {
	 *			simple		[0] OCTET STRING -- passwd
	 *			krbv42ldap	[1] OCTET STRING -- OBSOLETE
	 *			krbv42dsa	[2] OCTET STRING -- OBSOLETE
	 *			SASL		[3] SaslCredentials
	 *		}
	 *	}
	 *
	 *	SaslCredentials ::= SEQUENCE {
	 *		mechanism	    LDAPString,
	 *		credentials	    OCTET STRING OPTIONAL
	 *	}
	 */

	tag = ber_scanf( ber, "{imt" /*}*/, &version, &dn, &method );

	if ( tag == LBER_ERROR ) {
		Debug( LDAP_DEBUG_ANY, "%s do_bind: ber_scanf failed\n",
			op->o_log_prefix );
		send_ldap_discon( op, rs, LDAP_PROTOCOL_ERROR, "decoding error" );
		rs->sr_err = SLAPD_DISCONNECT;
		goto cleanup;
	}

	op->o_protocol = version;
	op->orb_method = method;

	if( op->orb_method != LDAP_AUTH_SASL ) {
		tag = ber_scanf( ber, /*{*/ "m}", &op->orb_cred );

	} else {
		tag = ber_scanf( ber, "{m" /*}*/, &mech );

		if ( tag != LBER_ERROR ) {
			ber_len_t len;
			tag = ber_peek_tag( ber, &len );

			if ( tag == LDAP_TAG_LDAPCRED ) {
				tag = ber_scanf( ber, "m", &op->orb_cred );
			} else {
				tag = LDAP_TAG_LDAPCRED;
				BER_BVZERO( &op->orb_cred );
			}

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

	if ( tag == LBER_ERROR ) {
		Debug( LDAP_DEBUG_ANY, "%s do_bind: ber_scanf failed\n",
			op->o_log_prefix );
		send_ldap_discon( op, rs, LDAP_PROTOCOL_ERROR, "decoding error" );
		rs->sr_err = SLAPD_DISCONNECT;
		goto cleanup;
	}

	if( get_ctrls( op, rs, 1 ) != LDAP_SUCCESS ) {
		Debug( LDAP_DEBUG_ANY, "%s do_bind: get_ctrls failed\n",
			op->o_log_prefix );
		goto cleanup;
	}

	/* We use the tmpmemctx here because it speeds up normalization.
	 * However, we must dup with regular malloc when storing any
	 * resulting DNs in the op or conn structures.
	 */
	rs->sr_err = dnPrettyNormal( NULL, &dn, &op->o_req_dn, &op->o_req_ndn,
		op->o_tmpmemctx );
	if ( rs->sr_err != LDAP_SUCCESS ) {
		Debug( LDAP_DEBUG_ANY, "%s do_bind: invalid dn (%s)\n",
			op->o_log_prefix, dn.bv_val );
		send_ldap_error( op, rs, LDAP_INVALID_DN_SYNTAX, "invalid DN" );
		goto cleanup;
	}

	Statslog( LDAP_DEBUG_STATS, "%s BIND dn=\"%s\" method=%ld\n",
	    op->o_log_prefix, op->o_req_dn.bv_val,
		(unsigned long) op->orb_method );

	if( op->orb_method == LDAP_AUTH_SASL ) {
		Debug( LDAP_DEBUG_TRACE, "do_bind: dn (%s) SASL mech %s\n",
			op->o_req_dn.bv_val, mech.bv_val );

	} else {
		Debug( LDAP_DEBUG_TRACE,
			"do_bind: version=%ld dn=\"%s\" method=%ld\n",
			(unsigned long) version, op->o_req_dn.bv_val,
			(unsigned long) op->orb_method );
	}

	if ( version < LDAP_VERSION_MIN || version > LDAP_VERSION_MAX ) {
		Debug( LDAP_DEBUG_ANY, "%s do_bind: unknown version=%ld\n",
			op->o_log_prefix, (unsigned long) version );
		send_ldap_error( op, rs, LDAP_PROTOCOL_ERROR,
			"requested protocol version not supported" );
		goto cleanup;

	} else if (!( global_allows & SLAP_ALLOW_BIND_V2 ) &&
		version < LDAP_VERSION3 )
	{
		send_ldap_error( op, rs, LDAP_PROTOCOL_ERROR,
			"historical protocol version requested, use LDAPv3 instead" );
		goto cleanup;
	}

	/*
	 * we set connection version regardless of whether bind succeeds or not.
	 */
	ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex );
	op->o_conn->c_protocol = version;
	ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );

	op->orb_mech = mech;

	op->o_bd = frontendDB;
	rs->sr_err = frontendDB->be_bind( op, rs );

cleanup:
	if ( rs->sr_err == LDAP_SUCCESS ) {
		if ( op->orb_method != LDAP_AUTH_SASL ) {
			ber_dupbv( &op->o_conn->c_authmech, &mech );
		}
		op->o_conn->c_authtype = op->orb_method;
	}

	if( !BER_BVISNULL( &op->o_req_dn ) ) {
		slap_sl_free( op->o_req_dn.bv_val, op->o_tmpmemctx );
		BER_BVZERO( &op->o_req_dn );
	}
	if( !BER_BVISNULL( &op->o_req_ndn ) ) {
		slap_sl_free( op->o_req_ndn.bv_val, op->o_tmpmemctx );
		BER_BVZERO( &op->o_req_ndn );
	}

	return rs->sr_err;
}
Beispiel #4
0
int
do_extended(
    Operation	*op,
    SlapReply	*rs
)
{
	struct berval reqdata = {0, NULL};
	ber_len_t len;

	Debug( LDAP_DEBUG_TRACE, "%s do_extended\n",
		op->o_log_prefix, 0, 0 );

	if( op->o_protocol < LDAP_VERSION3 ) {
		Debug( LDAP_DEBUG_ANY, "%s do_extended: protocol version (%d) too low\n",
			op->o_log_prefix, op->o_protocol, 0 );
		send_ldap_discon( op, rs, LDAP_PROTOCOL_ERROR, "requires LDAPv3" );
		rs->sr_err = SLAPD_DISCONNECT;
		goto done;
	}

	if ( ber_scanf( op->o_ber, "{m" /*}*/, &op->ore_reqoid ) == LBER_ERROR ) {
		Debug( LDAP_DEBUG_ANY, "%s do_extended: ber_scanf failed\n",
			op->o_log_prefix, 0, 0 );
		send_ldap_discon( op, rs, LDAP_PROTOCOL_ERROR, "decoding error" );
		rs->sr_err = SLAPD_DISCONNECT;
		goto done;
	}

	if( ber_peek_tag( op->o_ber, &len ) == LDAP_TAG_EXOP_REQ_VALUE ) {
		if( ber_scanf( op->o_ber, "m", &reqdata ) == LBER_ERROR ) {
			Debug( LDAP_DEBUG_ANY, "%s do_extended: ber_scanf failed\n",
				op->o_log_prefix, 0, 0 );
			send_ldap_discon( op, rs, LDAP_PROTOCOL_ERROR, "decoding error" );
			rs->sr_err = SLAPD_DISCONNECT;
			goto done;
		}
	}

	if( get_ctrls( op, rs, 1 ) != LDAP_SUCCESS ) {
		Debug( LDAP_DEBUG_ANY, "%s do_extended: get_ctrls failed\n",
			op->o_log_prefix, 0, 0 );
		return rs->sr_err;
	} 

	Statslog( LDAP_DEBUG_STATS, "%s EXT oid=%s\n",
	    op->o_log_prefix, op->ore_reqoid.bv_val, 0, 0, 0 );

	/* check for controls inappropriate for all extended operations */
	if( get_manageDSAit( op ) == SLAP_CONTROL_CRITICAL ) {
		send_ldap_error( op, rs,
			LDAP_UNAVAILABLE_CRITICAL_EXTENSION,
			"manageDSAit control inappropriate" );
		goto done;
	}

	/* FIXME: temporary? */
	if ( reqdata.bv_val ) {
		op->ore_reqdata = &reqdata;
	}

	op->o_bd = frontendDB;
	rs->sr_err = frontendDB->be_extended( op, rs );

	/* clean up in case some overlay set them? */
	if ( !BER_BVISNULL( &op->o_req_ndn ) ) {
		if ( !BER_BVISNULL( &op->o_req_dn )
			&& op->o_req_ndn.bv_val != op->o_req_dn.bv_val )
		{
			op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx );
		}
		op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx );
		BER_BVZERO( &op->o_req_dn );
		BER_BVZERO( &op->o_req_ndn );
	}

done:
	return rs->sr_err;
}
Beispiel #5
0
int
do_delete(
    Operation	*op,
    SlapReply	*rs )
{
	struct berval dn = BER_BVNULL;

	Debug( LDAP_DEBUG_TRACE, "%s do_delete\n",
		op->o_log_prefix, 0, 0 );
	/*
	 * Parse the delete request.  It looks like this:
	 *
	 *	DelRequest := DistinguishedName
	 */

	if ( ber_scanf( op->o_ber, "m", &dn ) == LBER_ERROR ) {
		Debug( LDAP_DEBUG_ANY, "%s do_delete: ber_scanf failed\n",
			op->o_log_prefix, 0, 0 );
		send_ldap_discon( op, rs, LDAP_PROTOCOL_ERROR, "decoding error" );
		return SLAPD_DISCONNECT;
	}

	if( get_ctrls( op, rs, 1 ) != LDAP_SUCCESS ) {
		Debug( LDAP_DEBUG_ANY, "%s do_delete: get_ctrls failed\n",
			op->o_log_prefix, 0, 0 );
		goto cleanup;
	} 

	rs->sr_err = dnPrettyNormal( NULL, &dn, &op->o_req_dn, &op->o_req_ndn,
		op->o_tmpmemctx );
	if( rs->sr_err != LDAP_SUCCESS ) {
		Debug( LDAP_DEBUG_ANY, "%s do_delete: invalid dn (%s)\n",
			op->o_log_prefix, dn.bv_val, 0 );
		send_ldap_error( op, rs, LDAP_INVALID_DN_SYNTAX, "invalid DN" );
		goto cleanup;
	}

	Statslog( LDAP_DEBUG_STATS, "%s DEL dn=\"%s\"\n",
		op->o_log_prefix, op->o_req_dn.bv_val, 0, 0, 0 );

	if( op->o_req_ndn.bv_len == 0 ) {
		Debug( LDAP_DEBUG_ANY, "%s do_delete: root dse!\n",
			op->o_log_prefix, 0, 0 );
		/* protocolError would likely be a more appropriate error */
		send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
			"cannot delete the root DSE" );
		goto cleanup;

	} else if ( bvmatch( &op->o_req_ndn, &frontendDB->be_schemandn ) ) {
		Debug( LDAP_DEBUG_ANY, "%s do_delete: subschema subentry!\n",
			op->o_log_prefix, 0, 0 );
		/* protocolError would likely be a more appropriate error */
		send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
			"cannot delete the root DSE" );
		goto cleanup;
	}

	op->o_bd = frontendDB;
	rs->sr_err = frontendDB->be_delete( op, rs );

#ifdef LDAP_X_TXN
	if( rs->sr_err == LDAP_X_TXN_SPECIFY_OKAY ) {
		/* skip cleanup */
		return rs->sr_err;
	}
#endif

cleanup:;
	op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx );
	op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx );
	return rs->sr_err;
}
Beispiel #6
0
int
do_modrdn(
    Operation	*op,
    SlapReply	*rs
)
{
	struct berval	dn = BER_BVNULL;
	struct berval	newrdn = BER_BVNULL;
	struct berval	newSuperior = BER_BVNULL;
	ber_int_t	deloldrdn;

	struct berval pnewSuperior = BER_BVNULL;

	struct berval nnewSuperior = BER_BVNULL;

	ber_len_t	length;

	Debug( LDAP_DEBUG_TRACE, "%s do_modrdn\n",
			op->o_log_prefix, 0, 0 );
	/*
	 * Parse the modrdn request.  It looks like this:
	 *
	 *	ModifyRDNRequest := SEQUENCE {
	 *		entry	DistinguishedName,
	 *		newrdn	RelativeDistinguishedName
	 *		deleteoldrdn	BOOLEAN,
	 *		newSuperior	[0] LDAPDN OPTIONAL (v3 Only!)
	 *	}
	 */

	if ( ber_scanf( op->o_ber, "{mmb", &dn, &newrdn, &deloldrdn )
	    == LBER_ERROR )
	{
		Debug( LDAP_DEBUG_ANY, "%s do_modrdn: ber_scanf failed\n",
			op->o_log_prefix, 0, 0 );
		send_ldap_discon( op, rs, LDAP_PROTOCOL_ERROR, "decoding error" );
		return SLAPD_DISCONNECT;
	}

	/* Check for newSuperior parameter, if present scan it */

	if ( ber_peek_tag( op->o_ber, &length ) == LDAP_TAG_NEWSUPERIOR ) {
		if ( op->o_protocol < LDAP_VERSION3 ) {
			/* Connection record indicates v2 but field 
			 * newSuperior is present: report error.
			 */
			Debug( LDAP_DEBUG_ANY,
				"%s do_modrdn: newSuperior requires LDAPv3\n",
				op->o_log_prefix, 0, 0 );

			send_ldap_discon( op, rs,
				LDAP_PROTOCOL_ERROR, "newSuperior requires LDAPv3" );
			rs->sr_err = SLAPD_DISCONNECT;
			goto cleanup;
		}

		if ( ber_scanf( op->o_ber, "m", &newSuperior ) 
		     == LBER_ERROR ) {

			Debug( LDAP_DEBUG_ANY, "%s do_modrdn: ber_scanf(\"m\") failed\n",
				op->o_log_prefix, 0, 0 );

			send_ldap_discon( op, rs,
				LDAP_PROTOCOL_ERROR, "decoding error" );
			rs->sr_err = SLAPD_DISCONNECT;
			goto cleanup;
		}
		op->orr_newSup = &pnewSuperior;
		op->orr_nnewSup = &nnewSuperior;
	}

	Debug( LDAP_DEBUG_ARGS,
	    "do_modrdn: dn (%s) newrdn (%s) newsuperior (%s)\n",
		dn.bv_val, newrdn.bv_val,
		newSuperior.bv_len ? newSuperior.bv_val : "" );

	if ( ber_scanf( op->o_ber, /*{*/ "}") == LBER_ERROR ) {
		Debug( LDAP_DEBUG_ANY, "%s do_modrdn: ber_scanf failed\n",
			op->o_log_prefix, 0, 0 );
		send_ldap_discon( op, rs,
			LDAP_PROTOCOL_ERROR, "decoding error" );
		rs->sr_err = SLAPD_DISCONNECT;
		goto cleanup;
	}

	if( get_ctrls( op, rs, 1 ) != LDAP_SUCCESS ) {
		Debug( LDAP_DEBUG_ANY, "%s do_modrdn: get_ctrls failed\n",
			op->o_log_prefix, 0, 0 );
		/* get_ctrls has sent results.	Now clean up. */
		goto cleanup;
	} 

	rs->sr_err = dnPrettyNormal( NULL, &dn, &op->o_req_dn, &op->o_req_ndn, op->o_tmpmemctx );
	if( rs->sr_err != LDAP_SUCCESS ) {
		Debug( LDAP_DEBUG_ANY, "%s do_modrdn: invalid dn (%s)\n",
			op->o_log_prefix, dn.bv_val, 0 );
		send_ldap_error( op, rs, LDAP_INVALID_DN_SYNTAX, "invalid DN" );
		goto cleanup;
	}

	/* FIXME: should have/use rdnPretty / rdnNormalize routines */

	rs->sr_err = dnPrettyNormal( NULL, &newrdn, &op->orr_newrdn, &op->orr_nnewrdn, op->o_tmpmemctx );
	if( rs->sr_err != LDAP_SUCCESS ) {
		Debug( LDAP_DEBUG_ANY, "%s do_modrdn: invalid newrdn (%s)\n",
			op->o_log_prefix, newrdn.bv_val, 0 );
		send_ldap_error( op, rs, LDAP_INVALID_DN_SYNTAX, "invalid new RDN" );
		goto cleanup;
	}

	if( rdn_validate( &op->orr_newrdn ) != LDAP_SUCCESS ) {
		Debug( LDAP_DEBUG_ANY, "%s do_modrdn: invalid rdn (%s)\n",
			op->o_log_prefix, op->orr_newrdn.bv_val, 0 );
		send_ldap_error( op, rs, LDAP_INVALID_DN_SYNTAX, "invalid new RDN" );
		goto cleanup;
	}

	if( op->orr_newSup ) {
		rs->sr_err = dnPrettyNormal( NULL, &newSuperior, &pnewSuperior,
			&nnewSuperior, op->o_tmpmemctx );
		if( rs->sr_err != LDAP_SUCCESS ) {
			Debug( LDAP_DEBUG_ANY,
				"%s do_modrdn: invalid newSuperior (%s)\n",
				op->o_log_prefix, newSuperior.bv_val, 0 );
			send_ldap_error( op, rs, LDAP_INVALID_DN_SYNTAX, "invalid newSuperior" );
			goto cleanup;
		}
	}

	Statslog( LDAP_DEBUG_STATS, "%s MODRDN dn=\"%s\"\n",
	    op->o_log_prefix, op->o_req_dn.bv_val, 0, 0, 0 );

	op->orr_deleteoldrdn = deloldrdn;
	op->orr_modlist = NULL;

	/* prepare modlist of modifications from old/new RDN */
	rs->sr_err = slap_modrdn2mods( op, rs );
	if ( rs->sr_err != LDAP_SUCCESS ) {
		send_ldap_result( op, rs );
		goto cleanup;
	}

	op->o_bd = frontendDB;
	rs->sr_err = frontendDB->be_modrdn( op, rs );

#ifdef LDAP_X_TXN
	if( rs->sr_err == LDAP_X_TXN_SPECIFY_OKAY ) {
		/* skip cleanup */
	}
#endif

cleanup:
	op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx );
	op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx );

	op->o_tmpfree( op->orr_newrdn.bv_val, op->o_tmpmemctx );	
	op->o_tmpfree( op->orr_nnewrdn.bv_val, op->o_tmpmemctx );	

	if ( op->orr_modlist != NULL )
		slap_mods_free( op->orr_modlist, 1 );

	if ( !BER_BVISNULL( &pnewSuperior ) ) {
		op->o_tmpfree( pnewSuperior.bv_val, op->o_tmpmemctx );
	}
	if ( !BER_BVISNULL( &nnewSuperior ) ) {
		op->o_tmpfree( nnewSuperior.bv_val, op->o_tmpmemctx );
	}

	return rs->sr_err;
}
Beispiel #7
0
int
do_modify(
    Operation	*op,
    SlapReply	*rs )
{
	struct berval dn = BER_BVNULL;
	char		textbuf[ SLAP_TEXT_BUFLEN ];
	size_t		textlen = sizeof( textbuf );
#ifdef LDAP_DEBUG
	Modifications	*tmp;
#endif

	Debug( LDAP_DEBUG_TRACE, "%s do_modify\n",
		op->o_log_prefix, 0, 0 );
	/*
	 * 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
	 *			}
	 *		}
	 *	}
	 */

	if ( ber_scanf( op->o_ber, "{m" /*}*/, &dn ) == LBER_ERROR ) {
		Debug( LDAP_DEBUG_ANY, "%s do_modify: ber_scanf failed\n",
			op->o_log_prefix, 0, 0 );
		send_ldap_discon( op, rs, LDAP_PROTOCOL_ERROR, "decoding error" );
		return SLAPD_DISCONNECT;
	}

	Debug( LDAP_DEBUG_ARGS, "%s do_modify: dn (%s)\n",
		op->o_log_prefix, dn.bv_val, 0 );

	rs->sr_err = slap_parse_modlist( op, rs, op->o_ber, &op->oq_modify );
	if ( rs->sr_err != LDAP_SUCCESS ) {
		Debug( LDAP_DEBUG_ANY, "%s do_modify: slap_parse_modlist failed err=%d msg=%s\n",
			op->o_log_prefix, rs->sr_err, rs->sr_text );
		send_ldap_result( op, rs );
		goto cleanup;
	}

	if( get_ctrls( op, rs, 1 ) != LDAP_SUCCESS ) {
		Debug( LDAP_DEBUG_ANY, "%s do_modify: get_ctrls failed\n",
			op->o_log_prefix, 0, 0 );
		/* get_ctrls has sent results.	Now clean up. */
		goto cleanup;
	}

	rs->sr_err = dnPrettyNormal( NULL, &dn, &op->o_req_dn, &op->o_req_ndn,
		op->o_tmpmemctx );
	if( rs->sr_err != LDAP_SUCCESS ) {
		Debug( LDAP_DEBUG_ANY, "%s do_modify: invalid dn (%s)\n",
			op->o_log_prefix, dn.bv_val, 0 );
		send_ldap_error( op, rs, LDAP_INVALID_DN_SYNTAX, "invalid DN" );
		goto cleanup;
	}

	op->orm_no_opattrs = 0;

#ifdef LDAP_DEBUG
	Debug( LDAP_DEBUG_ARGS, "%s modifications:\n",
			op->o_log_prefix, 0, 0 );

	for ( tmp = op->orm_modlist; tmp != NULL; tmp = tmp->sml_next ) {
		Debug( LDAP_DEBUG_ARGS, "\t%s: %s\n",
			tmp->sml_op == LDAP_MOD_ADD ? "add" :
				(tmp->sml_op == LDAP_MOD_INCREMENT ? "increment" :
				(tmp->sml_op == LDAP_MOD_DELETE ? "delete" :
					"replace")), tmp->sml_type.bv_val, 0 );

		if ( tmp->sml_values == NULL ) {
			Debug( LDAP_DEBUG_ARGS, "%s\n",
			   "\t\tno values", NULL, NULL );
		} else if ( BER_BVISNULL( &tmp->sml_values[ 0 ] ) ) {
			Debug( LDAP_DEBUG_ARGS, "%s\n",
			   "\t\tzero values", NULL, NULL );
		} else if ( BER_BVISNULL( &tmp->sml_values[ 1 ] ) ) {
			Debug( LDAP_DEBUG_ARGS, "%s, length %ld\n",
			   "\t\tone value", (long) tmp->sml_values[0].bv_len, NULL );
		} else {
			Debug( LDAP_DEBUG_ARGS, "%s\n",
			   "\t\tmultiple values", NULL, NULL );
		}
	}

	if ( StatslogTest( LDAP_DEBUG_STATS ) ) {
		char abuf[BUFSIZ/2], *ptr = abuf;
		int len = 0;

		Statslog( LDAP_DEBUG_STATS, "%s MOD dn=\"%s\"\n",
			op->o_log_prefix, op->o_req_dn.bv_val, 0, 0, 0 );

		for ( tmp = op->orm_modlist; tmp != NULL; tmp = tmp->sml_next ) {
			if (len + 1 + tmp->sml_type.bv_len > sizeof(abuf)) {
				Statslog( LDAP_DEBUG_STATS, "%s MOD attr=%s\n",
				    op->o_log_prefix, abuf, 0, 0, 0 );

				len = 0;
				ptr = abuf;

				if( 1 + tmp->sml_type.bv_len > sizeof(abuf)) {
					Statslog( LDAP_DEBUG_STATS, "%s MOD attr=%s\n",
						op->o_log_prefix, tmp->sml_type.bv_val, 0, 0, 0 );
					continue;
				}
			}
			if (len) {
				*ptr++ = ' ';
				len++;
			}
			ptr = lutil_strcopy(ptr, tmp->sml_type.bv_val);
			len += tmp->sml_type.bv_len;
		}
		if (len) {
			Statslog( LDAP_DEBUG_STATS, "%s MOD attr=%s\n",
	    			op->o_log_prefix, abuf, 0, 0, 0 );
		}
	}
#endif	/* LDAP_DEBUG */

	rs->sr_err = slap_mods_check( op, op->orm_modlist,
		&rs->sr_text, textbuf, textlen, NULL );

	if ( rs->sr_err != LDAP_SUCCESS ) {
		send_ldap_result( op, rs );
		goto cleanup;
	}

	op->o_bd = frontendDB;
	rs->sr_err = frontendDB->be_modify( op, rs );

#ifdef LDAP_X_TXN
	if( rs->sr_err == LDAP_X_TXN_SPECIFY_OKAY ) {
		/* skip cleanup */
		return rs->sr_err;
	}
#endif

cleanup:
	op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx );
	op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx );
	if ( op->orm_modlist != NULL ) slap_mods_free( op->orm_modlist, 1 );

	return rs->sr_err;
}
Beispiel #8
0
int
do_compare(
    Operation	*op,
    SlapReply	*rs )
{
	struct berval dn = BER_BVNULL;
	struct berval desc = BER_BVNULL;
	struct berval value = BER_BVNULL;
	AttributeAssertion ava = ATTRIBUTEASSERTION_INIT;

	Debug( LDAP_DEBUG_TRACE, "%s do_compare\n",
		op->o_log_prefix, 0, 0 );
	/*
	 * Parse the compare request.  It looks like this:
	 *
	 *	CompareRequest := [APPLICATION 14] SEQUENCE {
	 *		entry	DistinguishedName,
	 *		ava	SEQUENCE {
	 *			type	AttributeType,
	 *			value	AttributeValue
	 *		}
	 *	}
	 */

	if ( ber_scanf( op->o_ber, "{m" /*}*/, &dn ) == LBER_ERROR ) {
		Debug( LDAP_DEBUG_ANY, "%s do_compare: ber_scanf failed\n",
			op->o_log_prefix, 0, 0 );
		send_ldap_discon( op, rs, LDAP_PROTOCOL_ERROR, "decoding error" );
		return SLAPD_DISCONNECT;
	}

	if ( ber_scanf( op->o_ber, "{mm}", &desc, &value ) == LBER_ERROR ) {
		Debug( LDAP_DEBUG_ANY, "%s do_compare: get ava failed\n",
			op->o_log_prefix, 0, 0 );
		send_ldap_discon( op, rs, LDAP_PROTOCOL_ERROR, "decoding error" );
		return SLAPD_DISCONNECT;
	}

	if ( ber_scanf( op->o_ber, /*{*/ "}" ) == LBER_ERROR ) {
		Debug( LDAP_DEBUG_ANY, "%s do_compare: ber_scanf failed\n",
			op->o_log_prefix, 0, 0 );
		send_ldap_discon( op, rs, LDAP_PROTOCOL_ERROR, "decoding error" );
		return SLAPD_DISCONNECT;
	}

	if( get_ctrls( op, rs, 1 ) != LDAP_SUCCESS ) {
		Debug( LDAP_DEBUG_ANY, "%s do_compare: get_ctrls failed\n",
			op->o_log_prefix, 0, 0 );
		goto cleanup;
	} 

	rs->sr_err = dnPrettyNormal( NULL, &dn, &op->o_req_dn, &op->o_req_ndn,
		op->o_tmpmemctx );
	if( rs->sr_err != LDAP_SUCCESS ) {
		Debug( LDAP_DEBUG_ANY, "%s do_compare: invalid dn (%s)\n",
			op->o_log_prefix, dn.bv_val, 0 );
		send_ldap_error( op, rs, LDAP_INVALID_DN_SYNTAX, "invalid DN" );
		goto cleanup;
	}

	Statslog( LDAP_DEBUG_STATS,
		"%s CMP dn=\"%s\" attr=\"%s\"\n",
		op->o_log_prefix, op->o_req_dn.bv_val,
		desc.bv_val, 0, 0 );

	rs->sr_err = slap_bv2ad( &desc, &ava.aa_desc, &rs->sr_text );
	if( rs->sr_err != LDAP_SUCCESS ) {
		rs->sr_err = slap_bv2undef_ad( &desc, &ava.aa_desc,
				&rs->sr_text,
				SLAP_AD_PROXIED|SLAP_AD_NOINSERT );
		if( rs->sr_err != LDAP_SUCCESS ) {
			send_ldap_result( op, rs );
			goto cleanup;
		}
	}

	rs->sr_err = asserted_value_validate_normalize( ava.aa_desc,
		ava.aa_desc->ad_type->sat_equality,
		SLAP_MR_EQUALITY|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX,
		&value, &ava.aa_value, &rs->sr_text, op->o_tmpmemctx );
	if( rs->sr_err != LDAP_SUCCESS ) {
		send_ldap_result( op, rs );
		goto cleanup;
	}

	op->orc_ava = &ava;

	Debug( LDAP_DEBUG_ARGS,
		"do_compare: dn (%s) attr (%s) value (%s)\n",
		op->o_req_dn.bv_val,
		ava.aa_desc->ad_cname.bv_val, ava.aa_value.bv_val );

	op->o_bd = frontendDB;
	rs->sr_err = frontendDB->be_compare( op, rs );

cleanup:;
	op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx );
	op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx );
	if ( !BER_BVISNULL( &ava.aa_value ) ) {
		op->o_tmpfree( ava.aa_value.bv_val, op->o_tmpmemctx );
	}

	return rs->sr_err;
}
Beispiel #9
0
int open_mixers(px_mixer *Px, UINT deviceIn, UINT deviceOut)
{
    PxInfo*info;
    MMRESULT res;
    OSVERSIONINFO verInfo;

    memset(&verInfo, 0, sizeof(verInfo));
    verInfo.dwOSVersionInfoSize = sizeof(verInfo);
    GetVersionEx(&verInfo);
    if (verInfo.dwMajorVersion >= 6) {
        return open_ep_mixers(Px, deviceIn, deviceOut);
    }

    res = mixerGetID((HMIXEROBJ) (deviceIn == WAVE_MAPPER ? 0 : deviceIn),
                     &deviceIn,
                     MIXER_OBJECTF_WAVEIN);
    if (res != MMSYSERR_NOERROR) {
        return FALSE;
    }

    res = mixerGetID((HMIXEROBJ) (deviceOut == WAVE_MAPPER ? 0 : deviceOut),
                     &deviceOut,
                     MIXER_OBJECTF_WAVEIN);
    if (res != MMSYSERR_NOERROR) {
        return FALSE;
    }

    if (!initialize(Px)) {
        return FALSE;
    }

    info = (PxInfo *) Px->info;
    info->hInputMixer = NULL;
    info->hOutputMixer = NULL;
    info->numInputs = 0;
    info->muxID = 0;
    info->speakerID = 0;
    info->waveID = 0;

    if (deviceIn != UINT_MAX) {
        res = mixerOpen((LPHMIXER) &info->hInputMixer,
                        deviceIn,
                        0,
                        0,
                        MIXER_OBJECTF_MIXER);
        if (res != MMSYSERR_NOERROR) {
            return cleanup(Px);
        }

        info->muxID = find_ctrl(info->hInputMixer,
                                MIXERLINE_COMPONENTTYPE_DST_WAVEIN,
                                MIXERCONTROL_CONTROLTYPE_MUX);
        if (info->muxID == -1) {
            info->muxID = find_ctrl(info->hInputMixer,
                                    MIXERLINE_COMPONENTTYPE_DST_WAVEIN,
                                    MIXERCONTROL_CONTROLTYPE_MIXER);
        }

        info->numInputs = get_ctrls(info->hInputMixer,
                                    MIXERLINE_COMPONENTTYPE_DST_WAVEIN,
                                    &info->src);

        if (info->numInputs == 0) {
            return cleanup(Px);
        }
    }

    if (deviceOut != UINT_MAX) {
        res = mixerOpen((LPHMIXER) &info->hOutputMixer,
                        deviceOut,
                        0,
                        0,
                        MIXER_OBJECTF_MIXER);
        if (res != MMSYSERR_NOERROR) {
            return cleanup(Px);
        }

        info->speakerID = find_ctrl(info->hOutputMixer,
                                    MIXERLINE_COMPONENTTYPE_DST_SPEAKERS,
                                    MIXERCONTROL_CONTROLTYPE_VOLUME);

        info->waveID = find_ctrl(info->hOutputMixer,
                                 MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT,
                                 MIXERCONTROL_CONTROLTYPE_VOLUME);

        info->numOutputs = get_ctrls(info->hOutputMixer,
                                     MIXERLINE_COMPONENTTYPE_DST_SPEAKERS,
                                     &info->dst);

        if (info->numOutputs == 0) {
            return cleanup(Px);
        }
    }

    return TRUE;
}
Beispiel #10
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;
}