Print this page
*** NO COMMENTS ***


   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.

  24  */
  25 
  26 /*
  27  * For SUNWnskit - version 1.1
  28  */
  29 
  30 #include <stdlib.h>
  31 #include <unistd.h>
  32 #include <string.h>
  33 #include <stdio.h>
  34 #include <ctype.h>
  35 #include <pwd.h>
  36 #include <rpcsvc/ypclnt.h>
  37 #include "util.h"
  38 #include "table.h"
  39 #include "getgroup.h"

  40 
  41 #define MAXDOMAINLEN 256
  42 #define MAXGROUPLEN 1024

  43 
  44 /*
  45  * Reverse the netgroup file. A flag of "-u" means reverse by username,
  46  * one of "-h" means reverse by hostname. Each line in the output file
  47  * will begin with a key formed by concatenating the host or user name
  48  * with the domain name. The key will be followed by a tab, then the
  49  * comma-separated, newline-terminated list of groups to which the
  50  * user or host belongs.
  51  *
  52  * Exception: Groups to which everyone belongs (universal groups) will
  53  * not be included in the list.  The universal groups will be listed under
  54  * the special name "*".
  55  *
  56  * Thus to find out all the groups that user "foo" of domain "bar" is in,
  57  * lookup the groups under  foo.bar, foo.*, *.bar and *.*.
  58  *
  59  */
  60 
  61 
  62 
  63 /* Stores a list of strings */
  64 typedef struct stringnode *stringlist;
  65 struct stringnode {
  66     char *str;
  67     stringlist next;
  68 };
  69 typedef struct stringnode stringnode;
  70 
  71 
  72 
  73 /* Stores a list of (name,list-of-groups) */
  74 typedef struct groupentrynode *groupentrylist;
  75 struct groupentrynode {
  76     char *name;
  77     stringlist groups;
  78     groupentrylist next;
  79 };
  80 typedef struct groupentrynode groupentrynode;
  81 
  82 stringtable ngtable;
  83 
  84 static groupentrylist grouptable[TABLESIZE];
  85 
  86 static char *nextgroup(void);
  87 static void storegroup(char *group, struct grouplist *glist, int byuser);
  88 static void enter(char *name, char *group);
  89 static void appendgroup(groupentrylist grlist, char *group);
  90 static groupentrylist newentry(char *name, char *group);
  91 static void loadtable(FILE *nf);
  92 static void dumptable(void);

  93 
  94 int
  95 main(argc, argv)
  96     int argc;
  97     char *argv[];
  98 {
  99         char *group;
 100         struct grouplist *glist;
 101         int byuser;
 102 
 103         loadtable(stdin);
 104         if (argc == 2 && argv[1][0] == '-' &&
 105                         (argv[1][1] == 'u' || argv[1][1] == 'h')) {
 106                 byuser = (argv[1][1] == 'u');
 107         } else {
 108                 (void) fprintf(stderr,
 109                                 "usage: %s -h (by host), %s -u (by user)\n",
 110                                 argv[0], argv[0]);
 111                 exit(1);
 112         }
 113 
 114         while (group = nextgroup()) {
 115                 glist = my_getgroup(group);
 116                 storegroup(group, glist, byuser);
 117         }
 118         dumptable();
 119 


 120         return (0);
 121 }
 122 
 123 /*
 124  *      Get the next netgroup from /etc/netgroup
 125  */
 126 static char *
 127 nextgroup(void)
 128 {
 129         static int index = -1;
 130         static tablelist cur = NULL;
 131         char *group;
 132 
 133         while (cur == NULL) {
 134                 if (++index == TABLESIZE) {
 135                         return (NULL);



 136                 }
 137                 cur = ngtable[index];
 138         }
 139         group = cur->key;
 140         cur = cur->next;
 141         return (group);







 142 }
 143 
 144 




 145 































































 146 /*
 147  * Dump out all of the stored info into a file
 148  */
 149 static void
 150 dumptable(void)
 151 {
 152         int i;
 153         groupentrylist entry;
 154         stringlist groups;
 155 
 156         for (i = 0; i < TABLESIZE; i++) {
 157                 if (entry = grouptable[i]) {
 158                         while (entry) {
 159                                 fputs(entry->name, stdout);
 160                                 putc('\t', stdout);
 161                                 for (groups = entry->groups; groups;
 162                                                 groups = groups->next) {
 163                                         fputs(groups->str, stdout);
 164                                         if (groups->next) {
 165                                                 putc(',', stdout);
 166                                         }
 167                                 }
 168                                 putc('\n', stdout);
 169                                 entry = entry->next;
 170                         }
 171                 }
 172         }
 173 }
 174 
 175 
 176 
 177 
 178 /*
 179  *      Add a netgroup to a user's list of netgroups
 180  */
 181 static void
 182 storegroup(char *group, struct grouplist *glist, int byuser)
 183 {
 184         char *name;     /* username or hostname */
 185         char *domain;
 186         char *key;
 187         static char *universal = "*";
 188 
 189         for (; glist; glist = glist->gl_nxt) {
 190                 name = byuser ? glist->gl_name : glist->gl_machine;





 191                 if (!name) {
 192                     name = universal;
 193                 } else if (!isalnum(*name) && *name != '_') {
 194                     continue;
 195                 }
 196                 domain = glist->gl_domain;
 197                 if (!domain) {
 198                     domain = universal;
 199                 }
 200                 key = malloc((unsigned) (strlen(name)+strlen(domain)+2));
 201                 (void) sprintf(key, "%s.%s", name, domain);
 202                 enter(key, group);
 203         }

 204 }
 205 
 206 
 207 
 208 static groupentrylist
 209 newentry(char *name, char *group)
 210 {
 211         groupentrylist new;
 212 
 213         new = MALLOC(groupentrynode);
 214 
 215         STRCPY(new->name, name);
 216 
 217         new->groups = MALLOC(stringnode);
 218         new->groups->str = group;
 219         new->groups->next = NULL;
 220 
 221         new->next = NULL;
 222         return (new);
 223 }
 224 
 225 static void
 226 appendgroup(groupentrylist grlist, char *group)
 227 {
 228         stringlist cur, prev;
 229 
 230         for (cur = grlist->groups; cur; prev = cur, cur = cur->next) {
 231                 if (strcmp(group, cur->str) == 0) {
 232                     return;
 233                 }
 234         }
 235         prev->next = MALLOC(stringnode);
 236         cur = prev->next;
 237         cur->str = group;
 238         cur->next = NULL;
 239 }
 240 
 241 static void
 242 enter(char *name, char *group)
 243 {
 244         int key;
 245         groupentrylist gel;
 246         groupentrylist gelprev;
 247 
 248         key = tablekey(name);
 249         if (grouptable[key] == NULL) {
 250                 grouptable[key] = newentry(name, group);
 251         } else {
 252                 gel = grouptable[key];
 253                 while (gel && strcmp(gel->name, name)) {
 254                     gelprev = gel;
 255                     gel = gel->next;
 256                 }
 257                 if (gel) {
 258                     appendgroup(gel, group);
 259                 } else {
 260                     gelprev->next = newentry(name, group);
 261                 }
 262         }
 263 }
 264 
 265 /*
 266  * Load up a hash table with the info in /etc/netgroup
 267  */
 268 static void
 269 loadtable(FILE *nf)
 270 {
 271         char buf[MAXGROUPLEN];
 272         char *p;
 273         char *group;
 274         char *line;
 275 




 276         while (getaline(buf, MAXGROUPLEN, nf)) {

 277                 for (p = buf; *p && isspace((int)*p); p++)
 278                         ;       /* skip leading blanks */
 279                 for (; *p && *p != '#' && *p != ' ' && *p != '\t'; p++)
 280                         ;
 281                 if (*p == EOS || *p == '#')
 282                         continue;
 283                 *p++ = EOS;
 284 
 285                 while (*p == ' ' || *p == '\t') {
 286                         p++;
 287                 }
 288                 if (*p == EOS || *p == '#')
 289                         continue;
 290 
 291                 STRCPY(group, buf);
 292                 STRCPY(line, p);
 293                 store(ngtable, group, line);
 294         }


 295 }


   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2012 Nexenta Systems, Inc.  All rights reserved.
  25  */
  26 
  27 /*
  28  * For SUNWnskit - version 1.1
  29  */
  30 
  31 #include <stdlib.h>
  32 #include <unistd.h>
  33 #include <string.h>
  34 #include <stdio.h>
  35 #include <ctype.h>
  36 #include <pwd.h>
  37 #include <rpcsvc/ypclnt.h>
  38 #include "util.h"
  39 #include "table.h"
  40 #include "getgroup.h"
  41 #include "revnetgroup.h"
  42 
  43 #define MAXDOMAINLEN 256
  44 #define MAXGROUPLEN  131072
  45 #define MAXKEYLEN    512
  46 
  47 /*
  48  * Reverse the netgroup file. A flag of "-u" means reverse by username,
  49  * one of "-h" means reverse by hostname. Each line in the output file
  50  * will begin with a key formed by concatenating the host or user name
  51  * with the domain name. The key will be followed by a tab, then the
  52  * comma-separated, newline-terminated list of groups to which the
  53  * user or host belongs.
  54  *
  55  * Exception: Groups to which everyone belongs (universal groups) will
  56  * not be included in the list.  The universal groups will be listed under
  57  * the special name "*".
  58  *
  59  * Thus to find out all the groups that user "foo" of domain "bar" is in,
  60  * lookup the groups under  foo.bar, foo.*, *.bar and *.*.
  61  *
  62  */
  63 
  64 static char *nextgroup(revhandle_t *, tablelist *);
  65 static void storegroup(char *group, revhandle_t *hdl);
  66 static void enter(char *name, char *group, revhandle_t *hdl);

























  67 static void appendgroup(groupentrylist grlist, char *group);
  68 static groupentrylist newentry(char *name, char *group);
  69 static void loadtable(FILE *nf, revhandle_t *hdl);
  70 static void dumptable(FILE *out, revhandle_t *hdl);
  71 static void free_table(revhandle_t *hdl);
  72 
  73 int
  74 revnetgroup_handle(FILE *fin, FILE *fout, boolean_t byuser)


  75 {
  76         char *group;
  77         revhandle_t hdl = {0};
  78         tablelist walker = NULL;
  79 
  80         hdl.rh_byuser = byuser;
  81         loadtable(fin, &hdl);








  82 
  83         while (group = nextgroup(&hdl, &walker))
  84                 storegroup(group, &hdl);



  85 
  86         dumptable(fout, &hdl);
  87         free_table(&hdl);
  88         return (0);
  89 }
  90 
  91 /*
  92  *      Get the next netgroup from /etc/netgroup
  93  */
  94 static char *
  95 nextgroup(revhandle_t *hdl, tablelist *next)
  96 {
  97         tablelist entry = *next;
  98         uint_t i;

  99 
 100         if (entry == NULL) {
 101                 for (i = hdl->rh_index; i < TABLESIZE; i++) {
 102                         entry = hdl->ngtable[i];
 103                         if (entry != NULL) {
 104                                 hdl->rh_index = i + 1;
 105                                 break;
 106                         }

 107                 }
 108         }
 109 
 110         if (entry == NULL) {
 111                 /* out of table */
 112                 hdl->rh_index = 0;
 113                 return (NULL);
 114         }
 115 
 116         *next = entry->next;
 117         return (entry->key);
 118 }
 119 
 120 
 121 static void
 122 free_tablelist(tablelist e)
 123 {
 124         tablelist next;
 125 
 126         do {
 127                 next = e->next;
 128 
 129                 free(e->key);
 130                 free(e->datum);
 131                 free(e);
 132         } while ((e = next) != NULL);
 133 }
 134 
 135 static void
 136 free_stringnode(stringnode *s)
 137 {
 138         stringnode *next;
 139 
 140         do {
 141                 next = s->s_next;
 142 
 143                 free(s);
 144         } while ((s = next) != NULL);
 145 }
 146 
 147 static void
 148 free_groupentrylist(groupentrylist e)
 149 {
 150         groupentrylist next;
 151 
 152         do {
 153                 next = e->next;
 154 
 155                 free_stringnode(e->groups);
 156                 free(e->name);
 157                 free(e);
 158         } while ((e = next) != NULL);
 159 }
 160 
 161 static void
 162 free_table(revhandle_t *hdl)
 163 {
 164         int i;
 165 
 166         /* ngtable */
 167         for (i = 0; i < TABLESIZE; i++) {
 168                 tablelist e;
 169 
 170                 if ((e = hdl->ngtable[i]) == NULL)
 171                         continue;
 172 
 173                 free_tablelist(e);
 174                 hdl->ngtable[i] = NULL;
 175         }
 176 
 177         /* grouptable */
 178         for (i = 0; i < TABLESIZE; i++) {
 179                 groupentrylist e;
 180 
 181                 if ((e = hdl->grouptable[i]) == NULL)
 182                         continue;
 183 
 184                 free_groupentrylist(e);
 185                 hdl->grouptable[i] = NULL;
 186         }
 187 }
 188 
 189 /*
 190  * Dump out all of the stored info into a file
 191  */
 192 static void
 193 dumptable(FILE *out, revhandle_t *hdl)
 194 {
 195         int i;
 196         groupentrylist entry;
 197         stringnode *groups;
 198 
 199         for (i = 0; i < TABLESIZE; i++) {
 200                 if (entry = hdl->grouptable[i]) {
 201                         while (entry) {
 202                                 fputs(entry->name, out);
 203                                 putc('\t', out);
 204                                 for (groups = entry->groups; groups;
 205                                     groups = groups->s_next) {
 206                                         fputs(groups->str, out);
 207                                         if (groups->s_next) {
 208                                                 putc(',', out);
 209                                         }
 210                                 }
 211                                 putc('\n', out);
 212                                 entry = entry->next;
 213                         }
 214                 }
 215         }
 216 }
 217 
 218 
 219 

 220 /*
 221  *      Add a netgroup to a user's list of netgroups
 222  */
 223 static void
 224 storegroup(char *group, revhandle_t *hdl)
 225 {
 226         char key[MAXKEYLEN];
 227         struct grouplist *glist;


 228 
 229         doit(group, (struct list *)NULL, hdl);
 230 
 231         for (glist = hdl->grouplist; glist; glist = glist->gl_nxt) {
 232                 const char *name;       /* username or hostname */
 233                 const char *domain;
 234 
 235                 name = hdl->rh_byuser ? glist->gl_name : glist->gl_machine;
 236                 if (!name) {
 237                         name = "*";
 238                 } else if (!isalnum(*name) && *name != '_') {
 239                         continue;
 240                 }
 241                 domain = glist->gl_domain;
 242                 if (!domain) {
 243                         domain = "*";
 244                 }
 245                 (void) snprintf(key, sizeof (key), "%s.%s", name, domain);
 246                 enter(key, group, hdl);

 247         }
 248         freegrouplist(hdl);
 249 }
 250 
 251 
 252 
 253 static groupentrylist
 254 newentry(char *name, char *group)
 255 {
 256         groupentrylist new;
 257 
 258         new = MALLOC(groupentrynode);
 259 
 260         STRCPY(new->name, name);
 261 
 262         new->groups = MALLOC(stringnode);
 263         new->groups->str = group;
 264         new->groups->s_next = NULL;
 265 
 266         new->next = NULL;
 267         return (new);
 268 }
 269 
 270 static void
 271 appendgroup(groupentrylist grlist, char *group)
 272 {
 273         stringnode *cur, *prev;
 274 
 275         for (cur = grlist->groups; cur; prev = cur, cur = cur->s_next) {
 276                 if (strcmp(group, cur->str) == 0) {
 277                         return;
 278                 }
 279         }
 280         prev->s_next = MALLOC(stringnode);
 281         cur = prev->s_next;
 282         cur->str = group;
 283         cur->s_next = NULL;
 284 }
 285 
 286 static void
 287 enter(char *name, char *group, revhandle_t *hdl)
 288 {
 289         int key;
 290         groupentrylist gel;
 291         groupentrylist gelprev;
 292 
 293         key = tablekey(name);
 294         if (hdl->grouptable[key] == NULL) {
 295                 hdl->grouptable[key] = newentry(name, group);
 296         } else {
 297                 gel = hdl->grouptable[key];
 298                 while (gel && strcmp(gel->name, name)) {
 299                         gelprev = gel;
 300                         gel = gel->next;
 301                 }
 302                 if (gel) {
 303                         appendgroup(gel, group);
 304                 } else {
 305                         gelprev->next = newentry(name, group);
 306                 }
 307         }
 308 }
 309 
 310 /*
 311  * Load up a hash table with the info in /etc/netgroup
 312  */
 313 static void
 314 loadtable(FILE *nf, revhandle_t *hdl)
 315 {
 316         char *buf;
 317         char *p;
 318         char *group;
 319         char *line;
 320 
 321         buf = malloc(MAXGROUPLEN);
 322         if (buf == NULL)
 323                 return;
 324 
 325         while (getaline(buf, MAXGROUPLEN, nf)) {
 326                 /* skip leading blanks */
 327                 for (p = buf; *p && isspace((int)*p); p++)
 328                         ;
 329                 for (; *p && *p != '#' && *p != ' ' && *p != '\t'; p++)
 330                         ;
 331                 if (*p == EOS || *p == '#')
 332                         continue;
 333                 *p++ = EOS;
 334 
 335                 while (*p == ' ' || *p == '\t') {
 336                         p++;
 337                 }
 338                 if (*p == EOS || *p == '#')
 339                         continue;
 340 
 341                 STRCPY(group, buf);
 342                 STRCPY(line, p);
 343                 store(hdl->ngtable, group, line);
 344         }
 345 
 346         free(buf);
 347 }