4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
24 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
28 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
29 /* All Rights Reserved */
32 * Copyright (c) 2013 RackTop Systems.
37 #include <sys/types.h>
41 #include <user_attr.h>
51 /* Print out a NL when the line gets too long */
53 if (outcount > 40) { \
55 (void) fprintf(fptr, "\n"); \
58 #define SKIPWS(ptr) while (*ptr && (*ptr == ' ' || *ptr == '\t')) ptr++
60 static char *dup_to_nl(char *);
62 static struct userdefs defaults
= {
63 DEFRID
, DEFGROUP
, DEFGNAME
, DEFPARENT
, DEFSKL
,
64 DEFSHL
, DEFINACT
, DEFEXPIRE
, DEFAUTH
, DEFPROF
,
65 DEFROLE
, DEFPROJ
, DEFPROJNAME
, DEFLIMPRIV
,
66 DEFDFLTPRIV
, DEFLOCK_AFTER_RETRIES
73 #define DEFOFF(field) offsetof(struct userdefs, field)
74 #define FIELD(up, pe, type) (*(type *)((char *)(up) + (pe)->off))
76 typedef struct parsent
{
77 const char *name
; /* deffoo= */
78 const size_t nmsz
; /* length of def= string (excluding \0) */
79 const int type
; /* type of entry */
80 const ptrdiff_t off
; /* offset in userdefs structure */
81 const char *uakey
; /* user_attr key, if defined */
84 static const parsent_t tab
[] = {
85 { GIDSTR
, sizeof (GIDSTR
) - 1, INT
, DEFOFF(defgroup
) },
86 { GNAMSTR
, sizeof (GNAMSTR
) - 1, STR
, DEFOFF(defgname
) },
87 { PARSTR
, sizeof (PARSTR
) - 1, STR
, DEFOFF(defparent
) },
88 { SKLSTR
, sizeof (SKLSTR
) - 1, STR
, DEFOFF(defskel
) },
89 { SHELLSTR
, sizeof (SHELLSTR
) - 1, STR
, DEFOFF(defshell
) },
90 { INACTSTR
, sizeof (INACTSTR
) - 1, INT
, DEFOFF(definact
) },
91 { EXPIRESTR
, sizeof (EXPIRESTR
) - 1, STR
, DEFOFF(defexpire
) },
92 { AUTHSTR
, sizeof (AUTHSTR
) - 1, STR
, DEFOFF(defauth
),
94 { ROLESTR
, sizeof (ROLESTR
) - 1, STR
, DEFOFF(defrole
),
96 { PROFSTR
, sizeof (PROFSTR
) - 1, STR
, DEFOFF(defprof
),
97 USERATTR_PROFILES_KW
},
98 { PROJSTR
, sizeof (PROJSTR
) - 1, PROJID
, DEFOFF(defproj
) },
99 { PROJNMSTR
, sizeof (PROJNMSTR
) - 1, STR
, DEFOFF(defprojname
) },
100 { LIMPRSTR
, sizeof (LIMPRSTR
) - 1, STR
, DEFOFF(deflimpriv
),
101 USERATTR_LIMPRIV_KW
},
102 { DFLTPRSTR
, sizeof (DFLTPRSTR
) - 1, STR
, DEFOFF(defdfltpriv
),
103 USERATTR_DFLTPRIV_KW
},
104 { LOCK_AFTER_RETRIESSTR
, sizeof (LOCK_AFTER_RETRIESSTR
) - 1,
105 STR
, DEFOFF(deflock_after_retries
),
106 USERATTR_LOCK_AFTER_RETRIES_KW
},
109 #define NDEF (sizeof (tab) / sizeof (parsent_t))
111 FILE *defptr
; /* default file - fptr */
113 static const parsent_t
*
116 static int ind
= NDEF
- 1;
117 char *cur_p
= *start_p
;
120 if (!*cur_p
|| *cur_p
== '\n' || *cur_p
== '#')
124 * The magic in this loop is remembering the last index when
125 * reentering the function; the entries above are also used to
126 * order the output to the default file.
132 if (strncmp(cur_p
, tab
[ind
].name
, tab
[ind
].nmsz
) == 0) {
133 *start_p
= cur_p
+ tab
[ind
].nmsz
;
136 } while (ind
!= lastind
);
142 * getusrdef - access the user defaults file. If it doesn't exist,
143 * then returns default values of (values in userdefs.h):
148 * defskel = /usr/sadm/skel
156 * If getusrdef() is unable to access the defaults file, it
157 * returns a NULL pointer.
159 * If user defaults file exists, then getusrdef uses values
160 * in it to override the above values.
164 getusrdef(char *usertype
)
166 char instr
[512], *ptr
;
169 if (is_role(usertype
)) {
170 if ((defptr
= fopen(DEFROLEFILE
, "r")) == NULL
) {
171 defaults
.defshell
= DEFROLESHL
;
172 defaults
.defprof
= DEFROLEPROF
;
176 if ((defptr
= fopen(DEFFILE
, "r")) == NULL
)
180 while (fgets(instr
, sizeof (instr
), defptr
) != NULL
) {
193 FIELD(&defaults
, pe
, int) =
194 (int)strtol(ptr
, NULL
, 10);
197 FIELD(&defaults
, pe
, projid_t
) =
198 (projid_t
)strtol(ptr
, NULL
, 10);
201 FIELD(&defaults
, pe
, char *) = dup_to_nl(ptr
);
207 (void) fclose(defptr
);
213 dup_to_nl(char *from
)
215 char *res
= strdup(from
);
217 char *p
= strchr(res
, '\n');
225 dispusrdef(FILE *fptr
, unsigned flags
, char *usertype
)
227 struct userdefs
*deflts
= getusrdef(usertype
);
230 /* Print out values */
232 if (flags
& D_GROUP
) {
233 outcount
+= fprintf(fptr
, "group=%s,%ld ",
234 deflts
->defgname
, deflts
->defgroup
);
238 if (flags
& D_PROJ
) {
239 outcount
+= fprintf(fptr
, "project=%s,%ld ",
240 deflts
->defprojname
, deflts
->defproj
);
244 if (flags
& D_BASEDIR
) {
245 outcount
+= fprintf(fptr
, "basedir=%s ", deflts
->defparent
);
250 outcount
+= fprintf(fptr
, "rid=%ld ", deflts
->defrid
);
254 if (flags
& D_SKEL
) {
255 outcount
+= fprintf(fptr
, "skel=%s ", deflts
->defskel
);
259 if (flags
& D_SHELL
) {
260 outcount
+= fprintf(fptr
, "shell=%s ", deflts
->defshell
);
264 if (flags
& D_INACT
) {
265 outcount
+= fprintf(fptr
, "inactive=%d ", deflts
->definact
);
269 if (flags
& D_EXPIRE
) {
270 outcount
+= fprintf(fptr
, "expire=%s ", deflts
->defexpire
);
274 if (flags
& D_AUTH
) {
275 outcount
+= fprintf(fptr
, "auths=%s ", deflts
->defauth
);
279 if (flags
& D_PROF
) {
280 outcount
+= fprintf(fptr
, "profiles=%s ", deflts
->defprof
);
284 if ((flags
& D_ROLE
) &&
285 (!is_role(usertype
))) {
286 outcount
+= fprintf(fptr
, "roles=%s ", deflts
->defrole
);
290 if (flags
& D_LPRIV
) {
291 outcount
+= fprintf(fptr
, "limitpriv=%s ",
296 if (flags
& D_DPRIV
) {
297 outcount
+= fprintf(fptr
, "defaultpriv=%s ",
298 deflts
->defdfltpriv
);
302 if (flags
& D_LOCK
) {
303 outcount
+= fprintf(fptr
, "lock_after_retries=%s ",
304 deflts
->deflock_after_retries
);
308 (void) fprintf(fptr
, "\n");
313 * changes default values in defadduser file
316 putusrdef(struct userdefs
*defs
, char *usertype
)
318 time_t timeval
; /* time value from time */
325 * #<tab>Default values for adduser. Changed mm/dd/yy hh:mm:ss.
326 * defgroup=m (m=default group id)
327 * defgname=str1 (str1=default group name)
328 * defparent=str2 (str2=default base directory)
329 * definactive=x (x=default inactive)
330 * defexpire=y (y=default expire)
331 * defproj=z (z=numeric project id)
332 * defprojname=str3 (str3=default project name)
336 if (is_role(usertype
)) {
337 if ((defptr
= fopen(DEFROLEFILE
, "w")) == NULL
) {
342 if ((defptr
= fopen(DEFFILE
, "w")) == NULL
) {
348 if (lockf(fileno(defptr
), F_LOCK
, 0) != 0) {
349 /* print error if can't lock whole of DEFFILE */
350 errmsg(M_UPDATE
, "created");
354 if (is_role(usertype
)) {
355 /* If it's a role, we must skip the defrole field */
356 skip
= offsetof(struct userdefs
, defrole
);
364 timeval
= time(NULL
);
366 /* write it to file */
367 if (fprintf(defptr
, "%s%s\n", hdr
, ctime(&timeval
)) <= 0) {
368 errmsg(M_UPDATE
, "created");
372 for (i
= 0; i
< NDEF
; i
++) {
375 if (tab
[i
].off
== skip
)
378 switch (tab
[i
].type
) {
380 res
= fprintf(defptr
, "%s%d\n", tab
[i
].name
,
381 FIELD(defs
, &tab
[i
], int));
384 res
= fprintf(defptr
, "%s%s\n", tab
[i
].name
,
385 FIELD(defs
, &tab
[i
], char *));
388 res
= fprintf(defptr
, "%s%d\n", tab
[i
].name
,
389 (int)FIELD(defs
, &tab
[i
], projid_t
));
394 errmsg(M_UPDATE
, "created");
399 (void) lockf(fileno(defptr
), F_ULOCK
, 0);
400 (void) fclose(defptr
);
405 /* Export command line keys to defaults for useradd -D */
407 update_def(struct userdefs
*ud
)
411 for (i
= 0; i
< NDEF
; i
++) {
413 if (tab
[i
].uakey
!= NULL
&&
414 (val
= getsetdefval(tab
[i
].uakey
, NULL
)) != NULL
)
415 FIELD(ud
, &tab
[i
], char *) = val
;
419 /* Import default keys for ordinary useradd */
421 import_def(struct userdefs
*ud
)
425 for (i
= 0; i
< NDEF
; i
++) {
426 if (tab
[i
].uakey
!= NULL
&& tab
[i
].type
== STR
) {
427 char *val
= FIELD(ud
, &tab
[i
], char *);
428 if (val
== getsetdefval(tab
[i
].uakey
, val
))