4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright (c) 2016 by Delphix. All rights reserved.
28 * Network name to unix credential database generator.
29 * Uses /etc/passwd, /etc/group, /etc/hosts and /etc/netid to
30 * create the database.
32 * If some user appears in passwd, they get an entry like:
33 * sun.<uid>@<domainname> <uid>:<gid1>,<gid2>,...
34 * If some host appears in hosts, it gets an entry like:
35 * sun.<hostname>@<domainname> 0:<hostname>
37 * The file /etc/netid is used to add other domains (possibly non-unix)
43 #include <sys/param.h>
45 #include <rpc/key_prot.h>
48 #define MAXNAMELEN 256
49 #define MAXLINELEN 1024
50 #define MAXDOMAINLEN 32
52 #define GRPTABSIZE 256 /* size of group table */
53 #define PRNTABSIZE 4096 /* size of printed item table */
55 #define NUMGIDS (NGROUPS_MAX + 1) /* group-access-list + gid */
57 extern char **getaline();
58 extern char *malloc();
59 extern char *strcpy();
63 * Store username and groups to which they belong
69 struct group_list
*next
;
73 * General purpose list of strings
77 struct string_list
*next
;
80 static FILE *openfile();
81 static char *scanargs();
84 static char *cmdname
; /* name of this program */
85 static int quietmode
; /* quiet mode: don't print error messages */
86 static char *curfile
; /* name of file we are parsing */
87 static int curline
; /* current line parsed in this file */
89 static struct group_list
*groups
[GRPTABSIZE
]; /* group table */
90 static struct string_list
*printed
[PRNTABSIZE
]; /* printed item table */
91 static char domain
[MAXDOMAINLEN
]; /* name of our domain */
93 static char PASSWD
[] = "/etc/passwd"; /* default passwd database */
94 static char IDMAP
[] = "/etc/idmap"; /* default net-id map database */
95 static char GROUP
[] = "/etc/group"; /* default group database */
96 static char HOSTS
[] = "/etc/hosts"; /* default hosts database */
98 static char *pwdfile
= PASSWD
; /* password file to parse */
99 static char *grpfile
= GROUP
; /* group file */
100 static char *hostfile
= HOSTS
; /* hosts file */
101 static char *mapfile
= IDMAP
; /* network id file */
106 static char WHITE
[] = "\t ";
107 static char COLON
[] = ":";
108 static char COMMA
[] = ",";
110 void domapfile(char *, FILE *);
111 void dogrpfile(char *, FILE *);
112 void dopwdfile(char *, FILE *);
113 void dohostfile(char *, FILE *);
114 static int Atoi(char *);
115 void check_getname(char **, char *, char *, char *, char *);
116 void multdef(char *);
117 static int wasprinted(char *);
118 void storegid(int, char *);
119 void printgroups(char *, int);
120 int parseargs(int, char *[]);
130 FILE *pf
, *mf
, *gf
, *hf
;
133 if (!parseargs(argc
, argv
)) {
134 (void) fprintf(stderr
,
135 "usage: %s [-q] [-pghm filename]\n", cmdname
);
138 (void) getdomainname(domain
, sizeof (domain
));
140 pf
= openfile(pwdfile
);
141 gf
= openfile(grpfile
);
142 hf
= openfile(hostfile
);
143 mf
= fopen(mapfile
, "r");
147 domapfile(mapfile
, mf
);
149 dogrpfile(grpfile
, gf
);
150 dopwdfile(pwdfile
, pf
);
151 dohostfile(hostfile
, hf
);
158 * Parse the network id mapping file
161 domapfile(mapfile
, mf
)
166 char line
[MAXLINELEN
];
167 char name
[MAXNAMELEN
];
172 while (lp
= getaline(line
, sizeof (line
), mf
, &curline
, "#")) {
173 check_getname(lp
, name
, WHITE
, WHITE
, "#");
174 if (wasprinted(name
)) {
180 check_getname(lp
, name
, WHITE
, COLON
, "#");
185 check_getname(lp
, name
, WHITE
, "\t\n ", "#");
189 check_getname(lp
, name
, WHITE
, ",\n", "#");
192 while (getname(name
, sizeof (name
), WHITE
, ",\n", lp
,
199 (void) putchar('\n');
205 * Parse the groups file
208 dogrpfile(grpfile
, gf
)
213 char line
[MAXLINELEN
];
214 char name
[MAXNAMELEN
];
219 while (lp
= getaline(line
, sizeof (line
), gf
, &curline
, "")) {
220 check_getname(lp
, name
, WHITE
, COLON
, "");
221 if (name
[0] == '+') {
224 check_getname(lp
, name
, WHITE
, COLON
, ""); /* ignore passwd */
225 check_getname(lp
, name
, WHITE
, COLON
, "");
227 while (getname(name
, sizeof (name
), WHITE
, COMMA
, lp
,
236 * Parse the password file
239 dopwdfile(pwdfile
, pf
)
244 char line
[MAXLINELEN
];
245 char name
[MAXNAMELEN
];
246 char user
[MAXNAMELEN
];
252 while (lp
= getaline(line
, sizeof (line
), pf
, &curline
, "")) {
253 check_getname(lp
, user
, WHITE
, COLON
, ""); /* username */
254 if (user
[0] == '-' || user
[0] == '+') {
255 continue; /* NIS entry */
257 check_getname(lp
, name
, WHITE
, COLON
, ""); /* ignore passwd */
258 check_getname(lp
, name
, WHITE
, COLON
, ""); /* but get uid */
260 user2netname(name
, uid
, domain
);
261 if (wasprinted(name
)) {
267 check_getname(lp
, name
, WHITE
, COLON
, "");
271 printgroups(user
, gid
);
277 * Parse the hosts file
280 dohostfile(hostfile
, hf
)
285 char line
[MAXLINELEN
];
286 char name
[MAXNAMELEN
];
287 char netname
[MAXNETNAMELEN
];
291 while (lp
= getaline(line
, sizeof (line
), hf
, &curline
, "#")) {
292 check_getname(lp
, name
, WHITE
, WHITE
, "#");
293 if (getname(name
, MAXNAMELEN
, WHITE
, WHITE
, lp
, "#") != 1) {
296 host2netname(netname
, name
, domain
);
297 if (wasprinted(netname
)) {
301 (void) printf("%s 0:%.*s\n", netname
, sizeof (name
), name
);
306 * Open a file, exit on failure
314 f
= fopen(fname
, "r");
316 (void) fprintf(stderr
, "%s: can't open %s\n", cmdname
, fname
);
323 * Print syntax error message, then exit
328 (void) fprintf(stderr
, "%s: syntax error in file \"%s\", line %d\n",
329 cmdname
, curfile
, curline
);
335 * an atoi() that prints a message and exits upong failure
343 if (!sscanf(str
, "%d", &res
)) {
351 * Attempt to get a token from a file, print a message and exit upon failure
354 check_getname(lp
, name
, skip
, term
, com
)
361 if (getname(name
, MAXNAMELEN
, skip
, term
, lp
, com
) != 1) {
367 * Something was defined more than once
374 (void) fprintf(stderr
,
375 "%s: %s multiply defined, other definitions ignored\n",
392 val
^= (*str
++ << 6);
403 * Check if an item has been printed
404 * If not, store the item into the printed item table
410 struct string_list
*s
;
413 val
= hash((unsigned char *) name
, PRNTABSIZE
);
414 for (s
= printed
[val
]; s
!= NULL
&& strcmp(s
->str
, name
); s
= s
->next
)
419 s
= (struct string_list
*)malloc(sizeof (struct string_list
));
420 s
->str
= malloc((unsigned)strlen(name
) + 1);
421 (void) strcpy(s
->str
, name
);
422 s
->next
= printed
[val
];
428 * Add gid to the list of a user's groups
435 struct group_list
*g
;
439 val
= hash((unsigned char *) user
, GRPTABSIZE
);
440 for (g
= groups
[val
]; g
!= NULL
&& strcmp(g
->user
, user
); g
= g
->next
)
443 g
= (struct group_list
*)malloc(sizeof (struct group_list
));
444 g
->user
= malloc((unsigned)strlen(user
) + 1);
445 (void) strcpy(g
->user
, user
);
448 g
->next
= groups
[val
];
451 for (i
= 0; i
< g
->group_len
; i
++) {
452 if (g
->groups
[i
] == gid
) {
456 if (g
->group_len
>= NUMGIDS
) {
457 (void) fprintf(stderr
, "%s: %s's groups exceed %d\n",
458 cmdname
, user
, NGROUPS_MAX
);
461 g
->groups
[g
->group_len
++] = gid
;
466 * print out a user's groups
469 printgroups(user
, gid
)
473 struct group_list
*g
;
477 val
= hash((unsigned char *) user
, GRPTABSIZE
);
478 for (g
= groups
[val
]; g
!= NULL
&& strcmp(g
->user
, user
); g
= g
->next
)
482 for (i
= 0; i
< g
->group_len
; i
++) {
483 if (gid
!= g
->groups
[i
]) {
489 (void) putchar('\n');
494 * Parse command line arguments
497 parseargs(argc
, argv
)
508 { 'p', PASSWD
, &pwdfile
},
509 { 'g', GROUP
, &grpfile
},
510 { 'm', IDMAP
, &mapfile
},
511 { 'h', HOSTS
, &hostfile
}
514 #define TABSIZE sizeof (whattodo)/sizeof (whattodo[0])
516 for (i
= 1; i
< argc
; i
++) {
517 if (argv
[i
][0] == '-') {
518 if (argv
[i
][2] != 0) {
521 if (argv
[i
][1] == 'q') {
525 for (j
= 0; j
< TABSIZE
; j
++) {
526 if (whattodo
[j
].letter
== argv
[i
][1]) {
527 if (*whattodo
[j
].filename
!=
528 whattodo
[j
].standard
) {
534 *whattodo
[j
].filename
= argv
[i
];
547 * Print a string, quickly
553 (void) fwrite(s
, strlen(s
), 1, stdout
);
557 * Print an integer, quickly
574 p
= buf
+ sizeof (buf
);
577 *--p
= (d
% 10) + '0';