]> git.saurik.com Git - apple/system_cmds.git/blame - chpass.tproj/ds_pw_util.c
system_cmds-300.tar.gz
[apple/system_cmds.git] / chpass.tproj / ds_pw_util.c
CommitLineData
c3a08f59
A
1/*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
83f6dbe8
A
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
7 *
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
13 * file.
c3a08f59
A
14 *
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,
83f6dbe8
A
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.
c3a08f59
A
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25/*-
26 * Copyright (c) 1990, 1993, 1994
27 * The Regents of the University of California. All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
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 the University of
40 * California, Berkeley and its contributors.
41 * 4. Neither the name of the University nor the names of its contributors
42 * may be used to endorse or promote products derived from this software
43 * without specific prior written permission.
44 *
45 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
46 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
49 * FOR ANY 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
55 * SUCH DAMAGE.
56 */
57
58#ifndef lint
59static char sccsid[] = "@(#)pw_util.c 8.4 (Berkeley) 4/28/95";
60#endif /* not lint */
61
62/*
63 * This file is used by all the "password" programs; vipw(8), chpass(1),
64 * and passwd(1).
65 */
66
67#include <sys/param.h>
68#include <sys/time.h>
69#include <sys/resource.h>
70#include <sys/stat.h>
71#include <sys/wait.h>
72
73#include <err.h>
74#include <errno.h>
75#include <fcntl.h>
76#include <paths.h>
77#include <pwd.h>
78#include <signal.h>
79#include <stdio.h>
80#include <stdlib.h>
81#include <string.h>
82#include <unistd.h>
83
84#include "pw_util.h"
85#ifdef DIRECTORY_SERVICE
86#include "directory_service.h"
87#endif /* DIRECTORY_SERVICE */
88
89extern char *tempname;
90static pid_t editpid = -1;
91static int lockfd;
92
93void
94pw_cont(sig)
95 int sig;
96{
97
98 if (editpid != -1)
99 kill(editpid, sig);
100}
101
102void
103pw_init()
104{
105 struct rlimit rlim;
106
107 /* Unlimited resource limits. */
108 rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY;
109 (void)setrlimit(RLIMIT_CPU, &rlim);
110 (void)setrlimit(RLIMIT_FSIZE, &rlim);
111 (void)setrlimit(RLIMIT_STACK, &rlim);
112 (void)setrlimit(RLIMIT_DATA, &rlim);
113 (void)setrlimit(RLIMIT_RSS, &rlim);
114
115 /* Don't drop core (not really necessary, but GP's). */
116 rlim.rlim_cur = rlim.rlim_max = 0;
117 (void)setrlimit(RLIMIT_CORE, &rlim);
118
119 /* Turn off signals. */
120 (void)signal(SIGALRM, SIG_IGN);
121 (void)signal(SIGHUP, SIG_IGN);
122 (void)signal(SIGINT, SIG_IGN);
123 (void)signal(SIGPIPE, SIG_IGN);
124 (void)signal(SIGQUIT, SIG_IGN);
125 (void)signal(SIGTERM, SIG_IGN);
126 (void)signal(SIGCONT, pw_cont);
127
128 /* Create with exact permissions. */
129 (void)umask(0);
130}
131
132int
133pw_lock()
134{
135 /*
136 * If the master password file doesn't exist, the system is hosed.
137 * Might as well try to build one. Set the close-on-exec bit so
138 * that users can't get at the encrypted passwords while editing.
139 * Open should allow flock'ing the file; see 4.4BSD. XXX
140 */
141 lockfd = open(_PATH_MASTERPASSWD, O_RDONLY, 0);
142 if (lockfd < 0 || fcntl(lockfd, F_SETFD, 1) == -1)
143 err(1, "%s", _PATH_MASTERPASSWD);
144 if (flock(lockfd, LOCK_EX|LOCK_NB))
145 errx(1, "the password db file is busy");
146 return (lockfd);
147}
148
149int
150pw_tmp()
151{
152 static char path[MAXPATHLEN] = _PATH_MASTERPASSWD;
153 int fd;
154 char *p;
155
156 if (p = strrchr(path, '/'))
157 ++p;
158 else
159 p = path;
160 strcpy(p, "pw.XXXXXX");
161 if ((fd = mkstemp(path)) == -1)
162 err(1, "%s", path);
163 tempname = path;
164 return (fd);
165}
166
167int
168pw_mkdb()
169{
170 int pstat;
171 pid_t pid;
172
173 warnx("rebuilding the database...");
174 (void)fflush(stderr);
175 if (!(pid = vfork())) {
176 execl(_PATH_PWD_MKDB, "pwd_mkdb", "-p", tempname, NULL);
177 pw_error(_PATH_PWD_MKDB, 1, 1);
178 }
179 pid = waitpid(pid, &pstat, 0);
180 if (pid == -1 || !WIFEXITED(pstat) || WEXITSTATUS(pstat) != 0)
181 return (1);
182 warnx("done");
183 return (0);
184}
185
186void
187pw_edit(notsetuid)
188 int notsetuid;
189{
190 int pstat;
191 char *p, *editor;
192
193 if (!(editor = getenv("EDITOR")))
194 editor = _PATH_VI;
195 if (p = strrchr(editor, '/'))
196 ++p;
197 else
198 p = editor;
199
200 if (!(editpid = vfork())) {
201 if (notsetuid) {
202 (void)setgid(getgid());
203 (void)setuid(getuid());
204 }
205 execlp(editor, p, tempname, NULL);
206 _exit(1);
207 }
208 for (;;) {
209 editpid = waitpid(editpid, (int *)&pstat, WUNTRACED);
210 if (editpid == -1)
211 pw_error(editor, 1, 1);
212 else if (WIFSTOPPED(pstat))
213 raise(WSTOPSIG(pstat));
214 else if (WIFEXITED(pstat) && WEXITSTATUS(pstat) == 0)
215 break;
216 else
217 pw_error(editor, 1, 1);
218 }
219 editpid = -1;
220}
221
222void
223pw_prompt()
224{
225 int c;
226
227 (void)printf("re-edit the password file? [y]: ");
228 (void)fflush(stdout);
229 c = getchar();
230 if (c != EOF && c != '\n')
231 while (getchar() != '\n');
232 if (c == 'n')
233 pw_error(NULL, 0, 0);
234}
235
236void
237pw_error(name, err, eval)
238 char *name;
239 int err, eval;
240{
241#ifdef DIRECTORY_SERVICE
242 extern int dswhere;
243#endif /* DIRECTORY_SERVICE */
244 if (err)
245 warn("%s", name);
246
247#ifdef DIRECTORY_SERVICE
248 switch(dswhere) {
249 case WHERE_LOCALNI:
250 warnx("netinfo domain \"%s\": unchanged", DSPath);
251 break;
252 case WHERE_FILES:
253#endif /* DIRECTORY_SERVICE */
254 warnx("%s: unchanged", _PATH_MASTERPASSWD);
255#ifdef DIRECTORY_SERVICE
256 }
257#endif /* DIRECTORY_SERVICE */
258 (void)unlink(tempname);
259 exit(eval);
260}