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