]> git.sur5r.net Git - openldap/blob - servers/slapd/oidm.c
ITS#8616 don't check for existing value when deleting values
[openldap] / servers / slapd / oidm.c
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-2018 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
29 static LDAP_STAILQ_HEAD(OidMacroList, OidMacro) om_list
30         = LDAP_STAILQ_HEAD_INITIALIZER(om_list);
31
32 OidMacro *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  */
38 char *
39 oidm_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
80 void
81 oidm_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
96 int
97 parse_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
171 void 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 }