Пример #1
0
int
monitor_subsys_listener_init(
	BackendDB		*be,
	monitor_subsys_t	*ms
)
{
	monitor_info_t	*mi;
	Entry		*e_listener, **ep;
	int		i;
	monitor_entry_t	*mp;
	Listener	**l;

	assert( be != NULL );

	if ( ( l = slapd_get_listeners() ) == NULL ) {
		if ( slapMode & SLAP_TOOL_MODE ) {
			return 0;
		}

		Debug( LDAP_DEBUG_ANY,
			"monitor_subsys_listener_init: "
			"unable to get listeners\n", 0, 0, 0 );
		return( -1 );
	}

	mi = ( monitor_info_t * )be->be_private;

	if ( monitor_cache_get( mi, &ms->mss_ndn, &e_listener ) ) {
		Debug( LDAP_DEBUG_ANY,
			"monitor_subsys_listener_init: "
			"unable to get entry \"%s\"\n",
			ms->mss_ndn.bv_val, 0, 0 );
		return( -1 );
	}

	mp = ( monitor_entry_t * )e_listener->e_private;
	mp->mp_children = NULL;
	ep = &mp->mp_children;

	for ( i = 0; l[ i ]; i++ ) {
		char 		buf[ BACKMONITOR_BUFSIZE ];
		Entry		*e;
		struct berval bv;

		bv.bv_len = snprintf( buf, sizeof( buf ),
				"cn=Listener %d", i );
		bv.bv_val = buf;
		e = monitor_entry_stub( &ms->mss_dn, &ms->mss_ndn, &bv,
			mi->mi_oc_monitoredObject, mi, NULL, NULL );

		if ( e == NULL ) {
			Debug( LDAP_DEBUG_ANY,
				"monitor_subsys_listener_init: "
				"unable to create entry \"cn=Listener %d,%s\"\n",
				i, ms->mss_ndn.bv_val, 0 );
			return( -1 );
		}

		attr_merge_normalize_one( e, mi->mi_ad_monitorConnectionLocalAddress,
				&l[ i ]->sl_name, NULL );

		attr_merge_normalize_one( e, slap_schema.si_ad_labeledURI,
				&l[ i ]->sl_url, NULL );

#ifdef HAVE_TLS
		if ( l[ i ]->sl_is_tls ) {
			struct berval bv;

			BER_BVSTR( &bv, "TLS" );
			attr_merge_normalize_one( e, mi->mi_ad_monitoredInfo,
					&bv, NULL );
		}
#endif /* HAVE_TLS */
#ifdef LDAP_CONNECTIONLESS
		if ( l[ i ]->sl_is_udp ) {
			struct berval bv;

			BER_BVSTR( &bv, "UDP" );
			attr_merge_normalize_one( e, mi->mi_ad_monitoredInfo,
					&bv, NULL );
		}
#endif /* HAVE_TLS */

		mp = monitor_entrypriv_create();
		if ( mp == NULL ) {
			return -1;
		}
		e->e_private = ( void * )mp;
		mp->mp_info = ms;
		mp->mp_flags = ms->mss_flags
			| MONITOR_F_SUB;

		if ( monitor_cache_add( mi, e ) ) {
			Debug( LDAP_DEBUG_ANY,
				"monitor_subsys_listener_init: "
				"unable to add entry \"cn=Listener %d,%s\"\n",
				i, ms->mss_ndn.bv_val, 0 );
			return( -1 );
		}

		*ep = e;
		ep = &mp->mp_next;
	}
	
	monitor_cache_release( mi, e_listener );

	return( 0 );
}
Пример #2
0
/*
 * call from within ldap_back_db_open()
 */
int
ldap_back_monitor_db_open( BackendDB *be )
{
	ldapinfo_t		*li = (ldapinfo_t *) be->be_private;
	char			buf[ BACKMONITOR_BUFSIZE ];
	Entry			*e = NULL;
	monitor_callback_t	*cb = NULL;
	struct berval		suffix, *filter, *base;
	char			*ptr;
	time_t			now;
	char			timebuf[ LDAP_LUTIL_GENTIME_BUFSIZE ];
	struct berval 		timestamp;
	int			rc = 0;
	BackendInfo		*mi;
	monitor_extra_t		*mbe;

	if ( !SLAP_DBMONITORING( be ) ) {
		return 0;
	}

	/* check if monitor is configured and usable */
	mi = backend_info( "monitor" );
	if ( !mi || !mi->bi_extra ) {
		SLAP_DBFLAGS( be ) ^= SLAP_DBFLAG_MONITORING;
		return 0;
 	}
 	mbe = mi->bi_extra;

	/* don't bother if monitor is not configured */
	if ( !mbe->is_configured() ) {
		static int warning = 0;

		if ( warning++ == 0 ) {
			Debug( LDAP_DEBUG_ANY, "ldap_back_monitor_db_open: "
				"monitoring disabled; "
				"configure monitor database to enable\n",
				0, 0, 0 );
		}

		return 0;
	}

	/* set up the fake subsystem that is used to create
	 * the volatile connection entries */
	li->li_monitor_info.lmi_mss.mss_name = "back-ldap";
	li->li_monitor_info.lmi_mss.mss_flags = MONITOR_F_VOLATILE_CH;
	li->li_monitor_info.lmi_mss.mss_create = ldap_back_monitor_conn_create;

	li->li_monitor_info.lmi_li = li;
	li->li_monitor_info.lmi_scope = LDAP_SCOPE_SUBORDINATE;
	base = &li->li_monitor_info.lmi_base;
	BER_BVSTR( base, "cn=databases,cn=monitor" );
	filter = &li->li_monitor_info.lmi_filter;
	BER_BVZERO( filter );

	suffix.bv_len = ldap_bv2escaped_filter_value_len( &be->be_nsuffix[ 0 ] );
	if ( suffix.bv_len == be->be_nsuffix[ 0 ].bv_len ) {
		suffix = be->be_nsuffix[ 0 ];

	} else {
		ldap_bv2escaped_filter_value( &be->be_nsuffix[ 0 ], &suffix );
	}
	
	filter->bv_len = STRLENOF( "(&" )
		+ li->li_monitor_info.lmi_more_filter.bv_len
		+ STRLENOF( "(monitoredInfo=" )
		+ strlen( be->bd_info->bi_type )
		+ STRLENOF( ")(!(monitorOverlay=" )
		+ strlen( be->bd_info->bi_type )
		+ STRLENOF( "))(namingContexts:distinguishedNameMatch:=" )
		+ suffix.bv_len + STRLENOF( "))" );
	ptr = filter->bv_val = ch_malloc( filter->bv_len + 1 );
	ptr = lutil_strcopy( ptr, "(&" );
	ptr = lutil_strncopy( ptr, li->li_monitor_info.lmi_more_filter.bv_val,
		li->li_monitor_info.lmi_more_filter.bv_len );
	ptr = lutil_strcopy( ptr, "(monitoredInfo=" );
	ptr = lutil_strcopy( ptr, be->bd_info->bi_type );
	ptr = lutil_strcopy( ptr, ")(!(monitorOverlay=" );
	ptr = lutil_strcopy( ptr, be->bd_info->bi_type );
	ptr = lutil_strcopy( ptr, "))(namingContexts:distinguishedNameMatch:=" );
	ptr = lutil_strncopy( ptr, suffix.bv_val, suffix.bv_len );
	ptr = lutil_strcopy( ptr, "))" );
	ptr[ 0 ] = '\0';
	assert( ptr == &filter->bv_val[ filter->bv_len ] );

	if ( suffix.bv_val != be->be_nsuffix[ 0 ].bv_val ) {
		ch_free( suffix.bv_val );
	}

	now = slap_get_time();
	timestamp.bv_val = timebuf;
	timestamp.bv_len = sizeof( timebuf );
	slap_timestamp( &now, &timestamp );

	/* caller (e.g. an overlay based on back-ldap) may want to use
	 * a different RDN... */
	if ( BER_BVISNULL( &li->li_monitor_info.lmi_rdn ) ) {
		ber_str2bv( "cn=Connections", 0, 1, &li->li_monitor_info.lmi_rdn );
	}

	ptr = ber_bvchr( &li->li_monitor_info.lmi_rdn, '=' );
	assert( ptr != NULL );
	ptr[ 0 ] = '\0';
	ptr++;

	snprintf( buf, sizeof( buf ),
		"dn: %s=%s\n"
		"objectClass: monitorContainer\n"
		"%s: %s\n"
		"creatorsName: %s\n"
		"createTimestamp: %s\n"
		"modifiersName: %s\n"
		"modifyTimestamp: %s\n",
		li->li_monitor_info.lmi_rdn.bv_val,
			ptr,
		li->li_monitor_info.lmi_rdn.bv_val,
			ptr,
		BER_BVISNULL( &be->be_rootdn ) ? SLAPD_ANONYMOUS : be->be_rootdn.bv_val,
		timestamp.bv_val,
		BER_BVISNULL( &be->be_rootdn ) ? SLAPD_ANONYMOUS : be->be_rootdn.bv_val,
		timestamp.bv_val );
	e = str2entry( buf );
	if ( e == NULL ) {
		rc = -1;
		goto cleanup;
	}

	ptr[ -1 ] = '=';

	/* add labeledURI and special, modifiable URI value */
	if ( li->li_uri != NULL ) {
		struct berval	bv;
		LDAPURLDesc	*ludlist = NULL;
		int		rc;

		rc = ldap_url_parselist_ext( &ludlist,
			li->li_uri, NULL,
			LDAP_PVT_URL_PARSE_NOEMPTY_HOST
				| LDAP_PVT_URL_PARSE_DEF_PORT );
		if ( rc != LDAP_URL_SUCCESS ) {
			Debug( LDAP_DEBUG_ANY,
				"ldap_back_monitor_db_open: "
				"unable to parse URI list (ignored)\n",
				0, 0, 0 );
		} else {
			for ( ; ludlist != NULL; ) {
				LDAPURLDesc	*next = ludlist->lud_next;

				bv.bv_val = ldap_url_desc2str( ludlist );
				assert( bv.bv_val != NULL );
				ldap_free_urldesc( ludlist );
				bv.bv_len = strlen( bv.bv_val );
				attr_merge_normalize_one( e, slap_schema.si_ad_labeledURI,
					&bv, NULL );
				ch_free( bv.bv_val );

				ludlist = next;
			}
		}
		
		ber_str2bv( li->li_uri, 0, 0, &bv );
		attr_merge_normalize_one( e, ad_olmDbURIList,
			&bv, NULL );
	}

	ber_dupbv( &li->li_monitor_info.lmi_nrdn, &e->e_nname );

	cb = ch_calloc( sizeof( monitor_callback_t ), 1 );
	cb->mc_update = ldap_back_monitor_update;
	cb->mc_modify = ldap_back_monitor_modify;
	cb->mc_free = ldap_back_monitor_free;
	cb->mc_private = (void *)li;

	rc = mbe->register_entry_parent( e, cb,
		(monitor_subsys_t *)&li->li_monitor_info,
		MONITOR_F_VOLATILE_CH,
		base, LDAP_SCOPE_SUBORDINATE, filter );

cleanup:;
	if ( rc != 0 ) {
		if ( cb != NULL ) {
			ch_free( cb );
			cb = NULL;
		}

		if ( e != NULL ) {
			entry_free( e );
			e = NULL;
		}

		if ( !BER_BVISNULL( filter ) ) {
			ch_free( filter->bv_val );
			BER_BVZERO( filter );
		}
	}

	/* store for cleanup */
	li->li_monitor_info.lmi_cb = (void *)cb;

	if ( e != NULL ) {
		entry_free( e );
	}

	return rc;
}
Пример #3
0
int
schema_info( Entry **entry, const char **text )
{
	AttributeDescription *ad_structuralObjectClass
		= slap_schema.si_ad_structuralObjectClass;
	AttributeDescription *ad_objectClass
		= slap_schema.si_ad_objectClass;
	AttributeDescription *ad_createTimestamp
		= slap_schema.si_ad_createTimestamp;
	AttributeDescription *ad_modifyTimestamp
		= slap_schema.si_ad_modifyTimestamp;

	Entry		*e;
	struct berval	vals[5];
	struct berval	nvals[5];

	e = entry_alloc();
	if( e == NULL ) {
		/* Out of memory, do something about it */
		Debug( LDAP_DEBUG_ANY, 
			"schema_info: entry_alloc failed - out of memory.\n", 0, 0, 0 );
		*text = "out of memory";
		return LDAP_OTHER;
	}

	e->e_attrs = NULL;
	/* backend-specific schema info should be created by the
	 * backend itself
	 */
	ber_dupbv( &e->e_name, &frontendDB->be_schemadn );
	ber_dupbv( &e->e_nname, &frontendDB->be_schemandn );
	e->e_private = NULL;

	BER_BVSTR( &vals[0], "subentry" );
	if( attr_merge_one( e, ad_structuralObjectClass, vals, NULL ) ) {
		/* Out of memory, do something about it */
		entry_free( e );
		*text = "out of memory";
		return LDAP_OTHER;
	}

	BER_BVSTR( &vals[0], "top" );
	BER_BVSTR( &vals[1], "subentry" );
	BER_BVSTR( &vals[2], "subschema" );
	BER_BVSTR( &vals[3], "extensibleObject" );
	BER_BVZERO( &vals[4] );
	if ( attr_merge( e, ad_objectClass, vals, NULL ) ) {
		/* Out of memory, do something about it */
		entry_free( e );
		*text = "out of memory";
		return LDAP_OTHER;
	}

	{
		int rc;
		AttributeDescription *desc = NULL;
		struct berval rdn = frontendDB->be_schemadn;
		vals[0].bv_val = ber_bvchr( &rdn, '=' );

		if( vals[0].bv_val == NULL ) {
			*text = "improperly configured subschema subentry";
			return LDAP_OTHER;
		}

		vals[0].bv_val++;
		vals[0].bv_len = rdn.bv_len - (vals[0].bv_val - rdn.bv_val);
		rdn.bv_len -= vals[0].bv_len + 1;

		rc = slap_bv2ad( &rdn, &desc, text );

		if( rc != LDAP_SUCCESS ) {
			entry_free( e );
			*text = "improperly configured subschema subentry";
			return LDAP_OTHER;
		}

		nvals[0].bv_val = ber_bvchr( &frontendDB->be_schemandn, '=' );
		assert( nvals[0].bv_val != NULL );
		nvals[0].bv_val++;
		nvals[0].bv_len = frontendDB->be_schemandn.bv_len -
			(nvals[0].bv_val - frontendDB->be_schemandn.bv_val);

		if ( attr_merge_one( e, desc, vals, nvals ) ) {
			/* Out of memory, do something about it */
			entry_free( e );
			*text = "out of memory";
			return LDAP_OTHER;
		}
	}

	{
		char		timebuf[ LDAP_LUTIL_GENTIME_BUFSIZE ];

		/*
		 * According to RFC 4512:

   Servers SHOULD maintain the 'creatorsName', 'createTimestamp',       
   'modifiersName', and 'modifyTimestamp' attributes for all entries of 
   the DIT. 

		 * to be conservative, we declare schema created 
		 * AND modified at server startup time ...
		 */

		vals[0].bv_val = timebuf;
		vals[0].bv_len = sizeof( timebuf );

		slap_timestamp( &starttime, vals );

		if( attr_merge_one( e, ad_createTimestamp, vals, NULL ) ) {
			/* Out of memory, do something about it */
			entry_free( e );
			*text = "out of memory";
			return LDAP_OTHER;
		}
		if( attr_merge_one( e, ad_modifyTimestamp, vals, NULL ) ) {
			/* Out of memory, do something about it */
			entry_free( e );
			*text = "out of memory";
			return LDAP_OTHER;
		}
	}

	if ( syn_schema_info( e ) 
		|| mr_schema_info( e )
		|| mru_schema_info( e )
		|| at_schema_info( e )
		|| oc_schema_info( e )
		|| cr_schema_info( e ) )
	{
		/* Out of memory, do something about it */
		entry_free( e );
		*text = "out of memory";
		return LDAP_OTHER;
	}
	
	*entry = e;
	return LDAP_SUCCESS;
}
Пример #4
0
int
slapadd( int argc, char **argv )
{
	char *buf = NULL;
	const char *text;
	char textbuf[SLAP_TEXT_BUFLEN] = { '\0' };
	size_t textlen = sizeof textbuf;
	const char *progname = "slapadd";

	struct berval csn;
	struct berval maxcsn[ SLAP_SYNC_SID_MAX + 1 ];
	unsigned long sid;
	struct berval bvtext;
	Attribute *attr;
	Entry *ctxcsn_e;
	ID	ctxcsn_id, id;
	OperationBuffer opbuf;
	Operation *op;

	int match;
	int checkvals;
	int lineno, nextline;
	int lmax;
	int rc = EXIT_SUCCESS;
	int manage = 0;	

	/* default "000" */
	csnsid = 0;

	slap_tool_init( progname, SLAPADD, argc, argv );

	memset( &opbuf, 0, sizeof(opbuf) );
	op = &opbuf.ob_op;
	op->o_hdr = &opbuf.ob_hdr;

	if( !be->be_entry_open ||
		!be->be_entry_close ||
		!be->be_entry_put ||
		(update_ctxcsn &&
		 (!be->be_dn2id_get ||
		  !be->be_entry_get ||
		  !be->be_entry_modify)) )
	{
		fprintf( stderr, "%s: database doesn't support necessary operations.\n",
			progname );
		if ( dryrun ) {
			fprintf( stderr, "\t(dry) continuing...\n" );

		} else {
			exit( EXIT_FAILURE );
		}
	}

	checkvals = (slapMode & SLAP_TOOL_QUICK) ? 0 : 1;

	lmax = 0;
	nextline = 0;

	/* enforce schema checking unless not disabled */
	if ( (slapMode & SLAP_TOOL_NO_SCHEMA_CHECK) == 0) {
		SLAP_DBFLAGS(be) &= ~(SLAP_DBFLAG_NO_SCHEMA_CHECK);
	}

	if( !dryrun && be->be_entry_open( be, 1 ) != 0 ) {
		fprintf( stderr, "%s: could not open database.\n",
			progname );
		exit( EXIT_FAILURE );
	}

	if ( update_ctxcsn ) {
		maxcsn[ 0 ].bv_val = maxcsnbuf;
		for ( sid = 1; sid <= SLAP_SYNC_SID_MAX; sid++ ) {
			maxcsn[ sid ].bv_val = maxcsn[ sid - 1 ].bv_val + LDAP_LUTIL_CSNSTR_BUFSIZE;
			maxcsn[ sid ].bv_len = 0;
		}
	}

	/* nextline is the line number of the end of the current entry */
	for( lineno=1; ldif_read_record( ldiffp, &nextline, &buf, &lmax );
		lineno=nextline+1 ) {
		Entry *e;

		if ( lineno < jumpline )
			continue;

		e = str2entry2( buf, checkvals );

		/*
		 * Initialize text buffer
		 */
		bvtext.bv_len = textlen;
		bvtext.bv_val = textbuf;
		bvtext.bv_val[0] = '\0';

		if( e == NULL ) {
			fprintf( stderr, "%s: could not parse entry (line=%d)\n",
				progname, lineno );
			rc = EXIT_FAILURE;
			if( continuemode ) continue;
			break;
		}

		/* make sure the DN is not empty */
		if( BER_BVISEMPTY( &e->e_nname ) &&
			!BER_BVISEMPTY( be->be_nsuffix )) {
			fprintf( stderr, "%s: empty dn=\"%s\" (line=%d)\n",
				progname, e->e_dn, lineno );
			rc = EXIT_FAILURE;
			entry_free( e );
			if( continuemode ) continue;
			break;
		}

		/* check backend */
		if( select_backend( &e->e_nname, nosubordinates )
			!= be )
		{
			fprintf( stderr, "%s: line %d: "
				"database (%s) not configured to hold \"%s\"\n",
				progname, lineno,
				be ? be->be_suffix[0].bv_val : "<none>",
				e->e_dn );
			fprintf( stderr, "%s: line %d: "
				"database (%s) not configured to hold \"%s\"\n",
				progname, lineno,
				be ? be->be_nsuffix[0].bv_val : "<none>",
				e->e_ndn );
			rc = EXIT_FAILURE;
			entry_free( e );
			if( continuemode ) continue;
			break;
		}

		{
			Attribute *oc = attr_find( e->e_attrs,
				slap_schema.si_ad_objectClass );

			if( oc == NULL ) {
				fprintf( stderr, "%s: dn=\"%s\" (line=%d): %s\n",
					progname, e->e_dn, lineno,
					"no objectClass attribute");
				rc = EXIT_FAILURE;
				entry_free( e );
				if( continuemode ) continue;
				break;
			}

			/* check schema */
			op->o_bd = be;

			if ( (slapMode & SLAP_TOOL_NO_SCHEMA_CHECK) == 0) {
				rc = entry_schema_check( op, e, NULL, manage, 1,
					&text, textbuf, textlen );

				if( rc != LDAP_SUCCESS ) {
					fprintf( stderr, "%s: dn=\"%s\" (line=%d): (%d) %s\n",
						progname, e->e_dn, lineno, rc, text );
					rc = EXIT_FAILURE;
					entry_free( e );
					if( continuemode ) continue;
					break;
				}
				textbuf[ 0 ] = '\0';
			}
		}

		if ( SLAP_LASTMOD(be) ) {
			time_t now = slap_get_time();
			char uuidbuf[ LDAP_LUTIL_UUIDSTR_BUFSIZE ];
			struct berval vals[ 2 ];

			struct berval name, timestamp;

			struct berval nvals[ 2 ];
			struct berval nname;
			char timebuf[ LDAP_LUTIL_GENTIME_BUFSIZE ];

			vals[1].bv_len = 0;
			vals[1].bv_val = NULL;

			nvals[1].bv_len = 0;
			nvals[1].bv_val = NULL;

			csn.bv_len = lutil_csnstr( csnbuf, sizeof( csnbuf ), csnsid, 0 );
			csn.bv_val = csnbuf;

			timestamp.bv_val = timebuf;
			timestamp.bv_len = sizeof(timebuf);

			slap_timestamp( &now, &timestamp );

			if ( BER_BVISEMPTY( &be->be_rootndn ) ) {
				BER_BVSTR( &name, SLAPD_ANONYMOUS );
				nname = name;
			} else {
				name = be->be_rootdn;
				nname = be->be_rootndn;
			}

			if( attr_find( e->e_attrs, slap_schema.si_ad_entryUUID )
				== NULL )
			{
				vals[0].bv_len = lutil_uuidstr( uuidbuf, sizeof( uuidbuf ) );
				vals[0].bv_val = uuidbuf;
				attr_merge_normalize_one( e, slap_schema.si_ad_entryUUID, vals, NULL );
			}

			if( attr_find( e->e_attrs, slap_schema.si_ad_creatorsName )
				== NULL )
			{
				vals[0] = name;
				nvals[0] = nname;
				attr_merge( e, slap_schema.si_ad_creatorsName, vals, nvals );
			}

			if( attr_find( e->e_attrs, slap_schema.si_ad_createTimestamp )
				== NULL )
			{
				vals[0] = timestamp;
				attr_merge( e, slap_schema.si_ad_createTimestamp, vals, NULL );
			}

			if( attr_find( e->e_attrs, slap_schema.si_ad_entryCSN )
				== NULL )
			{
				vals[0] = csn;
				attr_merge( e, slap_schema.si_ad_entryCSN, vals, NULL );
			}

			if( attr_find( e->e_attrs, slap_schema.si_ad_modifiersName )
				== NULL )
			{
				vals[0] = name;
				nvals[0] = nname;
				attr_merge( e, slap_schema.si_ad_modifiersName, vals, nvals );
			}

			if( attr_find( e->e_attrs, slap_schema.si_ad_modifyTimestamp )
				== NULL )
			{
				vals[0] = timestamp;
				attr_merge( e, slap_schema.si_ad_modifyTimestamp, vals, NULL );
			}

			if ( update_ctxcsn ) {
				int rc_sid;

				attr = attr_find( e->e_attrs, slap_schema.si_ad_entryCSN );
				assert( attr != NULL );

				rc_sid = slap_parse_csn_sid( &attr->a_nvals[ 0 ] );
				if ( rc_sid < 0 ) {
					Debug( LDAP_DEBUG_ANY, "%s: could not "
						"extract SID from entryCSN=%s\n",
						progname, attr->a_nvals[ 0 ].bv_val, 0 );

				} else {
					assert( rc_sid <= SLAP_SYNC_SID_MAX );

					sid = (unsigned)rc_sid;
					if ( maxcsn[ sid ].bv_len != 0 ) {
						match = 0;
						value_match( &match, slap_schema.si_ad_entryCSN,
							slap_schema.si_ad_entryCSN->ad_type->sat_ordering,
							SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
							&maxcsn[ sid ], &attr->a_nvals[0], &text );
					} else {
						match = -1;
					}
					if ( match < 0 ) {
						strcpy( maxcsn[ sid ].bv_val, attr->a_nvals[0].bv_val );
						maxcsn[ sid ].bv_len = attr->a_nvals[0].bv_len;
					}
				}
			}
		}

		if ( !dryrun ) {
			id = be->be_entry_put( be, e, &bvtext );
			if( id == NOID ) {
				fprintf( stderr, "%s: could not add entry dn=\"%s\" "
								 "(line=%d): %s\n", progname, e->e_dn,
								 lineno, bvtext.bv_val );
				rc = EXIT_FAILURE;
				entry_free( e );
				if( continuemode ) continue;
				break;
			}
			if ( verbose )
				fprintf( stderr, "added: \"%s\" (%08lx)\n",
					e->e_dn, (long) id );
		} else {
			if ( verbose )
				fprintf( stderr, "added: \"%s\"\n",
					e->e_dn );
		}

		entry_free( e );
	}

	bvtext.bv_len = textlen;
	bvtext.bv_val = textbuf;
	bvtext.bv_val[0] = '\0';

	if ( rc == EXIT_SUCCESS && update_ctxcsn && !dryrun && sid != SLAP_SYNC_SID_MAX + 1 ) {
		ctxcsn_id = be->be_dn2id_get( be, be->be_nsuffix );
		if ( ctxcsn_id == NOID ) {
			fprintf( stderr, "%s: context entry is missing\n", progname );
			rc = EXIT_FAILURE;
		} else {
			ctxcsn_e = be->be_entry_get( be, ctxcsn_id );
			if ( ctxcsn_e != NULL ) {
				Entry *e = entry_dup( ctxcsn_e );
				int change;
				attr = attr_find( e->e_attrs, slap_schema.si_ad_contextCSN );
				if ( attr ) {
					int		i;

					change = 0;

					for ( i = 0; !BER_BVISNULL( &attr->a_nvals[ i ] ); i++ ) {
						int rc_sid;

						rc_sid = slap_parse_csn_sid( &attr->a_nvals[ i ] );
						if ( rc_sid < 0 ) {
							Debug( LDAP_DEBUG_ANY,
								"%s: unable to extract SID "
								"from #%d contextCSN=%s\n",
								progname, i,
								attr->a_nvals[ i ].bv_val );
							continue;
						}

						assert( rc_sid <= SLAP_SYNC_SID_MAX );

						sid = (unsigned)rc_sid;

						if ( maxcsn[ sid ].bv_len == 0 ) {
							match = -1;

						} else {
							value_match( &match, slap_schema.si_ad_entryCSN,
								slap_schema.si_ad_entryCSN->ad_type->sat_ordering,
								SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
								&maxcsn[ sid ], &attr->a_nvals[i], &text );
						}

						if ( match > 0 ) {
							change = 1;
						} else {
							AC_MEMCPY( maxcsn[ sid ].bv_val,
								attr->a_nvals[ i ].bv_val,
								attr->a_nvals[ i ].bv_len );
							maxcsn[ sid ].bv_val[ attr->a_nvals[ i ].bv_len ] = '\0';
							maxcsn[ sid ].bv_len = attr->a_nvals[ i ].bv_len;
						}
					}

					if ( change ) {
						if ( attr->a_nvals != attr->a_vals ) {
							ber_bvarray_free( attr->a_nvals );
						}
						attr->a_nvals = NULL;
						ber_bvarray_free( attr->a_vals );
						attr->a_vals = NULL;
						attr->a_numvals = 0;
					}
				} else {
					change = 1;
				}

				if ( change ) {
					for ( sid = 0; sid <= SLAP_SYNC_SID_MAX; sid++ ) {
						if ( maxcsn[ sid ].bv_len ) {
							attr_merge_one( e, slap_schema.si_ad_contextCSN,
								&maxcsn[ sid], NULL );
						}
					}

					ctxcsn_id = be->be_entry_modify( be, e, &bvtext );
					if( ctxcsn_id == NOID ) {
						fprintf( stderr, "%s: could not modify ctxcsn\n",
							progname);
						rc = EXIT_FAILURE;
					} else if ( verbose ) {
						fprintf( stderr, "modified: \"%s\" (%08lx)\n",
							e->e_dn, (long) ctxcsn_id );
					}
				}
				entry_free( e );
			}
		} 
	}

	ch_free( buf );

	if ( !dryrun ) {
		if( be->be_entry_close( be ) ) {
			rc = EXIT_FAILURE;
		}

		if( be->be_sync ) {
			be->be_sync( be );
		}
	}

	slap_tool_destroy();

	return rc;
}
Пример #5
0
int
meta_back_db_open(
	Backend		*be,
	ConfigReply	*cr )
{
	metainfo_t	*mi = (metainfo_t *)be->be_private;
	BackendInfo *bi;

	int		i,
			not_always = 0,
			not_always_anon_proxyauthz = 0,
			not_always_anon_non_prescriptive = 0,
			rc;

	if ( mi->mi_ntargets == 0 ) {
		Debug( LDAP_DEBUG_ANY,
			"meta_back_db_open: no targets defined\n",
			0, 0, 0 );
		return 1;
	}

	bi = backend_info( "ldap" );
	if ( !bi || !bi->bi_extra ) {
		Debug( LDAP_DEBUG_ANY,
			"meta_back_db_open: needs back-ldap\n",
			0, 0, 0 );
		return 1;
	}
	mi->mi_ldap_extra = (ldap_extra_t *)bi->bi_extra;

	for ( i = 0; i < mi->mi_ntargets; i++ ) {
		slap_bindconf	sb = { BER_BVNULL };
		metatarget_t	*mt = mi->mi_targets[ i ];

		ber_str2bv( mt->mt_uri, 0, 0, &sb.sb_uri );
		sb.sb_version = mt->mt_version;
		sb.sb_method = LDAP_AUTH_SIMPLE;
		BER_BVSTR( &sb.sb_binddn, "" );

		if ( META_BACK_TGT_T_F_DISCOVER( mt ) ) {
			rc = slap_discover_feature( &sb,
					slap_schema.si_ad_supportedFeatures->ad_cname.bv_val,
					LDAP_FEATURE_ABSOLUTE_FILTERS );
			if ( rc == LDAP_COMPARE_TRUE ) {
				mt->mt_flags |= LDAP_BACK_F_T_F;
			}
		}

		if ( META_BACK_TGT_CANCEL_DISCOVER( mt ) ) {
			rc = slap_discover_feature( &sb,
					slap_schema.si_ad_supportedExtension->ad_cname.bv_val,
					LDAP_EXOP_CANCEL );
			if ( rc == LDAP_COMPARE_TRUE ) {
				mt->mt_flags |= LDAP_BACK_F_CANCEL_EXOP;
			}
		}

		if ( not_always == 0 ) {
			if ( !( mt->mt_idassert_flags & LDAP_BACK_AUTH_OVERRIDE )
				|| mt->mt_idassert_authz != NULL )
			{
				not_always = 1;
			}
		}

		if ( ( mt->mt_idassert_flags & LDAP_BACK_AUTH_AUTHZ_ALL )
			&& !( mt->mt_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) )
		{
			Debug( LDAP_DEBUG_ANY, "meta_back_db_open(%s): "
				"target #%d inconsistent idassert configuration "
				"(likely authz=\"*\" used with \"non-prescriptive\" flag)\n",
				be->be_suffix[ 0 ].bv_val, i, 0 );
			return 1;
		}

		if ( not_always_anon_proxyauthz == 0 ) {
			if ( !( mt->mt_idassert_flags & LDAP_BACK_AUTH_AUTHZ_ALL ) )
			{
				not_always_anon_proxyauthz = 1;
			}
		}

		if ( not_always_anon_non_prescriptive == 0 ) {
			if ( ( mt->mt_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) )
			{
				not_always_anon_non_prescriptive = 1;
			}
		}
	}

	if ( not_always == 0 ) {
		mi->mi_flags |= META_BACK_F_PROXYAUTHZ_ALWAYS;
	}

	if ( not_always_anon_proxyauthz == 0 ) {
		mi->mi_flags |= META_BACK_F_PROXYAUTHZ_ANON;

	} else if ( not_always_anon_non_prescriptive == 0 ) {
		mi->mi_flags |= META_BACK_F_PROXYAUTHZ_NOANON;
	}

	return 0;
}
Пример #6
0
int
meta_target_finish(
	metainfo_t *mi,
	metatarget_t *mt,
	const char *log,
	char *msg,
	size_t msize
)
{
	slap_bindconf	sb = { BER_BVNULL };
	struct berval mapped;
	int rc;

	ber_str2bv( mt->mt_uri, 0, 0, &sb.sb_uri );
	sb.sb_version = mt->mt_version;
	sb.sb_method = LDAP_AUTH_SIMPLE;
	BER_BVSTR( &sb.sb_binddn, "" );

	if ( META_BACK_TGT_T_F_DISCOVER( mt ) ) {
		rc = slap_discover_feature( &sb,
				slap_schema.si_ad_supportedFeatures->ad_cname.bv_val,
				LDAP_FEATURE_ABSOLUTE_FILTERS );
		if ( rc == LDAP_COMPARE_TRUE ) {
			mt->mt_flags |= LDAP_BACK_F_T_F;
		}
	}

	if ( META_BACK_TGT_CANCEL_DISCOVER( mt ) ) {
		rc = slap_discover_feature( &sb,
				slap_schema.si_ad_supportedExtension->ad_cname.bv_val,
				LDAP_EXOP_CANCEL );
		if ( rc == LDAP_COMPARE_TRUE ) {
			mt->mt_flags |= LDAP_BACK_F_CANCEL_EXOP;
		}
	}

	if ( !( mt->mt_idassert_flags & LDAP_BACK_AUTH_OVERRIDE )
		|| mt->mt_idassert_authz != NULL )
	{
		mi->mi_flags &= ~META_BACK_F_PROXYAUTHZ_ALWAYS;
	}

	if ( ( mt->mt_idassert_flags & LDAP_BACK_AUTH_AUTHZ_ALL )
		&& !( mt->mt_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) )
	{
		snprintf( msg, msize,
			"%s: inconsistent idassert configuration "
			"(likely authz=\"*\" used with \"non-prescriptive\" flag)",
			log );
		Debug( LDAP_DEBUG_ANY, "%s (target %s)\n",
			msg, mt->mt_uri );
		return 1;
	}

	if ( !( mt->mt_idassert_flags & LDAP_BACK_AUTH_AUTHZ_ALL ) )
	{
		mi->mi_flags &= ~META_BACK_F_PROXYAUTHZ_ANON;
	}

	if ( ( mt->mt_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) )
	{
		mi->mi_flags &= ~META_BACK_F_PROXYAUTHZ_NOANON;
	}

	BER_BVZERO( &mapped );
	ldap_back_map( &mt->mt_rwmap.rwm_at,
		&slap_schema.si_ad_entryDN->ad_cname, &mapped,
		BACKLDAP_REMAP );
	if ( BER_BVISNULL( &mapped ) || mapped.bv_val[0] == '\0' ) {
		mt->mt_rep_flags |= REP_NO_ENTRYDN;
	}

	BER_BVZERO( &mapped );
	ldap_back_map( &mt->mt_rwmap.rwm_at,
		&slap_schema.si_ad_subschemaSubentry->ad_cname, &mapped,
		BACKLDAP_REMAP );
	if ( BER_BVISNULL( &mapped ) || mapped.bv_val[0] == '\0' ) {
		mt->mt_rep_flags |= REP_NO_SUBSCHEMA;
	}

	return 0;
}
Пример #7
0
static int
rwm_int_filter_map_rewrite(
	Operation		*op,
	dncookie		*dc,
	Filter			*f,
	struct berval		*fstr )
{
	int		i;
	Filter		*p;
	AttributeDescription *ad;
	struct berval	atmp,
			vtmp,
			*tmp;
	static struct berval
			/* better than nothing... */
			ber_bvfalse = BER_BVC( "(!(objectClass=*))" ),
			ber_bvtf_false = BER_BVC( "(|)" ),
			/* better than nothing... */
			ber_bvtrue = BER_BVC( "(objectClass=*)" ),
			ber_bvtf_true = BER_BVC( "(&)" ),
#if 0
			/* no longer needed; preserved for completeness */
			ber_bvundefined = BER_BVC( "(?=undefined)" ),
#endif
			ber_bverror = BER_BVC( "(?=error)" ),
			ber_bvunknown = BER_BVC( "(?=unknown)" ),
			ber_bvnone = BER_BVC( "(?=none)" );
	ber_len_t	len;

	assert( fstr != NULL );
	BER_BVZERO( fstr );

	if ( f == NULL ) {
		ber_dupbv_x( fstr, &ber_bvnone, op->o_tmpmemctx );
		return LDAP_OTHER;
	}

	if ( f->f_choice & SLAPD_FILTER_UNDEFINED ) {
		goto computed;
	}

	switch ( f->f_choice & SLAPD_FILTER_MASK ) {
	case LDAP_FILTER_EQUALITY:
		ad = f->f_av_desc;
		if ( map_attr_value( dc, &ad, &atmp,
			&f->f_av_value, &vtmp, RWM_MAP, op->o_tmpmemctx ) )
		{
			goto computed;
		}

		fstr->bv_len = atmp.bv_len + vtmp.bv_len + STRLENOF( "(=)" );
		fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx );

		snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=%s)",
			atmp.bv_val, vtmp.bv_len ? vtmp.bv_val : "" );

		op->o_tmpfree( vtmp.bv_val, op->o_tmpmemctx );
		break;

	case LDAP_FILTER_GE:
		ad = f->f_av_desc;
		if ( map_attr_value( dc, &ad, &atmp,
			&f->f_av_value, &vtmp, RWM_MAP, op->o_tmpmemctx ) )
		{
			goto computed;
		}

		fstr->bv_len = atmp.bv_len + vtmp.bv_len + STRLENOF( "(>=)" );
		fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx );

		snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s>=%s)",
			atmp.bv_val, vtmp.bv_len ? vtmp.bv_val : "" );

		op->o_tmpfree( vtmp.bv_val, op->o_tmpmemctx );
		break;

	case LDAP_FILTER_LE:
		ad = f->f_av_desc;
		if ( map_attr_value( dc, &ad, &atmp,
			&f->f_av_value, &vtmp, RWM_MAP, op->o_tmpmemctx ) )
		{
			goto computed;
		}

		fstr->bv_len = atmp.bv_len + vtmp.bv_len + STRLENOF( "(<=)" );
		fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx );

		snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s<=%s)",
			atmp.bv_val, vtmp.bv_len ? vtmp.bv_val : "" );

		op->o_tmpfree( vtmp.bv_val, op->o_tmpmemctx );
		break;

	case LDAP_FILTER_APPROX:
		ad = f->f_av_desc;
		if ( map_attr_value( dc, &ad, &atmp,
			&f->f_av_value, &vtmp, RWM_MAP, op->o_tmpmemctx ) )
		{
			goto computed;
		}

		fstr->bv_len = atmp.bv_len + vtmp.bv_len + STRLENOF( "(~=)" );
		fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx );

		snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s~=%s)",
			atmp.bv_val, vtmp.bv_len ? vtmp.bv_val : "" );

		op->o_tmpfree( vtmp.bv_val, op->o_tmpmemctx );
		break;

	case LDAP_FILTER_SUBSTRINGS:
		ad = f->f_sub_desc;
		if ( map_attr_value( dc, &ad, &atmp,
			NULL, NULL, RWM_MAP, op->o_tmpmemctx ) )
		{
			goto computed;
		}

		/* cannot be a DN ... */

		fstr->bv_len = atmp.bv_len + STRLENOF( "(=*)" );
		fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 128, op->o_tmpmemctx );

		snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=*)",
			atmp.bv_val );

		if ( !BER_BVISNULL( &f->f_sub_initial ) ) {
			len = fstr->bv_len;

			filter_escape_value_x( &f->f_sub_initial, &vtmp, op->o_tmpmemctx );

			fstr->bv_len += vtmp.bv_len;
			fstr->bv_val = op->o_tmprealloc( fstr->bv_val, fstr->bv_len + 1,
				op->o_tmpmemctx );

			snprintf( &fstr->bv_val[len - 2], vtmp.bv_len + 3,
				/* "(attr=" */ "%s*)",
				vtmp.bv_len ? vtmp.bv_val : "" );

			op->o_tmpfree( vtmp.bv_val, op->o_tmpmemctx );
		}

		if ( f->f_sub_any != NULL ) {
			for ( i = 0; !BER_BVISNULL( &f->f_sub_any[i] ); i++ ) {
				len = fstr->bv_len;
				filter_escape_value_x( &f->f_sub_any[i], &vtmp,
					op->o_tmpmemctx );

				fstr->bv_len += vtmp.bv_len + 1;
				fstr->bv_val = op->o_tmprealloc( fstr->bv_val, fstr->bv_len + 1,
					op->o_tmpmemctx );

				snprintf( &fstr->bv_val[len - 1], vtmp.bv_len + 3,
					/* "(attr=[init]*[any*]" */ "%s*)",
					vtmp.bv_len ? vtmp.bv_val : "" );
				op->o_tmpfree( vtmp.bv_val, op->o_tmpmemctx );
			}
		}

		if ( !BER_BVISNULL( &f->f_sub_final ) ) {
			len = fstr->bv_len;

			filter_escape_value_x( &f->f_sub_final, &vtmp, op->o_tmpmemctx );

			fstr->bv_len += vtmp.bv_len;
			fstr->bv_val = op->o_tmprealloc( fstr->bv_val, fstr->bv_len + 1,
				op->o_tmpmemctx );

			snprintf( &fstr->bv_val[len - 1], vtmp.bv_len + 3,
				/* "(attr=[init*][any*]" */ "%s)",
				vtmp.bv_len ? vtmp.bv_val : "" );

			op->o_tmpfree( vtmp.bv_val, op->o_tmpmemctx );
		}

		break;

	case LDAP_FILTER_PRESENT:
		ad = f->f_desc;
		if ( map_attr_value( dc, &ad, &atmp,
			NULL, NULL, RWM_MAP, op->o_tmpmemctx ) )
		{
			goto computed;
		}

		fstr->bv_len = atmp.bv_len + STRLENOF( "(=*)" );
		fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx );

		snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=*)",
			atmp.bv_val );
		break;

	case LDAP_FILTER_AND:
	case LDAP_FILTER_OR:
	case LDAP_FILTER_NOT:
		fstr->bv_len = STRLENOF( "(%)" );
		fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 128, op->o_tmpmemctx );

		snprintf( fstr->bv_val, fstr->bv_len + 1, "(%c)",
			f->f_choice == LDAP_FILTER_AND ? '&' :
			f->f_choice == LDAP_FILTER_OR ? '|' : '!' );

		for ( p = f->f_list; p != NULL; p = p->f_next ) {
			int	rc;

			len = fstr->bv_len;

			rc = rwm_int_filter_map_rewrite( op, dc, p, &vtmp );
			if ( rc != LDAP_SUCCESS ) {
				return rc;
			}
			
			fstr->bv_len += vtmp.bv_len;
			fstr->bv_val = op->o_tmprealloc( fstr->bv_val, fstr->bv_len + 1,
				op->o_tmpmemctx );

			snprintf( &fstr->bv_val[len-1], vtmp.bv_len + 2, 
				/*"("*/ "%s)", vtmp.bv_len ? vtmp.bv_val : "" );

			op->o_tmpfree( vtmp.bv_val, op->o_tmpmemctx );
		}

		break;

	case LDAP_FILTER_EXT: {
		if ( f->f_mr_desc ) {
			ad = f->f_mr_desc;
			if ( map_attr_value( dc, &ad, &atmp,
				&f->f_mr_value, &vtmp, RWM_MAP, op->o_tmpmemctx ) )
			{
				goto computed;
			}

		} else {
			BER_BVSTR( &atmp, "" );
			filter_escape_value_x( &f->f_mr_value, &vtmp, op->o_tmpmemctx );
		}
			

		fstr->bv_len = atmp.bv_len +
			( f->f_mr_dnattrs ? STRLENOF( ":dn" ) : 0 ) +
			( f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_len + 1 : 0 ) +
			vtmp.bv_len + STRLENOF( "(:=)" );
		fstr->bv_val = op->o_tmpalloc( fstr->bv_len + 1, op->o_tmpmemctx );

		snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s%s%s%s:=%s)",
			atmp.bv_val,
			f->f_mr_dnattrs ? ":dn" : "",
			!BER_BVISEMPTY( &f->f_mr_rule_text ) ? ":" : "",
			!BER_BVISEMPTY( &f->f_mr_rule_text ) ? f->f_mr_rule_text.bv_val : "",
			vtmp.bv_len ? vtmp.bv_val : "" );
		op->o_tmpfree( vtmp.bv_val, op->o_tmpmemctx );
		break;
	}

	case -1:
computed:;
		filter_free_x( op, f, 0 );
		f->f_choice = SLAPD_FILTER_COMPUTED;
		f->f_result = SLAPD_COMPARE_UNDEFINED;
		/* fallthru */

	case SLAPD_FILTER_COMPUTED:
		switch ( f->f_result ) {
		case LDAP_COMPARE_FALSE:
		/* FIXME: treat UNDEFINED as FALSE */
		case SLAPD_COMPARE_UNDEFINED:
			if ( dc->rwmap->rwm_flags & RWM_F_SUPPORT_T_F ) {
				tmp = &ber_bvtf_false;
				break;
			}
			tmp = &ber_bvfalse;
			break;

		case LDAP_COMPARE_TRUE:
			if ( dc->rwmap->rwm_flags & RWM_F_SUPPORT_T_F ) {
				tmp = &ber_bvtf_true;
				break;
			}
			tmp = &ber_bvtrue;
			break;
			
		default:
			tmp = &ber_bverror;
			break;
		}

		ber_dupbv_x( fstr, tmp, op->o_tmpmemctx );
		break;
		
	default:
		ber_dupbv_x( fstr, &ber_bvunknown, op->o_tmpmemctx );
		break;
	}

	return LDAP_SUCCESS;
}
Пример #8
0
/*
 * meta_back_proxy_authz_cred()
 *
 * prepares credentials & method for meta_back_proxy_authz_bind();
 * or, if method is SASL, performs the SASL bind directly.
 */
int
meta_back_proxy_authz_cred(
	metaconn_t		*mc,
	int			candidate,
	Operation		*op,
	SlapReply		*rs,
	ldap_back_send_t	sendok,
	struct berval		*binddn,
	struct berval		*bindcred,
	int			*method )
{
	metainfo_t		*mi = (metainfo_t *)op->o_bd->be_private;
	metatarget_t		*mt = mi->mi_targets[ candidate ];
	metasingleconn_t	*msc = &mc->mc_conns[ candidate ];
	struct berval		ndn;
	int			dobind = 0;

	/* don't proxyAuthz if protocol is not LDAPv3 */
	switch ( mt->mt_version ) {
	case LDAP_VERSION3:
		break;

	case 0:
		if ( op->o_protocol == 0 || op->o_protocol == LDAP_VERSION3 ) {
			break;
		}
		/* fall thru */

	default:
		rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
		if ( sendok & LDAP_BACK_SENDERR ) {
			send_ldap_result( op, rs );
		}
		LDAP_BACK_CONN_ISBOUND_CLEAR( msc );
		goto done;
	}

	if ( op->o_tag == LDAP_REQ_BIND ) {
		ndn = op->o_req_ndn;

	} else if ( !BER_BVISNULL( &op->o_conn->c_ndn ) ) {
		ndn = op->o_conn->c_ndn;

	} else {
		ndn = op->o_ndn;
	}
	rs->sr_err = LDAP_SUCCESS;

	/*
	 * FIXME: we need to let clients use proxyAuthz
	 * otherwise we cannot do symmetric pools of servers;
	 * we have to live with the fact that a user can
	 * authorize itself as any ID that is allowed
	 * by the authzTo directive of the "proxyauthzdn".
	 */
	/*
	 * NOTE: current Proxy Authorization specification
	 * and implementation do not allow proxy authorization
	 * control to be provided with Bind requests
	 */
	/*
	 * if no bind took place yet, but the connection is bound
	 * and the "proxyauthzdn" is set, then bind as
	 * "proxyauthzdn" and explicitly add the proxyAuthz
	 * control to every operation with the dn bound
	 * to the connection as control value.
	 */

	/* bind as proxyauthzdn only if no idassert mode
	 * is requested, or if the client's identity
	 * is authorized */
	switch ( mt->mt_idassert_mode ) {
	case LDAP_BACK_IDASSERT_LEGACY:
		if ( !BER_BVISNULL( &ndn ) && !BER_BVISEMPTY( &ndn ) ) {
			if ( !BER_BVISNULL( &mt->mt_idassert_authcDN ) && !BER_BVISEMPTY( &mt->mt_idassert_authcDN ) )
			{
				*binddn = mt->mt_idassert_authcDN;
				*bindcred = mt->mt_idassert_passwd;
				dobind = 1;
			}
		}
		break;

	default:
		/* NOTE: rootdn can always idassert */
		if ( BER_BVISNULL( &ndn )
			&& mt->mt_idassert_authz == NULL
			&& !( mt->mt_idassert_flags & LDAP_BACK_AUTH_AUTHZ_ALL ) )
		{
			if ( mt->mt_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) {
				rs->sr_err = LDAP_INAPPROPRIATE_AUTH;
				if ( sendok & LDAP_BACK_SENDERR ) {
					send_ldap_result( op, rs );
				}
				LDAP_BACK_CONN_ISBOUND_CLEAR( msc );
				goto done;

			}

			rs->sr_err = LDAP_SUCCESS;
			*binddn = slap_empty_bv;
			*bindcred = slap_empty_bv;
			break;

		} else if ( mt->mt_idassert_authz && !be_isroot( op ) ) {
			struct berval authcDN;

			if ( BER_BVISNULL( &ndn ) ) {
				authcDN = slap_empty_bv;

			} else {
				authcDN = ndn;
			}
			rs->sr_err = slap_sasl_matches( op, mt->mt_idassert_authz,
					&authcDN, &authcDN );
			if ( rs->sr_err != LDAP_SUCCESS ) {
				if ( mt->mt_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) {
					if ( sendok & LDAP_BACK_SENDERR ) {
						send_ldap_result( op, rs );
					}
					LDAP_BACK_CONN_ISBOUND_CLEAR( msc );
					goto done;
				}

				rs->sr_err = LDAP_SUCCESS;
				*binddn = slap_empty_bv;
				*bindcred = slap_empty_bv;
				break;
			}
		}

		*binddn = mt->mt_idassert_authcDN;
		*bindcred = mt->mt_idassert_passwd;
		dobind = 1;
		break;
	}

	if ( dobind && mt->mt_idassert_authmethod == LDAP_AUTH_SASL ) {
#ifdef HAVE_CYRUS_SASL
		void		*defaults = NULL;
		struct berval	authzID = BER_BVNULL;
		int		freeauthz = 0;

		/* if SASL supports native authz, prepare for it */
		if ( ( !op->o_do_not_cache || !op->o_is_auth_check ) &&
				( mt->mt_idassert_flags & LDAP_BACK_AUTH_NATIVE_AUTHZ ) )
		{
			switch ( mt->mt_idassert_mode ) {
			case LDAP_BACK_IDASSERT_OTHERID:
			case LDAP_BACK_IDASSERT_OTHERDN:
				authzID = mt->mt_idassert_authzID;
				break;

			case LDAP_BACK_IDASSERT_ANONYMOUS:
				BER_BVSTR( &authzID, "dn:" );
				break;

			case LDAP_BACK_IDASSERT_SELF:
				if ( BER_BVISNULL( &ndn ) ) {
					/* connection is not authc'd, so don't idassert */
					BER_BVSTR( &authzID, "dn:" );
					break;
				}
				authzID.bv_len = STRLENOF( "dn:" ) + ndn.bv_len;
				authzID.bv_val = slap_sl_malloc( authzID.bv_len + 1, op->o_tmpmemctx );
				memcpy( authzID.bv_val, "dn:", STRLENOF( "dn:" ) );
				memcpy( authzID.bv_val + STRLENOF( "dn:" ),
						ndn.bv_val, ndn.bv_len + 1 );
				freeauthz = 1;
				break;

			default:
				break;
			}
		}

		if ( mt->mt_idassert_secprops != NULL ) {
			rs->sr_err = ldap_set_option( msc->msc_ld,
				LDAP_OPT_X_SASL_SECPROPS,
				(void *)mt->mt_idassert_secprops );

			if ( rs->sr_err != LDAP_OPT_SUCCESS ) {
				rs->sr_err = LDAP_OTHER;
				if ( sendok & LDAP_BACK_SENDERR ) {
					send_ldap_result( op, rs );
				}
				LDAP_BACK_CONN_ISBOUND_CLEAR( msc );
				goto done;
			}
		}

		defaults = lutil_sasl_defaults( msc->msc_ld,
				mt->mt_idassert_sasl_mech.bv_val,
				mt->mt_idassert_sasl_realm.bv_val,
				mt->mt_idassert_authcID.bv_val,
				mt->mt_idassert_passwd.bv_val,
				authzID.bv_val );
		if ( defaults == NULL ) {
			rs->sr_err = LDAP_OTHER;
			LDAP_BACK_CONN_ISBOUND_CLEAR( msc );
			if ( sendok & LDAP_BACK_SENDERR ) {
				send_ldap_result( op, rs );
			}
			goto done;
		}

		rs->sr_err = ldap_sasl_interactive_bind_s( msc->msc_ld, binddn->bv_val,
				mt->mt_idassert_sasl_mech.bv_val, NULL, NULL,
				LDAP_SASL_QUIET, lutil_sasl_interact,
				defaults );

		rs->sr_err = slap_map_api2result( rs );
		if ( rs->sr_err != LDAP_SUCCESS ) {
			LDAP_BACK_CONN_ISBOUND_CLEAR( msc );
			if ( sendok & LDAP_BACK_SENDERR ) {
				send_ldap_result( op, rs );
			}

		} else {
			LDAP_BACK_CONN_ISBOUND_SET( msc );
		}

		lutil_sasl_freedefs( defaults );
		if ( freeauthz ) {
			slap_sl_free( authzID.bv_val, op->o_tmpmemctx );
		}

		goto done;
#endif /* HAVE_CYRUS_SASL */
	}

	*method = mt->mt_idassert_authmethod;
	switch ( mt->mt_idassert_authmethod ) {
	case LDAP_AUTH_NONE:
		BER_BVSTR( binddn, "" );
		BER_BVSTR( bindcred, "" );
		/* fallthru */

	case LDAP_AUTH_SIMPLE:
		break;

	default:
		/* unsupported! */
		LDAP_BACK_CONN_ISBOUND_CLEAR( msc );
		rs->sr_err = LDAP_AUTH_METHOD_NOT_SUPPORTED;
		if ( sendok & LDAP_BACK_SENDERR ) {
			send_ldap_result( op, rs );
		}
		break;
	}

done:;

	if ( !BER_BVISEMPTY( binddn ) ) {
		LDAP_BACK_CONN_ISIDASSERT_SET( msc );
	}

	return rs->sr_err;
}
Пример #9
0
int
monitor_subsys_conn_init(
	BackendDB		*be,
	monitor_subsys_t	*ms )
{
	monitor_info_t	*mi;
	Entry		*e, **ep, *e_conn;
	monitor_entry_t	*mp;
	char		buf[ BACKMONITOR_BUFSIZE ];
	struct berval	bv;

	assert( be != NULL );

	ms->mss_update = monitor_subsys_conn_update;
	ms->mss_create = monitor_subsys_conn_create;

	mi = ( monitor_info_t * )be->be_private;

	if ( monitor_cache_get( mi, &ms->mss_ndn, &e_conn ) ) {
		Debug( LDAP_DEBUG_ANY,
			"monitor_subsys_conn_init: "
			"unable to get entry \"%s\"\n",
			ms->mss_ndn.bv_val, 0, 0 );
		return( -1 );
	}

	mp = ( monitor_entry_t * )e_conn->e_private;
	mp->mp_children = NULL;
	ep = &mp->mp_children;

	/*
	 * Max file descriptors
	 */
	BER_BVSTR( &bv, "cn=Max File Descriptors" );
	e = monitor_entry_stub( &ms->mss_dn, &ms->mss_ndn, &bv,
		mi->mi_oc_monitorCounterObject, NULL, NULL );
	
	if ( e == NULL ) {
		Debug( LDAP_DEBUG_ANY,
			"monitor_subsys_conn_init: "
			"unable to create entry \"%s,%s\"\n",
			bv.bv_val, ms->mss_ndn.bv_val, 0 );
		return( -1 );
	}

	if ( dtblsize ) {
		bv.bv_val = buf;
		bv.bv_len = snprintf( buf, sizeof( buf ), "%d", dtblsize );

	} else {
		BER_BVSTR( &bv, "0" );
	}
	attr_merge_one( e, mi->mi_ad_monitorCounter, &bv, NULL );
	
	mp = monitor_entrypriv_create();
	if ( mp == NULL ) {
		return -1;
	}
	e->e_private = ( void * )mp;
	mp->mp_info = ms;
	mp->mp_flags = ms->mss_flags \
		| MONITOR_F_SUB | MONITOR_F_PERSISTENT;
	mp->mp_flags &= ~MONITOR_F_VOLATILE_CH;

	if ( monitor_cache_add( mi, e ) ) {
		Debug( LDAP_DEBUG_ANY,
			"monitor_subsys_conn_init: "
			"unable to add entry \"cn=Total,%s\"\n",
			ms->mss_ndn.bv_val, 0, 0 );
		return( -1 );
	}

	*ep = e;
	ep = &mp->mp_next;
	
	/*
	 * Total conns
	 */
	BER_BVSTR( &bv, "cn=Total" );
	e = monitor_entry_stub( &ms->mss_dn, &ms->mss_ndn, &bv,
		mi->mi_oc_monitorCounterObject, NULL, NULL );
	
	if ( e == NULL ) {
		Debug( LDAP_DEBUG_ANY,
			"monitor_subsys_conn_init: "
			"unable to create entry \"cn=Total,%s\"\n",
			ms->mss_ndn.bv_val, 0, 0 );
		return( -1 );
	}
	
	BER_BVSTR( &bv, "-1" );
	attr_merge_one( e, mi->mi_ad_monitorCounter, &bv, NULL );
	
	mp = monitor_entrypriv_create();
	if ( mp == NULL ) {
		return -1;
	}
	e->e_private = ( void * )mp;
	mp->mp_info = ms;
	mp->mp_flags = ms->mss_flags \
		| MONITOR_F_SUB | MONITOR_F_PERSISTENT;
	mp->mp_flags &= ~MONITOR_F_VOLATILE_CH;

	if ( monitor_cache_add( mi, e ) ) {
		Debug( LDAP_DEBUG_ANY,
			"monitor_subsys_conn_init: "
			"unable to add entry \"cn=Total,%s\"\n",
			ms->mss_ndn.bv_val, 0, 0 );
		return( -1 );
	}

	*ep = e;
	ep = &mp->mp_next;
	
	/*
	 * Current conns
	 */
	BER_BVSTR( &bv, "cn=Current" );
	e = monitor_entry_stub( &ms->mss_dn, &ms->mss_ndn, &bv,
		mi->mi_oc_monitorCounterObject, NULL, NULL );

	if ( e == NULL ) {
		Debug( LDAP_DEBUG_ANY,
			"monitor_subsys_conn_init: "
			"unable to create entry \"cn=Current,%s\"\n",
			ms->mss_ndn.bv_val, 0, 0 );
		return( -1 );
	}
	
	BER_BVSTR( &bv, "0" );
	attr_merge_one( e, mi->mi_ad_monitorCounter, &bv, NULL );
	
	mp = monitor_entrypriv_create();
	if ( mp == NULL ) {
		return -1;
	}
	e->e_private = ( void * )mp;
	mp->mp_info = ms;
	mp->mp_flags = ms->mss_flags \
		| MONITOR_F_SUB | MONITOR_F_PERSISTENT;
	mp->mp_flags &= ~MONITOR_F_VOLATILE_CH;

	if ( monitor_cache_add( mi, e ) ) {
		Debug( LDAP_DEBUG_ANY,
			"monitor_subsys_conn_init: "
			"unable to add entry \"cn=Current,%s\"\n",
			ms->mss_ndn.bv_val, 0, 0 );
		return( -1 );
	}
	
	*ep = e;
	ep = &mp->mp_next;

	monitor_cache_release( mi, e_conn );

	return( 0 );
}
Пример #10
0
int
meta_back_db_open(
	Backend		*be,
	ConfigReply	*cr )
{
	metainfo_t	*mi = (metainfo_t *)be->be_private;

	int		i,
			not_always = 0,
			not_always_anon_proxyauthz = 0,
			not_always_anon_non_prescriptive = 0,
			rc;

	if ( mi->mi_ntargets == 0 ) {
		Debug( LDAP_DEBUG_ANY,
			"meta_back_db_open: no targets defined\n",
			0, 0, 0 );
		return 1;
	}

	for ( i = 0; i < mi->mi_ntargets; i++ ) {
		slap_bindconf	sb = { BER_BVNULL };
		metatarget_t	*mt = mi->mi_targets[ i ];

		struct berval mapped;

		ber_str2bv( mt->mt_uri, 0, 0, &sb.sb_uri );
		sb.sb_version = mt->mt_version;
		sb.sb_method = LDAP_AUTH_SIMPLE;
		BER_BVSTR( &sb.sb_binddn, "" );

		if ( META_BACK_TGT_T_F_DISCOVER( mt ) ) {
			rc = slap_discover_feature( &sb,
					slap_schema.si_ad_supportedFeatures->ad_cname.bv_val,
					LDAP_FEATURE_ABSOLUTE_FILTERS );
			if ( rc == LDAP_COMPARE_TRUE ) {
				mt->mt_flags |= LDAP_BACK_F_T_F;
			}
		}

		if ( META_BACK_TGT_CANCEL_DISCOVER( mt ) ) {
			rc = slap_discover_feature( &sb,
					slap_schema.si_ad_supportedExtension->ad_cname.bv_val,
					LDAP_EXOP_CANCEL );
			if ( rc == LDAP_COMPARE_TRUE ) {
				mt->mt_flags |= LDAP_BACK_F_CANCEL_EXOP;
			}
		}

		if ( not_always == 0 ) {
			if ( !( mt->mt_idassert_flags & LDAP_BACK_AUTH_OVERRIDE )
				|| mt->mt_idassert_authz != NULL )
			{
				not_always = 1;
			}
		}

		if ( ( mt->mt_idassert_flags & LDAP_BACK_AUTH_AUTHZ_ALL )
			&& !( mt->mt_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) )
		{
			Debug( LDAP_DEBUG_ANY, "meta_back_db_open(%s): "
				"target #%d inconsistent idassert configuration "
				"(likely authz=\"*\" used with \"non-prescriptive\" flag)\n",
				be->be_suffix[ 0 ].bv_val, i, 0 );
			return 1;
		}

		if ( not_always_anon_proxyauthz == 0 ) {
			if ( !( mt->mt_idassert_flags & LDAP_BACK_AUTH_AUTHZ_ALL ) )
			{
				not_always_anon_proxyauthz = 1;
			}
		}

		if ( not_always_anon_non_prescriptive == 0 ) {
			if ( ( mt->mt_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) )
			{
				not_always_anon_non_prescriptive = 1;
			}
		}

		BER_BVZERO( &mapped );
		ldap_back_map( &mt->mt_rwmap.rwm_at,
			&slap_schema.si_ad_entryDN->ad_cname, &mapped,
			BACKLDAP_REMAP );
		if ( BER_BVISNULL( &mapped ) || mapped.bv_val[0] == '\0' ) {
			mt->mt_rep_flags |= REP_NO_ENTRYDN;
		}

		BER_BVZERO( &mapped );
		ldap_back_map( &mt->mt_rwmap.rwm_at,
			&slap_schema.si_ad_subschemaSubentry->ad_cname, &mapped,
			BACKLDAP_REMAP );
		if ( BER_BVISNULL( &mapped ) || mapped.bv_val[0] == '\0' ) {
			mt->mt_rep_flags |= REP_NO_SUBSCHEMA;
		}
	}

	if ( not_always == 0 ) {
		mi->mi_flags |= META_BACK_F_PROXYAUTHZ_ALWAYS;
	}

	if ( not_always_anon_proxyauthz == 0 ) {
		mi->mi_flags |= META_BACK_F_PROXYAUTHZ_ANON;

	} else if ( not_always_anon_non_prescriptive == 0 ) {
		mi->mi_flags |= META_BACK_F_PROXYAUTHZ_NOANON;
	}

	return 0;
}
Пример #11
0
int
passwd_back_search(
    Operation	*op,
    SlapReply	*rs )
{
	struct passwd	*pw;
	time_t		stoptime = (time_t)-1;

	LDAPRDN rdn = NULL;
	struct berval parent = BER_BVNULL;

	AttributeDescription *ad_objectClass = slap_schema.si_ad_objectClass;

	if ( op->ors_tlimit != SLAP_NO_LIMIT ) {
		stoptime = op->o_time + op->ors_tlimit;
	}

	/* Handle a query for the base of this backend */
	if ( be_issuffix( op->o_bd, &op->o_req_ndn ) ) {
		struct berval	val;

		rs->sr_matched = op->o_req_dn.bv_val;

		if( op->ors_scope != LDAP_SCOPE_ONELEVEL ) {
			AttributeDescription	*desc = NULL;
			char			*next;
			Entry			e = { 0 };

			/* Create an entry corresponding to the base DN */
			e.e_name.bv_val = ch_strdup( op->o_req_dn.bv_val );
			e.e_name.bv_len = op->o_req_dn.bv_len;
			e.e_nname.bv_val =  ch_strdup( op->o_req_ndn.bv_val );
			e.e_nname.bv_len = op->o_req_ndn.bv_len;

			/* Use the first attribute of the DN
		 	* as an attribute within the entry itself.
		 	*/
			if( ldap_bv2rdn( &op->o_req_dn, &rdn, &next, 
				LDAP_DN_FORMAT_LDAP ) )
			{
				rs->sr_err = LDAP_INVALID_DN_SYNTAX;
				goto done;
			}

			if( slap_bv2ad( &rdn[0]->la_attr, &desc, &rs->sr_text )) {
				rs->sr_err = LDAP_NO_SUCH_OBJECT;
				ldap_rdnfree(rdn);
				goto done;
			}

			attr_merge_normalize_one( &e, desc, &rdn[0]->la_value, NULL );

			ldap_rdnfree(rdn);
			rdn = NULL;

			/* Every entry needs an objectclass. We don't really
			 * know if our hardcoded choice here agrees with the
			 * DN that was configured for this backend, but it's
			 * better than nothing.
			 *
			 * should be a configuratable item
			 */
			BER_BVSTR( &val, "organizationalUnit" );
			attr_merge_one( &e, ad_objectClass, &val, NULL );
	
			if ( test_filter( op, &e, op->ors_filter ) == LDAP_COMPARE_TRUE ) {
				rs->sr_entry = &e;
				rs->sr_attrs = op->ors_attrs;
				rs->sr_flags = REP_ENTRY_MODIFIABLE;
				send_search_entry( op, rs );
			}

			entry_clean( &e );
		}

		if ( op->ors_scope != LDAP_SCOPE_BASE ) {
			/* check all our "children" */

			ldap_pvt_thread_mutex_lock( &passwd_mutex );
			pw_start( op->o_bd );
			for ( pw = getpwent(); pw != NULL; pw = getpwent() ) {
				Entry		e = { 0 };

				/* check for abandon */
				if ( op->o_abandon ) {
					endpwent();
					ldap_pvt_thread_mutex_unlock( &passwd_mutex );
					return( SLAPD_ABANDON );
				}

				/* check time limit */
				if ( op->ors_tlimit != SLAP_NO_LIMIT
						&& slap_get_time() > stoptime )
				{
					send_ldap_error( op, rs, LDAP_TIMELIMIT_EXCEEDED, NULL );
					endpwent();
					ldap_pvt_thread_mutex_unlock( &passwd_mutex );
					return( 0 );
				}

				if ( pw2entry( op->o_bd, pw, &e ) ) {
					rs->sr_err = LDAP_OTHER;
					endpwent();
					ldap_pvt_thread_mutex_unlock( &passwd_mutex );
					goto done;
				}

				if ( test_filter( op, &e, op->ors_filter ) == LDAP_COMPARE_TRUE ) {
					/* check size limit */
					if ( --op->ors_slimit == -1 ) {
						send_ldap_error( op, rs, LDAP_SIZELIMIT_EXCEEDED, NULL );
						endpwent();
						ldap_pvt_thread_mutex_unlock( &passwd_mutex );
						return( 0 );
					}

					rs->sr_entry = &e;
					rs->sr_attrs = op->ors_attrs;
					rs->sr_flags = REP_ENTRY_MODIFIABLE;
					send_search_entry( op, rs );
				}

				entry_clean( &e );
			}
			endpwent();
			ldap_pvt_thread_mutex_unlock( &passwd_mutex );
		}

	} else {
		char	*next;
		Entry	e = { 0 };
		int	rc;

		if (! be_issuffix( op->o_bd, &op->o_req_ndn ) ) {
			dnParent( &op->o_req_ndn, &parent );
		}

		/* This backend is only one layer deep. Don't answer requests for
		 * anything deeper than that.
		 */
		if( !be_issuffix( op->o_bd, &parent ) ) {
			int i;
			for( i=0; op->o_bd->be_nsuffix[i].bv_val != NULL; i++ ) {
				if( dnIsSuffix( &op->o_req_ndn, &op->o_bd->be_nsuffix[i] ) ) {
					rs->sr_matched = op->o_bd->be_suffix[i].bv_val;
					break;
				}
			}
			rs->sr_err = LDAP_NO_SUCH_OBJECT;
			goto done;
		}

		if( op->ors_scope == LDAP_SCOPE_ONELEVEL ) {
			goto done;
		}

		if ( ldap_bv2rdn( &op->o_req_dn, &rdn, &next,
			LDAP_DN_FORMAT_LDAP ))
		{ 
			rs->sr_err = LDAP_OTHER;
			goto done;
		}

		ldap_pvt_thread_mutex_lock( &passwd_mutex );
		pw_start( op->o_bd );
		pw = getpwnam( rdn[0]->la_value.bv_val );
		if ( pw == NULL ) {
			rs->sr_matched = parent.bv_val;
			rs->sr_err = LDAP_NO_SUCH_OBJECT;
			ldap_pvt_thread_mutex_unlock( &passwd_mutex );
			goto done;
		}

		rc = pw2entry( op->o_bd, pw, &e );
		ldap_pvt_thread_mutex_unlock( &passwd_mutex );
		if ( rc ) {
			rs->sr_err = LDAP_OTHER;
			goto done;
		}

		if ( test_filter( op, &e, op->ors_filter ) == LDAP_COMPARE_TRUE ) {
			rs->sr_entry = &e;
			rs->sr_attrs = op->ors_attrs;
			rs->sr_flags = REP_ENTRY_MODIFIABLE;
			send_search_entry( op, rs );
		}

		entry_clean( &e );
	}

done:
	if( rs->sr_err != LDAP_NO_SUCH_OBJECT ) rs->sr_matched = NULL;
	send_ldap_result( op, rs );

	if( rdn != NULL ) ldap_rdnfree( rdn );

	return( 0 );
}
Пример #12
0
static int
pw2entry( Backend *be, struct passwd *pw, Entry *e )
{
	size_t		pwlen;
	struct berval	val;
	struct berval	bv;

	int		rc;

	/*
	 * from pw we get pw_name and make it cn
	 * give it an objectclass of person.
	 */

	pwlen = strlen( pw->pw_name );
	val.bv_len = STRLENOF("uid=,") + ( pwlen + be->be_suffix[0].bv_len );
	val.bv_val = ch_malloc( val.bv_len + 1 );

	/* rdn attribute type should be a configuratable item */
	sprintf( val.bv_val, "uid=%s,%s",
		pw->pw_name, be->be_suffix[0].bv_val );

	rc = dnNormalize( 0, NULL, NULL, &val, &bv, NULL );
	if( rc != LDAP_SUCCESS ) {
		free( val.bv_val );
		return( -1 );
	}

	e->e_name = val;
	e->e_nname = bv;

	e->e_attrs = NULL;

	/* objectclasses should be configurable items */
	BER_BVSTR( &val, "person" );
	attr_merge_one( e, slap_schema.si_ad_objectClass, &val, NULL );

	BER_BVSTR( &val, "uidObject" );
	attr_merge_one( e, slap_schema.si_ad_objectClass, &val, NULL );

	val.bv_val = pw->pw_name;
	val.bv_len = pwlen;
	attr_merge_normalize_one( e, slap_schema.si_ad_uid, &val, NULL );	/* required by uidObject */
	attr_merge_normalize_one( e, slap_schema.si_ad_cn, &val, NULL );	/* required by person */
	attr_merge_normalize_one( e, ad_sn, &val, NULL );	/* required by person */

#ifdef HAVE_STRUCT_PASSWD_PW_GECOS
	/*
	 * if gecos is present, add it as a cn. first process it
	 * according to standard BSD usage. If the processed cn has
	 * a space, use the tail as the surname.
	 */
	if (pw->pw_gecos[0]) {
		char *s;

		ber_str2bv( pw->pw_gecos, 0, 0, &val );
		attr_merge_normalize_one( e, ad_desc, &val, NULL );

		s = ber_bvchr( &val, ',' );
		if ( s ) *s = '\0';

		s = ber_bvchr( &val, '&' );
		if ( s ) {
			char buf[1024];

			if( val.bv_len + pwlen < sizeof(buf) ) {
				int i = s - val.bv_val;
				strncpy( buf, val.bv_val, i );
				s = buf + i;
				strcpy( s, pw->pw_name );
				*s = TOUPPER((unsigned char)*s);
				strcat( s, val.bv_val + i + 1 );
				val.bv_val = buf;
			}
		}
		val.bv_len = strlen( val.bv_val );

		if ( val.bv_len && strcasecmp( val.bv_val, pw->pw_name ) ) {
			attr_merge_normalize_one( e, slap_schema.si_ad_cn, &val, NULL );
		}

		if ( ( s = strrchr(val.bv_val, ' ' ) ) ) {
			ber_str2bv( s + 1, 0, 0, &val );
			attr_merge_normalize_one( e, ad_sn, &val, NULL );
		}
	}
#endif /* HAVE_STRUCT_PASSWD_PW_GECOS */

	return( 0 );
}
Пример #13
0
int
monitor_subsys_time_init(
	BackendDB		*be,
	monitor_subsys_t	*ms )
{
	monitor_info_t	*mi;

	Entry		*e, **ep, *e_time = 0;
	monitor_entry_t	*mp;
	struct berval	bv, value;

	assert( be != NULL );

	ms->mss_update = monitor_subsys_time_update;

	mi = ( monitor_info_t * )be->be_private;

	if ( monitor_cache_get( mi,
			&ms->mss_ndn, &e_time ) ) {
		Debug( LDAP_DEBUG_ANY,
			"monitor_subsys_time_init: "
			"unable to get entry \"%s\"\n",
			ms->mss_ndn.bv_val );
		return -1;
	}

	mp = ( monitor_entry_t * )e_time->e_private;
	mp->mp_children = NULL;
	ep = &mp->mp_children;
	int rc = -1;

	BER_BVSTR( &bv, "cn=Start" );
	e = monitor_entry_stub( &ms->mss_dn, &ms->mss_ndn, &bv,
		mi->mi_oc_monitoredObject, NULL, NULL );
	if ( e == NULL ) {
		Debug( LDAP_DEBUG_ANY,
			"monitor_subsys_time_init: "
			"unable to create entry \"%s,%s\"\n",
			bv.bv_val, ms->mss_ndn.bv_val );
		goto bailout;
	}
	attr_merge_normalize_one( e, mi->mi_ad_monitorTimestamp,
		&mi->mi_startTime, NULL );

	mp = monitor_entrypriv_create();
	if ( mp == NULL ) {
		goto bailout;
	}
	e->e_private = ( void * )mp;
	mp->mp_info = ms;
	mp->mp_flags = ms->mss_flags \
		| MONITOR_F_SUB | MONITOR_F_PERSISTENT;

	if ( monitor_cache_add( mi, e ) ) {
		Debug( LDAP_DEBUG_ANY,
			"monitor_subsys_time_init: "
			"unable to add entry \"%s,%s\"\n",
			bv.bv_val, ms->mss_ndn.bv_val );
		goto bailout;
	}

	*ep = e;
	ep = &mp->mp_next;

	/*
	 * Current
	 */
	BER_BVSTR( &bv, "cn=Current" );
	e = monitor_entry_stub( &ms->mss_dn, &ms->mss_ndn, &bv,
		mi->mi_oc_monitoredObject, NULL, NULL );
	if ( e == NULL ) {
		Debug( LDAP_DEBUG_ANY,
			"monitor_subsys_time_init: "
			"unable to create entry \"%s,%s\"\n",
			bv.bv_val, ms->mss_ndn.bv_val );
		goto bailout;
	}
	attr_merge_normalize_one( e, mi->mi_ad_monitorTimestamp,
		&mi->mi_startTime, NULL );

	mp = monitor_entrypriv_create();
	if ( mp == NULL ) {
		goto bailout;
	}
	e->e_private = ( void * )mp;
	mp->mp_info = ms;
	mp->mp_flags = ms->mss_flags \
		| MONITOR_F_SUB | MONITOR_F_PERSISTENT;

	if ( monitor_cache_add( mi, e ) ) {
		Debug( LDAP_DEBUG_ANY,
			"monitor_subsys_time_init: "
			"unable to add entry \"%s,%s\"\n",
			bv.bv_val, ms->mss_ndn.bv_val );
		goto bailout;
	}

	*ep = e;
	ep = &mp->mp_next;

	/*
	 * Uptime
	 */
	BER_BVSTR( &bv, "cn=Uptime" );
	e = monitor_entry_stub( &ms->mss_dn, &ms->mss_ndn, &bv,
		mi->mi_oc_monitoredObject, NULL, NULL );
	if ( e == NULL ) {
		Debug( LDAP_DEBUG_ANY,
			"monitor_subsys_time_init: "
			"unable to create entry \"%s,%s\"\n",
			bv.bv_val, ms->mss_ndn.bv_val );
		goto bailout;
	}
	BER_BVSTR( &value, "0" );
	attr_merge_normalize_one( e, mi->mi_ad_monitoredInfo,
		&value, NULL );

	mp = monitor_entrypriv_create();
	if ( mp == NULL ) {
		goto bailout;
	}
	e->e_private = ( void * )mp;
	mp->mp_info = ms;
	mp->mp_flags = ms->mss_flags \
		| MONITOR_F_SUB | MONITOR_F_PERSISTENT;

	if ( monitor_cache_add( mi, e ) ) {
		Debug( LDAP_DEBUG_ANY,
			"monitor_subsys_time_init: "
			"unable to add entry \"%s,%s\"\n",
			bv.bv_val, ms->mss_ndn.bv_val );
		goto bailout;
	}

	*ep = e;
	ep = &mp->mp_next;
	rc = 0;

bailout:
	monitor_cache_release( mi, e_time );
	return rc;
}
Пример #14
0
int
fe_op_bind( Operation *op, SlapReply *rs )
{
	BackendDB	*bd = op->o_bd;

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

	if ( op->orb_method == LDAP_AUTH_SASL ) {
		if ( op->o_protocol < LDAP_VERSION3 ) {
			Debug( LDAP_DEBUG_ANY, "do_bind: sasl with LDAPv%ld\n",
				(unsigned long)op->o_protocol, 0, 0 );
			send_ldap_discon( op, rs,
				LDAP_PROTOCOL_ERROR, "SASL bind requires LDAPv3" );
			rs->sr_err = SLAPD_DISCONNECT;
			goto cleanup;
		}

		if( BER_BVISNULL( &op->orb_mech ) || BER_BVISEMPTY( &op->orb_mech ) ) {
			Debug( LDAP_DEBUG_ANY,
				"do_bind: no sasl mechanism provided\n",
				0, 0, 0 );
			send_ldap_error( op, rs, LDAP_AUTH_METHOD_NOT_SUPPORTED,
				"no SASL mechanism provided" );
			goto cleanup;
		}

		/* check restrictions */
		if( backend_check_restrictions( op, rs, &op->orb_mech ) != LDAP_SUCCESS ) {
			send_ldap_result( op, rs );
			goto cleanup;
		}

		ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex );
		if ( op->o_conn->c_sasl_bind_in_progress ) {
			if( !bvmatch( &op->o_conn->c_sasl_bind_mech, &op->orb_mech ) ) {
				/* mechanism changed between bind steps */
				slap_sasl_reset(op->o_conn);
			}
		} else {
			ber_dupbv(&op->o_conn->c_sasl_bind_mech, &op->orb_mech);
		}

		/* Set the bindop for the benefit of in-directory SASL lookups */
		op->o_conn->c_sasl_bindop = op;

		ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );

		rs->sr_err = slap_sasl_bind( op, rs );

		goto cleanup;

	} else {
		/* Not SASL, cancel any in-progress bind */
		ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex );

		if ( !BER_BVISNULL( &op->o_conn->c_sasl_bind_mech ) ) {
			free( op->o_conn->c_sasl_bind_mech.bv_val );
			BER_BVZERO( &op->o_conn->c_sasl_bind_mech );
		}
		op->o_conn->c_sasl_bind_in_progress = 0;

		slap_sasl_reset( op->o_conn );
		ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );
	}

	if ( op->orb_method == LDAP_AUTH_SIMPLE ) {
		BER_BVSTR( &op->orb_mech, "SIMPLE" );
		/* accept "anonymous" binds */
		if ( BER_BVISEMPTY( &op->orb_cred ) || BER_BVISEMPTY( &op->o_req_ndn ) ) {
			rs->sr_err = LDAP_SUCCESS;

			if( !BER_BVISEMPTY( &op->orb_cred ) &&
				!( global_allows & SLAP_ALLOW_BIND_ANON_CRED ))
			{
				/* cred is not empty, disallow */
				rs->sr_err = LDAP_INVALID_CREDENTIALS;

			} else if ( !BER_BVISEMPTY( &op->o_req_ndn ) &&
				!( global_allows & SLAP_ALLOW_BIND_ANON_DN ))
			{
				/* DN is not empty, disallow */
				rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
				rs->sr_text =
					"unauthenticated bind (DN with no password) disallowed";

			} else if ( global_disallows & SLAP_DISALLOW_BIND_ANON ) {
				/* disallow */
				rs->sr_err = LDAP_INAPPROPRIATE_AUTH;
				rs->sr_text = "anonymous bind disallowed";

			} else {
				backend_check_restrictions( op, rs, &op->orb_mech );
			}

			/*
			 * we already forced connection to "anonymous",
			 * just need to send success
			 */
			send_ldap_result( op, rs );
			Debug( LDAP_DEBUG_TRACE, "do_bind: v%d anonymous bind\n",
				op->o_protocol, 0, 0 );
			goto cleanup;

		} else if ( global_disallows & SLAP_DISALLOW_BIND_SIMPLE ) {
			/* disallow simple authentication */
			rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
			rs->sr_text = "unwilling to perform simple authentication";

			send_ldap_result( op, rs );
			Debug( LDAP_DEBUG_TRACE,
				"do_bind: v%d simple bind(%s) disallowed\n",
				op->o_protocol, op->o_req_ndn.bv_val, 0 );
			goto cleanup;
		}

	} else {
		rs->sr_err = LDAP_AUTH_METHOD_NOT_SUPPORTED;
		rs->sr_text = "unknown authentication method";

		send_ldap_result( op, rs );
		Debug( LDAP_DEBUG_TRACE,
			"do_bind: v%d unknown authentication method (%d)\n",
			op->o_protocol, op->orb_method, 0 );
		goto cleanup;
	}

	/*
	 * 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.
	 */

	if ( (op->o_bd = select_backend( &op->o_req_ndn, 0 )) == NULL ) {
		/* don't return referral for bind requests */
		/* noSuchObject is not allowed to be returned by bind */
		rs->sr_err = LDAP_INVALID_CREDENTIALS;
		op->o_bd = bd;
		send_ldap_result( op, rs );
		goto cleanup;
	}

	/* check restrictions */
	if( backend_check_restrictions( op, rs, NULL ) != LDAP_SUCCESS ) {
		send_ldap_result( op, rs );
		goto cleanup;
	}

	if( op->o_bd->be_bind ) {
		op->o_conn->c_authz_cookie = NULL;

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

		if ( rs->sr_err == 0 ) {
			(void)fe_op_bind_success( op, rs );

		} else if ( !BER_BVISNULL( &op->orb_edn ) ) {
			free( op->orb_edn.bv_val );
			BER_BVZERO( &op->orb_edn );
		}

	} else {
		send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
			"operation not supported within naming context" );
	}

cleanup:;
	op->o_bd = bd;
	return rs->sr_err;
}
Пример #15
0
int
monitor_subsys_rww_init(
	BackendDB		*be,
	monitor_subsys_t	*ms )
{
	monitor_info_t	*mi;
	
	Entry		**ep, *e_conn;
	monitor_entry_t	*mp;
	int			i;

	assert( be != NULL );

	ms->mss_destroy = monitor_subsys_rww_destroy;
	ms->mss_update = monitor_subsys_rww_update;

	mi = ( monitor_info_t * )be->be_private;

	if ( monitor_cache_get( mi, &ms->mss_ndn, &e_conn ) ) {
		Debug( LDAP_DEBUG_ANY,
			"monitor_subsys_rww_init: "
			"unable to get entry \"%s\"\n",
			ms->mss_ndn.bv_val, 0, 0 );
		return( -1 );
	}

	mp = ( monitor_entry_t * )e_conn->e_private;
	mp->mp_children = NULL;
	ep = &mp->mp_children;

	for ( i = 0; i < MONITOR_RWW_LAST; i++ ) {
		struct berval		nrdn, bv;
		Entry			*e;
		
		e = monitor_entry_stub( &ms->mss_dn, &ms->mss_ndn, &monitor_rww[i].rdn,
			mi->mi_oc_monitorCounterObject, mi, NULL, NULL );
		if ( e == NULL ) {
			Debug( LDAP_DEBUG_ANY,
				"monitor_subsys_rww_init: "
				"unable to create entry \"cn=Read,%s\"\n",
				ms->mss_ndn.bv_val, 0, 0 );
			return( -1 );
		}

		/* steal normalized RDN */
		dnRdn( &e->e_nname, &nrdn );
		ber_dupbv( &monitor_rww[ i ].nrdn, &nrdn );
	
		BER_BVSTR( &bv, "0" );
		attr_merge_one( e, mi->mi_ad_monitorCounter, &bv, NULL );
	
		mp = monitor_entrypriv_create();
		if ( mp == NULL ) {
			return -1;
		}
		e->e_private = ( void * )mp;
		mp->mp_info = ms;
		mp->mp_flags = ms->mss_flags \
			| MONITOR_F_SUB | MONITOR_F_PERSISTENT;

		if ( monitor_cache_add( mi, e ) ) {
			Debug( LDAP_DEBUG_ANY,
				"monitor_subsys_rww_init: "
				"unable to add entry \"%s,%s\"\n",
				monitor_rww[ i ].rdn.bv_val,
				ms->mss_ndn.bv_val, 0 );
			return( -1 );
		}
	
		*ep = e;
		ep = &mp->mp_next;
	}

	monitor_cache_release( mi, e_conn );

	return( 0 );
}
Пример #16
0
static int
ldap_back_int_filter_map_rewrite(
		dncookie		*dc,
		Filter			*f,
		struct berval	*fstr,
		int				remap,
		void			*memctx )
{
	int		i;
	Filter		*p;
	struct berval	atmp,
			vtmp,
			*tmp;
	static struct berval
			/* better than nothing... */
			ber_bvfalse = BER_BVC( "(!(objectClass=*))" ),
			ber_bvtf_false = BER_BVC( "(|)" ),
			/* better than nothing... */
			ber_bvtrue = BER_BVC( "(objectClass=*)" ),
			ber_bvtf_true = BER_BVC( "(&)" ),
#if 0
			/* no longer needed; preserved for completeness */
			ber_bvundefined = BER_BVC( "(?=undefined)" ),
#endif
			ber_bverror = BER_BVC( "(?=error)" ),
			ber_bvunknown = BER_BVC( "(?=unknown)" ),
			ber_bvnone = BER_BVC( "(?=none)" );
	ber_len_t	len;

	assert( fstr != NULL );
	BER_BVZERO( fstr );

	if ( f == NULL ) {
		ber_dupbv_x( fstr, &ber_bvnone, memctx );
		return LDAP_OTHER;
	}

	switch ( ( f->f_choice & SLAPD_FILTER_MASK ) ) {
	case LDAP_FILTER_EQUALITY:
		if ( map_attr_value( dc, f->f_av_desc, &atmp,
					&f->f_av_value, &vtmp, remap, memctx ) )
		{
			goto computed;
		}

		fstr->bv_len = atmp.bv_len + vtmp.bv_len
			+ ( sizeof("(=)") - 1 );
		fstr->bv_val = ber_memalloc_x( fstr->bv_len + 1, memctx );

		snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=%s)",
			atmp.bv_val, vtmp.bv_len ? vtmp.bv_val : "" );

		ber_memfree_x( vtmp.bv_val, memctx );
		break;

	case LDAP_FILTER_GE:
		if ( map_attr_value( dc, f->f_av_desc, &atmp,
					&f->f_av_value, &vtmp, remap, memctx ) )
		{
			goto computed;
		}

		fstr->bv_len = atmp.bv_len + vtmp.bv_len
			+ ( sizeof("(>=)") - 1 );
		fstr->bv_val = ber_memalloc_x( fstr->bv_len + 1, memctx );

		snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s>=%s)",
			atmp.bv_val, vtmp.bv_len ? vtmp.bv_val : "" );

		ber_memfree_x( vtmp.bv_val, memctx );
		break;

	case LDAP_FILTER_LE:
		if ( map_attr_value( dc, f->f_av_desc, &atmp,
					&f->f_av_value, &vtmp, remap, memctx ) )
		{
			goto computed;
		}

		fstr->bv_len = atmp.bv_len + vtmp.bv_len
			+ ( sizeof("(<=)") - 1 );
		fstr->bv_val = ber_memalloc_x( fstr->bv_len + 1, memctx );

		snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s<=%s)",
			atmp.bv_val, vtmp.bv_len ? vtmp.bv_val : "" );

		ber_memfree_x( vtmp.bv_val, memctx );
		break;

	case LDAP_FILTER_APPROX:
		if ( map_attr_value( dc, f->f_av_desc, &atmp,
					&f->f_av_value, &vtmp, remap, memctx ) )
		{
			goto computed;
		}

		fstr->bv_len = atmp.bv_len + vtmp.bv_len
			+ ( sizeof("(~=)") - 1 );
		fstr->bv_val = ber_memalloc_x( fstr->bv_len + 1, memctx );

		snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s~=%s)",
			atmp.bv_val, vtmp.bv_len ? vtmp.bv_val : "" );

		ber_memfree_x( vtmp.bv_val, memctx );
		break;

	case LDAP_FILTER_SUBSTRINGS:
		if ( map_attr_value( dc, f->f_sub_desc, &atmp,
					NULL, NULL, remap, memctx ) )
		{
			goto computed;
		}

		/* cannot be a DN ... */

		fstr->bv_len = atmp.bv_len + ( STRLENOF( "(=*)" ) );
		fstr->bv_val = ber_memalloc_x( fstr->bv_len + 128, memctx ); /* FIXME: why 128 ? */

		snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=*)",
			atmp.bv_val );

		if ( !BER_BVISNULL( &f->f_sub_initial ) ) {
			len = fstr->bv_len;

			filter_escape_value_x( &f->f_sub_initial, &vtmp, memctx );

			fstr->bv_len += vtmp.bv_len;
			fstr->bv_val = ber_memrealloc_x( fstr->bv_val, fstr->bv_len + 1, memctx );

			snprintf( &fstr->bv_val[len - 2], vtmp.bv_len + 3,
				/* "(attr=" */ "%s*)",
				vtmp.bv_len ? vtmp.bv_val : "" );

			ber_memfree_x( vtmp.bv_val, memctx );
		}

		if ( f->f_sub_any != NULL ) {
			for ( i = 0; !BER_BVISNULL( &f->f_sub_any[i] ); i++ ) {
				len = fstr->bv_len;
				filter_escape_value_x( &f->f_sub_any[i], &vtmp, memctx );

				fstr->bv_len += vtmp.bv_len + 1;
				fstr->bv_val = ber_memrealloc_x( fstr->bv_val, fstr->bv_len + 1, memctx );

				snprintf( &fstr->bv_val[len - 1], vtmp.bv_len + 3,
					/* "(attr=[init]*[any*]" */ "%s*)",
					vtmp.bv_len ? vtmp.bv_val : "" );
				ber_memfree_x( vtmp.bv_val, memctx );
			}
		}

		if ( !BER_BVISNULL( &f->f_sub_final ) ) {
			len = fstr->bv_len;

			filter_escape_value_x( &f->f_sub_final, &vtmp, memctx );

			fstr->bv_len += vtmp.bv_len;
			fstr->bv_val = ber_memrealloc_x( fstr->bv_val, fstr->bv_len + 1, memctx );

			snprintf( &fstr->bv_val[len - 1], vtmp.bv_len + 3,
				/* "(attr=[init*][any*]" */ "%s)",
				vtmp.bv_len ? vtmp.bv_val : "" );

			ber_memfree_x( vtmp.bv_val, memctx );
		}

		break;

	case LDAP_FILTER_PRESENT:
		if ( map_attr_value( dc, f->f_desc, &atmp,
					NULL, NULL, remap, memctx ) )
		{
			goto computed;
		}

		fstr->bv_len = atmp.bv_len + ( STRLENOF( "(=*)" ) );
		fstr->bv_val = ber_memalloc_x( fstr->bv_len + 1, memctx );

		snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=*)",
			atmp.bv_val );
		break;

	case LDAP_FILTER_AND:
	case LDAP_FILTER_OR:
	case LDAP_FILTER_NOT:
		fstr->bv_len = STRLENOF( "(%)" );
		fstr->bv_val = ber_memalloc_x( fstr->bv_len + 128, memctx );	/* FIXME: why 128? */

		snprintf( fstr->bv_val, fstr->bv_len + 1, "(%c)",
			f->f_choice == LDAP_FILTER_AND ? '&' :
			f->f_choice == LDAP_FILTER_OR ? '|' : '!' );

		for ( p = f->f_list; p != NULL; p = p->f_next ) {
			int	rc;

			len = fstr->bv_len;

			rc = ldap_back_int_filter_map_rewrite( dc, p, &vtmp, remap, memctx );
			if ( rc != LDAP_SUCCESS ) {
				return rc;
			}
			
			fstr->bv_len += vtmp.bv_len;
			fstr->bv_val = ber_memrealloc_x( fstr->bv_val, fstr->bv_len + 1, memctx );

			snprintf( &fstr->bv_val[len-1], vtmp.bv_len + 2, 
				/*"("*/ "%s)", vtmp.bv_len ? vtmp.bv_val : "" );

			ber_memfree_x( vtmp.bv_val, memctx );
		}

		break;

	case LDAP_FILTER_EXT:
		if ( f->f_mr_desc ) {
			if ( map_attr_value( dc, f->f_mr_desc, &atmp,
						&f->f_mr_value, &vtmp, remap, memctx ) )
			{
				goto computed;
			}

		} else {
			BER_BVSTR( &atmp, "" );
			filter_escape_value_x( &f->f_mr_value, &vtmp, memctx );
		}

		/* FIXME: cleanup (less ?: operators...) */
		fstr->bv_len = atmp.bv_len +
			( f->f_mr_dnattrs ? STRLENOF( ":dn" ) : 0 ) +
			( !BER_BVISEMPTY( &f->f_mr_rule_text ) ? f->f_mr_rule_text.bv_len + 1 : 0 ) +
			vtmp.bv_len + ( STRLENOF( "(:=)" ) );
		fstr->bv_val = ber_memalloc_x( fstr->bv_len + 1, memctx );

		snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s%s%s%s:=%s)",
			atmp.bv_val,
			f->f_mr_dnattrs ? ":dn" : "",
			!BER_BVISEMPTY( &f->f_mr_rule_text ) ? ":" : "",
			!BER_BVISEMPTY( &f->f_mr_rule_text ) ? f->f_mr_rule_text.bv_val : "",
			vtmp.bv_len ? vtmp.bv_val : "" );
		ber_memfree_x( vtmp.bv_val, memctx );
		break;

	case SLAPD_FILTER_COMPUTED:
		switch ( f->f_result ) {
		/* FIXME: treat UNDEFINED as FALSE */
		case SLAPD_COMPARE_UNDEFINED:
computed:;
			if ( META_BACK_TGT_NOUNDEFFILTER( dc->target ) ) {
				return LDAP_COMPARE_FALSE;
			}
			/* fallthru */

		case LDAP_COMPARE_FALSE:
			if ( META_BACK_TGT_T_F( dc->target ) ) {
				tmp = &ber_bvtf_false;
				break;
			}
			tmp = &ber_bvfalse;
			break;

		case LDAP_COMPARE_TRUE:
			if ( META_BACK_TGT_T_F( dc->target ) ) {
				tmp = &ber_bvtf_true;
				break;
			}

			tmp = &ber_bvtrue;
			break;

		default:
			tmp = &ber_bverror;
			break;
		}

		ber_dupbv_x( fstr, tmp, memctx );
		break;

	default:
		ber_dupbv_x( fstr, &ber_bvunknown, memctx );
		break;
	}

	return 0;
}
Пример #17
0
static int
dynlist_prepare_entry( Operation *op, SlapReply *rs, dynlist_info_t *dli )
{
	Attribute	*a, *id = NULL;
	slap_callback	cb;
	Operation	o = *op;
	SlapReply	r = { REP_SEARCH };
	struct berval	*url;
	Entry		*e;
	slap_mask_t	e_flags;
	int		opattrs,
			userattrs;
	dynlist_sc_t	dlc = { 0 };
	dynlist_map_t	*dlm;

	a = attrs_find( rs->sr_entry->e_attrs, dli->dli_ad );
	if ( a == NULL ) {
		/* FIXME: error? */
		return SLAP_CB_CONTINUE;
	}

#ifndef SLAP_OPATTRS
	opattrs = ( rs->sr_attrs == NULL ) ? 0 : an_find( rs->sr_attrs, &AllOper );
	userattrs = ( rs->sr_attrs == NULL ) ? 1 : an_find( rs->sr_attrs, &AllUser );
#else /* SLAP_OPATTRS */
	opattrs = SLAP_OPATTRS( rs->sr_attr_flags );
	userattrs = SLAP_USERATTRS( rs->sr_attr_flags );
#endif /* SLAP_OPATTRS */

	/* Don't generate member list if it wasn't requested */
	for ( dlm = dli->dli_dlm; dlm; dlm = dlm->dlm_next ) {
		if ( userattrs ||
		     ad_inlist( dlm->dlm_member_ad, rs->sr_attrs ) ) 
			break;
	}
	if ( dli->dli_dlm && !dlm )
		return SLAP_CB_CONTINUE;

	if ( ad_dgIdentity && ( id = attrs_find( rs->sr_entry->e_attrs, ad_dgIdentity ))) {
		Attribute *authz = NULL;

		/* if not rootdn and dgAuthz is present,
		 * check if user can be authorized as dgIdentity */
		if ( ad_dgAuthz && !BER_BVISEMPTY( &id->a_nvals[0] ) && !be_isroot( op )
			&& ( authz = attrs_find( rs->sr_entry->e_attrs, ad_dgAuthz ) ) )
		{
			if ( slap_sasl_matches( op, authz->a_nvals,
				&o.o_ndn, &o.o_ndn ) != LDAP_SUCCESS )
			{
				return SLAP_CB_CONTINUE;
			}
		}

		o.o_dn = id->a_vals[0];
		o.o_ndn = id->a_nvals[0];
		o.o_groups = NULL;
	}

	if ( !( rs->sr_flags & REP_ENTRY_MODIFIABLE ) ) {
		e = entry_dup( rs->sr_entry );
	} else {
		e = rs->sr_entry;
	}
	e_flags = rs->sr_flags | ( REP_ENTRY_MODIFIABLE | REP_ENTRY_MUSTBEFREED );

	dlc.dlc_e = e;
	dlc.dlc_dli = dli;
	cb.sc_private = &dlc;
	cb.sc_response = dynlist_sc_update;
	cb.sc_cleanup = NULL;
	cb.sc_next = NULL;

	o.o_callback = &cb;
	o.ors_deref = LDAP_DEREF_NEVER;
	o.ors_limit = NULL;
	o.ors_tlimit = SLAP_NO_LIMIT;
	o.ors_slimit = SLAP_NO_LIMIT;

	for ( url = a->a_nvals; !BER_BVISNULL( url ); url++ ) {
		LDAPURLDesc	*lud = NULL;
		int		i, j;
		struct berval	dn;
		int		rc;
		dynlist_map_t	*dlm;

		BER_BVZERO( &o.o_req_dn );
		BER_BVZERO( &o.o_req_ndn );
		o.ors_filter = NULL;
		o.ors_attrs = NULL;
		BER_BVZERO( &o.ors_filterstr );

		if ( ldap_url_parse( url->bv_val, &lud ) != LDAP_URL_SUCCESS ) {
			/* FIXME: error? */
			continue;
		}

		if ( lud->lud_host != NULL ) {
			/* FIXME: host not allowed; reject as illegal? */
			Debug( LDAP_DEBUG_ANY, "dynlist_prepare_entry(\"%s\"): "
				"illegal URI \"%s\"\n",
				e->e_name.bv_val, url->bv_val, 0 );
			goto cleanup;
		}

		if ( lud->lud_dn == NULL ) {
			/* note that an empty base is not honored in terms
			 * of defaultSearchBase, because select_backend()
			 * is not aware of the defaultSearchBase option;
			 * this can be useful in case of a database serving
			 * the empty suffix */
			BER_BVSTR( &dn, "" );

		} else {
			ber_str2bv( lud->lud_dn, 0, 0, &dn );
		}
		rc = dnPrettyNormal( NULL, &dn, &o.o_req_dn, &o.o_req_ndn, op->o_tmpmemctx );
		if ( rc != LDAP_SUCCESS ) {
			/* FIXME: error? */
			goto cleanup;
		}
		o.ors_scope = lud->lud_scope;

		for ( dlm = dli->dli_dlm; dlm; dlm = dlm->dlm_next ) {
			if ( dlm->dlm_mapped_ad != NULL ) {
				break;
			}
		}

		if ( dli->dli_dlm && !dlm ) {
			/* if ( lud->lud_attrs != NULL ),
			 * the URL should be ignored */
			o.ors_attrs = slap_anlist_no_attrs;

		} else if ( lud->lud_attrs == NULL ) {
			o.ors_attrs = rs->sr_attrs;

		} else {
			for ( i = 0; lud->lud_attrs[i]; i++)
				/* just count */ ;

			o.ors_attrs = op->o_tmpcalloc( i + 1, sizeof( AttributeName ), op->o_tmpmemctx );
			for ( i = 0, j = 0; lud->lud_attrs[i]; i++) {
				const char	*text = NULL;
	
				ber_str2bv( lud->lud_attrs[i], 0, 0, &o.ors_attrs[j].an_name );
				o.ors_attrs[j].an_desc = NULL;
				(void)slap_bv2ad( &o.ors_attrs[j].an_name, &o.ors_attrs[j].an_desc, &text );
				/* FIXME: ignore errors... */

				if ( rs->sr_attrs == NULL ) {
					if ( o.ors_attrs[j].an_desc != NULL &&
							is_at_operational( o.ors_attrs[j].an_desc->ad_type ) )
					{
						continue;
					}

				} else {
					if ( o.ors_attrs[j].an_desc != NULL &&
							is_at_operational( o.ors_attrs[j].an_desc->ad_type ) )
					{
						if ( !opattrs && !ad_inlist( o.ors_attrs[j].an_desc, rs->sr_attrs ) )
						{
							continue;
						}

					} else {
						if ( !userattrs && 
								o.ors_attrs[j].an_desc != NULL &&
								!ad_inlist( o.ors_attrs[j].an_desc, rs->sr_attrs ) )
						{
							continue;
						}
					}
				}

				j++;
			}

			if ( j == 0 ) {
				goto cleanup;
			}
		
			BER_BVZERO( &o.ors_attrs[j].an_name );
		}

		if ( lud->lud_filter == NULL ) {
			ber_dupbv_x( &o.ors_filterstr,
					&dli->dli_default_filter, op->o_tmpmemctx );

		} else {
			struct berval	flt;
			ber_str2bv( lud->lud_filter, 0, 0, &flt );
			if ( dynlist_make_filter( op, &flt, &o.ors_filterstr ) ) {
				/* error */
				goto cleanup;
			}
		}
		o.ors_filter = str2filter_x( op, o.ors_filterstr.bv_val );
		if ( o.ors_filter == NULL ) {
			goto cleanup;
		}
		
		o.o_bd = select_backend( &o.o_req_ndn, 1 );
		if ( o.o_bd && o.o_bd->be_search ) {
#ifdef SLAP_OPATTRS
			r.sr_attr_flags = slap_attr_flags( o.ors_attrs );
#endif /* SLAP_OPATTRS */
			(void)o.o_bd->be_search( &o, &r );
		}

cleanup:;
		if ( id ) {
			slap_op_groups_free( &o );
		}
		if ( o.ors_filter ) {
			filter_free_x( &o, o.ors_filter );
		}
		if ( o.ors_attrs && o.ors_attrs != rs->sr_attrs
				&& o.ors_attrs != slap_anlist_no_attrs )
		{
			op->o_tmpfree( o.ors_attrs, op->o_tmpmemctx );
		}
		if ( !BER_BVISNULL( &o.o_req_dn ) ) {
			op->o_tmpfree( o.o_req_dn.bv_val, op->o_tmpmemctx );
		}
		if ( !BER_BVISNULL( &o.o_req_ndn ) ) {
			op->o_tmpfree( o.o_req_ndn.bv_val, op->o_tmpmemctx );
		}
		assert( BER_BVISNULL( &o.ors_filterstr )
			|| o.ors_filterstr.bv_val != lud->lud_filter );
		op->o_tmpfree( o.ors_filterstr.bv_val, op->o_tmpmemctx );
		ldap_free_urldesc( lud );
	}

	rs->sr_entry = e;
	rs->sr_flags = e_flags;

	return SLAP_CB_CONTINUE;
}
Пример #18
0
/* Called for all modify and modrdn ops. If the current op was replicated
 * from elsewhere, all of the attrs should already be present.
 */
void slap_mods_opattrs(
	Operation *op,
	Modifications **modsp,
	int manage_ctxcsn )
{
	struct berval name, timestamp, csn = BER_BVNULL;
	struct berval nname;
	char timebuf[ LDAP_LUTIL_GENTIME_BUFSIZE ];
	char csnbuf[ LDAP_LUTIL_CSNSTR_BUFSIZE ];
	Modifications *mod, **modtail, *modlast;
	int gotcsn = 0, gotmname = 0, gotmtime = 0;

	if ( SLAP_LASTMOD( op->o_bd ) && !op->orm_no_opattrs ) {
		char *ptr;
		timestamp.bv_val = timebuf;
		for ( modtail = modsp; *modtail; modtail = &(*modtail)->sml_next ) {
			if ( (*modtail)->sml_op != LDAP_MOD_ADD &&
				(*modtail)->sml_op != SLAP_MOD_SOFTADD &&
				(*modtail)->sml_op != LDAP_MOD_REPLACE )
			{
				continue;
			}

			if ( (*modtail)->sml_desc == slap_schema.si_ad_entryCSN )
			{
				csn = (*modtail)->sml_values[0];
				gotcsn = 1;

			} else if ( (*modtail)->sml_desc == slap_schema.si_ad_modifiersName )
			{
				gotmname = 1;

			} else if ( (*modtail)->sml_desc == slap_schema.si_ad_modifyTimestamp )
			{
				gotmtime = 1;
			}
		}

		if ( BER_BVISEMPTY( &op->o_csn )) {
			if ( !gotcsn ) {
				csn.bv_val = csnbuf;
				csn.bv_len = sizeof( csnbuf );
				slap_get_csn( op, &csn, manage_ctxcsn );

			} else {
				if ( manage_ctxcsn ) {
					slap_queue_csn( op, &csn );
				}
			}

		} else {
			csn = op->o_csn;
		}

		ptr = ber_bvchr( &csn, '#' );
		if ( ptr ) {
			timestamp.bv_len = STRLENOF("YYYYMMDDHHMMSSZ");
			AC_MEMCPY( timebuf, csn.bv_val, timestamp.bv_len );
			timebuf[timestamp.bv_len-1] = 'Z';
			timebuf[timestamp.bv_len] = '\0';

		} else {
			time_t now = slap_get_time();

			timestamp.bv_len = sizeof(timebuf);

			slap_timestamp( &now, &timestamp );
		}

		if ( BER_BVISEMPTY( &op->o_dn ) ) {
			BER_BVSTR( &name, SLAPD_ANONYMOUS );
			nname = name;

		} else {
			name = op->o_dn;
			nname = op->o_ndn;
		}

		if ( !gotcsn ) {
			mod = (Modifications *) ch_malloc( sizeof( Modifications ) );
			mod->sml_op = LDAP_MOD_REPLACE;
			mod->sml_flags = SLAP_MOD_INTERNAL;
			mod->sml_next = NULL;
			BER_BVZERO( &mod->sml_type );
			mod->sml_desc = slap_schema.si_ad_entryCSN;
			mod->sml_numvals = 1;
			mod->sml_values = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
			ber_dupbv( &mod->sml_values[0], &csn );
			BER_BVZERO( &mod->sml_values[1] );
			assert( !BER_BVISNULL( &mod->sml_values[0] ) );
			mod->sml_nvalues = NULL;
			*modtail = mod;
			modlast = mod;
			modtail = &mod->sml_next;
		}

		if ( !gotmname ) {
			mod = (Modifications *) ch_malloc( sizeof( Modifications ) );
			mod->sml_op = LDAP_MOD_REPLACE;
			mod->sml_flags = SLAP_MOD_INTERNAL;
			mod->sml_next = NULL;
			BER_BVZERO( &mod->sml_type );
			mod->sml_desc = slap_schema.si_ad_modifiersName;
			mod->sml_numvals = 1;
			mod->sml_values = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
			ber_dupbv( &mod->sml_values[0], &name );
			BER_BVZERO( &mod->sml_values[1] );
			assert( !BER_BVISNULL( &mod->sml_values[0] ) );
			mod->sml_nvalues =
				(BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
			ber_dupbv( &mod->sml_nvalues[0], &nname );
			BER_BVZERO( &mod->sml_nvalues[1] );
			assert( !BER_BVISNULL( &mod->sml_nvalues[0] ) );
			*modtail = mod;
			modtail = &mod->sml_next;
		}

		if ( !gotmtime ) {
			mod = (Modifications *) ch_malloc( sizeof( Modifications ) );
			mod->sml_op = LDAP_MOD_REPLACE;
			mod->sml_flags = SLAP_MOD_INTERNAL;
			mod->sml_next = NULL;
			BER_BVZERO( &mod->sml_type );
			mod->sml_desc = slap_schema.si_ad_modifyTimestamp;
			mod->sml_numvals = 1;
			mod->sml_values = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
			ber_dupbv( &mod->sml_values[0], &timestamp );
			BER_BVZERO( &mod->sml_values[1] );
			assert( !BER_BVISNULL( &mod->sml_values[0] ) );
			mod->sml_nvalues = NULL;
			*modtail = mod;
			modtail = &mod->sml_next;
		}
	}
}
Пример #19
0
static int
retcode_db_open( BackendDB *be, ConfigReply *cr)
{
	slap_overinst	*on = (slap_overinst *)be->bd_info;
	retcode_t	*rd = (retcode_t *)on->on_bi.bi_private;

	retcode_item_t	*rdi;

	for ( rdi = rd->rd_item; rdi; rdi = rdi->rdi_next ) {
		LDAPRDN			rdn = NULL;
		int			rc, j;
		char*			p;
		struct berval		val[ 3 ];
		char			buf[ SLAP_TEXT_BUFLEN ];

		/* DN */
		rdi->rdi_e.e_name = rdi->rdi_dn;
		rdi->rdi_e.e_nname = rdi->rdi_ndn;

		/* objectClass */
		val[ 0 ] = oc_errObject->soc_cname;
		val[ 1 ] = slap_schema.si_oc_extensibleObject->soc_cname;
		BER_BVZERO( &val[ 2 ] );

		attr_merge( &rdi->rdi_e, slap_schema.si_ad_objectClass, val, NULL );

		/* RDN avas */
		rc = ldap_bv2rdn( &rdi->rdi_dn, &rdn, (char **) &p,
				LDAP_DN_FORMAT_LDAP );

		assert( rc == LDAP_SUCCESS );

		for ( j = 0; rdn[ j ]; j++ ) {
			LDAPAVA			*ava = rdn[ j ];
			AttributeDescription	*ad = NULL;
			const char		*text;

			rc = slap_bv2ad( &ava->la_attr, &ad, &text );
			assert( rc == LDAP_SUCCESS );
			
			attr_merge_normalize_one( &rdi->rdi_e, ad,
					&ava->la_value, NULL );
		}

		ldap_rdnfree( rdn );

		/* error code */
		snprintf( buf, sizeof( buf ), "%d", rdi->rdi_err );
		ber_str2bv( buf, 0, 0, &val[ 0 ] );

		attr_merge_one( &rdi->rdi_e, ad_errCode, &val[ 0 ], NULL );

		if ( rdi->rdi_ref != NULL ) {
			attr_merge_normalize( &rdi->rdi_e, slap_schema.si_ad_ref,
				rdi->rdi_ref, NULL );
		}

		/* text */
		if ( !BER_BVISNULL( &rdi->rdi_text ) ) {
			val[ 0 ] = rdi->rdi_text;

			attr_merge_normalize_one( &rdi->rdi_e, ad_errText, &val[ 0 ], NULL );
		}

		/* matched */
		if ( !BER_BVISNULL( &rdi->rdi_matched ) ) {
			val[ 0 ] = rdi->rdi_matched;

			attr_merge_normalize_one( &rdi->rdi_e, ad_errMatchedDN, &val[ 0 ], NULL );
		}

		/* sleep time */
		if ( rdi->rdi_sleeptime ) {
			snprintf( buf, sizeof( buf ), "%d", rdi->rdi_sleeptime );
			ber_str2bv( buf, 0, 0, &val[ 0 ] );

			attr_merge_one( &rdi->rdi_e, ad_errSleepTime, &val[ 0 ], NULL );
		}

		/* operations */
		if ( rdi->rdi_mask & SN_DG_OP_ADD ) {
			BER_BVSTR( &val[ 0 ], "add" );
			attr_merge_normalize_one( &rdi->rdi_e, ad_errOp, &val[ 0 ], NULL );
		}

		if ( rdi->rdi_mask & SN_DG_OP_BIND ) {
			BER_BVSTR( &val[ 0 ], "bind" );
			attr_merge_normalize_one( &rdi->rdi_e, ad_errOp, &val[ 0 ], NULL );
		}

		if ( rdi->rdi_mask & SN_DG_OP_COMPARE ) {
			BER_BVSTR( &val[ 0 ], "compare" );
			attr_merge_normalize_one( &rdi->rdi_e, ad_errOp, &val[ 0 ], NULL );
		}

		if ( rdi->rdi_mask & SN_DG_OP_DELETE ) {
			BER_BVSTR( &val[ 0 ], "delete" );
			attr_merge_normalize_one( &rdi->rdi_e, ad_errOp, &val[ 0 ], NULL );
		}

		if ( rdi->rdi_mask & SN_DG_EXTENDED ) {
			BER_BVSTR( &val[ 0 ], "extended" );
			attr_merge_normalize_one( &rdi->rdi_e, ad_errOp, &val[ 0 ], NULL );
		}

		if ( rdi->rdi_mask & SN_DG_OP_MODIFY ) {
			BER_BVSTR( &val[ 0 ], "modify" );
			attr_merge_normalize_one( &rdi->rdi_e, ad_errOp, &val[ 0 ], NULL );
		}

		if ( rdi->rdi_mask & SN_DG_OP_RENAME ) {
			BER_BVSTR( &val[ 0 ], "rename" );
			attr_merge_normalize_one( &rdi->rdi_e, ad_errOp, &val[ 0 ], NULL );
		}

		if ( rdi->rdi_mask & SN_DG_OP_SEARCH ) {
			BER_BVSTR( &val[ 0 ], "search" );
			attr_merge_normalize_one( &rdi->rdi_e, ad_errOp, &val[ 0 ], NULL );
		}
	}

	return 0;
}