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