summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorGünther Deschner <gd@samba.org>2006-04-25 12:24:25 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 11:16:29 -0500
commit351e749246a278b60a7e18c1eeafdc8ec70efea2 (patch)
tree7080fbf71b0f4cedfd4eeae1eb42478b2b327b49 /source3
parent66fd215dc754963c866c3c3402f65d6bd14b8dcd (diff)
downloadsamba-351e749246a278b60a7e18c1eeafdc8ec70efea2.tar.gz
samba-351e749246a278b60a7e18c1eeafdc8ec70efea2.tar.bz2
samba-351e749246a278b60a7e18c1eeafdc8ec70efea2.zip
r15240: Correctly disallow unauthorized access when logging on with the
kerberized pam_winbind and workstation restrictions are in effect. The krb5 AS-REQ needs to add the host netbios-name in the address-list. We don't get the clear NT_STATUS_INVALID_WORKSTATION code back yet from the edata of the KRB_ERROR but the login at least fails when the local machine is not in the workstation list on the DC. Guenther (This used to be commit 8b2ba11508e2730aba074d7c095291fac2a62176)
Diffstat (limited to 'source3')
-rw-r--r--source3/Makefile.in2
-rw-r--r--source3/configure.in24
-rw-r--r--source3/include/ads.h12
-rw-r--r--source3/include/includes.h2
-rw-r--r--source3/libads/kerberos.c26
-rw-r--r--source3/libsmb/clikrb5.c98
-rw-r--r--source3/libsmb/nmblib.c2
-rw-r--r--source3/nsswitch/winbindd_cred_cache.c1
-rw-r--r--source3/nsswitch/winbindd_pam.c1
9 files changed, 164 insertions, 4 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in
index 48a1b10f73..946f74e8a5 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -758,7 +758,7 @@ NTLM_AUTH_OBJ = ${NTLM_AUTH_OBJ1} $(LIBSAMBA_OBJ) $(POPT_LIB_OBJ) \
libsmb/asn1.o libsmb/spnego.o libsmb/clikrb5.o libads/kerberos.o \
libads/kerberos_verify.o $(SECRETS_OBJ) $(SERVER_MUTEX_OBJ) \
libads/authdata.o $(RPC_PARSE_OBJ1) $(PASSDB_OBJ) $(GROUPDB_OBJ) \
- $(SMBLDAP_OBJ) $(DOSERR_OBJ) rpc_parse/parse_net.o
+ $(SMBLDAP_OBJ) $(DOSERR_OBJ) rpc_parse/parse_net.o $(LIBNMB_OBJ)
######################################################################
# now the rules...
diff --git a/source3/configure.in b/source3/configure.in
index c479d2d290..d700740c0d 100644
--- a/source3/configure.in
+++ b/source3/configure.in
@@ -3655,6 +3655,18 @@ if test x"$with_ads_support" != x"no"; then
[Whether krb5_keytab_entry has keyblock member])
fi
+ AC_CACHE_CHECK([for magic in krb5_address],
+ samba_cv_HAVE_MAGIC_IN_KRB5_ADDRESS,[
+ AC_TRY_COMPILE([#include <krb5.h>],
+ [krb5_address addr; addr.magic = 0;],
+ samba_cv_HAVE_MAGIC_IN_KRB5_ADDRESS=yes,
+ samba_cv_HAVE_MAGIC_IN_KRB5_ADDRESS=no)])
+
+ if test x"$samba_cv_HAVE_MAGIC_IN_KRB5_ADDRESS" = x"yes"; then
+ AC_DEFINE(HAVE_MAGIC_IN_KRB5_ADDRESS,1,
+ [Whether the krb5_address struct has a magic property])
+ fi
+
if test x"$ac_cv_lib_ext_krb5_krb5_mk_req_extended" = x"yes"; then
AC_DEFINE(HAVE_KRB5,1,[Whether to have KRB5 support])
AC_DEFINE(WITH_ADS,1,[Whether to include Active Directory support])
@@ -3705,6 +3717,18 @@ if test x"$with_ads_support" != x"no"; then
[Whether krb5_princ_realm returns krb5_realm or krb5_data])
fi
+ AC_CACHE_CHECK([for krb5_addresses type],
+ samba_cv_HAVE_KRB5_ADDRESSES,[
+ AC_TRY_COMPILE([#include <krb5.h>],
+ [krb5_addresses addr;],
+ samba_cv_HAVE_KRB5_ADDRESSES=yes,
+ samba_cv_HAVE_KRB5_ADDRESSES=no)])
+
+ if test x"$samba_cv_HAVE_KRB5_ADDRESSES" = x"yes"; then
+ AC_DEFINE(HAVE_KRB5_ADDRESSES,1,
+ [Whether the type krb5_addresses type exists])
+ fi
+
LIBS="$ac_save_LIBS"
fi
diff --git a/source3/include/ads.h b/source3/include/ads.h
index 2c7999e24f..711dd2aa70 100644
--- a/source3/include/ads.h
+++ b/source3/include/ads.h
@@ -266,3 +266,15 @@ typedef void **ADS_MODLIST;
#define WELL_KNOWN_GUID_COMPUTERS "AA312825768811D1ADED00C04FD8D5CD"
#define WELL_KNOWN_GUID_USERS "A9D1CA15768811D1ADED00C04FD8D5CD"
+
+#ifndef KRB5_ADDR_NETBIOS
+#define KRB5_ADDR_NETBIOS 0x14
+#endif
+
+typedef struct {
+#if defined(HAVE_MAGIC_IN_KRB5_ADDRESS) && defined(HAVE_ADDRTYPE_IN_KRB5_ADDRESS) /* MIT */
+ krb5_address **addrs;
+#else /* Heimdal has the krb5_addresses type */
+ krb5_addresses *addrs;
+#endif
+} smb_krb5_addresses;
diff --git a/source3/include/includes.h b/source3/include/includes.h
index 944d1b43c0..0eb2ba83aa 100644
--- a/source3/include/includes.h
+++ b/source3/include/includes.h
@@ -1538,6 +1538,8 @@ int cli_krb5_get_ticket(const char *principal, time_t time_offset,
PAC_LOGON_INFO *get_logon_info_from_pac(PAC_DATA *pac_data);
krb5_error_code smb_krb5_renew_ticket(const char *ccache_string, const char *client_string, const char *service_string, time_t *new_start_time);
krb5_error_code kpasswd_err_to_krb5_err(krb5_error_code res_code);
+krb5_error_code smb_krb5_gen_netbios_krb5_address(smb_krb5_addresses **kerb_addr);
+krb5_error_code smb_krb5_free_addresses(krb5_context context, smb_krb5_addresses *addr);
NTSTATUS krb5_to_nt_status(krb5_error_code kerberos_error);
krb5_error_code nt_status_to_krb5(NTSTATUS nt_status);
#endif /* HAVE_KRB5 */
diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c
index 960709a5f0..2dfdc31dd5 100644
--- a/source3/libads/kerberos.c
+++ b/source3/libads/kerberos.c
@@ -65,6 +65,7 @@ int kerberos_kinit_password_ext(const char *principal,
time_t *renew_till_time,
const char *cache_name,
BOOL request_pac,
+ BOOL add_netbios_addr,
time_t renewable_time)
{
krb5_context ctx = NULL;
@@ -73,6 +74,7 @@ int kerberos_kinit_password_ext(const char *principal,
krb5_principal me;
krb5_creds my_creds;
krb5_get_init_creds_opt opt;
+ smb_krb5_addresses *addr = NULL;
initialize_krb5_error_table();
if ((code = krb5_init_context(&ctx)))
@@ -101,19 +103,36 @@ int kerberos_kinit_password_ext(const char *principal,
if (request_pac) {
#ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PAC_REQUEST
- krb5_get_init_creds_opt_set_pac_request(ctx, &opt, True);
+ code = krb5_get_init_creds_opt_set_pac_request(ctx, &opt, True);
+ if (code) {
+ krb5_free_principal(ctx, me);
+ krb5_free_context(ctx);
+ return code;
+ }
#endif
}
+ if (add_netbios_addr) {
+ code = smb_krb5_gen_netbios_krb5_address(&addr);
+ if (code) {
+ krb5_free_principal(ctx, me);
+ krb5_free_context(ctx);
+ return code;
+ }
+ krb5_get_init_creds_opt_set_address_list(&opt, addr->addrs);
+ }
+
if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, CONST_DISCARD(char *,password),
kerb_prompter, NULL, 0, NULL, &opt)))
{
+ smb_krb5_free_addresses(ctx, addr);
krb5_free_principal(ctx, me);
krb5_free_context(ctx);
return code;
}
if ((code = krb5_cc_initialize(ctx, cc, me))) {
+ smb_krb5_free_addresses(ctx, addr);
krb5_free_cred_contents(ctx, &my_creds);
krb5_free_principal(ctx, me);
krb5_free_context(ctx);
@@ -122,6 +141,7 @@ int kerberos_kinit_password_ext(const char *principal,
if ((code = krb5_cc_store_cred(ctx, cc, &my_creds))) {
krb5_cc_close(ctx, cc);
+ smb_krb5_free_addresses(ctx, addr);
krb5_free_cred_contents(ctx, &my_creds);
krb5_free_principal(ctx, me);
krb5_free_context(ctx);
@@ -137,6 +157,7 @@ int kerberos_kinit_password_ext(const char *principal,
}
krb5_cc_close(ctx, cc);
+ smb_krb5_free_addresses(ctx, addr);
krb5_free_cred_contents(ctx, &my_creds);
krb5_free_principal(ctx, me);
krb5_free_context(ctx);
@@ -178,7 +199,7 @@ int ads_kinit_password(ADS_STRUCT *ads)
}
ret = kerberos_kinit_password_ext(s, ads->auth.password, ads->auth.time_offset,
- &ads->auth.expire, NULL, NULL, False, ads->auth.renewable);
+ &ads->auth.expire, NULL, NULL, False, False, ads->auth.renewable);
if (ret) {
DEBUG(0,("kerberos_kinit_password %s failed: %s\n",
@@ -812,6 +833,7 @@ int kerberos_kinit_password(const char *principal,
0,
cache_name,
False,
+ False,
0);
}
diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c
index d3da25760b..40ffec6f53 100644
--- a/source3/libsmb/clikrb5.c
+++ b/source3/libsmb/clikrb5.c
@@ -1205,6 +1205,104 @@ done:
}
+ krb5_error_code smb_krb5_free_addresses(krb5_context context, smb_krb5_addresses *addr)
+{
+ krb5_error_code ret = 0;
+#if defined(HAVE_MAGIC_IN_KRB5_ADDRESS) && defined(HAVE_ADDRTYPE_IN_KRB5_ADDRESS) /* MIT */
+ krb5_free_addresses(context, addr->addrs);
+#elif defined(HAVE_ADDR_TYPE_IN_KRB5_ADDRESS) /* Heimdal */
+ ret = krb5_free_addresses(context, addr->addrs);
+ SAFE_FREE(addr->addrs);
+#endif
+ SAFE_FREE(addr);
+ addr = NULL;
+ return ret;
+}
+
+ krb5_error_code smb_krb5_gen_netbios_krb5_address(smb_krb5_addresses **kerb_addr)
+{
+ krb5_error_code ret = 0;
+ nstring buf;
+#if defined(HAVE_MAGIC_IN_KRB5_ADDRESS) && defined(HAVE_ADDRTYPE_IN_KRB5_ADDRESS) /* MIT */
+ krb5_address **addrs = NULL;
+#elif defined(HAVE_ADDR_TYPE_IN_KRB5_ADDRESS) /* Heimdal */
+ krb5_addresses *addrs = NULL;
+#endif
+
+ *kerb_addr = (smb_krb5_addresses *)SMB_MALLOC(sizeof(smb_krb5_addresses));
+ if (*kerb_addr == NULL) {
+ return ENOMEM;
+ }
+
+ put_name(buf, global_myname(), ' ', 0x20);
+
+#if defined(HAVE_MAGIC_IN_KRB5_ADDRESS) && defined(HAVE_ADDRTYPE_IN_KRB5_ADDRESS) /* MIT */
+ {
+ int num_addr = 2;
+
+ addrs = (krb5_address **)SMB_MALLOC(sizeof(krb5_address *) * num_addr);
+ if (addrs == NULL) {
+ return ENOMEM;
+ }
+
+ memset(addrs, 0, sizeof(krb5_address *) * num_addr);
+
+ addrs[0] = (krb5_address *)SMB_MALLOC(sizeof(krb5_address));
+ if (addrs[0] == NULL) {
+ SAFE_FREE(addrs);
+ return ENOMEM;
+ }
+
+ addrs[0]->magic = KV5M_ADDRESS;
+ addrs[0]->addrtype = KRB5_ADDR_NETBIOS;
+ addrs[0]->length = MAX_NETBIOSNAME_LEN;
+ addrs[0]->contents = (unsigned char *)SMB_MALLOC(addrs[0]->length);
+ if (addrs[0]->contents == NULL) {
+ SAFE_FREE(addrs[0]);
+ SAFE_FREE(addrs);
+ return ENOMEM;
+ }
+
+ memcpy(addrs[0]->contents, buf, addrs[0]->length);
+
+ addrs[1] = NULL;
+ }
+#elif defined(HAVE_ADDR_TYPE_IN_KRB5_ADDRESS) /* Heimdal */
+ {
+ addrs = (krb5_addresses *)SMB_MALLOC(sizeof(krb5_addresses));
+ if (addrs == NULL) {
+ return ENOMEM;
+ }
+
+ memset(addrs, 0, sizeof(krb5_addresses));
+
+ addrs->len = 1;
+ addrs->val = (krb5_address *)SMB_MALLOC(sizeof(krb5_address));
+ if (addrs->val == NULL) {
+ SAFE_FREE(addrs);
+ return ENOMEM;
+ }
+
+ addrs->val[0].addr_type = KRB5_ADDR_NETBIOS;
+ addrs->val[0].address.length = MAX_NETBIOSNAME_LEN;
+ addrs->val[0].address.data = (unsigned char *)SMB_MALLOC(addrs->val[0].address.length);
+ if (addrs->val[0].address.data == NULL) {
+ SAFE_FREE(addrs->val);
+ SAFE_FREE(addrs);
+ return ENOMEM;
+ }
+
+ memcpy(addrs->val[0].address.data, buf, addrs->val[0].address.length);
+ }
+#else
+#error UNKNOWN_KRB5_ADDRESS_FORMAT
+#endif
+ (*kerb_addr)->addrs = addrs;
+
+ return ret;
+}
+
+
#else /* HAVE_KRB5 */
/* this saves a few linking headaches */
int cli_krb5_get_ticket(const char *principal, time_t time_offset,
diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c
index 4d84d7bc49..5280dfdbff 100644
--- a/source3/libsmb/nmblib.c
+++ b/source3/libsmb/nmblib.c
@@ -265,7 +265,7 @@ static int parse_nmb_name(char *inbuf,int ofs,int length, struct nmb_name *name)
[15 bytes name + padding][1 byte name type].
****************************************************************************/
-static void put_name(char *dest, const char *name, int pad, unsigned int name_type)
+void put_name(char *dest, const char *name, int pad, unsigned int name_type)
{
size_t len = strlen(name);
diff --git a/source3/nsswitch/winbindd_cred_cache.c b/source3/nsswitch/winbindd_cred_cache.c
index 4c539b9b23..eb39d1dafb 100644
--- a/source3/nsswitch/winbindd_cred_cache.c
+++ b/source3/nsswitch/winbindd_cred_cache.c
@@ -113,6 +113,7 @@ static void krb5_ticket_refresh_handler(struct timed_event *te,
&entry->renew_until,
entry->ccname,
False, /* no PAC required anymore */
+ True,
WINBINDD_PAM_AUTH_KRB5_RENEW_TIME);
seteuid(0);
diff --git a/source3/nsswitch/winbindd_pam.c b/source3/nsswitch/winbindd_pam.c
index d35de4ce41..d38bdf3dfa 100644
--- a/source3/nsswitch/winbindd_pam.c
+++ b/source3/nsswitch/winbindd_pam.c
@@ -489,6 +489,7 @@ static NTSTATUS winbindd_raw_kerberos_login(struct winbindd_domain *domain,
&renewal_until,
cc,
True,
+ True,
WINBINDD_PAM_AUTH_KRB5_RENEW_TIME);
if (krb5_ret) {