Deleted Added
sdiff udiff text old ( 245390 ) new ( 247919 )
full compact
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 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;
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);
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{
442 struct group *newgr;
443 size_t len;
444 int num_mem;
445
446 num_mem = 0;
447 len = grmemlen(gr, newmember, &num_mem);
448 /* Create new group and copy old group into it. */
449 if ((newgr = malloc(len)) == NULL)
450 return (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)
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 */
493 dst = (char *)&newgr->gr_mem[ndx + 1];
494 if (gr->gr_name != NULL) {
495 newgr->gr_name = dst;
496 dst = stpcpy(dst, gr->gr_name) + 1;
497 } else
498 newgr->gr_name = NULL;
499 if (gr->gr_passwd != NULL) {
500 newgr->gr_passwd = dst;
501 dst = stpcpy(dst, gr->gr_passwd) + 1;
502 } else
503 newgr->gr_passwd = NULL;
504 newgr->gr_gid = gr->gr_gid;
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;
509 }
510 if (name != NULL) {
511 newgr->gr_mem[i++] = dst;
512 dst = stpcpy(dst, name) + 1;
513 }
514 newgr->gr_mem[i] = NULL;
515 }
516 return (newgr);
517}
518
519/*
520 * Calculate length of a struct group + given name
521 */
522static size_t
523grmemlen(const struct group *gr, const char *name, int *num_mem)
524{
525 size_t len;
526 int i;
527
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;
536 if (gr->gr_mem != NULL) {
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);
540 }
541 *num_mem = i;
542 }
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);
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 ---