1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-12 20:58:37 +03:00

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 commit is contained in:
Günther Deschner 2006-04-25 12:24:25 +00:00 committed by Gerald (Jerry) Carter
parent 77407c0219
commit 8b2ba11508
9 changed files with 164 additions and 4 deletions

View File

@ -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...

View File

@ -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

View File

@ -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;

View File

@ -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 */

View File

@ -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);
}

View File

@ -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,

View File

@ -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);

View File

@ -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);

View File

@ -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) {