]>
git.cameronkatri.com Git - pw-darwin.git/blob - pw/pw_conf.c
3 * David L. Nugent. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY DAVID L. NUGENT AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL DAVID L. NUGENT OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * $Id: pw_conf.c,v 1.1.1.2 1996/12/10 23:59:00 joerg Exp $
62 static char bourne_shell
[] = "sh";
64 static char *system_shells
[_UC_MAXSHELLS
] =
70 static char const *booltrue
[] =
72 "yes", "true", "1", "on", NULL
74 static char const *boolfalse
[] =
76 "no", "false", "0", "off", NULL
79 static struct userconf config
=
81 0, /* Default password for new users? (nologin) */
84 "/usr/share/skel", /* Where to obtain skeleton files */
85 NULL
, /* Mail to send to new accounts */
86 "/var/log/userlog", /* Where to log changes */
87 "/home", /* Where to create home directory */
88 "/bin", /* Where shells are located */
89 system_shells
, /* List of shells (first is default) */
90 bourne_shell
, /* Default shell */
91 NULL
, /* Default group name */
92 NULL
, /* Default (additional) groups */
93 NULL
, /* Default login class */
94 1000, 32000, /* Allowed range of uids */
95 1000, 32000, /* Allowed range of gids */
96 0, /* Days until account expires */
97 0 /* Days until password expires */
100 static char const *comments
[_UC_FIELDS
] =
102 "#\n# pw.conf - user/group configuration defaults\n#\n",
103 "\n# Password for new users? no=nologin yes=loginid none=blank random=random\n",
104 "\n# Reuse gaps in uid sequence? (yes or no)\n",
105 "\n# Reuse gaps in gid sequence? (yes or no)\n",
106 "\n# Obtain default dotfiles from this directory\n",
107 "\n# Mail this file to new user (/etc/newuser.msg or no)\n",
108 "\n# Log add/change/remove information in this file\n",
109 "\n# Root directory in which $HOME directory is created\n",
110 "\n# Colon separated list of directories containing valid shells\n",
111 "\n# Space separated list of available shells (without paths)\n",
112 "\n# Default shell (without path)\n",
113 "\n# Default group (leave blank for new group per user)\n",
114 "\n# Extra groups for new users\n",
115 "\n# Default login class for new users\n",
116 "\n# Range of valid default user ids\n",
118 "\n# Range of valid default group ids\n",
120 "\n# Days after which account expires (0=disabled)\n",
121 "\n# Days after which password expires (0=disabled)\n"
124 static char const *kwds
[] =
150 unquote(char const * str
)
152 if (str
&& (*str
== '"' || *str
== '\'')) {
153 char *p
= strchr(str
+ 1, *str
);
157 return (char *) (*++str
? str
: NULL
);
163 boolean_val(char const * str
, int dflt
)
165 if ((str
= unquote(str
)) != NULL
) {
168 for (i
= 0; booltrue
[i
]; i
++)
169 if (strcmp(str
, booltrue
[i
]) == 0)
171 for (i
= 0; boolfalse
[i
]; i
++)
172 if (strcmp(str
, boolfalse
[i
]) == 0)
176 * Special cases for defaultpassword
178 if (strcmp(str
, "random") == 0)
180 if (strcmp(str
, "none") == 0)
194 return val
? booltrue
[0] : boolfalse
[0];
198 newstr(char const * p
)
202 if ((p
= unquote(p
)) != NULL
) {
203 int l
= strlen(p
) + 1;
205 if ((q
= malloc(l
)) != NULL
)
215 read_userconfig(char const * file
)
219 extendarray(&config
.groups
, &config
.numgroups
, 200);
220 memset(config
.groups
, 0, config
.numgroups
* sizeof(char *));
222 file
= _PATH_PW_CONF
;
223 if ((fp
= fopen(file
, "r")) != NULL
) {
224 int buflen
= LNBUFSZ
;
225 char *buf
= malloc(buflen
);
228 while (fgets(buf
, buflen
, fp
) != NULL
) {
231 while ((p
= strchr(buf
, '\n')) == NULL
) {
233 if (extendline(&buf
, &buflen
, buflen
+ LNBUFSZ
) == -1) {
235 while ((ch
= fgetc(fp
)) != '\n' && ch
!= EOF
);
236 goto nextline
; /* Ignore it */
239 if (fgets(buf
+ l
, buflen
- l
, fp
) == NULL
)
240 break; /* Unterminated last line */
246 if (*buf
&& (p
= strtok(buf
, " \t\r\n=")) != NULL
&& *p
!= '#') {
247 static char const toks
[] = " \t\r\n,=";
248 char *q
= strtok(NULL
, toks
);
251 while (i
< _UC_FIELDS
&& strcmp(p
, kwds
[i
]) != 0)
255 printf("Got unknown kwd `%s' val=`%s'\n", p
, q
? q
: "");
257 printf("Got kwd[%s]=%s\n", p
, q
);
261 config
.default_password
= boolean_val(q
, 1);
264 config
.reuse_uids
= boolean_val(q
, 0);
267 config
.reuse_gids
= boolean_val(q
, 0);
270 config
.dotdir
= (q
== NULL
|| !boolean_val(q
, 1))
274 config
.newmail
= (q
== NULL
|| !boolean_val(q
, 1))
278 config
.logfile
= (q
== NULL
|| !boolean_val(q
, 1))
282 config
.home
= (q
== NULL
|| !boolean_val(q
, 1))
283 ? "/home" : newstr(q
);
286 config
.shelldir
= (q
== NULL
|| !boolean_val(q
, 1))
287 ? "/bin" : newstr(q
);
290 for (i
= 0; i
< _UC_MAXSHELLS
&& q
!= NULL
; i
++, q
= strtok(NULL
, toks
))
291 system_shells
[i
] = newstr(q
);
293 while (i
< _UC_MAXSHELLS
)
294 system_shells
[i
++] = NULL
;
296 case _UC_DEFAULTSHELL
:
297 config
.shell_default
= (q
== NULL
|| !boolean_val(q
, 1))
298 ? (char *) bourne_shell
: newstr(q
);
300 case _UC_DEFAULTGROUP
:
301 config
.default_group
= (q
== NULL
|| !boolean_val(q
, 1) || getgrnam(q
) == NULL
)
304 case _UC_EXTRAGROUPS
:
305 for (i
= 0; q
!= NULL
; q
= strtok(NULL
, toks
)) {
306 if (extendarray(&config
.groups
, &config
.numgroups
, i
+ 2) != -1)
307 config
.groups
[i
++] = newstr(q
);
310 while (i
< config
.numgroups
)
311 config
.groups
[i
++] = NULL
;
313 case _UC_DEFAULTCLASS
:
314 config
.default_class
= (q
== NULL
|| !boolean_val(q
, 1))
318 if ((q
= unquote(q
)) != NULL
&& isdigit(*q
))
319 config
.min_uid
= (uid_t
) atol(q
);
322 if ((q
= unquote(q
)) != NULL
&& isdigit(*q
))
323 config
.max_uid
= (uid_t
) atol(q
);
326 if ((q
= unquote(q
)) != NULL
&& isdigit(*q
))
327 config
.min_gid
= (gid_t
) atol(q
);
330 if ((q
= unquote(q
)) != NULL
&& isdigit(*q
))
331 config
.max_gid
= (gid_t
) atol(q
);
334 if ((q
= unquote(q
)) != NULL
&& isdigit(*q
))
335 config
.expire_days
= atoi(q
);
338 if ((q
= unquote(q
)) != NULL
&& isdigit(*q
))
339 config
.password_days
= atoi(q
);
355 write_userconfig(char const * file
)
360 file
= _PATH_PW_CONF
;
362 if ((fd
= open(file
, O_CREAT
| O_RDWR
| O_TRUNC
| O_EXLOCK
, 0644)) != -1) {
365 if ((fp
= fdopen(fd
, "w")) == NULL
)
370 char *buf
= malloc(len
);
372 for (i
= _UC_NONE
; i
< _UC_FIELDS
; i
++) {
374 char const *val
= buf
;
379 val
= boolean_str(config
.default_password
);
382 val
= boolean_str(config
.reuse_uids
);
385 val
= boolean_str(config
.reuse_gids
);
388 val
= config
.dotdir
? config
.dotdir
: boolean_str(0);
391 val
= config
.newmail
? config
.newmail
: boolean_str(0);
394 val
= config
.logfile
? config
.logfile
: boolean_str(0);
400 val
= config
.shelldir
;
403 for (j
= k
= 0; j
< _UC_MAXSHELLS
&& system_shells
[j
] != NULL
; j
++) {
405 int l
= snprintf(lbuf
, sizeof lbuf
, "%s\"%s\"", k
? "," : "", system_shells
[j
]);
406 if (l
+ k
+ 1 < len
|| extendline(&buf
, &len
, len
+ LNBUFSZ
) != -1) {
407 strcpy(buf
+ k
, lbuf
);
413 case _UC_DEFAULTSHELL
:
414 val
= config
.shell_default
? config
.shell_default
: bourne_shell
;
416 case _UC_DEFAULTGROUP
:
417 val
= config
.default_group
? config
.default_group
: "";
419 case _UC_EXTRAGROUPS
:
420 extendarray(&config
.groups
, &config
.numgroups
, 200);
421 for (j
= k
= 0; j
< config
.numgroups
&& config
.groups
[j
] != NULL
; j
++) {
423 int l
= snprintf(lbuf
, sizeof lbuf
, "%s\"%s\"", k
? "," : "", config
.groups
[j
]);
424 if (l
+ k
+ 1 < len
|| extendline(&buf
, &len
, len
+ 1024) != -1) {
425 strcpy(buf
+ k
, lbuf
);
431 case _UC_DEFAULTCLASS
:
432 val
= config
.default_class
? config
.default_class
: "";
435 sprintf(buf
, "%lu", (unsigned long) config
.min_uid
);
439 sprintf(buf
, "%lu", (unsigned long) config
.max_uid
);
443 sprintf(buf
, "%lu", (unsigned long) config
.min_gid
);
447 sprintf(buf
, "%lu", (unsigned long) config
.max_gid
);
451 sprintf(buf
, "%d", config
.expire_days
);
455 sprintf(buf
, "%d", config
.password_days
);
463 fputs(comments
[i
], fp
);
467 fprintf(fp
, "%s = \"%s\"\n", kwds
[i
], val
);
469 fprintf(fp
, "%s = %s\n", kwds
[i
], val
);
471 printf("WROTE: %s = %s\n", kwds
[i
], val
);
476 return fclose(fp
) != EOF
;