summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/auth/auth_sam_reply.c109
-rw-r--r--source4/auth/config.mk1
-rw-r--r--source4/auth/gensec/config.mk4
-rw-r--r--source4/auth/gensec/gensec_krb5.c6
-rw-r--r--source4/auth/kerberos/config.mk1
-rw-r--r--source4/auth/kerberos/kerberos.h7
-rw-r--r--source4/auth/kerberos/kerberos_pac.c182
-rw-r--r--source4/auth/kerberos/kerberos_verify.c17
-rw-r--r--source4/heimdal_build/config.mk4
-rw-r--r--source4/kdc/config.mk3
-rw-r--r--source4/kdc/hdb-ldb.c10
-rw-r--r--source4/kdc/kdc.c4
-rw-r--r--source4/kdc/kdc.h4
-rw-r--r--source4/kdc/pac-glue.c79
-rw-r--r--source4/librpc/idl/krb5pac.idl16
-rw-r--r--source4/librpc/idl/netlogon.idl6
-rw-r--r--source4/librpc/idl/samr.idl14
-rw-r--r--source4/rpc_server/netlogon/dcerpc_netlogon.c65
-rw-r--r--source4/rpc_server/samr/dcesrv_samr.c8
-rw-r--r--source4/torture/rpc/samsync.c4
20 files changed, 426 insertions, 118 deletions
diff --git a/source4/auth/auth_sam_reply.c b/source4/auth/auth_sam_reply.c
new file mode 100644
index 0000000000..2ff071f737
--- /dev/null
+++ b/source4/auth/auth_sam_reply.c
@@ -0,0 +1,109 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Convert a server info struct into the form for PAC and NETLOGON replies
+
+ Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004
+ Copyright (C) Stefan Metzmacher <metze@samba.org> 2005
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "librpc/gen_ndr/ndr_netlogon.h"
+#include "rpc_server/dcerpc_server.h"
+#include "rpc_server/common/common.h"
+#include "librpc/gen_ndr/ndr_dcom.h"
+#include "auth/auth.h"
+#include "lib/ldb/include/ldb.h"
+
+NTSTATUS auth_convert_server_info_sambaseinfo(TALLOC_CTX *mem_ctx,
+ struct auth_serversupplied_info *server_info,
+ struct netr_SamBaseInfo **_sam)
+{
+ struct netr_SamBaseInfo *sam = talloc_zero(mem_ctx, struct netr_SamBaseInfo);
+ NT_STATUS_HAVE_NO_MEMORY(sam);
+
+ sam->last_logon = server_info->last_logon;
+ sam->last_logoff = server_info->last_logoff;
+ sam->acct_expiry = server_info->acct_expiry;
+ sam->last_password_change = server_info->last_password_change;
+ sam->allow_password_change = server_info->allow_password_change;
+ sam->force_password_change = server_info->force_password_change;
+
+ sam->account_name.string = server_info->account_name;
+ sam->full_name.string = server_info->full_name;
+ sam->logon_script.string = server_info->logon_script;
+ sam->profile_path.string = server_info->profile_path;
+ sam->home_directory.string = server_info->home_directory;
+ sam->home_drive.string = server_info->home_drive;
+
+ sam->logon_count = server_info->logon_count;
+ sam->bad_password_count = sam->bad_password_count;
+ sam->rid = server_info->account_sid->sub_auths[server_info->account_sid->num_auths-1];
+ sam->primary_gid = server_info->primary_group_sid->sub_auths[server_info->primary_group_sid->num_auths-1];
+
+ sam->groups.count = 0;
+ sam->groups.rids = NULL;
+
+ if (server_info->n_domain_groups > 0) {
+ int i;
+ sam->groups.rids = talloc_array(sam, struct samr_RidWithAttribute,
+ server_info->n_domain_groups);
+
+ if (sam->groups.rids == NULL)
+ return NT_STATUS_NO_MEMORY;
+
+ for (i=0; i<server_info->n_domain_groups; i++) {
+
+ struct dom_sid *group_sid = server_info->domain_groups[i];
+ sam->groups.rids[sam->groups.count].rid =
+ group_sid->sub_auths[group_sid->num_auths-1];
+
+ sam->groups.rids[sam->groups.count].attributes =
+ SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED;
+ sam->groups.count += 1;
+ }
+ }
+
+ sam->user_flags = 0; /* TODO: w2k3 uses 0x120. We know 0x20
+ * as extra sids (PAC doc) but what is
+ * 0x100? */
+ sam->acct_flags = server_info->acct_flags;
+ sam->logon_server.string = lp_netbios_name();
+ sam->domain.string = server_info->domain_name;
+
+ sam->domain_sid = dom_sid_dup(mem_ctx, server_info->account_sid);
+ NT_STATUS_HAVE_NO_MEMORY(sam->domain_sid);
+ sam->domain_sid->num_auths--;
+
+ ZERO_STRUCT(sam->unknown);
+
+ ZERO_STRUCT(sam->key);
+ if (server_info->user_session_key.length == sizeof(sam->key.key)) {
+ memcpy(sam->key.key, server_info->user_session_key.data, sizeof(sam->key.key));
+ }
+
+ ZERO_STRUCT(sam->LMSessKey);
+ if (server_info->lm_session_key.length == sizeof(sam->LMSessKey.key)) {
+ memcpy(sam->LMSessKey.key, server_info->lm_session_key.data,
+ sizeof(sam->LMSessKey.key));
+ }
+
+ *_sam = sam;
+
+ return NT_STATUS_OK;
+}
+
diff --git a/source4/auth/config.mk b/source4/auth/config.mk
index 37c6ddc931..405f776830 100644
--- a/source4/auth/config.mk
+++ b/source4/auth/config.mk
@@ -76,6 +76,7 @@ INIT_OBJ_FILES = \
auth/auth.o
ADD_OBJ_FILES = \
auth/auth_util.o \
+ auth/auth_sam_reply.o \
auth/ntlm_check.o
# End SUBSYSTEM AUTH
#######################
diff --git a/source4/auth/gensec/config.mk b/source4/auth/gensec/config.mk
index 34587e2e45..03f7f24848 100644
--- a/source4/auth/gensec/config.mk
+++ b/source4/auth/gensec/config.mk
@@ -14,7 +14,7 @@ REQUIRED_SUBSYSTEMS = \
SUBSYSTEM = GENSEC
INIT_FUNCTION = gensec_krb5_init
INIT_OBJ_FILES = auth/gensec/gensec_krb5.o
-REQUIRED_SUBSYSTEMS = NDR_KRB5PAC KERBEROS KERBEROS_LIB AUTH
+REQUIRED_SUBSYSTEMS = KERBEROS AUTH
# End MODULE gensec_krb5
################################################
@@ -24,7 +24,7 @@ REQUIRED_SUBSYSTEMS = NDR_KRB5PAC KERBEROS KERBEROS_LIB AUTH
SUBSYSTEM = GENSEC
INIT_FUNCTION = gensec_gssapi_init
INIT_OBJ_FILES = auth/gensec/gensec_gssapi.o
-REQUIRED_SUBSYSTEMS = KERBEROS_LIB AUTH
+REQUIRED_SUBSYSTEMS = KERBEROS AUTH
# End MODULE gensec_gssapi
################################################
diff --git a/source4/auth/gensec/gensec_krb5.c b/source4/auth/gensec/gensec_krb5.c
index c8367d33f7..bd705531bd 100644
--- a/source4/auth/gensec/gensec_krb5.c
+++ b/source4/auth/gensec/gensec_krb5.c
@@ -47,7 +47,7 @@ struct gensec_krb5_state {
krb5_auth_context auth_context;
krb5_ccache ccache;
krb5_data ticket;
- krb5_keyblock keyblock;
+ krb5_keyblock *keyblock;
char *peer_principal;
};
@@ -61,8 +61,8 @@ static int gensec_krb5_destory(void *ptr)
}
/* ccache freed in a child destructor */
- krb5_free_keyblock_contents(gensec_krb5_state->smb_krb5_context->krb5_context,
- &gensec_krb5_state->keyblock);
+ krb5_free_keyblock(gensec_krb5_state->smb_krb5_context->krb5_context,
+ &gensec_krb5_state->keyblock);
if (gensec_krb5_state->auth_context) {
krb5_auth_con_free(gensec_krb5_state->smb_krb5_context->krb5_context,
diff --git a/source4/auth/kerberos/config.mk b/source4/auth/kerberos/config.mk
index 62710f3cc4..56ce64fdb1 100644
--- a/source4/auth/kerberos/config.mk
+++ b/source4/auth/kerberos/config.mk
@@ -8,5 +8,6 @@ ADD_OBJ_FILES = \
auth/kerberos/kerberos_util.o \
auth/kerberos/kerberos_pac.o \
auth/kerberos/gssapi_parse.o
+REQUIRED_SUBSYSTEMS = KERBEROS_LIB NDR_KRB5PAC
# End SUBSYSTEM KERBEROS
#################################
diff --git a/source4/auth/kerberos/kerberos.h b/source4/auth/kerberos/kerberos.h
index ca0bbbed0e..1fd48197f8 100644
--- a/source4/auth/kerberos/kerberos.h
+++ b/source4/auth/kerberos/kerberos.h
@@ -97,7 +97,7 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx,
const DATA_BLOB *ticket,
char **principal, DATA_BLOB *auth_data,
DATA_BLOB *ap_rep,
- krb5_keyblock *keyblock);
+ krb5_keyblock **keyblock);
int kerberos_kinit_password_cc(krb5_context ctx, krb5_ccache cc,
const char *principal, const char *password,
time_t *expire_time, time_t *kdc_time);
@@ -132,5 +132,10 @@ NTSTATUS kerberos_decode_pac(TALLOC_CTX *mem_ctx,
DATA_BLOB blob,
struct smb_krb5_context *smb_krb5_context,
krb5_keyblock *keyblock);
+krb5_error_code kerberos_encode_pac(TALLOC_CTX *mem_ctx,
+ struct auth_serversupplied_info *server_info,
+ krb5_context context,
+ krb5_keyblock *keyblock,
+ krb5_data *pac);
#endif /* HAVE_KRB5 */
diff --git a/source4/auth/kerberos/kerberos_pac.c b/source4/auth/kerberos/kerberos_pac.c
index 9d57245798..e1d05b9949 100644
--- a/source4/auth/kerberos/kerberos_pac.c
+++ b/source4/auth/kerberos/kerberos_pac.c
@@ -28,16 +28,16 @@
#include "system/kerberos.h"
#include "system/time.h"
#include "system/network.h"
+#include "auth/auth.h"
#include "auth/kerberos/kerberos.h"
#include "librpc/gen_ndr/ndr_krb5pac.h"
#include "auth/auth.h"
-static NTSTATUS kerberos_pac_checksum(TALLOC_CTX *mem_ctx,
- DATA_BLOB pac_data,
- struct PAC_SIGNATURE_DATA *sig,
- struct smb_krb5_context *smb_krb5_context,
- krb5_keyblock *keyblock,
- uint32_t keyusage)
+static NTSTATUS check_pac_checksum(TALLOC_CTX *mem_ctx,
+ DATA_BLOB pac_data,
+ struct PAC_SIGNATURE_DATA *sig,
+ krb5_context context,
+ krb5_keyblock *keyblock)
{
krb5_error_code ret;
krb5_crypto crypto;
@@ -48,7 +48,7 @@ static NTSTATUS kerberos_pac_checksum(TALLOC_CTX *mem_ctx,
cksum.checksum.data = sig->signature;
- ret = krb5_crypto_init(smb_krb5_context->krb5_context,
+ ret = krb5_crypto_init(context,
keyblock,
0,
&crypto);
@@ -56,7 +56,7 @@ static NTSTATUS kerberos_pac_checksum(TALLOC_CTX *mem_ctx,
DEBUG(0,("krb5_crypto_init() failed\n"));
return NT_STATUS_FOOBAR;
}
- ret = krb5_verify_checksum(smb_krb5_context->krb5_context,
+ ret = krb5_verify_checksum(context,
crypto,
KRB5_KU_OTHER_CKSUM,
pac_data.data,
@@ -64,10 +64,10 @@ static NTSTATUS kerberos_pac_checksum(TALLOC_CTX *mem_ctx,
&cksum);
if (ret) {
DEBUG(2, ("PAC Verification failed: %s\n",
- smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, mem_ctx)));
+ smb_get_krb5_error_message(context, ret, mem_ctx)));
}
- krb5_crypto_destroy(smb_krb5_context->krb5_context, crypto);
+ krb5_crypto_destroy(context, crypto);
if (ret) {
return NT_STATUS_ACCESS_DENIED;
@@ -92,6 +92,8 @@ static NTSTATUS kerberos_pac_checksum(TALLOC_CTX *mem_ctx,
DATA_BLOB modified_pac_blob = data_blob_talloc(mem_ctx, blob.data, blob.length);
int i;
+ file_save("/tmp/pac.in", blob.data, blob.length);
+
status = ndr_pull_struct_blob(&blob, mem_ctx, &pac_data,
(ndr_pull_flags_fn_t)ndr_pull_PAC_DATA);
if (!NT_STATUS_IS_OK(status)) {
@@ -127,7 +129,7 @@ static NTSTATUS kerberos_pac_checksum(TALLOC_CTX *mem_ctx,
kdc_sig_ptr = &pac_data.buffers[i].info->kdc_cksum;
kdc_sig = pac_data.buffers[i].info->kdc_cksum;
break;
- case PAC_TYPE_UNKNOWN_10:
+ case PAC_TYPE_LOGON_NAME:
break;
default:
break;
@@ -154,11 +156,13 @@ static NTSTATUS kerberos_pac_checksum(TALLOC_CTX *mem_ctx,
memset(&modified_pac_blob.data[modified_pac_blob.length - 44],
'\0', 16);
- /* verify by servie_key */
- status = kerberos_pac_checksum(mem_ctx,
- modified_pac_blob, &srv_sig,
- smb_krb5_context, keyblock, 0);
+ file_save("/tmp/pac.in.blanked", modified_pac_blob.data, modified_pac_blob.length);
+ /* verify by service_key */
+ status = check_pac_checksum(mem_ctx,
+ modified_pac_blob, &srv_sig,
+ smb_krb5_context->krb5_context, keyblock);
+
if (!NT_STATUS_IS_OK(status)) {
return status;
}
@@ -170,3 +174,151 @@ static NTSTATUS kerberos_pac_checksum(TALLOC_CTX *mem_ctx,
return status;
}
+static krb5_error_code make_pac_checksum(TALLOC_CTX *mem_ctx,
+ DATA_BLOB pac_data,
+ struct PAC_SIGNATURE_DATA *sig,
+ krb5_context context,
+ krb5_keyblock *keyblock)
+{
+ krb5_error_code ret;
+ krb5_crypto crypto;
+ Checksum cksum;
+
+
+ ret = krb5_crypto_init(context,
+ keyblock,
+ 0,
+ &crypto);
+ if (ret) {
+ DEBUG(0,("krb5_crypto_init() failed\n"));
+ return ret;
+ }
+ ret = krb5_create_checksum(context,
+ crypto,
+ KRB5_KU_OTHER_CKSUM,
+ 0,
+ pac_data.data,
+ pac_data.length,
+ &cksum);
+ if (ret) {
+ DEBUG(2, ("PAC Verification failed: %s\n",
+ smb_get_krb5_error_message(context, ret, mem_ctx)));
+ }
+
+ krb5_crypto_destroy(context, crypto);
+
+ if (ret) {
+ return ret;
+ }
+
+ sig->type = cksum.cksumtype;
+ if (cksum.checksum.length == sizeof(sig->signature)) {
+ memcpy(sig->signature, cksum.checksum.data, sizeof(sig->signature));
+ }
+
+ return 0;
+}
+
+ krb5_error_code kerberos_encode_pac(TALLOC_CTX *mem_ctx,
+ struct auth_serversupplied_info *server_info,
+ krb5_context context,
+ krb5_keyblock *keyblock,
+ krb5_data *pac)
+{
+ NTSTATUS nt_status;
+ DATA_BLOB tmp_blob = data_blob(NULL, 0);
+ krb5_error_code ret;
+ struct PAC_DATA *pac_data = talloc(mem_ctx, struct PAC_DATA);
+ struct netr_SamBaseInfo *sam;
+ struct timeval tv = timeval_current();
+
+ if (!pac_data) {
+ return ENOMEM;
+ }
+
+ pac_data->num_buffers = 4;
+ pac_data->version = 0;
+
+ pac_data->buffers = talloc_array(pac_data,
+ struct PAC_BUFFER,
+ pac_data->num_buffers);
+
+ if (!pac_data->buffers) {
+ talloc_free(pac_data);
+ return ENOMEM;
+ }
+ pac_data->buffers[0].type = PAC_TYPE_LOGON_INFO;
+ pac_data->buffers[0].info = talloc_zero(pac_data->buffers,
+ union PAC_INFO);
+
+ nt_status = auth_convert_server_info_sambaseinfo(pac_data->buffers[0].info,
+ server_info, &sam);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ DEBUG(1, ("Getting Samba info failed: %s\n", nt_errstr(nt_status)));
+ talloc_free(pac_data);
+ return EINVAL;
+ }
+
+ pac_data->buffers[0].info->logon_info.info3.base = *sam;
+
+ pac_data->buffers[1].type = PAC_TYPE_LOGON_NAME;
+ pac_data->buffers[1].info = talloc_zero(pac_data->buffers,
+ union PAC_INFO);
+ pac_data->buffers[1].info->logon_name.account_name
+ = server_info->account_name;
+ pac_data->buffers[1].info->logon_name.logon_time
+ = timeval_to_nttime(&tv);
+
+ pac_data->buffers[2].type = PAC_TYPE_KDC_CHECKSUM;
+ pac_data->buffers[2].info = talloc_zero(pac_data->buffers,
+ union PAC_INFO);
+
+ pac_data->buffers[3].type = PAC_TYPE_SRV_CHECKSUM;
+ pac_data->buffers[3].info = talloc_zero(pac_data->buffers,
+ union PAC_INFO);
+
+ /* First, just get the keytypes filled in (and lengths right, eventually) */
+ ret = make_pac_checksum(mem_ctx, tmp_blob, &pac_data->buffers[2].info->srv_cksum,
+ context, keyblock);
+ if (ret) {
+ DEBUG(2, ("making PAC checksum failed: %s\n",
+ smb_get_krb5_error_message(context, ret, mem_ctx)));
+ talloc_free(pac_data);
+ return ret;
+ }
+
+ /* But wipe out the actual signatures */
+ ZERO_STRUCT(pac_data->buffers[2].info->kdc_cksum.signature);
+ ZERO_STRUCT(pac_data->buffers[3].info->srv_cksum.signature);
+
+ nt_status = ndr_push_struct_blob(&tmp_blob, mem_ctx, pac_data,
+ (ndr_push_flags_fn_t)ndr_push_PAC_DATA);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ DEBUG(1, ("PAC push failed: %s\n", nt_errstr(nt_status)));
+ talloc_free(pac_data);
+ return EINVAL;
+ }
+
+ file_save("/tmp/pac.out.blank", tmp_blob.data, tmp_blob.length);
+
+ /* Then sign the result of the previous push, where the sig was zero'ed out */
+ ret = make_pac_checksum(mem_ctx, tmp_blob, &pac_data->buffers[3].info->srv_cksum,
+ context, keyblock);
+
+ /* And push it out to the world. This relies on determanistic pointer values */
+ nt_status = ndr_push_struct_blob(&tmp_blob, mem_ctx, pac_data,
+ (ndr_push_flags_fn_t)ndr_push_PAC_DATA);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ DEBUG(1, ("PAC push failed: %s\n", nt_errstr(nt_status)));
+ talloc_free(pac_data);
+ return EINVAL;
+ }
+
+ file_save("/tmp/pac.out.signed", tmp_blob.data, tmp_blob.length);
+
+ ret = krb5_data_copy(pac, tmp_blob.data, tmp_blob.length);
+
+ talloc_free(pac_data);
+ return ret;
+}
+
diff --git a/source4/auth/kerberos/kerberos_verify.c b/source4/auth/kerberos/kerberos_verify.c
index 01b8a75c95..b140eb6ae9 100644
--- a/source4/auth/kerberos/kerberos_verify.c
+++ b/source4/auth/kerberos/kerberos_verify.c
@@ -75,7 +75,7 @@ static krb5_error_code ads_keytab_verify_ticket(TALLOC_CTX *mem_ctx, krb5_contex
const char *service,
const DATA_BLOB *ticket, krb5_data *p_packet,
krb5_ticket **pp_tkt,
- krb5_keyblock *keyblock)
+ krb5_keyblock **keyblock)
{
krb5_error_code ret = 0;
krb5_keytab keytab = NULL;
@@ -149,7 +149,9 @@ static krb5_error_code ads_keytab_verify_ticket(TALLOC_CTX *mem_ctx, krb5_contex
p_packet->length = ticket->length;
p_packet->data = (krb5_pointer)ticket->data;
*pp_tkt = NULL;
- ret = krb5_rd_req(context, &auth_context, p_packet, kt_entry.principal, keytab, NULL, pp_tkt);
+ ret = krb5_rd_req_return_keyblock(context, &auth_context, p_packet,
+ kt_entry.principal, keytab,
+ NULL, pp_tkt, keyblock);
if (ret) {
last_error_message = smb_get_krb5_error_message(context, ret, mem_ctx);
DEBUG(10, ("ads_keytab_verify_ticket: krb5_rd_req(%s) failed: %s\n",
@@ -224,7 +226,7 @@ static krb5_error_code ads_secrets_verify_ticket(TALLOC_CTX *mem_ctx,
krb5_principal salt_princ,
const DATA_BLOB *ticket, krb5_data *p_packet,
krb5_ticket **pp_tkt,
- krb5_keyblock *keyblock)
+ krb5_keyblock **keyblock)
{
krb5_error_code ret = 0;
krb5_error_code our_ret;
@@ -274,9 +276,10 @@ static krb5_error_code ads_secrets_verify_ticket(TALLOC_CTX *mem_ctx,
krb5_free_keyblock(context, key);
- our_ret = krb5_rd_req(context, &auth_context, p_packet,
- NULL,
- NULL, NULL, pp_tkt);
+ our_ret = krb5_rd_req_return_keyblock(context, &auth_context, p_packet,
+ NULL,
+ NULL, NULL, pp_tkt,
+ keyblock);
if (!our_ret) {
DEBUG(10,("ads_secrets_verify_ticket: enc type [%u] decrypted message !\n",
@@ -311,7 +314,7 @@ static krb5_error_code ads_secrets_verify_ticket(TALLOC_CTX *mem_ctx,
const DATA_BLOB *ticket,
char **principal, DATA_BLOB *auth_data,
DATA_BLOB *ap_rep,
- krb5_keyblock *keyblock)
+ krb5_keyblock **keyblock)
{
NTSTATUS sret = NT_STATUS_LOGON_FAILURE;
krb5_data packet;
diff --git a/source4/heimdal_build/config.mk b/source4/heimdal_build/config.mk
index a376ceb9e4..8d46c536f1 100644
--- a/source4/heimdal_build/config.mk
+++ b/source4/heimdal_build/config.mk
@@ -1,6 +1,7 @@
#######################
# Start SUBSYSTEM HEIMDAL_KDC
[SUBSYSTEM::HEIMDAL_KDC]
+TARGET_CFLAGS = -Iheimdal_build -Iheimdal/kdc -Iheimdal/lib/des -Iheimdal/lib/roken -Iheimdal/include
ADD_OBJ_FILES = \
heimdal/kdc/default_config.o \
heimdal/kdc/kerberos5.o \
@@ -18,6 +19,7 @@ NOPROTO = YES
#######################
# Start SUBSYSTEM HEIMDAL_HDB
[SUBSYSTEM::HEIMDAL_HDB]
+TARGET_CFLAGS = -Iheimdal_build -Iheimdal/kdc -Iheimdal/lib/des -Iheimdal/lib/roken -Iheimdal/include
ADD_OBJ_FILES = \
heimdal/lib/hdb/db.o \
heimdal/lib/hdb/hdb.o \
@@ -372,7 +374,7 @@ REQUIRED_SUBSYSTEMS = ASN1_COMPILER
NOPROTO = YES
TARGET_CFLAGS = -Iheimdal_build -Iheimdal/kdc -Iheimdal/lib/des -Iheimdal/lib/roken -Iheimdal/include
REQUIRED_SUBSYSTEMS = \
- HEIMDAL_KDC HEIMDAL_HDB HEIMDAL_GSSAPI HEIMDAL_KRB5 \
+ HEIMDAL_GSSAPI HEIMDAL_KRB5 \
HEIMDAL_ASN1 HEIMDAL_DES HEIMDAL_ROKEN HEIMDAL_COM_ERR
# End SUBSYSTEM HEIMDAL
#######################
diff --git a/source4/kdc/config.mk b/source4/kdc/config.mk
index b1de650faa..ce655dea82 100644
--- a/source4/kdc/config.mk
+++ b/source4/kdc/config.mk
@@ -5,8 +5,9 @@
[SUBSYSTEM::KDC]
INIT_OBJ_FILES = \
kdc/kdc.o \
+ kdc/pac-glue.o \
kdc/hdb-ldb.o
REQUIRED_SUBSYSTEMS = \
- LIBLDB KERBEROS_LIB
+ LIBLDB KERBEROS_LIB HEIMDAL_KDC HEIMDAL_HDB
# End SUBSYSTEM KDC
#######################
diff --git a/source4/kdc/hdb-ldb.c b/source4/kdc/hdb-ldb.c
index 231d7db436..0875803be0 100644
--- a/source4/kdc/hdb-ldb.c
+++ b/source4/kdc/hdb-ldb.c
@@ -40,7 +40,8 @@
#include "system/iconv.h"
enum hdb_ldb_ent_type
-{ HDB_LDB_ENT_TYPE_CLIENT, HDB_LDB_ENT_TYPE_SERVER, HDB_LDB_ENT_TYPE_KRBTGT, HDB_LDB_ENT_TYPE_ANY };
+{ HDB_LDB_ENT_TYPE_CLIENT, HDB_LDB_ENT_TYPE_SERVER,
+ HDB_LDB_ENT_TYPE_KRBTGT, HDB_LDB_ENT_TYPE_ANY };
static const char * const krb5_attrs[] = {
"objectClass",
@@ -980,9 +981,10 @@ static krb5_error_code LDB_destroy(krb5_context context, HDB *db)
return 0;
}
-krb5_error_code hdb_ldb_create(krb5_context context, struct HDB **db, const char *arg)
+krb5_error_code hdb_ldb_create(TALLOC_CTX *mem_ctx,
+ krb5_context context, struct HDB **db, const char *arg)
{
- *db = talloc(NULL, HDB);
+ *db = talloc(mem_ctx, HDB);
if (!*db) {
krb5_set_error_string(context, "malloc: out of memory");
return ENOMEM;
@@ -990,8 +992,8 @@ krb5_error_code hdb_ldb_create(krb5_context context, struct HDB **db, const char
(*db)->hdb_master_key_set = 0;
(*db)->hdb_db = NULL;
- /* in future, we could cache the connect here, but for now KISS */
+ /* Setup the link to LDB */
(*db)->hdb_db = samdb_connect(db);
if ((*db)->hdb_db == NULL) {
krb5_warnx(context, "hdb_ldb_create: samdb_connect failed!");
diff --git a/source4/kdc/kdc.c b/source4/kdc/kdc.c
index 8a7e497913..a1958b54fa 100644
--- a/source4/kdc/kdc.c
+++ b/source4/kdc/kdc.c
@@ -29,6 +29,8 @@
#include "system/network.h"
#include "dlinklist.h"
+
+
/*
handle fd send events on a KDC socket
*/
@@ -276,7 +278,7 @@ static void kdc_task_init(struct task_server *task)
}
kdc->config->num_db = 1;
- ret = hdb_ldb_create(kdc->smb_krb5_context->krb5_context,
+ ret = hdb_ldb_create(kdc, kdc->smb_krb5_context->krb5_context,
&kdc->config->db[0], lp_sam_url());
if (ret != 0) {
DEBUG(1, ("kdc_task_init: hdb_ldb_create fails: %s\n",
diff --git a/source4/kdc/kdc.h b/source4/kdc/kdc.h
index 25f643eadd..d59fa3e2e7 100644
--- a/source4/kdc/kdc.h
+++ b/source4/kdc/kdc.h
@@ -24,8 +24,10 @@
#include "system/kerberos.h"
#include "auth/kerberos/kerberos.h"
#include "heimdal/kdc/kdc.h"
+#include "kdc/pac-glue.h"
-krb5_error_code hdb_ldb_create(krb5_context context, struct HDB **db, const char *arg);
+krb5_error_code hdb_ldb_create(TALLOC_CTX *mem_ctx,
+ krb5_context context, struct HDB **db, const char *arg);
/* hold all the info needed to send a reply */
struct kdc_reply {
diff --git a/source4/kdc/pac-glue.c b/source4/kdc/pac-glue.c
new file mode 100644
index 0000000000..40d11d31e9
--- /dev/null
+++ b/source4/kdc/pac-glue.c
@@ -0,0 +1,79 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ PAC Glue between Samba and the KDC
+
+ Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "kdc/kdc.h"
+
+ krb5_error_code samba_get_pac(krb5_context context,
+ struct krb5_kdc_configuration *config,
+ krb5_principal client,
+ krb5_keyblock *keyblock,
+ krb5_data *pac)
+{
+ krb5_error_code ret;
+ NTSTATUS nt_status;
+ struct auth_serversupplied_info *server_info;
+ char *username, *p;
+ const char *realm;
+ TALLOC_CTX *mem_ctx = talloc_named(config, 0, "samba_get_pac context");
+ if (!mem_ctx) {
+ return ENOMEM;
+ }
+
+ ret = krb5_unparse_name(context, client, &username);
+
+ if (ret != 0) {
+ krb5_set_error_string(context, "get pac: could not parse principal");
+ krb5_warnx(context, "get pac: could not parse principal");
+ talloc_free(mem_ctx);
+ return ret;
+ }
+
+ /* parse the principal name */
+ realm = krb5_principal_get_realm(context, client);
+ username = talloc_strdup(mem_ctx, username);
+ p = strchr(username, '@');
+ if (p) {
+ p[0] = '\0';
+ }
+
+
+ nt_status = sam_get_server_info(mem_ctx, username, realm,
+ data_blob(NULL, 0), data_blob(NULL, 0),
+ &server_info);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ DEBUG(0, ("Getting user info for PAC failed: %s\n",
+ nt_errstr(nt_status)));
+ talloc_free(mem_ctx);
+ return EINVAL;
+ }
+
+ ret = kerberos_encode_pac(mem_ctx, server_info,
+ context,
+ keyblock,
+ pac);
+
+ talloc_free(mem_ctx);
+
+ return ret;
+}
diff --git a/source4/librpc/idl/krb5pac.idl b/source4/librpc/idl/krb5pac.idl
index 16524197c5..e3395f8961 100644
--- a/source4/librpc/idl/krb5pac.idl
+++ b/source4/librpc/idl/krb5pac.idl
@@ -16,37 +16,39 @@ interface krb5pac
typedef struct {
NTTIME logon_time;
[flag(STR_SIZE2|STR_NOTERM|STR_BYTESIZE)] string account_name;
- } PAC_UNKNOWN_10;
+ [value(0)] uint32 _pad;
+ } PAC_LOGON_NAME;
typedef [flag(NDR_PAHEX)] struct {
uint32 type;
uint8 signature[16];
+ [value(0)] uint32 _pad;
} PAC_SIGNATURE_DATA;
typedef struct {
uint32 unknown[5];
netr_SamInfo3 info3;
dom_sid2 *res_group_dom_sid;
- samr_RidWithTypeArray res_groups;
+ samr_RidWithAttributeArray res_groups;
} PAC_LOGON_INFO;
const uint8 PAC_TYPE_LOGON_INFO = 1;
const uint8 PAC_TYPE_SRV_CHECKSUM = 6;
const uint8 PAC_TYPE_KDC_CHECKSUM = 7;
- const uint8 PAC_TYPE_UNKNOWN_10 = 10;
+ const uint8 PAC_TYPE_LOGON_NAME = 10;
- typedef [nodiscriminant] union {
+ typedef [nodiscriminant,gensize,flag(NDR_ALIGN8)] union {
[case(PAC_TYPE_LOGON_INFO)] PAC_LOGON_INFO logon_info;
[case(PAC_TYPE_SRV_CHECKSUM)] PAC_SIGNATURE_DATA srv_cksum;
[case(PAC_TYPE_KDC_CHECKSUM)] PAC_SIGNATURE_DATA kdc_cksum;
- [case(PAC_TYPE_UNKNOWN_10)] PAC_UNKNOWN_10 type_10;
+ [case(PAC_TYPE_LOGON_NAME)] PAC_LOGON_NAME logon_name;
} PAC_INFO;
typedef struct {
uint32 type;
- uint32 size;
+ [value(ndr_size_PAC_INFO(info,type,ndr->flags))] uint32 size;
[relative,switch_is(type)] PAC_INFO *info;
- uint32 _pad;
+ [value(0)] uint32 _pad; /* Top half of a 64 bit pointer? */
} PAC_BUFFER;
typedef [public,flag(NDR_ALIGN8)] struct {
diff --git a/source4/librpc/idl/netlogon.idl b/source4/librpc/idl/netlogon.idl
index 8301a6cf40..f73dc24f47 100644
--- a/source4/librpc/idl/netlogon.idl
+++ b/source4/librpc/idl/netlogon.idl
@@ -140,6 +140,10 @@ interface netlogon
uint8 key[8];
} netr_LMSessionKey;
+ /* Flags for user_flags below */
+ const int NETLOGON_EXTRA_SIDS = 0x0020;
+ const int NETLOGON_RESOURCE_GROUPS = 0x0200;
+
typedef struct {
NTTIME last_logon;
NTTIME last_logoff;
@@ -157,7 +161,7 @@ interface netlogon
uint16 bad_password_count;
uint32 rid;
uint32 primary_gid;
- samr_RidWithTypeArray groups;
+ samr_RidWithAttributeArray groups;
uint32 user_flags;
netr_UserSessionKey key;
netr_String logon_server;
diff --git a/source4/librpc/idl/samr.idl b/source4/librpc/idl/samr.idl
index cf61011387..a989d09486 100644
--- a/source4/librpc/idl/samr.idl
+++ b/source4/librpc/idl/samr.idl
@@ -357,6 +357,10 @@
[out,ref] policy_handle *group_handle
);
+ /* Group attributes */
+ const int SE_GROUP_MANDATORY = 0x0001;
+ const int SE_GROUP_ENABLED_BY_DEFAULT = 0x0002;
+ const int SE_GROUP_ENABLED = 0x0004;
/************************/
/* Function 0x14 */
@@ -816,17 +820,17 @@
typedef [public] struct {
uint32 rid;
- uint32 type;
- } samr_RidWithType;
+ uint32 attributes;
+ } samr_RidWithAttribute;
typedef [public] struct {
uint32 count;
- [size_is(count)] samr_RidWithType *rids;
- } samr_RidWithTypeArray;
+ [size_is(count)] samr_RidWithAttribute *rids;
+ } samr_RidWithAttributeArray;
NTSTATUS samr_GetGroupsForUser(
[in,ref] policy_handle *user_handle,
- [out] samr_RidWithTypeArray *rids
+ [out] samr_RidWithAttributeArray *rids
);
/************************/
diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
index 4dd8312df5..1317ea31a9 100644
--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
@@ -503,64 +503,9 @@ static NTSTATUS netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_
nt_status = auth_check_password(auth_context, mem_ctx, user_info, &server_info);
NT_STATUS_NOT_OK_RETURN(nt_status);
- sam = talloc_zero(mem_ctx, struct netr_SamBaseInfo);
- NT_STATUS_HAVE_NO_MEMORY(sam);
-
- sam->last_logon = server_info->last_logon;
- sam->last_logoff = server_info->last_logoff;
- sam->acct_expiry = server_info->acct_expiry;
- sam->last_password_change = server_info->last_password_change;
- sam->allow_password_change = server_info->allow_password_change;
- sam->force_password_change = server_info->force_password_change;
-
- sam->account_name.string = server_info->account_name;
- sam->full_name.string = server_info->full_name;
- sam->logon_script.string = server_info->logon_script;
- sam->profile_path.string = server_info->profile_path;
- sam->home_directory.string = server_info->home_directory;
- sam->home_drive.string = server_info->home_drive;
-
- sam->logon_count = server_info->logon_count;
- sam->bad_password_count = sam->bad_password_count;
- sam->rid = server_info->account_sid->sub_auths[server_info->account_sid->num_auths-1];
- sam->primary_gid = server_info->primary_group_sid->sub_auths[server_info->primary_group_sid->num_auths-1];
-
- sam->groups.count = 0;
- sam->groups.rids = NULL;
-
- if (server_info->n_domain_groups > 0) {
- int i;
- sam->groups.rids = talloc_array(mem_ctx, struct samr_RidWithType,
- server_info->n_domain_groups);
-
- if (sam->groups.rids == NULL)
- return NT_STATUS_NO_MEMORY;
-
- for (i=0; i<server_info->n_domain_groups; i++) {
-
- struct dom_sid *group_sid = server_info->domain_groups[i];
- sam->groups.rids[sam->groups.count].rid =
- group_sid->sub_auths[group_sid->num_auths-1];
- sam->groups.rids[sam->groups.count].type = 7;
- sam->groups.count += 1;
- }
- }
-
- sam->user_flags = 0; /* TODO: w2k3 uses 0x120 - what is this? */
- sam->acct_flags = server_info->acct_flags;
- sam->logon_server.string = lp_netbios_name();
- sam->domain.string = server_info->domain_name;
-
- sam->domain_sid = dom_sid_dup(mem_ctx, server_info->account_sid);
- NT_STATUS_HAVE_NO_MEMORY(sam->domain_sid);
- sam->domain_sid->num_auths--;
-
- ZERO_STRUCT(sam->unknown);
+ nt_status = auth_convert_server_info_sambaseinfo(mem_ctx, server_info, &sam);
- ZERO_STRUCT(sam->key);
- if (server_info->user_session_key.length == sizeof(sam->key.key)) {
- memcpy(sam->key.key, server_info->user_session_key.data, sizeof(sam->key.key));
- }
+ NT_STATUS_NOT_OK_RETURN(nt_status);
/* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
/* It appears that level 6 is not individually encrypted */
@@ -576,12 +521,6 @@ static NTSTATUS netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_
}
}
- ZERO_STRUCT(sam->LMSessKey);
- if (server_info->lm_session_key.length == sizeof(sam->LMSessKey.key)) {
- memcpy(sam->LMSessKey.key, server_info->lm_session_key.data,
- sizeof(sam->LMSessKey.key));
- }
-
/* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
/* It appears that level 6 is not individually encrypted */
if ((r->in.validation_level != 6)
diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c
index cce446533d..66f327b6f9 100644
--- a/source4/rpc_server/samr/dcesrv_samr.c
+++ b/source4/rpc_server/samr/dcesrv_samr.c
@@ -2757,7 +2757,7 @@ static NTSTATUS samr_GetGroupsForUser(struct dcesrv_call_state *dce_call, TALLOC
struct samr_domain_state *d_state;
struct ldb_message **res;
const char * const attrs[2] = { "objectSid", NULL };
- struct samr_RidWithTypeArray *array;
+ struct samr_RidWithAttributeArray *array;
int count;
DCESRV_PULL_HANDLE(h, r->in.user_handle, SAMR_HANDLE_USER);
@@ -2774,7 +2774,7 @@ static NTSTATUS samr_GetGroupsForUser(struct dcesrv_call_state *dce_call, TALLOC
if (count < 0)
return NT_STATUS_INTERNAL_DB_CORRUPTION;
- array = talloc(mem_ctx, struct samr_RidWithTypeArray);
+ array = talloc(mem_ctx, struct samr_RidWithAttributeArray);
if (array == NULL)
return NT_STATUS_NO_MEMORY;
@@ -2783,7 +2783,7 @@ static NTSTATUS samr_GetGroupsForUser(struct dcesrv_call_state *dce_call, TALLOC
if (count > 0) {
int i;
- array->rids = talloc_array(mem_ctx, struct samr_RidWithType,
+ array->rids = talloc_array(mem_ctx, struct samr_RidWithAttribute,
count);
if (array->rids == NULL)
@@ -2801,7 +2801,7 @@ static NTSTATUS samr_GetGroupsForUser(struct dcesrv_call_state *dce_call, TALLOC
array->rids[array->count].rid =
group_sid->sub_auths[group_sid->num_auths-1];
- array->rids[array->count].type = 7;
+ array->rids[array->count].attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED;
array->count += 1;
}
}
diff --git a/source4/torture/rpc/samsync.c b/source4/torture/rpc/samsync.c
index 652fef15c3..29e66ec4c3 100644
--- a/source4/torture/rpc/samsync.c
+++ b/source4/torture/rpc/samsync.c
@@ -629,8 +629,8 @@ static BOOL samsync_handle_user(TALLOC_CTX *mem_ctx, struct samsync_state *samsy
for (j = 0; j < count; j++) {
if ((getgroups.out.rids->rids[i].rid ==
info3->base.groups.rids[j].rid)
- && (getgroups.out.rids->rids[i].type ==
- info3->base.groups.rids[j].type)) {
+ && (getgroups.out.rids->rids[i].attributes ==
+ info3->base.groups.rids[j].attributes)) {
matched[i] = True;
}
}