-/* Copyright (c) 1998-2008, 2009 Free Software Foundation, Inc.
+/* Copyright (c) 1998-2015 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@suse.de>, 1998.
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
/* getent: get entries from administrative database. */
#include <netdb.h>
#include <pwd.h>
#include <shadow.h>
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Supported options. */
static const struct argp_option args_options[] =
{
- { "service", 's', "CONFIG", 0, N_("Service configuration to be used") },
+ { "service", 's', N_("CONFIG"), 0, N_("Service configuration to be used") },
+ { "no-idn", 'i', NULL, 0, N_("disable IDN encoding") },
{ NULL, 0, NULL, 0, NULL },
};
args_options, parse_option, args_doc, doc, NULL, more_help
};
+/* Additional getaddrinfo flags for IDN encoding. */
+static int idn_flags = AI_IDN | AI_CANONIDN;
+
/* Print the version information. */
static void
print_version (FILE *stream, struct argp_state *state)
{
- fprintf (stream, "getent (GNU %s) %s\n", PACKAGE, VERSION);
+ fprintf (stream, "getent %s%s\n", PKGVERSION, VERSION);
fprintf (stream, gettext ("\
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\
-"), "2009");
+"), "2015");
fprintf (stream, gettext ("Written by %s.\n"), "Thorsten Kukuk");
}
/* This is for aliases */
-static inline void
+static void
print_aliases (struct aliasent *alias)
{
unsigned int i = 0;
}
/* This is for group */
-static inline void
+static void
print_group (struct group *grp)
{
unsigned int i = 0;
struct addrinfo hint;
memset (&hint, '\0', sizeof (hint));
- hint.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG | AI_CANONNAME | xflags;
+ hint.ai_flags = (AI_V4MAPPED | AI_ADDRCONFIG | AI_CANONNAME
+ | idn_flags | xflags);
hint.ai_family = af;
for (i = 0; i < number; ++i)
netgroup_keys (int number, char *key[])
{
int result = 0;
- int i;
if (number == 0)
{
return 3;
}
- for (i = 0; i < number; ++i)
+ if (number == 4)
{
- if (!setnetgrent (key[i]))
+ char *host = strcmp (key[1], "*") == 0 ? NULL : key[1];
+ char *user = strcmp (key[2], "*") == 0 ? NULL : key[2];
+ char *domain = strcmp (key[3], "*") == 0 ? NULL : key[3];
+
+ printf ("%-21s (%s,%s,%s) = %d\n",
+ key[0], host ?: "", user ?: "", domain ?: "",
+ innetgr (key[0], host, user, domain));
+ }
+ else if (number == 1)
+ {
+ if (!setnetgrent (key[0]))
result = 2;
else
{
char *p[3];
- printf ("%-21s", key[i]);
+ printf ("%-21s", key[0]);
while (getnetgrent (p, p + 1, p + 2))
- printf (" (%s, %s, %s)", p[0] ?: " ", p[1] ?: "", p[2] ?: "");
+ printf (" (%s,%s,%s)", p[0] ?: " ", p[1] ?: "", p[2] ?: "");
putchar_unlocked ('\n');
}
}
return result;
}
+/* This is for initgroups */
+static int
+initgroups_keys (int number, char *key[])
+{
+ int ngrps = 100;
+ size_t grpslen = ngrps * sizeof (gid_t);
+ gid_t *grps = alloca (grpslen);
+
+ if (number == 0)
+ {
+ fprintf (stderr, _("Enumeration not supported on %s\n"), "initgroups");
+ return 3;
+ }
+
+ for (int i = 0; i < number; ++i)
+ {
+ int no = ngrps;
+ int n;
+ while ((n = getgrouplist (key[i], -1, grps, &no)) == -1
+ && no > ngrps)
+ {
+ grps = extend_alloca (grps, grpslen, no * sizeof (gid_t));
+ ngrps = no;
+ }
+
+ if (n == -1)
+ return 1;
+
+ printf ("%-21s", key[i]);
+ for (int j = 0; j < n; ++j)
+ if (grps[j] != -1)
+ printf (" %ld", (long int) grps[j]);
+ putchar_unlocked ('\n');
+ }
+
+ return 0;
+}
+
/* This is for networks */
static void
print_networks (struct netent *net)
}
/* Now is all for passwd */
-static inline void
+static void
print_passwd (struct passwd *pwd)
{
printf ("%s:%s:%lu:%lu:%s:%s:%s\n",
}
/* This is for protocols */
-static inline void
+static void
print_protocols (struct protoent *proto)
{
unsigned int i;
}
/* Now is all for rpc */
-static inline void
+static void
print_rpc (struct rpcent *rpc)
{
int i;
if (proto != NULL)
*proto++ = '\0';
- if (isdigit (key[i][0]))
- serv = getservbyport (htons (atol (key[i])), proto);
+ char *endptr;
+ long port = strtol (key[i], &endptr, 10);
+
+ if (isdigit (key[i][0]) && *endptr == '\0'
+ && 0 <= port && port <= 65535)
+ serv = getservbyport (htons (port), proto);
else
serv = getservbyname (key[i], proto);
setspent ();
while ((sp = getspent ()) != NULL)
print_shadow (sp);
- endpwent ();
+ endspent ();
return result;
}
D(group)
D(gshadow)
D(hosts)
+D(initgroups)
D(netgroup)
D(networks)
D(passwd)
}
break;
+ case 'i':
+ idn_flags = 0;
+ break;
+
default:
return ARGP_ERR_UNKNOWN;
}
fputs ("\n\n", fp);
- fputs (gettext ("\
+ fprintf (fp, gettext ("\
For bug reporting instructions, please see:\n\
-<http://www.gnu.org/software/libc/bugs.html>.\n"), fp);
+%s.\n"), REPORT_BUGS_TO);
if (fclose (fp) == 0)
return doc;