diff options
Diffstat (limited to 'nss/getent.c')
-rw-r--r-- | nss/getent.c | 617 |
1 files changed, 436 insertions, 181 deletions
diff --git a/nss/getent.c b/nss/getent.c index 5834d79..709293a 100644 --- a/nss/getent.c +++ b/nss/getent.c @@ -1,4 +1,4 @@ -/* Copyright (c) 1998, 1999, 2000 Free Software Foundation, Inc. +/* Copyright (c) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Thorsten Kukuk <kukuk@suse.de>, 1998. @@ -17,13 +17,13 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* getent: get entries from administrative database - supported databases: passwd, group, hosts, services, protocols - and networks */ +/* getent: get entries from administrative database. */ +#include <aliases.h> #include <argp.h> #include <grp.h> #include <pwd.h> +#include <shadow.h> #include <ctype.h> #include <error.h> #include <libintl.h> @@ -34,6 +34,7 @@ #include <string.h> #include <sys/socket.h> #include <netinet/in.h> +#include <netinet/ether.h> #include <arpa/inet.h> #include <arpa/nameser.h> @@ -49,13 +50,9 @@ void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version; /* Short description of parameters. */ static const char args_doc[] = N_("database [key ...]"); -/* Short description of program. */ -static const char doc[] = - N_("getent - get entries from administrative database."); - /* Data structure to communicate with argp functions. */ static struct argp argp = { - NULL, NULL, args_doc, doc, + NULL, NULL, args_doc, NULL, }; /* Print the version information. */ @@ -67,10 +64,101 @@ print_version (FILE *stream, struct argp_state *state) Copyright (C) %s Free Software Foundation, Inc.\n\ This is free software; see the source for copying conditions. There is NO\n\ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ -"), "1999"); +"), "2001"); fprintf (stream, gettext ("Written by %s.\n"), "Thorsten Kukuk"); } +/* This is for aliases */ +static inline void +print_aliases (struct aliasent *alias) +{ + unsigned int i = 0; + + printf ("%s: ", alias->alias_name); + for (i = strlen (alias->alias_name); i < 14; ++i) + fputs (" ", stdout); + + for (i = 0; + i < alias->alias_members_len; + ++i) + printf ("%s%s", + alias->alias_members [i], + i + 1 == alias->alias_members_len ? "\n" : ", "); +} + +static int +aliases_keys (int number, char *key[]) +{ + int result = 0; + int i; + struct aliasent *alias; + + if (!number) + { + setaliasent (); + while ((alias = getaliasent()) != NULL) + print_aliases (alias); + endaliasent (); + return result; + } + + for (i = 0; i < number; ++i) + { + alias = getaliasbyname (key[i]); + + if (alias == NULL) + result = 2; + else + print_aliases (alias); + } + + return result; +} + +/* This is for ethers */ +static int +ethers_keys (int number, char *key[]) +{ + int result = 0; + int i; + + if (!number) + { + fprintf (stderr, _("Enumeration not supported on %s\n"), "ethers"); + return 3; + } + + for (i = 0; i < number; ++i) + { + struct ether_addr *ethp, eth; + char buffer [1024], *p; + + ethp = ether_aton (key[i]); + if (ethp) + { + if (ether_ntohost (buffer, ethp)) + { + result = 2; + continue; + } + p = buffer; + } + else + { + if (ether_hostton (key[i], ð)) + { + result = 2; + continue; + } + p = key[i]; + ethp = ð + } + printf ("%s %s\n", ether_ntoa (ethp), p); + } + + return result; +} + /* This is for group */ static inline void print_group (struct group *grp) @@ -91,16 +179,24 @@ print_group (struct group *grp) fputs ("\n", stdout); } -static inline int +static int group_keys (int number, char *key[]) { int result = 0; int i; + struct group *grp; - for (i = 0; i < number; ++i) + if (!number) { - struct group *grp; + setgrent (); + while ((grp = getgrent()) != NULL) + print_group (grp); + endgrent (); + return result; + } + for (i = 0; i < number; ++i) + { if (isdigit (key[i][0])) grp = getgrgid (atol (key[i])); else @@ -115,6 +211,109 @@ group_keys (int number, char *key[]) return result; } +/* This is for hosts */ +static inline void +print_hosts (struct hostent *host) +{ + unsigned int i; + char buf[INET6_ADDRSTRLEN]; + const char *ip = inet_ntop (host->h_addrtype, host->h_addr_list[0], + buf, sizeof (buf)); + + fputs (ip, stdout); + for (i = strlen (ip); i < 15; ++i) + fputs (" ", stdout); + fputs (" ", stdout); + fputs (host->h_name, stdout); + + i = 0; + while (host->h_aliases[i] != NULL) + { + fputs (" ", stdout); + fputs (host->h_aliases[i], stdout); + ++i; + } + fputs ("\n", stdout); +} + +static int +hosts_keys (int number, char *key[]) +{ + int result = 0; + int i; + struct hostent *host; + + if (!number) + { + sethostent (0); + while ((host = gethostent()) != NULL) + print_hosts (host); + endhostent (); + return result; + } + + for (i = 0; i < number; ++i) + { + struct hostent *host = NULL; + + if (strchr (key[i], ':') != NULL) + { + char addr[IN6ADDRSZ]; + if (inet_pton (AF_INET6, key[i], &addr)) + host = gethostbyaddr (addr, sizeof (addr), AF_INET6); + } + else if (isdigit (key[i][0])) + { + char addr[INADDRSZ]; + if (inet_pton (AF_INET, key[i], &addr)) + host = gethostbyaddr (addr, sizeof (addr), AF_INET); + } + else if ((host = gethostbyname2 (key[i], AF_INET6)) == NULL) + host = gethostbyname2 (key[i], AF_INET); + + if (host == NULL) + result = 2; + else + print_hosts (host); + } + + return result; +} + +/* This is for netgroup */ +static int +netgroup_keys (int number, char *key[]) +{ + int result = 0; + int i, j; + + if (!number) + { + fprintf (stderr, _("Enumeration not supported on %s\n"), "netgroup"); + return 3; + } + + for (i = 0; i < number; ++i) + { + if (!setnetgrent (key[i])) + result = 2; + else + { + char *p[3]; + + fputs (key[i], stdout); + for (j = strlen (key[i]); j < 21; ++j) + fputs (" ", stdout); + + while (getnetgrent (p, p + 1, p + 2)) + printf (" (%s, %s, %s)", p[0] ?: " ", p[1] ?: "", p[2] ?: ""); + fputs ("\n", stdout); + } + } + + return result; +} + /* This is for networks */ static inline void print_networks (struct netent *net) @@ -123,8 +322,8 @@ print_networks (struct netent *net) struct in_addr ip; ip.s_addr = htonl (net->n_net); - fputs (net->n_name, stdout); - for (i = strlen (net->n_name); i < 22; ++i) + printf ("%s ", net->n_name); + for (i = strlen (net->n_name); i < 21; ++i) fputs (" ", stdout); fputs (inet_ntoa (ip), stdout); @@ -140,16 +339,24 @@ print_networks (struct netent *net) fputs ("\n", stdout); } -static inline int +static int networks_keys (int number, char *key[]) { int result = 0; int i; + struct netent *net; - for (i = 0; i < number; ++i) + if (!number) { - struct netent *net; + setnetent (0); + while ((net = getnetent()) != NULL) + print_networks (net); + endnetent (); + return result; + } + for (i = 0; i < number; ++i) + { if (isdigit (key[i][0])) net = getnetbyaddr (inet_addr (key[i]), AF_UNIX); else @@ -178,16 +385,24 @@ print_passwd (struct passwd *pwd) pwd->pw_shell ? pwd->pw_shell : ""); } -static inline int +static int passwd_keys (int number, char *key[]) { int result = 0; int i; + struct passwd *pwd; - for (i = 0; i < number; ++i) + if (!number) { - struct passwd *pwd; + setpwent (); + while ((pwd = getpwent()) != NULL) + print_passwd (pwd); + endpwent (); + return result; + } + for (i = 0; i < number; ++i) + { if (isdigit (key[i][0])) pwd = getpwuid (atol (key[i])); else @@ -209,9 +424,9 @@ print_protocols (struct protoent *proto) unsigned int i; fputs (proto->p_name, stdout); - for (i = strlen (proto->p_name); i < 22; ++i) + for (i = strlen (proto->p_name); i < 21; ++i) fputs (" ", stdout); - printf ("%d", proto->p_proto); + printf (" %d", proto->p_proto); i = 0; while (proto->p_aliases[i] != NULL) @@ -223,16 +438,24 @@ print_protocols (struct protoent *proto) fputs ("\n", stdout); } -static inline int +static int protocols_keys (int number, char *key[]) { int result = 0; int i; + struct protoent *proto; - for (i = 0; i < number; ++i) + if (!number) { - struct protoent *proto; + setprotoent (0); + while ((proto = getprotoent()) != NULL) + print_protocols (proto); + endprotoent (); + return result; + } + for (i = 0; i < number; ++i) + { if (isdigit (key[i][0])) proto = getprotobynumber (atol (key[i])); else @@ -247,75 +470,64 @@ protocols_keys (int number, char *key[]) return result; } -/* This is for hosts */ +/* Now is all for rpc */ static inline void -print_hosts (struct hostent *host) +print_rpc (struct rpcent *rpc) { - unsigned int i; - char buf[INET6_ADDRSTRLEN]; - const char *ip = inet_ntop (host->h_addrtype, host->h_addr_list[0], - buf, sizeof (buf)); + int i; - fputs (ip, stdout); - for (i = strlen (ip); i < 15; ++i) + fputs (rpc->r_name, stdout); + for (i = strlen (rpc->r_name); i < 15; ++i) fputs (" ", stdout); - fputs (" ", stdout); - fputs (host->h_name, stdout); + printf (" %d%s", rpc->r_number, rpc->r_aliases[0] ? " " : ""); - i = 0; - while (host->h_aliases[i] != NULL) - { - fputs (" ", stdout); - fputs (host->h_aliases[i], stdout); - ++i; - } + for (i = 0; rpc->r_aliases[i]; ++i) + printf (" %s", rpc->r_aliases[i]); fputs ("\n", stdout); } -static inline int -hosts_keys (int number, char *key[]) +static int +rpc_keys (int number, char *key[]) { int result = 0; int i; + struct rpcent *rpc; - for (i = 0; i < number; ++i) + if (!number) { - struct hostent *host = NULL; + setrpcent (0); + while ((rpc = getrpcent()) != NULL) + print_rpc (rpc); + endrpcent (); + return result; + } - if (strchr (key[i], ':') != NULL) - { - char addr[IN6ADDRSZ]; - if (inet_pton (AF_INET6, key[i], &addr)) - host = gethostbyaddr (addr, sizeof (addr), AF_INET6); - } - else if (isdigit (key[i][0])) - { - char addr[INADDRSZ]; - if (inet_pton (AF_INET, key[i], &addr)) - host = gethostbyaddr (addr, sizeof (addr), AF_INET); - } - else if ((host = gethostbyname2 (key[i], AF_INET6)) == NULL) - host = gethostbyname2 (key[i], AF_INET); + for (i = 0; i < number; ++i) + { + if (isdigit (key[i][0])) + rpc = getrpcbynumber (atol (key[i])); + else + rpc = getrpcbyname (key[i]); - if (host == NULL) + if (rpc == NULL) result = 2; else - print_hosts (host); + print_rpc (rpc); } return result; } /* for services */ -static inline void +static void print_services (struct servent *serv) { unsigned int i; fputs (serv->s_name, stdout); - for (i = strlen (serv->s_name); i < 22; ++i) + for (i = strlen (serv->s_name); i < 21; ++i) fputs (" ", stdout); - printf ("%d/%s", ntohs (serv->s_port), serv->s_proto); + printf (" %d/%s", ntohs (serv->s_port), serv->s_proto); i = 0; while (serv->s_aliases[i] != NULL) @@ -327,11 +539,21 @@ print_services (struct servent *serv) fputs ("\n", stdout); } -static inline int +static int services_keys (int number, char *key[]) { int result = 0; int i; + struct servent *serv; + + if (!number) + { + setservent (0); + while ((serv = getservent()) != NULL) + print_services (serv); + endservent (); + return result; + } for (i = 0; i < number; ++i) { @@ -353,12 +575,21 @@ services_keys (int number, char *key[]) } else { + int j; + while ((serv = getservent ()) != NULL) if (strcmp (serv->s_name, key[i]) == 0) { print_services (serv); break; } + else + for (j = 0; serv->s_aliases[j]; ++j) + if (strcmp (serv->s_aliases[j], key[i]) == 0) + { + print_services (serv); + break; + } } endservent (); } @@ -381,139 +612,163 @@ services_keys (int number, char *key[]) return result; } -/* the main function */ -int -main (int argc, char *argv[]) +/* This is for shadow */ +static inline void +print_shadow (struct spwd *sp) { - int remaining; - - /* Set locale via LC_ALL. */ - setlocale (LC_ALL, ""); - /* Set the text message domain. */ - textdomain (PACKAGE); + printf ("%s:%s:", + sp->sp_namp ? sp->sp_namp : "", + sp->sp_pwdp ? sp->sp_pwdp : ""); + +#define SHADOW_FIELD(n) \ + if (sp->n == -1) \ + fputs (":", stdout); \ + else \ + printf ("%ld:", sp->n) + + SHADOW_FIELD (sp_lstchg); + SHADOW_FIELD (sp_min); + SHADOW_FIELD (sp_max); + SHADOW_FIELD (sp_warn); + SHADOW_FIELD (sp_inact); + SHADOW_FIELD (sp_expire); + if (sp->sp_flag == ~0ul) + fputs ("\n", stdout); + else + printf ("%lu\n", sp->sp_flag); +} - /* Parse and process arguments. */ - argp_parse (&argp, argc, argv, 0, &remaining, NULL); +static int +shadow_keys (int number, char *key[]) +{ + int result = 0; + int i; - if ((argc - remaining) < 1) + if (!number) { - error (0, 0, gettext ("wrong number of arguments")); - argp_help (&argp, stdout, ARGP_HELP_SEE, program_invocation_short_name); - return 1; + struct spwd *sp; + + setspent (); + while ((sp = getspent()) != NULL) + print_shadow (sp); + endpwent (); + return result; } - switch(argv[1][0]) + for (i = 0; i < number; ++i) { - case 'g': /* group */ - if (strcmp (argv[1], "group") == 0) - { - if (argc == 2) - { - struct group *grp; + struct spwd *sp; - setgrent (); - while ((grp = getgrent()) != NULL) - print_group (grp); - endgrent (); - } - else - return group_keys (argc - 2, &argv[2]); - } - else - goto error; - break; - case 'h': /* hosts */ - if (strcmp (argv[1], "hosts") == 0) - { - if (argc == 2) - { - struct hostent *host; + sp = getspnam (key[i]); - sethostent (0); - while ((host = gethostent()) != NULL) - print_hosts (host); - endhostent (); - } - else - return hosts_keys (argc - 2, &argv[2]); - } + if (sp == NULL) + result = 2; else - goto error; - break; - case 'n': /* networks */ - if (strcmp (argv[1], "networks") == 0) - { - if (argc == 2) - { - struct netent *net; + print_shadow (sp); + } - setnetent (0); - while ((net = getnetent()) != NULL) - print_networks (net); - endnetent (); - } - else - return networks_keys (argc - 2, &argv[2]); - } - else - goto error; - break; - case 'p': /* passwd, protocols */ - if (strcmp (argv[1], "passwd") == 0) - { - if (argc == 2) - { - struct passwd *pwd; + return result; +} - setpwent (); - while ((pwd = getpwent()) != NULL) - print_passwd (pwd); - endpwent (); - } - else - return passwd_keys (argc - 2, &argv[2]); - } - else if (strcmp (argv[1], "protocols") == 0) - { - if (argc == 2) - { - struct protoent *proto; +struct + { + const char *name; + int (*func) (int number, char *key[]); + } databases[] = + { +#define D(name) { #name, name ## _keys }, +D(aliases) +D(ethers) +D(group) +D(hosts) +D(netgroup) +D(networks) +D(passwd) +D(protocols) +D(rpc) +D(services) +D(shadow) +#undef D + { NULL, NULL } + }; + +/* build doc */ +static inline void +build_doc (void) +{ + int i, j, len; + char *short_doc, *long_doc, *doc, *p; - setprotoent (0); - while ((proto = getprotoent()) != NULL) - print_protocols (proto); - endprotoent (); - } - else - return protocols_keys (argc - 2, &argv[2]); - } - else - goto error; - break; - case 's': /* services */ - if (strcmp (argv[1], "services") == 0) + short_doc = _("getent - get entries from administrative database."); + long_doc = _("Supported databases:"); + len = strlen (short_doc) + strlen (long_doc) + 3; + + for (i = 0; databases[i].name; ++i) + len += strlen (databases[i].name) + 1; + + doc = (char *) malloc (len); + if (!doc) + doc = short_doc; + else + { + p = stpcpy (doc, short_doc); + *p++ = '\v'; + p = stpcpy (p, long_doc); + *p++ = '\n'; + + for (i = 0, j = 0; databases[i].name; ++i) { - if (argc == 2) + len = strlen (databases[i].name); + if (i) { - struct servent *serv; - - setservent (0); - while ((serv = getservent()) != NULL) - print_services (serv); - endservent (); + if (j + len > 60) + { + j = 0; + *p++ = '\n'; + } + else + *p++ = ' '; } - else - return services_keys (argc - 2, &argv[2]); + + memcpy (p, databases[i].name, len); + p += len; + j += len + 1; } - else - goto error; - break; - default: - error: - fprintf (stderr, _("Unknown database: %s\n"), argv[1]); + } + + argp.doc = doc; +} + +/* the main function */ +int +main (int argc, char *argv[]) +{ + int remaining, i; + + /* Set locale via LC_ALL. */ + setlocale (LC_ALL, ""); + /* Set the text message domain. */ + textdomain (PACKAGE); + + /* Build argp.doc. */ + build_doc (); + + /* Parse and process arguments. */ + argp_parse (&argp, argc, argv, 0, &remaining, NULL); + + if ((argc - remaining) < 1) + { + error (0, 0, gettext ("wrong number of arguments")); argp_help (&argp, stdout, ARGP_HELP_SEE, program_invocation_short_name); return 1; } - return 0; + for (i = 0; databases[i].name; ++i) + if (argv[1][0] == databases[i].name[0] + && !strcmp (argv[1], databases[i].name)) + return databases[i].func (argc - 2, &argv[2]); + + fprintf (stderr, _("Unknown database: %s\n"), argv[1]); + argp_help (&argp, stdout, ARGP_HELP_SEE, program_invocation_short_name); + return 1; } |