(linenum→info "unix/slp.c:2238")

glibc/2.7/nss/getent.c

    1: /* Copyright (c) 1998-2006, 2007 Free Software Foundation, Inc.
    2:    This file is part of the GNU C Library.
    3:    Contributed by Thorsten Kukuk <kukuk@suse.de>, 1998.
    4: 
    5:    The GNU C Library is free software; you can redistribute it and/or
    6:    modify it under the terms of the GNU Lesser General Public
    7:    License as published by the Free Software Foundation; either
    8:    version 2.1 of the License, or (at your option) any later version.
    9: 
   10:    The GNU C Library is distributed in the hope that it will be useful,
   11:    but WITHOUT ANY WARRANTY; without even the implied warranty of
   12:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   13:    Lesser General Public License for more details.
   14: 
   15:    You should have received a copy of the GNU Lesser General Public
   16:    License along with the GNU C Library; if not, write to the Free
   17:    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   18:    02111-1307 USA.  */
   19: 
   20: /* getent: get entries from administrative database.  */
   21: 
   22: #include <aliases.h>
   23: #include <argp.h>
   24: #include <ctype.h>
   25: #include <error.h>
   26: #include <grp.h>
   27: #include <libintl.h>
   28: #include <locale.h>
   29: #include <mcheck.h>
   30: #include <netdb.h>
   31: #include <pwd.h>
   32: #include <shadow.h>
   33: #include <stdio.h>
   34: #include <stdlib.h>
   35: #include <string.h>
   36: #include <arpa/inet.h>
   37: #include <arpa/nameser.h>
   38: #include <netinet/ether.h>
   39: #include <netinet/in.h>
   40: #include <sys/socket.h>
   41: 
   42: /* Get libc version number.  */
   43: #include <version.h>
   44: 
   45: #define PACKAGE _libc_intl_domainname
   46: 
   47: /* Name and version of program.  */
   48: static void print_version (FILE *stream, struct argp_state *state);
   49: void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version;
   50: 
   51: /* Short description of parameters.  */
   52: static const char args_doc[] = N_("database [key ...]");
   53: 
   54: /* Supported options. */
   55: static const struct argp_option args_options[] =
   56:   {
   57:     { "service", 's', "CONFIG", 0, N_("Service configuration to be used") },
   58:     { NULL, 0, NULL, 0, NULL },
   59:   };
   60: 
   61: /* Short description of program.  */
   62: static const char doc[] = N_("Get entries from administrative database.\v\
   63: For bug reporting instructions, please see:\n\
   64: <http://www.gnu.org/software/libc/bugs.html>.\n");
   65: 
   66: /* Prototype for option handler.  */
   67: static error_t parse_option (int key, char *arg, struct argp_state *state);
   68: 
   69: /* Function to print some extra text in the help message.  */
   70: static char *more_help (int key, const char *text, void *input);
   71: 
   72: /* Data structure to communicate with argp functions.  */
   73: static struct argp argp =
   74:   {
   75:     args_options, parse_option, args_doc, doc, NULL, more_help
   76:   };
   77: 
   78: /* Print the version information.  */
   79: static void
   80: print_version (FILE *stream, struct argp_state *state)
   81: {
   82:   fprintf (stream, "getent (GNU %s) %s\n", PACKAGE, VERSION);
   83:   fprintf (stream, gettext ("\
   84: Copyright (C) %s Free Software Foundation, Inc.\n\
   85: This is free software; see the source for copying conditions.  There is NO\n\
   86: warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
   87: "), "2007");
   88:   fprintf (stream, gettext ("Written by %s.\n"), "Thorsten Kukuk");
   89: }
   90: 
   91: /* This is for aliases */
   92: static inline void
   93: print_aliases (struct aliasent *alias)
   94: {
   95:   unsigned int i = 0;
   96: 
   97:   printf ("%s: ", alias->alias_name);
   98:   for  (i = strlen (alias->alias_name); i < 14; ++i)
   99:     fputs_unlocked (" ", stdout);
  100: 
  101:   for (i = 0; i < alias->alias_members_len; ++i)
  102:     printf ("%s%s",
  103:             alias->alias_members [i],
  104:             i + 1 == alias->alias_members_len ? "\n" : ", ");
  105: }
  106: 
  107: static int
  108: aliases_keys (int number, char *key[])
  109: {
  110:   int result = 0;
  111:   int i;
  112:   struct aliasent *alias;
  113: 
  114:   if (number == 0)
  115:     {
  116:       setaliasent ();
  117:       while ((alias = getaliasent ()) != NULL)
  118:         print_aliases (alias);
  119:       endaliasent ();
  120:       return result;
  121:     }
  122: 
  123:   for (i = 0; i < number; ++i)
  124:     {
  125:       alias = getaliasbyname (key[i]);
  126: 
  127:       if (alias == NULL)
  128:         result = 2;
  129:       else
  130:         print_aliases (alias);
  131:     }
  132: 
  133:   return result;
  134: }
  135: 
  136: /* This is for ethers */
  137: static int
  138: ethers_keys (int number, char *key[])
  139: {
  140:   int result = 0;
  141:   int i;
  142: 
  143:   if (number == 0)
  144:     {
  145:       fprintf (stderr, _("Enumeration not supported on %s\n"), "ethers");
  146:       return 3;
  147:     }
  148: 
  149:   for (i = 0; i < number; ++i)
  150:     {
  151:       struct ether_addr *ethp, eth;
  152:       char buffer [1024], *p;
  153: 
  154:       ethp = ether_aton (key[i]);
  155:       if (ethp != NULL)
  156:         {
  157:           if (ether_ntohost (buffer, ethp))
  158:             {
  159:               result = 2;
  160:               continue;
  161:             }
  162:           p = buffer;
  163:         }
  164:       else
  165:         {
  166:           if (ether_hostton (key[i], &eth))
  167:             {
  168:               result = 2;
  169:               continue;
  170:             }
  171:           p = key[i];
  172:           ethp = &eth;
  173:         }
  174:       printf ("%s %s\n", ether_ntoa (ethp), p);
  175:     }
  176: 
  177:   return result;
  178: }
  179: 
  180: /* This is for group */
  181: static inline void
  182: print_group (struct group *grp)
  183: {
  184:   unsigned int i = 0;
  185: 
  186:   printf ("%s:%s:%lu:", grp->gr_name ? grp->gr_name : "",
  187:           grp->gr_passwd ? grp->gr_passwd : "",
  188:           (unsigned long int) grp->gr_gid);
  189: 
  190:   while (grp->gr_mem[i] != NULL)
  191:     {
  192:       fputs_unlocked (grp->gr_mem[i], stdout);
  193:       ++i;
  194:       if (grp->gr_mem[i] != NULL)
  195:         putchar_unlocked (',');
  196:     }
  197:   putchar_unlocked ('\n');
  198: }
  199: 
  200: static int
  201: group_keys (int number, char *key[])
  202: {
  203:   int result = 0;
  204:   int i;
  205:   struct group *grp;
  206: 
  207:   if (number == 0)
  208:     {
  209:       setgrent ();
  210:       while ((grp = getgrent ()) != NULL)
  211:         print_group (grp);
  212:       endgrent ();
  213:       return result;
  214:     }
  215: 
  216:   for (i = 0; i < number; ++i)
  217:     {
  218:       errno = 0;
  219:       char *ep;
  220:       gid_t arg_gid = strtoul(key[i], &ep, 10);
  221: 
  222:       if (errno != EINVAL && *key[i] != '\0' && *ep == '\0')
  223:         /* Valid numeric gid.  */
  224:         grp = getgrgid (arg_gid);
  225:       else
  226:         grp = getgrnam (key[i]);
  227: 
  228:       if (grp == NULL)
  229:         result = 2;
  230:       else
  231:         print_group (grp);
  232:     }
  233: 
  234:   return result;
  235: }
  236: 
  237: /* This is for hosts */
  238: static void
  239: print_hosts (struct hostent *host)
  240: {
  241:   unsigned int cnt;
  242: 
  243:   for (cnt = 0; host->h_addr_list[cnt] != NULL; ++cnt)
  244:     {
  245:       char buf[INET6_ADDRSTRLEN];
  246:       const char *ip = inet_ntop (host->h_addrtype, host->h_addr_list[cnt],
  247:                                   buf, sizeof (buf));
  248: 
  249:       printf ("%-15s %s", ip, host->h_name);
  250: 
  251:       unsigned int i;
  252:       for (i = 0; host->h_aliases[i] != NULL; ++i)
  253:         {
  254:           putchar_unlocked (' ');
  255:           fputs_unlocked (host->h_aliases[i], stdout);
  256:         }
  257:       putchar_unlocked ('\n');
  258:     }
  259: }
  260: 
  261: static int
  262: hosts_keys (int number, char *key[])
  263: {
  264:   int result = 0;
  265:   int i;
  266:   struct hostent *host;
  267: 
  268:   if (number == 0)
  269:     {
  270:       sethostent (0);
  271:       while ((host = gethostent ()) != NULL)
  272:         print_hosts (host);
  273:       endhostent ();
  274:       return result;
  275:     }
  276: 
  277:   for (i = 0; i < number; ++i)
  278:     {
  279:       struct hostent *host = NULL;
  280:       char addr[IN6ADDRSZ];
  281: 
  282:       if (inet_pton (AF_INET6, key[i], &addr) > 0)
  283:         host = gethostbyaddr (addr, IN6ADDRSZ, AF_INET6);
  284:       else if (inet_pton (AF_INET, key[i], &addr) > 0)
  285:         host = gethostbyaddr (addr, INADDRSZ, AF_INET);
  286:       else if ((host = gethostbyname2 (key[i], AF_INET6)) == NULL)
  287:         host = gethostbyname2 (key[i], AF_INET);
  288: 
  289:       if (host == NULL)
  290:         result = 2;
  291:       else
  292:         print_hosts (host);
  293:     }
  294: 
  295:   return result;
  296: }
  297: 
  298: /* This is for hosts, but using getaddrinfo */
  299: static int
  300: ahosts_keys_int (int af, int xflags, int number, char *key[])
  301: {
  302:   int result = 0;
  303:   int i;
  304:   struct hostent *host;
  305: 
  306:   if (number == 0)
  307:     {
  308:       sethostent (0);
  309:       while ((host = gethostent ()) != NULL)
  310:         print_hosts (host);
  311:       endhostent ();
  312:       return result;
  313:     }
  314: 
  315:   struct addrinfo hint;
  316:   memset (&hint, '\0', sizeof (hint));
  317:   hint.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG | AI_CANONNAME | xflags;
  318:   hint.ai_family = af;
  319: 
  320:   for (i = 0; i < number; ++i)
  321:     {
  322:       struct addrinfo *res;
  323: 
  324:       if (getaddrinfo (key[i], NULL, &hint, &res) != 0)
  325:         result = 2;
  326:       else
  327:         {
  328:           struct addrinfo *runp = res;
  329: 
  330:           while (runp != NULL)
  331:             {
  332:               char sockbuf[20];
  333:               const char *sockstr;
  334:               if (runp->ai_socktype == SOCK_STREAM)
  335:                 sockstr = "STREAM";
  336:               else if (runp->ai_socktype == SOCK_DGRAM)
  337:                 sockstr = "DGRAM";
  338:               else if (runp->ai_socktype == SOCK_RAW)
  339:                 sockstr = "RAW";
  340:               else
  341:                 {
  342:                   snprintf (sockbuf, sizeof (sockbuf), "%d",
  343:                             runp->ai_socktype);
  344:                   sockstr = sockbuf;
  345:                 }
  346: 
  347:               char buf[INET6_ADDRSTRLEN];
  348:               printf ("%-15s %-6s %s\n",
  349:                       inet_ntop (runp->ai_family,
  350:                                  runp->ai_family == AF_INET
  351:                                  ? (void *) &((struct sockaddr_in *) runp->ai_addr)->sin_addr
  352:                                  : (void *) &((struct sockaddr_in6 *) runp->ai_addr)->sin6_addr,
  353:                                  buf, sizeof (buf)),
  354:                       sockstr,
  355:                       runp->ai_canonname ?: "");
  356: 
  357:               runp = runp->ai_next;
  358:             }
  359: 
  360:           freeaddrinfo (res);
  361:         }
  362:     }
  363: 
  364:   return result;
  365: }
  366: 
  367: static int
  368: ahosts_keys (int number, char *key[])
  369: {
  370:   return ahosts_keys_int (AF_UNSPEC, 0, number, key);
  371: }
  372: 
  373: static int
  374: ahostsv4_keys (int number, char *key[])
  375: {
  376:   return ahosts_keys_int (AF_INET, 0, number, key);
  377: }
  378: 
  379: static int
  380: ahostsv6_keys (int number, char *key[])
  381: {
  382:   return ahosts_keys_int (AF_INET6, AI_V4MAPPED, number, key);
  383: }
  384: 
  385: /* This is for netgroup */
  386: static int
  387: netgroup_keys (int number, char *key[])
  388: {
  389:   int result = 0;
  390:   int i;
  391: 
  392:   if (number == 0)
  393:     {
  394:       fprintf (stderr, _("Enumeration not supported on %s\n"), "netgroup");
  395:       return 3;
  396:     }
  397: 
  398:   for (i = 0; i < number; ++i)
  399:     {
  400:       if (!setnetgrent (key[i]))
  401:         result = 2;
  402:       else
  403:         {
  404:           char *p[3];
  405: 
  406:           printf ("%-21s", key[i]);
  407: 
  408:           while (getnetgrent (p, p + 1, p + 2))
  409:             printf (" (%s, %s, %s)", p[0] ?: " ", p[1] ?: "", p[2] ?: "");
  410:           putchar_unlocked ('\n');
  411:         }
  412:     }
  413: 
  414:   endnetgrent ();
  415: 
  416:   return result;
  417: }
  418: 
  419: /* This is for networks */
  420: static void
  421: print_networks (struct netent *net)
  422: {
  423:   unsigned int i;
  424:   struct in_addr ip;
  425:   ip.s_addr = htonl (net->n_net);
  426: 
  427:   printf ("%-21s %s", net->n_name, inet_ntoa (ip));
  428: 
  429:   i = 0;
  430:   while (net->n_aliases[i] != NULL)
  431:     {
  432:       putchar_unlocked (' ');
  433:       fputs_unlocked (net->n_aliases[i], stdout);
  434:       ++i;
  435:       if (net->n_aliases[i] != NULL)
  436:         putchar_unlocked (',');
  437:     }
  438:   putchar_unlocked ('\n');
  439: }
  440: 
  441: static int
  442: networks_keys (int number, char *key[])
  443: {
  444:   int result = 0;
  445:   int i;
  446:   struct netent *net;
  447: 
  448:   if (number == 0)
  449:     {
  450:       setnetent (0);
  451:       while ((net = getnetent ()) != NULL)
  452:         print_networks (net);
  453:       endnetent ();
  454:       return result;
  455:     }
  456: 
  457:   for (i = 0; i < number; ++i)
  458:     {
  459:       if (isdigit (key[i][0]))
  460:         net = getnetbyaddr (inet_addr (key[i]), AF_UNIX);
  461:       else
  462:         net = getnetbyname (key[i]);
  463: 
  464:       if (net == NULL)
  465:         result = 2;
  466:       else
  467:         print_networks (net);
  468:     }
  469: 
  470:   return result;
  471: }
  472: 
  473: /* Now is all for passwd */
  474: static inline void
  475: print_passwd (struct passwd *pwd)
  476: {
  477:   printf ("%s:%s:%lu:%lu:%s:%s:%s\n",
  478:           pwd->pw_name ? pwd->pw_name : "",
  479:           pwd->pw_passwd ? pwd->pw_passwd : "",
  480:           (unsigned long int) pwd->pw_uid,
  481:           (unsigned long int) pwd->pw_gid,
  482:           pwd->pw_gecos ? pwd->pw_gecos : "",
  483:           pwd->pw_dir ? pwd->pw_dir : "",
  484:           pwd->pw_shell ? pwd->pw_shell : "");
  485: }
  486: 
  487: static int
  488: passwd_keys (int number, char *key[])
  489: {
  490:   int result = 0;
  491:   int i;
  492:   struct passwd *pwd;
  493: 
  494:   if (number == 0)
  495:     {
  496:       setpwent ();
  497:       while ((pwd = getpwent ()) != NULL)
  498:         print_passwd (pwd);
  499:       endpwent ();
  500:       return result;
  501:     }
  502: 
  503:   for (i = 0; i < number; ++i)
  504:     {
  505:       errno = 0;
  506:       char *ep;
  507:       uid_t arg_uid = strtoul(key[i], &ep, 10);
  508: 
  509:       if (errno != EINVAL && *key[i] != '\0' && *ep == '\0')
  510:         /* Valid numeric uid.  */
  511:         pwd = getpwuid (arg_uid);
  512:       else
  513:         pwd = getpwnam (key[i]);
  514: 
  515:       if (pwd == NULL)
  516:         result = 2;
  517:       else
  518:         print_passwd (pwd);
  519:     }
  520: 
  521:   return result;
  522: }
  523: 
  524: /* This is for protocols */
  525: static inline void
  526: print_protocols (struct protoent *proto)
  527: {
  528:   unsigned int i;
  529: 
  530:   printf ("%-21s %d", proto->p_name, proto->p_proto);
  531: 
  532:   i = 0;
  533:   while (proto->p_aliases[i] != NULL)
  534:     {
  535:       putchar_unlocked (' ');
  536:       fputs_unlocked (proto->p_aliases[i], stdout);
  537:       ++i;
  538:     }
  539:   putchar_unlocked ('\n');
  540: }
  541: 
  542: static int
  543: protocols_keys (int number, char *key[])
  544: {
  545:   int result = 0;
  546:   int i;
  547:   struct protoent *proto;
  548: 
  549:   if (number == 0)
  550:     {
  551:       setprotoent (0);
  552:       while ((proto = getprotoent ()) != NULL)
  553:         print_protocols (proto);
  554:       endprotoent ();
  555:       return result;
  556:     }
  557: 
  558:   for (i = 0; i < number; ++i)
  559:     {
  560:       if (isdigit (key[i][0]))
  561:         proto = getprotobynumber (atol (key[i]));
  562:       else
  563:         proto = getprotobyname (key[i]);
  564: 
  565:       if (proto == NULL)
  566:         result = 2;
  567:       else
  568:         print_protocols (proto);
  569:     }
  570: 
  571:   return result;
  572: }
  573: 
  574: /* Now is all for rpc */
  575: static inline void
  576: print_rpc (struct rpcent *rpc)
  577: {
  578:   int i;
  579: 
  580:   printf ("%-15s %d%s",
  581:           rpc->r_name, rpc->r_number, rpc->r_aliases[0] ? " " : "");
  582: 
  583:   for (i = 0; rpc->r_aliases[i]; ++i)
  584:     printf (" %s", rpc->r_aliases[i]);
  585:   putchar_unlocked ('\n');
  586: }
  587: 
  588: static int
  589: rpc_keys (int number, char *key[])
  590: {
  591:   int result = 0;
  592:   int i;
  593:   struct rpcent *rpc;
  594: 
  595:   if (number == 0)
  596:     {
  597:       setrpcent (0);
  598:       while ((rpc = getrpcent ()) != NULL)
  599:         print_rpc (rpc);
  600:       endrpcent ();
  601:       return result;
  602:     }
  603: 
  604:   for (i = 0; i < number; ++i)
  605:     {
  606:       if (isdigit (key[i][0]))
  607:         rpc = getrpcbynumber (atol (key[i]));
  608:       else
  609:         rpc = getrpcbyname (key[i]);
  610: 
  611:       if (rpc == NULL)