1*df57947fSPedro F. Giffuni /*- 2*df57947fSPedro F. Giffuni * SPDX-License-Identifier: BSD-4-Clause 3*df57947fSPedro F. Giffuni * 49b50d902SRodney W. Grimes * Copyright (c) 1988, 1993, 1994 59b50d902SRodney W. Grimes * The Regents of the University of California. All rights reserved. 6f1d05925SDag-Erling Smørgrav * Copyright (c) 2002 Networks Associates Technology, Inc. 7f1d05925SDag-Erling Smørgrav * All rights reserved. 8f1d05925SDag-Erling Smørgrav * 9f1d05925SDag-Erling Smørgrav * Portions of this software were developed for the FreeBSD Project by 10f1d05925SDag-Erling Smørgrav * ThinkSec AS and NAI Labs, the Security Research Division of Network 11f1d05925SDag-Erling Smørgrav * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 12f1d05925SDag-Erling Smørgrav * ("CBOSS"), as part of the DARPA CHATS research program. 139b50d902SRodney W. Grimes * 149b50d902SRodney W. Grimes * Redistribution and use in source and binary forms, with or without 159b50d902SRodney W. Grimes * modification, are permitted provided that the following conditions 169b50d902SRodney W. Grimes * are met: 179b50d902SRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 189b50d902SRodney W. Grimes * notice, this list of conditions and the following disclaimer. 199b50d902SRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 209b50d902SRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 219b50d902SRodney W. Grimes * documentation and/or other materials provided with the distribution. 229b50d902SRodney W. Grimes * 3. All advertising materials mentioning features or use of this software 239b50d902SRodney W. Grimes * must display the following acknowledgement: 249b50d902SRodney W. Grimes * This product includes software developed by the University of 259b50d902SRodney W. Grimes * California, Berkeley and its contributors. 269b50d902SRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 279b50d902SRodney W. Grimes * may be used to endorse or promote products derived from this software 289b50d902SRodney W. Grimes * without specific prior written permission. 299b50d902SRodney W. Grimes * 309b50d902SRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 319b50d902SRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 329b50d902SRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 339b50d902SRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 349b50d902SRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 359b50d902SRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 369b50d902SRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 379b50d902SRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 389b50d902SRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 399b50d902SRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 409b50d902SRodney W. Grimes * SUCH DAMAGE. 419b50d902SRodney W. Grimes */ 429b50d902SRodney W. Grimes 43afa6d859SDavid Malone #if 0 449b50d902SRodney W. Grimes #ifndef lint 45afa6d859SDavid Malone static char sccsid[] = "@(#)field.c 8.4 (Berkeley) 4/2/94"; 469b50d902SRodney W. Grimes #endif /* not lint */ 47afa6d859SDavid Malone #endif 489b50d902SRodney W. Grimes 495ea73378SMark Murray #include <sys/cdefs.h> 505ea73378SMark Murray __FBSDID("$FreeBSD$"); 515ea73378SMark Murray 529b50d902SRodney W. Grimes #include <sys/param.h> 53d33c4953SMike Pritchard #include <sys/stat.h> 549b50d902SRodney W. Grimes 559b50d902SRodney W. Grimes #include <ctype.h> 569b50d902SRodney W. Grimes #include <err.h> 579b50d902SRodney W. Grimes #include <errno.h> 589b50d902SRodney W. Grimes #include <grp.h> 59f1d05925SDag-Erling Smørgrav #include <paths.h> 609b50d902SRodney W. Grimes #include <pwd.h> 619b50d902SRodney W. Grimes #include <stdlib.h> 629b50d902SRodney W. Grimes #include <string.h> 639b50d902SRodney W. Grimes 649b50d902SRodney W. Grimes #include "chpass.h" 659b50d902SRodney W. Grimes 669b50d902SRodney W. Grimes /* ARGSUSED */ 679b50d902SRodney W. Grimes int 685ea73378SMark Murray p_login(char *p, struct passwd *pw, ENTRY *ep __unused) 699b50d902SRodney W. Grimes { 709b50d902SRodney W. Grimes if (!*p) { 719b50d902SRodney W. Grimes warnx("empty login field"); 72f1d05925SDag-Erling Smørgrav return (-1); 739b50d902SRodney W. Grimes } 749b50d902SRodney W. Grimes if (*p == '-') { 759b50d902SRodney W. Grimes warnx("login names may not begin with a hyphen"); 76f1d05925SDag-Erling Smørgrav return (-1); 779b50d902SRodney W. Grimes } 789b50d902SRodney W. Grimes if (!(pw->pw_name = strdup(p))) { 799b50d902SRodney W. Grimes warnx("can't save entry"); 80f1d05925SDag-Erling Smørgrav return (-1); 819b50d902SRodney W. Grimes } 829b50d902SRodney W. Grimes if (strchr(p, '.')) 839b50d902SRodney W. Grimes warnx("\'.\' is dangerous in a login name"); 849b50d902SRodney W. Grimes for (; *p; ++p) 859b50d902SRodney W. Grimes if (isupper(*p)) { 869b50d902SRodney W. Grimes warnx("upper-case letters are dangerous in a login name"); 879b50d902SRodney W. Grimes break; 889b50d902SRodney W. Grimes } 899b50d902SRodney W. Grimes return (0); 909b50d902SRodney W. Grimes } 919b50d902SRodney W. Grimes 929b50d902SRodney W. Grimes /* ARGSUSED */ 939b50d902SRodney W. Grimes int 945ea73378SMark Murray p_passwd(char *p, struct passwd *pw, ENTRY *ep __unused) 959b50d902SRodney W. Grimes { 96afa6d859SDavid Malone if (!(pw->pw_passwd = strdup(p))) { 979b50d902SRodney W. Grimes warnx("can't save password entry"); 98f1d05925SDag-Erling Smørgrav return (-1); 999b50d902SRodney W. Grimes } 1009b50d902SRodney W. Grimes 1019b50d902SRodney W. Grimes return (0); 1029b50d902SRodney W. Grimes } 1039b50d902SRodney W. Grimes 1049b50d902SRodney W. Grimes /* ARGSUSED */ 1059b50d902SRodney W. Grimes int 1065ea73378SMark Murray p_uid(char *p, struct passwd *pw, ENTRY *ep __unused) 1079b50d902SRodney W. Grimes { 1089b50d902SRodney W. Grimes uid_t id; 1099b50d902SRodney W. Grimes char *np; 1109b50d902SRodney W. Grimes 1119b50d902SRodney W. Grimes if (!*p) { 1129b50d902SRodney W. Grimes warnx("empty uid field"); 113f1d05925SDag-Erling Smørgrav return (-1); 1149b50d902SRodney W. Grimes } 1159b50d902SRodney W. Grimes if (!isdigit(*p)) { 1169b50d902SRodney W. Grimes warnx("illegal uid"); 117f1d05925SDag-Erling Smørgrav return (-1); 1189b50d902SRodney W. Grimes } 1199b50d902SRodney W. Grimes errno = 0; 1209b50d902SRodney W. Grimes id = strtoul(p, &np, 10); 1218a50130bSAlexander Kabaev if (*np || (id == (uid_t)ULONG_MAX && errno == ERANGE)) { 1229b50d902SRodney W. Grimes warnx("illegal uid"); 123f1d05925SDag-Erling Smørgrav return (-1); 1249b50d902SRodney W. Grimes } 1259b50d902SRodney W. Grimes pw->pw_uid = id; 1269b50d902SRodney W. Grimes return (0); 1279b50d902SRodney W. Grimes } 1289b50d902SRodney W. Grimes 1299b50d902SRodney W. Grimes /* ARGSUSED */ 1309b50d902SRodney W. Grimes int 1315ea73378SMark Murray p_gid(char *p, struct passwd *pw, ENTRY *ep __unused) 1329b50d902SRodney W. Grimes { 1339b50d902SRodney W. Grimes struct group *gr; 1349b50d902SRodney W. Grimes gid_t id; 1359b50d902SRodney W. Grimes char *np; 1369b50d902SRodney W. Grimes 1379b50d902SRodney W. Grimes if (!*p) { 1389b50d902SRodney W. Grimes warnx("empty gid field"); 139f1d05925SDag-Erling Smørgrav return (-1); 1409b50d902SRodney W. Grimes } 1419b50d902SRodney W. Grimes if (!isdigit(*p)) { 1429b50d902SRodney W. Grimes if (!(gr = getgrnam(p))) { 1439b50d902SRodney W. Grimes warnx("unknown group %s", p); 144f1d05925SDag-Erling Smørgrav return (-1); 1459b50d902SRodney W. Grimes } 1469b50d902SRodney W. Grimes pw->pw_gid = gr->gr_gid; 1479b50d902SRodney W. Grimes return (0); 1489b50d902SRodney W. Grimes } 1499b50d902SRodney W. Grimes errno = 0; 1509b50d902SRodney W. Grimes id = strtoul(p, &np, 10); 1518a50130bSAlexander Kabaev if (*np || (id == (uid_t)ULONG_MAX && errno == ERANGE)) { 1529b50d902SRodney W. Grimes warnx("illegal gid"); 153f1d05925SDag-Erling Smørgrav return (-1); 1549b50d902SRodney W. Grimes } 1559b50d902SRodney W. Grimes pw->pw_gid = id; 1569b50d902SRodney W. Grimes return (0); 1579b50d902SRodney W. Grimes } 1589b50d902SRodney W. Grimes 1599b50d902SRodney W. Grimes /* ARGSUSED */ 1609b50d902SRodney W. Grimes int 1615ea73378SMark Murray p_class(char *p, struct passwd *pw, ENTRY *ep __unused) 1629b50d902SRodney W. Grimes { 163afa6d859SDavid Malone if (!(pw->pw_class = strdup(p))) { 1649b50d902SRodney W. Grimes warnx("can't save entry"); 165f1d05925SDag-Erling Smørgrav return (-1); 1669b50d902SRodney W. Grimes } 1679b50d902SRodney W. Grimes 1689b50d902SRodney W. Grimes return (0); 1699b50d902SRodney W. Grimes } 1709b50d902SRodney W. Grimes 1719b50d902SRodney W. Grimes /* ARGSUSED */ 1729b50d902SRodney W. Grimes int 1735ea73378SMark Murray p_change(char *p, struct passwd *pw, ENTRY *ep __unused) 1749b50d902SRodney W. Grimes { 1759b50d902SRodney W. Grimes if (!atot(p, &pw->pw_change)) 1769b50d902SRodney W. Grimes return (0); 1779b50d902SRodney W. Grimes warnx("illegal date for change field"); 178f1d05925SDag-Erling Smørgrav return (-1); 1799b50d902SRodney W. Grimes } 1809b50d902SRodney W. Grimes 1819b50d902SRodney W. Grimes /* ARGSUSED */ 1829b50d902SRodney W. Grimes int 1835ea73378SMark Murray p_expire(char *p, struct passwd *pw, ENTRY *ep __unused) 1849b50d902SRodney W. Grimes { 1859b50d902SRodney W. Grimes if (!atot(p, &pw->pw_expire)) 1869b50d902SRodney W. Grimes return (0); 1879b50d902SRodney W. Grimes warnx("illegal date for expire field"); 188f1d05925SDag-Erling Smørgrav return (-1); 1899b50d902SRodney W. Grimes } 1909b50d902SRodney W. Grimes 1919b50d902SRodney W. Grimes /* ARGSUSED */ 1929b50d902SRodney W. Grimes int 193f1d05925SDag-Erling Smørgrav p_gecos(char *p, struct passwd *pw __unused, ENTRY *ep) 1949b50d902SRodney W. Grimes { 195afa6d859SDavid Malone if (!(ep->save = strdup(p))) { 1969b50d902SRodney W. Grimes warnx("can't save entry"); 197f1d05925SDag-Erling Smørgrav return (-1); 1989b50d902SRodney W. Grimes } 1999b50d902SRodney W. Grimes return (0); 2009b50d902SRodney W. Grimes } 2019b50d902SRodney W. Grimes 2029b50d902SRodney W. Grimes /* ARGSUSED */ 2039b50d902SRodney W. Grimes int 2045ea73378SMark Murray p_hdir(char *p, struct passwd *pw, ENTRY *ep __unused) 2059b50d902SRodney W. Grimes { 2069b50d902SRodney W. Grimes if (!*p) { 2079b50d902SRodney W. Grimes warnx("empty home directory field"); 208f1d05925SDag-Erling Smørgrav return (-1); 2099b50d902SRodney W. Grimes } 2109b50d902SRodney W. Grimes if (!(pw->pw_dir = strdup(p))) { 2119b50d902SRodney W. Grimes warnx("can't save entry"); 212f1d05925SDag-Erling Smørgrav return (-1); 2139b50d902SRodney W. Grimes } 2149b50d902SRodney W. Grimes return (0); 2159b50d902SRodney W. Grimes } 2169b50d902SRodney W. Grimes 2179b50d902SRodney W. Grimes /* ARGSUSED */ 2189b50d902SRodney W. Grimes int 2195ea73378SMark Murray p_shell(char *p, struct passwd *pw, ENTRY *ep __unused) 2209b50d902SRodney W. Grimes { 221d33c4953SMike Pritchard struct stat sbuf; 2229b50d902SRodney W. Grimes 2239b50d902SRodney W. Grimes if (!*p) { 2245ea73378SMark Murray pw->pw_shell = strdup(_PATH_BSHELL); 2259b50d902SRodney W. Grimes return (0); 2269b50d902SRodney W. Grimes } 2279b50d902SRodney W. Grimes /* only admin can change from or to "restricted" shells */ 228f1d05925SDag-Erling Smørgrav if (!master_mode && pw->pw_shell && !ok_shell(pw->pw_shell)) { 2299b50d902SRodney W. Grimes warnx("%s: current shell non-standard", pw->pw_shell); 230f1d05925SDag-Erling Smørgrav return (-1); 2319b50d902SRodney W. Grimes } 232612956f6SPhilippe Charnier if (!ok_shell(p)) { 233f1d05925SDag-Erling Smørgrav if (!master_mode) { 2349b50d902SRodney W. Grimes warnx("%s: non-standard shell", p); 235f1d05925SDag-Erling Smørgrav return (-1); 2369b50d902SRodney W. Grimes } 237612956f6SPhilippe Charnier pw->pw_shell = strdup(p); 2389b50d902SRodney W. Grimes } 2399b50d902SRodney W. Grimes else 240612956f6SPhilippe Charnier pw->pw_shell = dup_shell(p); 241612956f6SPhilippe Charnier if (!pw->pw_shell) { 2429b50d902SRodney W. Grimes warnx("can't save entry"); 243f1d05925SDag-Erling Smørgrav return (-1); 2449b50d902SRodney W. Grimes } 245d33c4953SMike Pritchard if (stat(pw->pw_shell, &sbuf) < 0) { 246d33c4953SMike Pritchard if (errno == ENOENT) 247d33c4953SMike Pritchard warnx("WARNING: shell '%s' does not exist", 248d33c4953SMike Pritchard pw->pw_shell); 249d33c4953SMike Pritchard else 250d33c4953SMike Pritchard warn("WARNING: can't stat shell '%s'", pw->pw_shell); 251d33c4953SMike Pritchard return (0); 252d33c4953SMike Pritchard } 253d33c4953SMike Pritchard if (!S_ISREG(sbuf.st_mode)) { 254d33c4953SMike Pritchard warnx("WARNING: shell '%s' is not a regular file", 255d33c4953SMike Pritchard pw->pw_shell); 256d33c4953SMike Pritchard return (0); 257d33c4953SMike Pritchard } 258d33c4953SMike Pritchard if ((sbuf.st_mode & (S_IXOTH | S_IXGRP | S_IXUSR)) == 0) { 259d33c4953SMike Pritchard warnx("WARNING: shell '%s' is not executable", pw->pw_shell); 260d33c4953SMike Pritchard return (0); 261d33c4953SMike Pritchard } 2629b50d902SRodney W. Grimes return (0); 2639b50d902SRodney W. Grimes } 264