mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
s3-krb: Reformat and add doxygen comment to decode_pac_data()
Signed-off-by: Günther Deschner <gd@samba.org>
This commit is contained in:
parent
43d0ef1175
commit
26e24928b3
@ -68,10 +68,20 @@ static krb5_error_code check_pac_checksum(TALLOC_CTX *mem_ctx,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
****************************************************************/
|
||||
|
||||
NTSTATUS decode_pac_data(TALLOC_CTX *mem_ctx,
|
||||
/**
|
||||
* @brief Decode a blob containing a NDR envoded PAC structure
|
||||
*
|
||||
* @param mem_ctx - The memory context
|
||||
* @param pac_data_blob - The data blob containing the NDR encoded data
|
||||
* @param context - The Kerberos Context
|
||||
* @param service_keyblock - The Service Key used to verify the checksum
|
||||
* @param client_principal - The client principal
|
||||
* @param tgs_authtime - The ticket timestamp
|
||||
* @param pac_data_out - [out] The decoded PAC
|
||||
*
|
||||
* @return - A NTSTATUS error code
|
||||
*/
|
||||
NTSTATUS decode_pac_data(TALLOC_CTX *mem_ctx,
|
||||
DATA_BLOB *pac_data_blob,
|
||||
krb5_context context,
|
||||
krb5_keyblock *service_keyblock,
|
||||
@ -127,8 +137,9 @@ static krb5_error_code check_pac_checksum(TALLOC_CTX *mem_ctx,
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
ndr_err = ndr_pull_struct_blob(pac_data_blob, pac_data_raw, pac_data_raw,
|
||||
(ndr_pull_flags_fn_t)ndr_pull_PAC_DATA_RAW);
|
||||
ndr_err = ndr_pull_struct_blob(
|
||||
pac_data_blob, pac_data_raw, pac_data_raw,
|
||||
(ndr_pull_flags_fn_t)ndr_pull_PAC_DATA_RAW);
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
|
||||
status = ndr_map_error2ntstatus(ndr_err);
|
||||
DEBUG(0,("can't parse the PAC: %s\n",
|
||||
@ -144,43 +155,48 @@ static krb5_error_code check_pac_checksum(TALLOC_CTX *mem_ctx,
|
||||
|
||||
if (pac_data->num_buffers != pac_data_raw->num_buffers) {
|
||||
/* we need logon_ingo, service_key and kdc_key */
|
||||
DEBUG(0,("misparse! PAC_DATA has %d buffers while PAC_DATA_RAW has %d\n",
|
||||
pac_data->num_buffers, pac_data_raw->num_buffers));
|
||||
DEBUG(0, ("misparse! PAC_DATA has %d buffers while "
|
||||
"PAC_DATA_RAW has %d\n", pac_data->num_buffers,
|
||||
pac_data_raw->num_buffers));
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
for (i=0; i < pac_data->num_buffers; i++) {
|
||||
if (pac_data->buffers[i].type != pac_data_raw->buffers[i].type) {
|
||||
DEBUG(0,("misparse! PAC_DATA buffer %d has type %d while PAC_DATA_RAW has %d\n",
|
||||
i, pac_data->buffers[i].type, pac_data->buffers[i].type));
|
||||
struct PAC_BUFFER *data_buf = &pac_data->buffers[i];
|
||||
struct PAC_BUFFER_RAW *raw_buf = &pac_data_raw->buffers[i];
|
||||
|
||||
if (data_buf->type != raw_buf->type) {
|
||||
DEBUG(0, ("misparse! PAC_DATA buffer %d has type "
|
||||
"%d while PAC_DATA_RAW has %d\n", i,
|
||||
data_buf->type, raw_buf->type));
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
switch (pac_data->buffers[i].type) {
|
||||
case PAC_TYPE_LOGON_INFO:
|
||||
if (!pac_data->buffers[i].info) {
|
||||
break;
|
||||
}
|
||||
logon_info = pac_data->buffers[i].info->logon_info.info;
|
||||
switch (data_buf->type) {
|
||||
case PAC_TYPE_LOGON_INFO:
|
||||
if (!data_buf->info) {
|
||||
break;
|
||||
case PAC_TYPE_SRV_CHECKSUM:
|
||||
if (!pac_data->buffers[i].info) {
|
||||
break;
|
||||
}
|
||||
srv_sig_ptr = &pac_data->buffers[i].info->srv_cksum;
|
||||
srv_sig_blob = &pac_data_raw->buffers[i].info->remaining;
|
||||
}
|
||||
logon_info = data_buf->info->logon_info.info;
|
||||
break;
|
||||
case PAC_TYPE_SRV_CHECKSUM:
|
||||
if (!data_buf->info) {
|
||||
break;
|
||||
case PAC_TYPE_KDC_CHECKSUM:
|
||||
if (!pac_data->buffers[i].info) {
|
||||
break;
|
||||
}
|
||||
kdc_sig_ptr = &pac_data->buffers[i].info->kdc_cksum;
|
||||
kdc_sig_blob = &pac_data_raw->buffers[i].info->remaining;
|
||||
break;
|
||||
case PAC_TYPE_LOGON_NAME:
|
||||
logon_name = &pac_data->buffers[i].info->logon_name;
|
||||
break;
|
||||
default:
|
||||
}
|
||||
srv_sig_ptr = &data_buf->info->srv_cksum;
|
||||
srv_sig_blob = &raw_buf->info->remaining;
|
||||
break;
|
||||
case PAC_TYPE_KDC_CHECKSUM:
|
||||
if (!data_buf->info) {
|
||||
break;
|
||||
}
|
||||
kdc_sig_ptr = &data_buf->info->kdc_cksum;
|
||||
kdc_sig_blob = &raw_buf->info->remaining;
|
||||
break;
|
||||
case PAC_TYPE_LOGON_NAME:
|
||||
logon_name = &data_buf->info->logon_name;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -204,11 +220,14 @@ static krb5_error_code check_pac_checksum(TALLOC_CTX *mem_ctx,
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* Find and zero out the signatures, as required by the signing algorithm */
|
||||
/* Find and zero out the signatures,
|
||||
* as required by the signing algorithm */
|
||||
|
||||
/* We find the data blobs above, now we parse them to get at the exact portion we should zero */
|
||||
ndr_err = ndr_pull_struct_blob(kdc_sig_blob, kdc_sig_wipe, kdc_sig_wipe,
|
||||
(ndr_pull_flags_fn_t)ndr_pull_PAC_SIGNATURE_DATA);
|
||||
/* We find the data blobs above,
|
||||
* now we parse them to get at the exact portion we should zero */
|
||||
ndr_err = ndr_pull_struct_blob(
|
||||
kdc_sig_blob, kdc_sig_wipe, kdc_sig_wipe,
|
||||
(ndr_pull_flags_fn_t)ndr_pull_PAC_SIGNATURE_DATA);
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
|
||||
status = ndr_map_error2ntstatus(ndr_err);
|
||||
DEBUG(0,("can't parse the KDC signature: %s\n",
|
||||
@ -216,8 +235,9 @@ static krb5_error_code check_pac_checksum(TALLOC_CTX *mem_ctx,
|
||||
return status;
|
||||
}
|
||||
|
||||
ndr_err = ndr_pull_struct_blob(srv_sig_blob, srv_sig_wipe, srv_sig_wipe,
|
||||
(ndr_pull_flags_fn_t)ndr_pull_PAC_SIGNATURE_DATA);
|
||||
ndr_err = ndr_pull_struct_blob(
|
||||
srv_sig_blob, srv_sig_wipe, srv_sig_wipe,
|
||||
(ndr_pull_flags_fn_t)ndr_pull_PAC_SIGNATURE_DATA);
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
|
||||
status = ndr_map_error2ntstatus(ndr_err);
|
||||
DEBUG(0,("can't parse the SRV signature: %s\n",
|
||||
@ -226,20 +246,24 @@ static krb5_error_code check_pac_checksum(TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
|
||||
/* Now zero the decoded structure */
|
||||
memset(kdc_sig_wipe->signature.data, '\0', kdc_sig_wipe->signature.length);
|
||||
memset(srv_sig_wipe->signature.data, '\0', srv_sig_wipe->signature.length);
|
||||
memset(kdc_sig_wipe->signature.data,
|
||||
'\0', kdc_sig_wipe->signature.length);
|
||||
memset(srv_sig_wipe->signature.data,
|
||||
'\0', srv_sig_wipe->signature.length);
|
||||
|
||||
/* and reencode, back into the same place it came from */
|
||||
ndr_err = ndr_push_struct_blob(kdc_sig_blob, pac_data_raw, kdc_sig_wipe,
|
||||
(ndr_push_flags_fn_t)ndr_push_PAC_SIGNATURE_DATA);
|
||||
ndr_err = ndr_push_struct_blob(
|
||||
kdc_sig_blob, pac_data_raw, kdc_sig_wipe,
|
||||
(ndr_push_flags_fn_t)ndr_push_PAC_SIGNATURE_DATA);
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
|
||||
status = ndr_map_error2ntstatus(ndr_err);
|
||||
DEBUG(0,("can't repack the KDC signature: %s\n",
|
||||
nt_errstr(status)));
|
||||
return status;
|
||||
}
|
||||
ndr_err = ndr_push_struct_blob(srv_sig_blob, pac_data_raw, srv_sig_wipe,
|
||||
(ndr_push_flags_fn_t)ndr_push_PAC_SIGNATURE_DATA);
|
||||
ndr_err = ndr_push_struct_blob(
|
||||
srv_sig_blob, pac_data_raw, srv_sig_wipe,
|
||||
(ndr_push_flags_fn_t)ndr_push_PAC_SIGNATURE_DATA);
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
|
||||
status = ndr_map_error2ntstatus(ndr_err);
|
||||
DEBUG(0,("can't repack the SRV signature: %s\n",
|
||||
@ -248,9 +272,9 @@ static krb5_error_code check_pac_checksum(TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
|
||||
/* push out the whole structure, but now with zero'ed signatures */
|
||||
ndr_err = ndr_push_struct_blob(&modified_pac_blob, pac_data_raw,
|
||||
pac_data_raw,
|
||||
(ndr_push_flags_fn_t)ndr_push_PAC_DATA_RAW);
|
||||
ndr_err = ndr_push_struct_blob(
|
||||
&modified_pac_blob, pac_data_raw, pac_data_raw,
|
||||
(ndr_push_flags_fn_t)ndr_push_PAC_DATA_RAW);
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
|
||||
status = ndr_map_error2ntstatus(ndr_err);
|
||||
DEBUG(0,("can't repack the RAW PAC: %s\n",
|
||||
@ -264,8 +288,8 @@ static krb5_error_code check_pac_checksum(TALLOC_CTX *mem_ctx,
|
||||
context,
|
||||
service_keyblock);
|
||||
if (ret) {
|
||||
DEBUG(1, ("PAC Decode: Failed to verify the service signature: %s\n",
|
||||
error_message(ret)));
|
||||
DEBUG(1, ("PAC Decode: Failed to verify the service "
|
||||
"signature: %s\n", error_message(ret)));
|
||||
return NT_STATUS_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
@ -273,29 +297,33 @@ static krb5_error_code check_pac_checksum(TALLOC_CTX *mem_ctx,
|
||||
unix_to_nt_time(&tgs_authtime_nttime, tgs_authtime);
|
||||
|
||||
if (tgs_authtime_nttime != logon_name->logon_time) {
|
||||
DEBUG(2, ("PAC Decode: Logon time mismatch between ticket and PAC!\n"));
|
||||
DEBUG(2, ("PAC Decode: PAC: %s\n", nt_time_string(mem_ctx, logon_name->logon_time)));
|
||||
DEBUG(2, ("PAC Decode: Ticket: %s\n", nt_time_string(mem_ctx, tgs_authtime_nttime)));
|
||||
DEBUG(2, ("PAC Decode: "
|
||||
"Logon time mismatch between ticket and PAC!\n"));
|
||||
DEBUG(2, ("PAC Decode: PAC: %s\n",
|
||||
nt_time_string(mem_ctx, logon_name->logon_time)));
|
||||
DEBUG(2, ("PAC Decode: Ticket: %s\n",
|
||||
nt_time_string(mem_ctx, tgs_authtime_nttime)));
|
||||
return NT_STATUS_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
ret = smb_krb5_parse_name_norealm(context, logon_name->account_name,
|
||||
&client_principal_pac);
|
||||
ret = smb_krb5_parse_name_norealm(context,
|
||||
logon_name->account_name,
|
||||
&client_principal_pac);
|
||||
if (ret) {
|
||||
DEBUG(2, ("Could not parse name from incoming PAC: [%s]: %s\n",
|
||||
logon_name->account_name,
|
||||
error_message(ret)));
|
||||
DEBUG(2, ("Could not parse name from PAC: [%s]:%s\n",
|
||||
logon_name->account_name, error_message(ret)));
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
bool_ret = smb_krb5_principal_compare_any_realm(
|
||||
context, client_principal, client_principal_pac);
|
||||
bool_ret = smb_krb5_principal_compare_any_realm(context,
|
||||
client_principal,
|
||||
client_principal_pac);
|
||||
|
||||
krb5_free_principal(context, client_principal_pac);
|
||||
|
||||
if (!bool_ret) {
|
||||
DEBUG(2, ("Name in PAC [%s] does not match principal name in ticket\n",
|
||||
logon_name->account_name));
|
||||
DEBUG(2, ("Name in PAC [%s] does not match principal name "
|
||||
"in ticket\n", logon_name->account_name));
|
||||
return NT_STATUS_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user