fix mci_state after sending RSET command
[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
f50531a3 9static char sccsid[] = "@(#)pw_util.c 5.4 (Berkeley) %G%";
4cea479e
KB
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;
4cea479e 36
f50531a3 37 /* Unlimited resource limits. */
4cea479e
KB
38 rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY;
39 (void)setrlimit(RLIMIT_CPU, &rlim);
40 (void)setrlimit(RLIMIT_FSIZE, &rlim);
f50531a3
KB
41 (void)setrlimit(RLIMIT_STACK, &rlim);
42 (void)setrlimit(RLIMIT_DATA, &rlim);
43 (void)setrlimit(RLIMIT_RSS, &rlim);
4cea479e
KB
44
45 /* Don't drop core (not really necessary, but GP's). */
46 rlim.rlim_cur = rlim.rlim_max = 0;
47 (void)setrlimit(RLIMIT_CORE, &rlim);
48
f50531a3
KB
49 /* Turn off signals. */
50 (void)signal(SIGALRM, SIG_IGN);
1b7ac17b
KB
51 (void)signal(SIGHUP, SIG_IGN);
52 (void)signal(SIGINT, SIG_IGN);
f50531a3 53 (void)signal(SIGPIPE, SIG_IGN);
1b7ac17b
KB
54 (void)signal(SIGQUIT, SIG_IGN);
55 (void)signal(SIGTERM, SIG_IGN);
56 (void)signal(SIGTSTP, SIG_IGN);
f50531a3 57 (void)signal(SIGTTOU, SIG_IGN);
4cea479e
KB
58
59 /* Create with exact permissions. */
60 (void)umask(0);
61}
62
63static int lockfd;
64pw_lock()
65{
66 /*
67 * If the master password file doesn't exist, the system is hosed.
68 * Might as well try to build one.
69 * Open should allow flock'ing the file; see 4.4BSD. XXX
70 */
71 lockfd = open(_PATH_MASTERPASSWD, O_RDONLY, 0);
72 if (lockfd < 0) {
73 (void)fprintf(stderr, "%s: %s: %s\n",
74 progname, _PATH_MASTERPASSWD, strerror(errno));
75 exit(1);
76 }
36c2926d 77 if (flock(lockfd, LOCK_EX|LOCK_NB)) {
4cea479e
KB
78 (void)fprintf(stderr,
79 "%s: the password db is busy.\n", progname);
80 exit(1);
81 }
82 return(lockfd);
83}
84
85pw_tmp()
86{
87 static char path[MAXPATHLEN] = _PATH_MASTERPASSWD;
88 int fd;
89 char *p;
90
91 if (p = rindex(path, '/'))
92 ++p;
93 else
94 p = path;
95 (void)sprintf(p, "%s.XXXXXX", progname);
96 if ((fd = mkstemp(path)) == -1) {
97 (void)fprintf(stderr,
98 "%s: %s: %s\n", progname, path, strerror(errno));
99 exit(1);
100 }
101 tempname = path;
102 return(fd);
103}
104
105pw_mkdb()
106{
107 union wait pstat;
108 pid_t pid;
109
110 (void)printf("%s: rebuilding the database...\n", progname);
111 (void)fflush(stdout);
112 if (!(pid = vfork())) {
113 execl(_PATH_PWD_MKDB, "pwd_mkdb", "-p", tempname, NULL);
114 pw_error(_PATH_PWD_MKDB, 1, 1);
115 }
116 pid = waitpid(pid, (int *)&pstat, 0);
117 if (pid == -1 || pstat.w_status)
118 return(0);
119 (void)printf("%s: done\n", progname);
120 return(1);
121}
122
123pw_edit(notsetuid)
124 int notsetuid;
125{
126 union wait pstat;
127 pid_t pid;
128 char *p, *editor;
129
130 if (!(editor = getenv("EDITOR")))
131 editor = _PATH_VI;
132 if (p = rindex(editor, '/'))
133 ++p;
134 else
135 p = editor;
136
137 if (!(pid = vfork())) {
138 if (notsetuid) {
139 (void)setgid(getgid());
140 (void)setuid(getuid());
141 }
142 execlp(editor, p, tempname, NULL);
36c2926d 143 _exit(1);
4cea479e
KB
144 }
145 pid = waitpid(pid, (int *)&pstat, 0);
36c2926d
KB
146 if (pid == -1 || pstat.w_status)
147 pw_error(editor, 1, 1);
4cea479e
KB
148}
149
150pw_prompt()
151{
152 register int c;
153
154 for (;;) {
155 (void)printf("re-edit the password file? [y]: ");
156 (void)fflush(stdout);
157 c = getchar();
158 if (c != EOF && c != (int)'\n')
159 while (getchar() != (int)'\n');
160 if (c == (int)'n')
161 pw_error((char *)NULL, 0, 0);
162 break;
163 }
164}
165
166pw_error(name, err, eval)
167 char *name;
168 int err, eval;
169{
170 int sverrno;
171
172 if (err) {
173 sverrno = errno;
174 (void)fprintf(stderr, "%s: ", progname);
175 if (name)
176 (void)fprintf(stderr, "%s: ", name);
177 (void)fprintf(stderr, "%s\n", strerror(sverrno));
178 }
179 (void)fprintf(stderr,
180 "%s: %s unchanged\n", progname, _PATH_MASTERPASSWD);
181 (void)unlink(tempname);
182 exit(eval);
183}