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, ldap_repops, nss_repops;
47
48 repops_t *rops[REP_LAST+1] = {
49 NULL,
50 &files_repops,
51 &nis_repops,
52 NULL,
53 &ldap_repops,
54 NULL,
55 NULL,
56 NULL,
57 &nss_repops,
58 };
59
60 void
free_pwd(struct passwd * pw)61 free_pwd(struct passwd *pw)
62 {
63 if (pw->pw_name) free(pw->pw_name);
64 if (pw->pw_passwd) free(pw->pw_passwd);
65 if (pw->pw_gecos) free(pw->pw_gecos);
66 if (pw->pw_dir) free(pw->pw_dir);
67 if (pw->pw_shell) free(pw->pw_shell);
68 free(pw);
69 }
70
71 void
free_spwd(struct spwd * spw)72 free_spwd(struct spwd *spw)
73 {
74 if (spw->sp_namp) free(spw->sp_namp);
75 if (spw->sp_pwdp) free(spw->sp_pwdp);
76 free(spw);
77 }
78
79 int
dup_pw(struct passwd ** d,struct passwd * s)80 dup_pw(struct passwd **d, struct passwd *s)
81 {
82 if (s == NULL) {
83 *d = NULL;
84 return (PWU_NOT_FOUND);
85 }
86 if ((*d = calloc(1, sizeof (**d))) == NULL)
87 return (PWU_NOMEM);
88
89 if (s->pw_name) {
90 if (((*d)->pw_name = strdup(s->pw_name)) == NULL)
91 goto no_mem;
92 }
93 if (s->pw_passwd) {
94 if (((*d)->pw_passwd = strdup(s->pw_passwd)) == NULL)
95 goto no_mem;
96 }
97 (*d)->pw_uid = s->pw_uid;
98 (*d)->pw_gid = s->pw_gid;
99
100 if (s->pw_gecos) {
101 if (((*d)->pw_gecos = strdup(s->pw_gecos)) == NULL)
102 goto no_mem;
103 }
104 if (s->pw_dir) {
105 if (((*d)->pw_dir = strdup(s->pw_dir)) == NULL)
106 goto no_mem;
107 }
108 if (s->pw_shell) {
109 if (((*d)->pw_shell = strdup(s->pw_shell)) == NULL)
110 goto no_mem;
111 }
112
113 return (PWU_SUCCESS);
114
115 no_mem:
116 free_pwd(*d);
117 *d = NULL;
118 return (PWU_NOMEM);
119 }
120
121 int
dup_spw(struct spwd ** d,struct spwd * s)122 dup_spw(struct spwd **d, struct spwd *s)
123 {
124 if (s == NULL) {
125 *d = NULL;
126 return (PWU_NOT_FOUND);
127 }
128 if ((*d = calloc(1, sizeof (**d))) == NULL)
129 return (PWU_NOMEM);
130
131 **d = *s;
132
133 if (s->sp_namp)
134 if (((*d)->sp_namp = strdup(s->sp_namp)) == NULL)
135 goto no_mem;
136 if (s->sp_pwdp)
137 if (((*d)->sp_pwdp = strdup(s->sp_pwdp)) == NULL)
138 goto no_mem;
139 return (PWU_SUCCESS);
140
141 no_mem:
142 free_spwd(*d);
143 return (PWU_NOMEM);
144 }
145
146 /*
147 * read a value from the defaults file, and return it if it is
148 * a positive integer. If the value is not defined, or negative,
149 * return the supplied default value
150 */
151 int
def_getuint(char * name,int defvalue,void * defp)152 def_getuint(char *name, int defvalue, void *defp)
153 {
154 char *p;
155 int val = -1; /* -1 is a guard to catch undefined values */
156
157 if ((p = defread_r(name, defp)) != NULL)
158 val = atoi(p);
159
160 return (val >= 0 ? val : defvalue);
161 }
162
163 void
turn_on_default_aging(struct spwd * spw)164 turn_on_default_aging(struct spwd *spw)
165 {
166 int minweeks;
167 int maxweeks;
168 int warnweeks;
169 void *defp;
170
171 if ((defp = defopen_r(PWADMIN)) == NULL) {
172 minweeks = MINWEEKS;
173 maxweeks = MAXWEEKS;
174 warnweeks = WARNWEEKS;
175 } else {
176 minweeks = def_getuint("MINWEEKS=", MINWEEKS, defp);
177 maxweeks = def_getuint("MAXWEEKS=", MAXWEEKS, defp);
178 warnweeks = def_getuint("WARNWEEKS=", WARNWEEKS, defp);
179 defclose_r(defp);
180 }
181
182 /*
183 * The values specified in /etc/default/passwd are interpreted
184 * in a specific way. Special cases are
185 * MINWEEKS==0 (results in sp_min = -1)
186 * MAXWEEKS==0 (results in sp_max = default)
187 */
188 spw->sp_min = 7 * minweeks;
189 if (spw->sp_min <= 0)
190 spw->sp_min = -1;
191
192 spw->sp_max = 7 * maxweeks;
193 if (spw->sp_max == 0)
194 spw->sp_max = 7 * MAXWEEKS;
195 if (spw->sp_max < 0)
196 spw->sp_max = -1;
197
198 spw->sp_warn = 7 * warnweeks;
199 if (spw->sp_warn <= 0)
200 spw->sp_warn = -1;
201 }
202
203 /*
204 * open and read a value from the defaults file,
205 * return value found or default value if not found.
206 */
207 int
def_getint(char * name,int defvalue)208 def_getint(char *name, int defvalue)
209 {
210 int val;
211 void *defp;
212
213 if ((defp = defopen_r(PWADMIN)) == NULL) {
214 val = defvalue;
215 } else {
216 val = def_getuint(name, defvalue, defp);
217 defclose_r(defp);
218 }
219
220 return (val);
221 }
222