oidm.c revision 1.1.1.5
1/* $NetBSD: oidm.c,v 1.1.1.5 2017/02/09 01:46:58 christos Exp $ */ 2 3/* oidm.c - object identifier macro routines */ 4/* $OpenLDAP$ */ 5/* This work is part of OpenLDAP Software <http://www.openldap.org/>. 6 * 7 * Copyright 1998-2016 The OpenLDAP Foundation. 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted only as authorized by the OpenLDAP 12 * Public License. 13 * 14 * A copy of this license is available in the file LICENSE in the 15 * top-level directory of the distribution or, alternatively, at 16 * <http://www.OpenLDAP.org/license.html>. 17 */ 18 19#include <sys/cdefs.h> 20__RCSID("$NetBSD: oidm.c,v 1.1.1.5 2017/02/09 01:46:58 christos Exp $"); 21 22#include "portable.h" 23 24#include <stdio.h> 25 26#include <ac/ctype.h> 27#include <ac/string.h> 28#include <ac/socket.h> 29 30#include "slap.h" 31#include "lutil.h" 32#include "config.h" 33 34static LDAP_STAILQ_HEAD(OidMacroList, OidMacro) om_list 35 = LDAP_STAILQ_HEAD_INITIALIZER(om_list); 36 37OidMacro *om_sys_tail; 38 39/* Replace an OID Macro invocation with its full numeric OID. 40 * If the macro is used with "macroname:suffix" append ".suffix" 41 * to the expansion. 42 */ 43char * 44oidm_find(char *oid) 45{ 46 OidMacro *om; 47 48 /* OID macros must start alpha */ 49 if ( OID_LEADCHAR( *oid ) ) { 50 return oid; 51 } 52 53 LDAP_STAILQ_FOREACH( om, &om_list, som_next ) { 54 BerVarray names = om->som_names; 55 56 if( names == NULL ) { 57 continue; 58 } 59 60 for( ; !BER_BVISNULL( names ) ; names++ ) { 61 int pos = dscompare(names->bv_val, oid, ':'); 62 63 if( pos ) { 64 int suflen = strlen(oid + pos); 65 char *tmp = SLAP_MALLOC( om->som_oid.bv_len 66 + suflen + 1); 67 if( tmp == NULL ) { 68 Debug( LDAP_DEBUG_ANY, 69 "oidm_find: SLAP_MALLOC failed", 0, 0, 0 ); 70 return NULL; 71 } 72 strcpy(tmp, om->som_oid.bv_val); 73 if( suflen ) { 74 suflen = om->som_oid.bv_len; 75 tmp[suflen++] = '.'; 76 strcpy(tmp+suflen, oid+pos+1); 77 } 78 return tmp; 79 } 80 } 81 } 82 return NULL; 83} 84 85void 86oidm_destroy() 87{ 88 OidMacro *om; 89 while( !LDAP_STAILQ_EMPTY( &om_list )) { 90 om = LDAP_STAILQ_FIRST( &om_list ); 91 LDAP_STAILQ_REMOVE_HEAD( &om_list, som_next ); 92 93 ber_bvarray_free(om->som_names); 94 ber_bvarray_free(om->som_subs); 95 free(om->som_oid.bv_val); 96 free(om); 97 98 } 99} 100 101int 102parse_oidm( 103 struct config_args_s *c, 104 int user, 105 OidMacro **rom) 106{ 107 char *oid, *oidv; 108 OidMacro *om = NULL, *prev = NULL; 109 struct berval bv; 110 111 oidv = oidm_find( c->argv[2] ); 112 if( !oidv ) { 113 snprintf( c->cr_msg, sizeof( c->cr_msg ), 114 "%s: OID %s not recognized", 115 c->argv[0], c->argv[2] ); 116 Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE, 117 "%s %s\n", c->log, c->cr_msg, 0 ); 118 return 1; 119 } 120 121 oid = oidm_find( c->argv[1] ); 122 if( oid != NULL ) { 123 int rc; 124 snprintf( c->cr_msg, sizeof( c->cr_msg ), 125 "%s: \"%s\" previously defined \"%s\"", 126 c->argv[0], c->argv[1], oid ); 127 Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE, 128 "%s %s\n", c->log, c->cr_msg, 0 ); 129 /* Allow duplicate if the definition is identical */ 130 rc = strcmp( oid, oidv ) != 0; 131 SLAP_FREE( oid ); 132 if ( oidv != c->argv[2] ) 133 SLAP_FREE( oidv ); 134 return rc; 135 } 136 137 om = (OidMacro *) SLAP_CALLOC( sizeof(OidMacro), 1 ); 138 if( om == NULL ) { 139 snprintf( c->cr_msg, sizeof( c->cr_msg ), 140 "%s: SLAP_CALLOC failed", c->argv[0] ); 141 Debug( LDAP_DEBUG_ANY, 142 "%s %s\n", c->log, c->cr_msg, 0 ); 143 if ( oidv != c->argv[2] ) 144 SLAP_FREE( oidv ); 145 return 1; 146 } 147 148 om->som_names = NULL; 149 om->som_subs = NULL; 150 ber_str2bv( c->argv[1], 0, 1, &bv ); 151 ber_bvarray_add( &om->som_names, &bv ); 152 ber_str2bv( c->argv[2], 0, 1, &bv ); 153 ber_bvarray_add( &om->som_subs, &bv ); 154 om->som_oid.bv_val = oidv; 155 156 if (om->som_oid.bv_val == c->argv[2]) { 157 om->som_oid.bv_val = ch_strdup( c->argv[2] ); 158 } 159 160 om->som_oid.bv_len = strlen( om->som_oid.bv_val ); 161 if ( !user ) { 162 om->som_flags |= SLAP_OM_HARDCODE; 163 prev = om_sys_tail; 164 om_sys_tail = om; 165 } 166 167 if ( prev ) { 168 LDAP_STAILQ_INSERT_AFTER( &om_list, prev, om, som_next ); 169 } else { 170 LDAP_STAILQ_INSERT_TAIL( &om_list, om, som_next ); 171 } 172 if ( rom ) *rom = om; 173 return 0; 174} 175 176void oidm_unparse( BerVarray *res, OidMacro *start, OidMacro *end, int sys ) 177{ 178 OidMacro *om; 179 int i, j, num; 180 struct berval *bva = NULL, idx; 181 char ibuf[32], *ptr; 182 183 if ( !start ) 184 start = LDAP_STAILQ_FIRST( &om_list ); 185 186 /* count the result size */ 187 i = 0; 188 for ( om=start; om; om=LDAP_STAILQ_NEXT(om, som_next)) { 189 if ( sys && !(om->som_flags & SLAP_OM_HARDCODE)) break; 190 for ( j=0; !BER_BVISNULL(&om->som_names[j]); j++ ); 191 i += j; 192 if ( om == end ) break; 193 } 194 num = i; 195 if (!i) return; 196 197 bva = ch_malloc( (num+1) * sizeof(struct berval) ); 198 BER_BVZERO( bva+num ); 199 idx.bv_val = ibuf; 200 if ( sys ) { 201 idx.bv_len = 0; 202 ibuf[0] = '\0'; 203 } 204 for ( i=0,om=start; om; om=LDAP_STAILQ_NEXT(om, som_next)) { 205 if ( sys && !(om->som_flags & SLAP_OM_HARDCODE)) break; 206 for ( j=0; !BER_BVISNULL(&om->som_names[j]); i++,j++ ) { 207 if ( !sys ) { 208 idx.bv_len = sprintf(idx.bv_val, "{%d}", i ); 209 } 210 bva[i].bv_len = idx.bv_len + om->som_names[j].bv_len + 211 om->som_subs[j].bv_len + 1; 212 bva[i].bv_val = ch_malloc( bva[i].bv_len + 1 ); 213 ptr = lutil_strcopy( bva[i].bv_val, ibuf ); 214 ptr = lutil_strcopy( ptr, om->som_names[j].bv_val ); 215 *ptr++ = ' '; 216 strcpy( ptr, om->som_subs[j].bv_val ); 217 } 218 if ( i>=num ) break; 219 if ( om == end ) break; 220 } 221 *res = bva; 222} 223