1 /* $NetBSD: mknetid.c,v 1.16 2009/04/19 06:06:40 lukem Exp $ */
4 * Copyright (c) 1996 Mats O Jansson <moj@stacken.kth.se>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
17 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include <sys/cdefs.h>
31 __RCSID("$NetBSD: mknetid.c,v 1.16 2009/04/19 06:06:40 lukem Exp $");
35 * Originally written by Mats O Jansson <moj@stacken.kth.se>
36 * Simplified a bit by Jason R. Thorpe <thorpej@NetBSD.org>
39 #include <sys/param.h>
40 #include <sys/queue.h>
52 #include <rpcsvc/ypclnt.h>
57 char *usr_name
; /* user name */
58 int usr_uid
; /* user uid */
59 int usr_gid
; /* user gid */
60 int gid_count
; /* number of gids */
61 int gid
[NGROUPS
]; /* additional gids */
62 TAILQ_ENTRY(user
) read
; /* links in read order */
63 TAILQ_ENTRY(user
) hash
; /* links in hash order */
68 void add_group(const char *, const char *);
69 void add_user(const char *, const char *, const char *);
72 int main(int, char *[]);
73 void print_hosts(const char *, const char *);
74 void print_netid(const char *);
75 void print_passwd_group(int, const char *);
76 void read_group(const char *);
77 void read_passwd(const char *);
80 TAILQ_HEAD(user_list
, user
);
81 struct user_list root
;
82 struct user_list hroot
[HASHMAX
];
85 main(int argc
, char *argv
[])
87 const char *HostFile
= _PATH_HOSTS
;
88 const char *PasswdFile
= _PATH_PASSWD
;
89 const char *GroupFile
= _PATH_GROUP
;
90 const char *NetidFile
= "/etc/netid";
96 for (ch
= 0; ch
< HASHMAX
; ch
++)
97 TAILQ_INIT((&hroot
[ch
]));
102 while ((ch
= getopt(argc
, argv
, "d:g:h:m:p:q")) != -1) {
136 if (yp_get_default_domain(&domain
))
137 errx(1, "Can't get YP domain name");
139 read_passwd(PasswdFile
);
140 read_group(GroupFile
);
142 print_passwd_group(qflag
, domain
);
143 print_hosts(HostFile
, domain
);
144 print_netid(NetidFile
);
156 return(1 + key
- 'A');
162 return(28 + key
- 'a');
168 add_user(const char *username
, const char *uid
, const char *gid
)
173 idx
= hashidx(username
[0]);
175 u
= (struct user
*)malloc(sizeof(struct user
));
177 err(1, "can't allocate user");
178 memset(u
, 0, sizeof(struct user
));
180 u
->usr_name
= strdup(username
);
181 if (u
->usr_name
== NULL
)
182 err(1, "can't allocate user name");
184 u
->usr_uid
= atoi(uid
);
185 u
->usr_gid
= atoi(gid
);
188 TAILQ_INSERT_TAIL(&root
, u
, read
);
189 TAILQ_INSERT_TAIL((&hroot
[idx
]), u
, hash
);
193 add_group(const char *username
, const char *gid
)
199 idx
= hashidx(username
[0]);
201 for (u
= hroot
[idx
].tqh_first
;
202 u
!= NULL
; u
= u
->hash
.tqe_next
) {
203 if (strcmp(username
, u
->usr_name
) == 0) {
204 if (g
!= u
->usr_gid
) {
206 if (u
->gid_count
< NGROUPS
)
207 u
->gid
[u
->gid_count
] = g
;
215 read_passwd(const char *fname
)
221 char *line
, *p
, *k
, *u
, *g
;
223 if ((pfile
= fopen(fname
, "r")) == NULL
)
228 (line
= fparseln(pfile
, &len
, &line_no
, NULL
, FPARSELN_UNESCALL
));
231 warnx("%s line %lu: empty line", fname
,
232 (unsigned long)line_no
);
237 for (k
= p
, colon
= 0; *k
!= '\0'; k
++)
242 warnx("%s line %lu: incorrect number of fields",
243 fname
, (unsigned long)line_no
);
251 /* If it's a YP entry, skip it. */
252 if (*k
== '+' || *k
== '-')
255 /* terminate password */
290 read_group(const char *fname
)
296 char *line
, *p
, *k
, *u
, *g
;
298 if ((gfile
= fopen(fname
, "r")) == NULL
)
303 (line
= fparseln(gfile
, &len
, &line_no
, NULL
, FPARSELN_UNESCALL
));
306 warnx("%s line %lu: empty line", fname
,
307 (unsigned long)line_no
);
312 for (k
= p
, colon
= 0; *k
!= '\0'; k
++)
317 warnx("%s line %lu: incorrect number of fields",
318 fname
, (unsigned long)line_no
);
327 if (*k
== '+' || *k
== '-')
330 /* terminate password */
339 /* get the group list */
340 for (u
= p
; *u
!= '\0'; u
= p
) {
342 for (; isgsep(*p
) == 0; p
++)
358 print_passwd_group(int qflag
, const char *domain
)
363 for (u
= root
.tqh_first
; u
!= NULL
; u
= u
->read
.tqe_next
) {
364 for (p
= root
.tqh_first
; p
->usr_uid
!= u
->usr_uid
;
365 p
= p
->read
.tqe_next
)
369 warnx("unix.%d@%s %s", u
->usr_uid
, domain
,
370 "multiply defined, ignoring duplicate");
373 printf("unix.%d@%s %d:%d", u
->usr_uid
, domain
,
374 u
->usr_uid
, u
->usr_gid
);
375 if (u
->gid_count
>= 0)
376 for (i
= 0; i
<= u
->gid_count
; i
++)
377 printf(",%d", u
->gid
[i
]);
384 print_hosts(const char *fname
, const char *domain
)
388 char *line
, *p
, *k
, *u
;
390 if ((hfile
= fopen(fname
, "r")) == NULL
)
394 (line
= fparseln(hfile
, &len
, NULL
, NULL
, FPARSELN_UNESCALL
));
400 /* Find the key, replace trailing whitespace will <NUL> */
401 for (k
= p
; *p
&& isspace((unsigned char)*p
) == 0; p
++)
403 while (*p
&& isspace((unsigned char)*p
))
406 /* Get first hostname. */
407 for (u
= p
; *p
&& !isspace((unsigned char)*p
); p
++)
411 printf("unix.%s@%s 0:%s\n", u
, domain
, u
);
413 (void) fclose(hfile
);
417 print_netid(const char *fname
)
421 char *line
, *p
, *k
, *u
;
423 mfile
= fopen(fname
, "r");
428 (line
= fparseln(mfile
, &len
, NULL
, NULL
, FPARSELN_UNESCALL
));
434 /* Find the key, replace trailing whitespace will <NUL> */
435 for (k
= p
; *p
&& !isspace((unsigned char)*p
); p
++)
437 while (*p
&& isspace((unsigned char)*p
))
440 /* Get netid entry. */
441 for (u
= p
; *p
&& !isspace((unsigned char)*p
); p
++)
445 printf("%s %s\n", k
, u
);
453 fprintf(stderr
, "usage: %s %s\n", getprogname(),
454 "[-d domain] [-q] [-p passwdfile] [-g groupfile]");
455 fprintf(stderr
, " %s %s", getprogname(),
456 "[-g groupfile] [-h hostfile] [-m netidfile]");