Bring in a few useful PAM modules.
pam_krb5 is a Kerberos 5 (Heimdal) authentication module. pam_nologin checks for /etc/nologin and does the "usual stuff" if it is found, otherwise it silently succeeds. pam_rootok silently succeeds if the user is root, otherwise it fails. pam_wheel silently succeeds if the user is a member of group "wheel" (or another nominated group), and fails otherwise. There is an issue with kerberosIV and kerberos5 - if both are being built, then static linking fails with duplicate symbols. This will take a bit of work to sort out in the kerberii.
This commit is contained in:
parent
3abfa903d2
commit
84d6cd8ea1
@ -70,15 +70,18 @@ STATIC_MODULES+= ${MODOBJDIR}/pam_deny/libpam_deny.a
|
||||
.if defined(MAKE_KERBEROS4) && !defined(NOCRYPT) && !defined(NO_OPENSSL)
|
||||
STATIC_MODULES+= ${MODOBJDIR}/pam_kerberosIV/libpam_kerberosIV.a
|
||||
.endif
|
||||
.if defined(MAKE_KERBEROS5__) && !defined(NOCRYPT) && !defined(NO_OPENSSL)
|
||||
STATIC_MODULES+= ${MODOBJDIR}/pam_kerberos5/libpam_kerberos5.a
|
||||
.if defined(MAKE_KERBEROS5) && !defined(NOCRYPT) && !defined(NO_OPENSSL)
|
||||
STATIC_MODULES+= ${MODOBJDIR}/pam_krb5/libpam_krb5.a
|
||||
.endif
|
||||
STATIC_MODULES+= ${MODOBJDIR}/pam_nologin/libpam_nologin.a
|
||||
STATIC_MODULES+= ${MODOBJDIR}/pam_opie/libpam_opie.a
|
||||
STATIC_MODULES+= ${MODOBJDIR}/pam_permit/libpam_permit.a
|
||||
STATIC_MODULES+= ${MODOBJDIR}/pam_radius/libpam_radius.a
|
||||
STATIC_MODULES+= ${MODOBJDIR}/pam_rootok/libpam_rootok.a
|
||||
STATIC_MODULES+= ${MODOBJDIR}/pam_skey/libpam_skey.a
|
||||
STATIC_MODULES+= ${MODOBJDIR}/pam_tacplus/libpam_tacplus.a
|
||||
STATIC_MODULES+= ${MODOBJDIR}/pam_unix/libpam_unix.a
|
||||
STATIC_MODULES+= ${MODOBJDIR}/pam_wheel/libpam_wheel.a
|
||||
|
||||
STATICOBJS+= pam_static_modules.o
|
||||
CLEANFILES+= pam_static.o
|
||||
|
@ -29,14 +29,17 @@ SUBDIR+= pam_deny
|
||||
.if defined(MAKE_KERBEROS4) && !defined(NOCRYPT) && !defined(NO_OPENSSL)
|
||||
SUBDIR+= pam_kerberosIV
|
||||
.endif
|
||||
.if defined(MAKE_KERBEROS5__) && !defined(NOCRYPT) && !defined(NO_OPENSSL)
|
||||
SUBDIR+= pam_kerberos5
|
||||
.if defined(MAKE_KERBEROS5) && !defined(NOCRYPT) && !defined(NO_OPENSSL)
|
||||
SUBDIR+= pam_krb5
|
||||
.endif
|
||||
SUBDIR+= pam_nologin
|
||||
SUBDIR+= pam_opie
|
||||
SUBDIR+= pam_permit
|
||||
SUBDIR+= pam_radius
|
||||
SUBDIR+= pam_rootok
|
||||
SUBDIR+= pam_skey
|
||||
SUBDIR+= pam_tacplus
|
||||
SUBDIR+= pam_unix
|
||||
SUBDIR+= pam_wheel
|
||||
|
||||
.include <bsd.subdir.mk>
|
||||
|
195
lib/libpam/modules/pam_krb5/COPYRIGHT
Normal file
195
lib/libpam/modules/pam_krb5/COPYRIGHT
Normal file
@ -0,0 +1,195 @@
|
||||
pam_krb5:
|
||||
|
||||
$FreeBSD$
|
||||
|
||||
Copyright (c) Frank Cusack, 1999-2000.
|
||||
fcusack@fcusack.com
|
||||
All rights reserved
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, and the entire permission notice in its entirety,
|
||||
including the disclaimer of warranties.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. The name of the author may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
ALTERNATIVELY, this product may be distributed under the terms of
|
||||
the GNU Public License, in which case the provisions of the GPL are
|
||||
required INSTEAD OF the above restrictions. (This clause is
|
||||
necessary due to a potential bad interaction between the GPL and
|
||||
the restrictions contained in a BSD-style copyright.)
|
||||
|
||||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
This software may contain code from Naomaru Itoi:
|
||||
|
||||
PAM-kerberos5 module Copyright notice.
|
||||
Naomaru Itoi <itoi@eecs.umich.edu>, June 24, 1997.
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
COPYRIGHT (c) 1997
|
||||
THE REGENTS OF THE UNIVERSITY OF MICHIGAN
|
||||
ALL RIGHTS RESERVED
|
||||
|
||||
PERMISSION IS GRANTED TO USE, COPY, CREATE DERIVATIVE WORKS AND REDISTRIBUTE
|
||||
THIS SOFTWARE AND SUCH DERIVATIVE WORKS FOR ANY PURPOSE, SO LONG AS THE NAME
|
||||
OF THE UNIVERSITY OF MICHIGAN IS NOT USED IN ANY ADVERTISING OR PUBLICITY
|
||||
PERTAINING TO THE USE OR DISTRIBUTION OF THIS SOFTWARE WITHOUT SPECIFIC,
|
||||
WRITTEN PRIOR AUTHORIZATION. IF THE ABOVE COPYRIGHT NOTICE OR ANY OTHER
|
||||
IDENTIFICATION OF THE UNIVERSITY OF MICHIGAN IS INCLUDED IN ANY COPY OF ANY
|
||||
PORTION OF THIS SOFTWARE, THEN THE DISCLAIMER BELOW MUST ALSO BE INCLUDED.
|
||||
|
||||
THE SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE UNIVERSITY OF
|
||||
MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND WITHOUT WARRANTY BY THE
|
||||
UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||
WITHOUT LIMITATION THE IMPLIED WARRANTIES OF MERCHANTABITILY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE. THE REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE
|
||||
LIABLE FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
|
||||
CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING OUT OF OR IN
|
||||
CONNECTION WITH THE USE OF THE SOFTWARE, EVEN IF IT HAS BEEN OR IS HEREAFTER
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
PAM-kerberos5 module is written based on PAM-kerberos4 module
|
||||
by Derrick J. Brashear and kerberos5-1.0pl1 by M.I.T. kerberos team.
|
||||
Permission to use, copy, modify, distribute this software is hereby
|
||||
granted, as long as it is granted by Derrick J. Brashear and
|
||||
M.I.T. kerberos team. Followings are their copyright information.
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
This software may contain code from Derrick J. Brashear:
|
||||
|
||||
|
||||
Copyright (c) Derrick J. Brashear, 1996. All rights reserved
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, and the entire permission notice in its entirety,
|
||||
including the disclaimer of warranties.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. The name of the author may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
ALTERNATIVELY, this product may be distributed under the terms of
|
||||
the GNU Public License, in which case the provisions of the GPL are
|
||||
required INSTEAD OF the above restrictions. (This clause is
|
||||
necessary due to a potential bad interaction between the GPL and
|
||||
the restrictions contained in a BSD-style copyright.)
|
||||
|
||||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
This software may contain code from MIT Kerberos 5:
|
||||
|
||||
Copyright Notice and Legal Administrivia
|
||||
----------------------------------------
|
||||
|
||||
Copyright (C) 1996 by the Massachusetts Institute of Technology.
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Export of this software from the United States of America may require
|
||||
a specific license from the United States Government. It is the
|
||||
responsibility of any person or organization contemplating export to
|
||||
obtain such a license before exporting.
|
||||
|
||||
WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
|
||||
distribute this software and its documentation for any purpose and
|
||||
without fee is hereby granted, provided that the above copyright
|
||||
notice appear in all copies and that both that copyright notice and
|
||||
this permission notice appear in supporting documentation, and that
|
||||
the name of M.I.T. not be used in advertising or publicity pertaining
|
||||
to distribution of the software without specific, written prior
|
||||
permission. M.I.T. makes no representations about the suitability of
|
||||
this software for any purpose. It is provided "as is" without express
|
||||
or implied warranty.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
Individual source code files are copyright MIT, Cygnus Support,
|
||||
OpenVision, Oracle, Sun Soft, and others.
|
||||
|
||||
Project Athena, Athena, Athena MUSE, Discuss, Hesiod, Kerberos, Moira,
|
||||
and Zephyr are trademarks of the Massachusetts Institute of Technology
|
||||
(MIT). No commercial use of these trademarks may be made without
|
||||
prior written permission of MIT.
|
||||
|
||||
"Commercial use" means use of a name in a product or other for-profit
|
||||
manner. It does NOT prevent a commercial firm from referring to the
|
||||
MIT trademarks in order to convey information (although in doing so,
|
||||
recognition of their trademark status should be given).
|
||||
|
||||
The following copyright and permission notice applies to the
|
||||
OpenVision Kerberos Administration system located in kadmin/create,
|
||||
kadmin/dbutil, kadmin/passwd, kadmin/server, lib/kadm5, and portions
|
||||
of lib/rpc:
|
||||
|
||||
Copyright, OpenVision Technologies, Inc., 1996, All Rights Reserved
|
||||
|
||||
WARNING: Retrieving the OpenVision Kerberos Administration system
|
||||
source code, as described below, indicates your acceptance of the
|
||||
following terms. If you do not agree to the following terms, do not
|
||||
retrieve the OpenVision Kerberos administration system.
|
||||
|
||||
You may freely use and distribute the Source Code and Object Code
|
||||
compiled from it, with or without modification, but this Source
|
||||
Code is provided to you "AS IS" EXCLUSIVE OF ANY WARRANTY,
|
||||
INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY OR
|
||||
FITNESS FOR A PARTICULAR PURPOSE, OR ANY OTHER WARRANTY, WHETHER
|
||||
EXPRESS OR IMPLIED. IN NO EVENT WILL OPENVISION HAVE ANY LIABILITY
|
||||
FOR ANY LOST PROFITS, LOSS OF DATA OR COSTS OF PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES, OR FOR ANY SPECIAL, INDIRECT, OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, INCLUDING,
|
||||
WITHOUT LIMITATION, THOSE RESULTING FROM THE USE OF THE SOURCE
|
||||
CODE, OR THE FAILURE OF THE SOURCE CODE TO PERFORM, OR FOR ANY
|
||||
OTHER REASON.
|
||||
|
||||
OpenVision retains all copyrights in the donated Source Code. OpenVision
|
||||
also retains copyright to derivative works of the Source Code, whether
|
||||
created by OpenVision or by a third party. The OpenVision copyright
|
||||
notice must be preserved if derivative works are made based on the
|
||||
donated Source Code.
|
||||
|
||||
OpenVision Technologies, Inc. has donated this Kerberos
|
||||
Administration system to MIT for inclusion in the standard
|
||||
Kerberos 5 distribution. This donation underscores our
|
||||
commitment to continuing Kerberos technology development
|
||||
and our gratitude for the valuable work which has been
|
||||
performed by MIT and the Kerberos community.
|
||||
|
||||
|
44
lib/libpam/modules/pam_krb5/Makefile
Normal file
44
lib/libpam/modules/pam_krb5/Makefile
Normal file
@ -0,0 +1,44 @@
|
||||
# Copyright 2001 FreeBSD, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
# SUCH DAMAGE.
|
||||
#
|
||||
# $FreeBSD$
|
||||
|
||||
PAMDIR= ${.CURDIR}/../../../../contrib/libpam
|
||||
|
||||
LIB= pam_krb5
|
||||
SHLIB_NAME= pam_krb5.so
|
||||
SRCS= pam_krb5_auth.c pam_krb5_pass.c pam_krb5_acct.c \
|
||||
pam_krb5_sess.c support.c compat_heimdal.c
|
||||
CFLAGS+= -Wall
|
||||
CFLAGS+= -I${PAMDIR}/libpam/include
|
||||
CFLAGS+= -I${.CURDIR}/../../libpam
|
||||
DPADD+= ${LIBKRB5} ${LIBGSSAPI} ${LIBASN1} ${LIBCRYPTO} ${LIBCRYPT} \
|
||||
${LIBCOM_ERR}
|
||||
LDADD+= -lkrb5 -lgssapi -lasn1 -lroken -lcrypto -lcrypt -lcom_err \
|
||||
-L${.OBJDIR}/../../../../kerberos5/lib/libroken
|
||||
INTERNALLIB= yes
|
||||
INTERNALSTATICLIB=yes
|
||||
MAN= pam_krb5.8
|
||||
|
||||
.include <bsd.lib.mk>
|
72
lib/libpam/modules/pam_krb5/README
Normal file
72
lib/libpam/modules/pam_krb5/README
Normal file
@ -0,0 +1,72 @@
|
||||
$FreeBSD$
|
||||
|
||||
This is the README for pam_krb5, a PAM module which support Kerberos 5
|
||||
authentication.
|
||||
|
||||
This software is Copyright (c) 1999-2000 Frank Cusack.
|
||||
All Rights Reserved.
|
||||
|
||||
See the COPYRIGHT file, included with this distribution, for copyright
|
||||
and redistribution information.
|
||||
|
||||
Author:
|
||||
Frank Cusack
|
||||
<fcusack@fcusack.com>
|
||||
|
||||
|
||||
I. Kerberos notes
|
||||
|
||||
This PAM module requires the MIT 1.1+ release of Kerberos, or the Cygnus
|
||||
CNS distribution. It has not been tested against heimdal or any other
|
||||
Kerberos distributions.
|
||||
|
||||
Unlike other PAM Kerberos 5 modules out there, this one does not
|
||||
use any private Kerberos interfaces. Thus, you need only the
|
||||
header files and libraries that are part of the Kerberos distribution.
|
||||
|
||||
|
||||
II. OS notes
|
||||
|
||||
This software has been tested against Solaris 2.6. It should compile
|
||||
against Linux (distributions?) with minimal (if any) changes. Reports
|
||||
of OS [in]compatibilities are welcomed.
|
||||
|
||||
dtlogin on Solaris doesn't support xrealm logins (probably a good thing).
|
||||
|
||||
III. PAM notes/open issues
|
||||
|
||||
auth module:
|
||||
When is pam_sm_setcred() ever called with flags other than PAM_ESTABLISH_CRED
|
||||
or PAM_DELETE_CRED?
|
||||
|
||||
acct module:
|
||||
I believe this to be complete.
|
||||
|
||||
session module:
|
||||
This is complete (both functions just return success).
|
||||
|
||||
passwd module:
|
||||
When is pam_sm_chauthtok() ever called with flags other than
|
||||
PAM_UPDATE_AUTHTOK?
|
||||
|
||||
|
||||
IV. Usage
|
||||
|
||||
Simply change /etc/pam.conf to include this module. Make sure to include
|
||||
the acct category whenever you use the auth category, or .k5login will
|
||||
not get checked.
|
||||
|
||||
You probably want to make this module "sufficient", before your unix
|
||||
(or other) module(s).
|
||||
|
||||
|
||||
V. Acknowledgements
|
||||
|
||||
Thanks to Naomaru Itoi <itoi@eecs.umich.edu>,
|
||||
Curtis King <curtis.king@cul.ca>, and Derrick Brashear <shadow@dementia.org>,
|
||||
all of whom have written and made available Kerberos 4/5 modules.
|
||||
Although no code in this module is directly from these author's modules,
|
||||
(except the get_user_info() routine in support.c; derived from whichever
|
||||
of these authors originally wrote the first module the other 2 copied from),
|
||||
it was extremely helpful to look over their code which aided in my design.
|
||||
|
16
lib/libpam/modules/pam_krb5/TODO
Normal file
16
lib/libpam/modules/pam_krb5/TODO
Normal file
@ -0,0 +1,16 @@
|
||||
$FreeBSD$
|
||||
|
||||
Things for 1.1, in no particular order:
|
||||
|
||||
Check against Solaris 7, Solaris 8 beta. Check SEAM compatibility.
|
||||
Check against Linux (Redhat, others?).
|
||||
Check against HPUX.
|
||||
Fix PAM flags checking.
|
||||
Add more debugging for successful calls.
|
||||
Move "entry" debugging up.
|
||||
Check bounds on str* calls. [paranoia]
|
||||
|
||||
Get defaults from krb5.conf?
|
||||
** Allow no-xrealm, this module typically used for local login **
|
||||
** Add notes about runtime text relocation on Solaris **
|
||||
|
141
lib/libpam/modules/pam_krb5/compat_heimdal.c
Normal file
141
lib/libpam/modules/pam_krb5/compat_heimdal.c
Normal file
@ -0,0 +1,141 @@
|
||||
/*
|
||||
* compat_heimdal.c
|
||||
*
|
||||
* Heimdal compatability layer.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <krb5.h>
|
||||
#include <security/pam_appl.h>
|
||||
#include <security/pam_modules.h>
|
||||
#include "pam_krb5.h"
|
||||
|
||||
const char *
|
||||
compat_princ_component(krb5_context context, krb5_principal princ, int n)
|
||||
{
|
||||
return princ->name.name_string.val[n];
|
||||
}
|
||||
|
||||
void
|
||||
compat_free_data_contents(krb5_context context, krb5_data *data)
|
||||
{
|
||||
krb5_xfree(data->data);
|
||||
}
|
||||
|
||||
krb5_error_code
|
||||
compat_cc_next_cred(krb5_context context, const krb5_ccache id,
|
||||
krb5_cc_cursor *cursor, krb5_creds *creds)
|
||||
{
|
||||
return krb5_cc_next_cred(context, id, creds, cursor);
|
||||
}
|
||||
|
||||
|
||||
static krb5_error_code
|
||||
heimdal_pam_prompter(krb5_context context, void *data, const char *banner, int
|
||||
num_prompts, krb5_prompt prompts[])
|
||||
{
|
||||
int pam_prompts = num_prompts;
|
||||
int pamret, i;
|
||||
|
||||
struct pam_message *msg;
|
||||
struct pam_response *resp = NULL;
|
||||
struct pam_conv *conv;
|
||||
pam_handle_t *pamh = (pam_handle_t *) data;
|
||||
|
||||
if ((pamret = pam_get_item(pamh, PAM_CONV, (const void **) &conv)) != 0)
|
||||
return KRB5KRB_ERR_GENERIC;
|
||||
|
||||
if (banner)
|
||||
pam_prompts++;
|
||||
|
||||
msg = calloc(sizeof(struct pam_message) * pam_prompts, 1);
|
||||
if (!msg)
|
||||
return ENOMEM;
|
||||
|
||||
/* Now use pam_prompts as an index */
|
||||
pam_prompts = 0;
|
||||
|
||||
if (banner) {
|
||||
msg[pam_prompts].msg = malloc(strlen(banner) + 1);
|
||||
if (!msg[pam_prompts].msg)
|
||||
goto cleanup;
|
||||
strcpy((char *) msg[pam_prompts].msg, banner);
|
||||
msg[pam_prompts].msg_style = PAM_TEXT_INFO;
|
||||
pam_prompts++;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_prompts; i++) {
|
||||
msg[pam_prompts].msg = malloc(strlen(prompts[i].prompt) + 3);
|
||||
if (!msg[pam_prompts].msg)
|
||||
goto cleanup;
|
||||
sprintf((char *) msg[pam_prompts].msg, "%s: ", prompts[i].prompt);
|
||||
msg[pam_prompts].msg_style = prompts[i].hidden ? PAM_PROMPT_ECHO_OFF
|
||||
: PAM_PROMPT_ECHO_ON;
|
||||
pam_prompts++;
|
||||
}
|
||||
|
||||
if ((pamret = conv->conv(pam_prompts, (const struct pam_message **) &msg,
|
||||
&resp, conv->appdata_ptr)) != 0)
|
||||
goto cleanup;
|
||||
|
||||
if (!resp)
|
||||
goto cleanup;
|
||||
|
||||
/* Reuse pam_prompts as a starting index */
|
||||
pam_prompts = 0;
|
||||
if (banner)
|
||||
pam_prompts++;
|
||||
|
||||
for (i = 0; i < num_prompts; i++, pam_prompts++) {
|
||||
register int len;
|
||||
if (!resp[pam_prompts].resp) {
|
||||
pamret = PAM_AUTH_ERR;
|
||||
goto cleanup;
|
||||
}
|
||||
len = strlen(resp[pam_prompts].resp); /* Help out the compiler */
|
||||
if (len > prompts[i].reply->length) {
|
||||
pamret = PAM_AUTH_ERR;
|
||||
goto cleanup;
|
||||
}
|
||||
memcpy(prompts[i].reply->data, resp[pam_prompts].resp, len);
|
||||
prompts[i].reply->length = len;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
/* pam_prompts is correct at this point */
|
||||
|
||||
for (i = 0; i < pam_prompts; i++) {
|
||||
if (msg[i].msg)
|
||||
free((char *) msg[i].msg);
|
||||
}
|
||||
free(msg);
|
||||
|
||||
if (resp) {
|
||||
for (i = 0; i < pam_prompts; i++) {
|
||||
/*
|
||||
* Note that PAM is underspecified wrt free()'ing resp[i].resp.
|
||||
* It's not clear if I should free it, or if the application
|
||||
* has to. Therefore most (all?) apps won't free() it, and I
|
||||
* can't either, as I am not sure it was malloc()'d. All PAM
|
||||
* implementations I've seen leak memory here. Not so bad, IFF
|
||||
* you fork/exec for each PAM authentication (as is typical).
|
||||
*/
|
||||
#if 0
|
||||
if (resp[i].resp)
|
||||
free(resp[i].resp);
|
||||
#endif /* 0 */
|
||||
}
|
||||
/* This does not lose resp[i].resp if the application saved a copy. */
|
||||
free(resp);
|
||||
}
|
||||
|
||||
return (pamret ? KRB5KRB_ERR_GENERIC : 0);
|
||||
}
|
||||
|
||||
krb5_prompter_fct pam_prompter = heimdal_pam_prompter;
|
191
lib/libpam/modules/pam_krb5/pam_krb5.8
Normal file
191
lib/libpam/modules/pam_krb5/pam_krb5.8
Normal file
@ -0,0 +1,191 @@
|
||||
.\"
|
||||
.\" $Id: pam_krb5.5,v 1.5 2000/01/05 00:59:56 fcusack Exp $
|
||||
.\" $FreeBSD$
|
||||
.TH pam_krb5 8 "15 Jan 1999"
|
||||
.SH NAME
|
||||
pam_krb5 \- Kerberos 5 PAM module
|
||||
.SH SYNOPSIS
|
||||
.LP
|
||||
.B /usr/lib/pam_krb5.so
|
||||
.LP
|
||||
.SH DESCRIPTION
|
||||
.IX "pam_krb5" "" "\fLpam_krb5\fP \(em Kerberos 5 PAM module"
|
||||
.PP
|
||||
The Kerberos 5 service module for PAM, typically
|
||||
.BR /usr/lib/pam_krb5.so ,
|
||||
provides functionality for three PAM categories:
|
||||
authentication,
|
||||
account management,
|
||||
and password management.
|
||||
It also provides null functions for session management.
|
||||
The
|
||||
.B pam_krb5.so
|
||||
module is a shared object
|
||||
that can be dynamically loaded to provide
|
||||
the necessary functionality upon demand.
|
||||
Its path is specified in the
|
||||
.SM PAM
|
||||
configuration file.
|
||||
.SH Kerberos 5 Authentication Module
|
||||
The Kerberos 5 authentication component
|
||||
provides functions to verify the identity of a user.
|
||||
(\f3pam_sm_authenticate(\|)\f1)
|
||||
and to set user specific credentials
|
||||
(\f3pam_sm_setcred(\|)\f1).
|
||||
.B pam_sm_authenticate(\|)
|
||||
converts the supplied username into a Kerberos principal,
|
||||
by appending the default local realm name.
|
||||
It also supports usernames with explicit realm names.
|
||||
If a realm name is supplied, then upon a sucessful return, it
|
||||
changes the username by mapping the principal name into a local username
|
||||
(calling \f3krb5_aname_to_localname()\f1). This typically just means
|
||||
the realm name is stripped.
|
||||
.LP
|
||||
It prompts the user for a password and obtains a new Kerberos TGT for
|
||||
the principal. The TGT is verified by obtaining a service
|
||||
ticket for the local host.
|
||||
.LP
|
||||
When prompting for the current password, the authentication
|
||||
module will use the prompt "Password for <principal>: ".
|
||||
.LP
|
||||
The
|
||||
.B pam_sm_setcred(\|)
|
||||
function stores the newly acquired credentials in a credentials cache,
|
||||
and sets the environment variable
|
||||
.B KRB5CCNAME
|
||||
appropriately.
|
||||
The credentials cache should be destroyed by the user at logout with
|
||||
.BR kdestroy (1) .
|
||||
.LP
|
||||
The following options may be passed to the authentication module:
|
||||
.TP 15
|
||||
.B debug
|
||||
.BR syslog (3)
|
||||
debugging information at
|
||||
.SB LOG_DEBUG
|
||||
level.
|
||||
.TP
|
||||
.B use_first_pass
|
||||
If the authentication module is not the first in the stack,
|
||||
and a previous module obtained the user's password, that password is
|
||||
used to authenticate the user. If this fails, the authentication
|
||||
module returns failure without prompting the user for a password.
|
||||
This option has no effect if the authentication module is
|
||||
the first in the stack, or if no previous modules obtained the
|
||||
user's password.
|
||||
.TP
|
||||
.B try_first_pass
|
||||
This option is similar to the
|
||||
.B use_first_pass
|
||||
option, except that if the previously obtained password fails, the
|
||||
user is prompted for another password.
|
||||
.TP
|
||||
.B forwardable
|
||||
Obtain forwardable Kerberos credentials for the user.
|
||||
.TP
|
||||
.B no_ccache
|
||||
Do not save the obtained credentials in a credentials cache. This is a
|
||||
useful option if the authentication module is used for services such
|
||||
as ftp or pop, where the user would not be able to destroy them. [This
|
||||
is not a recommendation to use the module for those services.]
|
||||
.TP
|
||||
.B ccache=<name>
|
||||
Use <name> as the credentials cache. <name> must be in the form
|
||||
.IR type:residual .
|
||||
The special tokens
|
||||
.BR %u ,
|
||||
to designate the decimal uid of the user;
|
||||
and
|
||||
.BR %p ,
|
||||
to designate the current process id; can be used in <name>.
|
||||
.SH Kerberos 5 Account Management Module
|
||||
The Kerberos 5 account management component
|
||||
provides a function to perform account management,
|
||||
.BR pam_sm_acct_mgmt(\|) .
|
||||
The function verifies that the authenticated principal is allowed
|
||||
to login to the local user account by calling
|
||||
.B krb5_kuserok()
|
||||
(which checks the user's \&.k5login file).
|
||||
.SH Kerberos 5 Password Management Module
|
||||
The Kerberos 5 password management component
|
||||
provides a function to change passwords
|
||||
(\f3pam_sm_chauthtok(\|)\f1). The username supplied (the
|
||||
user running the
|
||||
.BR passwd (1)
|
||||
command, or the username given as an argument) is mapped into
|
||||
a Kerberos principal name, using the same technique as in
|
||||
the authentication module. Note that if a realm name was
|
||||
explicitly supplied during authentication, but not during
|
||||
a password change, the mapping
|
||||
done by the password management module may not result in the
|
||||
same principal as was used for authentication.
|
||||
.LP
|
||||
Unlike when
|
||||
changing a unix password, the password management module will
|
||||
allow any user to change any principal's password (if the user knows
|
||||
the principal's old password, of course). Also unlike unix, root
|
||||
is always prompted for the principal's old password.
|
||||
.LP
|
||||
The password management module uses the same heuristics as
|
||||
.BR kpasswd (1)
|
||||
to determine how to contact the Kerberos password server.
|
||||
.LP
|
||||
The following options may be passed to the password management
|
||||
module:
|
||||
.TP 15
|
||||
.B debug
|
||||
.BR syslog (3)
|
||||
debugging information at
|
||||
.SB LOG_DEBUG
|
||||
level.
|
||||
.TP
|
||||
.B use_first_pass
|
||||
If the password management module is not the first in the stack,
|
||||
and a previous module obtained the user's old password, that password is
|
||||
used to authenticate the user. If this fails, the password
|
||||
management
|
||||
module returns failure without prompting the user for the old password.
|
||||
If successful, the new password entered to the previous module is also
|
||||
used as the new Kerberos password. If the new password fails,
|
||||
the password management module returns failure without
|
||||
prompting the user for a new password.
|
||||
.TP
|
||||
.B try_first_pass
|
||||
This option is similar to the
|
||||
.B use_first_pass
|
||||
option, except that if the previously obtained old or new passwords fail,
|
||||
the user is prompted for them.
|
||||
.SH Kerberos 5 Session Management Module
|
||||
The Kerberos 5 session management component
|
||||
provides functions to initiate
|
||||
(\f3pam_sm_open_session(\|)\f1)
|
||||
and terminate
|
||||
(\f3pam_sm_close_session(\|)\f1)
|
||||
sessions. Since session management is not defined under Kerberos 5,
|
||||
both of these functions simply return success. They are provided
|
||||
only because of the naming conventions for PAM modules.
|
||||
.SH ENVIRONMENT
|
||||
.TP "\w'.SM KRB5CCNAME\ \ 'u"
|
||||
.SM KRB5CCNAME
|
||||
Location of the credentials cache.
|
||||
.SH FILES
|
||||
.TP "\w'/tmp/krb5cc_[uid]\ \ 'u"
|
||||
/tmp/krb5cc_[uid]
|
||||
default credentials cache ([uid] is the decimal UID of the user).
|
||||
.TP
|
||||
~/\&.k5login
|
||||
file containing Kerberos principals that are allowed access.
|
||||
.SH SEE ALSO
|
||||
.BR kdestroy (1),
|
||||
.BR passwd (1),
|
||||
.BR pam (8),
|
||||
.BR syslog (3),
|
||||
.BR pam.conf (5).
|
||||
.SH NOTES
|
||||
Applications should not call
|
||||
.B pam_authenticate()
|
||||
more than once between calls to
|
||||
.B pam_start()
|
||||
and
|
||||
.B pam_end()
|
||||
when using the Kerberos 5 PAM module.
|
23
lib/libpam/modules/pam_krb5/pam_krb5.h
Normal file
23
lib/libpam/modules/pam_krb5/pam_krb5.h
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* pam_krb5.h
|
||||
*
|
||||
* $Id: pam_krb5.h,v 1.5 1999/01/19 23:43:10 fcusack Exp $
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
int get_user_info(pam_handle_t *, char *, int, char **);
|
||||
int verify_krb_v5_tgt(krb5_context, krb5_ccache, char *, int);
|
||||
void cleanup_cache(pam_handle_t *, void *, int);
|
||||
|
||||
krb5_prompter_fct pam_prompter;
|
||||
|
||||
const char *compat_princ_component(krb5_context, krb5_principal, int);
|
||||
void compat_free_data_contents(krb5_context, krb5_data *);
|
||||
krb5_error_code compat_cc_next_cred(krb5_context, const krb5_ccache,
|
||||
krb5_cc_cursor *, krb5_creds *);
|
||||
|
||||
#ifndef ENCTYPE_DES_CBC_MD5
|
||||
#define ENCTYPE_DES_CBC_MD5 ETYPE_DES_CBC_MD5
|
||||
#endif
|
||||
|
||||
|
83
lib/libpam/modules/pam_krb5/pam_krb5_acct.c
Normal file
83
lib/libpam/modules/pam_krb5/pam_krb5_acct.c
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* pam_krb5_acct.c
|
||||
*
|
||||
* PAM account management functions for pam_krb5
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
static const char rcsid[] = "$Id: pam_krb5_acct.c,v 1.3 1999/01/19 21:26:44 fcusack Exp $";
|
||||
|
||||
#include <syslog.h> /* syslog */
|
||||
#include <security/pam_appl.h>
|
||||
#include <security/pam_modules.h>
|
||||
#include <krb5.h>
|
||||
#include <com_err.h>
|
||||
#include "pam_krb5.h"
|
||||
|
||||
/* A useful logging macro */
|
||||
#define DLOG(error_func, error_msg) \
|
||||
if (debug) \
|
||||
syslog(LOG_DEBUG, "pam_krb5: pam_sm_acct_mgmt(%s %s): %s: %s", \
|
||||
service, name, error_func, error_msg)
|
||||
|
||||
/* Check authorization of user */
|
||||
int
|
||||
pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv)
|
||||
{
|
||||
krb5_error_code krbret;
|
||||
krb5_context pam_context;
|
||||
krb5_ccache ccache;
|
||||
krb5_principal princ;
|
||||
|
||||
char *service, *name;
|
||||
int debug = 0;
|
||||
int i, pamret;
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
if (strcmp(argv[i], "debug") == 0)
|
||||
debug = 1;
|
||||
}
|
||||
|
||||
/* Get username */
|
||||
if (pam_get_item(pamh, PAM_USER, (const void **) &name)) {
|
||||
return PAM_PERM_DENIED;;
|
||||
}
|
||||
|
||||
/* Get service name */
|
||||
(void) pam_get_item(pamh, PAM_SERVICE, (const void **) &service);
|
||||
if (!service)
|
||||
service = "unknown";
|
||||
|
||||
DLOG("entry", "");
|
||||
|
||||
if (pam_get_data(pamh, "ccache", (const void **) &ccache)) {
|
||||
/* User did not use krb5 to login */
|
||||
DLOG("ccache", "not found");
|
||||
return PAM_SUCCESS;
|
||||
}
|
||||
|
||||
if ((krbret = krb5_init_context(&pam_context)) != 0) {
|
||||
DLOG("krb5_init_context()", error_message(krbret));
|
||||
return PAM_PERM_DENIED;;
|
||||
}
|
||||
|
||||
if ((krbret = krb5_cc_get_principal(pam_context, ccache, &princ)) != 0) {
|
||||
DLOG("krb5_cc_get_principal()", error_message(krbret));
|
||||
pamret = PAM_PERM_DENIED;;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (krb5_kuserok(pam_context, princ, name))
|
||||
pamret = PAM_SUCCESS;
|
||||
else
|
||||
pamret = PAM_PERM_DENIED;
|
||||
krb5_free_principal(pam_context, princ);
|
||||
|
||||
cleanup:
|
||||
krb5_free_context(pam_context);
|
||||
DLOG("exit", pamret ? "failure" : "success");
|
||||
return pamret;
|
||||
|
||||
}
|
||||
|
505
lib/libpam/modules/pam_krb5/pam_krb5_auth.c
Normal file
505
lib/libpam/modules/pam_krb5/pam_krb5_auth.c
Normal file
@ -0,0 +1,505 @@
|
||||
/*
|
||||
* pam_krb5_auth.c
|
||||
*
|
||||
* PAM authentication management functions for pam_krb5
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
static const char rcsid[] = "$Id: pam_krb5_auth.c,v 1.18 2000/01/04 08:44:08 fcusack Exp $";
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h> /* PATH_MAX */
|
||||
#include <pwd.h> /* getpwnam */
|
||||
#include <stdio.h> /* tmpnam */
|
||||
#include <stdlib.h> /* malloc */
|
||||
#include <strings.h> /* strchr */
|
||||
#include <syslog.h> /* syslog */
|
||||
#include <unistd.h> /* chown */
|
||||
|
||||
#include <security/pam_appl.h>
|
||||
#include <security/pam_modules.h>
|
||||
|
||||
#include <krb5.h>
|
||||
#include <com_err.h>
|
||||
#include "pam_krb5.h"
|
||||
|
||||
extern krb5_cc_ops krb5_mcc_ops;
|
||||
|
||||
/* A useful logging macro */
|
||||
#define DLOG(error_func, error_msg) \
|
||||
if (debug) \
|
||||
syslog(LOG_DEBUG, "pam_krb5: pam_sm_authenticate(%s %s): %s: %s", \
|
||||
service, name, error_func, error_msg)
|
||||
|
||||
/* Authenticate a user via krb5 */
|
||||
int
|
||||
pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc,
|
||||
const char **argv)
|
||||
{
|
||||
krb5_error_code krbret;
|
||||
krb5_context pam_context;
|
||||
krb5_creds creds;
|
||||
krb5_principal princ;
|
||||
krb5_ccache ccache, ccache_check;
|
||||
krb5_get_init_creds_opt opts;
|
||||
|
||||
int pamret, i;
|
||||
const char *name;
|
||||
char *source_princ = NULL;
|
||||
char *princ_name = NULL;
|
||||
char *pass = NULL, *service = NULL;
|
||||
char *prompt = NULL;
|
||||
char cache_name[L_tmpnam + 8];
|
||||
char lname[64]; /* local acct name */
|
||||
struct passwd *pw;
|
||||
uid_t ruid;
|
||||
|
||||
int debug = 0, try_first_pass = 0, use_first_pass = 0;
|
||||
int forwardable = 0, reuse_ccache = 0, no_ccache = 0;
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
if (strcmp(argv[i], "debug") == 0)
|
||||
debug = 1;
|
||||
else if (strcmp(argv[i], "try_first_pass") == 0)
|
||||
try_first_pass = 1;
|
||||
else if (strcmp(argv[i], "use_first_pass") == 0)
|
||||
use_first_pass = 1;
|
||||
else if (strcmp(argv[i], "forwardable") == 0)
|
||||
forwardable = 1;
|
||||
else if (strcmp(argv[i], "reuse_ccache") == 0)
|
||||
reuse_ccache = 1;
|
||||
else if (strcmp(argv[i], "no_ccache") == 0)
|
||||
no_ccache = 1;
|
||||
}
|
||||
|
||||
/* Get username */
|
||||
if ((pamret = pam_get_user(pamh, &name, "login: ")) != PAM_SUCCESS) {
|
||||
return PAM_SERVICE_ERR;
|
||||
}
|
||||
|
||||
/* Get service name */
|
||||
(void) pam_get_item(pamh, PAM_SERVICE, (const void **) &service);
|
||||
if (!service)
|
||||
service = "unknown";
|
||||
|
||||
DLOG("entry", "");
|
||||
|
||||
if ((krbret = krb5_init_context(&pam_context)) != 0) {
|
||||
DLOG("krb5_init_context()", error_message(krbret));
|
||||
return PAM_SERVICE_ERR;
|
||||
}
|
||||
krb5_get_init_creds_opt_init(&opts);
|
||||
memset(&creds, 0, sizeof(krb5_creds));
|
||||
memset(cache_name, 0, sizeof(cache_name));
|
||||
memset(lname, 0, sizeof(lname));
|
||||
|
||||
if (forwardable)
|
||||
krb5_get_init_creds_opt_set_forwardable(&opts, 1);
|
||||
|
||||
/* For CNS */
|
||||
if ((krbret = krb5_cc_register(pam_context, &krb5_mcc_ops, FALSE)) != 0) {
|
||||
/* Solaris dtlogin doesn't call pam_end() on failure */
|
||||
if (krbret != KRB5_CC_TYPE_EXISTS) {
|
||||
DLOG("krb5_cc_register()", error_message(krbret));
|
||||
pamret = PAM_SERVICE_ERR;
|
||||
goto cleanup3;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get principal name */
|
||||
/* This case is for use mainly by su.
|
||||
If non-root is authenticating as "root", use "source_user/root". */
|
||||
if (!strcmp(name, "root") && (ruid = getuid()) != 0) {
|
||||
pw = getpwuid(ruid);
|
||||
if (pw != NULL)
|
||||
source_princ = (char *)malloc(strlen(pw->pw_name) + 6);
|
||||
if (source_princ)
|
||||
sprintf(source_princ, "%s/root", pw->pw_name);
|
||||
} else {
|
||||
source_princ = strdup(name);
|
||||
}
|
||||
if (!source_princ) {
|
||||
DLOG("malloc()", "failure");
|
||||
pamret = PAM_BUF_ERR;
|
||||
goto cleanup2;
|
||||
}
|
||||
|
||||
if ((krbret = krb5_parse_name(pam_context, source_princ, &princ)) != 0) {
|
||||
DLOG("krb5_parse_name()", error_message(krbret));
|
||||
pamret = PAM_SERVICE_ERR;
|
||||
goto cleanup3;
|
||||
}
|
||||
|
||||
/* Now convert the principal name into something human readable */
|
||||
if ((krbret = krb5_unparse_name(pam_context, princ, &princ_name)) != 0) {
|
||||
DLOG("krb5_unparse_name()", error_message(krbret));
|
||||
pamret = PAM_SERVICE_ERR;
|
||||
goto cleanup2;
|
||||
}
|
||||
|
||||
/* Get password */
|
||||
prompt = malloc(16 + strlen(princ_name));
|
||||
if (!prompt) {
|
||||
DLOG("malloc()", "failure");
|
||||
pamret = PAM_BUF_ERR;
|
||||
goto cleanup2;
|
||||
}
|
||||
(void) sprintf(prompt, "Password for %s: ", princ_name);
|
||||
|
||||
if (try_first_pass || use_first_pass)
|
||||
(void) pam_get_item(pamh, PAM_AUTHTOK, (const void **) &pass);
|
||||
|
||||
get_pass:
|
||||
if (!pass) {
|
||||
try_first_pass = 0;
|
||||
if ((pamret = get_user_info(pamh, prompt, PAM_PROMPT_ECHO_OFF,
|
||||
&pass)) != 0) {
|
||||
DLOG("get_user_info()", pam_strerror(pamh, pamret));
|
||||
pamret = PAM_SERVICE_ERR;
|
||||
goto cleanup2;
|
||||
}
|
||||
/* We have to free pass. */
|
||||
if ((pamret = pam_set_item(pamh, PAM_AUTHTOK, pass)) != 0) {
|
||||
DLOG("pam_set_item()", pam_strerror(pamh, pamret));
|
||||
free(pass);
|
||||
pamret = PAM_SERVICE_ERR;
|
||||
goto cleanup2;
|
||||
}
|
||||
free(pass);
|
||||
/* Now we get it back from the library. */
|
||||
(void) pam_get_item(pamh, PAM_AUTHTOK, (const void **) &pass);
|
||||
}
|
||||
|
||||
/* get a local account name for this principal */
|
||||
if ((krbret = krb5_aname_to_localname(pam_context, princ,
|
||||
sizeof(lname), lname)) == 0) {
|
||||
DLOG("changing PAM_USER to", lname);
|
||||
if ((pamret = pam_set_item(pamh, PAM_USER, lname)) != 0) {
|
||||
DLOG("pam_set_item()", pam_strerror(pamh, pamret));
|
||||
pamret = PAM_SERVICE_ERR;
|
||||
goto cleanup2;
|
||||
}
|
||||
if ((pamret = pam_get_item(pamh, PAM_USER, (const void **) &name)
|
||||
!= 0)) {
|
||||
DLOG("pam_get_item()", pam_strerror(pamh, pamret));
|
||||
pamret = PAM_SERVICE_ERR;
|
||||
goto cleanup2;
|
||||
}
|
||||
} else {
|
||||
DLOG("krb5_aname_to_localname()", error_message(krbret));
|
||||
/* Not an error. */
|
||||
}
|
||||
|
||||
/* Verify the local user exists (AFTER getting the password) */
|
||||
pw = getpwnam(name);
|
||||
if (!pw) {
|
||||
DLOG("getpwnam()", lname);
|
||||
pamret = PAM_USER_UNKNOWN;
|
||||
goto cleanup2;
|
||||
}
|
||||
|
||||
/* Get a TGT */
|
||||
if ((krbret = krb5_get_init_creds_password(pam_context, &creds, princ,
|
||||
pass, pam_prompter, pamh, 0, NULL, &opts)) != 0) {
|
||||
DLOG("krb5_get_init_creds_password()", error_message(krbret));
|
||||
if (try_first_pass && krbret == KRB5KRB_AP_ERR_BAD_INTEGRITY) {
|
||||
pass = NULL;
|
||||
goto get_pass;
|
||||
}
|
||||
pamret = PAM_AUTH_ERR;
|
||||
goto cleanup2;
|
||||
}
|
||||
|
||||
/* Generate a unique cache_name */
|
||||
strcpy(cache_name, "MEMORY:");
|
||||
(void) tmpnam(&cache_name[7]);
|
||||
|
||||
if ((krbret = krb5_cc_resolve(pam_context, cache_name, &ccache)) != 0) {
|
||||
DLOG("krb5_cc_resolve()", error_message(krbret));
|
||||
pamret = PAM_SERVICE_ERR;
|
||||
goto cleanup;
|
||||
}
|
||||
if ((krbret = krb5_cc_initialize(pam_context, ccache, princ)) != 0) {
|
||||
DLOG("krb5_cc_initialize()", error_message(krbret));
|
||||
pamret = PAM_SERVICE_ERR;
|
||||
goto cleanup;
|
||||
}
|
||||
if ((krbret = krb5_cc_store_cred(pam_context, ccache, &creds)) != 0) {
|
||||
DLOG("krb5_cc_store_cred()", error_message(krbret));
|
||||
(void) krb5_cc_destroy(pam_context, ccache);
|
||||
pamret = PAM_SERVICE_ERR;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Verify it */
|
||||
if (verify_krb_v5_tgt(pam_context, ccache, service, debug) == -1) {
|
||||
(void) krb5_cc_destroy(pam_context, ccache);
|
||||
pamret = PAM_AUTH_ERR;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* A successful authentication, store ccache for sm_setcred() */
|
||||
if (!pam_get_data(pamh, "ccache", (const void **) &ccache_check)) {
|
||||
DLOG("pam_get_data()", "ccache data already present");
|
||||
(void) krb5_cc_destroy(pam_context, ccache);
|
||||
pamret = PAM_AUTH_ERR;
|
||||
goto cleanup;
|
||||
}
|
||||
if ((pamret = pam_set_data(pamh, "ccache", ccache, cleanup_cache)) != 0) {
|
||||
DLOG("pam_set_data()", pam_strerror(pamh, pamret));
|
||||
(void) krb5_cc_destroy(pam_context, ccache);
|
||||
pamret = PAM_SERVICE_ERR;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
krb5_free_cred_contents(pam_context, &creds);
|
||||
cleanup2:
|
||||
krb5_free_principal(pam_context, princ);
|
||||
cleanup3:
|
||||
if (prompt)
|
||||
free(prompt);
|
||||
if (princ_name)
|
||||
free(princ_name);
|
||||
if (source_princ)
|
||||
free(source_princ);
|
||||
|
||||
krb5_free_context(pam_context);
|
||||
DLOG("exit", pamret ? "failure" : "success");
|
||||
return pamret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* redefine this for pam_sm_setcred() */
|
||||
#undef DLOG
|
||||
#define DLOG(error_func, error_msg) \
|
||||
if (debug) \
|
||||
syslog(LOG_DEBUG, "pam_krb5: pam_sm_setcred(%s %s): %s: %s", \
|
||||
service, name, error_func, error_msg)
|
||||
|
||||
/* Called after a successful authentication. Set user credentials. */
|
||||
int
|
||||
pam_sm_setcred(pam_handle_t *pamh, int flags, int argc,
|
||||
const char **argv)
|
||||
{
|
||||
|
||||
krb5_error_code krbret;
|
||||
krb5_context pam_context;
|
||||
krb5_principal princ;
|
||||
krb5_creds creds;
|
||||
krb5_ccache ccache_temp, ccache_perm;
|
||||
krb5_cc_cursor cursor;
|
||||
|
||||
int i, pamret;
|
||||
char *name, *service = NULL;
|
||||
char *cache_name = NULL, *cache_env_name;
|
||||
struct passwd *pw = NULL;
|
||||
|
||||
int debug = 0;
|
||||
uid_t euid;
|
||||
gid_t egid;
|
||||
|
||||
if (flags == PAM_REINITIALIZE_CRED)
|
||||
return PAM_SUCCESS; /* XXX Incorrect behavior */
|
||||
|
||||
if (flags != PAM_ESTABLISH_CRED && flags != PAM_DELETE_CRED)
|
||||
return PAM_SERVICE_ERR;
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
if (strcmp(argv[i], "debug") == 0)
|
||||
debug = 1;
|
||||
else if (strcmp(argv[i], "no_ccache") == 0)
|
||||
return PAM_SUCCESS;
|
||||
else if (strstr(argv[i], "ccache=") == argv[i])
|
||||
cache_name = (char *) &argv[i][7]; /* save for later */
|
||||
}
|
||||
|
||||
/* Get username */
|
||||
if (pam_get_item(pamh, PAM_USER, (const void **) &name)) {
|
||||
return PAM_SERVICE_ERR;
|
||||
}
|
||||
|
||||
/* Get service name */
|
||||
(void) pam_get_item(pamh, PAM_SERVICE, (const void **) &service);
|
||||
if (!service)
|
||||
service = "unknown";
|
||||
|
||||
DLOG("entry", "");
|
||||
|
||||
if ((krbret = krb5_init_context(&pam_context)) != 0) {
|
||||
DLOG("krb5_init_context()", error_message(krbret));
|
||||
return PAM_SERVICE_ERR;
|
||||
}
|
||||
|
||||
euid = geteuid(); /* Usually 0 */
|
||||
egid = getegid();
|
||||
|
||||
/* Retrieve the cache name */
|
||||
if ((pamret = pam_get_data(pamh, "ccache", (const void **) &ccache_temp))
|
||||
!= 0) {
|
||||
/* User did not use krb5 to login */
|
||||
DLOG("ccache", "not found");
|
||||
pamret = PAM_SUCCESS;
|
||||
goto cleanup3;
|
||||
}
|
||||
|
||||
/* Get the uid. This should exist. */
|
||||
pw = getpwnam(name);
|
||||
if (!pw) {
|
||||
DLOG("getpwnam()", name);
|
||||
pamret = PAM_USER_UNKNOWN;
|
||||
goto cleanup3;
|
||||
}
|
||||
|
||||
/* Avoid following a symlink as root */
|
||||
if (setegid(pw->pw_gid)) {
|
||||
DLOG("setegid()", name); /* XXX should really log group name or id */
|
||||
pamret = PAM_SERVICE_ERR;
|
||||
goto cleanup3;
|
||||
}
|
||||
if (seteuid(pw->pw_uid)) {
|
||||
DLOG("seteuid()", name);
|
||||
pamret = PAM_SERVICE_ERR;
|
||||
goto cleanup3;
|
||||
}
|
||||
|
||||
/* Get the cache name */
|
||||
if (!cache_name) {
|
||||
cache_name = malloc(64); /* plenty big */
|
||||
if (!cache_name) {
|
||||
DLOG("malloc()", "failure");
|
||||
pamret = PAM_BUF_ERR;
|
||||
goto cleanup3;
|
||||
}
|
||||
sprintf(cache_name, "FILE:/tmp/krb5cc_%d", pw->pw_uid);
|
||||
} else {
|
||||
/* cache_name was supplied */
|
||||
char *p = calloc(PATH_MAX + 10, 1); /* should be plenty */
|
||||
char *q = cache_name;
|
||||
if (!p) {
|
||||
DLOG("malloc()", "failure");
|
||||
pamret = PAM_BUF_ERR;
|
||||
goto cleanup3;
|
||||
}
|
||||
cache_name = p;
|
||||
|
||||
/* convert %u and %p */
|
||||
while (*q) {
|
||||
if (*q == '%') {
|
||||
q++;
|
||||
if (*q == 'u') {
|
||||
sprintf(p, "%d", pw->pw_uid);
|
||||
p += strlen(p);
|
||||
} else if (*q == 'p') {
|
||||
sprintf(p, "%d", getpid());
|
||||
p += strlen(p);
|
||||
} else {
|
||||
/* Not a special token */
|
||||
*p++ = '%';
|
||||
q--;
|
||||
}
|
||||
q++;
|
||||
} else {
|
||||
*p++ = *q++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((krbret = krb5_cc_resolve(pam_context, cache_name, &ccache_perm))
|
||||
!= 0) {
|
||||
DLOG("krb5_cc_resolve()", error_message(krbret));
|
||||
pamret = PAM_SERVICE_ERR;
|
||||
goto cleanup3;
|
||||
}
|
||||
if (flags == PAM_ESTABLISH_CRED) {
|
||||
/* Initialize the new ccache */
|
||||
if ((krbret = krb5_cc_get_principal(pam_context, ccache_temp, &princ))
|
||||
!= 0) {
|
||||
DLOG("krb5_cc_get_principal()", error_message(krbret));
|
||||
pamret = PAM_SERVICE_ERR;
|
||||
goto cleanup3;
|
||||
}
|
||||
if ((krbret = krb5_cc_initialize(pam_context, ccache_perm, princ)) != 0) {
|
||||
DLOG("krb5_cc_initialize()", error_message(krbret));
|
||||
pamret = PAM_SERVICE_ERR;
|
||||
goto cleanup2;
|
||||
}
|
||||
|
||||
/* Prepare for iteration over creds */
|
||||
if ((krbret = krb5_cc_start_seq_get(pam_context, ccache_temp, &cursor))
|
||||
!= 0) {
|
||||
DLOG("krb5_cc_start_seq_get()", error_message(krbret));
|
||||
(void) krb5_cc_destroy(pam_context, ccache_perm);
|
||||
pamret = PAM_SERVICE_ERR;
|
||||
goto cleanup2;
|
||||
}
|
||||
|
||||
/* Copy the creds (should be two of them) */
|
||||
while ((krbret = compat_cc_next_cred(pam_context, ccache_temp,
|
||||
&cursor, &creds) == 0)) {
|
||||
if ((krbret = krb5_cc_store_cred(pam_context, ccache_perm,
|
||||
&creds)) != 0) {
|
||||
DLOG("krb5_cc_store_cred()", error_message(krbret));
|
||||
(void) krb5_cc_destroy(pam_context, ccache_perm);
|
||||
krb5_free_cred_contents(pam_context, &creds);
|
||||
pamret = PAM_SERVICE_ERR;
|
||||
goto cleanup2;
|
||||
}
|
||||
krb5_free_cred_contents(pam_context, &creds);
|
||||
}
|
||||
(void) krb5_cc_end_seq_get(pam_context, ccache_temp, &cursor);
|
||||
|
||||
if (strstr(cache_name, "FILE:") == cache_name) {
|
||||
if (chown(&cache_name[5], pw->pw_uid, pw->pw_gid) == -1) {
|
||||
DLOG("chown()", strerror(errno));
|
||||
(void) krb5_cc_destroy(pam_context, ccache_perm);
|
||||
pamret = PAM_SERVICE_ERR;
|
||||
goto cleanup2;
|
||||
}
|
||||
if (chmod(&cache_name[5], (S_IRUSR|S_IWUSR)) == -1) {
|
||||
DLOG("chmod()", strerror(errno));
|
||||
(void) krb5_cc_destroy(pam_context, ccache_perm);
|
||||
pamret = PAM_SERVICE_ERR;
|
||||
goto cleanup2;
|
||||
}
|
||||
}
|
||||
(void) krb5_cc_close(pam_context, ccache_perm);
|
||||
|
||||
cache_env_name = malloc(strlen(cache_name) + 12);
|
||||
if (!cache_env_name) {
|
||||
DLOG("malloc()", "failure");
|
||||
(void) krb5_cc_destroy(pam_context, ccache_perm);
|
||||
pamret = PAM_BUF_ERR;
|
||||
goto cleanup2;
|
||||
}
|
||||
|
||||
sprintf(cache_env_name, "KRB5CCNAME=%s", cache_name);
|
||||
if ((pamret = pam_putenv(pamh, cache_env_name)) != 0) {
|
||||
DLOG("pam_putenv()", pam_strerror(pamh, pamret));
|
||||
(void) krb5_cc_destroy(pam_context, ccache_perm);
|
||||
pamret = PAM_SERVICE_ERR;
|
||||
goto cleanup2;
|
||||
}
|
||||
} else {
|
||||
/* flag == PAM_DELETE_CRED */
|
||||
if ((krbret = krb5_cc_destroy(pam_context, ccache_perm)) != 0) {
|
||||
/* log error, but otherwise ignore it */
|
||||
DLOG("krb5_cc_destroy()", error_message(krbret));
|
||||
}
|
||||
goto cleanup3;
|
||||
}
|
||||
|
||||
cleanup2:
|
||||
krb5_free_principal(pam_context, princ);
|
||||
cleanup3:
|
||||
krb5_free_context(pam_context);
|
||||
DLOG("exit", pamret ? "failure" : "success");
|
||||
(void) seteuid(euid);
|
||||
(void) setegid(egid);
|
||||
return pamret;
|
||||
}
|
||||
|
200
lib/libpam/modules/pam_krb5/pam_krb5_pass.c
Normal file
200
lib/libpam/modules/pam_krb5/pam_krb5_pass.c
Normal file
@ -0,0 +1,200 @@
|
||||
/*
|
||||
* pam_krb5_pass.c
|
||||
*
|
||||
* PAM password management functions for pam_krb5
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
static const char rcsid[] = "$Id: pam_krb5_pass.c,v 1.3 1999/01/19 23:43:11 fcusack Exp $";
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h> /* sprintf */
|
||||
#include <stdlib.h> /* malloc */
|
||||
#include <syslog.h> /* syslog */
|
||||
#include <security/pam_appl.h>
|
||||
#include <security/pam_modules.h>
|
||||
#include <krb5.h>
|
||||
#include <com_err.h>
|
||||
#include "pam_krb5.h"
|
||||
|
||||
/* A useful logging macro */
|
||||
#define DLOG(error_func, error_msg) \
|
||||
if (debug) \
|
||||
syslog(LOG_DEBUG, "pam_krb5: pam_sm_chauthtok(%s %s): %s: %s", \
|
||||
service, name, error_func, error_msg)
|
||||
|
||||
/* Change a user's password */
|
||||
int
|
||||
pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv)
|
||||
{
|
||||
krb5_error_code krbret;
|
||||
krb5_context pam_context;
|
||||
krb5_creds creds;
|
||||
krb5_principal princ;
|
||||
krb5_get_init_creds_opt opts;
|
||||
|
||||
int result_code;
|
||||
krb5_data result_code_string, result_string;
|
||||
|
||||
int pamret, i;
|
||||
char *name, *service = NULL, *pass = NULL, *pass2;
|
||||
char *princ_name = NULL;
|
||||
char *prompt = NULL;
|
||||
|
||||
int debug = 0;
|
||||
int try_first_pass = 0, use_first_pass = 0;
|
||||
|
||||
if (!(flags & PAM_UPDATE_AUTHTOK))
|
||||
return PAM_AUTHTOK_ERR;
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
if (strcmp(argv[i], "debug") == 0)
|
||||
debug = 1;
|
||||
else if (strcmp(argv[i], "try_first_pass") == 0)
|
||||
try_first_pass = 1;
|
||||
else if (strcmp(argv[i], "use_first_pass") == 0)
|
||||
use_first_pass = 1;
|
||||
}
|
||||
|
||||
/* Get username */
|
||||
if ((pam_get_item(pamh, PAM_USER, (const void **) &name)) != 0) {
|
||||
return PAM_SERVICE_ERR;
|
||||
}
|
||||
|
||||
/* Get service name */
|
||||
(void) pam_get_item(pamh, PAM_SERVICE, (const void **) &service);
|
||||
if (!service)
|
||||
service = "unknown";
|
||||
|
||||
DLOG("entry", "");
|
||||
|
||||
if ((krbret = krb5_init_context(&pam_context)) != 0) {
|
||||
DLOG("krb5_init_context()", error_message(krbret));
|
||||
return PAM_SERVICE_ERR;
|
||||
}
|
||||
|
||||
if ((krbret = krb5_init_context(&pam_context)) != 0) {
|
||||
DLOG("krb5_init_context()", error_message(krbret));
|
||||
return PAM_SERVICE_ERR;
|
||||
}
|
||||
krb5_get_init_creds_opt_init(&opts);
|
||||
memset(&creds, 0, sizeof(krb5_creds));
|
||||
|
||||
/* Get principal name */
|
||||
if ((krbret = krb5_parse_name(pam_context, name, &princ)) != 0) {
|
||||
DLOG("krb5_parse_name()", error_message(krbret));
|
||||
pamret = PAM_USER_UNKNOWN;
|
||||
goto cleanup3;
|
||||
}
|
||||
|
||||
/* Now convert the principal name into something human readable */
|
||||
if ((krbret = krb5_unparse_name(pam_context, princ, &princ_name)) != 0) {
|
||||
DLOG("krb5_unparse_name()", error_message(krbret));
|
||||
pamret = PAM_SERVICE_ERR;
|
||||
goto cleanup2;
|
||||
}
|
||||
|
||||
/* Get password */
|
||||
prompt = malloc(16 + strlen(princ_name));
|
||||
if (!prompt) {
|
||||
DLOG("malloc()", "failure");
|
||||
pamret = PAM_BUF_ERR;
|
||||
goto cleanup2;
|
||||
}
|
||||
(void) sprintf(prompt, "Password for %s: ", princ_name);
|
||||
|
||||
if (try_first_pass || use_first_pass)
|
||||
(void) pam_get_item(pamh, PAM_AUTHTOK, (const void **) &pass);
|
||||
|
||||
get_pass:
|
||||
if (!pass) {
|
||||
try_first_pass = 0;
|
||||
if ((pamret = get_user_info(pamh, prompt, PAM_PROMPT_ECHO_OFF,
|
||||
&pass)) != 0) {
|
||||
DLOG("get_user_info()", pam_strerror(pamh, pamret));
|
||||
pamret = PAM_SERVICE_ERR;
|
||||
goto cleanup2;
|
||||
}
|
||||
/* We have to free pass. */
|
||||
if ((pamret = pam_set_item(pamh, PAM_AUTHTOK, pass)) != 0) {
|
||||
DLOG("pam_set_item()", pam_strerror(pamh, pamret));
|
||||
free(pass);
|
||||
pamret = PAM_SERVICE_ERR;
|
||||
goto cleanup2;
|
||||
}
|
||||
free(pass);
|
||||
/* Now we get it back from the library. */
|
||||
(void) pam_get_item(pamh, PAM_AUTHTOK, (const void **) &pass);
|
||||
}
|
||||
|
||||
if ((krbret = krb5_get_init_creds_password(pam_context, &creds, princ,
|
||||
pass, pam_prompter, pamh, 0, "kadmin/changepw", &opts)) != 0) {
|
||||
DLOG("krb5_get_init_creds_password()", error_message(krbret));
|
||||
if (try_first_pass && krbret == KRB5KRB_AP_ERR_BAD_INTEGRITY) {
|
||||
pass = NULL;
|
||||
goto get_pass;
|
||||
}
|
||||
pamret = PAM_AUTH_ERR;
|
||||
goto cleanup2;
|
||||
}
|
||||
|
||||
/* Now get the new password */
|
||||
free(prompt);
|
||||
prompt = "Enter new password: ";
|
||||
if ((pamret = get_user_info(pamh, prompt, PAM_PROMPT_ECHO_OFF, &pass))
|
||||
!= 0) {
|
||||
DLOG("get_user_info()", pam_strerror(pamh, pamret));
|
||||
prompt = NULL;
|
||||
pamret = PAM_SERVICE_ERR;
|
||||
goto cleanup;
|
||||
}
|
||||
prompt = "Enter it again: ";
|
||||
if ((pamret = get_user_info(pamh, prompt, PAM_PROMPT_ECHO_OFF, &pass2))
|
||||
!= 0) {
|
||||
DLOG("get_user_info()", pam_strerror(pamh, pamret));
|
||||
prompt = NULL;
|
||||
pamret = PAM_SERVICE_ERR;
|
||||
goto cleanup;
|
||||
}
|
||||
prompt = NULL;
|
||||
|
||||
if (strcmp(pass, pass2) != 0) {
|
||||
DLOG("strcmp()", "passwords not equal");
|
||||
pamret = PAM_AUTHTOK_ERR;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Change it */
|
||||
if ((krbret = krb5_change_password(pam_context, &creds, pass,
|
||||
&result_code, &result_code_string, &result_string)) != 0) {
|
||||
DLOG("krb5_change_password()", error_message(krbret));
|
||||
pamret = PAM_AUTHTOK_ERR;
|
||||
goto cleanup;
|
||||
}
|
||||
if (result_code) {
|
||||
DLOG("krb5_change_password() (result_code)", "");
|
||||
pamret = PAM_AUTHTOK_ERR;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (result_string.data)
|
||||
free(result_string.data);
|
||||
if (result_code_string.data)
|
||||
free(result_code_string.data);
|
||||
|
||||
cleanup:
|
||||
krb5_free_cred_contents(pam_context, &creds);
|
||||
cleanup2:
|
||||
krb5_free_principal(pam_context, princ);
|
||||
cleanup3:
|
||||
if (prompt)
|
||||
free(prompt);
|
||||
if (princ_name)
|
||||
free(princ_name);
|
||||
|
||||
krb5_free_context(pam_context);
|
||||
DLOG("exit", pamret ? "failure" : "success");
|
||||
return pamret;
|
||||
}
|
||||
|
28
lib/libpam/modules/pam_krb5/pam_krb5_sess.c
Normal file
28
lib/libpam/modules/pam_krb5/pam_krb5_sess.c
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* pam_krb5_sess.c
|
||||
*
|
||||
* PAM session management functions for pam_krb5
|
||||
* (null functions)
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
static const char rcsid[] = "$Id: pam_krb5_sess.c,v 1.3 1999/01/19 20:49:44 fcusack Exp $";
|
||||
|
||||
#include <security/pam_appl.h>
|
||||
#include <security/pam_modules.h>
|
||||
|
||||
/* Initiate session management */
|
||||
int
|
||||
pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv)
|
||||
{
|
||||
return PAM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* Terminate session management */
|
||||
int
|
||||
pam_sm_close_session(pam_handle_t *pamh, int flags, int argc, const char **argv)
|
||||
{
|
||||
return PAM_SUCCESS;
|
||||
}
|
185
lib/libpam/modules/pam_krb5/support.c
Normal file
185
lib/libpam/modules/pam_krb5/support.c
Normal file
@ -0,0 +1,185 @@
|
||||
/*
|
||||
* support.c
|
||||
*
|
||||
* Support functions for pam_krb5
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
static const char rcsid[] = "$Id: support.c,v 1.8 2000/01/04 09:50:03 fcusack Exp $";
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h> /* BUFSIZ */
|
||||
#include <stdlib.h> /* malloc */
|
||||
#include <string.h> /* strncpy */
|
||||
#include <syslog.h> /* syslog */
|
||||
#include <security/pam_appl.h>
|
||||
#include <security/pam_modules.h>
|
||||
#include <krb5.h>
|
||||
#include <com_err.h>
|
||||
#include "pam_krb5.h"
|
||||
|
||||
/*
|
||||
* Get info from the user. Disallow null responses (regardless of flags).
|
||||
* response gets allocated and filled in on successful return. Caller
|
||||
* is responsible for freeing it.
|
||||
*/
|
||||
int
|
||||
get_user_info(pam_handle_t *pamh, char *prompt, int type, char **response)
|
||||
{
|
||||
int pamret;
|
||||
struct pam_message msg;
|
||||
const struct pam_message *pmsg;
|
||||
struct pam_response *resp = NULL;
|
||||
struct pam_conv *conv;
|
||||
|
||||
if ((pamret = pam_get_item(pamh, PAM_CONV, (const void **) &conv)) != 0)
|
||||
return pamret;
|
||||
|
||||
/* set up conversation call */
|
||||
pmsg = &msg;
|
||||
msg.msg_style = type;
|
||||
msg.msg = prompt;
|
||||
|
||||
if ((pamret = conv->conv(1, &pmsg, &resp, conv->appdata_ptr)) != 0)
|
||||
return pamret;
|
||||
|
||||
/* Caller should ignore errors for non-response conversations */
|
||||
if (!resp)
|
||||
return PAM_CONV_ERR;
|
||||
|
||||
if (!(resp->resp && resp->resp[0])) {
|
||||
free(resp);
|
||||
return PAM_AUTH_ERR;
|
||||
}
|
||||
|
||||
*response = resp->resp;
|
||||
free(resp);
|
||||
return pamret;
|
||||
}
|
||||
|
||||
/*
|
||||
* This routine with some modification is from the MIT V5B6 appl/bsd/login.c
|
||||
* Modified by Sam Hartman <hartmans@mit.edu> to support PAM services
|
||||
* for Debian.
|
||||
*
|
||||
* Verify the Kerberos ticket-granting ticket just retrieved for the
|
||||
* user. If the Kerberos server doesn't respond, assume the user is
|
||||
* trying to fake us out (since we DID just get a TGT from what is
|
||||
* supposedly our KDC). If the host/<host> service is unknown (i.e.,
|
||||
* the local keytab doesn't have it), and we cannot find another
|
||||
* service we do have, let her in.
|
||||
*
|
||||
* Returns 1 for confirmation, -1 for failure, 0 for uncertainty.
|
||||
*/
|
||||
int
|
||||
verify_krb_v5_tgt(krb5_context context, krb5_ccache ccache,
|
||||
char * pam_service, int debug)
|
||||
{
|
||||
char phost[BUFSIZ];
|
||||
char *services [3];
|
||||
char **service;
|
||||
krb5_error_code retval = -1;
|
||||
krb5_principal princ;
|
||||
krb5_keyblock * keyblock = 0;
|
||||
krb5_data packet;
|
||||
krb5_auth_context auth_context = NULL;
|
||||
|
||||
packet.data = 0;
|
||||
|
||||
/*
|
||||
* If possible we want to try and verify the ticket we have
|
||||
* received against a keytab. We will try multiple service
|
||||
* principals, including at least the host principal and the PAM
|
||||
* service principal. The host principal is preferred because access
|
||||
* to that key is generally sufficient to compromise root, while the
|
||||
* service key for this PAM service may be less carefully guarded.
|
||||
* It is important to check the keytab first before the KDC so we do
|
||||
* not get spoofed by a fake KDC.*/
|
||||
services [0] = "host";
|
||||
services [1] = pam_service;
|
||||
services [2] = NULL;
|
||||
for ( service = &services[0]; *service != NULL; service++ ) {
|
||||
if ((retval = krb5_sname_to_principal(context, NULL, *service, KRB5_NT_SRV_HST,
|
||||
&princ)) != 0) {
|
||||
if (debug)
|
||||
syslog(LOG_DEBUG, "pam_krb5: verify_krb_v5_tgt(): %s: %s",
|
||||
"krb5_sname_to_principal()", error_message(retval));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Extract the name directly. */
|
||||
strncpy(phost, compat_princ_component(context, princ, 1), BUFSIZ);
|
||||
phost[BUFSIZ - 1] = '\0';
|
||||
|
||||
/*
|
||||
* Do we have service/<host> keys?
|
||||
* (use default/configured keytab, kvno IGNORE_VNO to get the
|
||||
* first match, and ignore enctype.)
|
||||
*/
|
||||
if ((retval = krb5_kt_read_service_key(context, NULL, princ, 0,
|
||||
0, &keyblock)) != 0)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
if (retval != 0 ) { /* failed to find key */
|
||||
/* Keytab or service key does not exist */
|
||||
if (debug)
|
||||
syslog(LOG_DEBUG, "pam_krb5: verify_krb_v5_tgt(): %s: %s",
|
||||
"krb5_kt_read_service_key()", error_message(retval));
|
||||
retval = 0;
|
||||
goto cleanup;
|
||||
}
|
||||
if (keyblock)
|
||||
krb5_free_keyblock(context, keyblock);
|
||||
|
||||
/* Talk to the kdc and construct the ticket. */
|
||||
retval = krb5_mk_req(context, &auth_context, 0, *service, phost,
|
||||
NULL, ccache, &packet);
|
||||
if (auth_context) {
|
||||
krb5_auth_con_free(context, auth_context);
|
||||
auth_context = NULL; /* setup for rd_req */
|
||||
}
|
||||
if (retval) {
|
||||
if (debug)
|
||||
syslog(LOG_DEBUG, "pam_krb5: verify_krb_v5_tgt(): %s: %s",
|
||||
"krb5_mk_req()", error_message(retval));
|
||||
retval = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Try to use the ticket. */
|
||||
retval = krb5_rd_req(context, &auth_context, &packet, princ,
|
||||
NULL, NULL, NULL);
|
||||
if (retval) {
|
||||
if (debug)
|
||||
syslog(LOG_DEBUG, "pam_krb5: verify_krb_v5_tgt(): %s: %s",
|
||||
"krb5_rd_req()", error_message(retval));
|
||||
retval = -1;
|
||||
} else {
|
||||
retval = 1;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (packet.data)
|
||||
compat_free_data_contents(context, &packet);
|
||||
krb5_free_principal(context, princ);
|
||||
return retval;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Free the memory for cache_name. Called by pam_end() */
|
||||
void
|
||||
cleanup_cache(pam_handle_t *pamh, void *data, int pam_end_status)
|
||||
{
|
||||
krb5_context pam_context;
|
||||
krb5_ccache ccache;
|
||||
|
||||
if (krb5_init_context(&pam_context))
|
||||
return;
|
||||
|
||||
ccache = (krb5_ccache) data;
|
||||
(void) krb5_cc_destroy(pam_context, ccache);
|
||||
krb5_free_context(pam_context);
|
||||
}
|
39
lib/libpam/modules/pam_nologin/Makefile
Normal file
39
lib/libpam/modules/pam_nologin/Makefile
Normal file
@ -0,0 +1,39 @@
|
||||
# Copyright 2001 Mark R V Murray
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
# SUCH DAMAGE.
|
||||
#
|
||||
# $FreeBSD$
|
||||
|
||||
PAMDIR= ${.CURDIR}/../../../../contrib/libpam
|
||||
|
||||
.PATH: ${PAMDIR}/modules/pam_nologin
|
||||
|
||||
LIB= pam_nologin
|
||||
SHLIB_NAME= pam_nologin.so
|
||||
SRCS= pam_nologin.c
|
||||
CFLAGS+= -Wall
|
||||
CFLAGS+= -I${PAMDIR}/libpam/include
|
||||
INTERNALLIB= yes
|
||||
INTERNALSTATICLIB=yes
|
||||
|
||||
.include <bsd.lib.mk>
|
39
lib/libpam/modules/pam_rootok/Makefile
Normal file
39
lib/libpam/modules/pam_rootok/Makefile
Normal file
@ -0,0 +1,39 @@
|
||||
# Copyright 2001 Mark R V Murray
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
# SUCH DAMAGE.
|
||||
#
|
||||
# $FreeBSD$
|
||||
|
||||
PAMDIR= ${.CURDIR}/../../../../contrib/libpam
|
||||
|
||||
.PATH: ${PAMDIR}/modules/pam_rootok
|
||||
|
||||
LIB= pam_rootok
|
||||
SHLIB_NAME= pam_rootok.so
|
||||
SRCS= pam_rootok.c
|
||||
CFLAGS+= -Wall
|
||||
CFLAGS+= -I${PAMDIR}/libpam/include
|
||||
INTERNALLIB= yes
|
||||
INTERNALSTATICLIB=yes
|
||||
|
||||
.include <bsd.lib.mk>
|
39
lib/libpam/modules/pam_wheel/Makefile
Normal file
39
lib/libpam/modules/pam_wheel/Makefile
Normal file
@ -0,0 +1,39 @@
|
||||
# Copyright 2001 Mark R V Murray
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
# SUCH DAMAGE.
|
||||
#
|
||||
# $FreeBSD$
|
||||
|
||||
PAMDIR= ${.CURDIR}/../../../../contrib/libpam
|
||||
|
||||
.PATH: ${PAMDIR}/modules/pam_wheel
|
||||
|
||||
LIB= pam_wheel
|
||||
SHLIB_NAME= pam_wheel.so
|
||||
SRCS= pam_wheel.c
|
||||
CFLAGS+= -Wall
|
||||
CFLAGS+= -I${PAMDIR}/libpam/include
|
||||
INTERNALLIB= yes
|
||||
INTERNALSTATICLIB=yes
|
||||
|
||||
.include <bsd.lib.mk>
|
Loading…
Reference in New Issue
Block a user