10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 50Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 60Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 70Sstevel@tonic-gate * with the License. 80Sstevel@tonic-gate * 90Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 100Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 110Sstevel@tonic-gate * See the License for the specific language governing permissions 120Sstevel@tonic-gate * and limitations under the License. 130Sstevel@tonic-gate * 140Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 150Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 160Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 170Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 180Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 190Sstevel@tonic-gate * 200Sstevel@tonic-gate * CDDL HEADER END 210Sstevel@tonic-gate */ 220Sstevel@tonic-gate /* 23*1736Swy83408 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 240Sstevel@tonic-gate * Use is subject to license terms. 250Sstevel@tonic-gate */ 260Sstevel@tonic-gate 270Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 280Sstevel@tonic-gate 290Sstevel@tonic-gate #include <sys/types.h> 300Sstevel@tonic-gate #include <sys/time.h> 310Sstevel@tonic-gate #include <string.h> 320Sstevel@tonic-gate #include <thread.h> 330Sstevel@tonic-gate #include <unistd.h> 340Sstevel@tonic-gate #include <stdlib.h> 350Sstevel@tonic-gate #include <crypt.h> 360Sstevel@tonic-gate #include <pwd.h> 370Sstevel@tonic-gate #include <shadow.h> 380Sstevel@tonic-gate 390Sstevel@tonic-gate #include <deflt.h> 400Sstevel@tonic-gate 410Sstevel@tonic-gate #include "passwdutil.h" 420Sstevel@tonic-gate 430Sstevel@tonic-gate #define PWADMIN "/etc/default/passwd" 440Sstevel@tonic-gate 450Sstevel@tonic-gate #define MINWEEKS -1 460Sstevel@tonic-gate #define MAXWEEKS -1 470Sstevel@tonic-gate #define WARNWEEKS -1 480Sstevel@tonic-gate 49*1736Swy83408 extern repops_t files_repops, nis_repops, 50*1736Swy83408 nisplus_repops, ldap_repops, nss_repops; 51*1736Swy83408 52*1736Swy83408 repops_t *rops[REP_LAST+1] = { 53*1736Swy83408 NULL, 54*1736Swy83408 &files_repops, 55*1736Swy83408 &nis_repops, 56*1736Swy83408 NULL, 57*1736Swy83408 &nisplus_repops, 58*1736Swy83408 NULL, 59*1736Swy83408 NULL, 60*1736Swy83408 NULL, 61*1736Swy83408 &ldap_repops, 62*1736Swy83408 NULL, 63*1736Swy83408 NULL, 64*1736Swy83408 NULL, 65*1736Swy83408 NULL, 66*1736Swy83408 NULL, 67*1736Swy83408 NULL, 68*1736Swy83408 NULL, 69*1736Swy83408 &nss_repops, 70*1736Swy83408 }; 71*1736Swy83408 720Sstevel@tonic-gate void 730Sstevel@tonic-gate free_pwd(struct passwd *pw) 740Sstevel@tonic-gate { 750Sstevel@tonic-gate if (pw->pw_name) free(pw->pw_name); 760Sstevel@tonic-gate if (pw->pw_passwd) free(pw->pw_passwd); 770Sstevel@tonic-gate if (pw->pw_gecos) free(pw->pw_gecos); 780Sstevel@tonic-gate if (pw->pw_dir) free(pw->pw_dir); 790Sstevel@tonic-gate if (pw->pw_shell) free(pw->pw_shell); 800Sstevel@tonic-gate free(pw); 810Sstevel@tonic-gate } 820Sstevel@tonic-gate 830Sstevel@tonic-gate void 840Sstevel@tonic-gate free_spwd(struct spwd *spw) 850Sstevel@tonic-gate { 860Sstevel@tonic-gate if (spw->sp_namp) free(spw->sp_namp); 870Sstevel@tonic-gate if (spw->sp_pwdp) free(spw->sp_pwdp); 880Sstevel@tonic-gate free(spw); 890Sstevel@tonic-gate } 900Sstevel@tonic-gate 910Sstevel@tonic-gate int 920Sstevel@tonic-gate dup_pw(struct passwd **d, struct passwd *s) 930Sstevel@tonic-gate { 940Sstevel@tonic-gate if (s == NULL) { 950Sstevel@tonic-gate *d = NULL; 960Sstevel@tonic-gate return (PWU_NOT_FOUND); 970Sstevel@tonic-gate } 980Sstevel@tonic-gate if ((*d = calloc(1, sizeof (**d))) == NULL) 990Sstevel@tonic-gate return (PWU_NOMEM); 1000Sstevel@tonic-gate 1010Sstevel@tonic-gate if (s->pw_name) { 1020Sstevel@tonic-gate if (((*d)->pw_name = strdup(s->pw_name)) == NULL) 1030Sstevel@tonic-gate goto no_mem; 1040Sstevel@tonic-gate } 1050Sstevel@tonic-gate if (s->pw_passwd) { 1060Sstevel@tonic-gate if (((*d)->pw_passwd = strdup(s->pw_passwd)) == NULL) 1070Sstevel@tonic-gate goto no_mem; 1080Sstevel@tonic-gate } 1090Sstevel@tonic-gate (*d)->pw_uid = s->pw_uid; 1100Sstevel@tonic-gate (*d)->pw_gid = s->pw_gid; 1110Sstevel@tonic-gate 1120Sstevel@tonic-gate if (s->pw_gecos) { 1130Sstevel@tonic-gate if (((*d)->pw_gecos = strdup(s->pw_gecos)) == NULL) 1140Sstevel@tonic-gate goto no_mem; 1150Sstevel@tonic-gate } 1160Sstevel@tonic-gate if (s->pw_dir) { 1170Sstevel@tonic-gate if (((*d)->pw_dir = strdup(s->pw_dir)) == NULL) 1180Sstevel@tonic-gate goto no_mem; 1190Sstevel@tonic-gate } 1200Sstevel@tonic-gate if (s->pw_shell) { 1210Sstevel@tonic-gate if (((*d)->pw_shell = strdup(s->pw_shell)) == NULL) 1220Sstevel@tonic-gate goto no_mem; 1230Sstevel@tonic-gate } 1240Sstevel@tonic-gate 1250Sstevel@tonic-gate return (PWU_SUCCESS); 1260Sstevel@tonic-gate 1270Sstevel@tonic-gate no_mem: 1280Sstevel@tonic-gate free_pwd(*d); 1290Sstevel@tonic-gate *d = NULL; 1300Sstevel@tonic-gate return (PWU_NOMEM); 1310Sstevel@tonic-gate } 1320Sstevel@tonic-gate 1330Sstevel@tonic-gate int 1340Sstevel@tonic-gate dup_spw(struct spwd **d, struct spwd *s) 1350Sstevel@tonic-gate { 1360Sstevel@tonic-gate if (s == NULL) { 1370Sstevel@tonic-gate *d = NULL; 1380Sstevel@tonic-gate return (PWU_NOT_FOUND); 1390Sstevel@tonic-gate } 1400Sstevel@tonic-gate if ((*d = calloc(1, sizeof (**d))) == NULL) 1410Sstevel@tonic-gate return (PWU_NOMEM); 1420Sstevel@tonic-gate 1430Sstevel@tonic-gate **d = *s; 1440Sstevel@tonic-gate 1450Sstevel@tonic-gate if (s->sp_namp) 1460Sstevel@tonic-gate if (((*d)->sp_namp = strdup(s->sp_namp)) == NULL) 1470Sstevel@tonic-gate goto no_mem; 1480Sstevel@tonic-gate if (s->sp_pwdp) 1490Sstevel@tonic-gate if (((*d)->sp_pwdp = strdup(s->sp_pwdp)) == NULL) 1500Sstevel@tonic-gate goto no_mem; 1510Sstevel@tonic-gate return (PWU_SUCCESS); 1520Sstevel@tonic-gate 1530Sstevel@tonic-gate no_mem: 1540Sstevel@tonic-gate free_spwd(*d); 1550Sstevel@tonic-gate return (PWU_NOMEM); 1560Sstevel@tonic-gate } 1570Sstevel@tonic-gate 1580Sstevel@tonic-gate /* 1590Sstevel@tonic-gate * read a value from the defaults file, and return it if it is 1600Sstevel@tonic-gate * a positive integer. If the value is not defined, or negative, 1610Sstevel@tonic-gate * return the supplied default value 1620Sstevel@tonic-gate */ 1630Sstevel@tonic-gate int 1640Sstevel@tonic-gate def_getuint(char *name, int defvalue) 1650Sstevel@tonic-gate { 1660Sstevel@tonic-gate char *p; 1670Sstevel@tonic-gate int val = -1; /* -1 is a guard to catch undefined values */ 1680Sstevel@tonic-gate 1690Sstevel@tonic-gate if (p = defread(name)) 1700Sstevel@tonic-gate val = atoi(p); 1710Sstevel@tonic-gate 1720Sstevel@tonic-gate return (val >= 0 ? val : defvalue); 1730Sstevel@tonic-gate } 1740Sstevel@tonic-gate 1750Sstevel@tonic-gate void 1760Sstevel@tonic-gate turn_on_default_aging(struct spwd *spw) 1770Sstevel@tonic-gate { 1780Sstevel@tonic-gate int minweeks; 1790Sstevel@tonic-gate int maxweeks; 1800Sstevel@tonic-gate int warnweeks; 1810Sstevel@tonic-gate 1820Sstevel@tonic-gate if (defopen(PWADMIN) != 0) { 1830Sstevel@tonic-gate minweeks = MINWEEKS; 1840Sstevel@tonic-gate maxweeks = MAXWEEKS; 1850Sstevel@tonic-gate warnweeks = WARNWEEKS; 1860Sstevel@tonic-gate } else { 1870Sstevel@tonic-gate minweeks = def_getuint("MINWEEKS=", MINWEEKS); 1880Sstevel@tonic-gate maxweeks = def_getuint("MAXWEEKS=", MAXWEEKS); 1890Sstevel@tonic-gate warnweeks = def_getuint("WARNWEEKS=", WARNWEEKS); 1900Sstevel@tonic-gate (void) defopen(NULL); 1910Sstevel@tonic-gate } 1920Sstevel@tonic-gate 1930Sstevel@tonic-gate /* 1940Sstevel@tonic-gate * The values specified in /etc/default/passwd are interpreted 1950Sstevel@tonic-gate * in a specific way. Special cases are 1960Sstevel@tonic-gate * MINWEEKS==0 (results in sp_min = -1) 1970Sstevel@tonic-gate * MAXWEEKS==0 (results in sp_max = default) 1980Sstevel@tonic-gate */ 1990Sstevel@tonic-gate spw->sp_min = 7 * minweeks; 2000Sstevel@tonic-gate if (spw->sp_min <= 0) 2010Sstevel@tonic-gate spw->sp_min = -1; 2020Sstevel@tonic-gate 2030Sstevel@tonic-gate spw->sp_max = 7 * maxweeks; 2040Sstevel@tonic-gate if (spw->sp_max == 0) 2050Sstevel@tonic-gate spw->sp_max = 7 * MAXWEEKS; 2060Sstevel@tonic-gate if (spw->sp_max < 0) 2070Sstevel@tonic-gate spw->sp_max = -1; 2080Sstevel@tonic-gate 2090Sstevel@tonic-gate spw->sp_warn = 7 * warnweeks; 2100Sstevel@tonic-gate if (spw->sp_warn <= 0) 2110Sstevel@tonic-gate spw->sp_warn = -1; 2120Sstevel@tonic-gate } 2130Sstevel@tonic-gate 2140Sstevel@tonic-gate /* 2150Sstevel@tonic-gate * open and read a value from the defaults file, 2160Sstevel@tonic-gate * return value found or default value if not found. 2170Sstevel@tonic-gate */ 2180Sstevel@tonic-gate int 2190Sstevel@tonic-gate def_getint(char *name, int defvalue) 2200Sstevel@tonic-gate { 2210Sstevel@tonic-gate int val; 2220Sstevel@tonic-gate 2230Sstevel@tonic-gate if (defopen(PWADMIN) != 0) 2240Sstevel@tonic-gate val = defvalue; 2250Sstevel@tonic-gate else 2260Sstevel@tonic-gate val = def_getuint(name, defvalue); 2270Sstevel@tonic-gate 2280Sstevel@tonic-gate (void) defopen(NULL); 2290Sstevel@tonic-gate return (val); 2300Sstevel@tonic-gate } 231