| File: | tviced/./../libacl/aclprocs.c |
| Location: | line 313, column 5 |
| Description: | Value stored to 'j' is never read |
| 1 | /* |
| 2 | * Copyright 2000, International Business Machines Corporation and others. |
| 3 | * All Rights Reserved. |
| 4 | * |
| 5 | * This software has been released under the terms of the IBM Public |
| 6 | * License. For details, see the LICENSE file in the top-level source |
| 7 | * directory or online at http://www.openafs.org/dl/license10.html |
| 8 | */ |
| 9 | |
| 10 | /* |
| 11 | Information Technology Center |
| 12 | Carnegie-Mellon University |
| 13 | */ |
| 14 | |
| 15 | |
| 16 | #include <afsconfig.h> |
| 17 | #include <afs/param.h> |
| 18 | |
| 19 | #include <roken.h> |
| 20 | |
| 21 | #include <rx/xdr.h> |
| 22 | #include <rx/rx.h> |
| 23 | #include <afs/ptclient.h> |
| 24 | #include <afs/ptuser.h> |
| 25 | |
| 26 | #include "acl.h" |
| 27 | |
| 28 | #ifdef AFS_PTHREAD_ENV1 |
| 29 | #include <assert.h> |
| 30 | #include <pthread.h> |
| 31 | pthread_mutex_t acl_list_mutex; |
| 32 | #endif /* AFS_PTHREAD_ENV */ |
| 33 | |
| 34 | struct freeListEntry { |
| 35 | struct freeListEntry *next; |
| 36 | int size; |
| 37 | char body[1]; |
| 38 | }; |
| 39 | |
| 40 | struct freeListEntry *freeList; |
| 41 | |
| 42 | static int AddToList(struct freeListEntry **, struct freeListEntry *); |
| 43 | static int GetFromList(struct freeListEntry **, struct freeListEntry **, |
| 44 | afs_int32); |
| 45 | |
| 46 | /*todo: for sorting acls - make sure they work with new groups lists 10/5*/ |
| 47 | static int |
| 48 | CmpPlus(const void *arg1, const void *arg2) |
| 49 | { |
| 50 | const struct acl_accessEntry *a = (struct acl_accessEntry *) arg1; |
| 51 | const struct acl_accessEntry *b = (struct acl_accessEntry *) arg2; |
| 52 | if (a->id < b->id) |
| 53 | return (-1); |
| 54 | if (a->id == b->id) |
| 55 | return (0); |
| 56 | return (1); |
| 57 | } |
| 58 | |
| 59 | static int |
| 60 | CmpMinus(const void *arg1, const void *arg2) |
| 61 | { |
| 62 | const struct acl_accessEntry *a = (struct acl_accessEntry *) arg1; |
| 63 | const struct acl_accessEntry *b = (struct acl_accessEntry *) arg2; |
| 64 | |
| 65 | if (a->id > b->id) |
| 66 | return (-1); |
| 67 | if (a->id == b->id) |
| 68 | return (0); |
| 69 | return (1); |
| 70 | } |
| 71 | |
| 72 | static int |
| 73 | CmpInt(int x, int y) |
| 74 | { |
| 75 | if (x < y) |
| 76 | return (-1); |
| 77 | if (x == y) |
| 78 | return (0); |
| 79 | return (1); |
| 80 | } |
| 81 | |
| 82 | |
| 83 | int |
| 84 | acl_NewACL(int nEntries, struct acl_accessList **acl) |
| 85 | { |
| 86 | /* Creates an access list capable of holding at least nEntries entries. |
| 87 | * Returns 0 on success; aborts if we run out of memory. */ |
| 88 | |
| 89 | int t; |
| 90 | struct freeListEntry *e; |
| 91 | |
| 92 | t = sizeof(struct acl_accessList) + (nEntries - |
| 93 | 1) * sizeof(struct acl_accessEntry); |
| 94 | if (GetFromList(&freeList, &e, t) < 0) { |
| 95 | e = (struct freeListEntry *)malloc(t + sizeof(int) + |
| 96 | sizeof(struct freeListEntry *)); |
| 97 | if (e == NULL((void *)0)) { |
| 98 | perror("acl_NewACL: malloc() failed"); |
| 99 | abort(); |
| 100 | } |
| 101 | e->size = t; |
| 102 | *acl = (struct acl_accessList *)(e->body); |
| 103 | } else |
| 104 | *acl = (struct acl_accessList *)(e->body); |
| 105 | |
| 106 | (*acl)->size = t; /* May be less than actual size of storage */ |
| 107 | (*acl)->version = ACL_ACLVERSION1; |
| 108 | (*acl)->total = nEntries; |
| 109 | (*acl)->positive = (*acl)->negative = 0; |
| 110 | return (0); |
| 111 | } |
| 112 | |
| 113 | |
| 114 | int |
| 115 | acl_FreeACL(struct acl_accessList **acl) |
| 116 | { |
| 117 | /* Releases the access list defined by acl. Returns 0 always. */ |
| 118 | struct freeListEntry *x; |
| 119 | |
| 120 | x = (struct freeListEntry *) |
| 121 | ((char *)*acl - sizeof(struct freeListEntry *) - sizeof(int)); |
| 122 | *acl = NULL((void *)0); |
| 123 | return (AddToList(&freeList, x)); |
| 124 | } |
| 125 | |
| 126 | int |
| 127 | acl_NewExternalACL(int nEntries, char **r) |
| 128 | { |
| 129 | /* Puts an external acl big enough to hold nEntries in r. Returns 0 on success, aborts if insufficient memory. */ |
| 130 | |
| 131 | int t; |
| 132 | struct freeListEntry *e; |
| 133 | |
| 134 | t = 20 + (nEntries) * (PR_MAXNAMELEN64 + 20); |
| 135 | /* Conservative estimate: enough space in each entry for longest |
| 136 | * name plus decimal 2**32 (for largest rights mask) plus some formatting */ |
| 137 | |
| 138 | if (GetFromList(&freeList, &e, t)) { |
| 139 | e = (struct freeListEntry *)malloc(t + sizeof(int) + |
| 140 | sizeof(struct freeListEntry *)); |
| 141 | if (e == NULL((void *)0)) { |
| 142 | perror("acl_NewExternalACL(): malloc() failed"); |
| 143 | abort(); |
| 144 | } |
| 145 | e->size = t; |
| 146 | } |
| 147 | |
| 148 | *r = e->body; |
| 149 | sprintf(*r, "0\n0\n"); |
| 150 | return (0); |
| 151 | } |
| 152 | |
| 153 | int |
| 154 | acl_FreeExternalACL(char **r) |
| 155 | { |
| 156 | /* Releases the external access list defined by r. Returns 0 always. */ |
| 157 | |
| 158 | struct freeListEntry *x; |
| 159 | |
| 160 | x = (struct freeListEntry *) |
| 161 | ((char *)*r - sizeof(struct freeListEntry *) - sizeof(int)); |
| 162 | *r = NULL((void *)0); |
| 163 | return (AddToList(&freeList, x)); |
| 164 | } |
| 165 | |
| 166 | int |
| 167 | acl_Externalize_pr(int (*func)(idlist *ids, namelist *names), struct acl_accessList *acl, char **elist) |
| 168 | { |
| 169 | /* Converts the access list defined by acl into the external access list |
| 170 | * in elist. Non-translatable id's are converted to their ASCII string |
| 171 | * representations. Returns 0 on success, -1 if number of entries |
| 172 | * exceeds ACL_MAXENTRIES, or a failure code from the protection server |
| 173 | * if the problem occured there. */ |
| 174 | |
| 175 | int i; |
| 176 | int j; |
| 177 | int code; |
| 178 | char *nextc; |
| 179 | idlist lids; |
| 180 | namelist lnames; |
| 181 | |
| 182 | if (acl->total > ACL_MAXENTRIES20) |
| 183 | return (-1); |
| 184 | acl_NewExternalACL(acl->total, elist); |
| 185 | nextc = *elist; |
| 186 | lids.idlist_val = |
| 187 | (afs_int32 *) malloc(ACL_MAXENTRIES20 * sizeof(afs_int32)); |
| 188 | memset(lids.idlist_val, 0, ACL_MAXENTRIES20 * sizeof(afs_int32)); |
| 189 | lids.idlist_len = acl->total; |
| 190 | lnames.namelist_len = 0; |
| 191 | lnames.namelist_val = (prname *) 0; |
| 192 | sprintf(nextc, "%d\n%d\n", acl->positive, acl->negative); |
| 193 | nextc += strlen(nextc); |
| 194 | for (i = 0; i < acl->positive; i++) |
| 195 | lids.idlist_val[i] = acl->entries[i].id; |
| 196 | j = i; |
| 197 | for (i = acl->total - 1; i >= acl->total - acl->negative; i--, j++) |
| 198 | lids.idlist_val[j] = acl->entries[i].id; |
| 199 | code = (*func)(&lids, &lnames); |
| 200 | if (code != 0) { |
| 201 | if (lids.idlist_val) |
| 202 | free(lids.idlist_val); |
| 203 | if (lnames.namelist_val) |
| 204 | free(lnames.namelist_val); |
| 205 | return code; |
| 206 | } |
| 207 | for (i = 0; i < acl->positive; i++) { |
| 208 | sprintf(nextc, "%s", lnames.namelist_val[i]); |
| 209 | nextc += strlen(nextc); |
| 210 | sprintf(nextc, "\t%d\n", acl->entries[i].rights); |
| 211 | nextc += strlen(nextc); |
| 212 | } |
| 213 | j = i; |
| 214 | for (i = acl->total - 1; i >= acl->total - acl->negative; i--, j++) { |
| 215 | sprintf(nextc, "%s", lnames.namelist_val[j]); |
| 216 | nextc += strlen(nextc); |
| 217 | sprintf(nextc, "\t%d\n", acl->entries[i].rights); |
| 218 | nextc += strlen(nextc); |
| 219 | } |
| 220 | if (lids.idlist_val) |
| 221 | free(lids.idlist_val); |
| 222 | if (lnames.namelist_val) |
| 223 | free(lnames.namelist_val); |
| 224 | return (0); |
| 225 | } |
| 226 | |
| 227 | int |
| 228 | acl_Externalize(struct acl_accessList *acl, char **elist) |
| 229 | { |
| 230 | return acl_Externalize_pr(pr_IdToName, acl, elist); |
| 231 | } |
| 232 | |
| 233 | int |
| 234 | acl_Internalize_pr(int (*func)(namelist *names, idlist *ids), char *elist, struct acl_accessList **acl) |
| 235 | { |
| 236 | /* Converts the external access list elist into the access list acl. |
| 237 | * Returns 0 on success, -1 if ANY name is not translatable, or if |
| 238 | * the number of entries exceeds al_maxExtEntries. */ |
| 239 | int i; |
| 240 | int j; |
| 241 | char *nextc; |
| 242 | afs_int32 code; |
| 243 | int p, n; |
| 244 | namelist lnames; |
| 245 | idlist lids; |
| 246 | |
| 247 | if (sscanf(elist, "%d\n%d\n", &p, &n) != 2) |
| 248 | return -1; |
| 249 | if (p + n > ACL_MAXENTRIES20) |
| 250 | return (-1); |
| 251 | acl_NewACL(p + n, acl); |
| 252 | (*acl)->total = p + n; |
| 253 | (*acl)->positive = p; |
| 254 | (*acl)->negative = n; |
| 255 | if ((*acl)->total == 0) { |
| 256 | /* Empty acl entry; simply return success */ |
| 257 | return 0; |
| 258 | } |
| 259 | lnames.namelist_len = (*acl)->total; |
| 260 | lnames.namelist_val = |
| 261 | (prname *) malloc(lnames.namelist_len * PR_MAXNAMELEN64); |
| 262 | if (lnames.namelist_val == 0) { |
| 263 | return -1; |
| 264 | } |
| 265 | nextc = elist; |
| 266 | while (*nextc && *nextc != '\n') |
| 267 | nextc++; |
| 268 | nextc++; |
| 269 | while (*nextc && *nextc != '\n') |
| 270 | nextc++; |
| 271 | nextc++; /* now at the beginning of the entry list */ |
| 272 | for (i = 0; i < (*acl)->positive; i++) { |
| 273 | int k; |
| 274 | if (sscanf(nextc, "%s\t%d\n", lnames.namelist_val[i], &k) != 2) { |
| 275 | free(lnames.namelist_val); |
| 276 | return (-1); |
| 277 | } |
| 278 | (*acl)->entries[i].rights = k; |
| 279 | nextc = strchr(nextc, '\n'); |
| 280 | nextc++; /* 1 + index can cast ptr to integer */ |
| 281 | } |
| 282 | j = i; |
| 283 | for (i = (*acl)->total - 1; i >= (*acl)->total - (*acl)->negative; |
| 284 | i--, j++) { |
| 285 | if (sscanf |
| 286 | (nextc, "%s\t%d\n", lnames.namelist_val[j], |
| 287 | &((*acl)->entries[j].rights)) != 2) { |
| 288 | free(lnames.namelist_val); |
| 289 | return (-1); |
| 290 | } |
| 291 | nextc = strchr(nextc, '\n'); |
| 292 | nextc++; |
| 293 | } |
| 294 | lids.idlist_len = 0; |
| 295 | lids.idlist_val = 0; |
| 296 | |
| 297 | code = (*func)(&lnames, &lids); |
| 298 | if (code) { |
| 299 | free(lnames.namelist_val); |
| 300 | if (lids.idlist_val) |
| 301 | free(lids.idlist_val); |
| 302 | return -1; |
| 303 | } |
| 304 | for (i = 0; i < (*acl)->positive; i++) { |
| 305 | if (lids.idlist_val[i] == ANONYMOUSID32766) { |
| 306 | free(lnames.namelist_val); |
| 307 | if (lids.idlist_val) |
| 308 | free(lids.idlist_val); |
| 309 | return -1; |
| 310 | } |
| 311 | (*acl)->entries[i].id = lids.idlist_val[i]; |
| 312 | } |
| 313 | j = i; |
Value stored to 'j' is never read | |
| 314 | for (i = (*acl)->total - 1; i >= (*acl)->total - (*acl)->negative; i--) { |
| 315 | if (lids.idlist_val[i] == ANONYMOUSID32766) { |
| 316 | free(lnames.namelist_val); |
| 317 | if (lids.idlist_val) |
| 318 | free(lids.idlist_val); |
| 319 | return -1; |
| 320 | } |
| 321 | (*acl)->entries[i].id = lids.idlist_val[i]; |
| 322 | } |
| 323 | /* sort for easier lookup */ |
| 324 | qsort(&((*acl)->entries[0]), (*acl)->positive, |
| 325 | sizeof(struct acl_accessEntry), CmpPlus); |
| 326 | qsort(&((*acl)->entries[(*acl)->total - (*acl)->negative]), |
| 327 | (*acl)->negative, sizeof(struct acl_accessEntry), CmpMinus); |
| 328 | free(lnames.namelist_val); |
| 329 | if (lids.idlist_val) |
| 330 | free(lids.idlist_val); |
| 331 | return (0); |
| 332 | } |
| 333 | |
| 334 | int |
| 335 | acl_Internalize(char *elist, struct acl_accessList **acl) |
| 336 | { |
| 337 | return acl_Internalize_pr(pr_NameToId, elist, acl); |
| 338 | } |
| 339 | |
| 340 | int |
| 341 | acl_CheckRights(struct acl_accessList *acl, prlist *groups, int *rights) |
| 342 | { |
| 343 | /* Returns the rights given by acl to groups */ |
| 344 | |
| 345 | int temprights; /* positive rights accumulated so far */ |
| 346 | int negrights; /* negative rights accumulated so far */ |
| 347 | int a; /* index into next entry in acl */ |
| 348 | int c; /* index into next entry in CPS */ |
| 349 | |
| 350 | /* more sanity checks */ |
| 351 | if (acl->total > ACL_MAXENTRIES20) |
| 352 | return 1; |
| 353 | if (acl->total < 0) |
| 354 | return 1; |
| 355 | if (acl->size > 192) |
| 356 | return 1; /* 192 is the room in a 256 byte vnode reserved for the ACL */ |
| 357 | |
| 358 | if (acl->total <= 0 || groups->prlist_len <= 0) { |
| 359 | *rights = 0; |
| 360 | return (0); |
| 361 | } |
| 362 | if (groups->prlist_val[groups->prlist_len - 1] == SYSADMINID-204) { |
| 363 | *rights = -1; |
| 364 | return 0; |
| 365 | } |
| 366 | |
| 367 | /* Each iteration eats up exactly one entry from either acl or groups. |
| 368 | * Duplicate Entries in access list ==> accumulated rights are obtained. |
| 369 | * Duplicate Entries in groups ==> irrelevant */ |
| 370 | temprights = 0; |
| 371 | c = a = 0; |
| 372 | while ((a < acl->positive) && (c < groups->prlist_len)) |
| 373 | switch (CmpInt(acl->entries[a].id, groups->prlist_val[c])) { |
| 374 | case -1: |
| 375 | a += 1; |
| 376 | break; |
| 377 | |
| 378 | case 0: |
| 379 | temprights |= acl->entries[a].rights; |
| 380 | a += 1; |
| 381 | break; |
| 382 | |
| 383 | case 1: |
| 384 | c += 1; |
| 385 | break; |
| 386 | |
| 387 | default: |
| 388 | printf("CmpInt() returned bogus value. Aborting ...\n"); |
| 389 | abort(); |
| 390 | } |
| 391 | negrights = 0; |
| 392 | c = 0; |
| 393 | a = acl->total - 1; |
| 394 | while ((c < groups->prlist_len) && (a > acl->total - acl->negative - 1)) |
| 395 | switch (CmpInt(acl->entries[a].id, groups->prlist_val[c])) { |
| 396 | case -1: |
| 397 | a -= 1; |
| 398 | break; |
| 399 | case 0: |
| 400 | negrights |= acl->entries[a].rights; |
| 401 | a -= 1; |
| 402 | break; |
| 403 | case 1: |
| 404 | c += 1; |
| 405 | break; |
| 406 | } |
| 407 | *rights = temprights & (~negrights); |
| 408 | return (0); |
| 409 | } |
| 410 | |
| 411 | int |
| 412 | acl_Initialize(char *version) |
| 413 | { |
| 414 | /* I'm sure we need to do some initialization, I'm just not quite sure what yet! */ |
| 415 | if (strcmp(version, ACL_VERSION"Version 1") != 0) { |
| 416 | fprintf(stderr__stderrp, "Wrong version of acl package!\n"); |
| 417 | fprintf(stderr__stderrp, "This is version %s, file server passed in %s.\n", |
| 418 | ACL_VERSION"Version 1", version); |
| 419 | } |
| 420 | #ifdef AFS_PTHREAD_ENV1 |
| 421 | assert(pthread_mutex_init(&acl_list_mutex, NULL) == 0)((pthread_mutex_init(&acl_list_mutex, ((void *)0)) == 0) ? (void)0 : __assert(__func__, "./../libacl/aclprocs.c", 421, "pthread_mutex_init(&acl_list_mutex, NULL) == 0" )); |
| 422 | #endif /* AFS_PTHREAD_ENV */ |
| 423 | return 0; |
| 424 | } |
| 425 | |
| 426 | int |
| 427 | acl_IsAMember(afs_int32 aid, prlist *cps) |
| 428 | { |
| 429 | afs_int32 i; |
| 430 | |
| 431 | for (i = 0; i < cps->prlist_len; i++) |
| 432 | if (cps->prlist_val[i] == aid) |
| 433 | return 1; |
| 434 | return 0; |
| 435 | } |
| 436 | |
| 437 | |
| 438 | static int |
| 439 | AddToList(struct freeListEntry **pflist, struct freeListEntry *elem) |
| 440 | { |
| 441 | /* Adds elem to the freelist flist; returns 0 */ |
| 442 | #ifdef AFS_PTHREAD_ENV1 |
| 443 | assert(pthread_mutex_lock(&acl_list_mutex) == 0)((pthread_mutex_lock(&acl_list_mutex) == 0) ? (void)0 : __assert (__func__, "./../libacl/aclprocs.c", 443, "pthread_mutex_lock(&acl_list_mutex) == 0" )); |
| 444 | #endif /* AFS_PTHREAD_ENV */ |
| 445 | elem->next = *pflist; |
| 446 | *pflist = elem; |
| 447 | #ifdef AFS_PTHREAD_ENV1 |
| 448 | assert(pthread_mutex_unlock(&acl_list_mutex) == 0)((pthread_mutex_unlock(&acl_list_mutex) == 0) ? (void)0 : __assert(__func__, "./../libacl/aclprocs.c", 448, "pthread_mutex_unlock(&acl_list_mutex) == 0" )); |
| 449 | #endif /* AFS_PTHREAD_ENV */ |
| 450 | return 0; |
| 451 | } |
| 452 | |
| 453 | static int |
| 454 | GetFromList(struct freeListEntry **pflist, struct freeListEntry **elem, |
| 455 | afs_int32 minsize) |
| 456 | { |
| 457 | /* Looks for an element whose body is at least minsize bytes in the |
| 458 | * freelist flist. If found, unlinks it, puts its address in elem, |
| 459 | * and returns 0, else returns -1. A trivial first-fit algorithm is |
| 460 | * used. */ |
| 461 | |
| 462 | struct freeListEntry *y, *z; |
| 463 | |
| 464 | #ifdef AFS_PTHREAD_ENV1 |
| 465 | assert(pthread_mutex_lock(&acl_list_mutex) == 0)((pthread_mutex_lock(&acl_list_mutex) == 0) ? (void)0 : __assert (__func__, "./../libacl/aclprocs.c", 465, "pthread_mutex_lock(&acl_list_mutex) == 0" )); |
| 466 | #endif /* AFS_PTHREAD_ENV */ |
| 467 | if (*pflist == NULL((void *)0)) { |
| 468 | #ifdef AFS_PTHREAD_ENV1 |
| 469 | assert(pthread_mutex_unlock(&acl_list_mutex) == 0)((pthread_mutex_unlock(&acl_list_mutex) == 0) ? (void)0 : __assert(__func__, "./../libacl/aclprocs.c", 469, "pthread_mutex_unlock(&acl_list_mutex) == 0" )); |
| 470 | #endif /* AFS_PTHREAD_ENV */ |
| 471 | return -1; |
| 472 | } |
| 473 | for (y = *pflist, z = NULL((void *)0); y != NULL((void *)0); z = y, y = y->next) { |
| 474 | if (y->size >= minsize) { |
| 475 | *elem = y; |
| 476 | if (z == NULL((void *)0)) { /* pulling off the head */ |
| 477 | *pflist = y->next; |
| 478 | #ifdef AFS_PTHREAD_ENV1 |
| 479 | assert(pthread_mutex_unlock(&acl_list_mutex) == 0)((pthread_mutex_unlock(&acl_list_mutex) == 0) ? (void)0 : __assert(__func__, "./../libacl/aclprocs.c", 479, "pthread_mutex_unlock(&acl_list_mutex) == 0" )); |
| 480 | #endif /* AFS_PTHREAD_ENV */ |
| 481 | return 0; |
| 482 | } |
| 483 | z->next = y->next; |
| 484 | #ifdef AFS_PTHREAD_ENV1 |
| 485 | assert(pthread_mutex_unlock(&acl_list_mutex) == 0)((pthread_mutex_unlock(&acl_list_mutex) == 0) ? (void)0 : __assert(__func__, "./../libacl/aclprocs.c", 485, "pthread_mutex_unlock(&acl_list_mutex) == 0" )); |
| 486 | #endif /* AFS_PTHREAD_ENV */ |
| 487 | return 0; |
| 488 | } |
| 489 | } |
| 490 | #ifdef AFS_PTHREAD_ENV1 |
| 491 | assert(pthread_mutex_unlock(&acl_list_mutex) == 0)((pthread_mutex_unlock(&acl_list_mutex) == 0) ? (void)0 : __assert(__func__, "./../libacl/aclprocs.c", 491, "pthread_mutex_unlock(&acl_list_mutex) == 0" )); |
| 492 | #endif /* AFS_PTHREAD_ENV */ |
| 493 | return -1; |
| 494 | } |