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
58563SKenjiro.Tsuji@Sun.COM * Common Development and Distribution License (the "License").
68563SKenjiro.Tsuji@Sun.COM * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
210Sstevel@tonic-gate /*
228563SKenjiro.Tsuji@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
230Sstevel@tonic-gate * Use is subject to license terms.
240Sstevel@tonic-gate */
250Sstevel@tonic-gate
260Sstevel@tonic-gate #include <sys/types.h>
270Sstevel@tonic-gate #include <sys/time.h>
280Sstevel@tonic-gate #include <string.h>
290Sstevel@tonic-gate #include <thread.h>
300Sstevel@tonic-gate #include <unistd.h>
310Sstevel@tonic-gate #include <stdlib.h>
320Sstevel@tonic-gate #include <crypt.h>
330Sstevel@tonic-gate #include <pwd.h>
340Sstevel@tonic-gate #include <shadow.h>
350Sstevel@tonic-gate
360Sstevel@tonic-gate #include <deflt.h>
370Sstevel@tonic-gate
380Sstevel@tonic-gate #include "passwdutil.h"
390Sstevel@tonic-gate
400Sstevel@tonic-gate #define PWADMIN "/etc/default/passwd"
410Sstevel@tonic-gate
420Sstevel@tonic-gate #define MINWEEKS -1
430Sstevel@tonic-gate #define MAXWEEKS -1
440Sstevel@tonic-gate #define WARNWEEKS -1
450Sstevel@tonic-gate
46*11262SRajagopal.Andra@Sun.COM extern repops_t files_repops, nis_repops, ldap_repops, nss_repops;
471736Swy83408
481736Swy83408 repops_t *rops[REP_LAST+1] = {
491736Swy83408 NULL,
501736Swy83408 &files_repops,
511736Swy83408 &nis_repops,
521736Swy83408 NULL,
531736Swy83408 &ldap_repops,
541736Swy83408 NULL,
551736Swy83408 NULL,
561736Swy83408 NULL,
571736Swy83408 &nss_repops,
581736Swy83408 };
591736Swy83408
600Sstevel@tonic-gate void
free_pwd(struct passwd * pw)610Sstevel@tonic-gate free_pwd(struct passwd *pw)
620Sstevel@tonic-gate {
630Sstevel@tonic-gate if (pw->pw_name) free(pw->pw_name);
640Sstevel@tonic-gate if (pw->pw_passwd) free(pw->pw_passwd);
650Sstevel@tonic-gate if (pw->pw_gecos) free(pw->pw_gecos);
660Sstevel@tonic-gate if (pw->pw_dir) free(pw->pw_dir);
670Sstevel@tonic-gate if (pw->pw_shell) free(pw->pw_shell);
680Sstevel@tonic-gate free(pw);
690Sstevel@tonic-gate }
700Sstevel@tonic-gate
710Sstevel@tonic-gate void
free_spwd(struct spwd * spw)720Sstevel@tonic-gate free_spwd(struct spwd *spw)
730Sstevel@tonic-gate {
740Sstevel@tonic-gate if (spw->sp_namp) free(spw->sp_namp);
750Sstevel@tonic-gate if (spw->sp_pwdp) free(spw->sp_pwdp);
760Sstevel@tonic-gate free(spw);
770Sstevel@tonic-gate }
780Sstevel@tonic-gate
790Sstevel@tonic-gate int
dup_pw(struct passwd ** d,struct passwd * s)800Sstevel@tonic-gate dup_pw(struct passwd **d, struct passwd *s)
810Sstevel@tonic-gate {
820Sstevel@tonic-gate if (s == NULL) {
830Sstevel@tonic-gate *d = NULL;
840Sstevel@tonic-gate return (PWU_NOT_FOUND);
850Sstevel@tonic-gate }
860Sstevel@tonic-gate if ((*d = calloc(1, sizeof (**d))) == NULL)
870Sstevel@tonic-gate return (PWU_NOMEM);
880Sstevel@tonic-gate
890Sstevel@tonic-gate if (s->pw_name) {
900Sstevel@tonic-gate if (((*d)->pw_name = strdup(s->pw_name)) == NULL)
910Sstevel@tonic-gate goto no_mem;
920Sstevel@tonic-gate }
930Sstevel@tonic-gate if (s->pw_passwd) {
940Sstevel@tonic-gate if (((*d)->pw_passwd = strdup(s->pw_passwd)) == NULL)
950Sstevel@tonic-gate goto no_mem;
960Sstevel@tonic-gate }
970Sstevel@tonic-gate (*d)->pw_uid = s->pw_uid;
980Sstevel@tonic-gate (*d)->pw_gid = s->pw_gid;
990Sstevel@tonic-gate
1000Sstevel@tonic-gate if (s->pw_gecos) {
1010Sstevel@tonic-gate if (((*d)->pw_gecos = strdup(s->pw_gecos)) == NULL)
1020Sstevel@tonic-gate goto no_mem;
1030Sstevel@tonic-gate }
1040Sstevel@tonic-gate if (s->pw_dir) {
1050Sstevel@tonic-gate if (((*d)->pw_dir = strdup(s->pw_dir)) == NULL)
1060Sstevel@tonic-gate goto no_mem;
1070Sstevel@tonic-gate }
1080Sstevel@tonic-gate if (s->pw_shell) {
1090Sstevel@tonic-gate if (((*d)->pw_shell = strdup(s->pw_shell)) == NULL)
1100Sstevel@tonic-gate goto no_mem;
1110Sstevel@tonic-gate }
1120Sstevel@tonic-gate
1130Sstevel@tonic-gate return (PWU_SUCCESS);
1140Sstevel@tonic-gate
1150Sstevel@tonic-gate no_mem:
1160Sstevel@tonic-gate free_pwd(*d);
1170Sstevel@tonic-gate *d = NULL;
1180Sstevel@tonic-gate return (PWU_NOMEM);
1190Sstevel@tonic-gate }
1200Sstevel@tonic-gate
1210Sstevel@tonic-gate int
dup_spw(struct spwd ** d,struct spwd * s)1220Sstevel@tonic-gate dup_spw(struct spwd **d, struct spwd *s)
1230Sstevel@tonic-gate {
1240Sstevel@tonic-gate if (s == NULL) {
1250Sstevel@tonic-gate *d = NULL;
1260Sstevel@tonic-gate return (PWU_NOT_FOUND);
1270Sstevel@tonic-gate }
1280Sstevel@tonic-gate if ((*d = calloc(1, sizeof (**d))) == NULL)
1290Sstevel@tonic-gate return (PWU_NOMEM);
1300Sstevel@tonic-gate
1310Sstevel@tonic-gate **d = *s;
1320Sstevel@tonic-gate
1330Sstevel@tonic-gate if (s->sp_namp)
1340Sstevel@tonic-gate if (((*d)->sp_namp = strdup(s->sp_namp)) == NULL)
1350Sstevel@tonic-gate goto no_mem;
1360Sstevel@tonic-gate if (s->sp_pwdp)
1370Sstevel@tonic-gate if (((*d)->sp_pwdp = strdup(s->sp_pwdp)) == NULL)
1380Sstevel@tonic-gate goto no_mem;
1390Sstevel@tonic-gate return (PWU_SUCCESS);
1400Sstevel@tonic-gate
1410Sstevel@tonic-gate no_mem:
1420Sstevel@tonic-gate free_spwd(*d);
1430Sstevel@tonic-gate return (PWU_NOMEM);
1440Sstevel@tonic-gate }
1450Sstevel@tonic-gate
1460Sstevel@tonic-gate /*
1470Sstevel@tonic-gate * read a value from the defaults file, and return it if it is
1480Sstevel@tonic-gate * a positive integer. If the value is not defined, or negative,
1490Sstevel@tonic-gate * return the supplied default value
1500Sstevel@tonic-gate */
1510Sstevel@tonic-gate int
def_getuint(char * name,int defvalue,void * defp)1528563SKenjiro.Tsuji@Sun.COM def_getuint(char *name, int defvalue, void *defp)
1530Sstevel@tonic-gate {
1540Sstevel@tonic-gate char *p;
1550Sstevel@tonic-gate int val = -1; /* -1 is a guard to catch undefined values */
1560Sstevel@tonic-gate
1578563SKenjiro.Tsuji@Sun.COM if ((p = defread_r(name, defp)) != NULL)
1580Sstevel@tonic-gate val = atoi(p);
1590Sstevel@tonic-gate
1600Sstevel@tonic-gate return (val >= 0 ? val : defvalue);
1610Sstevel@tonic-gate }
1620Sstevel@tonic-gate
1630Sstevel@tonic-gate void
turn_on_default_aging(struct spwd * spw)1640Sstevel@tonic-gate turn_on_default_aging(struct spwd *spw)
1650Sstevel@tonic-gate {
1660Sstevel@tonic-gate int minweeks;
1670Sstevel@tonic-gate int maxweeks;
1680Sstevel@tonic-gate int warnweeks;
1698563SKenjiro.Tsuji@Sun.COM void *defp;
1700Sstevel@tonic-gate
1718563SKenjiro.Tsuji@Sun.COM if ((defp = defopen_r(PWADMIN)) == NULL) {
1720Sstevel@tonic-gate minweeks = MINWEEKS;
1730Sstevel@tonic-gate maxweeks = MAXWEEKS;
1740Sstevel@tonic-gate warnweeks = WARNWEEKS;
1750Sstevel@tonic-gate } else {
1768563SKenjiro.Tsuji@Sun.COM minweeks = def_getuint("MINWEEKS=", MINWEEKS, defp);
1778563SKenjiro.Tsuji@Sun.COM maxweeks = def_getuint("MAXWEEKS=", MAXWEEKS, defp);
1788563SKenjiro.Tsuji@Sun.COM warnweeks = def_getuint("WARNWEEKS=", WARNWEEKS, defp);
1798563SKenjiro.Tsuji@Sun.COM defclose_r(defp);
1800Sstevel@tonic-gate }
1810Sstevel@tonic-gate
1820Sstevel@tonic-gate /*
1830Sstevel@tonic-gate * The values specified in /etc/default/passwd are interpreted
1840Sstevel@tonic-gate * in a specific way. Special cases are
1850Sstevel@tonic-gate * MINWEEKS==0 (results in sp_min = -1)
1860Sstevel@tonic-gate * MAXWEEKS==0 (results in sp_max = default)
1870Sstevel@tonic-gate */
1880Sstevel@tonic-gate spw->sp_min = 7 * minweeks;
1890Sstevel@tonic-gate if (spw->sp_min <= 0)
1900Sstevel@tonic-gate spw->sp_min = -1;
1910Sstevel@tonic-gate
1920Sstevel@tonic-gate spw->sp_max = 7 * maxweeks;
1930Sstevel@tonic-gate if (spw->sp_max == 0)
1940Sstevel@tonic-gate spw->sp_max = 7 * MAXWEEKS;
1950Sstevel@tonic-gate if (spw->sp_max < 0)
1960Sstevel@tonic-gate spw->sp_max = -1;
1970Sstevel@tonic-gate
1980Sstevel@tonic-gate spw->sp_warn = 7 * warnweeks;
1990Sstevel@tonic-gate if (spw->sp_warn <= 0)
2000Sstevel@tonic-gate spw->sp_warn = -1;
2010Sstevel@tonic-gate }
2020Sstevel@tonic-gate
2030Sstevel@tonic-gate /*
2040Sstevel@tonic-gate * open and read a value from the defaults file,
2050Sstevel@tonic-gate * return value found or default value if not found.
2060Sstevel@tonic-gate */
2070Sstevel@tonic-gate int
def_getint(char * name,int defvalue)2080Sstevel@tonic-gate def_getint(char *name, int defvalue)
2090Sstevel@tonic-gate {
2100Sstevel@tonic-gate int val;
2118563SKenjiro.Tsuji@Sun.COM void *defp;
2120Sstevel@tonic-gate
2138563SKenjiro.Tsuji@Sun.COM if ((defp = defopen_r(PWADMIN)) == NULL) {
2140Sstevel@tonic-gate val = defvalue;
2158563SKenjiro.Tsuji@Sun.COM } else {
2168563SKenjiro.Tsuji@Sun.COM val = def_getuint(name, defvalue, defp);
2178563SKenjiro.Tsuji@Sun.COM defclose_r(defp);
2188563SKenjiro.Tsuji@Sun.COM }
2190Sstevel@tonic-gate
2200Sstevel@tonic-gate return (val);
2210Sstevel@tonic-gate }
222