xref: /illumos-gate/usr/src/cmd/oamuser/user/userdefs.c (revision 7c478bd9)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
23*7c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
24*7c478bd9Sstevel@tonic-gate 
25*7c478bd9Sstevel@tonic-gate 
26*7c478bd9Sstevel@tonic-gate /*
27*7c478bd9Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
28*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
29*7c478bd9Sstevel@tonic-gate  */
30*7c478bd9Sstevel@tonic-gate 
31*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI" /* SVr4.0 1.4 */
32*7c478bd9Sstevel@tonic-gate 
33*7c478bd9Sstevel@tonic-gate 
34*7c478bd9Sstevel@tonic-gate /*LINTLIBRARY*/
35*7c478bd9Sstevel@tonic-gate 
36*7c478bd9Sstevel@tonic-gate #include	<sys/types.h>
37*7c478bd9Sstevel@tonic-gate #include	<stdio.h>
38*7c478bd9Sstevel@tonic-gate #include	<string.h>
39*7c478bd9Sstevel@tonic-gate #include	<userdefs.h>
40*7c478bd9Sstevel@tonic-gate #include	<user_attr.h>
41*7c478bd9Sstevel@tonic-gate #include	<limits.h>
42*7c478bd9Sstevel@tonic-gate #include	<stdlib.h>
43*7c478bd9Sstevel@tonic-gate #include	<stddef.h>
44*7c478bd9Sstevel@tonic-gate #include	<time.h>
45*7c478bd9Sstevel@tonic-gate #include	<unistd.h>
46*7c478bd9Sstevel@tonic-gate #include	"userdisp.h"
47*7c478bd9Sstevel@tonic-gate #include	"funcs.h"
48*7c478bd9Sstevel@tonic-gate #include	"messages.h"
49*7c478bd9Sstevel@tonic-gate 
50*7c478bd9Sstevel@tonic-gate /* Print out a NL when the line gets too long */
51*7c478bd9Sstevel@tonic-gate #define	PRINTNL()	\
52*7c478bd9Sstevel@tonic-gate 	if (outcount > 40) { \
53*7c478bd9Sstevel@tonic-gate 		outcount = 0; \
54*7c478bd9Sstevel@tonic-gate 		(void) fprintf(fptr, "\n"); \
55*7c478bd9Sstevel@tonic-gate 	}
56*7c478bd9Sstevel@tonic-gate 
57*7c478bd9Sstevel@tonic-gate #define	SKIPWS(ptr)	while (*ptr && *ptr == ' ' || *ptr == '\t') ptr++
58*7c478bd9Sstevel@tonic-gate 
59*7c478bd9Sstevel@tonic-gate static char *dup_to_nl(char *);
60*7c478bd9Sstevel@tonic-gate 
61*7c478bd9Sstevel@tonic-gate static struct userdefs defaults = {
62*7c478bd9Sstevel@tonic-gate 	DEFRID, DEFGROUP, DEFGNAME, DEFPARENT, DEFSKL,
63*7c478bd9Sstevel@tonic-gate 	DEFSHL, DEFINACT, DEFEXPIRE, DEFAUTH, DEFPROF,
64*7c478bd9Sstevel@tonic-gate 	DEFROLE, DEFPROJ, DEFPROJNAME, DEFLIMPRIV,
65*7c478bd9Sstevel@tonic-gate 	DEFDFLTPRIV, DEFLOCK_AFTER_RETRIES
66*7c478bd9Sstevel@tonic-gate };
67*7c478bd9Sstevel@tonic-gate 
68*7c478bd9Sstevel@tonic-gate #define	INT	0
69*7c478bd9Sstevel@tonic-gate #define	STR	1
70*7c478bd9Sstevel@tonic-gate #define	PROJID	2
71*7c478bd9Sstevel@tonic-gate 
72*7c478bd9Sstevel@tonic-gate #define	DEFOFF(field)		offsetof(struct userdefs, field)
73*7c478bd9Sstevel@tonic-gate #define	FIELD(up, pe, type)	(*(type *)((char *)(up) + (pe)->off))
74*7c478bd9Sstevel@tonic-gate 
75*7c478bd9Sstevel@tonic-gate typedef struct parsent {
76*7c478bd9Sstevel@tonic-gate 	const char *name;	/* deffoo= */
77*7c478bd9Sstevel@tonic-gate 	const size_t nmsz;	/* length of def= string (excluding \0) */
78*7c478bd9Sstevel@tonic-gate 	const int type;		/* type of entry */
79*7c478bd9Sstevel@tonic-gate 	const ptrdiff_t off;	/* offset in userdefs structure */
80*7c478bd9Sstevel@tonic-gate 	const char *uakey;	/* user_attr key, if defined */
81*7c478bd9Sstevel@tonic-gate } parsent_t;
82*7c478bd9Sstevel@tonic-gate 
83*7c478bd9Sstevel@tonic-gate static const parsent_t tab[] = {
84*7c478bd9Sstevel@tonic-gate 	{ GIDSTR,	sizeof (GIDSTR) - 1,	INT,	DEFOFF(defgroup) },
85*7c478bd9Sstevel@tonic-gate 	{ GNAMSTR,	sizeof (GNAMSTR) - 1,	STR,	DEFOFF(defgname) },
86*7c478bd9Sstevel@tonic-gate 	{ PARSTR,	sizeof (PARSTR) - 1,	STR,	DEFOFF(defparent) },
87*7c478bd9Sstevel@tonic-gate 	{ SKLSTR,	sizeof (SKLSTR) - 1,	STR,	DEFOFF(defskel) },
88*7c478bd9Sstevel@tonic-gate 	{ SHELLSTR,	sizeof (SHELLSTR) - 1,	STR,	DEFOFF(defshell) },
89*7c478bd9Sstevel@tonic-gate 	{ INACTSTR,	sizeof (INACTSTR) - 1,	INT,	DEFOFF(definact) },
90*7c478bd9Sstevel@tonic-gate 	{ EXPIRESTR,	sizeof (EXPIRESTR) - 1,	STR,	DEFOFF(defexpire) },
91*7c478bd9Sstevel@tonic-gate 	{ AUTHSTR,	sizeof (AUTHSTR) - 1,	STR,	DEFOFF(defauth),
92*7c478bd9Sstevel@tonic-gate 		USERATTR_AUTHS_KW },
93*7c478bd9Sstevel@tonic-gate 	{ ROLESTR,	sizeof (ROLESTR) - 1,	STR,	DEFOFF(defrole),
94*7c478bd9Sstevel@tonic-gate 		USERATTR_ROLES_KW },
95*7c478bd9Sstevel@tonic-gate 	{ PROFSTR,	sizeof (PROFSTR) - 1,	STR,	DEFOFF(defprof),
96*7c478bd9Sstevel@tonic-gate 		USERATTR_PROFILES_KW },
97*7c478bd9Sstevel@tonic-gate 	{ PROJSTR,	sizeof (PROJSTR) - 1,	PROJID,	DEFOFF(defproj) },
98*7c478bd9Sstevel@tonic-gate 	{ PROJNMSTR,	sizeof (PROJNMSTR) - 1,	STR,	DEFOFF(defprojname) },
99*7c478bd9Sstevel@tonic-gate 	{ LIMPRSTR,	sizeof (LIMPRSTR) - 1,	STR,	DEFOFF(deflimpriv),
100*7c478bd9Sstevel@tonic-gate 		USERATTR_LIMPRIV_KW },
101*7c478bd9Sstevel@tonic-gate 	{ DFLTPRSTR,	sizeof (DFLTPRSTR) - 1,	STR,	DEFOFF(defdfltpriv),
102*7c478bd9Sstevel@tonic-gate 		USERATTR_DFLTPRIV_KW },
103*7c478bd9Sstevel@tonic-gate 	{ LOCK_AFTER_RETRIESSTR,	sizeof (LOCK_AFTER_RETRIESSTR) - 1,
104*7c478bd9Sstevel@tonic-gate 		STR,	DEFOFF(deflock_after_retries),
105*7c478bd9Sstevel@tonic-gate 		USERATTR_LOCK_AFTER_RETRIES_KW },
106*7c478bd9Sstevel@tonic-gate };
107*7c478bd9Sstevel@tonic-gate 
108*7c478bd9Sstevel@tonic-gate #define	NDEF	(sizeof (tab) / sizeof (parsent_t))
109*7c478bd9Sstevel@tonic-gate 
110*7c478bd9Sstevel@tonic-gate FILE *defptr;		/* default file - fptr */
111*7c478bd9Sstevel@tonic-gate 
112*7c478bd9Sstevel@tonic-gate static const parsent_t *
113*7c478bd9Sstevel@tonic-gate scan(char **start_p)
114*7c478bd9Sstevel@tonic-gate {
115*7c478bd9Sstevel@tonic-gate 	static int ind = NDEF - 1;
116*7c478bd9Sstevel@tonic-gate 	char *cur_p = *start_p;
117*7c478bd9Sstevel@tonic-gate 	int lastind = ind;
118*7c478bd9Sstevel@tonic-gate 
119*7c478bd9Sstevel@tonic-gate 	if (!*cur_p || *cur_p == '\n' || *cur_p == '#')
120*7c478bd9Sstevel@tonic-gate 		return (NULL);
121*7c478bd9Sstevel@tonic-gate 
122*7c478bd9Sstevel@tonic-gate 	/*
123*7c478bd9Sstevel@tonic-gate 	 * The magic in this loop is remembering the last index when
124*7c478bd9Sstevel@tonic-gate 	 * reentering the function; the entries above are also used to
125*7c478bd9Sstevel@tonic-gate 	 * order the output to the default file.
126*7c478bd9Sstevel@tonic-gate 	 */
127*7c478bd9Sstevel@tonic-gate 	do {
128*7c478bd9Sstevel@tonic-gate 		ind++;
129*7c478bd9Sstevel@tonic-gate 		ind %= NDEF;
130*7c478bd9Sstevel@tonic-gate 
131*7c478bd9Sstevel@tonic-gate 		if (strncmp(cur_p, tab[ind].name, tab[ind].nmsz) == 0) {
132*7c478bd9Sstevel@tonic-gate 			*start_p = cur_p + tab[ind].nmsz;
133*7c478bd9Sstevel@tonic-gate 			return (&tab[ind]);
134*7c478bd9Sstevel@tonic-gate 		}
135*7c478bd9Sstevel@tonic-gate 	} while (ind != lastind);
136*7c478bd9Sstevel@tonic-gate 
137*7c478bd9Sstevel@tonic-gate 	return (NULL);
138*7c478bd9Sstevel@tonic-gate }
139*7c478bd9Sstevel@tonic-gate 
140*7c478bd9Sstevel@tonic-gate /*
141*7c478bd9Sstevel@tonic-gate  * getusrdef - access the user defaults file.  If it doesn't exist,
142*7c478bd9Sstevel@tonic-gate  *		then returns default values of (values in userdefs.h):
143*7c478bd9Sstevel@tonic-gate  *		defrid = 100
144*7c478bd9Sstevel@tonic-gate  *		defgroup = 1
145*7c478bd9Sstevel@tonic-gate  *		defgname = other
146*7c478bd9Sstevel@tonic-gate  *		defparent = /home
147*7c478bd9Sstevel@tonic-gate  *		defskel	= /usr/sadm/skel
148*7c478bd9Sstevel@tonic-gate  *		defshell = /bin/sh
149*7c478bd9Sstevel@tonic-gate  *		definact = 0
150*7c478bd9Sstevel@tonic-gate  *		defexpire = 0
151*7c478bd9Sstevel@tonic-gate  *		defauth = 0
152*7c478bd9Sstevel@tonic-gate  *		defprof = 0
153*7c478bd9Sstevel@tonic-gate  *		defrole = 0
154*7c478bd9Sstevel@tonic-gate  *
155*7c478bd9Sstevel@tonic-gate  *	If getusrdef() is unable to access the defaults file, it
156*7c478bd9Sstevel@tonic-gate  *	returns a NULL pointer.
157*7c478bd9Sstevel@tonic-gate  *
158*7c478bd9Sstevel@tonic-gate  * 	If user defaults file exists, then getusrdef uses values
159*7c478bd9Sstevel@tonic-gate  *  in it to override the above values.
160*7c478bd9Sstevel@tonic-gate  */
161*7c478bd9Sstevel@tonic-gate 
162*7c478bd9Sstevel@tonic-gate struct userdefs *
163*7c478bd9Sstevel@tonic-gate getusrdef(char *usertype)
164*7c478bd9Sstevel@tonic-gate {
165*7c478bd9Sstevel@tonic-gate 	char instr[512], *ptr;
166*7c478bd9Sstevel@tonic-gate 	const parsent_t *pe;
167*7c478bd9Sstevel@tonic-gate 
168*7c478bd9Sstevel@tonic-gate 	if (is_role(usertype)) {
169*7c478bd9Sstevel@tonic-gate 		if ((defptr = fopen(DEFROLEFILE, "r")) == NULL) {
170*7c478bd9Sstevel@tonic-gate 			defaults.defshell = DEFROLESHL;
171*7c478bd9Sstevel@tonic-gate 			defaults.defprof = DEFROLEPROF;
172*7c478bd9Sstevel@tonic-gate 			return (&defaults);
173*7c478bd9Sstevel@tonic-gate 		}
174*7c478bd9Sstevel@tonic-gate 	} else {
175*7c478bd9Sstevel@tonic-gate 		if ((defptr = fopen(DEFFILE, "r")) == NULL)
176*7c478bd9Sstevel@tonic-gate 			return (&defaults);
177*7c478bd9Sstevel@tonic-gate 	}
178*7c478bd9Sstevel@tonic-gate 
179*7c478bd9Sstevel@tonic-gate 	while (fgets(instr, sizeof (instr), defptr) != NULL) {
180*7c478bd9Sstevel@tonic-gate 		ptr = instr;
181*7c478bd9Sstevel@tonic-gate 
182*7c478bd9Sstevel@tonic-gate 		SKIPWS(ptr);
183*7c478bd9Sstevel@tonic-gate 
184*7c478bd9Sstevel@tonic-gate 		if (*ptr == '#')
185*7c478bd9Sstevel@tonic-gate 			continue;
186*7c478bd9Sstevel@tonic-gate 
187*7c478bd9Sstevel@tonic-gate 		pe = scan(&ptr);
188*7c478bd9Sstevel@tonic-gate 
189*7c478bd9Sstevel@tonic-gate 		if (pe != NULL) {
190*7c478bd9Sstevel@tonic-gate 			switch (pe->type) {
191*7c478bd9Sstevel@tonic-gate 			case INT:
192*7c478bd9Sstevel@tonic-gate 				FIELD(&defaults, pe, int) =
193*7c478bd9Sstevel@tonic-gate 					(int)strtol(ptr, NULL, 10);
194*7c478bd9Sstevel@tonic-gate 				break;
195*7c478bd9Sstevel@tonic-gate 			case PROJID:
196*7c478bd9Sstevel@tonic-gate 				FIELD(&defaults, pe, projid_t) =
197*7c478bd9Sstevel@tonic-gate 					(projid_t)strtol(ptr, NULL, 10);
198*7c478bd9Sstevel@tonic-gate 				break;
199*7c478bd9Sstevel@tonic-gate 			case STR:
200*7c478bd9Sstevel@tonic-gate 				FIELD(&defaults, pe, char *) = dup_to_nl(ptr);
201*7c478bd9Sstevel@tonic-gate 				break;
202*7c478bd9Sstevel@tonic-gate 			}
203*7c478bd9Sstevel@tonic-gate 		}
204*7c478bd9Sstevel@tonic-gate 	}
205*7c478bd9Sstevel@tonic-gate 
206*7c478bd9Sstevel@tonic-gate 	(void) fclose(defptr);
207*7c478bd9Sstevel@tonic-gate 
208*7c478bd9Sstevel@tonic-gate 	return (&defaults);
209*7c478bd9Sstevel@tonic-gate }
210*7c478bd9Sstevel@tonic-gate 
211*7c478bd9Sstevel@tonic-gate static char *
212*7c478bd9Sstevel@tonic-gate dup_to_nl(char *from)
213*7c478bd9Sstevel@tonic-gate {
214*7c478bd9Sstevel@tonic-gate 	char *res = strdup(from);
215*7c478bd9Sstevel@tonic-gate 
216*7c478bd9Sstevel@tonic-gate 	char *p = strchr(res, '\n');
217*7c478bd9Sstevel@tonic-gate 	if (p)
218*7c478bd9Sstevel@tonic-gate 		*p = '\0';
219*7c478bd9Sstevel@tonic-gate 
220*7c478bd9Sstevel@tonic-gate 	return (res);
221*7c478bd9Sstevel@tonic-gate }
222*7c478bd9Sstevel@tonic-gate 
223*7c478bd9Sstevel@tonic-gate void
224*7c478bd9Sstevel@tonic-gate dispusrdef(fptr, flags, usertype)
225*7c478bd9Sstevel@tonic-gate FILE *fptr;
226*7c478bd9Sstevel@tonic-gate unsigned flags;
227*7c478bd9Sstevel@tonic-gate char *usertype;
228*7c478bd9Sstevel@tonic-gate {
229*7c478bd9Sstevel@tonic-gate 	struct userdefs *deflts = getusrdef(usertype);
230*7c478bd9Sstevel@tonic-gate 	register outcount = 0;
231*7c478bd9Sstevel@tonic-gate 
232*7c478bd9Sstevel@tonic-gate 	/* Print out values */
233*7c478bd9Sstevel@tonic-gate 
234*7c478bd9Sstevel@tonic-gate 	if (flags & D_GROUP) {
235*7c478bd9Sstevel@tonic-gate 		outcount += fprintf(fptr, "group=%s,%ld  ",
236*7c478bd9Sstevel@tonic-gate 			deflts->defgname, deflts->defgroup);
237*7c478bd9Sstevel@tonic-gate 		PRINTNL();
238*7c478bd9Sstevel@tonic-gate 	}
239*7c478bd9Sstevel@tonic-gate 
240*7c478bd9Sstevel@tonic-gate 	if (flags & D_PROJ) {
241*7c478bd9Sstevel@tonic-gate 		outcount += fprintf(fptr, "project=%s,%ld  ",
242*7c478bd9Sstevel@tonic-gate 		    deflts->defprojname, deflts->defproj);
243*7c478bd9Sstevel@tonic-gate 		PRINTNL();
244*7c478bd9Sstevel@tonic-gate 	}
245*7c478bd9Sstevel@tonic-gate 
246*7c478bd9Sstevel@tonic-gate 	if (flags & D_BASEDIR) {
247*7c478bd9Sstevel@tonic-gate 		outcount += fprintf(fptr, "basedir=%s  ", deflts->defparent);
248*7c478bd9Sstevel@tonic-gate 		PRINTNL();
249*7c478bd9Sstevel@tonic-gate 	}
250*7c478bd9Sstevel@tonic-gate 
251*7c478bd9Sstevel@tonic-gate 	if (flags & D_RID) {
252*7c478bd9Sstevel@tonic-gate 		outcount += fprintf(fptr, "rid=%ld  ", deflts->defrid);
253*7c478bd9Sstevel@tonic-gate 		PRINTNL();
254*7c478bd9Sstevel@tonic-gate 	}
255*7c478bd9Sstevel@tonic-gate 
256*7c478bd9Sstevel@tonic-gate 	if (flags & D_SKEL) {
257*7c478bd9Sstevel@tonic-gate 		outcount += fprintf(fptr, "skel=%s  ", deflts->defskel);
258*7c478bd9Sstevel@tonic-gate 		PRINTNL();
259*7c478bd9Sstevel@tonic-gate 	}
260*7c478bd9Sstevel@tonic-gate 
261*7c478bd9Sstevel@tonic-gate 	if (flags & D_SHELL) {
262*7c478bd9Sstevel@tonic-gate 		outcount += fprintf(fptr, "shell=%s  ", deflts->defshell);
263*7c478bd9Sstevel@tonic-gate 		PRINTNL();
264*7c478bd9Sstevel@tonic-gate 	}
265*7c478bd9Sstevel@tonic-gate 
266*7c478bd9Sstevel@tonic-gate 	if (flags & D_INACT) {
267*7c478bd9Sstevel@tonic-gate 		outcount += fprintf(fptr, "inactive=%d  ", deflts->definact);
268*7c478bd9Sstevel@tonic-gate 		PRINTNL();
269*7c478bd9Sstevel@tonic-gate 	}
270*7c478bd9Sstevel@tonic-gate 
271*7c478bd9Sstevel@tonic-gate 	if (flags & D_EXPIRE) {
272*7c478bd9Sstevel@tonic-gate 		outcount += fprintf(fptr, "expire=%s  ", deflts->defexpire);
273*7c478bd9Sstevel@tonic-gate 		PRINTNL();
274*7c478bd9Sstevel@tonic-gate 	}
275*7c478bd9Sstevel@tonic-gate 
276*7c478bd9Sstevel@tonic-gate 	if (flags & D_AUTH) {
277*7c478bd9Sstevel@tonic-gate 		outcount += fprintf(fptr, "auths=%s  ", deflts->defauth);
278*7c478bd9Sstevel@tonic-gate 		PRINTNL();
279*7c478bd9Sstevel@tonic-gate 	}
280*7c478bd9Sstevel@tonic-gate 
281*7c478bd9Sstevel@tonic-gate 	if (flags & D_PROF) {
282*7c478bd9Sstevel@tonic-gate 		outcount += fprintf(fptr, "profiles=%s  ", deflts->defprof);
283*7c478bd9Sstevel@tonic-gate 		PRINTNL();
284*7c478bd9Sstevel@tonic-gate 	}
285*7c478bd9Sstevel@tonic-gate 
286*7c478bd9Sstevel@tonic-gate 	if ((flags & D_ROLE) &&
287*7c478bd9Sstevel@tonic-gate 	    (!is_role(usertype))) {
288*7c478bd9Sstevel@tonic-gate 		outcount += fprintf(fptr, "roles=%s  ", deflts->defrole);
289*7c478bd9Sstevel@tonic-gate 		PRINTNL();
290*7c478bd9Sstevel@tonic-gate 	}
291*7c478bd9Sstevel@tonic-gate 
292*7c478bd9Sstevel@tonic-gate 	if (flags & D_LPRIV) {
293*7c478bd9Sstevel@tonic-gate 		outcount += fprintf(fptr, "limitpriv=%s  ",
294*7c478bd9Sstevel@tonic-gate 			deflts->deflimpriv);
295*7c478bd9Sstevel@tonic-gate 		PRINTNL();
296*7c478bd9Sstevel@tonic-gate 	}
297*7c478bd9Sstevel@tonic-gate 
298*7c478bd9Sstevel@tonic-gate 	if (flags & D_DPRIV) {
299*7c478bd9Sstevel@tonic-gate 		outcount += fprintf(fptr, "defaultpriv=%s  ",
300*7c478bd9Sstevel@tonic-gate 			deflts->defdfltpriv);
301*7c478bd9Sstevel@tonic-gate 		PRINTNL();
302*7c478bd9Sstevel@tonic-gate 	}
303*7c478bd9Sstevel@tonic-gate 
304*7c478bd9Sstevel@tonic-gate 	if (flags & D_LOCK) {
305*7c478bd9Sstevel@tonic-gate 		outcount += fprintf(fptr, "lock_after_retries=%s  ",
306*7c478bd9Sstevel@tonic-gate 		    deflts->deflock_after_retries);
307*7c478bd9Sstevel@tonic-gate 	}
308*7c478bd9Sstevel@tonic-gate 
309*7c478bd9Sstevel@tonic-gate 	if (outcount > 0)
310*7c478bd9Sstevel@tonic-gate 		(void) fprintf(fptr, "\n");
311*7c478bd9Sstevel@tonic-gate }
312*7c478bd9Sstevel@tonic-gate 
313*7c478bd9Sstevel@tonic-gate /*
314*7c478bd9Sstevel@tonic-gate  * putusrdef -
315*7c478bd9Sstevel@tonic-gate  * 	changes default values in defadduser file
316*7c478bd9Sstevel@tonic-gate  */
317*7c478bd9Sstevel@tonic-gate int
318*7c478bd9Sstevel@tonic-gate putusrdef(struct userdefs *defs, char *usertype)
319*7c478bd9Sstevel@tonic-gate {
320*7c478bd9Sstevel@tonic-gate 	time_t timeval;		/* time value from time */
321*7c478bd9Sstevel@tonic-gate 	int i;
322*7c478bd9Sstevel@tonic-gate 	ptrdiff_t skip;
323*7c478bd9Sstevel@tonic-gate 	char *hdr;
324*7c478bd9Sstevel@tonic-gate 
325*7c478bd9Sstevel@tonic-gate 	/*
326*7c478bd9Sstevel@tonic-gate 	 * file format is:
327*7c478bd9Sstevel@tonic-gate 	 * #<tab>Default values for adduser.  Changed mm/dd/yy hh:mm:ss.
328*7c478bd9Sstevel@tonic-gate 	 * defgroup=m	(m=default group id)
329*7c478bd9Sstevel@tonic-gate 	 * defgname=str1	(str1=default group name)
330*7c478bd9Sstevel@tonic-gate 	 * defparent=str2	(str2=default base directory)
331*7c478bd9Sstevel@tonic-gate 	 * definactive=x	(x=default inactive)
332*7c478bd9Sstevel@tonic-gate 	 * defexpire=y		(y=default expire)
333*7c478bd9Sstevel@tonic-gate 	 * defproj=z		(z=numeric project id)
334*7c478bd9Sstevel@tonic-gate 	 * defprojname=str3	(str3=default project name)
335*7c478bd9Sstevel@tonic-gate 	 * ... etc ...
336*7c478bd9Sstevel@tonic-gate 	 */
337*7c478bd9Sstevel@tonic-gate 
338*7c478bd9Sstevel@tonic-gate 	if (is_role(usertype)) {
339*7c478bd9Sstevel@tonic-gate 		if ((defptr = fopen(DEFROLEFILE, "w")) == NULL) {
340*7c478bd9Sstevel@tonic-gate 			errmsg(M_FAILED);
341*7c478bd9Sstevel@tonic-gate 			return (EX_UPDATE);
342*7c478bd9Sstevel@tonic-gate 		}
343*7c478bd9Sstevel@tonic-gate 	} else {
344*7c478bd9Sstevel@tonic-gate 		if ((defptr = fopen(DEFFILE, "w")) == NULL) {
345*7c478bd9Sstevel@tonic-gate 			errmsg(M_FAILED);
346*7c478bd9Sstevel@tonic-gate 			return (EX_UPDATE);
347*7c478bd9Sstevel@tonic-gate 		}
348*7c478bd9Sstevel@tonic-gate 	}
349*7c478bd9Sstevel@tonic-gate 
350*7c478bd9Sstevel@tonic-gate 	if (lockf(fileno(defptr), F_LOCK, 0) != 0) {
351*7c478bd9Sstevel@tonic-gate 		/* print error if can't lock whole of DEFFILE */
352*7c478bd9Sstevel@tonic-gate 		errmsg(M_UPDATE, "created");
353*7c478bd9Sstevel@tonic-gate 		return (EX_UPDATE);
354*7c478bd9Sstevel@tonic-gate 	}
355*7c478bd9Sstevel@tonic-gate 
356*7c478bd9Sstevel@tonic-gate 	if (is_role(usertype)) {
357*7c478bd9Sstevel@tonic-gate 		/* If it's a role, we must skip the defrole field */
358*7c478bd9Sstevel@tonic-gate 		skip = offsetof(struct userdefs, defrole);
359*7c478bd9Sstevel@tonic-gate 		hdr = FHEADER_ROLE;
360*7c478bd9Sstevel@tonic-gate 	} else {
361*7c478bd9Sstevel@tonic-gate 		skip = -1;
362*7c478bd9Sstevel@tonic-gate 		hdr = FHEADER;
363*7c478bd9Sstevel@tonic-gate 	}
364*7c478bd9Sstevel@tonic-gate 
365*7c478bd9Sstevel@tonic-gate 	/* get time */
366*7c478bd9Sstevel@tonic-gate 	timeval = time(NULL);
367*7c478bd9Sstevel@tonic-gate 
368*7c478bd9Sstevel@tonic-gate 	/* write it to file */
369*7c478bd9Sstevel@tonic-gate 	if (fprintf(defptr, "%s%s\n", hdr, ctime(&timeval)) <= 0) {
370*7c478bd9Sstevel@tonic-gate 		errmsg(M_UPDATE, "created");
371*7c478bd9Sstevel@tonic-gate 		return (EX_UPDATE);
372*7c478bd9Sstevel@tonic-gate 	}
373*7c478bd9Sstevel@tonic-gate 
374*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < NDEF; i++) {
375*7c478bd9Sstevel@tonic-gate 		int res = 0;
376*7c478bd9Sstevel@tonic-gate 
377*7c478bd9Sstevel@tonic-gate 		if (tab[i].off == skip)
378*7c478bd9Sstevel@tonic-gate 			continue;
379*7c478bd9Sstevel@tonic-gate 
380*7c478bd9Sstevel@tonic-gate 		switch (tab[i].type) {
381*7c478bd9Sstevel@tonic-gate 		case INT:
382*7c478bd9Sstevel@tonic-gate 			res = fprintf(defptr, "%s%d\n", tab[i].name,
383*7c478bd9Sstevel@tonic-gate 					FIELD(defs, &tab[i], int));
384*7c478bd9Sstevel@tonic-gate 			break;
385*7c478bd9Sstevel@tonic-gate 		case STR:
386*7c478bd9Sstevel@tonic-gate 			res = fprintf(defptr, "%s%s\n", tab[i].name,
387*7c478bd9Sstevel@tonic-gate 					FIELD(defs, &tab[i], char *));
388*7c478bd9Sstevel@tonic-gate 			break;
389*7c478bd9Sstevel@tonic-gate 		case PROJID:
390*7c478bd9Sstevel@tonic-gate 			res = fprintf(defptr, "%s%d\n", tab[i].name,
391*7c478bd9Sstevel@tonic-gate 					(int)FIELD(defs, &tab[i], projid_t));
392*7c478bd9Sstevel@tonic-gate 			break;
393*7c478bd9Sstevel@tonic-gate 		}
394*7c478bd9Sstevel@tonic-gate 
395*7c478bd9Sstevel@tonic-gate 		if (res <= 0) {
396*7c478bd9Sstevel@tonic-gate 			errmsg(M_UPDATE, "created");
397*7c478bd9Sstevel@tonic-gate 			return (EX_UPDATE);
398*7c478bd9Sstevel@tonic-gate 		}
399*7c478bd9Sstevel@tonic-gate 	}
400*7c478bd9Sstevel@tonic-gate 
401*7c478bd9Sstevel@tonic-gate 	(void) lockf(fileno(defptr), F_ULOCK, 0);
402*7c478bd9Sstevel@tonic-gate 	(void) fclose(defptr);
403*7c478bd9Sstevel@tonic-gate 
404*7c478bd9Sstevel@tonic-gate 	return (EX_SUCCESS);
405*7c478bd9Sstevel@tonic-gate }
406*7c478bd9Sstevel@tonic-gate 
407*7c478bd9Sstevel@tonic-gate /* Export command line keys to defaults for useradd -D */
408*7c478bd9Sstevel@tonic-gate void
409*7c478bd9Sstevel@tonic-gate update_def(struct userdefs *ud)
410*7c478bd9Sstevel@tonic-gate {
411*7c478bd9Sstevel@tonic-gate 	int i;
412*7c478bd9Sstevel@tonic-gate 
413*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < NDEF; i++) {
414*7c478bd9Sstevel@tonic-gate 		char *val;
415*7c478bd9Sstevel@tonic-gate 		if (tab[i].uakey != NULL &&
416*7c478bd9Sstevel@tonic-gate 		    (val = getsetdefval(tab[i].uakey, NULL)) != NULL)
417*7c478bd9Sstevel@tonic-gate 			FIELD(ud, &tab[i], char *) = val;
418*7c478bd9Sstevel@tonic-gate 	}
419*7c478bd9Sstevel@tonic-gate }
420*7c478bd9Sstevel@tonic-gate 
421*7c478bd9Sstevel@tonic-gate /* Import default keys for ordinary useradd */
422*7c478bd9Sstevel@tonic-gate void
423*7c478bd9Sstevel@tonic-gate import_def(struct userdefs *ud)
424*7c478bd9Sstevel@tonic-gate {
425*7c478bd9Sstevel@tonic-gate 	int i;
426*7c478bd9Sstevel@tonic-gate 
427*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < NDEF; i++) {
428*7c478bd9Sstevel@tonic-gate 		if (tab[i].uakey != NULL && tab[i].type == STR) {
429*7c478bd9Sstevel@tonic-gate 			char *val = FIELD(ud, &tab[i], char *);
430*7c478bd9Sstevel@tonic-gate 			if (val == getsetdefval(tab[i].uakey, val))
431*7c478bd9Sstevel@tonic-gate 				nkeys ++;
432*7c478bd9Sstevel@tonic-gate 		}
433*7c478bd9Sstevel@tonic-gate 	}
434*7c478bd9Sstevel@tonic-gate }
435