Skip to content
Snippets Groups Projects
oidm.c 5.02 KiB
Newer Older
  • Learn to ignore specific revisions
  • Kurt Zeilenga's avatar
    Kurt Zeilenga committed
    /* oidm.c - object identifier macro routines */
    
    Kurt Zeilenga's avatar
    Kurt Zeilenga committed
    /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
     *
    
    Kurt Zeilenga's avatar
    Kurt Zeilenga committed
     * Copyright 1998-2014 The OpenLDAP Foundation.
    
    Kurt Zeilenga's avatar
    Kurt Zeilenga committed
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted only as authorized by the OpenLDAP
     * Public License.
     *
     * A copy of this license is available in the file LICENSE in the
     * top-level directory of the distribution or, alternatively, at
     * <http://www.OpenLDAP.org/license.html>.
    
     */
    
    #include "portable.h"
    
    #include <stdio.h>
    
    #include <ac/ctype.h>
    #include <ac/string.h>
    #include <ac/socket.h>
    
    #include "slap.h"
    
    Howard Chu's avatar
    Howard Chu committed
    #include "lutil.h"
    
    static LDAP_STAILQ_HEAD(OidMacroList, OidMacro) om_list
    
    Howard Chu's avatar
    Howard Chu committed
    	= LDAP_STAILQ_HEAD_INITIALIZER(om_list);
    
    /* Replace an OID Macro invocation with its full numeric OID.
     * If the macro is used with "macroname:suffix" append ".suffix"
     * to the expansion.
     */
    char *
    oidm_find(char *oid)
    {
    	OidMacro *om;
    
    	/* OID macros must start alpha */
    	if ( OID_LEADCHAR( *oid ) )	{
    		return oid;
    	}
    
    
    Howard Chu's avatar
    Howard Chu committed
    	LDAP_STAILQ_FOREACH( om, &om_list, som_next ) {
    
    Howard Chu's avatar
    Howard Chu committed
    		BerVarray names = om->som_names;
    
    Howard Chu's avatar
    Howard Chu committed
    		for( ; !BER_BVISNULL( names ) ; names++ ) {
    			int pos = dscompare(names->bv_val, oid, ':');
    
    
    			if( pos ) {
    				int suflen = strlen(oid + pos);
    
    Julius Enarusai's avatar
     
    Julius Enarusai committed
    				char *tmp = SLAP_MALLOC( om->som_oid.bv_len
    
    Julius Enarusai's avatar
     
    Julius Enarusai committed
    				if( tmp == NULL ) {
    					Debug( LDAP_DEBUG_ANY,
    						"oidm_find: SLAP_MALLOC failed", 0, 0, 0 );
    					return NULL;
    				}
    
    				strcpy(tmp, om->som_oid.bv_val);
    				if( suflen ) {
    					suflen = om->som_oid.bv_len;
    					tmp[suflen++] = '.';
    					strcpy(tmp+suflen, oid+pos+1);
    				}
    				return tmp;
    			}
    		}
    	}
    	return NULL;
    }
    
    void
    oidm_destroy()
    {
    
    	OidMacro *om;
    
    Howard Chu's avatar
    Howard Chu committed
    	while( !LDAP_STAILQ_EMPTY( &om_list )) {
    		om = LDAP_STAILQ_FIRST( &om_list );
    		LDAP_STAILQ_REMOVE_HEAD( &om_list, som_next );
    
    Howard Chu's avatar
    Howard Chu committed
    		ber_bvarray_free(om->som_names);
    		ber_bvarray_free(om->som_subs);
    
    		free(om->som_oid.bv_val);
    		free(om);
    
    Howard Chu's avatar
    Howard Chu committed
    	int		user,
    	OidMacro **rom)
    
    	OidMacro *om = NULL, *prev = NULL;
    
    Howard Chu's avatar
    Howard Chu committed
    	struct berval bv;
    
    	oidv = oidm_find( c->argv[2] );
    	if( !oidv ) {
    
    		snprintf( c->cr_msg, sizeof( c->cr_msg ),
    
    			"%s: OID %s not recognized",
    			c->argv[0], c->argv[2] );
    		Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
    
    			"%s %s\n", c->log, c->cr_msg, 0 );
    
    		snprintf( c->cr_msg, sizeof( c->cr_msg ),
    
    			"%s: \"%s\" previously defined \"%s\"",
    			c->argv[0], c->argv[1], oid );
    		Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
    
    			"%s %s\n", c->log, c->cr_msg, 0 );
    
    		/* Allow duplicate if the definition is identical */
    		rc = strcmp( oid, oidv ) != 0;
    
    Howard Chu's avatar
    Howard Chu committed
    		SLAP_FREE( oid );
    
    		if ( oidv != c->argv[2] )
    			SLAP_FREE( oidv );
    		return rc;
    
    	om = (OidMacro *) SLAP_CALLOC( sizeof(OidMacro), 1 );
    
    Julius Enarusai's avatar
     
    Julius Enarusai committed
    	if( om == NULL ) {
    
    		snprintf( c->cr_msg, sizeof( c->cr_msg ),
    
    			"%s: SLAP_CALLOC failed", c->argv[0] );
    		Debug( LDAP_DEBUG_ANY,
    
    			"%s %s\n", c->log, c->cr_msg, 0 );
    
    		if ( oidv != c->argv[2] )
    			SLAP_FREE( oidv );
    
    Julius Enarusai's avatar
     
    Julius Enarusai committed
    		return 1;
    	}
    
    Howard Chu's avatar
    Howard Chu committed
    	om->som_subs = NULL;
    
    	ber_str2bv( c->argv[1], 0, 1, &bv );
    
    Howard Chu's avatar
    Howard Chu committed
    	ber_bvarray_add( &om->som_names, &bv );
    
    	ber_str2bv( c->argv[2], 0, 1, &bv );
    
    Howard Chu's avatar
    Howard Chu committed
    	ber_bvarray_add( &om->som_subs, &bv );
    
    	if (om->som_oid.bv_val == c->argv[2]) {
    		om->som_oid.bv_val = ch_strdup( c->argv[2] );
    
    	}
    
    	om->som_oid.bv_len = strlen( om->som_oid.bv_val );
    
    	if ( !user ) {
    
    Howard Chu's avatar
    Howard Chu committed
    		om->som_flags |= SLAP_OM_HARDCODE;
    
    		prev = om_sys_tail;
    
    	if ( prev ) {
    		LDAP_STAILQ_INSERT_AFTER( &om_list, prev, om, som_next );
    	} else {
    		LDAP_STAILQ_INSERT_TAIL( &om_list, om, som_next );
    	}
    
    Howard Chu's avatar
    Howard Chu committed
    	if ( rom ) *rom = om;
    
    Howard Chu's avatar
    Howard Chu committed
    
    
    Howard Chu's avatar
    Howard Chu committed
    void oidm_unparse( BerVarray *res, OidMacro *start, OidMacro *end, int sys )
    
    Howard Chu's avatar
    Howard Chu committed
    {
    	OidMacro *om;
    	int i, j, num;
    
    	struct berval *bva = NULL, idx;
    
    Howard Chu's avatar
    Howard Chu committed
    	char ibuf[32], *ptr;
    
    
    Howard Chu's avatar
    Howard Chu committed
    	if ( !start )
    		start = LDAP_STAILQ_FIRST( &om_list );
    
    
    Howard Chu's avatar
    Howard Chu committed
    	/* count the result size */
    	i = 0;
    
    	for ( om=start; om; om=LDAP_STAILQ_NEXT(om, som_next)) {
    
    		if ( sys && !(om->som_flags & SLAP_OM_HARDCODE)) break;
    
    Howard Chu's avatar
    Howard Chu committed
    		for ( j=0; !BER_BVISNULL(&om->som_names[j]); j++ );
    		i += j;
    
    		if ( om == end ) break;
    
    Howard Chu's avatar
    Howard Chu committed
    	}
    	num = i;
    
    Howard Chu's avatar
    Howard Chu committed
    	if (!i) return;
    
    
    Howard Chu's avatar
    Howard Chu committed
    	bva = ch_malloc( (num+1) * sizeof(struct berval) );
    	BER_BVZERO( bva+num );
    	idx.bv_val = ibuf;
    
    Howard Chu's avatar
    Howard Chu committed
    	if ( sys ) {
    		idx.bv_len = 0;
    		ibuf[0] = '\0';
    	}
    
    	for ( i=0,om=start; om; om=LDAP_STAILQ_NEXT(om, som_next)) {
    
    		if ( sys && !(om->som_flags & SLAP_OM_HARDCODE)) break;
    
    Howard Chu's avatar
    Howard Chu committed
    		for ( j=0; !BER_BVISNULL(&om->som_names[j]); i++,j++ ) {
    			if ( !sys ) {
    
    				idx.bv_len = sprintf(idx.bv_val, "{%d}", i );
    
    Howard Chu's avatar
    Howard Chu committed
    			}
    
    Howard Chu's avatar
    Howard Chu committed
    			bva[i].bv_len = idx.bv_len + om->som_names[j].bv_len +
    				om->som_subs[j].bv_len + 1;
    			bva[i].bv_val = ch_malloc( bva[i].bv_len + 1 );
    			ptr = lutil_strcopy( bva[i].bv_val, ibuf );
    			ptr = lutil_strcopy( ptr, om->som_names[j].bv_val );
    			*ptr++ = ' ';
    
    Howard Chu's avatar
    Howard Chu committed
    			strcpy( ptr, om->som_subs[j].bv_val );
    
    Howard Chu's avatar
    Howard Chu committed
    		}
    
    Howard Chu's avatar
    Howard Chu committed
    		if ( i>=num ) break;
    
    		if ( om == end ) break;
    
    Howard Chu's avatar
    Howard Chu committed
    	}
    	*res = bva;
    }