xref: /netbsd-src/external/bsd/openldap/dist/servers/slapd/oidm.c (revision 549b59ed3ccf0d36d3097190a0db27b770f3a839)
1*549b59edSchristos /*	$NetBSD: oidm.c,v 1.3 2021/08/14 16:14:58 christos Exp $	*/
24e6df137Slukem 
32de962bdSlukem /* oidm.c - object identifier macro routines */
4d11b170bStron /* $OpenLDAP$ */
52de962bdSlukem /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
62de962bdSlukem  *
7*549b59edSchristos  * Copyright 1998-2021 The OpenLDAP Foundation.
82de962bdSlukem  * All rights reserved.
92de962bdSlukem  *
102de962bdSlukem  * Redistribution and use in source and binary forms, with or without
112de962bdSlukem  * modification, are permitted only as authorized by the OpenLDAP
122de962bdSlukem  * Public License.
132de962bdSlukem  *
142de962bdSlukem  * A copy of this license is available in the file LICENSE in the
152de962bdSlukem  * top-level directory of the distribution or, alternatively, at
162de962bdSlukem  * <http://www.OpenLDAP.org/license.html>.
172de962bdSlukem  */
182de962bdSlukem 
19376af7d7Schristos #include <sys/cdefs.h>
20*549b59edSchristos __RCSID("$NetBSD: oidm.c,v 1.3 2021/08/14 16:14:58 christos Exp $");
21376af7d7Schristos 
222de962bdSlukem #include "portable.h"
232de962bdSlukem 
242de962bdSlukem #include <stdio.h>
252de962bdSlukem 
262de962bdSlukem #include <ac/ctype.h>
272de962bdSlukem #include <ac/string.h>
282de962bdSlukem #include <ac/socket.h>
292de962bdSlukem 
302de962bdSlukem #include "slap.h"
312de962bdSlukem #include "lutil.h"
32*549b59edSchristos #include "slap-config.h"
332de962bdSlukem 
342de962bdSlukem static LDAP_STAILQ_HEAD(OidMacroList, OidMacro) om_list
352de962bdSlukem 	= LDAP_STAILQ_HEAD_INITIALIZER(om_list);
362de962bdSlukem 
372de962bdSlukem OidMacro *om_sys_tail;
382de962bdSlukem 
392de962bdSlukem /* Replace an OID Macro invocation with its full numeric OID.
402de962bdSlukem  * If the macro is used with "macroname:suffix" append ".suffix"
412de962bdSlukem  * to the expansion.
422de962bdSlukem  */
432de962bdSlukem char *
oidm_find(char * oid)442de962bdSlukem oidm_find(char *oid)
452de962bdSlukem {
462de962bdSlukem 	OidMacro *om;
472de962bdSlukem 
482de962bdSlukem 	/* OID macros must start alpha */
492de962bdSlukem 	if ( OID_LEADCHAR( *oid ) )	{
502de962bdSlukem 		return oid;
512de962bdSlukem 	}
522de962bdSlukem 
532de962bdSlukem 	LDAP_STAILQ_FOREACH( om, &om_list, som_next ) {
542de962bdSlukem 		BerVarray names = om->som_names;
552de962bdSlukem 
562de962bdSlukem 		if( names == NULL ) {
572de962bdSlukem 			continue;
582de962bdSlukem 		}
592de962bdSlukem 
602de962bdSlukem 		for( ; !BER_BVISNULL( names ) ; names++ ) {
612de962bdSlukem 			int pos = dscompare(names->bv_val, oid, ':');
622de962bdSlukem 
632de962bdSlukem 			if( pos ) {
642de962bdSlukem 				int suflen = strlen(oid + pos);
652de962bdSlukem 				char *tmp = SLAP_MALLOC( om->som_oid.bv_len
662de962bdSlukem 					+ suflen + 1);
672de962bdSlukem 				if( tmp == NULL ) {
682de962bdSlukem 					Debug( LDAP_DEBUG_ANY,
69*549b59edSchristos 						"oidm_find: SLAP_MALLOC failed" );
702de962bdSlukem 					return NULL;
712de962bdSlukem 				}
722de962bdSlukem 				strcpy(tmp, om->som_oid.bv_val);
732de962bdSlukem 				if( suflen ) {
742de962bdSlukem 					suflen = om->som_oid.bv_len;
752de962bdSlukem 					tmp[suflen++] = '.';
762de962bdSlukem 					strcpy(tmp+suflen, oid+pos+1);
772de962bdSlukem 				}
782de962bdSlukem 				return tmp;
792de962bdSlukem 			}
802de962bdSlukem 		}
812de962bdSlukem 	}
822de962bdSlukem 	return NULL;
832de962bdSlukem }
842de962bdSlukem 
852de962bdSlukem void
oidm_destroy()862de962bdSlukem oidm_destroy()
872de962bdSlukem {
882de962bdSlukem 	OidMacro *om;
892de962bdSlukem 	while( !LDAP_STAILQ_EMPTY( &om_list )) {
902de962bdSlukem 		om = LDAP_STAILQ_FIRST( &om_list );
912de962bdSlukem 		LDAP_STAILQ_REMOVE_HEAD( &om_list, som_next );
922de962bdSlukem 
932de962bdSlukem 		ber_bvarray_free(om->som_names);
942de962bdSlukem 		ber_bvarray_free(om->som_subs);
952de962bdSlukem 		free(om->som_oid.bv_val);
962de962bdSlukem 		free(om);
972de962bdSlukem 
982de962bdSlukem 	}
992de962bdSlukem }
1002de962bdSlukem 
1012de962bdSlukem int
parse_oidm(struct config_args_s * c,int user,OidMacro ** rom)1022de962bdSlukem parse_oidm(
1032de962bdSlukem 	struct config_args_s *c,
1042de962bdSlukem 	int		user,
1052de962bdSlukem 	OidMacro **rom)
1062de962bdSlukem {
1072de962bdSlukem 	char *oid, *oidv;
1082de962bdSlukem 	OidMacro *om = NULL, *prev = NULL;
1092de962bdSlukem 	struct berval bv;
1102de962bdSlukem 
1112de962bdSlukem 	oidv = oidm_find( c->argv[2] );
1122de962bdSlukem 	if( !oidv ) {
1132de962bdSlukem 		snprintf( c->cr_msg, sizeof( c->cr_msg ),
1142de962bdSlukem 			"%s: OID %s not recognized",
1152de962bdSlukem 			c->argv[0], c->argv[2] );
1162de962bdSlukem 		Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
117*549b59edSchristos 			"%s %s\n", c->log, c->cr_msg );
1182de962bdSlukem 		return 1;
1192de962bdSlukem 	}
1202de962bdSlukem 
1212de962bdSlukem 	oid = oidm_find( c->argv[1] );
1222de962bdSlukem 	if( oid != NULL ) {
1232de962bdSlukem 		int rc;
1242de962bdSlukem 		snprintf( c->cr_msg, sizeof( c->cr_msg ),
1252de962bdSlukem 			"%s: \"%s\" previously defined \"%s\"",
1262de962bdSlukem 			c->argv[0], c->argv[1], oid );
1272de962bdSlukem 		Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
128*549b59edSchristos 			"%s %s\n", c->log, c->cr_msg );
1292de962bdSlukem 		/* Allow duplicate if the definition is identical */
1302de962bdSlukem 		rc = strcmp( oid, oidv ) != 0;
1312de962bdSlukem 		SLAP_FREE( oid );
1322de962bdSlukem 		if ( oidv != c->argv[2] )
1332de962bdSlukem 			SLAP_FREE( oidv );
1342de962bdSlukem 		return rc;
1352de962bdSlukem 	}
1362de962bdSlukem 
1372de962bdSlukem 	om = (OidMacro *) SLAP_CALLOC( sizeof(OidMacro), 1 );
1382de962bdSlukem 	if( om == NULL ) {
1392de962bdSlukem 		snprintf( c->cr_msg, sizeof( c->cr_msg ),
1402de962bdSlukem 			"%s: SLAP_CALLOC failed", c->argv[0] );
1412de962bdSlukem 		Debug( LDAP_DEBUG_ANY,
142*549b59edSchristos 			"%s %s\n", c->log, c->cr_msg );
1432de962bdSlukem 		if ( oidv != c->argv[2] )
1442de962bdSlukem 			SLAP_FREE( oidv );
1452de962bdSlukem 		return 1;
1462de962bdSlukem 	}
1472de962bdSlukem 
1482de962bdSlukem 	om->som_names = NULL;
1492de962bdSlukem 	om->som_subs = NULL;
1502de962bdSlukem 	ber_str2bv( c->argv[1], 0, 1, &bv );
1512de962bdSlukem 	ber_bvarray_add( &om->som_names, &bv );
1522de962bdSlukem 	ber_str2bv( c->argv[2], 0, 1, &bv );
1532de962bdSlukem 	ber_bvarray_add( &om->som_subs, &bv );
1542de962bdSlukem 	om->som_oid.bv_val = oidv;
1552de962bdSlukem 
1562de962bdSlukem 	if (om->som_oid.bv_val == c->argv[2]) {
1572de962bdSlukem 		om->som_oid.bv_val = ch_strdup( c->argv[2] );
1582de962bdSlukem 	}
1592de962bdSlukem 
1602de962bdSlukem 	om->som_oid.bv_len = strlen( om->som_oid.bv_val );
1612de962bdSlukem 	if ( !user ) {
1622de962bdSlukem 		om->som_flags |= SLAP_OM_HARDCODE;
1632de962bdSlukem 		prev = om_sys_tail;
1642de962bdSlukem 		om_sys_tail = om;
1652de962bdSlukem 	}
1662de962bdSlukem 
1672de962bdSlukem 	if ( prev ) {
1682de962bdSlukem 		LDAP_STAILQ_INSERT_AFTER( &om_list, prev, om, som_next );
1692de962bdSlukem 	} else {
1702de962bdSlukem 		LDAP_STAILQ_INSERT_TAIL( &om_list, om, som_next );
1712de962bdSlukem 	}
1722de962bdSlukem 	if ( rom ) *rom = om;
1732de962bdSlukem 	return 0;
1742de962bdSlukem }
1752de962bdSlukem 
oidm_unparse(BerVarray * res,OidMacro * start,OidMacro * end,int sys)1762de962bdSlukem void oidm_unparse( BerVarray *res, OidMacro *start, OidMacro *end, int sys )
1772de962bdSlukem {
1782de962bdSlukem 	OidMacro *om;
1792de962bdSlukem 	int i, j, num;
1802de962bdSlukem 	struct berval *bva = NULL, idx;
1812de962bdSlukem 	char ibuf[32], *ptr;
1822de962bdSlukem 
1832de962bdSlukem 	if ( !start )
1842de962bdSlukem 		start = LDAP_STAILQ_FIRST( &om_list );
1852de962bdSlukem 
1862de962bdSlukem 	/* count the result size */
1872de962bdSlukem 	i = 0;
1882de962bdSlukem 	for ( om=start; om; om=LDAP_STAILQ_NEXT(om, som_next)) {
1892de962bdSlukem 		if ( sys && !(om->som_flags & SLAP_OM_HARDCODE)) break;
1902de962bdSlukem 		for ( j=0; !BER_BVISNULL(&om->som_names[j]); j++ );
1912de962bdSlukem 		i += j;
1922de962bdSlukem 		if ( om == end ) break;
1932de962bdSlukem 	}
1942de962bdSlukem 	num = i;
1952de962bdSlukem 	if (!i) return;
1962de962bdSlukem 
1972de962bdSlukem 	bva = ch_malloc( (num+1) * sizeof(struct berval) );
1982de962bdSlukem 	BER_BVZERO( bva+num );
1992de962bdSlukem 	idx.bv_val = ibuf;
2002de962bdSlukem 	if ( sys ) {
2012de962bdSlukem 		idx.bv_len = 0;
2022de962bdSlukem 		ibuf[0] = '\0';
2032de962bdSlukem 	}
2042de962bdSlukem 	for ( i=0,om=start; om; om=LDAP_STAILQ_NEXT(om, som_next)) {
2052de962bdSlukem 		if ( sys && !(om->som_flags & SLAP_OM_HARDCODE)) break;
2062de962bdSlukem 		for ( j=0; !BER_BVISNULL(&om->som_names[j]); i++,j++ ) {
2072de962bdSlukem 			if ( !sys ) {
2082de962bdSlukem 				idx.bv_len = sprintf(idx.bv_val, "{%d}", i );
2092de962bdSlukem 			}
2102de962bdSlukem 			bva[i].bv_len = idx.bv_len + om->som_names[j].bv_len +
2112de962bdSlukem 				om->som_subs[j].bv_len + 1;
2122de962bdSlukem 			bva[i].bv_val = ch_malloc( bva[i].bv_len + 1 );
2132de962bdSlukem 			ptr = lutil_strcopy( bva[i].bv_val, ibuf );
2142de962bdSlukem 			ptr = lutil_strcopy( ptr, om->som_names[j].bv_val );
2152de962bdSlukem 			*ptr++ = ' ';
2162de962bdSlukem 			strcpy( ptr, om->som_subs[j].bv_val );
2172de962bdSlukem 		}
2182de962bdSlukem 		if ( i>=num ) break;
2192de962bdSlukem 		if ( om == end ) break;
2202de962bdSlukem 	}
2212de962bdSlukem 	*res = bva;
2222de962bdSlukem }
223