]>
git.saurik.com Git - apple/network_cmds.git/blob - rpc_yppasswdd.tproj/yppasswdd_mkpw.c
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.0 (the 'License'). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
22 * @APPLE_LICENSE_HEADER_END@
24 /* $OpenBSD: yppasswdd_mkpw.c,v 1.16 1997/11/17 23:56:20 gene Exp $ */
27 * Copyright (c) 1994 Mats O Jansson <moj@stacken.kth.se>
28 * All rights reserved.
30 * Redistribution and use in source and binary forms, with or without
31 * modification, are permitted provided that the following conditions
33 * 1. Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * 2. Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in the
37 * documentation and/or other materials provided with the distribution.
38 * 3. All advertising materials mentioning features or use of this software
39 * must display the following acknowledgement:
40 * This product includes software developed by Mats O Jansson
41 * 4. The name of the author may not be used to endorse or promote products
42 * derived from this software without specific prior written permission.
44 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
45 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
46 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
47 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
48 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
49 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
50 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
51 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
52 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
53 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 static char rcsid
[] = "$OpenBSD: yppasswdd_mkpw.c,v 1.16 1997/11/17 23:56:20 gene Exp $";
61 #include <sys/param.h>
62 #include <sys/types.h>
67 #include <rpcsvc/yppasswd.h>
82 extern char make_arg
[];
84 static void _pw_copy(int, int, struct passwd
*);
86 /* This is imported from OpenBSD's libutil because it's argument
87 * incompatible with NetBSD's. However, the NetBSD libutil is
88 * at least what the prototypes suggest is in System.framework,
89 * even though I can't find the code. I assume it will be there
90 * eventually. We need to use NetBSD's because it works with the
91 * pwd_mkdb binary that's shipped with Rhapsody. This is an area
92 * where OpenBSD diverges; however, we wanted to keep the OpenBSD
93 * rpc.yppasswdd because the rest of our YP code is from OpenBSD.
97 _pw_copy(ffd
, tfd
, pw
)
105 if (!(from
= fdopen(ffd
, "r")))
106 pw_error(_PATH_MASTERPASSWD
, 1, 1);
107 if (!(to
= fdopen(tfd
, "w")))
108 pw_error(_PATH_MASTERPASSWD_LOCK
, 1, 1);
110 for (done
= 0; fgets(buf
, sizeof(buf
), from
);) {
111 if (!strchr(buf
, '\n')) {
112 warnx("%s: line too long", _PATH_MASTERPASSWD
);
113 pw_error(NULL
, 0, 1);
116 (void)fprintf(to
, "%s", buf
);
121 if (!(p
= strchr(buf
, ':'))) {
122 warnx("%s: corrupted entry", _PATH_MASTERPASSWD
);
123 pw_error(NULL
, 0, 1);
126 if (strcmp(buf
, pw
->pw_name
)) {
128 (void)fprintf(to
, "%s", buf
);
133 (void)fprintf(to
, "%s:%s:%d:%d:%s:%ld:%ld:%s:%s:%s\n",
134 pw
->pw_name
, pw
->pw_passwd
, pw
->pw_uid
, pw
->pw_gid
,
135 pw
->pw_class
, pw
->pw_change
, pw
->pw_expire
, pw
->pw_gecos
,
136 pw
->pw_dir
, pw
->pw_shell
);
142 (void)fprintf(to
, "%s:%s:%d:%d:%s:%ld:%ld:%s:%s:%s\n",
143 pw
->pw_name
, pw
->pw_passwd
, pw
->pw_uid
, pw
->pw_gid
,
144 pw
->pw_class
, pw
->pw_change
, pw
->pw_expire
, pw
->pw_gecos
,
145 pw
->pw_dir
, pw
->pw_shell
);
149 pw_error(NULL
, 0, 1);
161 for (s
= base
; *s
; s
++) {
166 if (strchr(":\n\t\r", *s
))
197 char buf
[10], *bp
= NULL
, *p
, *t
;
204 pfd
= open(_PATH_MASTERPASSWD
, O_RDONLY
);
209 p
= bp
= malloc((resid
= st
.st_size
) + 1);
211 cnt
= read(pfd
, p
, resid
);
219 *p
= '\0'; /* Buf oflow prevention */
222 subst(p
, '\n', '\0');
223 for (n
= 1; p
< bp
+ st
.st_size
; n
++, p
= t
) {
224 t
= strchr(p
, '\0') + 1;
225 /* Rhapsody allows the passwd file to have comments in it. */
229 cnt
= subst(p
, ':', '\0');
231 syslog(LOG_WARNING
, "bad entry at line %d of %s", n
,
236 if (strcmp(p
, argp
->newpw
.pw_name
) == 0)
239 if (p
>= bp
+ st
.st_size
)
242 #define EXPAND(e) e = p; while (*p++);
244 EXPAND(pw
.pw_passwd
);
245 pw
.pw_uid
= atoi(p
); EXPAND(t
);
246 pw
.pw_gid
= atoi(p
); EXPAND(t
);
248 pw
.pw_change
= (time_t)atol(p
); EXPAND(t
);
249 pw
.pw_expire
= (time_t)atol(p
); EXPAND(t
);
254 /* crypt() is broken under Rhapsody. It doesn't deal with
255 * empty keys or salts like other Unices.
257 if (pw
.pw_passwd
[0] != '\0' && argp
->oldpass
!= NULL
&& argp
->oldpass
[0] != '\0') {
258 if (strcmp(crypt(argp
->oldpass
, pw
.pw_passwd
), pw
.pw_passwd
) != 0)
262 if (!nopw
&& badchars(argp
->newpw
.pw_passwd
))
264 if (!nogecos
&& badchars(argp
->newpw
.pw_gecos
))
266 if (!nogecos
&& badchars(argp
->newpw
.pw_shell
))
270 * Get the new password. Reset passwd change time to zero; when
271 * classes are implemented, go and get the "offset" value for this
272 * class and reset the timer.
275 pw
.pw_passwd
= argp
->newpw
.pw_passwd
;
279 pw
.pw_gecos
= argp
->newpw
.pw_gecos
;
281 pw
.pw_shell
= argp
->newpw
.pw_shell
;
283 for (n
= 0, p
= pw
.pw_gecos
; *p
; p
++)
285 n
= n
+ strlen(pw
.pw_name
) - 1;
286 if (strlen(pw
.pw_name
) + 1 + strlen(pw
.pw_passwd
) + 1 +
287 strlen((sprintf(buf
, "%d", pw
.pw_uid
), buf
)) + 1 +
288 strlen((sprintf(buf
, "%d", pw
.pw_gid
), buf
)) + 1 +
289 strlen(pw
.pw_gecos
) + n
+ 1 + strlen(pw
.pw_dir
) + 1 +
290 strlen(pw
.pw_shell
) >= 1023)
293 pfd
= open(_PATH_MASTERPASSWD
, O_RDONLY
, 0);
295 syslog(LOG_ERR
, "cannot open %s", _PATH_MASTERPASSWD
);
303 _pw_copy(pfd
, tfd
, &pw
);