]>
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 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
25 /* $OpenBSD: yppasswdd_mkpw.c,v 1.16 1997/11/17 23:56:20 gene Exp $ */
28 * Copyright (c) 1994 Mats O Jansson <moj@stacken.kth.se>
29 * All rights reserved.
31 * Redistribution and use in source and binary forms, with or without
32 * modification, are permitted provided that the following conditions
34 * 1. Redistributions of source code must retain the above copyright
35 * notice, this list of conditions and the following disclaimer.
36 * 2. Redistributions in binary form must reproduce the above copyright
37 * notice, this list of conditions and the following disclaimer in the
38 * documentation and/or other materials provided with the distribution.
39 * 3. All advertising materials mentioning features or use of this software
40 * must display the following acknowledgement:
41 * This product includes software developed by Mats O Jansson
42 * 4. The name of the author may not be used to endorse or promote products
43 * derived from this software without specific prior written permission.
45 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
46 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
47 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
49 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59 static char rcsid
[] = "$OpenBSD: yppasswdd_mkpw.c,v 1.16 1997/11/17 23:56:20 gene Exp $";
62 #include <sys/param.h>
63 #include <sys/types.h>
68 #include <rpcsvc/yppasswd.h>
83 extern char make_arg
[];
85 static void _pw_copy(int, int, struct passwd
*);
87 /* This is imported from OpenBSD's libutil because it's argument
88 * incompatible with NetBSD's. However, the NetBSD libutil is
89 * at least what the prototypes suggest is in System.framework,
90 * even though I can't find the code. I assume it will be there
91 * eventually. We need to use NetBSD's because it works with the
92 * pwd_mkdb binary that's shipped with Rhapsody. This is an area
93 * where OpenBSD diverges; however, we wanted to keep the OpenBSD
94 * rpc.yppasswdd because the rest of our YP code is from OpenBSD.
98 _pw_copy(ffd
, tfd
, pw
)
106 if (!(from
= fdopen(ffd
, "r")))
107 pw_error(_PATH_MASTERPASSWD
, 1, 1);
108 if (!(to
= fdopen(tfd
, "w")))
109 pw_error(_PATH_MASTERPASSWD_LOCK
, 1, 1);
111 for (done
= 0; fgets(buf
, sizeof(buf
), from
);) {
112 if (!strchr(buf
, '\n')) {
113 warnx("%s: line too long", _PATH_MASTERPASSWD
);
114 pw_error(NULL
, 0, 1);
117 (void)fprintf(to
, "%s", buf
);
122 if (!(p
= strchr(buf
, ':'))) {
123 warnx("%s: corrupted entry", _PATH_MASTERPASSWD
);
124 pw_error(NULL
, 0, 1);
127 if (strcmp(buf
, pw
->pw_name
)) {
129 (void)fprintf(to
, "%s", buf
);
134 (void)fprintf(to
, "%s:%s:%d:%d:%s:%ld:%ld:%s:%s:%s\n",
135 pw
->pw_name
, pw
->pw_passwd
, pw
->pw_uid
, pw
->pw_gid
,
136 pw
->pw_class
, pw
->pw_change
, pw
->pw_expire
, pw
->pw_gecos
,
137 pw
->pw_dir
, pw
->pw_shell
);
143 (void)fprintf(to
, "%s:%s:%d:%d:%s:%ld:%ld:%s:%s:%s\n",
144 pw
->pw_name
, pw
->pw_passwd
, pw
->pw_uid
, pw
->pw_gid
,
145 pw
->pw_class
, pw
->pw_change
, pw
->pw_expire
, pw
->pw_gecos
,
146 pw
->pw_dir
, pw
->pw_shell
);
150 pw_error(NULL
, 0, 1);
162 for (s
= base
; *s
; s
++) {
167 if (strchr(":\n\t\r", *s
))
198 char buf
[10], *bp
= NULL
, *p
, *t
;
205 pfd
= open(_PATH_MASTERPASSWD
, O_RDONLY
);
210 p
= bp
= malloc((resid
= st
.st_size
) + 1);
212 cnt
= read(pfd
, p
, resid
);
220 *p
= '\0'; /* Buf oflow prevention */
223 subst(p
, '\n', '\0');
224 for (n
= 1; p
< bp
+ st
.st_size
; n
++, p
= t
) {
225 t
= strchr(p
, '\0') + 1;
226 /* Rhapsody allows the passwd file to have comments in it. */
230 cnt
= subst(p
, ':', '\0');
232 syslog(LOG_WARNING
, "bad entry at line %d of %s", n
,
237 if (strcmp(p
, argp
->newpw
.pw_name
) == 0)
240 if (p
>= bp
+ st
.st_size
)
243 #define EXPAND(e) e = p; while (*p++);
245 EXPAND(pw
.pw_passwd
);
246 pw
.pw_uid
= atoi(p
); EXPAND(t
);
247 pw
.pw_gid
= atoi(p
); EXPAND(t
);
249 pw
.pw_change
= (time_t)atol(p
); EXPAND(t
);
250 pw
.pw_expire
= (time_t)atol(p
); EXPAND(t
);
255 /* crypt() is broken under Rhapsody. It doesn't deal with
256 * empty keys or salts like other Unices.
258 if (pw
.pw_passwd
[0] != '\0' && argp
->oldpass
!= NULL
&& argp
->oldpass
[0] != '\0') {
259 if (strcmp(crypt(argp
->oldpass
, pw
.pw_passwd
), pw
.pw_passwd
) != 0)
263 if (!nopw
&& badchars(argp
->newpw
.pw_passwd
))
265 if (!nogecos
&& badchars(argp
->newpw
.pw_gecos
))
267 if (!nogecos
&& badchars(argp
->newpw
.pw_shell
))
271 * Get the new password. Reset passwd change time to zero; when
272 * classes are implemented, go and get the "offset" value for this
273 * class and reset the timer.
276 pw
.pw_passwd
= argp
->newpw
.pw_passwd
;
280 pw
.pw_gecos
= argp
->newpw
.pw_gecos
;
282 pw
.pw_shell
= argp
->newpw
.pw_shell
;
284 for (n
= 0, p
= pw
.pw_gecos
; *p
; p
++)
286 n
= n
+ strlen(pw
.pw_name
) - 1;
287 if (strlen(pw
.pw_name
) + 1 + strlen(pw
.pw_passwd
) + 1 +
288 strlen((sprintf(buf
, "%d", pw
.pw_uid
), buf
)) + 1 +
289 strlen((sprintf(buf
, "%d", pw
.pw_gid
), buf
)) + 1 +
290 strlen(pw
.pw_gecos
) + n
+ 1 + strlen(pw
.pw_dir
) + 1 +
291 strlen(pw
.pw_shell
) >= 1023)
294 pfd
= open(_PATH_MASTERPASSWD
, O_RDONLY
, 0);
296 syslog(LOG_ERR
, "cannot open %s", _PATH_MASTERPASSWD
);
304 _pw_copy(pfd
, tfd
, &pw
);