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