38 #include <stdio.h>
39 #include <string.h>
40 #include <userdefs.h>
41 #include <user_attr.h>
42 #include <limits.h>
43 #include <stdlib.h>
44 #include <stddef.h>
45 #include <time.h>
46 #include <unistd.h>
47 #include "userdisp.h"
48 #include "funcs.h"
49 #include "messages.h"
50
51 /* Print out a NL when the line gets too long */
52 #define PRINTNL() \
53 if (outcount > 40) { \
54 outcount = 0; \
55 (void) fprintf(fptr, "\n"); \
56 }
57
58 #define SKIPWS(ptr) while (*ptr && (*ptr == ' ' || *ptr == '\t')) ptr++
59
60 static char *dup_to_nl(char *);
61
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
67 };
68
69 #define INT 0
70 #define STR 1
71 #define PROJID 2
72
73 #define DEFOFF(field) offsetof(struct userdefs, field)
74 #define FIELD(up, pe, type) (*(type *)((char *)(up) + (pe)->off))
75
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 */
82 } parsent_t;
83
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),
93 USERATTR_AUTHS_KW },
94 { ROLESTR, sizeof (ROLESTR) - 1, STR, DEFOFF(defrole),
95 USERATTR_ROLES_KW },
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 },
107 };
108
109 #define NDEF (sizeof (tab) / sizeof (parsent_t))
110
111 FILE *defptr; /* default file - fptr */
112
113 static const parsent_t *
114 scan(char **start_p)
115 {
116 static int ind = NDEF - 1;
117 char *cur_p = *start_p;
118 int lastind = ind;
119
120 if (!*cur_p || *cur_p == '\n' || *cur_p == '#')
121 return (NULL);
122
123 /*
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.
127 */
128 do {
129 ind++;
130 ind %= NDEF;
131
132 if (strncmp(cur_p, tab[ind].name, tab[ind].nmsz) == 0) {
133 *start_p = cur_p + tab[ind].nmsz;
134 return (&tab[ind]);
135 }
136 } while (ind != lastind);
137
138 return (NULL);
139 }
140
141 /*
142 * getusrdef - access the user defaults file. If it doesn't exist,
143 * then returns default values of (values in userdefs.h):
144 * defrid = 100
145 * defgroup = 1
146 * defgname = other
147 * defparent = /home
148 * defskel = /usr/sadm/skel
149 * defshell = /bin/sh
150 * definact = 0
151 * defexpire = 0
152 * defauth = 0
153 * defprof = 0
154 * defrole = 0
155 *
156 * If getusrdef() is unable to access the defaults file, it
157 * returns a NULL pointer.
158 *
159 * If user defaults file exists, then getusrdef uses values
160 * in it to override the above values.
161 */
162
163 struct userdefs *
164 getusrdef(char *usertype)
165 {
166 char instr[512], *ptr;
167 const parsent_t *pe;
168
169 if (is_role(usertype)) {
170 if ((defptr = fopen(DEFROLEFILE, "r")) == NULL) {
171 defaults.defshell = DEFROLESHL;
172 defaults.defprof = DEFROLEPROF;
173 return (&defaults);
174 }
175 } else {
176 if ((defptr = fopen(DEFFILE, "r")) == NULL)
177 return (&defaults);
178 }
179
180 while (fgets(instr, sizeof (instr), defptr) != NULL) {
181 ptr = instr;
182
183 SKIPWS(ptr);
184
185 if (*ptr == '#')
186 continue;
187
188 pe = scan(&ptr);
189
190 if (pe != NULL) {
191 switch (pe->type) {
192 case INT:
193 FIELD(&defaults, pe, int) =
194 (int)strtol(ptr, NULL, 10);
195 break;
196 case PROJID:
197 FIELD(&defaults, pe, projid_t) =
198 (projid_t)strtol(ptr, NULL, 10);
199 break;
200 case STR:
201 FIELD(&defaults, pe, char *) = dup_to_nl(ptr);
202 break;
203 }
204 }
205 }
206
207 (void) fclose(defptr);
208
209 return (&defaults);
210 }
211
212 static char *
213 dup_to_nl(char *from)
214 {
215 char *res = strdup(from);
216
217 char *p = strchr(res, '\n');
218 if (p)
219 *p = '\0';
220
221 return (res);
222 }
223
224 void
225 dispusrdef(FILE *fptr, unsigned flags, char *usertype)
226 {
227 struct userdefs *deflts = getusrdef(usertype);
228 int outcount = 0;
229
230 /* Print out values */
231
232 if (flags & D_GROUP) {
233 outcount += fprintf(fptr, "group=%s,%ld ",
234 deflts->defgname, deflts->defgroup);
235 PRINTNL();
236 }
237
238 if (flags & D_PROJ) {
239 outcount += fprintf(fptr, "project=%s,%ld ",
240 deflts->defprojname, deflts->defproj);
241 PRINTNL();
242 }
243
298 deflts->defdfltpriv);
299 PRINTNL();
300 }
301
302 if (flags & D_LOCK) {
303 outcount += fprintf(fptr, "lock_after_retries=%s ",
304 deflts->deflock_after_retries);
305 }
306
307 if (outcount > 0)
308 (void) fprintf(fptr, "\n");
309 }
310
311 /*
312 * putusrdef -
313 * changes default values in defadduser file
314 */
315 int
316 putusrdef(struct userdefs *defs, char *usertype)
317 {
318 time_t timeval; /* time value from time */
319 int i;
320 ptrdiff_t skip;
321 char *hdr;
322
323 /*
324 * file format is:
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)
333 * ... etc ...
334 */
335
336 if (is_role(usertype)) {
337 if ((defptr = fopen(DEFROLEFILE, "w")) == NULL) {
338 errmsg(M_FAILED);
339 return (EX_UPDATE);
340 }
341 } else {
342 if ((defptr = fopen(DEFFILE, "w")) == NULL) {
343 errmsg(M_FAILED);
344 return (EX_UPDATE);
345 }
346 }
347
348 if (lockf(fileno(defptr), F_LOCK, 0) != 0) {
349 /* print error if can't lock whole of DEFFILE */
350 errmsg(M_UPDATE, "created");
351 return (EX_UPDATE);
352 }
353
354 if (is_role(usertype)) {
355 /* If it's a role, we must skip the defrole field */
356 skip = offsetof(struct userdefs, defrole);
357 hdr = FHEADER_ROLE;
358 } else {
359 skip = -1;
360 hdr = FHEADER;
361 }
362
363 /* get time */
364 timeval = time(NULL);
365
366 /* write it to file */
367 if (fprintf(defptr, "%s%s\n", hdr, ctime(&timeval)) <= 0) {
368 errmsg(M_UPDATE, "created");
369 return (EX_UPDATE);
370 }
371
372 for (i = 0; i < NDEF; i++) {
373 int res = 0;
374
375 if (tab[i].off == skip)
376 continue;
377
378 switch (tab[i].type) {
379 case INT:
380 res = fprintf(defptr, "%s%d\n", tab[i].name,
381 FIELD(defs, &tab[i], int));
382 break;
383 case STR:
384 res = fprintf(defptr, "%s%s\n", tab[i].name,
385 FIELD(defs, &tab[i], char *));
386 break;
387 case PROJID:
388 res = fprintf(defptr, "%s%d\n", tab[i].name,
389 (int)FIELD(defs, &tab[i], projid_t));
390 break;
391 }
392
393 if (res <= 0) {
394 errmsg(M_UPDATE, "created");
395 return (EX_UPDATE);
396 }
397 }
398
399 (void) lockf(fileno(defptr), F_ULOCK, 0);
400 (void) fclose(defptr);
401
402 return (EX_SUCCESS);
403 }
404
405 /* Export command line keys to defaults for useradd -D */
406 void
407 update_def(struct userdefs *ud)
408 {
409 int i;
410
411 for (i = 0; i < NDEF; i++) {
412 char *val;
413 if (tab[i].uakey != NULL &&
414 (val = getsetdefval(tab[i].uakey, NULL)) != NULL)
415 FIELD(ud, &tab[i], char *) = val;
416 }
417 }
418
419 /* Import default keys for ordinary useradd */
420 void
421 import_def(struct userdefs *ud)
422 {
423 int i;
424
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))
429 nkeys ++;
430 }
431 }
432 }
|
38 #include <stdio.h>
39 #include <string.h>
40 #include <userdefs.h>
41 #include <user_attr.h>
42 #include <limits.h>
43 #include <stdlib.h>
44 #include <stddef.h>
45 #include <time.h>
46 #include <unistd.h>
47 #include "userdisp.h"
48 #include "funcs.h"
49 #include "messages.h"
50
51 /* Print out a NL when the line gets too long */
52 #define PRINTNL() \
53 if (outcount > 40) { \
54 outcount = 0; \
55 (void) fprintf(fptr, "\n"); \
56 }
57
58 /*
59 * getusrdef - get the user defaults file for the type of
60 * user entry (user or role). See libuserdefs
61 */
62
63 struct userdefs *
64 getusrdef(char *usertype)
65 {
66 struct userdefs *ud;
67
68 if (is_role(usertype))
69 ud = _get_roledefs();
70 else
71 ud = _get_userdefs();
72
73 return (ud);
74 }
75
76 void
77 dispusrdef(FILE *fptr, unsigned flags, char *usertype)
78 {
79 struct userdefs *deflts = getusrdef(usertype);
80 int outcount = 0;
81
82 /* Print out values */
83
84 if (flags & D_GROUP) {
85 outcount += fprintf(fptr, "group=%s,%ld ",
86 deflts->defgname, deflts->defgroup);
87 PRINTNL();
88 }
89
90 if (flags & D_PROJ) {
91 outcount += fprintf(fptr, "project=%s,%ld ",
92 deflts->defprojname, deflts->defproj);
93 PRINTNL();
94 }
95
150 deflts->defdfltpriv);
151 PRINTNL();
152 }
153
154 if (flags & D_LOCK) {
155 outcount += fprintf(fptr, "lock_after_retries=%s ",
156 deflts->deflock_after_retries);
157 }
158
159 if (outcount > 0)
160 (void) fprintf(fptr, "\n");
161 }
162
163 /*
164 * putusrdef -
165 * changes default values in defadduser file
166 */
167 int
168 putusrdef(struct userdefs *defs, char *usertype)
169 {
170 FILE *fp = NULL; /* default file - fptr */
171 boolean_t locked = B_FALSE;
172 int res;
173 int ex = EX_UPDATE;
174
175 if (is_role(usertype)) {
176 fp = fopen(DEFROLEFILE, "w");
177 } else {
178 fp = fopen(DEFFILE, "w");
179 }
180 if (fp == NULL) {
181 errmsg(M_FAILED);
182 goto out;
183 }
184
185 if (lockf(fileno(fp), F_LOCK, 0) != 0) {
186 /* print error if can't lock whole of DEFFILE */
187 errmsg(M_UPDATE, "created");
188 goto out;
189 }
190 locked = B_TRUE;
191
192 if (is_role(usertype)) {
193 res = fwrite_roledefs(fp, defs);
194 } else {
195 res = fwrite_userdefs(fp, defs);
196 }
197 if (res <= 0) {
198 errmsg(M_UPDATE, "created");
199 goto out;
200 }
201 ex = EX_SUCCESS;
202
203 out:
204 if (fp != NULL) {
205 if (locked)
206 (void) lockf(fileno(fp), F_ULOCK, 0);
207 (void) fclose(fp);
208 }
209
210 return (ex);
211 }
|