summaryrefslogtreecommitdiff
path: root/security
diff options
context:
space:
mode:
authorJacques Vidrine <nectar@FreeBSD.org>2001-01-24 20:36:33 +0000
committerJacques Vidrine <nectar@FreeBSD.org>2001-01-24 20:36:33 +0000
commit31d87969c907658eba1ac1eb5d876fd9b01fb3a9 (patch)
treee4872a4afdb06e2d416c56b65d7a208238f710b3 /security
parents/w32/win32/, my fault :Q (diff)
Bug fixes and paranoia:
compat_heimdal.c: = Stop shooting at feet when freeing a particular chunk of memory. Found by complaints from free(), and pinpointed with MALLOC_OPTIONS=A. pam_krb5_auth.c: = In addition to dropping and restoring uid when delving in /tmp, drop and restore gid. = Explicitly set permissions on the credentials cache for good measure. The following was Obtained from: Sam Hartman <hartmans@mit.edu> via bugs.debian.org support.c: = verify_krb_v5_tgt: Do a little more to prevent KDC spoofing. Allow for a key separate from the host key to use only for PAM.
Notes
Notes: svn path=/head/; revision=37547
Diffstat (limited to 'security')
-rw-r--r--security/pam_krb5/files/patch-ab5
-rw-r--r--security/pam_krb5/files/patch-ad93
-rw-r--r--security/pam_krb5/files/patch-af108
-rw-r--r--security/pam_krb5/files/patch-ah6
4 files changed, 163 insertions, 49 deletions
diff --git a/security/pam_krb5/files/patch-ab b/security/pam_krb5/files/patch-ab
index 29f2cac50699..55b8502c3914 100644
--- a/security/pam_krb5/files/patch-ab
+++ b/security/pam_krb5/files/patch-ab
@@ -1,12 +1,13 @@
--- pam_krb5.h.orig Tue Jan 4 19:08:51 2000
-+++ pam_krb5.h Mon Nov 6 13:42:22 2000
++++ pam_krb5.h Wed Jan 24 13:37:28 2001
@@ -5,7 +5,18 @@
*/
int get_user_info(pam_handle_t *, char *, int, char **);
-krb5_error_code pam_prompter(krb5_context, void *, const char *,
- const char *, int, krb5_prompt[]);
- int verify_krb_v5_tgt(krb5_context, krb5_ccache, int);
+-int verify_krb_v5_tgt(krb5_context, krb5_ccache, int);
++int verify_krb_v5_tgt(krb5_context, krb5_ccache, char *, int);
void cleanup_cache(pam_handle_t *, void *, int);
+
+krb5_prompter_fct pam_prompter;
diff --git a/security/pam_krb5/files/patch-ad b/security/pam_krb5/files/patch-ad
index ee54cfe5b873..e753e20043a7 100644
--- a/security/pam_krb5/files/patch-ad
+++ b/security/pam_krb5/files/patch-ad
@@ -1,9 +1,11 @@
--- pam_krb5_auth.c.orig Tue Jan 4 19:08:51 2000
-+++ pam_krb5_auth.c Mon Nov 6 13:45:48 2000
-@@ -7,9 +7,11 @@
++++ pam_krb5_auth.c Wed Jan 24 14:08:18 2001
+@@ -7,18 +7,22 @@
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 */
@@ -12,7 +14,9 @@
#include <strings.h> /* strchr */
#include <syslog.h> /* syslog */
#include <unistd.h> /* chown */
-@@ -19,6 +21,7 @@
+-#include <sys/types.h> /* chown */
+
+ #include <security/pam_appl.h>
#include <security/pam_modules.h>
#include <krb5.h>
@@ -20,7 +24,7 @@
#include "pam_krb5.h"
extern krb5_cc_ops krb5_mcc_ops;
-@@ -42,7 +45,7 @@
+@@ -42,7 +46,7 @@
krb5_get_init_creds_opt opts;
int pamret, i;
@@ -29,7 +33,7 @@
char *princ_name = NULL;
char *pass = NULL, *service = NULL;
char *prompt = NULL;
-@@ -74,13 +77,13 @@
+@@ -74,13 +78,13 @@
}
/* Get service name */
@@ -45,7 +49,7 @@
DLOG("krb5_init_context()", error_message(krbret));
return PAM_SERVICE_ERR;
}
-@@ -93,7 +96,7 @@
+@@ -93,7 +97,7 @@
krb5_get_init_creds_opt_set_forwardable(&opts, 1);
/* For CNS */
@@ -54,7 +58,7 @@
/* Solaris dtlogin doesn't call pam_end() on failure */
if (krbret != KRB5_CC_TYPE_EXISTS) {
DLOG("krb5_cc_register()", error_message(krbret));
-@@ -103,14 +106,14 @@
+@@ -103,14 +107,14 @@
}
/* Get principal name */
@@ -71,7 +75,7 @@
DLOG("krb5_unparse_name()", error_message(krbret));
pamret = PAM_SERVICE_ERR;
goto cleanup2;
-@@ -126,18 +129,19 @@
+@@ -126,18 +130,19 @@
(void) sprintf(prompt, "Password for %s: ", princ_name);
if (try_first_pass || use_first_pass)
@@ -94,7 +98,7 @@
DLOG("pam_set_item()", pam_strerror(pamh, pamret));
free(pass);
pamret = PAM_SERVICE_ERR;
-@@ -145,25 +149,26 @@
+@@ -145,25 +150,26 @@
}
free(pass);
/* Now we get it back from the library. */
@@ -126,7 +130,7 @@
DLOG("pam_get_item()", pam_strerror(pamh, pamret));
pamret = PAM_SERVICE_ERR;
goto cleanup2;
-@@ -177,9 +182,8 @@
+@@ -177,9 +183,8 @@
}
/* Get a TGT */
@@ -138,7 +142,7 @@
DLOG("krb5_get_init_creds_password()", error_message(krbret));
if (try_first_pass && krbret == KRB5KRB_AP_ERR_BAD_INTEGRITY) {
pass = NULL;
-@@ -193,17 +197,17 @@
+@@ -193,17 +198,17 @@
strcpy(cache_name, "MEMORY:");
(void) tmpnam(&cache_name[7]);
@@ -159,7 +163,16 @@
DLOG("krb5_cc_store_cred()", error_message(krbret));
(void) krb5_cc_destroy(pam_context, ccache);
pamret = PAM_SERVICE_ERR;
-@@ -224,7 +228,7 @@
+@@ -211,7 +216,7 @@
+ }
+
+ /* Verify it */
+- if (verify_krb_v5_tgt(pam_context, ccache, debug) == -1) {
++ if (verify_krb_v5_tgt(pam_context, ccache, service, debug) == -1) {
+ (void) krb5_cc_destroy(pam_context, ccache);
+ pamret = PAM_AUTH_ERR;
+ goto cleanup;
+@@ -224,7 +229,7 @@
pamret = PAM_AUTH_ERR;
goto cleanup;
}
@@ -168,7 +181,15 @@
DLOG("pam_set_data()", pam_strerror(pamh, pamret));
(void) krb5_cc_destroy(pam_context, ccache);
pamret = PAM_SERVICE_ERR;
-@@ -288,22 +292,22 @@
+@@ -275,6 +280,7 @@
+
+ int debug = 0;
+ uid_t euid;
++ gid_t egid;
+
+ if (flags == PAM_REINITIALIZE_CRED)
+ return PAM_SUCCESS; /* XXX Incorrect behavior */
+@@ -288,30 +294,32 @@
else if (strcmp(argv[i], "no_ccache") == 0)
return PAM_SUCCESS;
else if (strstr(argv[i], "ccache=") == argv[i])
@@ -195,8 +216,9 @@
DLOG("krb5_init_context()", error_message(krbret));
return PAM_SERVICE_ERR;
}
-@@ -311,7 +315,8 @@
+
euid = geteuid(); /* Usually 0 */
++ egid = getegid();
/* Retrieve the cache name */
- if (pamret = pam_get_data(pamh, "ccache", (const void **) &ccache_temp)) {
@@ -205,7 +227,19 @@
DLOG("pam_get_data()", pam_strerror(pamh, pamret));
pamret = PAM_CRED_UNAVAIL;
goto cleanup3;
-@@ -340,7 +345,7 @@
+@@ -326,6 +334,11 @@
+ }
+
+ /* 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;
+@@ -340,7 +353,7 @@
pamret = PAM_BUF_ERR;
goto cleanup3;
}
@@ -214,7 +248,7 @@
} else {
/* cache_name was supplied */
char *p = calloc(PATH_MAX + 10, 1); /* should be plenty */
-@@ -357,10 +362,10 @@
+@@ -357,10 +370,10 @@
if (*q == '%') {
q++;
if (*q == 'u') {
@@ -227,7 +261,7 @@
p += strlen(p);
} else {
/* Not a special token */
-@@ -375,24 +380,27 @@
+@@ -375,24 +388,27 @@
}
/* Initialize the new ccache */
@@ -259,7 +293,7 @@
DLOG("krb5_cc_start_seq_get()", error_message(krbret));
(void) krb5_cc_destroy(pam_context, ccache_perm);
pamret = PAM_SERVICE_ERR;
-@@ -400,9 +408,10 @@
+@@ -400,9 +416,10 @@
}
/* Copy the creds (should be two of them) */
@@ -273,7 +307,20 @@
DLOG("krb5_cc_store_cred()", error_message(krbret));
(void) krb5_cc_destroy(pam_context, ccache_perm);
krb5_free_cred_contents(pam_context, &creds);
-@@ -432,7 +441,7 @@
+@@ -420,6 +437,12 @@
+ 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);
+
+@@ -432,7 +455,7 @@
}
sprintf(cache_env_name, "KRB5CCNAME=%s", cache_name);
@@ -282,3 +329,11 @@
DLOG("pam_putenv()", pam_strerror(pamh, pamret));
(void) krb5_cc_destroy(pam_context, ccache_perm);
pamret = PAM_SERVICE_ERR;
+@@ -445,6 +468,7 @@
+ krb5_free_context(pam_context);
+ DLOG("exit", pamret ? "failure" : "success");
+ (void) seteuid(euid);
++ (void) setegid(egid);
+ return pamret;
+ }
+
diff --git a/security/pam_krb5/files/patch-af b/security/pam_krb5/files/patch-af
index 26167b15def5..552f6b726a86 100644
--- a/security/pam_krb5/files/patch-af
+++ b/security/pam_krb5/files/patch-af
@@ -1,5 +1,5 @@
--- support.c.orig Tue Jan 4 19:08:51 2000
-+++ support.c Mon Nov 6 13:36:39 2000
++++ support.c Wed Jan 24 13:37:28 2001
@@ -6,11 +6,15 @@
static const char rcsid[] = "$Id: support.c,v 1.8 2000/01/04 09:50:03 fcusack Exp $";
@@ -40,7 +40,7 @@
return pamret;
/* Caller should ignore errors for non-response conversations */
-@@ -51,124 +56,6 @@
+@@ -51,172 +56,71 @@
return pamret;
}
@@ -164,8 +164,30 @@
-
/*
* 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.
*
-@@ -189,8 +76,6 @@
+ * 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), let her in.
++ * 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, int debug)
++verify_krb_v5_tgt(krb5_context context, krb5_ccache ccache,
++ char * pam_service, int debug)
+ {
+ char phost[BUFSIZ];
+- krb5_error_code retval;
++ 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;
@@ -174,38 +196,74 @@
packet.data = 0;
-@@ -198,8 +83,8 @@
- * Get the server principal for the local host.
- * (Use defaults of "host" and canonicalized local name.)
- */
+ /*
+- * Get the server principal for the local host.
+- * (Use defaults of "host" and canonicalized local name.)
+- */
- if (retval = krb5_sname_to_principal(context, NULL, NULL,
- KRB5_NT_SRV_HST, &princ)) {
-+ if ((retval = krb5_sname_to_principal(context, NULL, NULL, KRB5_NT_SRV_HST,
-+ &princ)) != 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));
-@@ -207,7 +92,7 @@
- }
+- syslog(LOG_DEBUG, "pam_krb5: verify_krb_v5_tgt(): %s: %s",
+- "krb5_sname_to_principal()", error_message(retval));
++ syslog(LOG_DEBUG, "pam_krb5: verify_krb_v5_tgt(): %s: %s",
++ "krb5_sname_to_principal()", error_message(retval));
+ return -1;
+- }
++ }
- /* Extract the name directly. */
+- /* Extract the name directly. */
- strncpy(phost, krb5_princ_component(c, princ, 1)->data, BUFSIZ);
-+ strncpy(phost, compat_princ_component(context, princ, 1), BUFSIZ);
- phost[BUFSIZ - 1] = '\0';
-
- /*
-@@ -215,8 +100,8 @@
- * (use default/configured keytab, kvno IGNORE_VNO to get the
- * first match, and enctype is currently ignored anyhow.)
- */
+- phost[BUFSIZ - 1] = '\0';
+-
+- /*
+- * Do we have host/<host> keys?
+- * (use default/configured keytab, kvno IGNORE_VNO to get the
+- * first match, and enctype is currently ignored anyhow.)
+- */
- if (retval = krb5_kt_read_service_key(context, NULL, princ, 0,
- ENCTYPE_DES_CBC_MD5, &keyblock)) {
-+ if ((retval = krb5_kt_read_service_key(context, NULL, princ, 0,
-+ ENCTYPE_DES_CBC_MD5, &keyblock)) != 0) {
++ /* 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",
-@@ -256,7 +141,7 @@
+@@ -228,7 +132,7 @@
+ krb5_free_keyblock(context, keyblock);
+
+ /* Talk to the kdc and construct the ticket. */
+- retval = krb5_mk_req(context, &auth_context, 0, "host", phost,
++ retval = krb5_mk_req(context, &auth_context, 0, *service, phost,
+ NULL, ccache, &packet);
+ if (auth_context) {
+ krb5_auth_con_free(context, auth_context);
+@@ -256,7 +160,7 @@
cleanup:
if (packet.data)
diff --git a/security/pam_krb5/files/patch-ah b/security/pam_krb5/files/patch-ah
index 480089da1745..933c37ed4ec6 100644
--- a/security/pam_krb5/files/patch-ah
+++ b/security/pam_krb5/files/patch-ah
@@ -1,5 +1,5 @@
---- compat_heimdal.c.orig Mon Nov 6 13:27:02 2000
-+++ compat_heimdal.c Mon Nov 6 13:43:10 2000
+--- compat_heimdal.c.orig Wed Jan 24 12:40:26 2001
++++ compat_heimdal.c Wed Jan 24 12:50:52 2001
@@ -0,0 +1,133 @@
+#include <errno.h>
+#include <stdio.h>
@@ -20,7 +20,7 @@
+void
+compat_free_data_contents(krb5_context context, krb5_data *data)
+{
-+ krb5_xfree(data);
++ krb5_xfree(data->data);
+}
+
+krb5_error_code