Beispiel #1
0
/* return 0 IFF op_dn is a value in group_at (member) attribute
 * of entry with gr_dn AND that entry has an objectClass
 * value of group_oc (groupOfNames)
 */
int
ldap_back_group(
	Backend		*be,
	Connection 	*conn,
	Operation 	*op,
	Entry		*target,
	struct berval	*gr_ndn,
	struct berval	*op_ndn,
	ObjectClass	*group_oc,
	AttributeDescription* group_at
)
{
	struct ldapinfo *li = (struct ldapinfo *) be->be_private;    
	int rc = 1;
	Attribute   *attr;

	LDAPMessage	*result;
	char *gattr[2];
	char *filter = NULL, *ptr;
	LDAP *ld;
	struct berval mop_ndn = { 0, NULL }, mgr_ndn = { 0, NULL };

	AttributeDescription *ad_objectClass = slap_schema.si_ad_objectClass;
	struct berval group_oc_name = {0, NULL};
	struct berval group_at_name = group_at->ad_cname;

	if( group_oc->soc_names && group_oc->soc_names[0] ) {
		group_oc_name.bv_val = group_oc->soc_names[0];
	} else {
		group_oc_name.bv_val = group_oc->soc_oid;
	}
	if (group_oc_name.bv_val)
		group_oc_name.bv_len = strlen(group_oc_name.bv_val);

	if (target != NULL && dn_match( &target->e_nname, gr_ndn ) ) {
		/* we already have a copy of the entry */
		/* attribute and objectclass mapping has already been done */

		/*
		 * first we need to check if the objectClass attribute
		 * has been retieved; otherwise we need to repeat the search
		 */
		attr = attr_find( target->e_attrs, ad_objectClass );
		if ( attr != NULL ) {

			/*
			 * Now we can check for the group objectClass value
			 */
			if( !is_entry_objectclass( target, group_oc, 0 ) ) {
				return(1);
			}

			/*
			 * This part has been reworked: the group attr compare
			 * fails only if the attribute is PRESENT but the value
			 * is NOT PRESENT; if the attribute is NOT PRESENT, the
			 * search must be repeated as well.
			 * This may happen if a search for an entry has already
			 * been performed (target is not null) but the group
			 * attribute has not been required
			 */
			if ((attr = attr_find(target->e_attrs, group_at)) != NULL) {
				if( value_find_ex( group_at, SLAP_MR_VALUE_NORMALIZED_MATCH,
					attr->a_vals, op_ndn ) != LDAP_SUCCESS )
					return(1);
				return(0);
			} /* else: repeat the search */
		} /* else: repeat the search */
	} /* else: do the search */

	/*
	 * Rewrite the op ndn if needed
	 */
#ifdef ENABLE_REWRITE
	switch ( rewrite_session( li->rwinfo, "bindDn",
				op_ndn->bv_val, conn, &mop_ndn.bv_val ) ) {
	case REWRITE_REGEXEC_OK:
		if ( mop_ndn.bv_val == NULL ) {
			mop_ndn = *op_ndn;
		}
#ifdef NEW_LOGGING
		LDAP_LOG( BACK_LDAP, DETAIL1, 
			"[rw] bindDn (op ndn in group): \"%s\" -> \"%s\"\n", 
			op_ndn->bv_val, mop_ndn.bv_val, 0 );
#else /* !NEW_LOGGING */
		Debug( LDAP_DEBUG_ARGS,
			"rw> bindDn (op ndn in group): \"%s\" -> \"%s\"\n%s",
			op_ndn->bv_val, mop_ndn.bv_val, "" );
#endif /* !NEW_LOGGING */
		break;
	
	case REWRITE_REGEXEC_UNWILLING:
	
	case REWRITE_REGEXEC_ERR:
		goto cleanup;
	}

	/*
	 * Rewrite the gr ndn if needed
	 */
        switch ( rewrite_session( li->rwinfo, "searchBase",
				gr_ndn->bv_val, conn, &mgr_ndn.bv_val ) ) {
	case REWRITE_REGEXEC_OK:
		if ( mgr_ndn.bv_val == NULL ) {
			mgr_ndn = *gr_ndn;
		}
#ifdef NEW_LOGGING
		LDAP_LOG( BACK_LDAP, DETAIL1, 
			"[rw] searchBase (gr ndn in group): \"%s\" -> \"%s\"\n%s", 
			gr_ndn->bv_val, mgr_ndn.bv_val, "" );
#else /* !NEW_LOGGING */
		Debug( LDAP_DEBUG_ARGS,
			"rw> searchBase (gr ndn in group):"
			" \"%s\" -> \"%s\"\n%s",
			gr_ndn->bv_val, mgr_ndn.bv_val, "" );
#endif /* !NEW_LOGGING */
		break;
	
	case REWRITE_REGEXEC_UNWILLING:
	
	case REWRITE_REGEXEC_ERR:
		goto cleanup;
	}
#else /* !ENABLE_REWRITE */
	ldap_back_dn_massage( li, op_ndn, &mop_ndn, 1, 1 );
	if ( mop_ndn.bv_val == NULL ) {
		goto cleanup;
	}
	ldap_back_dn_massage( li, gr_ndn, &mgr_ndn, 1, 1 );
	if ( mgr_ndn.bv_val == NULL ) {
		goto cleanup;
	}
#endif /* !ENABLE_REWRITE */

	ldap_back_map(&li->oc_map, &group_oc_name, &group_oc_name,
			BACKLDAP_MAP);
	if (group_oc_name.bv_val == NULL || group_oc_name.bv_val[0] == '\0')
		goto cleanup;
	ldap_back_map(&li->at_map, &group_at_name, &group_at_name,
			BACKLDAP_MAP);
	if (group_at_name.bv_val == NULL || group_at_name.bv_val[0] == '\0')
		goto cleanup;

	filter = ch_malloc(sizeof("(&(objectclass=)(=))")
						+ group_oc_name.bv_len
						+ group_at_name.bv_len
						+ mop_ndn.bv_len + 1);
	if (filter == NULL)
		goto cleanup;

	if (ldap_initialize(&ld, li->url) != LDAP_SUCCESS) {
		goto cleanup;
	}

	if (ldap_bind_s(ld, li->binddn, li->bindpw, LDAP_AUTH_SIMPLE)
			!= LDAP_SUCCESS) {
		goto cleanup;
	}

	ptr = lutil_strcopy(filter, "(&(objectclass=");
	ptr = lutil_strcopy(ptr, group_oc_name.bv_val);
	ptr = lutil_strcopy(ptr, ")(");
	ptr = lutil_strcopy(ptr, group_at_name.bv_val);
	ptr = lutil_strcopy(ptr, "=");
	ptr = lutil_strcopy(ptr, mop_ndn.bv_val);
	strcpy(ptr, "))");

	gattr[0] = "objectclass";
	gattr[1] = NULL;
	if (ldap_search_ext_s(ld, mgr_ndn.bv_val, LDAP_SCOPE_BASE, filter,
		gattr, 0, NULL, NULL, LDAP_NO_LIMIT,
		LDAP_NO_LIMIT, &result) == LDAP_SUCCESS) {
		if (ldap_first_entry(ld, result) != NULL)
			rc = 0;
		ldap_msgfree(result);
	}

cleanup:;
	if ( ld != NULL ) {
		ldap_unbind(ld);
	}
	ch_free(filter);
	if ( mop_ndn.bv_val != op_ndn->bv_val ) {
		free( mop_ndn.bv_val );
	}
	if ( mgr_ndn.bv_val != gr_ndn->bv_val ) {
		free( mgr_ndn.bv_val );
	}
	return(rc);
}
Beispiel #2
0
static int
autoca_op_response(
	Operation *op,
	SlapReply *rs
)
{
	slap_overinst *on = op->o_callback->sc_private;
	autoca_info *ai = on->on_bi.bi_private;
	Attribute *a;
	int isusr = 0;

	if (rs->sr_type != REP_SEARCH)
		return SLAP_CB_CONTINUE;

	/* If root or self */
	if ( !be_isroot( op ) &&
		!dn_match( &rs->sr_entry->e_nname, &op->o_ndn ))
		return SLAP_CB_CONTINUE;

	isusr = is_entry_objectclass( rs->sr_entry, ai->ai_usrclass, SLAP_OCF_CHECK_SUP );
	if ( !isusr )
	{
		if (!is_entry_objectclass( rs->sr_entry, ai->ai_srvclass, SLAP_OCF_CHECK_SUP ))
			return SLAP_CB_CONTINUE;
	}
	a = attr_find( rs->sr_entry->e_attrs, ad_usrPkey );
	if ( !a )
	{
		Operation op2;
		genargs args;
		saveargs arg2;
		myext extras[2];
		int rc;

		args.issuer_cert = ai->ai_cert;
		args.issuer_pkey = ai->ai_pkey;
		args.subjectDN = &rs->sr_entry->e_name;
		args.more_exts = NULL;
		if ( isusr )
		{
			args.cert_exts = usrExts;
			args.keybits = ai->ai_usrkeybits;
			args.days = ai->ai_usrdays;
			a = attr_find( rs->sr_entry->e_attrs, ad_mail );
			if ( a )
			{
				extras[0].name = "subjectAltName";
				extras[1].name = NULL;
				extras[0].value = op->o_tmpalloc( sizeof("email:") + a->a_vals[0].bv_len, op->o_tmpmemctx );
				sprintf(extras[0].value, "email:%s", a->a_vals[0].bv_val);
				args.more_exts = extras;
			}
		} else
		{
			args.cert_exts = srvExts;
			args.keybits = ai->ai_srvkeybits;
			args.days = ai->ai_srvdays;
			if ( ad_ipaddr && (a = attr_find( rs->sr_entry->e_attrs, ad_ipaddr )))
			{
				extras[0].name = "subjectAltName";
				extras[1].name = NULL;
				extras[0].value = op->o_tmpalloc( sizeof("IP:") + a->a_vals[0].bv_len, op->o_tmpmemctx );
				sprintf(extras[0].value, "IP:%s", a->a_vals[0].bv_val);
				args.more_exts = extras;
			}
		}
		rc = autoca_gencert( op, &args );
		if ( rc )
			return SLAP_CB_CONTINUE;
		X509_free( args.newcert );
		EVP_PKEY_free( args.newpkey );

		if ( is_entry_objectclass( rs->sr_entry, oc_usrObj, 0 ))
			arg2.oc = NULL;
		else
			arg2.oc = oc_usrObj;
		if ( !( rs->sr_flags & REP_ENTRY_MODIFIABLE ))
		{
			Entry *e = entry_dup( rs->sr_entry );
			rs_replace_entry( op, rs, on, e );
			rs->sr_flags |= REP_ENTRY_MODIFIABLE | REP_ENTRY_MUSTBEFREED;
		}
		arg2.dercert = &args.dercert;
		arg2.derpkey = &args.derpkey;
		arg2.on = on;
		arg2.dn = &rs->sr_entry->e_name;
		arg2.ndn = &rs->sr_entry->e_nname;
		arg2.isca = 0;
		op2 = *op;
		rc = autoca_savecert( &op2, &arg2 );
		if ( !rc )
		{
			/* If this is our cert DN, configure it */
			if ( dn_match( &rs->sr_entry->e_nname, &ai->ai_localndn ))
				autoca_setlocal( &op2, &args.dercert, &args.derpkey );
			attr_merge_one( rs->sr_entry, ad_usrCert, &args.dercert, NULL );
			attr_merge_one( rs->sr_entry, ad_usrPkey, &args.derpkey, NULL );
		}
		op->o_tmpfree( args.dercert.bv_val, op->o_tmpmemctx );
		op->o_tmpfree( args.derpkey.bv_val, op->o_tmpmemctx );
	}

	return SLAP_CB_CONTINUE;
}
Beispiel #3
0
static int
autoca_db_open(
	BackendDB *be,
	ConfigReply *cr
)
{
	slap_overinst *on = (slap_overinst *)be->bd_info;
	autoca_info *ai = on->on_bi.bi_private;

	Connection conn = { 0 };
	OperationBuffer opbuf;
	Operation *op;
	void *thrctx;
	Entry *e;
	Attribute *a;
	int rc;

	if (slapMode & SLAP_TOOL_MODE)
		return 0;

	if ( ! *aca_attr2[0].ad ) {
		int i, code;
		const char *text;

		for ( i=0; aca_attr2[i].at; i++ ) {
			code = slap_str2ad( aca_attr2[i].at, aca_attr2[i].ad, &text );
			if ( code ) return code;
		}

		/* Schema may not be loaded, ignore if missing */
		slap_str2ad( "ipHostNumber", &ad_ipaddr, &text );

		for ( i=0; aca_ocs[i].ot; i++ ) {
			code = register_oc( aca_ocs[i].ot, aca_ocs[i].oc, 0 );
			if ( code ) return code;
		}
	}

	thrctx = ldap_pvt_thread_pool_context();
	connection_fake_init2( &conn, &opbuf, thrctx, 0 );
	op = &opbuf.ob_op;
	op->o_bd = be;
	op->o_dn = be->be_rootdn;
	op->o_ndn = be->be_rootndn;
	rc = overlay_entry_get_ov( op, be->be_nsuffix, NULL, 
		NULL, 0, &e, on );

	if ( e ) {
		int gotoc = 0, gotat = 0;
		if ( is_entry_objectclass( e, oc_caObj, 0 )) {
			gotoc = 1;
			a = attr_find( e->e_attrs, ad_caPkey );
			if ( a ) {
				const unsigned char *pp;
				pp = (unsigned char *)a->a_vals[0].bv_val;
				ai->ai_pkey = d2i_AutoPrivateKey( NULL, &pp, a->a_vals[0].bv_len );
				if ( ai->ai_pkey )
				{
					a = attr_find( e->e_attrs, ad_caCert );
					if ( a )
					{
						pp = (unsigned char *)a->a_vals[0].bv_val;
						ai->ai_cert = d2i_X509( NULL, &pp, a->a_vals[0].bv_len );
						/* If TLS wasn't configured yet, set this as our CA */
						if ( !slap_tls_ctx )
							autoca_setca( a->a_vals );
					}
				}
				gotat = 1;
			}
		}
		overlay_entry_release_ov( op, e, 0, on );
		/* generate attrs, store... */
		if ( !gotat ) {
			genargs args;
			saveargs arg2;

			args.issuer_cert = NULL;
			args.issuer_pkey = NULL;
			args.subjectDN = &be->be_suffix[0];
			args.cert_exts = CAexts;
			args.more_exts = NULL;
			args.keybits = ai->ai_cakeybits;
			args.days = ai->ai_cadays;

			rc = autoca_gencert( op, &args );
			if ( rc )
				return -1;

			ai->ai_cert = args.newcert;
			ai->ai_pkey = args.newpkey;

			arg2.dn = be->be_suffix;
			arg2.ndn = be->be_nsuffix;
			arg2.isca = 1;
			if ( !gotoc )
				arg2.oc = oc_caObj;
			else
				arg2.oc = NULL;
			arg2.on = on;
			arg2.dercert = &args.dercert;
			arg2.derpkey = &args.derpkey;

			autoca_savecert( op, &arg2 );

			/* If TLS wasn't configured yet, set this as our CA */
			if ( !slap_tls_ctx )
				autoca_setca( &args.dercert );

			op->o_tmpfree( args.dercert.bv_val, op->o_tmpmemctx );
			op->o_tmpfree( args.derpkey.bv_val, op->o_tmpmemctx );
		}
	}

	return 0;
}
Beispiel #4
0
/**
 * Look for posixAccount adds with no autoPosixIds/gidNumber,
 * and add in the next available autoPosixIds/gidNumber as needed.
 */
static int autoPosixIds_add( Operation *op, SlapReply *rs ) {

	Entry* to_add = NULL;
 	AttributeDescription* ad = NULL;
	AttributeDescription* ad2 = NULL;
	Attribute* attr = NULL;
	char uidstr[64];
	char gidstr[64];
	struct berval uidbv = BER_BVNULL;
	struct berval gidbv = BER_BVNULL;
  	unsigned long uid;
	const char* text;
	const char* text2;
	int rc;
	int rc2;

	to_add = op->oq_add.rs_e;

	// if the user doesn't have access, default through to the normal ADD
	if( !access_allowed( op, to_add, slap_schema.si_ad_entry, NULL, ACL_WRITE, NULL ) )
	    return SLAP_CB_CONTINUE;

	// only interested in posixAccounts
	if( !is_entry_objectclass( (to_add), oc_posix_account, 0) ) {
	    Debug( LDAP_DEBUG_TRACE, "%s: entry %s is not of objectclass posixAccount\n", autoPosixIds.on_bi.bi_type, to_add->e_nname.bv_val, 0 );
	    return SLAP_CB_CONTINUE;
	}

	// if autoPosixIds present, no further processing required
	for( attr = to_add->e_attrs; attr; attr = attr->a_next ) {

	     if( !strcmp( attr->a_desc->ad_cname.bv_val, uid_attr_name ) ) {
		 Debug(LDAP_DEBUG_TRACE, "%s: ignoring %s due to present uidNumber attribute\n", autoPosixIds.on_bi.bi_type, to_add->e_nname.bv_val, 0 );
		 return SLAP_CB_CONTINUE;
	     }
	}

        // get next assignable number
	uid = autoPosixIds_next_available( op );

        // add autoPosixIds
	rc = slap_str2ad( uid_attr_name, &ad, &text );
	if( rc != LDAP_SUCCESS ) {
	    Debug( LDAP_DEBUG_ANY, "%s: failed to add uidNumber attribute to entry\n", autoPosixIds.on_bi.bi_type, 0, 0 );
	    return SLAP_CB_CONTINUE;
	}
	sprintf( uidstr, "%lu", uid );
	ber_str2bv( uidstr, 0, 0, &uidbv );
	attr_merge_one( to_add, ad, &uidbv, 0 );
	Debug( LDAP_DEBUG_ANY, "%s: added uidNumber %s to entry\n", autoPosixIds.on_bi.bi_type, uidstr, 0 );

        // if gidNumber present, no further processing required
	for( attr = to_add->e_attrs; attr; attr = attr->a_next ) {
	     if( !strcmp( attr->a_desc->ad_cname.bv_val, gid_attr_name ) ) {
		 Debug( LDAP_DEBUG_TRACE, "%s: ignoring %s due to present gidNumber attribute\n", autoPosixIds.on_bi.bi_type, to_add->e_nname.bv_val, 0 );
		 return SLAP_CB_CONTINUE;
	     }
	}

	// add gidNumber
	rc2 = slap_str2ad( gid_attr_name, &ad2, &text2 );
	if( rc2 != LDAP_SUCCESS ) {
 	    Debug( LDAP_DEBUG_ANY, "%s: failed to add gidNumber attribute to entry\n", autoPosixIds.on_bi.bi_type, 0, 0 );
	    return SLAP_CB_CONTINUE;
	}
	sprintf( gidstr, "%lu", uid );
	ber_str2bv( gidstr, 0, 0, &gidbv );
	attr_merge_one( to_add, ad2, &gidbv, 0 );
	Debug( LDAP_DEBUG_ANY, "%s: added gidNumber %s to entry\n", autoPosixIds.on_bi.bi_type, gidstr, 0 );

	return SLAP_CB_CONTINUE;
}