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