Back to index

openldap  2.4.31
oidm.c
Go to the documentation of this file.
00001 /* oidm.c - object identifier macro routines */
00002 /* $OpenLDAP$ */
00003 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
00004  *
00005  * Copyright 1998-2012 The OpenLDAP Foundation.
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted only as authorized by the OpenLDAP
00010  * Public License.
00011  *
00012  * A copy of this license is available in the file LICENSE in the
00013  * top-level directory of the distribution or, alternatively, at
00014  * <http://www.OpenLDAP.org/license.html>.
00015  */
00016 
00017 #include "portable.h"
00018 
00019 #include <stdio.h>
00020 
00021 #include <ac/ctype.h>
00022 #include <ac/string.h>
00023 #include <ac/socket.h>
00024 
00025 #include "slap.h"
00026 #include "lutil.h"
00027 #include "config.h"
00028 
00029 static LDAP_STAILQ_HEAD(OidMacroList, OidMacro) om_list
00030        = LDAP_STAILQ_HEAD_INITIALIZER(om_list);
00031 
00032 OidMacro *om_sys_tail;
00033 
00034 /* Replace an OID Macro invocation with its full numeric OID.
00035  * If the macro is used with "macroname:suffix" append ".suffix"
00036  * to the expansion.
00037  */
00038 char *
00039 oidm_find(char *oid)
00040 {
00041        OidMacro *om;
00042 
00043        /* OID macros must start alpha */
00044        if ( OID_LEADCHAR( *oid ) ) {
00045               return oid;
00046        }
00047 
00048        LDAP_STAILQ_FOREACH( om, &om_list, som_next ) {
00049               BerVarray names = om->som_names;
00050 
00051               if( names == NULL ) {
00052                      continue;
00053               }
00054 
00055               for( ; !BER_BVISNULL( names ) ; names++ ) {
00056                      int pos = dscompare(names->bv_val, oid, ':');
00057 
00058                      if( pos ) {
00059                             int suflen = strlen(oid + pos);
00060                             char *tmp = SLAP_MALLOC( om->som_oid.bv_len
00061                                    + suflen + 1);
00062                             if( tmp == NULL ) {
00063                                    Debug( LDAP_DEBUG_ANY,
00064                                           "oidm_find: SLAP_MALLOC failed", 0, 0, 0 );
00065                                    return NULL;
00066                             }
00067                             strcpy(tmp, om->som_oid.bv_val);
00068                             if( suflen ) {
00069                                    suflen = om->som_oid.bv_len;
00070                                    tmp[suflen++] = '.';
00071                                    strcpy(tmp+suflen, oid+pos+1);
00072                             }
00073                             return tmp;
00074                      }
00075               }
00076        }
00077        return NULL;
00078 }
00079 
00080 void
00081 oidm_destroy()
00082 {
00083        OidMacro *om;
00084        while( !LDAP_STAILQ_EMPTY( &om_list )) {
00085               om = LDAP_STAILQ_FIRST( &om_list );
00086               LDAP_STAILQ_REMOVE_HEAD( &om_list, som_next );
00087 
00088               ber_bvarray_free(om->som_names);
00089               ber_bvarray_free(om->som_subs);
00090               free(om->som_oid.bv_val);
00091               free(om);
00092               
00093        }
00094 }
00095 
00096 int
00097 parse_oidm(
00098        struct config_args_s *c,
00099        int           user,
00100        OidMacro **rom)
00101 {
00102        char *oid, *oidv;
00103        OidMacro *om = NULL, *prev = NULL;
00104        struct berval bv;
00105 
00106        oidv = oidm_find( c->argv[2] );
00107        if( !oidv ) {
00108               snprintf( c->cr_msg, sizeof( c->cr_msg ),
00109                      "%s: OID %s not recognized",
00110                      c->argv[0], c->argv[2] );
00111               Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
00112                      "%s %s\n", c->log, c->cr_msg, 0 );
00113               return 1;
00114        }
00115 
00116        oid = oidm_find( c->argv[1] );
00117        if( oid != NULL ) {
00118               int rc;
00119               snprintf( c->cr_msg, sizeof( c->cr_msg ),
00120                      "%s: \"%s\" previously defined \"%s\"",
00121                      c->argv[0], c->argv[1], oid );
00122               Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
00123                      "%s %s\n", c->log, c->cr_msg, 0 );
00124               /* Allow duplicate if the definition is identical */
00125               rc = strcmp( oid, oidv ) != 0;
00126               SLAP_FREE( oid );
00127               if ( oidv != c->argv[2] )
00128                      SLAP_FREE( oidv );
00129               return rc;
00130        }
00131 
00132        om = (OidMacro *) SLAP_CALLOC( sizeof(OidMacro), 1 );
00133        if( om == NULL ) {
00134               snprintf( c->cr_msg, sizeof( c->cr_msg ),
00135                      "%s: SLAP_CALLOC failed", c->argv[0] );
00136               Debug( LDAP_DEBUG_ANY,
00137                      "%s %s\n", c->log, c->cr_msg, 0 );
00138               if ( oidv != c->argv[2] )
00139                      SLAP_FREE( oidv );
00140               return 1;
00141        }
00142 
00143        om->som_names = NULL;
00144        om->som_subs = NULL;
00145        ber_str2bv( c->argv[1], 0, 1, &bv );
00146        ber_bvarray_add( &om->som_names, &bv );
00147        ber_str2bv( c->argv[2], 0, 1, &bv );
00148        ber_bvarray_add( &om->som_subs, &bv );
00149        om->som_oid.bv_val = oidv;
00150 
00151        if (om->som_oid.bv_val == c->argv[2]) {
00152               om->som_oid.bv_val = ch_strdup( c->argv[2] );
00153        }
00154 
00155        om->som_oid.bv_len = strlen( om->som_oid.bv_val );
00156        if ( !user ) {
00157               om->som_flags |= SLAP_OM_HARDCODE;
00158               prev = om_sys_tail;
00159               om_sys_tail = om;
00160        }
00161 
00162        if ( prev ) {
00163               LDAP_STAILQ_INSERT_AFTER( &om_list, prev, om, som_next );
00164        } else {
00165               LDAP_STAILQ_INSERT_TAIL( &om_list, om, som_next );
00166        }
00167        if ( rom ) *rom = om;
00168        return 0;
00169 }
00170 
00171 void oidm_unparse( BerVarray *res, OidMacro *start, OidMacro *end, int sys )
00172 {
00173        OidMacro *om;
00174        int i, j, num;
00175        struct berval *bva = NULL, idx;
00176        char ibuf[32], *ptr;
00177 
00178        if ( !start )
00179               start = LDAP_STAILQ_FIRST( &om_list );
00180 
00181        /* count the result size */
00182        i = 0;
00183        for ( om=start; om; om=LDAP_STAILQ_NEXT(om, som_next)) {
00184               if ( sys && !(om->som_flags & SLAP_OM_HARDCODE)) break;
00185               for ( j=0; !BER_BVISNULL(&om->som_names[j]); j++ );
00186               i += j;
00187               if ( om == end ) break;
00188        }
00189        num = i;
00190        if (!i) return;
00191 
00192        bva = ch_malloc( (num+1) * sizeof(struct berval) );
00193        BER_BVZERO( bva+num );
00194        idx.bv_val = ibuf;
00195        if ( sys ) {
00196               idx.bv_len = 0;
00197               ibuf[0] = '\0';
00198        }
00199        for ( i=0,om=start; om; om=LDAP_STAILQ_NEXT(om, som_next)) {
00200               if ( sys && !(om->som_flags & SLAP_OM_HARDCODE)) break;
00201               for ( j=0; !BER_BVISNULL(&om->som_names[j]); i++,j++ ) {
00202                      if ( !sys ) {
00203                             idx.bv_len = sprintf(idx.bv_val, "{%d}", i );
00204                      }
00205                      bva[i].bv_len = idx.bv_len + om->som_names[j].bv_len +
00206                             om->som_subs[j].bv_len + 1;
00207                      bva[i].bv_val = ch_malloc( bva[i].bv_len + 1 );
00208                      ptr = lutil_strcopy( bva[i].bv_val, ibuf );
00209                      ptr = lutil_strcopy( ptr, om->som_names[j].bv_val );
00210                      *ptr++ = ' ';
00211                      strcpy( ptr, om->som_subs[j].bv_val );
00212               }
00213               if ( i>=num ) break;
00214               if ( om == end ) break;
00215        }
00216        *res = bva;
00217 }