| /* |
| * CDDL HEADER START |
| * |
| * The contents of this file are subject to the terms of the |
| * Common Development and Distribution License (the "License"). |
| * You may not use this file except in compliance with the License. |
| * |
| * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE |
| * or http://www.opensolaris.org/os/licensing. |
| * See the License for the specific language governing permissions |
| * and limitations under the License. |
| * |
| * When distributing Covered Code, include this CDDL HEADER in each |
| * file and include the License file at usr/src/OPENSOLARIS.LICENSE. |
| * If applicable, add the following below this CDDL HEADER, with the |
| * fields enclosed by brackets "[]" replaced with your own identifying |
| * information: Portions Copyright [yyyy] [name of copyright owner] |
| * |
| * CDDL HEADER END |
| */ |
| /* |
| * Copyright 2009 Sun Microsystems, Inc. All rights reserved. |
| * Use is subject to license terms. |
| */ |
| |
| #include <sys/types.h> |
| #include <sys/time.h> |
| #include <string.h> |
| #include <thread.h> |
| #include <unistd.h> |
| #include <stdlib.h> |
| #include <crypt.h> |
| #include <pwd.h> |
| #include <shadow.h> |
| |
| #include <deflt.h> |
| |
| #include "passwdutil.h" |
| |
| #define PWADMIN "/etc/default/passwd" |
| |
| #define MINWEEKS -1 |
| #define MAXWEEKS -1 |
| #define WARNWEEKS -1 |
| |
| extern repops_t files_repops, nis_repops, ldap_repops, nss_repops; |
| |
| repops_t *rops[REP_LAST+1] = { |
| NULL, |
| &files_repops, |
| &nis_repops, |
| NULL, |
| &ldap_repops, |
| NULL, |
| NULL, |
| NULL, |
| &nss_repops, |
| }; |
| |
| void |
| free_pwd(struct passwd *pw) |
| { |
| if (pw->pw_name) free(pw->pw_name); |
| if (pw->pw_passwd) free(pw->pw_passwd); |
| if (pw->pw_gecos) free(pw->pw_gecos); |
| if (pw->pw_dir) free(pw->pw_dir); |
| if (pw->pw_shell) free(pw->pw_shell); |
| free(pw); |
| } |
| |
| void |
| free_spwd(struct spwd *spw) |
| { |
| if (spw->sp_namp) free(spw->sp_namp); |
| if (spw->sp_pwdp) free(spw->sp_pwdp); |
| free(spw); |
| } |
| |
| int |
| dup_pw(struct passwd **d, struct passwd *s) |
| { |
| if (s == NULL) { |
| *d = NULL; |
| return (PWU_NOT_FOUND); |
| } |
| if ((*d = calloc(1, sizeof (**d))) == NULL) |
| return (PWU_NOMEM); |
| |
| if (s->pw_name) { |
| if (((*d)->pw_name = strdup(s->pw_name)) == NULL) |
| goto no_mem; |
| } |
| if (s->pw_passwd) { |
| if (((*d)->pw_passwd = strdup(s->pw_passwd)) == NULL) |
| goto no_mem; |
| } |
| (*d)->pw_uid = s->pw_uid; |
| (*d)->pw_gid = s->pw_gid; |
| |
| if (s->pw_gecos) { |
| if (((*d)->pw_gecos = strdup(s->pw_gecos)) == NULL) |
| goto no_mem; |
| } |
| if (s->pw_dir) { |
| if (((*d)->pw_dir = strdup(s->pw_dir)) == NULL) |
| goto no_mem; |
| } |
| if (s->pw_shell) { |
| if (((*d)->pw_shell = strdup(s->pw_shell)) == NULL) |
| goto no_mem; |
| } |
| |
| return (PWU_SUCCESS); |
| |
| no_mem: |
| free_pwd(*d); |
| *d = NULL; |
| return (PWU_NOMEM); |
| } |
| |
| int |
| dup_spw(struct spwd **d, struct spwd *s) |
| { |
| if (s == NULL) { |
| *d = NULL; |
| return (PWU_NOT_FOUND); |
| } |
| if ((*d = calloc(1, sizeof (**d))) == NULL) |
| return (PWU_NOMEM); |
| |
| **d = *s; |
| |
| if (s->sp_namp) |
| if (((*d)->sp_namp = strdup(s->sp_namp)) == NULL) |
| goto no_mem; |
| if (s->sp_pwdp) |
| if (((*d)->sp_pwdp = strdup(s->sp_pwdp)) == NULL) |
| goto no_mem; |
| return (PWU_SUCCESS); |
| |
| no_mem: |
| free_spwd(*d); |
| return (PWU_NOMEM); |
| } |
| |
| /* |
| * read a value from the defaults file, and return it if it is |
| * a positive integer. If the value is not defined, or negative, |
| * return the supplied default value |
| */ |
| int |
| def_getuint(char *name, int defvalue, void *defp) |
| { |
| char *p; |
| int val = -1; /* -1 is a guard to catch undefined values */ |
| |
| if ((p = defread_r(name, defp)) != NULL) |
| val = atoi(p); |
| |
| return (val >= 0 ? val : defvalue); |
| } |
| |
| void |
| turn_on_default_aging(struct spwd *spw) |
| { |
| int minweeks; |
| int maxweeks; |
| int warnweeks; |
| void *defp; |
| |
| if ((defp = defopen_r(PWADMIN)) == NULL) { |
| minweeks = MINWEEKS; |
| maxweeks = MAXWEEKS; |
| warnweeks = WARNWEEKS; |
| } else { |
| minweeks = def_getuint("MINWEEKS=", MINWEEKS, defp); |
| maxweeks = def_getuint("MAXWEEKS=", MAXWEEKS, defp); |
| warnweeks = def_getuint("WARNWEEKS=", WARNWEEKS, defp); |
| defclose_r(defp); |
| } |
| |
| /* |
| * The values specified in /etc/default/passwd are interpreted |
| * in a specific way. Special cases are |
| * MINWEEKS==0 (results in sp_min = -1) |
| * MAXWEEKS==0 (results in sp_max = default) |
| */ |
| spw->sp_min = 7 * minweeks; |
| if (spw->sp_min <= 0) |
| spw->sp_min = -1; |
| |
| spw->sp_max = 7 * maxweeks; |
| if (spw->sp_max == 0) |
| spw->sp_max = 7 * MAXWEEKS; |
| if (spw->sp_max < 0) |
| spw->sp_max = -1; |
| |
| spw->sp_warn = 7 * warnweeks; |
| if (spw->sp_warn <= 0) |
| spw->sp_warn = -1; |
| } |
| |
| /* |
| * open and read a value from the defaults file, |
| * return value found or default value if not found. |
| */ |
| int |
| def_getint(char *name, int defvalue) |
| { |
| int val; |
| void *defp; |
| |
| if ((defp = defopen_r(PWADMIN)) == NULL) { |
| val = defvalue; |
| } else { |
| val = def_getuint(name, defvalue, defp); |
| defclose_r(defp); |
| } |
| |
| return (val); |
| } |