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