1c912a3f7SMaxim Konovalov /* $NetBSD: getent.c,v 1.7 2005/08/24 14:31:02 ginsbach Exp $ */ 2c912a3f7SMaxim Konovalov 3c912a3f7SMaxim Konovalov /*- 4c912a3f7SMaxim Konovalov * Copyright (c) 2004 The NetBSD Foundation, Inc. 5c912a3f7SMaxim Konovalov * All rights reserved. 6c912a3f7SMaxim Konovalov * 7c912a3f7SMaxim Konovalov * This code is derived from software contributed to The NetBSD Foundation 8c912a3f7SMaxim Konovalov * by Luke Mewburn. 9c912a3f7SMaxim Konovalov * 10c912a3f7SMaxim Konovalov * Redistribution and use in source and binary forms, with or without 11c912a3f7SMaxim Konovalov * modification, are permitted provided that the following conditions 12c912a3f7SMaxim Konovalov * are met: 13c912a3f7SMaxim Konovalov * 1. Redistributions of source code must retain the above copyright 14c912a3f7SMaxim Konovalov * notice, this list of conditions and the following disclaimer. 15c912a3f7SMaxim Konovalov * 2. Redistributions in binary form must reproduce the above copyright 16c912a3f7SMaxim Konovalov * notice, this list of conditions and the following disclaimer in the 17c912a3f7SMaxim Konovalov * documentation and/or other materials provided with the distribution. 18c912a3f7SMaxim Konovalov * 19c912a3f7SMaxim Konovalov * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20c912a3f7SMaxim Konovalov * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21c912a3f7SMaxim Konovalov * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22c912a3f7SMaxim Konovalov * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23c912a3f7SMaxim Konovalov * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24c912a3f7SMaxim Konovalov * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25c912a3f7SMaxim Konovalov * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26c912a3f7SMaxim Konovalov * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27c912a3f7SMaxim Konovalov * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28c912a3f7SMaxim Konovalov * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29c912a3f7SMaxim Konovalov * POSSIBILITY OF SUCH DAMAGE. 30c912a3f7SMaxim Konovalov */ 31c912a3f7SMaxim Konovalov 32c912a3f7SMaxim Konovalov #include <sys/cdefs.h> 33c912a3f7SMaxim Konovalov __FBSDID("$FreeBSD$"); 34c912a3f7SMaxim Konovalov 35c912a3f7SMaxim Konovalov #include <sys/socket.h> 36c912a3f7SMaxim Konovalov #include <sys/param.h> 37c912a3f7SMaxim Konovalov #include <arpa/inet.h> 38c912a3f7SMaxim Konovalov #include <arpa/nameser.h> 39c912a3f7SMaxim Konovalov #include <net/if.h> 40c912a3f7SMaxim Konovalov #include <netinet/if_ether.h> 41c912a3f7SMaxim Konovalov #include <netinet/in.h> /* for INET6_ADDRSTRLEN */ 42c912a3f7SMaxim Konovalov #include <rpc/rpcent.h> 43c912a3f7SMaxim Konovalov 44c912a3f7SMaxim Konovalov #include <assert.h> 45c912a3f7SMaxim Konovalov #include <ctype.h> 46c912a3f7SMaxim Konovalov #include <errno.h> 47c912a3f7SMaxim Konovalov #include <grp.h> 48c912a3f7SMaxim Konovalov #include <limits.h> 49c912a3f7SMaxim Konovalov #include <netdb.h> 50c912a3f7SMaxim Konovalov #include <pwd.h> 51c912a3f7SMaxim Konovalov #include <stdarg.h> 5232fc554eSEd Schouten #include <stdint.h> 5332fc554eSEd Schouten #include <stdio.h> 54c912a3f7SMaxim Konovalov #include <stdlib.h> 55c912a3f7SMaxim Konovalov #include <string.h> 56c912a3f7SMaxim Konovalov #include <unistd.h> 5786586473SEd Schouten #include <utmpx.h> 58c912a3f7SMaxim Konovalov 59c912a3f7SMaxim Konovalov static int usage(void); 60c912a3f7SMaxim Konovalov static int parsenum(const char *, unsigned long *); 61c912a3f7SMaxim Konovalov static int ethers(int, char *[]); 62c912a3f7SMaxim Konovalov static int group(int, char *[]); 63c912a3f7SMaxim Konovalov static int hosts(int, char *[]); 6408ad1a7aSGuy Helmer static int netgroup(int, char *[]); 65c912a3f7SMaxim Konovalov static int networks(int, char *[]); 66c912a3f7SMaxim Konovalov static int passwd(int, char *[]); 67c912a3f7SMaxim Konovalov static int protocols(int, char *[]); 68c912a3f7SMaxim Konovalov static int rpc(int, char *[]); 69c912a3f7SMaxim Konovalov static int services(int, char *[]); 70c912a3f7SMaxim Konovalov static int shells(int, char *[]); 7186586473SEd Schouten static int utmpx(int, char *[]); 72c912a3f7SMaxim Konovalov 73c912a3f7SMaxim Konovalov enum { 74c912a3f7SMaxim Konovalov RV_OK = 0, 75c912a3f7SMaxim Konovalov RV_USAGE = 1, 76c912a3f7SMaxim Konovalov RV_NOTFOUND = 2, 773181f555SRalf S. Engelschall RV_NOENUM = 3 78c912a3f7SMaxim Konovalov }; 79c912a3f7SMaxim Konovalov 80c912a3f7SMaxim Konovalov static struct getentdb { 81c912a3f7SMaxim Konovalov const char *name; 82c912a3f7SMaxim Konovalov int (*callback)(int, char *[]); 83c912a3f7SMaxim Konovalov } databases[] = { 84c912a3f7SMaxim Konovalov { "ethers", ethers, }, 85c912a3f7SMaxim Konovalov { "group", group, }, 86c912a3f7SMaxim Konovalov { "hosts", hosts, }, 87*0f1c6d28SMark Johnston { "netgroup", netgroup, }, 88c912a3f7SMaxim Konovalov { "networks", networks, }, 89c912a3f7SMaxim Konovalov { "passwd", passwd, }, 90c912a3f7SMaxim Konovalov { "protocols", protocols, }, 91c912a3f7SMaxim Konovalov { "rpc", rpc, }, 92c912a3f7SMaxim Konovalov { "services", services, }, 93c912a3f7SMaxim Konovalov { "shells", shells, }, 9486586473SEd Schouten { "utmpx", utmpx, }, 95c912a3f7SMaxim Konovalov 96c912a3f7SMaxim Konovalov { NULL, NULL, }, 97c912a3f7SMaxim Konovalov }; 98c912a3f7SMaxim Konovalov 99c912a3f7SMaxim Konovalov int 100c912a3f7SMaxim Konovalov main(int argc, char *argv[]) 101c912a3f7SMaxim Konovalov { 102c912a3f7SMaxim Konovalov struct getentdb *curdb; 103c912a3f7SMaxim Konovalov 104c912a3f7SMaxim Konovalov setprogname(argv[0]); 105c912a3f7SMaxim Konovalov 106c912a3f7SMaxim Konovalov if (argc < 2) 107c912a3f7SMaxim Konovalov usage(); 108c912a3f7SMaxim Konovalov for (curdb = databases; curdb->name != NULL; curdb++) { 109c912a3f7SMaxim Konovalov if (strcmp(curdb->name, argv[1]) == 0) { 110c912a3f7SMaxim Konovalov exit(curdb->callback(argc, argv)); 111c912a3f7SMaxim Konovalov } 112c912a3f7SMaxim Konovalov } 113c912a3f7SMaxim Konovalov fprintf(stderr, "Unknown database: %s\n", argv[1]); 114c912a3f7SMaxim Konovalov usage(); 115c912a3f7SMaxim Konovalov /* NOTREACHED */ 116c912a3f7SMaxim Konovalov return RV_USAGE; 117c912a3f7SMaxim Konovalov } 118c912a3f7SMaxim Konovalov 119c912a3f7SMaxim Konovalov static int 120c912a3f7SMaxim Konovalov usage(void) 121c912a3f7SMaxim Konovalov { 122c912a3f7SMaxim Konovalov struct getentdb *curdb; 123c912a3f7SMaxim Konovalov 124c912a3f7SMaxim Konovalov fprintf(stderr, "Usage: %s database [key ...]\n", 125c912a3f7SMaxim Konovalov getprogname()); 126c912a3f7SMaxim Konovalov fprintf(stderr, " database may be one of:\n\t"); 127c912a3f7SMaxim Konovalov for (curdb = databases; curdb->name != NULL; curdb++) { 128c912a3f7SMaxim Konovalov fprintf(stderr, " %s", curdb->name); 129c912a3f7SMaxim Konovalov } 130c912a3f7SMaxim Konovalov fprintf(stderr, "\n"); 131c912a3f7SMaxim Konovalov exit(RV_USAGE); 132c912a3f7SMaxim Konovalov /* NOTREACHED */ 133c912a3f7SMaxim Konovalov } 134c912a3f7SMaxim Konovalov 135c912a3f7SMaxim Konovalov static int 136c912a3f7SMaxim Konovalov parsenum(const char *word, unsigned long *result) 137c912a3f7SMaxim Konovalov { 138c912a3f7SMaxim Konovalov unsigned long num; 139c912a3f7SMaxim Konovalov char *ep; 140c912a3f7SMaxim Konovalov 141c912a3f7SMaxim Konovalov assert(word != NULL); 142c912a3f7SMaxim Konovalov assert(result != NULL); 143c912a3f7SMaxim Konovalov 144c912a3f7SMaxim Konovalov if (!isdigit((unsigned char)word[0])) 145c912a3f7SMaxim Konovalov return 0; 146c912a3f7SMaxim Konovalov errno = 0; 147c912a3f7SMaxim Konovalov num = strtoul(word, &ep, 10); 148c912a3f7SMaxim Konovalov if (num == ULONG_MAX && errno == ERANGE) 149c912a3f7SMaxim Konovalov return 0; 150c912a3f7SMaxim Konovalov if (*ep != '\0') 151c912a3f7SMaxim Konovalov return 0; 152c912a3f7SMaxim Konovalov *result = num; 153c912a3f7SMaxim Konovalov return 1; 154c912a3f7SMaxim Konovalov } 155c912a3f7SMaxim Konovalov 156c912a3f7SMaxim Konovalov /* 157c912a3f7SMaxim Konovalov * printfmtstrings -- 158c912a3f7SMaxim Konovalov * vprintf(format, ...), 159c912a3f7SMaxim Konovalov * then the aliases (beginning with prefix, separated by sep), 160c912a3f7SMaxim Konovalov * then a newline 161c912a3f7SMaxim Konovalov */ 162c912a3f7SMaxim Konovalov static void 163c912a3f7SMaxim Konovalov printfmtstrings(char *strings[], const char *prefix, const char *sep, 164c912a3f7SMaxim Konovalov const char *fmt, ...) 165c912a3f7SMaxim Konovalov { 166c912a3f7SMaxim Konovalov va_list ap; 167c912a3f7SMaxim Konovalov const char *curpref; 168c912a3f7SMaxim Konovalov int i; 169c912a3f7SMaxim Konovalov 170c912a3f7SMaxim Konovalov va_start(ap, fmt); 171c912a3f7SMaxim Konovalov vprintf(fmt, ap); 172c912a3f7SMaxim Konovalov 173c912a3f7SMaxim Konovalov curpref = prefix; 174c912a3f7SMaxim Konovalov for (i = 0; strings[i] != NULL; i++) { 175c912a3f7SMaxim Konovalov printf("%s%s", curpref, strings[i]); 176c912a3f7SMaxim Konovalov curpref = sep; 177c912a3f7SMaxim Konovalov } 178c912a3f7SMaxim Konovalov printf("\n"); 1793181f555SRalf S. Engelschall va_end(ap); 180c912a3f7SMaxim Konovalov } 181c912a3f7SMaxim Konovalov 182c912a3f7SMaxim Konovalov /* 183c912a3f7SMaxim Konovalov * ethers 184c912a3f7SMaxim Konovalov */ 185c912a3f7SMaxim Konovalov static int 186c912a3f7SMaxim Konovalov ethers(int argc, char *argv[]) 187c912a3f7SMaxim Konovalov { 188c912a3f7SMaxim Konovalov char hostname[MAXHOSTNAMELEN + 1], *hp; 189c912a3f7SMaxim Konovalov struct ether_addr ea, *eap; 190c912a3f7SMaxim Konovalov int i, rv; 191c912a3f7SMaxim Konovalov 192c912a3f7SMaxim Konovalov assert(argc > 1); 193c912a3f7SMaxim Konovalov assert(argv != NULL); 194c912a3f7SMaxim Konovalov 195c912a3f7SMaxim Konovalov #define ETHERSPRINT printf("%-17s %s\n", ether_ntoa(eap), hp) 196c912a3f7SMaxim Konovalov 197c912a3f7SMaxim Konovalov rv = RV_OK; 198c912a3f7SMaxim Konovalov if (argc == 2) { 199c912a3f7SMaxim Konovalov fprintf(stderr, "Enumeration not supported on ethers\n"); 200c912a3f7SMaxim Konovalov rv = RV_NOENUM; 201c912a3f7SMaxim Konovalov } else { 202c912a3f7SMaxim Konovalov for (i = 2; i < argc; i++) { 203c912a3f7SMaxim Konovalov if ((eap = ether_aton(argv[i])) == NULL) { 204c912a3f7SMaxim Konovalov eap = &ea; 205c912a3f7SMaxim Konovalov hp = argv[i]; 206c912a3f7SMaxim Konovalov if (ether_hostton(hp, eap) != 0) { 207c912a3f7SMaxim Konovalov rv = RV_NOTFOUND; 208c912a3f7SMaxim Konovalov break; 209c912a3f7SMaxim Konovalov } 210c912a3f7SMaxim Konovalov } else { 211c912a3f7SMaxim Konovalov hp = hostname; 212c912a3f7SMaxim Konovalov if (ether_ntohost(hp, eap) != 0) { 213c912a3f7SMaxim Konovalov rv = RV_NOTFOUND; 214c912a3f7SMaxim Konovalov break; 215c912a3f7SMaxim Konovalov } 216c912a3f7SMaxim Konovalov } 217c912a3f7SMaxim Konovalov ETHERSPRINT; 218c912a3f7SMaxim Konovalov } 219c912a3f7SMaxim Konovalov } 220c912a3f7SMaxim Konovalov return rv; 221c912a3f7SMaxim Konovalov } 222c912a3f7SMaxim Konovalov 223c912a3f7SMaxim Konovalov /* 224c912a3f7SMaxim Konovalov * group 225c912a3f7SMaxim Konovalov */ 226c912a3f7SMaxim Konovalov 227c912a3f7SMaxim Konovalov static int 228c912a3f7SMaxim Konovalov group(int argc, char *argv[]) 229c912a3f7SMaxim Konovalov { 230c912a3f7SMaxim Konovalov struct group *gr; 231c912a3f7SMaxim Konovalov unsigned long id; 232c912a3f7SMaxim Konovalov int i, rv; 233c912a3f7SMaxim Konovalov 234c912a3f7SMaxim Konovalov assert(argc > 1); 235c912a3f7SMaxim Konovalov assert(argv != NULL); 236c912a3f7SMaxim Konovalov 237c912a3f7SMaxim Konovalov #define GROUPPRINT printfmtstrings(gr->gr_mem, ":", ",", "%s:%s:%u", \ 238c912a3f7SMaxim Konovalov gr->gr_name, gr->gr_passwd, gr->gr_gid) 239c912a3f7SMaxim Konovalov 240c912a3f7SMaxim Konovalov setgroupent(1); 241c912a3f7SMaxim Konovalov rv = RV_OK; 242c912a3f7SMaxim Konovalov if (argc == 2) { 243c912a3f7SMaxim Konovalov while ((gr = getgrent()) != NULL) 244c912a3f7SMaxim Konovalov GROUPPRINT; 245c912a3f7SMaxim Konovalov } else { 246c912a3f7SMaxim Konovalov for (i = 2; i < argc; i++) { 247c912a3f7SMaxim Konovalov if (parsenum(argv[i], &id)) 248c912a3f7SMaxim Konovalov gr = getgrgid((gid_t)id); 249c912a3f7SMaxim Konovalov else 250c912a3f7SMaxim Konovalov gr = getgrnam(argv[i]); 251c912a3f7SMaxim Konovalov if (gr != NULL) 252c912a3f7SMaxim Konovalov GROUPPRINT; 253c912a3f7SMaxim Konovalov else { 254c912a3f7SMaxim Konovalov rv = RV_NOTFOUND; 255c912a3f7SMaxim Konovalov break; 256c912a3f7SMaxim Konovalov } 257c912a3f7SMaxim Konovalov } 258c912a3f7SMaxim Konovalov } 259c912a3f7SMaxim Konovalov endgrent(); 260c912a3f7SMaxim Konovalov return rv; 261c912a3f7SMaxim Konovalov } 262c912a3f7SMaxim Konovalov 263c912a3f7SMaxim Konovalov 264c912a3f7SMaxim Konovalov /* 265c912a3f7SMaxim Konovalov * hosts 266c912a3f7SMaxim Konovalov */ 267c912a3f7SMaxim Konovalov 268c912a3f7SMaxim Konovalov static void 269c912a3f7SMaxim Konovalov hostsprint(const struct hostent *he) 270c912a3f7SMaxim Konovalov { 271c912a3f7SMaxim Konovalov char buf[INET6_ADDRSTRLEN]; 272c912a3f7SMaxim Konovalov 273c912a3f7SMaxim Konovalov assert(he != NULL); 274c912a3f7SMaxim Konovalov if (inet_ntop(he->h_addrtype, he->h_addr, buf, sizeof(buf)) == NULL) 275c912a3f7SMaxim Konovalov strlcpy(buf, "# unknown", sizeof(buf)); 276c912a3f7SMaxim Konovalov printfmtstrings(he->h_aliases, " ", " ", "%-16s %s", buf, he->h_name); 277c912a3f7SMaxim Konovalov } 278c912a3f7SMaxim Konovalov 279c912a3f7SMaxim Konovalov static int 280c912a3f7SMaxim Konovalov hosts(int argc, char *argv[]) 281c912a3f7SMaxim Konovalov { 282d1f1954bSKevin Lo struct hostent *he4, *he6; 283c912a3f7SMaxim Konovalov char addr[IN6ADDRSZ]; 284c912a3f7SMaxim Konovalov int i, rv; 285c912a3f7SMaxim Konovalov 286c912a3f7SMaxim Konovalov assert(argc > 1); 287c912a3f7SMaxim Konovalov assert(argv != NULL); 288c912a3f7SMaxim Konovalov 289c912a3f7SMaxim Konovalov sethostent(1); 290d1f1954bSKevin Lo he4 = he6 = NULL; 291c912a3f7SMaxim Konovalov rv = RV_OK; 292c912a3f7SMaxim Konovalov if (argc == 2) { 293d1f1954bSKevin Lo while ((he4 = gethostent()) != NULL) 294d1f1954bSKevin Lo hostsprint(he4); 295c912a3f7SMaxim Konovalov } else { 296c912a3f7SMaxim Konovalov for (i = 2; i < argc; i++) { 297d1f1954bSKevin Lo if (inet_pton(AF_INET6, argv[i], (void *)addr) > 0) { 298d1f1954bSKevin Lo he6 = gethostbyaddr(addr, IN6ADDRSZ, AF_INET6); 299d1f1954bSKevin Lo if (he6 != NULL) 300d1f1954bSKevin Lo hostsprint(he6); 301d1f1954bSKevin Lo } else if (inet_pton(AF_INET, argv[i], 302d1f1954bSKevin Lo (void *)addr) > 0) { 303d1f1954bSKevin Lo he4 = gethostbyaddr(addr, INADDRSZ, AF_INET); 304d1f1954bSKevin Lo if (he4 != NULL) 305d1f1954bSKevin Lo hostsprint(he4); 306d1f1954bSKevin Lo } else { 307d1f1954bSKevin Lo he6 = gethostbyname2(argv[i], AF_INET6); 308d1f1954bSKevin Lo if (he6 != NULL) 309d1f1954bSKevin Lo hostsprint(he6); 310d1f1954bSKevin Lo he4 = gethostbyname(argv[i]); 311d1f1954bSKevin Lo if (he4 != NULL) 312d1f1954bSKevin Lo hostsprint(he4); 313d1f1954bSKevin Lo } 314d1f1954bSKevin Lo if ( he4 == NULL && he6 == NULL ) { 315c912a3f7SMaxim Konovalov rv = RV_NOTFOUND; 316c912a3f7SMaxim Konovalov break; 317c912a3f7SMaxim Konovalov } 318c912a3f7SMaxim Konovalov } 319c912a3f7SMaxim Konovalov } 320c912a3f7SMaxim Konovalov endhostent(); 321c912a3f7SMaxim Konovalov return rv; 322c912a3f7SMaxim Konovalov } 323c912a3f7SMaxim Konovalov 324c912a3f7SMaxim Konovalov /* 325c912a3f7SMaxim Konovalov * networks 326c912a3f7SMaxim Konovalov */ 327c912a3f7SMaxim Konovalov static void 328c912a3f7SMaxim Konovalov networksprint(const struct netent *ne) 329c912a3f7SMaxim Konovalov { 330c912a3f7SMaxim Konovalov char buf[INET6_ADDRSTRLEN]; 331c912a3f7SMaxim Konovalov struct in_addr ianet; 332c912a3f7SMaxim Konovalov 333c912a3f7SMaxim Konovalov assert(ne != NULL); 334c912a3f7SMaxim Konovalov ianet = inet_makeaddr(ne->n_net, 0); 335c912a3f7SMaxim Konovalov if (inet_ntop(ne->n_addrtype, &ianet, buf, sizeof(buf)) == NULL) 336c912a3f7SMaxim Konovalov strlcpy(buf, "# unknown", sizeof(buf)); 337c912a3f7SMaxim Konovalov printfmtstrings(ne->n_aliases, " ", " ", "%-16s %s", ne->n_name, buf); 338c912a3f7SMaxim Konovalov } 339c912a3f7SMaxim Konovalov 340c912a3f7SMaxim Konovalov static int 341c912a3f7SMaxim Konovalov networks(int argc, char *argv[]) 342c912a3f7SMaxim Konovalov { 343c912a3f7SMaxim Konovalov struct netent *ne; 344c912a3f7SMaxim Konovalov in_addr_t net; 345c912a3f7SMaxim Konovalov int i, rv; 346c912a3f7SMaxim Konovalov 347c912a3f7SMaxim Konovalov assert(argc > 1); 348c912a3f7SMaxim Konovalov assert(argv != NULL); 349c912a3f7SMaxim Konovalov 350c912a3f7SMaxim Konovalov setnetent(1); 351c912a3f7SMaxim Konovalov rv = RV_OK; 352c912a3f7SMaxim Konovalov if (argc == 2) { 353c912a3f7SMaxim Konovalov while ((ne = getnetent()) != NULL) 354c912a3f7SMaxim Konovalov networksprint(ne); 355c912a3f7SMaxim Konovalov } else { 356c912a3f7SMaxim Konovalov for (i = 2; i < argc; i++) { 357c912a3f7SMaxim Konovalov net = inet_network(argv[i]); 358c912a3f7SMaxim Konovalov if (net != INADDR_NONE) 359c912a3f7SMaxim Konovalov ne = getnetbyaddr(net, AF_INET); 360c912a3f7SMaxim Konovalov else 361c912a3f7SMaxim Konovalov ne = getnetbyname(argv[i]); 362c912a3f7SMaxim Konovalov if (ne != NULL) 363c912a3f7SMaxim Konovalov networksprint(ne); 364c912a3f7SMaxim Konovalov else { 365c912a3f7SMaxim Konovalov rv = RV_NOTFOUND; 366c912a3f7SMaxim Konovalov break; 367c912a3f7SMaxim Konovalov } 368c912a3f7SMaxim Konovalov } 369c912a3f7SMaxim Konovalov } 370c912a3f7SMaxim Konovalov endnetent(); 371c912a3f7SMaxim Konovalov return rv; 372c912a3f7SMaxim Konovalov } 373c912a3f7SMaxim Konovalov 374c912a3f7SMaxim Konovalov /* 375c912a3f7SMaxim Konovalov * passwd 376c912a3f7SMaxim Konovalov */ 377c912a3f7SMaxim Konovalov static int 378c912a3f7SMaxim Konovalov passwd(int argc, char *argv[]) 379c912a3f7SMaxim Konovalov { 380c912a3f7SMaxim Konovalov struct passwd *pw; 381c912a3f7SMaxim Konovalov unsigned long id; 382c912a3f7SMaxim Konovalov int i, rv; 383c912a3f7SMaxim Konovalov 384c912a3f7SMaxim Konovalov assert(argc > 1); 385c912a3f7SMaxim Konovalov assert(argv != NULL); 386c912a3f7SMaxim Konovalov 387c912a3f7SMaxim Konovalov #define PASSWDPRINT printf("%s:%s:%u:%u:%s:%s:%s\n", \ 388c912a3f7SMaxim Konovalov pw->pw_name, pw->pw_passwd, pw->pw_uid, \ 389c912a3f7SMaxim Konovalov pw->pw_gid, pw->pw_gecos, pw->pw_dir, pw->pw_shell) 390c912a3f7SMaxim Konovalov 391c912a3f7SMaxim Konovalov setpassent(1); 392c912a3f7SMaxim Konovalov rv = RV_OK; 393c912a3f7SMaxim Konovalov if (argc == 2) { 394c912a3f7SMaxim Konovalov while ((pw = getpwent()) != NULL) 395c912a3f7SMaxim Konovalov PASSWDPRINT; 396c912a3f7SMaxim Konovalov } else { 397c912a3f7SMaxim Konovalov for (i = 2; i < argc; i++) { 398c912a3f7SMaxim Konovalov if (parsenum(argv[i], &id)) 399c912a3f7SMaxim Konovalov pw = getpwuid((uid_t)id); 400c912a3f7SMaxim Konovalov else 401c912a3f7SMaxim Konovalov pw = getpwnam(argv[i]); 402c912a3f7SMaxim Konovalov if (pw != NULL) 403c912a3f7SMaxim Konovalov PASSWDPRINT; 404c912a3f7SMaxim Konovalov else { 405c912a3f7SMaxim Konovalov rv = RV_NOTFOUND; 406c912a3f7SMaxim Konovalov break; 407c912a3f7SMaxim Konovalov } 408c912a3f7SMaxim Konovalov } 409c912a3f7SMaxim Konovalov } 410c912a3f7SMaxim Konovalov endpwent(); 411c912a3f7SMaxim Konovalov return rv; 412c912a3f7SMaxim Konovalov } 413c912a3f7SMaxim Konovalov 414c912a3f7SMaxim Konovalov /* 415c912a3f7SMaxim Konovalov * protocols 416c912a3f7SMaxim Konovalov */ 417c912a3f7SMaxim Konovalov static int 418c912a3f7SMaxim Konovalov protocols(int argc, char *argv[]) 419c912a3f7SMaxim Konovalov { 420c912a3f7SMaxim Konovalov struct protoent *pe; 421c912a3f7SMaxim Konovalov unsigned long id; 422c912a3f7SMaxim Konovalov int i, rv; 423c912a3f7SMaxim Konovalov 424c912a3f7SMaxim Konovalov assert(argc > 1); 425c912a3f7SMaxim Konovalov assert(argv != NULL); 426c912a3f7SMaxim Konovalov 427c912a3f7SMaxim Konovalov #define PROTOCOLSPRINT printfmtstrings(pe->p_aliases, " ", " ", \ 428c912a3f7SMaxim Konovalov "%-16s %5d", pe->p_name, pe->p_proto) 429c912a3f7SMaxim Konovalov 430c912a3f7SMaxim Konovalov setprotoent(1); 431c912a3f7SMaxim Konovalov rv = RV_OK; 432c912a3f7SMaxim Konovalov if (argc == 2) { 433c912a3f7SMaxim Konovalov while ((pe = getprotoent()) != NULL) 434c912a3f7SMaxim Konovalov PROTOCOLSPRINT; 435c912a3f7SMaxim Konovalov } else { 436c912a3f7SMaxim Konovalov for (i = 2; i < argc; i++) { 437c912a3f7SMaxim Konovalov if (parsenum(argv[i], &id)) 438c912a3f7SMaxim Konovalov pe = getprotobynumber((int)id); 439c912a3f7SMaxim Konovalov else 440c912a3f7SMaxim Konovalov pe = getprotobyname(argv[i]); 441c912a3f7SMaxim Konovalov if (pe != NULL) 442c912a3f7SMaxim Konovalov PROTOCOLSPRINT; 443c912a3f7SMaxim Konovalov else { 444c912a3f7SMaxim Konovalov rv = RV_NOTFOUND; 445c912a3f7SMaxim Konovalov break; 446c912a3f7SMaxim Konovalov } 447c912a3f7SMaxim Konovalov } 448c912a3f7SMaxim Konovalov } 449c912a3f7SMaxim Konovalov endprotoent(); 450c912a3f7SMaxim Konovalov return rv; 451c912a3f7SMaxim Konovalov } 452c912a3f7SMaxim Konovalov 453c912a3f7SMaxim Konovalov /* 454c912a3f7SMaxim Konovalov * rpc 455c912a3f7SMaxim Konovalov */ 456c912a3f7SMaxim Konovalov static int 457c912a3f7SMaxim Konovalov rpc(int argc, char *argv[]) 458c912a3f7SMaxim Konovalov { 459c912a3f7SMaxim Konovalov struct rpcent *re; 460c912a3f7SMaxim Konovalov unsigned long id; 461c912a3f7SMaxim Konovalov int i, rv; 462c912a3f7SMaxim Konovalov 463c912a3f7SMaxim Konovalov assert(argc > 1); 464c912a3f7SMaxim Konovalov assert(argv != NULL); 465c912a3f7SMaxim Konovalov 466c912a3f7SMaxim Konovalov #define RPCPRINT printfmtstrings(re->r_aliases, " ", " ", \ 467c912a3f7SMaxim Konovalov "%-16s %6d", \ 468c912a3f7SMaxim Konovalov re->r_name, re->r_number) 469c912a3f7SMaxim Konovalov 470c912a3f7SMaxim Konovalov setrpcent(1); 471c912a3f7SMaxim Konovalov rv = RV_OK; 472c912a3f7SMaxim Konovalov if (argc == 2) { 473c912a3f7SMaxim Konovalov while ((re = getrpcent()) != NULL) 474c912a3f7SMaxim Konovalov RPCPRINT; 475c912a3f7SMaxim Konovalov } else { 476c912a3f7SMaxim Konovalov for (i = 2; i < argc; i++) { 477c912a3f7SMaxim Konovalov if (parsenum(argv[i], &id)) 478c912a3f7SMaxim Konovalov re = getrpcbynumber((int)id); 479c912a3f7SMaxim Konovalov else 480c912a3f7SMaxim Konovalov re = getrpcbyname(argv[i]); 481c912a3f7SMaxim Konovalov if (re != NULL) 482c912a3f7SMaxim Konovalov RPCPRINT; 483c912a3f7SMaxim Konovalov else { 484c912a3f7SMaxim Konovalov rv = RV_NOTFOUND; 485c912a3f7SMaxim Konovalov break; 486c912a3f7SMaxim Konovalov } 487c912a3f7SMaxim Konovalov } 488c912a3f7SMaxim Konovalov } 489c912a3f7SMaxim Konovalov endrpcent(); 490c912a3f7SMaxim Konovalov return rv; 491c912a3f7SMaxim Konovalov } 492c912a3f7SMaxim Konovalov 493c912a3f7SMaxim Konovalov /* 494c912a3f7SMaxim Konovalov * services 495c912a3f7SMaxim Konovalov */ 496c912a3f7SMaxim Konovalov static int 497c912a3f7SMaxim Konovalov services(int argc, char *argv[]) 498c912a3f7SMaxim Konovalov { 499c912a3f7SMaxim Konovalov struct servent *se; 500c912a3f7SMaxim Konovalov unsigned long id; 501c912a3f7SMaxim Konovalov char *proto; 502c912a3f7SMaxim Konovalov int i, rv; 503c912a3f7SMaxim Konovalov 504c912a3f7SMaxim Konovalov assert(argc > 1); 505c912a3f7SMaxim Konovalov assert(argv != NULL); 506c912a3f7SMaxim Konovalov 507c912a3f7SMaxim Konovalov #define SERVICESPRINT printfmtstrings(se->s_aliases, " ", " ", \ 508c912a3f7SMaxim Konovalov "%-16s %5d/%s", \ 509c912a3f7SMaxim Konovalov se->s_name, ntohs(se->s_port), se->s_proto) 510c912a3f7SMaxim Konovalov 511c912a3f7SMaxim Konovalov setservent(1); 512c912a3f7SMaxim Konovalov rv = RV_OK; 513c912a3f7SMaxim Konovalov if (argc == 2) { 514c912a3f7SMaxim Konovalov while ((se = getservent()) != NULL) 515c912a3f7SMaxim Konovalov SERVICESPRINT; 516c912a3f7SMaxim Konovalov } else { 517c912a3f7SMaxim Konovalov for (i = 2; i < argc; i++) { 518c912a3f7SMaxim Konovalov proto = strchr(argv[i], '/'); 519c912a3f7SMaxim Konovalov if (proto != NULL) 520c912a3f7SMaxim Konovalov *proto++ = '\0'; 521920b61d0SHajimu UMEMOTO if (parsenum(argv[i], &id)) 522920b61d0SHajimu UMEMOTO se = getservbyport(htons((u_short)id), proto); 523920b61d0SHajimu UMEMOTO else 524c912a3f7SMaxim Konovalov se = getservbyname(argv[i], proto); 525c912a3f7SMaxim Konovalov if (se != NULL) 526c912a3f7SMaxim Konovalov SERVICESPRINT; 527c912a3f7SMaxim Konovalov else { 528c912a3f7SMaxim Konovalov rv = RV_NOTFOUND; 529c912a3f7SMaxim Konovalov break; 530c912a3f7SMaxim Konovalov } 531c912a3f7SMaxim Konovalov } 532c912a3f7SMaxim Konovalov } 533c912a3f7SMaxim Konovalov endservent(); 534c912a3f7SMaxim Konovalov return rv; 535c912a3f7SMaxim Konovalov } 536c912a3f7SMaxim Konovalov 537c912a3f7SMaxim Konovalov /* 538c912a3f7SMaxim Konovalov * shells 539c912a3f7SMaxim Konovalov */ 540c912a3f7SMaxim Konovalov static int 541c912a3f7SMaxim Konovalov shells(int argc, char *argv[]) 542c912a3f7SMaxim Konovalov { 543c912a3f7SMaxim Konovalov const char *sh; 544c912a3f7SMaxim Konovalov int i, rv; 545c912a3f7SMaxim Konovalov 546c912a3f7SMaxim Konovalov assert(argc > 1); 547c912a3f7SMaxim Konovalov assert(argv != NULL); 548c912a3f7SMaxim Konovalov 549c912a3f7SMaxim Konovalov #define SHELLSPRINT printf("%s\n", sh) 550c912a3f7SMaxim Konovalov 551c912a3f7SMaxim Konovalov setusershell(); 552c912a3f7SMaxim Konovalov rv = RV_OK; 553c912a3f7SMaxim Konovalov if (argc == 2) { 554c912a3f7SMaxim Konovalov while ((sh = getusershell()) != NULL) 555c912a3f7SMaxim Konovalov SHELLSPRINT; 556c912a3f7SMaxim Konovalov } else { 557c912a3f7SMaxim Konovalov for (i = 2; i < argc; i++) { 558c912a3f7SMaxim Konovalov setusershell(); 559c912a3f7SMaxim Konovalov while ((sh = getusershell()) != NULL) { 560c912a3f7SMaxim Konovalov if (strcmp(sh, argv[i]) == 0) { 561c912a3f7SMaxim Konovalov SHELLSPRINT; 562c912a3f7SMaxim Konovalov break; 563c912a3f7SMaxim Konovalov } 564c912a3f7SMaxim Konovalov } 565c912a3f7SMaxim Konovalov if (sh == NULL) { 566c912a3f7SMaxim Konovalov rv = RV_NOTFOUND; 567c912a3f7SMaxim Konovalov break; 568c912a3f7SMaxim Konovalov } 569c912a3f7SMaxim Konovalov } 570c912a3f7SMaxim Konovalov } 571c912a3f7SMaxim Konovalov endusershell(); 572c912a3f7SMaxim Konovalov return rv; 573c912a3f7SMaxim Konovalov } 57486586473SEd Schouten 57586586473SEd Schouten /* 57608ad1a7aSGuy Helmer * netgroup 57708ad1a7aSGuy Helmer */ 57808ad1a7aSGuy Helmer static int 57908ad1a7aSGuy Helmer netgroup(int argc, char *argv[]) 58008ad1a7aSGuy Helmer { 58108ad1a7aSGuy Helmer char *host, *user, *domain; 58208ad1a7aSGuy Helmer int first; 58308ad1a7aSGuy Helmer int rv, i; 58408ad1a7aSGuy Helmer 58508ad1a7aSGuy Helmer assert(argc > 1); 58608ad1a7aSGuy Helmer assert(argv != NULL); 58708ad1a7aSGuy Helmer 58808ad1a7aSGuy Helmer #define NETGROUPPRINT(s) (((s) != NULL) ? (s) : "") 58908ad1a7aSGuy Helmer 59008ad1a7aSGuy Helmer rv = RV_OK; 59108ad1a7aSGuy Helmer if (argc == 2) { 59208ad1a7aSGuy Helmer fprintf(stderr, "Enumeration not supported on netgroup\n"); 59308ad1a7aSGuy Helmer rv = RV_NOENUM; 59408ad1a7aSGuy Helmer } else { 59508ad1a7aSGuy Helmer for (i = 2; i < argc; i++) { 59608ad1a7aSGuy Helmer setnetgrent(argv[i]); 59708ad1a7aSGuy Helmer first = 1; 59808ad1a7aSGuy Helmer while (getnetgrent(&host, &user, &domain) != 0) { 59908ad1a7aSGuy Helmer if (first) { 60008ad1a7aSGuy Helmer first = 0; 60108ad1a7aSGuy Helmer (void)fputs(argv[i], stdout); 60208ad1a7aSGuy Helmer } 60308ad1a7aSGuy Helmer (void)printf(" (%s,%s,%s)", 60408ad1a7aSGuy Helmer NETGROUPPRINT(host), 60508ad1a7aSGuy Helmer NETGROUPPRINT(user), 60608ad1a7aSGuy Helmer NETGROUPPRINT(domain)); 60708ad1a7aSGuy Helmer } 60808ad1a7aSGuy Helmer if (!first) 60908ad1a7aSGuy Helmer (void)putchar('\n'); 61008ad1a7aSGuy Helmer endnetgrent(); 61108ad1a7aSGuy Helmer } 61208ad1a7aSGuy Helmer } 61308ad1a7aSGuy Helmer return rv; 61408ad1a7aSGuy Helmer } 61508ad1a7aSGuy Helmer 61608ad1a7aSGuy Helmer /* 61786586473SEd Schouten * utmpx 61886586473SEd Schouten */ 61986586473SEd Schouten 62086586473SEd Schouten #define UTMPXPRINTID do { \ 62186586473SEd Schouten size_t i; \ 62286586473SEd Schouten for (i = 0; i < sizeof ut->ut_id; i++) \ 62386586473SEd Schouten printf("%02hhx", ut->ut_id[i]); \ 62486586473SEd Schouten } while (0) 62586586473SEd Schouten 62686586473SEd Schouten static void 62786586473SEd Schouten utmpxprint(const struct utmpx *ut) 62886586473SEd Schouten { 62986586473SEd Schouten 63086586473SEd Schouten if (ut->ut_type == EMPTY) 63186586473SEd Schouten return; 63286586473SEd Schouten 63332fc554eSEd Schouten printf("[%jd.%06u -- %.24s] ", 63432fc554eSEd Schouten (intmax_t)ut->ut_tv.tv_sec, (unsigned int)ut->ut_tv.tv_usec, 63532fc554eSEd Schouten ctime(&ut->ut_tv.tv_sec)); 63686586473SEd Schouten 63786586473SEd Schouten switch (ut->ut_type) { 63886586473SEd Schouten case BOOT_TIME: 63986586473SEd Schouten printf("system boot\n"); 64086586473SEd Schouten return; 64186586473SEd Schouten case SHUTDOWN_TIME: 64286586473SEd Schouten printf("system shutdown\n"); 64386586473SEd Schouten return; 64486586473SEd Schouten case OLD_TIME: 64586586473SEd Schouten printf("old system time\n"); 64686586473SEd Schouten return; 64786586473SEd Schouten case NEW_TIME: 64886586473SEd Schouten printf("new system time\n"); 64986586473SEd Schouten return; 65086586473SEd Schouten case USER_PROCESS: 65186586473SEd Schouten printf("user process: id=\""); 65286586473SEd Schouten UTMPXPRINTID; 653093d0b66SEd Schouten printf("\" pid=\"%d\" user=\"%s\" line=\"%s\" host=\"%s\"\n", 654093d0b66SEd Schouten ut->ut_pid, ut->ut_user, ut->ut_line, ut->ut_host); 65586586473SEd Schouten break; 6568e2eadb2SEd Schouten case INIT_PROCESS: 6578e2eadb2SEd Schouten printf("init process: id=\""); 6588e2eadb2SEd Schouten UTMPXPRINTID; 6598e2eadb2SEd Schouten printf("\" pid=\"%d\"\n", ut->ut_pid); 6608e2eadb2SEd Schouten break; 6618e2eadb2SEd Schouten case LOGIN_PROCESS: 6628e2eadb2SEd Schouten printf("login process: id=\""); 6638e2eadb2SEd Schouten UTMPXPRINTID; 6648e2eadb2SEd Schouten printf("\" pid=\"%d\" user=\"%s\" line=\"%s\" host=\"%s\"\n", 6658e2eadb2SEd Schouten ut->ut_pid, ut->ut_user, ut->ut_line, ut->ut_host); 6668e2eadb2SEd Schouten break; 66786586473SEd Schouten case DEAD_PROCESS: 66886586473SEd Schouten printf("dead process: id=\""); 66986586473SEd Schouten UTMPXPRINTID; 670093d0b66SEd Schouten printf("\" pid=\"%d\"\n", ut->ut_pid); 67186586473SEd Schouten break; 67286586473SEd Schouten default: 6738e2eadb2SEd Schouten printf("unknown record type %hu\n", ut->ut_type); 67486586473SEd Schouten break; 67586586473SEd Schouten } 67686586473SEd Schouten } 67786586473SEd Schouten 67886586473SEd Schouten static int 67986586473SEd Schouten utmpx(int argc, char *argv[]) 68086586473SEd Schouten { 68186586473SEd Schouten const struct utmpx *ut; 68293ce19dfSEd Schouten const char *file = NULL; 68393ce19dfSEd Schouten int rv = RV_OK, db = 0; 68486586473SEd Schouten 68586586473SEd Schouten assert(argc > 1); 68686586473SEd Schouten assert(argv != NULL); 68786586473SEd Schouten 68893ce19dfSEd Schouten if (argc == 3 || argc == 4) { 68986586473SEd Schouten if (strcmp(argv[2], "active") == 0) 69086586473SEd Schouten db = UTXDB_ACTIVE; 69186586473SEd Schouten else if (strcmp(argv[2], "lastlogin") == 0) 69286586473SEd Schouten db = UTXDB_LASTLOGIN; 69386586473SEd Schouten else if (strcmp(argv[2], "log") == 0) 69486586473SEd Schouten db = UTXDB_LOG; 69586586473SEd Schouten else 69686586473SEd Schouten rv = RV_USAGE; 69793ce19dfSEd Schouten if (argc == 4) 69893ce19dfSEd Schouten file = argv[3]; 69986586473SEd Schouten } else { 70086586473SEd Schouten rv = RV_USAGE; 70186586473SEd Schouten } 70286586473SEd Schouten 70386586473SEd Schouten if (rv == RV_USAGE) { 70493ce19dfSEd Schouten fprintf(stderr, 70593ce19dfSEd Schouten "Usage: %s utmpx active | lastlogin | log [filename]\n", 70686586473SEd Schouten getprogname()); 70786586473SEd Schouten } else if (rv == RV_OK) { 70893ce19dfSEd Schouten if (setutxdb(db, file) != 0) 70986586473SEd Schouten return (RV_NOTFOUND); 71086586473SEd Schouten while ((ut = getutxent()) != NULL) 71186586473SEd Schouten utmpxprint(ut); 71286586473SEd Schouten endutxent(); 71386586473SEd Schouten } 71486586473SEd Schouten return (rv); 71586586473SEd Schouten } 716