GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/chpass/field.c Lines: 0 91 0.0 %
Date: 2016-12-06 Branches: 0 62 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: field.c,v 1.14 2015/01/16 06:40:06 deraadt Exp $	*/
2
/*	$NetBSD: field.c,v 1.3 1995/03/26 04:55:28 glass Exp $	*/
3
4
/*
5
 * Copyright (c) 1988, 1993, 1994
6
 *	The Regents of the University of California.  All rights reserved.
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 * 1. Redistributions of source code must retain the above copyright
12
 *    notice, this list of conditions and the following disclaimer.
13
 * 2. Redistributions in binary form must reproduce the above copyright
14
 *    notice, this list of conditions and the following disclaimer in the
15
 *    documentation and/or other materials provided with the distribution.
16
 * 3. Neither the name of the University nor the names of its contributors
17
 *    may be used to endorse or promote products derived from this software
18
 *    without specific prior written permission.
19
 *
20
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30
 * SUCH DAMAGE.
31
 */
32
33
#include <ctype.h>
34
#include <err.h>
35
#include <errno.h>
36
#include <grp.h>
37
#include <paths.h>
38
#include <pwd.h>
39
#include <stdio.h>
40
#include <stdlib.h>
41
#include <string.h>
42
#include <unistd.h>
43
#include <limits.h>
44
45
#include "chpass.h"
46
47
/* ARGSUSED */
48
int
49
p_login(char *p, struct passwd *pw, ENTRY *ep)
50
{
51
	if (!*p) {
52
		warnx("empty login field");
53
		return (1);
54
	}
55
	if (*p == '-') {
56
		warnx("login names may not begin with a hyphen");
57
		return (1);
58
	}
59
	/* XXX - what about truncated names? */
60
	if (strcmp(pw->pw_name, p) != 0 && getpwnam(p) != NULL) {
61
		warnx("login %s already exists", p);
62
		return (1);
63
	}
64
	if (!(pw->pw_name = strdup(p))) {
65
		warnx("can't save entry");
66
		return (1);
67
	}
68
	if (strchr(p, '.'))
69
		warnx("\'.\' is dangerous in a login name");
70
	for (; *p; ++p)
71
		if (isupper((unsigned char)*p)) {
72
			warnx("upper-case letters are dangerous in a login name");
73
			break;
74
		}
75
	return (0);
76
}
77
78
/* ARGSUSED */
79
int
80
p_passwd(char *p, struct passwd *pw, ENTRY *ep)
81
{
82
	if (!*p)
83
		pw->pw_passwd = "";	/* "NOLOGIN"; */
84
	else if (!(pw->pw_passwd = strdup(p))) {
85
		warnx("can't save password entry");
86
		return (1);
87
	}
88
89
	return (0);
90
}
91
92
/* ARGSUSED */
93
int
94
p_uid(char *p, struct passwd *pw, ENTRY *ep)
95
{
96
	uid_t id;
97
	const char *errstr;
98
99
	if (!*p) {
100
		warnx("empty uid field");
101
		return (1);
102
	}
103
	id = (uid_t)strtonum(p, 0, UID_MAX, &errstr);
104
	if (errstr) {
105
		warnx("uid is %s", errstr);
106
		return (1);
107
	}
108
	pw->pw_uid = id;
109
	return (0);
110
}
111
112
/* ARGSUSED */
113
int
114
p_gid(char *p, struct passwd *pw, ENTRY *ep)
115
{
116
	struct group *gr;
117
	const char *errstr;
118
	gid_t id;
119
120
	if (!*p) {
121
		warnx("empty gid field");
122
		return (1);
123
	}
124
	if (!isdigit((unsigned char)*p)) {
125
		if (!(gr = getgrnam(p))) {
126
			warnx("unknown group %s", p);
127
			return (1);
128
		}
129
		pw->pw_gid = gr->gr_gid;
130
		return (0);
131
	}
132
	id = (uid_t)strtonum(p, 0, GID_MAX, &errstr);
133
	if (errstr) {
134
		warnx("gid is %s", errstr);
135
		return (1);
136
	}
137
	pw->pw_gid = id;
138
	return (0);
139
}
140
141
/* ARGSUSED */
142
int
143
p_class(char *p, struct passwd *pw, ENTRY *ep)
144
{
145
	if (!*p)
146
		pw->pw_class = "";
147
	else if (!(pw->pw_class = strdup(p))) {
148
		warnx("can't save entry");
149
		return (1);
150
	}
151
152
	return (0);
153
}
154
155
/* ARGSUSED */
156
int
157
p_change(char *p, struct passwd *pw, ENTRY *ep)
158
{
159
	if (!atot(p, &pw->pw_change))
160
		return (0);
161
	warnx("illegal date for change field");
162
	return (1);
163
}
164
165
/* ARGSUSED */
166
int
167
p_expire(char *p, struct passwd *pw, ENTRY *ep)
168
{
169
	if (!atot(p, &pw->pw_expire))
170
		return (0);
171
	warnx("illegal date for expire field");
172
	return (1);
173
}
174
175
/* ARGSUSED */
176
int
177
p_gecos(char *p, struct passwd *pw, ENTRY *ep)
178
{
179
	if (!*p)
180
		ep->save = "";
181
	else if (!(ep->save = strdup(p))) {
182
		warnx("can't save entry");
183
		return (1);
184
	}
185
	return (0);
186
}
187
188
/* ARGSUSED */
189
int
190
p_hdir(char *p, struct passwd *pw, ENTRY *ep)
191
{
192
	if (!*p) {
193
		warnx("empty home directory field");
194
		return (1);
195
	}
196
	if (!(pw->pw_dir = strdup(p))) {
197
		warnx("can't save entry");
198
		return (1);
199
	}
200
	return (0);
201
}
202
203
/* ARGSUSED */
204
int
205
p_shell(char *p, struct passwd *pw, ENTRY *ep)
206
{
207
	char *t;
208
209
	if (!*p) {
210
		pw->pw_shell = _PATH_BSHELL;
211
		return (0);
212
	}
213
	/* only admin can change from or to "restricted" shells */
214
	if (uid && pw->pw_shell && !ok_shell(pw->pw_shell, NULL)) {
215
		warnx("%s: current shell non-standard", pw->pw_shell);
216
		return (1);
217
	}
218
	if (!ok_shell(p, &t)) {
219
		if (uid) {
220
			warnx("%s: non-standard shell", p);
221
			return (1);
222
		} else
223
			t = strdup(p);
224
	}
225
	if (!(pw->pw_shell = t)) {
226
		warnx("can't save entry");
227
		return (1);
228
	}
229
	return (0);
230
}