1 #pragma ident "%Z%%M% %I% %E% SMI"
2
3 /*
4 * kadmin/ldap_util/kdb5_ldap_list.c
5 */
6
7 /* Copyright (c) 2004-2005, Novell, Inc.
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions are met:
12 *
13 * * Redistributions of source code must retain the above copyright notice,
14 * this list of conditions and the following disclaimer.
15 * * Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * * The copyright holder's name is not used to endorse or promote products
19 * derived from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 /*
35 * Miscellaneous functions for managing the string and integer lists
36 */
37
38 #include <k5-int.h>
39 #include "kdb5_ldap_list.h"
40
41 /*
42 * Counts the number of entries in the given array of strings
43 */
list_count_str_array(char ** list)44 int list_count_str_array(char **list)
45 {
46 int i = 0;
47
48 if (list == NULL)
49 return 0;
50
51 for (i = 0; *list != NULL; list++) {
52 i++;
53 }
54
55 return i;
56 }
57
58
59 /*
60 * Counts the number of entries in the given array of integers
61 */
list_count_int_array(int * list)62 int list_count_int_array(int *list)
63 {
64 int i = 0;
65
66 if (list == NULL)
67 return 0;
68
69 for (i = 0; *list != END_OF_LIST; list++) {
70 i++;
71 }
72
73 return i;
74 }
75
76
77 /*
78 * Frees the entries in a given list and not the list pointer
79 */
krb5_free_list_entries(list)80 void krb5_free_list_entries(list)
81 char **list;
82 {
83 if (list == NULL)
84 return;
85 for (; *list != NULL; list++) {
86 free(*list);
87 *list = NULL;
88 }
89
90 return;
91 }
92
93
94 /*
95 * Tokenize the given string based on the delimiter provided
96 * and return the result as a list
97 */
98 krb5_error_code
krb5_parse_list(buffer,delimiter,list)99 krb5_parse_list(buffer, delimiter, list)
100 char *buffer;
101 char *delimiter;
102 char **list;
103 {
104 char *str = NULL;
105 char *token = NULL;
106 char *ptrptr = NULL;
107 char **plist = list;
108 krb5_error_code retval = 0;
109 int count = 0;
110
111 if ((buffer == NULL) || (list == NULL) || (delimiter == NULL)) {
112 return EINVAL;
113 }
114
115 str = strdup(buffer);
116 if (str == NULL)
117 return ENOMEM;
118
119 token = strtok_r(str, delimiter, &ptrptr);
120 for (count = 1; ((token != NULL) && (count < MAX_LIST_ENTRIES));
121 plist++, count++) {
122 *plist = strdup(token);
123 if (*plist == NULL) {
124 retval = ENOMEM;
125 goto cleanup;
126 }
127 token = strtok_r(NULL, delimiter, &ptrptr);
128 }
129 *plist = NULL;
130
131 cleanup:
132 if (str) {
133 free(str);
134 str = NULL;
135 }
136 if (retval)
137 krb5_free_list_entries(list);
138
139 return retval;
140 }
141
142
compare_int(m1,m2)143 int compare_int(m1, m2)
144 const void *m1;
145 const void *m2;
146 {
147 int mi1 = *(const int *)m1;
148 int mi2 = *(const int *)m2;
149
150 return (mi1 - mi2);
151 }
152
153
154 /*
155 * Modifies the destination list to contain or not to contain the
156 * entries present in the source list, depending on the mode
157 * (ADD or DELETE).
158 */
list_modify_str_array(destlist,sourcelist,mode)159 void list_modify_str_array(destlist, sourcelist, mode)
160 char ***destlist;
161 const char **sourcelist;
162 int mode;
163 {
164 char **dlist = NULL, **tmplist = NULL;
165 const char **slist = NULL;
166 int dcount = 0, scount = 0, copycount = 0;
167 int found = 0;
168
169 if ((destlist == NULL) || (*destlist == NULL) || (sourcelist == NULL))
170 return;
171
172 /* We need to add every entry present in the source list to
173 * the destination list */
174 if (mode == LIST_MODE_ADD) {
175 /* Traverse throught the end of destlist for appending */
176 for (dlist = *destlist, dcount = 0; *dlist != NULL;
177 dlist++, dcount++) {
178 ; /* NULL statement */
179 }
180 /* Count the number of entries in the source list */
181 for (slist = sourcelist, scount = 0; *slist != NULL;
182 slist++, scount++) {
183 ; /* NULL statement */
184 }
185 /* Reset the slist pointer to the start of source list */
186 slist = sourcelist;
187
188 /* Now append the source list to the existing destlist */
189 if ((dcount + scount) < MAX_LIST_ENTRIES)
190 copycount = scount;
191 else
192 /* Leave the last entry for list terminator(=NULL) */
193 copycount = (MAX_LIST_ENTRIES -1) - dcount;
194
195 memcpy(dlist, slist, (sizeof(char *) * copycount));
196 dlist += copycount;
197 *dlist = NULL;
198 } else if (mode == LIST_MODE_DELETE) {
199 /* We need to delete every entry present in the source list
200 * from the destination list */
201 for (slist = sourcelist; *slist != NULL; slist++) {
202 for (dlist = *destlist; *dlist != NULL; dlist++) {
203 found = 0; /* value not found */
204 /* DN is case insensitive string */
205 if (strcasecmp(*dlist, *slist) == 0) {
206 found = 1;
207 free(*dlist);
208 /* Advance the rest of the entries by one */
209 for (tmplist = dlist; *tmplist != NULL; tmplist++) {
210 *tmplist = *(tmplist+1);
211 }
212 break;
213 }
214 }
215 }
216 }
217
218 return;
219 }
220
221
222 /*
223 * Modifies the destination list to contain or not to contain the
224 * entries present in the source list, depending on the mode
225 * (ADD or DELETE). where the list is array of integers.
226 */
list_modify_int_array(destlist,sourcelist,mode)227 int list_modify_int_array(destlist, sourcelist, mode)
228 int *destlist;
229 const int *sourcelist;
230 int mode;
231 {
232 int *dlist = NULL, *tmplist = NULL;
233 const int *slist = NULL;
234 int dcount = 0, scount = 0, copycount = 0;
235 int tcount = 0;
236
237 if ((destlist == NULL) || (sourcelist == NULL))
238 return 0;
239
240 /* We need to add every entry present in the source list to the
241 * destination list */
242 if (mode == LIST_MODE_ADD) {
243 /* Traverse throught the end of destlist for appending */
244 for (dlist = destlist, dcount = 0; *dlist != END_OF_LIST;
245 dlist++, dcount++)
246 ; /* NULL statement */
247
248 /* Count the number of entries in the source list */
249 for (slist = sourcelist, scount = 0; *slist != END_OF_LIST;
250 slist++, scount++)
251 ; /* NULL statement */
252
253 /* Reset the slist pointer to the start of source list */
254 slist = sourcelist;
255
256 /* Now append the source list to the existing destlist */
257 if ((dcount + scount) < MAX_LIST_ENTRIES)
258 copycount = scount;
259 else
260 /* Leave the last entry for list terminator(=NULL) */
261 copycount = (MAX_LIST_ENTRIES -1) - dcount;
262
263 memcpy(dlist, slist, (sizeof(int) * copycount));
264 dlist += copycount;
265 *dlist = END_OF_LIST;
266 tcount = dcount + copycount;
267 } else if (mode == LIST_MODE_DELETE) {
268 /* We need to delete every entry present in the source list from
269 * the destination list */
270 for (slist = sourcelist; *slist != END_OF_LIST; slist++) {
271 for (dlist = destlist; *dlist != END_OF_LIST; dlist++) {
272 if (*dlist == *slist) {
273 /* Advance the rest of the entries by one */
274 for (tmplist = dlist; *tmplist != END_OF_LIST; tmplist++) {
275 *tmplist = *(tmplist+1);
276 }
277 break;
278 }
279 }
280 }
281 /* count the number of entries */
282 for (dlist = destlist, tcount = 0; *dlist != END_OF_LIST; dlist++) {
283 tcount++;
284 }
285 }
286
287 return tcount;
288 }
289
290