xref: /onnv-gate/usr/src/lib/passwdutil/utils.c (revision 1736)
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