xref: /netbsd-src/usr.sbin/ypserv/mknetid/mknetid.c (revision 0a77b69ab60e06bb70aa1a4d61d4cfa9d106f2ca)
1*0a77b69aSchristos /*	$NetBSD: mknetid.c,v 1.19 2013/10/19 17:16:38 christos Exp $	*/
260aa689cSthorpej 
360aa689cSthorpej /*
460aa689cSthorpej  * Copyright (c) 1996 Mats O Jansson <moj@stacken.kth.se>
560aa689cSthorpej  * All rights reserved.
660aa689cSthorpej  *
760aa689cSthorpej  * Redistribution and use in source and binary forms, with or without
860aa689cSthorpej  * modification, are permitted provided that the following conditions
960aa689cSthorpej  * are met:
1060aa689cSthorpej  * 1. Redistributions of source code must retain the above copyright
1160aa689cSthorpej  *    notice, this list of conditions and the following disclaimer.
1260aa689cSthorpej  * 2. Redistributions in binary form must reproduce the above copyright
1360aa689cSthorpej  *    notice, this list of conditions and the following disclaimer in the
1460aa689cSthorpej  *    documentation and/or other materials provided with the distribution.
1560aa689cSthorpej  *
1660aa689cSthorpej  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
1760aa689cSthorpej  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1860aa689cSthorpej  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1960aa689cSthorpej  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
2060aa689cSthorpej  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2160aa689cSthorpej  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2260aa689cSthorpej  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2360aa689cSthorpej  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2460aa689cSthorpej  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2560aa689cSthorpej  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2660aa689cSthorpej  * SUCH DAMAGE.
2760aa689cSthorpej  */
2860aa689cSthorpej 
292a43cbe6Slukem #include <sys/cdefs.h>
302a43cbe6Slukem #ifndef lint
31*0a77b69aSchristos __RCSID("$NetBSD: mknetid.c,v 1.19 2013/10/19 17:16:38 christos Exp $");
322a43cbe6Slukem #endif
332a43cbe6Slukem 
3460aa689cSthorpej /*
3560aa689cSthorpej  * Originally written by Mats O Jansson <moj@stacken.kth.se>
36cacf2d0fSgrant  * Simplified a bit by Jason R. Thorpe <thorpej@NetBSD.org>
3760aa689cSthorpej  */
3860aa689cSthorpej 
3960aa689cSthorpej #include <sys/param.h>
4060aa689cSthorpej #include <sys/queue.h>
4160aa689cSthorpej #include <ctype.h>
4260aa689cSthorpej #include <err.h>
4360aa689cSthorpej #include <grp.h>
4460aa689cSthorpej #include <limits.h>
4560aa689cSthorpej #include <netdb.h>
4660aa689cSthorpej #include <pwd.h>
4760aa689cSthorpej #include <stdio.h>
4860aa689cSthorpej #include <string.h>
4960aa689cSthorpej #include <stdlib.h>
5060aa689cSthorpej #include <unistd.h>
5160aa689cSthorpej 
523d8138fcSthorpej #include <rpcsvc/ypclnt.h>
533d8138fcSthorpej 
5460aa689cSthorpej #include "protos.h"
5560aa689cSthorpej 
5660aa689cSthorpej struct user {
5760aa689cSthorpej 	char 	*usr_name;		/* user name */
5860aa689cSthorpej 	int	usr_uid;		/* user uid */
5960aa689cSthorpej 	int	usr_gid;		/* user gid */
6060aa689cSthorpej 	int	gid_count;		/* number of gids */
6160aa689cSthorpej 	int	gid[NGROUPS];		/* additional gids */
6260aa689cSthorpej 	TAILQ_ENTRY(user) read;		/* links in read order */
6360aa689cSthorpej 	TAILQ_ENTRY(user) hash;		/* links in hash order */
6460aa689cSthorpej };
6560aa689cSthorpej 
6660aa689cSthorpej #define HASHMAX 55
6760aa689cSthorpej 
688583b49cSjoerg static void	add_group(const char *, const char *);
698583b49cSjoerg static void	add_user(const char *, const char *, const char *);
708583b49cSjoerg static int	hashidx(char);
718583b49cSjoerg static int	isgsep(char);
728583b49cSjoerg static void	print_hosts(const char *, const char *);
738583b49cSjoerg static void	print_netid(const char *);
748583b49cSjoerg static void	print_passwd_group(int, const char *);
758583b49cSjoerg static void	read_group(const char *);
768583b49cSjoerg static void	read_passwd(const char *);
778583b49cSjoerg __dead static void	usage(void);
7860aa689cSthorpej 
7960aa689cSthorpej TAILQ_HEAD(user_list, user);
808583b49cSjoerg static struct user_list root;
818583b49cSjoerg static struct user_list hroot[HASHMAX];
8260aa689cSthorpej 
8360aa689cSthorpej int
main(int argc,char * argv[])845c90fa67Swiz main(int argc, char *argv[])
8560aa689cSthorpej {
86d3d3aa62Slukem 	const char *HostFile = _PATH_HOSTS;
87d3d3aa62Slukem 	const char *PasswdFile = _PATH_PASSWD;
88d3d3aa62Slukem 	const char *GroupFile = _PATH_GROUP;
89d3d3aa62Slukem 	const char *NetidFile = "/etc/netid";
90f4fb444bSlukem 
9160aa689cSthorpej 	int qflag, ch;
9260aa689cSthorpej 	char *domain;
9360aa689cSthorpej 
9460aa689cSthorpej 	TAILQ_INIT(&root);
9560aa689cSthorpej 	for (ch = 0; ch < HASHMAX; ch++)
9660aa689cSthorpej 		TAILQ_INIT((&hroot[ch]));
9760aa689cSthorpej 
9860aa689cSthorpej 	qflag = 0;
9960aa689cSthorpej 	domain = NULL;
10060aa689cSthorpej 
10160aa689cSthorpej 	while ((ch = getopt(argc, argv, "d:g:h:m:p:q")) != -1) {
10260aa689cSthorpej 		switch (ch) {
10360aa689cSthorpej 		case 'd':
10460aa689cSthorpej 			domain = optarg;
10560aa689cSthorpej 			break;
10660aa689cSthorpej 
10760aa689cSthorpej 		case 'g':
10860aa689cSthorpej 			GroupFile = optarg;
10960aa689cSthorpej 			break;
11060aa689cSthorpej 
11160aa689cSthorpej 		case 'h':
11260aa689cSthorpej 			HostFile = optarg;
11360aa689cSthorpej 			break;
11460aa689cSthorpej 
11560aa689cSthorpej 		case 'm':
11660aa689cSthorpej 			NetidFile = optarg;
11760aa689cSthorpej 			break;
11860aa689cSthorpej 
11960aa689cSthorpej 		case 'p':
12060aa689cSthorpej 			PasswdFile = optarg;
12160aa689cSthorpej 			break;
12260aa689cSthorpej 
12360aa689cSthorpej 		case 'q':
12460aa689cSthorpej 			qflag++;
12560aa689cSthorpej 			break;
12660aa689cSthorpej 
12760aa689cSthorpej 		default:
12860aa689cSthorpej 			usage();
12960aa689cSthorpej 		}
13060aa689cSthorpej 	}
131f4fb444bSlukem 	if (argc != optind)
13260aa689cSthorpej 		usage();
13360aa689cSthorpej 
13460aa689cSthorpej 	if (domain == NULL)
13560aa689cSthorpej 		if (yp_get_default_domain(&domain))
1366ea62c33Slukem 			errx(1, "Can't get YP domain name");
13760aa689cSthorpej 
138f4fb444bSlukem 	read_passwd(PasswdFile);
139f4fb444bSlukem 	read_group(GroupFile);
14060aa689cSthorpej 
14160aa689cSthorpej 	print_passwd_group(qflag, domain);
142f4fb444bSlukem 	print_hosts(HostFile, domain);
143f4fb444bSlukem 	print_netid(NetidFile);
14460aa689cSthorpej 
14560aa689cSthorpej 	exit (0);
14660aa689cSthorpej }
14760aa689cSthorpej 
1488583b49cSjoerg static int
hashidx(char key)1495c90fa67Swiz hashidx(char key)
15060aa689cSthorpej {
15160aa689cSthorpej 	if (key < 'A')
15260aa689cSthorpej 		return(0);
15360aa689cSthorpej 
15460aa689cSthorpej 	if (key <= 'Z')
15560aa689cSthorpej 		return(1 + key - 'A');
15660aa689cSthorpej 
15760aa689cSthorpej 	if (key < 'a')
15860aa689cSthorpej 		return(27);
15960aa689cSthorpej 
16060aa689cSthorpej 	if (key <= 'z')
16160aa689cSthorpej 		return(28 + key - 'a');
16260aa689cSthorpej 
16360aa689cSthorpej 	return(54);
16460aa689cSthorpej }
16560aa689cSthorpej 
1668583b49cSjoerg static void
add_user(const char * username,const char * uid,const char * gid)1675c90fa67Swiz add_user(const char *username, const char *uid, const char *gid)
16860aa689cSthorpej {
16960aa689cSthorpej 	struct user *u;
17060aa689cSthorpej 	int idx;
17160aa689cSthorpej 
17260aa689cSthorpej 	idx = hashidx(username[0]);
17360aa689cSthorpej 
17460aa689cSthorpej 	u = (struct user *)malloc(sizeof(struct user));
17560aa689cSthorpej 	if (u == NULL)
17660aa689cSthorpej 		err(1, "can't allocate user");
17760aa689cSthorpej 	memset(u, 0, sizeof(struct user));
17860aa689cSthorpej 
179f4fb444bSlukem 	u->usr_name = strdup(username);
18060aa689cSthorpej 	if (u->usr_name == NULL)
18160aa689cSthorpej 		err(1, "can't allocate user name");
18260aa689cSthorpej 
18360aa689cSthorpej 	u->usr_uid = atoi(uid);
18460aa689cSthorpej 	u->usr_gid = atoi(gid);
18560aa689cSthorpej 	u->gid_count = -1;
18660aa689cSthorpej 
18760aa689cSthorpej 	TAILQ_INSERT_TAIL(&root, u, read);
18860aa689cSthorpej 	TAILQ_INSERT_TAIL((&hroot[idx]), u, hash);
18960aa689cSthorpej }
19060aa689cSthorpej 
1918583b49cSjoerg static void
add_group(const char * username,const char * gid)1925c90fa67Swiz add_group(const char *username, const char *gid)
19360aa689cSthorpej {
19460aa689cSthorpej 	struct user *u;
19560aa689cSthorpej 	int g, idx;
19660aa689cSthorpej 
19760aa689cSthorpej 	g = atoi(gid);
19860aa689cSthorpej 	idx = hashidx(username[0]);
19960aa689cSthorpej 
20060aa689cSthorpej 	for (u = hroot[idx].tqh_first;
20160aa689cSthorpej 	    u != NULL; u = u->hash.tqe_next) {
20260aa689cSthorpej 		if (strcmp(username, u->usr_name) == 0) {
20360aa689cSthorpej 			if (g != u->usr_gid) {
20460aa689cSthorpej 				u->gid_count++;
20560aa689cSthorpej 				if (u->gid_count < NGROUPS)
20660aa689cSthorpej 					u->gid[u->gid_count] = g;
20760aa689cSthorpej 			}
20860aa689cSthorpej 			return;
20960aa689cSthorpej 		}
21060aa689cSthorpej 	}
21160aa689cSthorpej }
21260aa689cSthorpej 
2138583b49cSjoerg static void
read_passwd(const char * fname)2145c90fa67Swiz read_passwd(const char *fname)
21560aa689cSthorpej {
216f4fb444bSlukem 	FILE	*pfile;
21741dc2c91Skleink 	size_t	 line_no;
21841dc2c91Skleink 	int	 colon;
219ade3ce97Sthorpej 	size_t	 len;
220811d7dcaSlukem 	char	*line, *p, *k, *u, *g;
22160aa689cSthorpej 
222f4fb444bSlukem 	if ((pfile = fopen(fname, "r")) == NULL)
223f4fb444bSlukem 		err(1, "%s", fname);
22460aa689cSthorpej 
225f4fb444bSlukem 	line_no = 0;
226211a72a8Slukem 	for (;
227811d7dcaSlukem 	    (line = fparseln(pfile, &len, &line_no, NULL, FPARSELN_UNESCALL));
228811d7dcaSlukem 	    free(line)) {
229f4fb444bSlukem 		if (len == 0) {
23041dc2c91Skleink 			warnx("%s line %lu: empty line", fname,
23141dc2c91Skleink 			    (unsigned long)line_no);
23260aa689cSthorpej 			continue;
233f4fb444bSlukem 		}
23460aa689cSthorpej 
235811d7dcaSlukem 		p = line;
23660aa689cSthorpej 		for (k = p, colon = 0; *k != '\0'; k++)
23760aa689cSthorpej 			if (*k == ':')
23860aa689cSthorpej 				colon++;
23960aa689cSthorpej 
240f4fb444bSlukem 		if (colon != 6) {
24141dc2c91Skleink 			warnx("%s line %lu: incorrect number of fields",
24241dc2c91Skleink 			    fname, (unsigned long)line_no);
24360aa689cSthorpej 			continue;
24460aa689cSthorpej 		}
24560aa689cSthorpej 
246f4fb444bSlukem 		k = p;
247f4fb444bSlukem 		p = strchr(p, ':');
248f4fb444bSlukem 		*p++ = '\0';
249f4fb444bSlukem 
250f4fb444bSlukem 		/* If it's a YP entry, skip it. */
251f4fb444bSlukem 		if (*k == '+' || *k == '-')
252f4fb444bSlukem 			continue;
253f4fb444bSlukem 
25460aa689cSthorpej 		/* terminate password */
255f4fb444bSlukem 		p = strchr(p, ':');
25660aa689cSthorpej 		*p++ = '\0';
25760aa689cSthorpej 
25860aa689cSthorpej 		/* terminate uid */
259f4fb444bSlukem 		u = p;
260f4fb444bSlukem 		p = strchr(p, ':');
26160aa689cSthorpej 		*p++ = '\0';
26260aa689cSthorpej 
26360aa689cSthorpej 		/* terminate gid */
264f4fb444bSlukem 		g = p;
265f4fb444bSlukem 		p = strchr(p, ':');
26660aa689cSthorpej 		*p++ = '\0';
26760aa689cSthorpej 
26860aa689cSthorpej 		add_user(k, u, g);
26960aa689cSthorpej 	}
270f4fb444bSlukem 	(void)fclose(pfile);
27160aa689cSthorpej }
27260aa689cSthorpej 
2738583b49cSjoerg static int
isgsep(char ch)2745c90fa67Swiz isgsep(char ch)
27560aa689cSthorpej {
27660aa689cSthorpej 
27760aa689cSthorpej 	switch (ch) {
27860aa689cSthorpej 	case ',':
27960aa689cSthorpej 	case ' ':
28060aa689cSthorpej 	case '\t':
28160aa689cSthorpej 	case '\0':
28260aa689cSthorpej 		return (1);
28360aa689cSthorpej 	}
28460aa689cSthorpej 
28560aa689cSthorpej 	return (0);
28660aa689cSthorpej }
28760aa689cSthorpej 
2888583b49cSjoerg static void
read_group(const char * fname)2895c90fa67Swiz read_group(const char *fname)
29060aa689cSthorpej {
291f4fb444bSlukem 	FILE	*gfile;
29241dc2c91Skleink 	size_t	 line_no;
29341dc2c91Skleink 	int	 colon;
294ade3ce97Sthorpej 	size_t	 len;
295811d7dcaSlukem 	char	*line, *p, *k, *u, *g;
29660aa689cSthorpej 
297f4fb444bSlukem 	if ((gfile = fopen(fname, "r")) == NULL)
298f4fb444bSlukem 		err(1, "%s", fname);
29960aa689cSthorpej 
300f4fb444bSlukem 	line_no = 0;
301211a72a8Slukem 	for (;
302811d7dcaSlukem 	    (line = fparseln(gfile, &len, &line_no, NULL, FPARSELN_UNESCALL));
303811d7dcaSlukem 	    free(line)) {
304f4fb444bSlukem 		if (len == 0) {
30541dc2c91Skleink 			warnx("%s line %lu: empty line", fname,
30641dc2c91Skleink 			    (unsigned long)line_no);
30760aa689cSthorpej 			continue;
30860aa689cSthorpej 		}
30960aa689cSthorpej 
310811d7dcaSlukem 		p = line;
31160aa689cSthorpej 		for (k = p, colon = 0; *k != '\0'; k++)
31260aa689cSthorpej 			if (*k == ':')
31360aa689cSthorpej 				colon++;
31460aa689cSthorpej 
315f4fb444bSlukem 		if (colon != 3) {
31641dc2c91Skleink 			warnx("%s line %lu: incorrect number of fields",
31741dc2c91Skleink 			    fname, (unsigned long)line_no);
31860aa689cSthorpej 			continue;
31960aa689cSthorpej 		}
32060aa689cSthorpej 
321f4fb444bSlukem 		/* terminate key */
322f4fb444bSlukem 		k = p;
323f4fb444bSlukem 		p = strchr(p, ':');
324f4fb444bSlukem 		*p++ = '\0';
325f4fb444bSlukem 
326f4fb444bSlukem 		if (*k == '+' || *k == '-')
327f4fb444bSlukem 			continue;
328f4fb444bSlukem 
32960aa689cSthorpej 		/* terminate password */
330f4fb444bSlukem 		p = strchr(p, ':');
33160aa689cSthorpej 		*p++ = '\0';
33260aa689cSthorpej 
33360aa689cSthorpej 		/* terminate gid */
334f4fb444bSlukem 		g = p;
335f4fb444bSlukem 		p = strchr(p, ':');
33660aa689cSthorpej 		*p++ = '\0';
33760aa689cSthorpej 
33860aa689cSthorpej 		/* get the group list */
33960aa689cSthorpej 		for (u = p; *u != '\0'; u = p) {
34060aa689cSthorpej 			/* find separator */
341f4fb444bSlukem 			for (; isgsep(*p) == 0; p++)
342f4fb444bSlukem 				;
34360aa689cSthorpej 
34460aa689cSthorpej 			if (*p != '\0') {
34560aa689cSthorpej 				*p = '\0';
34660aa689cSthorpej 				if (u != p)
34760aa689cSthorpej 					add_group(u, g);
34860aa689cSthorpej 				p++;
34960aa689cSthorpej 			} else if (u != p)
35060aa689cSthorpej 				add_group(u, g);
35160aa689cSthorpej 		}
35260aa689cSthorpej 	}
353f4fb444bSlukem 	(void)fclose(gfile);
35460aa689cSthorpej }
35560aa689cSthorpej 
3568583b49cSjoerg static void
print_passwd_group(int qflag,const char * domain)3575c90fa67Swiz print_passwd_group(int qflag, const char *domain)
35860aa689cSthorpej {
35960aa689cSthorpej 	struct user *u, *p;
36060aa689cSthorpej 	int i;
36160aa689cSthorpej 
36260aa689cSthorpej 	for (u = root.tqh_first; u != NULL; u = u->read.tqe_next) {
36360aa689cSthorpej 		for (p = root.tqh_first; p->usr_uid != u->usr_uid;
36460aa689cSthorpej 		    p = p->read.tqe_next)
36560aa689cSthorpej 			/* empty */ ;
36660aa689cSthorpej 		if (p != u) {
36760aa689cSthorpej 			if (!qflag) {
36860aa689cSthorpej 				warnx("unix.%d@%s %s", u->usr_uid, domain,
36960aa689cSthorpej 				 "multiply defined, ignoring duplicate");
37060aa689cSthorpej 			}
37160aa689cSthorpej 		} else {
37260aa689cSthorpej 			printf("unix.%d@%s %d:%d", u->usr_uid, domain,
37360aa689cSthorpej 			    u->usr_uid, u->usr_gid);
37460aa689cSthorpej 			if (u->gid_count >= 0)
37560aa689cSthorpej 				for (i = 0; i <= u->gid_count; i++)
37660aa689cSthorpej 					printf(",%d", u->gid[i]);
37760aa689cSthorpej 			printf("\n");
37860aa689cSthorpej 		}
37960aa689cSthorpej 	}
38060aa689cSthorpej }
38160aa689cSthorpej 
3828583b49cSjoerg static void
print_hosts(const char * fname,const char * domain)3835c90fa67Swiz print_hosts(const char *fname, const char *domain)
38460aa689cSthorpej {
385f4fb444bSlukem 	FILE	*hfile;
386ade3ce97Sthorpej 	size_t	 len;
387*0a77b69aSchristos 	char	*line, *p, *u;
38860aa689cSthorpej 
389f4fb444bSlukem 	if ((hfile = fopen(fname, "r")) == NULL)
390f4fb444bSlukem 		err(1, "%s", fname);
39160aa689cSthorpej 
392211a72a8Slukem 	for (;
393811d7dcaSlukem 	    (line = fparseln(hfile, &len, NULL, NULL, FPARSELN_UNESCALL));
394811d7dcaSlukem 	    free(line)) {
395211a72a8Slukem 		if (len == 0)
39660aa689cSthorpej 			continue;
39760aa689cSthorpej 
398811d7dcaSlukem 		p = line;
39960aa689cSthorpej 		/* Find the key, replace trailing whitespace will <NUL> */
400*0a77b69aSchristos 		for (; *p && isspace((unsigned char)*p) == 0; p++)
401f4fb444bSlukem 			;
4023cca093eSdsl 		while (*p && isspace((unsigned char)*p))
40360aa689cSthorpej 			*p++ = '\0';
40460aa689cSthorpej 
40560aa689cSthorpej 		/* Get first hostname. */
4063cca093eSdsl 		for (u = p; *p && !isspace((unsigned char)*p); p++)
407f4fb444bSlukem 			;
40860aa689cSthorpej 		*p = '\0';
40960aa689cSthorpej 
41060aa689cSthorpej 		printf("unix.%s@%s 0:%s\n", u, domain, u);
41160aa689cSthorpej 	}
412f4fb444bSlukem 	(void) fclose(hfile);
41360aa689cSthorpej }
41460aa689cSthorpej 
4158583b49cSjoerg static void
print_netid(const char * fname)4165c90fa67Swiz print_netid(const char *fname)
41760aa689cSthorpej {
418f4fb444bSlukem 	FILE	*mfile;
419ade3ce97Sthorpej 	size_t	 len;
420811d7dcaSlukem 	char	*line, *p, *k, *u;
42160aa689cSthorpej 
422f4fb444bSlukem 	mfile = fopen(fname, "r");
423f4fb444bSlukem 	if (mfile == NULL)
424f4fb444bSlukem 		return;
42560aa689cSthorpej 
426211a72a8Slukem 	for (;
427811d7dcaSlukem 	    (line = fparseln(mfile, &len, NULL, NULL, FPARSELN_UNESCALL));
428811d7dcaSlukem 	    free(line)) {
429211a72a8Slukem 		if (len == 0)
43060aa689cSthorpej 			continue;
43160aa689cSthorpej 
432811d7dcaSlukem 		p = line;
43360aa689cSthorpej 		/* Find the key, replace trailing whitespace will <NUL> */
4343cca093eSdsl 		for (k = p; *p && !isspace((unsigned char)*p); p++)
435f4fb444bSlukem 			;
4363cca093eSdsl 		while (*p && isspace((unsigned char)*p))
43760aa689cSthorpej 			*p++ = '\0';
43860aa689cSthorpej 
43960aa689cSthorpej 		/* Get netid entry. */
4403cca093eSdsl 		for (u = p; *p && !isspace((unsigned char)*p); p++)
441f4fb444bSlukem 			;
44260aa689cSthorpej 		*p = '\0';
44360aa689cSthorpej 
44460aa689cSthorpej 		printf("%s %s\n", k, u);
44560aa689cSthorpej 	}
44660aa689cSthorpej }
44760aa689cSthorpej 
4488583b49cSjoerg static void
usage(void)4495c90fa67Swiz usage(void)
45060aa689cSthorpej {
45160aa689cSthorpej 
45225bdbb66Scgd 	fprintf(stderr, "usage: %s %s\n", getprogname(),
45360aa689cSthorpej 	    "[-d domain] [-q] [-p passwdfile] [-g groupfile]");
45425bdbb66Scgd 	fprintf(stderr, "       %s  %s", getprogname(),
45560aa689cSthorpej 	    "[-g groupfile] [-h hostfile] [-m netidfile]");
4563d8138fcSthorpej 	exit(1);
45760aa689cSthorpej }
458