Files
cdesktop/cde/lib/pam/pam_modules/unix/unix_setcred.c
2018-04-28 12:30:20 -06:00

195 lines
5.2 KiB
C

/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these libraries and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/* $XConsortium: unix_setcred.c /main/5 1996/05/09 04:35:09 drk $ */
/*
* Copyright (c) 1992-1995, by Sun Microsystems, Inc.
* All rights reserved.
*/
#ident "@(#)unix_setcred.c 1.51 95/12/12 SMI"
#include "unix_headers.h"
/*
* pam_sm_setcred - Set the process credentials
*
* XXX: If this module succeeds when invoked with PAM_ESTABLISH_CREd,
* and a subsequent module in the stack fails, then there is no way
* to delete the user's Secure RPC credentials (keylogout). Currently
* there is no way for PAM to correct this problem.
*/
int
pam_sm_setcred(
pam_handle_t *pamh,
int flags,
int argc,
const char **argv)
{
int i;
int debug = 0;
int err = 0;
struct pam_conv *pam_convp;
char messages[PAM_MAX_NUM_MSG][PAM_MAX_MSG_SIZE];
#ifdef PAM_SECURE_RPC
unix_auth_data *status;
char secret[HEXKEYBYTES + 1];
struct nfs_revauth_args nra; /* revoking kernel NFS creds */
#endif
for (i = 0; i < argc; i++) {
if (strcasecmp(argv[i], "debug") == 0)
debug = 1;
else if (strcasecmp(argv[i], "nowarn") == 0)
flags = flags | PAM_SILENT;
}
/* make sure flags are valid */
if (flags &&
!(flags & PAM_ESTABLISH_CRED) &&
!(flags & PAM_REINITIALIZE_CRED) &&
!(flags & PAM_REFRESH_CRED) &&
!(flags & PAM_DELETE_CRED) &&
!(flags & PAM_SILENT)) {
syslog(LOG_ERR, "unix setcred: illegal flag %d", flags);
err = PAM_SYSTEM_ERR;
goto out;
}
if (pam_get_item(pamh, PAM_CONV, (void **) &pam_convp) !=
PAM_SUCCESS) {
if (debug) {
syslog(LOG_DEBUG,
"pam_sm_setcred(): unable to get conv structure");
}
err = PAM_SERVICE_ERR;
goto out;
}
if ((flags & PAM_REINITIALIZE_CRED) ||
(flags & PAM_REFRESH_CRED)) {
/* For unix, these flags are not applicable */
err = PAM_SUCCESS;
} else if (flags & PAM_DELETE_CRED) {
#ifdef PAM_SECURE_RPC
/* do a keylogout */
memset(secret, 0, sizeof (secret));
if (geteuid() == 0) {
if (!(flags & PAM_SILENT)) {
sprintf(messages[0], PAM_MSG(pamh, 50,
"removing root credentials would break the rpc services that"));
sprintf(messages[1], PAM_MSG(pamh, 51,
"use secure rpc on this host!"));
sprintf(messages[2], PAM_MSG(pamh, 52,
"root may use keylogout -f to do this (at your own risk)!"));
__pam_display_msg(pamh, PAM_ERROR_MSG,
3, messages, NULL);
}
err = PAM_PERM_DENIED;
goto out;
}
if (key_setsecret(secret) < 0) {
if (!(flags & PAM_SILENT)) {
sprintf(messages[0], PAM_MSG(pamh, 53,
"Could not unset your secret key."));
sprintf(messages[1], PAM_MSG(pamh, 54,
"Maybe the keyserver is down?"));
__pam_display_msg(pamh, PAM_ERROR_MSG,
2, messages, NULL);
}
err = PAM_AUTH_ERR;
goto out;
}
nra.authtype = AUTH_DES; /* only revoke DES creds */
nra.uid = getuid(); /* use the real uid */
if (_nfssys(NFS_REVAUTH, &nra) < 0) {
if (!(flags & PAM_SILENT)) {
sprintf(messages[0], PAM_MSG(pamh, 55,
"Warning: NFS credentials not destroyed"));
__pam_display_msg(pamh, PAM_ERROR_MSG,
1, messages, NULL);
}
err = PAM_AUTH_ERR;
goto out;
}
#endif
err = PAM_SUCCESS;
} else {
#ifdef PAM_SECURE_RPC
/*
* Default case: PAM_ESTABLISH_CRED
* For unix, the keylogin was already done in
* unix_authenticate.c. Only print out the
* keylogin status here.
*/
if (!(flags & PAM_SILENT)) {
if (pam_get_data(pamh, UNIX_AUTH_DATA,
(void**)&status) == PAM_SUCCESS) {
switch (status->key_status) {
case ESTKEY_SUCCESS:
if (debug)
syslog(LOG_DEBUG,
"unix setcred successful");
case ESTKEY_ALREADY:
case ESTKEY_NOCREDENTIALS:
break;
case ESTKEY_BADPASSWD:
if (!(flags & PAM_SILENT)) {
sprintf(messages[0],
PAM_MSG(pamh, 56,
"Password does not decrypt secret key for %s."),
status->netname);
__pam_display_msg(
pamh,
PAM_ERROR_MSG, 1,
messages, NULL);
}
break;
case ESTKEY_CANTSETKEY:
if (!(flags & PAM_SILENT)) {
sprintf(messages[0],
PAM_MSG(pamh, 57,
"Could not set secret key for %s. The key server may be down."),
status->netname);
__pam_display_msg(
pamh,
PAM_ERROR_MSG, 1,
messages, NULL);
}
break;
}
} else {
if (debug)
syslog(LOG_DEBUG,
"pam_sm_setcred(): no module data");
}
}
#endif
err = PAM_SUCCESS;
}
out:
return (err);
}