fix error message when user doesn't know the old passwd
[unix-history] / usr / src / usr.sbin / vipw / pw_util.c
CommitLineData
4cea479e
KB
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 */
7
8#ifndef lint
9static char sccsid[] = "@(#)pw_util.c 5.1 (Berkeley) %G%";
10#endif /* not lint */
11
12/*
13 * This file is used by all the "password" programs; vipw(8), chpass(1),
14 * and passwd(1).
15 */
16
17#include <sys/param.h>
18#include <sys/wait.h>
19#include <sys/time.h>
20#include <sys/resource.h>
21#include <signal.h>
22#include <fcntl.h>
23#include <pwd.h>
24#include <errno.h>
25#include <stdio.h>
26#include <paths.h>
27#include <string.h>
28#include <stdlib.h>
29
30extern char *progname;
31extern char *tempname;
32
33pw_init()
34{
35 struct rlimit rlim;
36 sigset_t set;
37
38 /* Unlimited cpu, file size. */
39 rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY;
40 (void)setrlimit(RLIMIT_CPU, &rlim);
41 (void)setrlimit(RLIMIT_FSIZE, &rlim);
42
43 /* Don't drop core (not really necessary, but GP's). */
44 rlim.rlim_cur = rlim.rlim_max = 0;
45 (void)setrlimit(RLIMIT_CORE, &rlim);
46
47 /* Turn off usual signals. */
48 sigemptyset(&set);
49 (void)sigaddset(&set, SIGTSTP);
50 (void)sigaddset(&set, SIGHUP);
51 (void)sigaddset(&set, SIGINT);
52 (void)sigaddset(&set, SIGQUIT);
53 (void)sigaddset(&set, SIGTERM);
54 (void)sigprocmask(SIG_BLOCK, &set, (sigset_t *)NULL);
55
56 /* Create with exact permissions. */
57 (void)umask(0);
58}
59
60static int lockfd;
61pw_lock()
62{
63 /*
64 * If the master password file doesn't exist, the system is hosed.
65 * Might as well try to build one.
66 * Open should allow flock'ing the file; see 4.4BSD. XXX
67 */
68 lockfd = open(_PATH_MASTERPASSWD, O_RDONLY, 0);
69 if (lockfd < 0) {
70 (void)fprintf(stderr, "%s: %s: %s\n",
71 progname, _PATH_MASTERPASSWD, strerror(errno));
72 exit(1);
73 }
74 if (flock(lockfd, LOCK_EX)) {
75 (void)fprintf(stderr,
76 "%s: the password db is busy.\n", progname);
77 exit(1);
78 }
79 return(lockfd);
80}
81
82pw_tmp()
83{
84 static char path[MAXPATHLEN] = _PATH_MASTERPASSWD;
85 int fd;
86 char *p;
87
88 if (p = rindex(path, '/'))
89 ++p;
90 else
91 p = path;
92 (void)sprintf(p, "%s.XXXXXX", progname);
93 if ((fd = mkstemp(path)) == -1) {
94 (void)fprintf(stderr,
95 "%s: %s: %s\n", progname, path, strerror(errno));
96 exit(1);
97 }
98 tempname = path;
99 return(fd);
100}
101
102pw_mkdb()
103{
104 union wait pstat;
105 pid_t pid;
106
107 (void)printf("%s: rebuilding the database...\n", progname);
108 (void)fflush(stdout);
109 if (!(pid = vfork())) {
110 execl(_PATH_PWD_MKDB, "pwd_mkdb", "-p", tempname, NULL);
111 pw_error(_PATH_PWD_MKDB, 1, 1);
112 }
113 pid = waitpid(pid, (int *)&pstat, 0);
114 if (pid == -1 || pstat.w_status)
115 return(0);
116 (void)printf("%s: done\n", progname);
117 return(1);
118}
119
120pw_edit(notsetuid)
121 int notsetuid;
122{
123 union wait pstat;
124 pid_t pid;
125 char *p, *editor;
126
127 if (!(editor = getenv("EDITOR")))
128 editor = _PATH_VI;
129 if (p = rindex(editor, '/'))
130 ++p;
131 else
132 p = editor;
133
134 if (!(pid = vfork())) {
135 if (notsetuid) {
136 (void)setgid(getgid());
137 (void)setuid(getuid());
138 }
139 execlp(editor, p, tempname, NULL);
140 pw_error(editor, 1, 1);
141 }
142 pid = waitpid(pid, (int *)&pstat, 0);
143 return (pid == -1 ? 1 : pstat.w_status);
144}
145
146pw_prompt()
147{
148 register int c;
149
150 for (;;) {
151 (void)printf("re-edit the password file? [y]: ");
152 (void)fflush(stdout);
153 c = getchar();
154 if (c != EOF && c != (int)'\n')
155 while (getchar() != (int)'\n');
156 if (c == (int)'n')
157 pw_error((char *)NULL, 0, 0);
158 break;
159 }
160}
161
162pw_error(name, err, eval)
163 char *name;
164 int err, eval;
165{
166 int sverrno;
167
168 if (err) {
169 sverrno = errno;
170 (void)fprintf(stderr, "%s: ", progname);
171 if (name)
172 (void)fprintf(stderr, "%s: ", name);
173 (void)fprintf(stderr, "%s\n", strerror(sverrno));
174 }
175 (void)fprintf(stderr,
176 "%s: %s unchanged\n", progname, _PATH_MASTERPASSWD);
177 (void)unlink(tempname);
178 exit(eval);
179}