utils.c revision b9175c69691c8949bec97fb8f689b7d1efdb05bb
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson/*
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson * CDDL HEADER START
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson *
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson * The contents of this file are subject to the terms of the
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * Common Development and Distribution License (the "License").
ae115bc77f6fcde83175c75b4206dc2e50747966mrj * You may not use this file except in compliance with the License.
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson *
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson * or http://www.opensolaris.org/os/licensing.
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson * See the License for the specific language governing permissions
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson * and limitations under the License.
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson *
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson * When distributing Covered Code, include this CDDL HEADER in each
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson * If applicable, add the following below this CDDL HEADER, with the
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson * fields enclosed by brackets "[]" replaced with your own identifying
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson * information: Portions Copyright [yyyy] [name of copyright owner]
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson *
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson * CDDL HEADER END
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson */
1e49577a7fcde812700ded04431b49d67cc57d6dRod Evans/*
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson * Use is subject to license terms.
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson */
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson#include <sys/types.h>
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson#include <sys/time.h>
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson#include <string.h>
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson#include <thread.h>
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson#include <unistd.h>
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson#include <stdlib.h>
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson#include <crypt.h>
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson#include <pwd.h>
48bc00d6814e04ff3edb32cafe7d1bc580baff68jmcp#include <shadow.h>
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson#include <deflt.h>
48bc00d6814e04ff3edb32cafe7d1bc580baff68jmcp
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson#include "passwdutil.h"
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson
48bc00d6814e04ff3edb32cafe7d1bc580baff68jmcp#define PWADMIN "/etc/default/passwd"
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson#define MINWEEKS -1
48bc00d6814e04ff3edb32cafe7d1bc580baff68jmcp#define MAXWEEKS -1
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson#define WARNWEEKS -1
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson
48bc00d6814e04ff3edb32cafe7d1bc580baff68jmcpextern repops_t files_repops, nis_repops,
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson nisplus_repops, ldap_repops, nss_repops;
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson
48bc00d6814e04ff3edb32cafe7d1bc580baff68jmcprepops_t *rops[REP_LAST+1] = {
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson NULL,
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson &files_repops,
48bc00d6814e04ff3edb32cafe7d1bc580baff68jmcp &nis_repops,
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson NULL,
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson &nisplus_repops,
48bc00d6814e04ff3edb32cafe7d1bc580baff68jmcp NULL,
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson NULL,
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson NULL,
48bc00d6814e04ff3edb32cafe7d1bc580baff68jmcp &ldap_repops,
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson NULL,
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson NULL,
48bc00d6814e04ff3edb32cafe7d1bc580baff68jmcp NULL,
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson NULL,
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson NULL,
48bc00d6814e04ff3edb32cafe7d1bc580baff68jmcp NULL,
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson NULL,
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson &nss_repops,
24fe0b3bf671e123467ce1df0b67cadd3614c8e4jmcp};
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelsonvoid
24fe0b3bf671e123467ce1df0b67cadd3614c8e4jmcpfree_pwd(struct passwd *pw)
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson{
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson if (pw->pw_name) free(pw->pw_name);
48bc00d6814e04ff3edb32cafe7d1bc580baff68jmcp if (pw->pw_passwd) free(pw->pw_passwd);
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson if (pw->pw_gecos) free(pw->pw_gecos);
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson if (pw->pw_dir) free(pw->pw_dir);
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson if (pw->pw_shell) free(pw->pw_shell);
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson free(pw);
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson}
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelsonvoid
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelsonfree_spwd(struct spwd *spw)
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson{
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson if (spw->sp_namp) free(spw->sp_namp);
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson if (spw->sp_pwdp) free(spw->sp_pwdp);
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson free(spw);
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson}
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelson
1cb6af97c6f66f456d4f726ef056e1ebc0f73305wnelsonint
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);
}