1 /*
   2  * This file and its contents are supplied under the terms of the
   3  * Common Development and Distribution License ("CDDL"), version 1.0.
   4  * You may only use this file in accordance with the terms of version
   5  * 1.0 of the CDDL.
   6  *
   7  * A full copy of the text of the CDDL should have accompanied this
   8  * source.  A copy of the CDDL is also available via the Internet at
   9  * http://www.illumos.org/license/CDDL.
  10  */
  11 
  12 /*
  13  * Copyright 2012 Nexenta Systems, Inc.  All rights reserved.
  14  */
  15 
  16 /*
  17  * Test program for files / netgroup support
  18  */
  19 
  20 #include <nsswitch.h>
  21 #include <nss_common.h>
  22 #include <nss_dbdefs.h>
  23 #include <stdio.h>
  24 #include <stdlib.h>
  25 #include <string.h>
  26 #include <ctype.h>
  27 
  28 static DEFINE_NSS_DB_ROOT(db_root);
  29 
  30 /*
  31  * This is a NSS str2ent (parse) function to fill in a
  32  * struct nss_netgrent.  See NSS_XbyY_INIT below.
  33  *
  34  * A specialized but parse-equivalent version of this function
  35  * is in the files back end.  See str2netr() in:
  36  * $SRC/lib/nsswitch/files/common/getnetgrent.c
  37  */
  38 static int
  39 str2netgr(const char *instr, int lenstr, void *ent, char *buffer, int buflen)
  40 {
  41         const char sep[] = " \t\n";
  42         struct nss_netgrent *netgr = ent;
  43         char            *p;
  44 
  45         if (lenstr + 1 > buflen)
  46                 return (NSS_STR_PARSE_ERANGE);
  47 
  48         /*
  49          * We copy the input string into the output buffer and
  50          * operate on it in place.
  51          */
  52         if (instr != buffer) {
  53                 /* Overlapping buffer copies are OK */
  54                 (void) memmove(buffer, instr, lenstr);
  55                 buffer[lenstr] = '\0';
  56         }
  57 
  58         /* quick exit do not entry fill if not needed */
  59         if (ent == (void *)NULL)
  60                 return (NSS_STR_PARSE_SUCCESS);
  61 
  62         /* skip leading space */
  63         p = buffer;
  64         while (isspace(*p))
  65                 p++;
  66 
  67         /* should be at the key */
  68         if (*p == '\0')
  69                 return (NSS_STR_PARSE_PARSE);
  70         netgr->netgr_name = p;
  71 
  72         /* skip the key and null terminate */
  73         p = strpbrk(p, sep);
  74         if (p == NULL)
  75                 return (NSS_STR_PARSE_PARSE);
  76         *p++ = '\0';
  77 
  78         /* skip separators */
  79         while (isspace(*p))
  80                 p++;
  81 
  82         /*
  83          * Should be at the members list, which is the
  84          * rest of the input line.
  85          */
  86         if (*p == '\0')
  87                 return (NSS_STR_PARSE_PARSE);
  88         netgr->netgr_members = p;
  89 
  90         return (NSS_STR_PARSE_SUCCESS);
  91 }
  92 
  93 static void
  94 initf_netgroup(nss_db_params_t *p)
  95 {
  96         p->name      = NSS_DBNAM_NETGROUP;
  97         p->default_config = NSS_DEFCONF_NETGROUP;
  98 }
  99 
 100 struct nss_netgrent *
 101 netgr_getbyname(const char *name, struct nss_netgrent *result,
 102         char *buffer, int buflen)
 103 {
 104         nss_XbyY_args_t arg = {0};
 105 
 106         if (name == (const char *)NULL) {
 107                 errno = ERANGE;
 108                 return (NULL);
 109         }
 110         NSS_XbyY_INIT(&arg, result, buffer, buflen, str2netgr);
 111         arg.key.name = name;
 112         (void) nss_search(&db_root, initf_netgroup,
 113             NSS_DBOP_NETGROUP_BYNAME, &arg);
 114         return ((struct nss_netgrent *)NSS_XbyY_FINI(&arg));
 115 }
 116 
 117 static char buf[NSS_LINELEN_NETGROUP];
 118 
 119 int
 120 main(int argc, char **argv)
 121 {
 122         struct nss_netgrent netgr, *ng;
 123         int i;
 124 
 125         if (argc < 2) {
 126                 (void) fprintf(stderr, "usage: %s netgroup [...]\n", argv[0]);
 127                 exit(1);
 128         }
 129 
 130         for (i = 1; i < argc; i++) {
 131                 ng = netgr_getbyname(argv[i], &netgr, buf, sizeof (buf));
 132                 if (ng == NULL) {
 133                         perror(argv[i]);
 134                         continue;
 135                 }
 136                 (void) printf("%s => %s\n",
 137                     netgr.netgr_name,
 138                     netgr.netgr_members);
 139         }
 140         return (0);
 141 }