pw_scan.c revision 54034
11553Srgrimes/*- 21553Srgrimes * Copyright (c) 1990, 1993, 1994 31553Srgrimes * The Regents of the University of California. All rights reserved. 41553Srgrimes * 51553Srgrimes * Redistribution and use in source and binary forms, with or without 61553Srgrimes * modification, are permitted provided that the following conditions 71553Srgrimes * are met: 81553Srgrimes * 1. Redistributions of source code must retain the above copyright 91553Srgrimes * notice, this list of conditions and the following disclaimer. 101553Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111553Srgrimes * notice, this list of conditions and the following disclaimer in the 121553Srgrimes * documentation and/or other materials provided with the distribution. 131553Srgrimes * 3. All advertising materials mentioning features or use of this software 141553Srgrimes * must display the following acknowledgement: 151553Srgrimes * This product includes software developed by the University of 161553Srgrimes * California, Berkeley and its contributors. 171553Srgrimes * 4. Neither the name of the University nor the names of its contributors 181553Srgrimes * may be used to endorse or promote products derived from this software 191553Srgrimes * without specific prior written permission. 201553Srgrimes * 211553Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221553Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231553Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241553Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251553Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261553Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271553Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281553Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291553Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301553Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311553Srgrimes * SUCH DAMAGE. 321553Srgrimes */ 331553Srgrimes 341553Srgrimes#ifndef lint 3530260Scharnier#if 0 361553Srgrimesstatic char sccsid[] = "@(#)pw_scan.c 8.3 (Berkeley) 4/2/94"; 3730260Scharnier#endif 3830260Scharnierstatic const char rcsid[] = 3950479Speter "$FreeBSD: head/lib/libc/gen/pw_scan.c 54034 1999-12-02 16:39:15Z sheldonh $"; 401553Srgrimes#endif /* not lint */ 411553Srgrimes 421553Srgrimes/* 431553Srgrimes * This module is used to "verify" password entries by chpass(1) and 441553Srgrimes * pwd_mkdb(8). 451553Srgrimes */ 461553Srgrimes 471553Srgrimes#include <sys/param.h> 481553Srgrimes 491553Srgrimes#include <err.h> 501553Srgrimes#include <fcntl.h> 511553Srgrimes#include <pwd.h> 521553Srgrimes#include <stdio.h> 531553Srgrimes#include <string.h> 541553Srgrimes#include <stdlib.h> 551553Srgrimes#include <unistd.h> 561553Srgrimes 571553Srgrimes#include "pw_scan.h" 581553Srgrimes 5953183Ssheldonh/* 6053183Ssheldonh * Some software assumes that IDs are short. We should emit warnings 6153183Ssheldonh * for id's which can not be stored in a short, but we are more liberal 6253183Ssheldonh * by default, warning for IDs greater than USHRT_MAX. 6354034Ssheldonh * 6454034Ssheldonh * If pw_big_ids_warning is anything other than -1 on entry to pw_scan() 6554034Ssheldonh * it will be set based on the existance of PW_SCAN_BIG_IDS in the 6654034Ssheldonh * environment. 6753183Ssheldonh */ 6854034Ssheldonhint pw_big_ids_warning = -1; 6953183Ssheldonh 701553Srgrimesint 711553Srgrimespw_scan(bp, pw) 721553Srgrimes char *bp; 731553Srgrimes struct passwd *pw; 741553Srgrimes{ 751553Srgrimes long id; 761553Srgrimes int root; 771553Srgrimes char *p, *sh; 781553Srgrimes 7954034Ssheldonh if (pw_big_ids_warning == -1) 8054034Ssheldonh pw_big_ids_warning = getenv("PW_SCAN_BIG_IDS") == NULL ? 1 : 0; 8154034Ssheldonh 822916Swollman pw->pw_fields = 0; 831553Srgrimes if (!(pw->pw_name = strsep(&bp, ":"))) /* login */ 841553Srgrimes goto fmt; 851553Srgrimes root = !strcmp(pw->pw_name, "root"); 862916Swollman if(pw->pw_name[0] && (pw->pw_name[0] != '+' || pw->pw_name[1] == '\0')) 872916Swollman pw->pw_fields |= _PWF_NAME; 881553Srgrimes 891553Srgrimes if (!(pw->pw_passwd = strsep(&bp, ":"))) /* passwd */ 901553Srgrimes goto fmt; 912916Swollman if(pw->pw_passwd[0]) pw->pw_fields |= _PWF_PASSWD; 921553Srgrimes 931553Srgrimes if (!(p = strsep(&bp, ":"))) /* uid */ 941553Srgrimes goto fmt; 9552921Seivind if (p[0]) 9652921Seivind pw->pw_fields |= _PWF_UID; 9752921Seivind else { 9853581Seivind if (pw->pw_name[0] != '+' && pw->pw_name[0] != '-') { 9953581Seivind warnx("no uid for user %s", pw->pw_name); 10053581Seivind return (0); 10153581Seivind } 10252921Seivind } 1031553Srgrimes id = atol(p); 1041553Srgrimes if (root && id) { 1051553Srgrimes warnx("root uid should be 0"); 1061553Srgrimes return (0); 1071553Srgrimes } 10853183Ssheldonh if (pw_big_ids_warning && id > USHRT_MAX) { 10953183Ssheldonh warnx("%s > max uid value (%u)", p, USHRT_MAX); 11050700Ssheldonh /*return (0);*/ /* THIS SHOULD NOT BE FATAL! */ 1111553Srgrimes } 1121553Srgrimes pw->pw_uid = id; 1131553Srgrimes 1141553Srgrimes if (!(p = strsep(&bp, ":"))) /* gid */ 1151553Srgrimes goto fmt; 1162916Swollman if(p[0]) pw->pw_fields |= _PWF_GID; 1171553Srgrimes id = atol(p); 11853183Ssheldonh if (pw_big_ids_warning && id > USHRT_MAX) { 11953183Ssheldonh warnx("%s > max gid value (%u)", p, USHRT_MAX); 12050700Ssheldonh /* return (0); This should not be fatal! */ 1211553Srgrimes } 1221553Srgrimes pw->pw_gid = id; 1231553Srgrimes 1241553Srgrimes pw->pw_class = strsep(&bp, ":"); /* class */ 1252916Swollman if(pw->pw_class[0]) pw->pw_fields |= _PWF_CLASS; 1262916Swollman 1271553Srgrimes if (!(p = strsep(&bp, ":"))) /* change */ 1281553Srgrimes goto fmt; 1292916Swollman if(p[0]) pw->pw_fields |= _PWF_CHANGE; 1301553Srgrimes pw->pw_change = atol(p); 1312916Swollman 1321553Srgrimes if (!(p = strsep(&bp, ":"))) /* expire */ 1331553Srgrimes goto fmt; 1342916Swollman if(p[0]) pw->pw_fields |= _PWF_EXPIRE; 1351553Srgrimes pw->pw_expire = atol(p); 1362916Swollman 1375964Sdg if (!(pw->pw_gecos = strsep(&bp, ":"))) /* gecos */ 1385964Sdg goto fmt; 1392916Swollman if(pw->pw_gecos[0]) pw->pw_fields |= _PWF_GECOS; 1402916Swollman 1415964Sdg if (!(pw->pw_dir = strsep(&bp, ":"))) /* directory */ 1425964Sdg goto fmt; 1432916Swollman if(pw->pw_dir[0]) pw->pw_fields |= _PWF_DIR; 1442916Swollman 1451553Srgrimes if (!(pw->pw_shell = strsep(&bp, ":"))) /* shell */ 1461553Srgrimes goto fmt; 1471553Srgrimes 1481553Srgrimes p = pw->pw_shell; 1491553Srgrimes if (root && *p) /* empty == /bin/sh */ 1501553Srgrimes for (setusershell();;) { 1511553Srgrimes if (!(sh = getusershell())) { 1521553Srgrimes warnx("warning, unknown root shell"); 1531553Srgrimes break; 1541553Srgrimes } 1551553Srgrimes if (!strcmp(p, sh)) 1568857Srgrimes break; 1571553Srgrimes } 1582916Swollman if(p[0]) pw->pw_fields |= _PWF_SHELL; 1591553Srgrimes 16030260Scharnier if ((p = strsep(&bp, ":"))) { /* too many */ 1611553Srgrimesfmt: warnx("corrupted entry"); 1621553Srgrimes return (0); 1631553Srgrimes } 1641553Srgrimes return (1); 1651553Srgrimes} 166