mirror of
https://github.com/samba-team/samba.git
synced 2024-12-22 13:34:15 +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 used to be commit 8b2ba11508
)
This commit is contained in:
parent
66fd215dc7
commit
351e749246
@ -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...
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user