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