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