gr_util.c (245390) | gr_util.c (247919) |
---|---|
1/*- 2 * Copyright (c) 2008 Sean C. Farley <scf@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 11 unchanged lines hidden (view full) --- 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2008 Sean C. Farley <scf@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 11 unchanged lines hidden (view full) --- 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> |
28__FBSDID("$FreeBSD: head/lib/libutil/gr_util.c 245390 2013-01-13 22:08:18Z mjg $"); | 28__FBSDID("$FreeBSD: head/lib/libutil/gr_util.c 247919 2013-03-07 19:00:00Z db $"); |
29 30#include <sys/param.h> 31#include <sys/errno.h> 32#include <sys/stat.h> 33 34#include <ctype.h> 35#include <err.h> 36#include <fcntl.h> --- 7 unchanged lines hidden (view full) --- 44#include <string.h> 45#include <unistd.h> 46 47static int lockfd = -1; 48static char group_dir[PATH_MAX]; 49static char group_file[PATH_MAX]; 50static char tempname[PATH_MAX]; 51static int initialized; | 29 30#include <sys/param.h> 31#include <sys/errno.h> 32#include <sys/stat.h> 33 34#include <ctype.h> 35#include <err.h> 36#include <fcntl.h> --- 7 unchanged lines hidden (view full) --- 44#include <string.h> 45#include <unistd.h> 46 47static int lockfd = -1; 48static char group_dir[PATH_MAX]; 49static char group_file[PATH_MAX]; 50static char tempname[PATH_MAX]; 51static int initialized; |
52static size_t grmemlen(const struct group *, const char *, int *); 53static struct group *grcopy(const struct group *gr, struct group *newgr, const char *, int ndx); |
|
52 53/* 54 * Initialize statics 55 */ 56int 57gr_init(const char *dir, const char *group) 58{ 59 --- 364 unchanged lines hidden (view full) --- 424} 425 426/* 427 * Duplicate a struct group. 428 */ 429struct group * 430gr_dup(const struct group *gr) 431{ | 54 55/* 56 * Initialize statics 57 */ 58int 59gr_init(const char *dir, const char *group) 60{ 61 --- 364 unchanged lines hidden (view full) --- 426} 427 428/* 429 * Duplicate a struct group. 430 */ 431struct group * 432gr_dup(const struct group *gr) 433{ |
434 return (gr_add(gr, NULL)); 435} 436/* 437 * Add a new member name to a struct group. 438 */ 439struct group * 440gr_add(const struct group *gr, const char *newmember) 441{ |
|
432 struct group *newgr; | 442 struct group *newgr; |
433 char *dst; | |
434 size_t len; | 443 size_t len; |
435 int ndx; | |
436 int num_mem; 437 | 444 int num_mem; 445 |
438 /* Calculate size of the group. */ 439 len = sizeof(*newgr); 440 if (gr->gr_name != NULL) 441 len += strlen(gr->gr_name) + 1; 442 if (gr->gr_passwd != NULL) 443 len += strlen(gr->gr_passwd) + 1; 444 if (gr->gr_mem != NULL) { 445 for (num_mem = 0; gr->gr_mem[num_mem] != NULL; num_mem++) 446 len += strlen(gr->gr_mem[num_mem]) + 1; 447 len += (num_mem + 1) * sizeof(*gr->gr_mem); 448 } else 449 num_mem = -1; | 446 num_mem = 0; 447 len = grmemlen(gr, newmember, &num_mem); |
450 /* Create new group and copy old group into it. */ 451 if ((newgr = malloc(len)) == NULL) 452 return (NULL); | 448 /* Create new group and copy old group into it. */ 449 if ((newgr = malloc(len)) == NULL) 450 return (NULL); |
453 /* point new gr_mem to end of struct + 1 */ 454 if (gr->gr_mem != NULL) | 451 return (grcopy(gr, newgr, newmember, num_mem)); 452} 453 454/* It is safer to walk the pointers given at gr_mem since there is no 455 * guarantee the gr_mem + strings are continguous in the given struct group 456 * but compact the new group into the following form. 457 * 458 * The new struct is laid out like this in memory. The example given is 459 * for a group with two members only. 460 * 461 * { 462 * (char *name) 463 * (char *passwd) 464 * (int gid) 465 * (gr_mem * newgrp + sizeof(struct group) + sizeof(**)) points to gr_mem area 466 * gr_mem area 467 * (member1 *) 468 * (member2 *) 469 * (NULL) 470 * (name string) 471 * (passwd string) 472 * (member1 string) 473 * (member2 string) 474 * } 475 */ 476/* 477 * Copy the guts of a group plus given name to a preallocated group struct 478 */ 479static struct group * 480grcopy(const struct group *gr, struct group *newgr, const char *name, int ndx) 481{ 482 char *dst; 483 int i; 484 485 if (name != NULL) 486 ndx++; 487 /* point new gr_mem to end of struct + 1 if there are names */ 488 if (ndx != 0) |
455 newgr->gr_mem = (char **)(newgr + 1); 456 else 457 newgr->gr_mem = NULL; 458 /* point dst after the end of all the gr_mem pointers in newgr */ | 489 newgr->gr_mem = (char **)(newgr + 1); 490 else 491 newgr->gr_mem = NULL; 492 /* point dst after the end of all the gr_mem pointers in newgr */ |
459 dst = (char *)&newgr->gr_mem[num_mem + 1]; | 493 dst = (char *)&newgr->gr_mem[ndx + 1]; |
460 if (gr->gr_name != NULL) { 461 newgr->gr_name = dst; 462 dst = stpcpy(dst, gr->gr_name) + 1; | 494 if (gr->gr_name != NULL) { 495 newgr->gr_name = dst; 496 dst = stpcpy(dst, gr->gr_name) + 1; |
463 } else { | 497 } else |
464 newgr->gr_name = NULL; | 498 newgr->gr_name = NULL; |
465 } | |
466 if (gr->gr_passwd != NULL) { 467 newgr->gr_passwd = dst; 468 dst = stpcpy(dst, gr->gr_passwd) + 1; | 499 if (gr->gr_passwd != NULL) { 500 newgr->gr_passwd = dst; 501 dst = stpcpy(dst, gr->gr_passwd) + 1; |
469 } else { | 502 } else |
470 newgr->gr_passwd = NULL; | 503 newgr->gr_passwd = NULL; |
471 } | |
472 newgr->gr_gid = gr->gr_gid; | 504 newgr->gr_gid = gr->gr_gid; |
473 if (gr->gr_mem != NULL) { 474 for (ndx = 0; ndx < num_mem; ndx++) { 475 newgr->gr_mem[ndx] = dst; 476 dst = stpcpy(dst, gr->gr_mem[ndx]) + 1; | 505 if (ndx != 0) { 506 for (i = 0; gr->gr_mem[i] != NULL; i++) { 507 newgr->gr_mem[i] = dst; 508 dst = stpcpy(dst, gr->gr_mem[i]) + 1; |
477 } | 509 } |
478 newgr->gr_mem[ndx] = NULL; | 510 if (name != NULL) { 511 newgr->gr_mem[i++] = dst; 512 dst = stpcpy(dst, name) + 1; 513 } 514 newgr->gr_mem[i] = NULL; |
479 } 480 return (newgr); 481} 482 483/* | 515 } 516 return (newgr); 517} 518 519/* |
484 * Add a new member name to a struct group. | 520 * Calculate length of a struct group + given name |
485 */ | 521 */ |
486struct group * 487gr_add(struct group *gr, char *newmember) | 522static size_t 523grmemlen(const struct group *gr, const char *name, int *num_mem) |
488{ | 524{ |
489 size_t mlen; 490 int num_mem=0; 491 char **members; 492 struct group *newgr; | 525 size_t len; 526 int i; |
493 | 527 |
494 if (newmember == NULL) 495 return(gr_dup(gr)); 496 | 528 if (gr == NULL) 529 return (0); 530 /* Calculate size of the group. */ 531 len = sizeof(*gr); 532 if (gr->gr_name != NULL) 533 len += strlen(gr->gr_name) + 1; 534 if (gr->gr_passwd != NULL) 535 len += strlen(gr->gr_passwd) + 1; |
497 if (gr->gr_mem != NULL) { | 536 if (gr->gr_mem != NULL) { |
498 for (num_mem = 0; gr->gr_mem[num_mem] != NULL; num_mem++) { 499 if (strcmp(gr->gr_mem[num_mem], newmember) == 0) { 500 errno = EEXIST; 501 return (NULL); 502 } | 537 for (len = i = 0; gr->gr_mem[i] != NULL; i++) { 538 len += strlen(gr->gr_mem[i]) + 1; 539 len += sizeof(*gr->gr_mem); |
503 } | 540 } |
541 *num_mem = i; |
|
504 } | 542 } |
505 /* Allocate enough for current pointers + 1 more and NULL marker */ 506 mlen = (num_mem + 2) * sizeof(*gr->gr_mem); 507 if ((members = malloc(mlen)) == NULL) 508 return (NULL); 509 memcpy(members, gr->gr_mem, num_mem * sizeof(*gr->gr_mem)); 510 members[num_mem++] = newmember; 511 members[num_mem] = NULL; 512 gr->gr_mem = members; 513 newgr = gr_dup(gr); 514 free(members); 515 return (newgr); | 543 if (name != NULL) { 544 len += strlen(name) + 1; 545 if (gr->gr_mem == NULL) 546 len += sizeof(*gr->gr_mem); 547 } 548 return(len); |
516} 517 518/* 519 * Scan a line and place it into a group structure. 520 */ 521static bool 522__gr_scan(char *line, struct group *gr) 523{ --- 63 unchanged lines hidden --- | 549} 550 551/* 552 * Scan a line and place it into a group structure. 553 */ 554static bool 555__gr_scan(char *line, struct group *gr) 556{ --- 63 unchanged lines hidden --- |