/*
* 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
* 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
*/
/*
*/
#include <string.h>
#include <syslog.h>
#include <stdlib.h>
#include <security/pam_appl.h>
#include <security/pam_modules.h>
#include <security/pam_impl.h>
#include <user_attr.h>
#include <secdb.h>
#include <libintl.h>
#include <passwdutil.h>
#include <shadow.h>
/*PRINTFLIKE3*/
static void
{
if (nowarn == 0)
NULL);
}
/*PRINTFLIKE3*/
static void
{
if (nowarn == 0)
NULL);
}
#if defined(ENABLE_AGING)
/*
* test if authtok is aged.
* returns 1 if it is, 0 otherwise
*/
static int
{
(const void **)status) != PAM_SUCCESS)
return (0);
}
#endif
int
{
int i;
int debug = 0;
int nowarn = 0;
attrlist l;
char *user;
char *oldpw;
char *newpw;
char *service;
int res;
int updated_reps = 0;
int server_policy = 0;
for (i = 0; i < argc; i++) {
debug = 1;
nowarn = 1;
server_policy = 1;
}
if ((flags & PAM_PRELIM_CHECK) != 0)
return (PAM_IGNORE);
if ((flags & PAM_UPDATE_AUTHTOK) == 0)
return (PAM_SYSTEM_ERR);
if ((flags & PAM_SILENT) != 0)
nowarn = 1;
if (debug)
#if defined(ENABLE_AGING)
return (PAM_IGNORE);
}
#endif
if (res != PAM_SUCCESS) {
return (PAM_SYSTEM_ERR);
}
if (res != PAM_SUCCESS) {
return (PAM_SYSTEM_ERR);
}
/*
* If the PAM_USER who's password is being changed is a role
* with roleauth=user then we ignore it because those accounts
* should not have a UNIX password. We can't return a failure
* though because the account may have other creds (eg kerberos)
* that should be getting updated in the PAM stack for password.
* We also warn the user and tell them what to do to resolve it.
*/
return (PAM_USER_UNKNOWN);
"%s: Role '%s' has roleauth=user. "
"UNIX password updates are ignored."),
return (PAM_IGNORE);
}
}
if (res != PAM_SUCCESS) {
return (PAM_SYSTEM_ERR);
}
/*
* A module on the stack has removed PAM_AUTHTOK. We fail
*/
return (PAM_SYSTEM_ERR);
}
/*
* If the server_policy option is specified,
* use the special attribute, ATTR_PASSWD_SERVER_POLICY,
* to tell the update routine for each repository
* to perform the necessary special operations.
* For now, only the LDAP routine treats this attribute
* differently that ATTR_PASSWD. It will skip the
* crypting of the password before storing it in the LDAP
* server. NIS, and FILES will handle ATTR_PASSWD_SERVER_POLICY
* the same as ATTR_PASSWD.
*/
if (server_policy)
else
l.type = ATTR_PASSWD;
if (res != PAM_SUCCESS) {
return (PAM_SYSTEM_ERR);
}
} else {
return (PAM_BUF_ERR);
}
if (pwu_rep != PWU_DEFAULT_REP)
/*
* now map the various passwdutil return states to user messages
* and PAM return codes.
*/
switch (res) {
case PWU_SUCCESS:
if ((updated_reps & i) == 0)
continue;
"%s: password successfully changed for %s"),
}
res = PAM_SUCCESS;
break;
case PWU_BUSY:
"%s: Password database busy. Try again later."),
service);
break;
case PWU_STAT_FAILED:
break;
case PWU_OPEN_FAILED:
case PWU_WRITE_FAILED:
case PWU_CLOSE_FAILED:
case PWU_UPDATE_FAILED:
"%s: Unexpected failure. Password database unchanged."),
service);
break;
case PWU_NOT_FOUND:
/* Different error if repository was explicitly specified */
"%s: System error: no %s password for %s."),
} else {
}
break;
case PWU_NOMEM:
"%s: Internal memory allocation failure."), service);
res = PAM_BUF_ERR;
break;
case PWU_SERVER_ERROR:
break;
case PWU_SYSTEM_ERROR:
break;
case PWU_DENIED:
break;
case PWU_NO_CHANGE:
/*
* we're not changing anything.
*/
"%s: Password information unchanged."), service);
res = PAM_SUCCESS;
break;
case PWU_REPOSITORY_ERROR:
"unsupported configuration in /etc/nsswitch.conf.");
"%s: System error: repository out of range."), service);
break;
case PWU_PWD_TOO_SHORT:
"%s: Password too short."), service);
break;
case PWU_PWD_INVALID:
"%s: Invalid password syntax."), service);
break;
case PWU_PWD_IN_HISTORY:
"%s: Reuse of old passwords not "
"allowed, the new password is in the history list."),
service);
break;
case PWU_CHANGE_NOT_ALLOWED:
"%s: You may not change "
"this password."), service);
break;
case PWU_WITHIN_MIN_AGE:
"%s: Password can not be changed yet, "
"not enough time has passed."), service);
break;
default:
break;
}
return (res);
}