1 /* $NetBSD: oidm.c,v 1.3 2021/08/14 16:14: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-2021 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.3 2021/08/14 16:14: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 "slap-config.h"
33
34 static LDAP_STAILQ_HEAD(OidMacroList, OidMacro) om_list
35 = LDAP_STAILQ_HEAD_INITIALIZER(om_list);
36
37 OidMacro *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 */
43 char *
oidm_find(char * oid)44 oidm_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" );
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
85 void
oidm_destroy()86 oidm_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
101 int
parse_oidm(struct config_args_s * c,int user,OidMacro ** rom)102 parse_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 );
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 );
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 );
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
oidm_unparse(BerVarray * res,OidMacro * start,OidMacro * end,int sys)176 void 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