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 */ 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 */ 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 */ 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 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 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 */ 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 */ 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