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 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 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 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 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 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 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 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