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