xref: /illumos-gate/usr/src/lib/passwdutil/utils.c (revision 46b592853d0f4f11781b6b0a7533f267c6aee132)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #include <sys/types.h>
27 #include <sys/time.h>
28 #include <string.h>
29 #include <thread.h>
30 #include <unistd.h>
31 #include <stdlib.h>
32 #include <crypt.h>
33 #include <pwd.h>
34 #include <shadow.h>
35 
36 #include <deflt.h>
37 
38 #include "passwdutil.h"
39 
40 #define	PWADMIN "/etc/default/passwd"
41 
42 #define	MINWEEKS	-1
43 #define	MAXWEEKS	-1
44 #define	WARNWEEKS	-1
45 
46 extern repops_t files_repops, nis_repops,
47 	nisplus_repops, ldap_repops, nss_repops;
48 
49 repops_t *rops[REP_LAST+1] = {
50 	NULL,
51 	&files_repops,
52 	&nis_repops,
53 	NULL,
54 	&nisplus_repops,
55 	NULL,
56 	NULL,
57 	NULL,
58 	&ldap_repops,
59 	NULL,
60 	NULL,
61 	NULL,
62 	NULL,
63 	NULL,
64 	NULL,
65 	NULL,
66 	&nss_repops,
67 };
68 
69 void
70 free_pwd(struct passwd *pw)
71 {
72 	if (pw->pw_name) free(pw->pw_name);
73 	if (pw->pw_passwd) free(pw->pw_passwd);
74 	if (pw->pw_gecos) free(pw->pw_gecos);
75 	if (pw->pw_dir) free(pw->pw_dir);
76 	if (pw->pw_shell) free(pw->pw_shell);
77 	free(pw);
78 }
79 
80 void
81 free_spwd(struct spwd *spw)
82 {
83 	if (spw->sp_namp) free(spw->sp_namp);
84 	if (spw->sp_pwdp) free(spw->sp_pwdp);
85 	free(spw);
86 }
87 
88 int
89 dup_pw(struct passwd **d, struct passwd *s)
90 {
91 	if (s == NULL) {
92 		*d = NULL;
93 		return (PWU_NOT_FOUND);
94 	}
95 	if ((*d = calloc(1, sizeof (**d))) == NULL)
96 		return (PWU_NOMEM);
97 
98 	if (s->pw_name) {
99 		if (((*d)->pw_name = strdup(s->pw_name)) == NULL)
100 			goto no_mem;
101 	}
102 	if (s->pw_passwd) {
103 		if (((*d)->pw_passwd = strdup(s->pw_passwd)) == NULL)
104 			goto no_mem;
105 	}
106 	(*d)->pw_uid = s->pw_uid;
107 	(*d)->pw_gid = s->pw_gid;
108 
109 	if (s->pw_gecos) {
110 		if (((*d)->pw_gecos = strdup(s->pw_gecos)) == NULL)
111 			goto no_mem;
112 	}
113 	if (s->pw_dir) {
114 		if (((*d)->pw_dir = strdup(s->pw_dir)) == NULL)
115 			goto no_mem;
116 	}
117 	if (s->pw_shell) {
118 		if (((*d)->pw_shell = strdup(s->pw_shell)) == NULL)
119 			goto no_mem;
120 	}
121 
122 	return (PWU_SUCCESS);
123 
124 no_mem:
125 	free_pwd(*d);
126 	*d = NULL;
127 	return (PWU_NOMEM);
128 }
129 
130 int
131 dup_spw(struct spwd **d, struct spwd *s)
132 {
133 	if (s == NULL) {
134 		*d = NULL;
135 		return (PWU_NOT_FOUND);
136 	}
137 	if ((*d = calloc(1, sizeof (**d))) == NULL)
138 		return (PWU_NOMEM);
139 
140 	**d = *s;
141 
142 	if (s->sp_namp)
143 		if (((*d)->sp_namp = strdup(s->sp_namp)) == NULL)
144 			goto no_mem;
145 	if (s->sp_pwdp)
146 		if (((*d)->sp_pwdp = strdup(s->sp_pwdp)) == NULL)
147 			goto no_mem;
148 	return (PWU_SUCCESS);
149 
150 no_mem:
151 	free_spwd(*d);
152 	return (PWU_NOMEM);
153 }
154 
155 /*
156  * read a value from the defaults file, and return it if it is
157  * a positive integer. If the value is not defined, or negative,
158  * return the supplied default value
159  */
160 int
161 def_getuint(char *name, int defvalue, void *defp)
162 {
163 	char *p;
164 	int val = -1;	/* -1 is a guard to catch undefined values */
165 
166 	if ((p = defread_r(name, defp)) != NULL)
167 		val = atoi(p);
168 
169 	return (val >= 0 ? val : defvalue);
170 }
171 
172 void
173 turn_on_default_aging(struct spwd *spw)
174 {
175 	int minweeks;
176 	int maxweeks;
177 	int warnweeks;
178 	void	*defp;
179 
180 	if ((defp = defopen_r(PWADMIN)) == NULL) {
181 		minweeks = MINWEEKS;
182 		maxweeks = MAXWEEKS;
183 		warnweeks = WARNWEEKS;
184 	} else {
185 		minweeks = def_getuint("MINWEEKS=", MINWEEKS, defp);
186 		maxweeks = def_getuint("MAXWEEKS=", MAXWEEKS, defp);
187 		warnweeks = def_getuint("WARNWEEKS=", WARNWEEKS, defp);
188 		defclose_r(defp);
189 	}
190 
191 	/*
192 	 * The values specified in /etc/default/passwd are interpreted
193 	 * in a specific way. Special cases are
194 	 *   MINWEEKS==0 (results in sp_min = -1)
195 	 *   MAXWEEKS==0 (results in sp_max = default)
196 	 */
197 	spw->sp_min = 7 * minweeks;
198 	if (spw->sp_min <= 0)
199 		spw->sp_min = -1;
200 
201 	spw->sp_max = 7 * maxweeks;
202 	if (spw->sp_max == 0)
203 		spw->sp_max = 7 * MAXWEEKS;
204 	if (spw->sp_max < 0)
205 		spw->sp_max = -1;
206 
207 	spw->sp_warn = 7 * warnweeks;
208 	if (spw->sp_warn <= 0)
209 		spw->sp_warn = -1;
210 }
211 
212 /*
213  * open and read a value from the defaults file,
214  * return value found or default value if not found.
215  */
216 int
217 def_getint(char *name, int defvalue)
218 {
219 	int	val;
220 	void	*defp;
221 
222 	if ((defp = defopen_r(PWADMIN)) == NULL) {
223 		val = defvalue;
224 	} else {
225 		val = def_getuint(name, defvalue, defp);
226 		defclose_r(defp);
227 	}
228 
229 	return (val);
230 }
231