Print this page
*** NO COMMENTS ***
@@ -19,10 +19,11 @@
* CDDL HEADER END
*/
/*
* Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
*/
/*
* For SUNWnskit - version 1.1
*/
@@ -35,13 +36,15 @@
#include <pwd.h>
#include <rpcsvc/ypclnt.h>
#include "util.h"
#include "table.h"
#include "getgroup.h"
+#include "revnetgroup.h"
#define MAXDOMAINLEN 256
-#define MAXGROUPLEN 1024
+#define MAXGROUPLEN 131072
+#define MAXKEYLEN 512
/*
* Reverse the netgroup file. A flag of "-u" means reverse by username,
* one of "-h" means reverse by hostname. Each line in the output file
* will begin with a key formed by concatenating the host or user name
@@ -56,153 +59,195 @@
* Thus to find out all the groups that user "foo" of domain "bar" is in,
* lookup the groups under foo.bar, foo.*, *.bar and *.*.
*
*/
-
-
-/* Stores a list of strings */
-typedef struct stringnode *stringlist;
-struct stringnode {
- char *str;
- stringlist next;
-};
-typedef struct stringnode stringnode;
-
-
-
-/* Stores a list of (name,list-of-groups) */
-typedef struct groupentrynode *groupentrylist;
-struct groupentrynode {
- char *name;
- stringlist groups;
- groupentrylist next;
-};
-typedef struct groupentrynode groupentrynode;
-
-stringtable ngtable;
-
-static groupentrylist grouptable[TABLESIZE];
-
-static char *nextgroup(void);
-static void storegroup(char *group, struct grouplist *glist, int byuser);
-static void enter(char *name, char *group);
+static char *nextgroup(revhandle_t *, tablelist *);
+static void storegroup(char *group, revhandle_t *hdl);
+static void enter(char *name, char *group, revhandle_t *hdl);
static void appendgroup(groupentrylist grlist, char *group);
static groupentrylist newentry(char *name, char *group);
-static void loadtable(FILE *nf);
-static void dumptable(void);
+static void loadtable(FILE *nf, revhandle_t *hdl);
+static void dumptable(FILE *out, revhandle_t *hdl);
+static void free_table(revhandle_t *hdl);
int
-main(argc, argv)
- int argc;
- char *argv[];
+revnetgroup_handle(FILE *fin, FILE *fout, boolean_t byuser)
{
char *group;
- struct grouplist *glist;
- int byuser;
+ revhandle_t hdl = {0};
+ tablelist walker = NULL;
- loadtable(stdin);
- if (argc == 2 && argv[1][0] == '-' &&
- (argv[1][1] == 'u' || argv[1][1] == 'h')) {
- byuser = (argv[1][1] == 'u');
- } else {
- (void) fprintf(stderr,
- "usage: %s -h (by host), %s -u (by user)\n",
- argv[0], argv[0]);
- exit(1);
- }
+ hdl.rh_byuser = byuser;
+ loadtable(fin, &hdl);
- while (group = nextgroup()) {
- glist = my_getgroup(group);
- storegroup(group, glist, byuser);
- }
- dumptable();
+ while (group = nextgroup(&hdl, &walker))
+ storegroup(group, &hdl);
+ dumptable(fout, &hdl);
+ free_table(&hdl);
return (0);
}
/*
* Get the next netgroup from /etc/netgroup
*/
static char *
-nextgroup(void)
+nextgroup(revhandle_t *hdl, tablelist *next)
{
- static int index = -1;
- static tablelist cur = NULL;
- char *group;
+ tablelist entry = *next;
+ uint_t i;
- while (cur == NULL) {
- if (++index == TABLESIZE) {
- return (NULL);
+ if (entry == NULL) {
+ for (i = hdl->rh_index; i < TABLESIZE; i++) {
+ entry = hdl->ngtable[i];
+ if (entry != NULL) {
+ hdl->rh_index = i + 1;
+ break;
}
- cur = ngtable[index];
}
- group = cur->key;
- cur = cur->next;
- return (group);
+ }
+
+ if (entry == NULL) {
+ /* out of table */
+ hdl->rh_index = 0;
+ return (NULL);
+ }
+
+ *next = entry->next;
+ return (entry->key);
}
+static void
+free_tablelist(tablelist e)
+{
+ tablelist next;
+ do {
+ next = e->next;
+
+ free(e->key);
+ free(e->datum);
+ free(e);
+ } while ((e = next) != NULL);
+}
+
+static void
+free_stringnode(stringnode *s)
+{
+ stringnode *next;
+
+ do {
+ next = s->s_next;
+
+ free(s);
+ } while ((s = next) != NULL);
+}
+
+static void
+free_groupentrylist(groupentrylist e)
+{
+ groupentrylist next;
+
+ do {
+ next = e->next;
+
+ free_stringnode(e->groups);
+ free(e->name);
+ free(e);
+ } while ((e = next) != NULL);
+}
+
+static void
+free_table(revhandle_t *hdl)
+{
+ int i;
+
+ /* ngtable */
+ for (i = 0; i < TABLESIZE; i++) {
+ tablelist e;
+
+ if ((e = hdl->ngtable[i]) == NULL)
+ continue;
+
+ free_tablelist(e);
+ hdl->ngtable[i] = NULL;
+ }
+
+ /* grouptable */
+ for (i = 0; i < TABLESIZE; i++) {
+ groupentrylist e;
+
+ if ((e = hdl->grouptable[i]) == NULL)
+ continue;
+
+ free_groupentrylist(e);
+ hdl->grouptable[i] = NULL;
+ }
+}
+
/*
* Dump out all of the stored info into a file
*/
static void
-dumptable(void)
+dumptable(FILE *out, revhandle_t *hdl)
{
int i;
groupentrylist entry;
- stringlist groups;
+ stringnode *groups;
for (i = 0; i < TABLESIZE; i++) {
- if (entry = grouptable[i]) {
+ if (entry = hdl->grouptable[i]) {
while (entry) {
- fputs(entry->name, stdout);
- putc('\t', stdout);
+ fputs(entry->name, out);
+ putc('\t', out);
for (groups = entry->groups; groups;
- groups = groups->next) {
- fputs(groups->str, stdout);
- if (groups->next) {
- putc(',', stdout);
+ groups = groups->s_next) {
+ fputs(groups->str, out);
+ if (groups->s_next) {
+ putc(',', out);
}
}
- putc('\n', stdout);
+ putc('\n', out);
entry = entry->next;
}
}
}
}
-
/*
* Add a netgroup to a user's list of netgroups
*/
static void
-storegroup(char *group, struct grouplist *glist, int byuser)
+storegroup(char *group, revhandle_t *hdl)
{
- char *name; /* username or hostname */
- char *domain;
- char *key;
- static char *universal = "*";
+ char key[MAXKEYLEN];
+ struct grouplist *glist;
- for (; glist; glist = glist->gl_nxt) {
- name = byuser ? glist->gl_name : glist->gl_machine;
+ doit(group, (struct list *)NULL, hdl);
+
+ for (glist = hdl->grouplist; glist; glist = glist->gl_nxt) {
+ const char *name; /* username or hostname */
+ const char *domain;
+
+ name = hdl->rh_byuser ? glist->gl_name : glist->gl_machine;
if (!name) {
- name = universal;
+ name = "*";
} else if (!isalnum(*name) && *name != '_') {
continue;
}
domain = glist->gl_domain;
if (!domain) {
- domain = universal;
+ domain = "*";
}
- key = malloc((unsigned) (strlen(name)+strlen(domain)+2));
- (void) sprintf(key, "%s.%s", name, domain);
- enter(key, group);
+ (void) snprintf(key, sizeof (key), "%s.%s", name, domain);
+ enter(key, group, hdl);
}
+ freegrouplist(hdl);
}
static groupentrylist
@@ -214,44 +259,44 @@
STRCPY(new->name, name);
new->groups = MALLOC(stringnode);
new->groups->str = group;
- new->groups->next = NULL;
+ new->groups->s_next = NULL;
new->next = NULL;
return (new);
}
static void
appendgroup(groupentrylist grlist, char *group)
{
- stringlist cur, prev;
+ stringnode *cur, *prev;
- for (cur = grlist->groups; cur; prev = cur, cur = cur->next) {
+ for (cur = grlist->groups; cur; prev = cur, cur = cur->s_next) {
if (strcmp(group, cur->str) == 0) {
return;
}
}
- prev->next = MALLOC(stringnode);
- cur = prev->next;
+ prev->s_next = MALLOC(stringnode);
+ cur = prev->s_next;
cur->str = group;
- cur->next = NULL;
+ cur->s_next = NULL;
}
static void
-enter(char *name, char *group)
+enter(char *name, char *group, revhandle_t *hdl)
{
int key;
groupentrylist gel;
groupentrylist gelprev;
key = tablekey(name);
- if (grouptable[key] == NULL) {
- grouptable[key] = newentry(name, group);
+ if (hdl->grouptable[key] == NULL) {
+ hdl->grouptable[key] = newentry(name, group);
} else {
- gel = grouptable[key];
+ gel = hdl->grouptable[key];
while (gel && strcmp(gel->name, name)) {
gelprev = gel;
gel = gel->next;
}
if (gel) {
@@ -264,20 +309,25 @@
/*
* Load up a hash table with the info in /etc/netgroup
*/
static void
-loadtable(FILE *nf)
+loadtable(FILE *nf, revhandle_t *hdl)
{
- char buf[MAXGROUPLEN];
+ char *buf;
char *p;
char *group;
char *line;
+ buf = malloc(MAXGROUPLEN);
+ if (buf == NULL)
+ return;
+
while (getaline(buf, MAXGROUPLEN, nf)) {
+ /* skip leading blanks */
for (p = buf; *p && isspace((int)*p); p++)
- ; /* skip leading blanks */
+ ;
for (; *p && *p != '#' && *p != ' ' && *p != '\t'; p++)
;
if (*p == EOS || *p == '#')
continue;
*p++ = EOS;
@@ -288,8 +338,10 @@
if (*p == EOS || *p == '#')
continue;
STRCPY(group, buf);
STRCPY(line, p);
- store(ngtable, group, line);
+ store(hdl->ngtable, group, line);
}
+
+ free(buf);
}