Exemple #1
0
struct berval * slap_passwd_return(
	struct berval		*cred )
{
	int rc;
	struct berval *bv = NULL;
	BerElementBuffer berbuf;
	/* opaque structure, size unknown but smaller than berbuf */
	BerElement *ber = (BerElement *)&berbuf;

	assert( cred != NULL );

	Debug( LDAP_DEBUG_TRACE, "slap_passwd_return: %ld\n",
		(long) cred->bv_len, 0, 0 );
	
	ber_init_w_nullc( ber, LBER_USE_DER );

	rc = ber_printf( ber, "{tON}",
		LDAP_TAG_EXOP_MODIFY_PASSWD_GEN, cred );

	if( rc >= 0 ) {
		(void) ber_flatten( ber, &bv );
	}

	ber_free_buf( ber );

	return bv;
}
Exemple #2
0
struct berval * slap_passwd_return(
    struct berval		*cred )
{
    int rc;
    struct berval *bv = NULL;
    char berbuf[LBER_ELEMENT_SIZEOF];
    /* opaque structure, size unknown but smaller than berbuf */
    BerElement *ber = (BerElement *)berbuf;

    assert( cred != NULL );

#ifdef NEW_LOGGING
    LDAP_LOG( OPERATION, ENTRY,
              "slap_passwd_return: %ld\n",(long)cred->bv_len, 0, 0 );
#else
    Debug( LDAP_DEBUG_TRACE, "slap_passwd_return: %ld\n",
           (long) cred->bv_len, 0, 0 );
#endif

    ber_init_w_nullc( ber, LBER_USE_DER );

    rc = ber_printf( ber, "{tON}",
                     LDAP_TAG_EXOP_MODIFY_PASSWD_GEN, cred );

    if( rc >= 0 ) {
        (void) ber_flatten( ber, &bv );
    }

    ber_free_buf( ber );

    return bv;
}
Exemple #3
0
static int
send_ldap_response(
	Operation *op,
	SlapReply *rs )
{
	BerElementBuffer berbuf;
	BerElement	*ber = (BerElement *) &berbuf;
	int		rc = LDAP_SUCCESS;
	long	bytes;

	/* op was actually aborted, bypass everything if client didn't Cancel */
	if (( rs->sr_err == SLAPD_ABANDON ) && !op->o_cancel ) {
		rc = SLAPD_ABANDON;
		goto clean2;
	}

	if ( op->o_callback ) {
		rc = slap_response_play( op, rs );
		if ( rc != SLAP_CB_CONTINUE ) {
			goto clean2;
		}
	}

	/* op completed, connection aborted, bypass sending response */
	if ( op->o_abandon && !op->o_cancel ) {
		rc = SLAPD_ABANDON;
		goto clean2;
	}

#ifdef LDAP_CONNECTIONLESS
	if (op->o_conn && op->o_conn->c_is_udp)
		ber = op->o_res_ber;
	else
#endif
	{
		ber_init_w_nullc( ber, LBER_USE_DER );
		ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx );
	}

	rc = rs->sr_err;
	if ( rc == SLAPD_ABANDON && op->o_cancel )
		rc = LDAP_CANCELLED;

	Debug( LDAP_DEBUG_TRACE,
		"send_ldap_response: msgid=%d tag=%lu err=%d\n",
		rs->sr_msgid, rs->sr_tag, rc );

	if( rs->sr_ref ) {
		Debug( LDAP_DEBUG_ARGS, "send_ldap_response: ref=\"%s\"\n",
			rs->sr_ref[0].bv_val ? rs->sr_ref[0].bv_val : "NULL" );
	}

#ifdef LDAP_CONNECTIONLESS
	if (op->o_conn && op->o_conn->c_is_udp &&
		op->o_protocol == LDAP_VERSION2 )
	{
		rc = ber_printf( ber, "t{ess" /*"}"*/,
			rs->sr_tag, rc,
		rs->sr_matched == NULL ? "" : rs->sr_matched,
		rs->sr_text == NULL ? "" : rs->sr_text );
	} else
#endif
	if ( rs->sr_type == REP_INTERMEDIATE ) {
	    rc = ber_printf( ber, "{it{" /*"}}"*/,
			rs->sr_msgid, rs->sr_tag );

	} else {
	    rc = ber_printf( ber, "{it{ess" /*"}}"*/,
		rs->sr_msgid, rs->sr_tag, rc,
		rs->sr_matched == NULL ? "" : rs->sr_matched,
		rs->sr_text == NULL ? "" : rs->sr_text );
	}

	if( rc != -1 ) {
		if ( rs->sr_ref != NULL ) {
			assert( rs->sr_err == LDAP_REFERRAL );
			rc = ber_printf( ber, "t{W}",
				LDAP_TAG_REFERRAL, rs->sr_ref );
		} else {
			assert( rs->sr_err != LDAP_REFERRAL );
		}
	}

	if( rc != -1 && rs->sr_type == REP_SASL && rs->sr_sasldata != NULL ) {
		rc = ber_printf( ber, "tO",
			LDAP_TAG_SASL_RES_CREDS, rs->sr_sasldata );
	}

	if( rc != -1 &&
		( rs->sr_type == REP_EXTENDED || rs->sr_type == REP_INTERMEDIATE ))
	{
		if ( rs->sr_rspoid != NULL ) {
			rc = ber_printf( ber, "ts",
				rs->sr_type == REP_EXTENDED
					? LDAP_TAG_EXOP_RES_OID : LDAP_TAG_IM_RES_OID,
				rs->sr_rspoid );
		}
		if( rc != -1 && rs->sr_rspdata != NULL ) {
			rc = ber_printf( ber, "tO",
				rs->sr_type == REP_EXTENDED
					? LDAP_TAG_EXOP_RES_VALUE : LDAP_TAG_IM_RES_VALUE,
				rs->sr_rspdata );
		}
	}

	if( rc != -1 ) {
		rc = ber_printf( ber, /*"{"*/ "N}" );
	}

	if( rc != -1 ) {
		rc = send_ldap_controls( op, ber, rs->sr_ctrls );
	}

	if( rc != -1 ) {
		rc = ber_printf( ber, /*"{"*/ "N}" );
	}

#ifdef LDAP_CONNECTIONLESS
	if( op->o_conn && op->o_conn->c_is_udp && op->o_protocol == LDAP_VERSION2
		&& rc != -1 )
	{
		rc = ber_printf( ber, /*"{"*/ "N}" );
	}
#endif

	if ( rc == -1 ) {
		Debug( LDAP_DEBUG_ANY, "ber_printf failed\n" );

#ifdef LDAP_CONNECTIONLESS
		if (!op->o_conn || op->o_conn->c_is_udp == 0)
#endif
		{
			ber_free_buf( ber );
		}
		goto cleanup;
	}

	/* send BER */
	bytes = send_ldap_ber( op, ber );
#ifdef LDAP_CONNECTIONLESS
	if (!op->o_conn || op->o_conn->c_is_udp == 0)
#endif
	{
		ber_free_buf( ber );
	}

	if ( bytes < 0 ) {
		Debug( LDAP_DEBUG_ANY,
			"send_ldap_response: ber write failed\n" );

		goto cleanup;
	}

	ldap_pvt_thread_mutex_lock( &op->o_counters->sc_mutex );
	ldap_pvt_mp_add_ulong( op->o_counters->sc_pdu, 1 );
	ldap_pvt_mp_add_ulong( op->o_counters->sc_bytes, (unsigned long)bytes );
	ldap_pvt_thread_mutex_unlock( &op->o_counters->sc_mutex );

cleanup:;
	/* Tell caller that we did this for real, as opposed to being
	 * overridden by a callback
	 */
	rc = SLAP_CB_CONTINUE;

clean2:;
	if ( op->o_callback ) {
		(void)slap_cleanup_play( op, rs );
	}

	if ( rs->sr_flags & REP_MATCHED_MUSTBEFREED ) {
		rs->sr_flags ^= REP_MATCHED_MUSTBEFREED; /* paranoia */
		if ( rs->sr_matched ) {
			free( (char *)rs->sr_matched );
			rs->sr_matched = NULL;
		}
	}

	if ( rs->sr_flags & REP_REF_MUSTBEFREED ) {
		rs->sr_flags ^= REP_REF_MUSTBEFREED; /* paranoia */
		if ( rs->sr_ref ) {
			ber_bvarray_free( rs->sr_ref );
			rs->sr_ref = NULL;
		}
	}

	if ( rs->sr_flags & REP_CTRLS_MUSTBEFREED ) {
		rs->sr_flags ^= REP_CTRLS_MUSTBEFREED; /* paranoia */
		if ( rs->sr_ctrls ) {
			slap_free_ctrls( op, rs->sr_ctrls );
			rs->sr_ctrls = NULL;
		}
	}

	return rc;
}
Exemple #4
0
int
slap_send_search_reference( Operation *op, SlapReply *rs )
{
	BerElementBuffer berbuf;
	BerElement	*ber = (BerElement *) &berbuf;
	int rc = 0;
	int bytes;
	char *edn = rs->sr_entry ? rs->sr_entry->e_name.bv_val : "(null)";

	AttributeDescription *ad_ref = slap_schema.si_ad_ref;
	AttributeDescription *ad_entry = slap_schema.si_ad_entry;

	rs->sr_type = REP_SEARCHREF;
	if ( op->o_callback ) {
		rc = slap_response_play( op, rs );
		if ( rc != SLAP_CB_CONTINUE ) {
			goto rel;
		}
	}

	Debug( LDAP_DEBUG_TRACE,
		"=> send_search_reference: dn=\"%s\"\n",
		edn );

	if (  rs->sr_entry && ! access_allowed( op, rs->sr_entry,
		ad_entry, NULL, ACL_READ, NULL ) )
	{
		Debug( LDAP_DEBUG_ACL,
			"send_search_reference: access to entry not allowed\n" );
		rc = 1;
		goto rel;
	}

	if ( rs->sr_entry && ! access_allowed( op, rs->sr_entry,
		ad_ref, NULL, ACL_READ, NULL ) )
	{
		Debug( LDAP_DEBUG_ACL,
			"send_search_reference: access "
			"to reference not allowed\n" );
		rc = 1;
		goto rel;
	}

	if( op->o_domain_scope ) {
		Debug( LDAP_DEBUG_ANY,
			"send_search_reference: domainScope control in (%s)\n",
			edn );
		rc = 0;
		goto rel;
	}

	if( rs->sr_ref == NULL ) {
		Debug( LDAP_DEBUG_ANY,
			"send_search_reference: null ref in (%s)\n",
			edn );
		rc = 1;
		goto rel;
	}

	if( op->o_protocol < LDAP_VERSION3 ) {
		rc = 0;
		/* save the references for the result */
		if( rs->sr_ref[0].bv_val != NULL ) {
			if( value_add( &rs->sr_v2ref, rs->sr_ref ) )
				rc = LDAP_OTHER;
		}
		goto rel;
	}

#ifdef LDAP_CONNECTIONLESS
	if( op->o_conn && op->o_conn->c_is_udp ) {
		ber = op->o_res_ber;
	} else
#endif
	{
		ber_init_w_nullc( ber, LBER_USE_DER );
		ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx );
	}

	rc = ber_printf( ber, "{it{W}" /*"}"*/ , op->o_msgid,
		LDAP_RES_SEARCH_REFERENCE, rs->sr_ref );

	if( rc != -1 ) {
		rc = send_ldap_controls( op, ber, rs->sr_ctrls );
	}

	if( rc != -1 ) {
		rc = ber_printf( ber, /*"{"*/ "N}" );
	}

	if ( rc == -1 ) {
		Debug( LDAP_DEBUG_ANY,
			"send_search_reference: ber_printf failed\n" );

#ifdef LDAP_CONNECTIONLESS
		if (!op->o_conn || op->o_conn->c_is_udp == 0)
#endif
		ber_free_buf( ber );
		set_ldap_error( rs, LDAP_OTHER, "encode DN error" );
		goto rel;
	}

	rc = 0;
	rs_flush_entry( op, rs, NULL );

#ifdef LDAP_CONNECTIONLESS
	if (!op->o_conn || op->o_conn->c_is_udp == 0) {
#endif
	bytes = send_ldap_ber( op, ber );
	ber_free_buf( ber );

	if ( bytes < 0 ) {
		rc = LDAP_UNAVAILABLE;
	} else {
		ldap_pvt_thread_mutex_lock( &op->o_counters->sc_mutex );
		ldap_pvt_mp_add_ulong( op->o_counters->sc_bytes, (unsigned long)bytes );
		ldap_pvt_mp_add_ulong( op->o_counters->sc_refs, 1 );
		ldap_pvt_mp_add_ulong( op->o_counters->sc_pdu, 1 );
		ldap_pvt_thread_mutex_unlock( &op->o_counters->sc_mutex );
	}
#ifdef LDAP_CONNECTIONLESS
	}
#endif
	if ( rs->sr_ref != NULL ) {
		int	r;

		for ( r = 0; !BER_BVISNULL( &rs->sr_ref[ r ] ); r++ ) {
			Statslog( LDAP_DEBUG_STATS2, "%s REF #%d \"%s\"\n",
				op->o_log_prefix, r, rs->sr_ref[0].bv_val );
		}

	} else {
		Statslog( LDAP_DEBUG_STATS2, "%s REF \"(null)\"\n",
			op->o_log_prefix );
	}

	Debug( LDAP_DEBUG_TRACE, "<= send_search_reference\n" );

	if ( 0 ) {
rel:
	    rs_flush_entry( op, rs, NULL );
	}

	if ( op->o_callback ) {
		(void)slap_cleanup_play( op, rs );
	}

	if ( rs->sr_flags & REP_CTRLS_MUSTBEFREED ) {
		rs->sr_flags ^= REP_CTRLS_MUSTBEFREED; /* paranoia */
		if ( rs->sr_ctrls ) {
			slap_free_ctrls( op, rs->sr_ctrls );
			rs->sr_ctrls = NULL;
		}
	}

	return rc;
}
Exemple #5
0
int pam_pwmod(nssov_info *ni,TFILE *fp,Operation *op)
{
	struct berval npw;
	int32_t tmpint32;
	char dnc[1024];
	char uidc[32];
	char opwc[256];
	char npwc[256];
	char svcc[256];
	struct paminfo pi;
	int rc;

	READ_STRING(fp,uidc);
	pi.uid.bv_val = uidc;
	pi.uid.bv_len = tmpint32;
	READ_STRING(fp,dnc);
	pi.dn.bv_val = dnc;
	pi.dn.bv_len = tmpint32;
	READ_STRING(fp,svcc);
	pi.svc.bv_val = svcc;
	pi.svc.bv_len = tmpint32;
	READ_STRING(fp,opwc);
	pi.pwd.bv_val = opwc;
	pi.pwd.bv_len = tmpint32;
	READ_STRING(fp,npwc);
	npw.bv_val = npwc;
	npw.bv_len = tmpint32;

	Debug(LDAP_DEBUG_TRACE,"nssov_pam_pwmod(%s), %s\n",
		pi.dn.bv_val,pi.uid.bv_val,0);

	BER_BVZERO(&pi.msg);

	/* This is a prelim check */
	if (BER_BVISEMPTY(&pi.dn)) {
		rc = pam_do_bind(ni,fp,op,&pi);
		if (rc == NSLCD_PAM_IGNORE)
			rc = NSLCD_PAM_SUCCESS;
	} else {
		BerElementBuffer berbuf;
		BerElement *ber = (BerElement *)&berbuf;
		struct berval bv;
		SlapReply rs = {REP_RESULT};
		slap_callback cb = {0};

		ber_init_w_nullc(ber, LBER_USE_DER);
		ber_printf(ber, "{");
		if (!BER_BVISEMPTY(&pi.pwd))
			ber_printf(ber, "tO", LDAP_TAG_EXOP_MODIFY_PASSWD_OLD,
				&pi.pwd);
		if (!BER_BVISEMPTY(&npw))
			ber_printf(ber, "tO", LDAP_TAG_EXOP_MODIFY_PASSWD_NEW,
				&npw);
		ber_printf(ber, "N}");
		ber_flatten2(ber, &bv, 0);
		op->o_tag = LDAP_REQ_EXTENDED;
		op->ore_reqoid = slap_EXOP_MODIFY_PASSWD;
		op->ore_reqdata = &bv;
		op->o_dn = pi.dn;
		op->o_ndn = pi.dn;
		op->o_callback = &cb;
		op->o_conn->c_authz_backend = op->o_bd;
		cb.sc_response = slap_null_cb;
		op->o_bd = frontendDB;
		rc = op->o_bd->be_extended(op, &rs);
		if (rs.sr_text)
			ber_str2bv(rs.sr_text, 0, 0, &pi.msg);
		if (rc == LDAP_SUCCESS)
			rc = NSLCD_PAM_SUCCESS;
		else
			rc = NSLCD_PAM_PERM_DENIED;
	}
	WRITE_INT32(fp,NSLCD_VERSION);
	WRITE_INT32(fp,NSLCD_ACTION_PAM_PWMOD);
	WRITE_INT32(fp,NSLCD_RESULT_BEGIN);
	WRITE_BERVAL(fp,&pi.uid);
	WRITE_BERVAL(fp,&pi.dn);
	WRITE_INT32(fp,rc);
	WRITE_BERVAL(fp,&pi.msg);
	return 0;
}
Exemple #6
0
static int
dds_op_extended( Operation *op, SlapReply *rs )
{
	slap_overinst	*on = (slap_overinst *)op->o_bd->bd_info;
	dds_info_t	*di = on->on_bi.bi_private;

	if ( DDS_OFF( di ) ) {
		return SLAP_CB_CONTINUE;
	}

	if ( bvmatch( &op->ore_reqoid, &slap_EXOP_REFRESH ) ) {
		Entry		*e = NULL;
		time_t		ttl;
		BackendDB	db = *op->o_bd;
		SlapReply	rs2 = { REP_RESULT };
		Operation	op2 = *op;
		slap_callback	sc = { 0 };
		Modifications	ttlmod = { { 0 } };
		struct berval	ttlvalues[ 2 ];
		char		ttlbuf[STRLENOF("31557600") + 1];

		rs->sr_err = slap_parse_refresh( op->ore_reqdata, NULL, &ttl,
			&rs->sr_text, NULL );
		assert( rs->sr_err == LDAP_SUCCESS );

		if ( ttl <= 0 || ttl > DDS_RF2589_MAX_TTL ) {
			rs->sr_err = LDAP_PROTOCOL_ERROR;
			rs->sr_text = "invalid time-to-live for dynamicObject";
			return rs->sr_err;
		}

		if ( ttl > di->di_max_ttl ) {
			/* FIXME: I don't understand if this has to be an error,
			 * or an indication that the requested Ttl has been
			 * shortened to di->di_max_ttl >= 1 day */
			rs->sr_err = LDAP_SIZELIMIT_EXCEEDED;
			rs->sr_text = "time-to-live for dynamicObject exceeds limit";
			return rs->sr_err;
		}

		if ( di->di_min_ttl && ttl < di->di_min_ttl ) {
			ttl = di->di_min_ttl;
		}

		/* This does not apply to multi-master case */
		if ( !( !SLAP_SINGLE_SHADOW( op->o_bd ) || be_isupdate( op ) ) ) {
			/* we SHOULD return a referral in this case */
			BerVarray defref = op->o_bd->be_update_refs
				? op->o_bd->be_update_refs : default_referral;

			if ( defref != NULL ) {
				rs->sr_ref = referral_rewrite( op->o_bd->be_update_refs,
					NULL, NULL, LDAP_SCOPE_DEFAULT );
				if ( rs->sr_ref ) {
					rs->sr_flags |= REP_REF_MUSTBEFREED;
				} else {
					rs->sr_ref = defref;
				}
				rs->sr_err = LDAP_REFERRAL;

			} else {
				rs->sr_text = "shadow context; no update referral";
				rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
			}

			return rs->sr_err;
		}

		assert( !BER_BVISNULL( &op->o_req_ndn ) );



		/* check if exists but not dynamicObject */
		op->o_bd->bd_info = (BackendInfo *)on->on_info;
		rs->sr_err = be_entry_get_rw( op, &op->o_req_ndn,
			slap_schema.si_oc_dynamicObject, NULL, 0, &e );
		if ( rs->sr_err != LDAP_SUCCESS ) {
			rs->sr_err = be_entry_get_rw( op, &op->o_req_ndn,
				NULL, NULL, 0, &e );
			if ( rs->sr_err == LDAP_SUCCESS && e != NULL ) {
				/* return referral only if "disclose"
				 * is granted on the object */
				if ( ! access_allowed( op, e,
						slap_schema.si_ad_entry,
						NULL, ACL_DISCLOSE, NULL ) )
				{
					rs->sr_err = LDAP_NO_SUCH_OBJECT;

				} else {
					rs->sr_err = LDAP_OBJECT_CLASS_VIOLATION;
					rs->sr_text = "refresh operation only applies to dynamic objects";
				}
				be_entry_release_r( op, e );

			} else {
				rs->sr_err = LDAP_NO_SUCH_OBJECT;
			}
			return rs->sr_err;

		} else if ( e != NULL ) {
			be_entry_release_r( op, e );
		}

		/* we require manage privileges on the entryTtl,
		 * and fake a Relax control */
		op2.o_tag = LDAP_REQ_MODIFY;
		op2.o_bd = &db;
		db.bd_info = (BackendInfo *)on->on_info;
		op2.o_callback = &sc;
		sc.sc_response = slap_null_cb;
		op2.o_relax = SLAP_CONTROL_CRITICAL;
		op2.orm_modlist = &ttlmod;

		ttlmod.sml_op = LDAP_MOD_REPLACE;
		ttlmod.sml_flags = SLAP_MOD_MANAGING;
		ttlmod.sml_desc = slap_schema.si_ad_entryTtl;
		ttlmod.sml_values = ttlvalues;
		ttlmod.sml_numvals = 1;
		ttlvalues[ 0 ].bv_val = ttlbuf;
		ttlvalues[ 0 ].bv_len = snprintf( ttlbuf, sizeof( ttlbuf ), "%ld", ttl );
		BER_BVZERO( &ttlvalues[ 1 ] );

		/* the entryExpireTimestamp is added by modify */
		rs->sr_err = slap_biglock_call_be( op_modify, &op2, &rs2 );

		if ( ttlmod.sml_next != NULL ) {
			slap_mods_free( ttlmod.sml_next, 1 );
		}

		if ( rs->sr_err == LDAP_SUCCESS ) {
			int			rc;
			BerElementBuffer	berbuf;
			BerElement		*ber = (BerElement *)&berbuf;

			ber_init_w_nullc( ber, LBER_USE_DER );

			rc = ber_printf( ber, "{tiN}", LDAP_TAG_EXOP_REFRESH_RES_TTL, (int)ttl );

			if ( rc < 0 ) {
				rs->sr_err = LDAP_OTHER;
				rs->sr_text = "internal error";

			} else {
				(void)ber_flatten( ber, &rs->sr_rspdata );
				rs->sr_rspoid = ch_strdup( slap_EXOP_REFRESH.bv_val );

				Log3( LDAP_DEBUG_TRACE, LDAP_LEVEL_INFO,
					"%s REFRESH dn=\"%s\" TTL=%ld\n",
					op->o_log_prefix, op->o_req_ndn.bv_val, ttl );
			}

			ber_free_buf( ber );
		}

		return rs->sr_err;
	}

	return SLAP_CB_CONTINUE;
}