1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-26 10:04:02 +03:00

s4:PAC Streamline pac-glue step 2

Split functions so that no assumption is made about which plugin
is using them
This commit is contained in:
Simo Sorce 2010-01-26 11:09:32 -05:00
parent 85e3561dc9
commit 82a80b7f71

View File

@ -50,7 +50,7 @@ static NTSTATUS
get_logon_info_pac_blob(TALLOC_CTX *mem_ctx, get_logon_info_pac_blob(TALLOC_CTX *mem_ctx,
struct smb_iconv_convenience *ic, struct smb_iconv_convenience *ic,
struct auth_serversupplied_info *info, struct auth_serversupplied_info *info,
DATA_BLOB pac_data) DATA_BLOB *pac_data)
{ {
struct netr_SamInfo3 *info3; struct netr_SamInfo3 *info3;
union PAC_INFO pac_info; union PAC_INFO pac_info;
@ -73,7 +73,7 @@ get_logon_info_pac_blob(TALLOC_CTX *mem_ctx,
pac_info.logon_info.info->info3 = *info3; pac_info.logon_info.info->info3 = *info3;
ndr_err = ndr_push_union_blob(&pac_data, mem_ctx, ic, &pac_info, ndr_err = ndr_push_union_blob(pac_data, mem_ctx, ic, &pac_info,
PAC_TYPE_LOGON_INFO, PAC_TYPE_LOGON_INFO,
(ndr_push_flags_fn_t)ndr_push_PAC_INFO); (ndr_push_flags_fn_t)ndr_push_PAC_INFO);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
@ -86,25 +86,14 @@ get_logon_info_pac_blob(TALLOC_CTX *mem_ctx,
return NT_STATUS_OK; return NT_STATUS_OK;
} }
static krb5_error_code make_pac(krb5_context context, static krb5_error_code make_krb5_pac(krb5_context context,
TALLOC_CTX *mem_ctx, DATA_BLOB *pac_blob,
struct smb_iconv_convenience *iconv_convenience, krb5_pac *pac)
struct auth_serversupplied_info *server_info,
krb5_pac *pac)
{ {
krb5_data pac_data; krb5_data pac_data;
DATA_BLOB pac_out;
NTSTATUS nt_status;
krb5_error_code ret; krb5_error_code ret;
nt_status = get_logon_info_pac_blob(mem_ctx, ret = krb5_data_copy(&pac_data, pac_blob->data, pac_blob->length);
iconv_convenience,
server_info, pac_out);
if (!NT_STATUS_IS_OK(nt_status)) {
return EINVAL;
}
ret = krb5_data_copy(&pac_data, pac_out.data, pac_out.length);
if (ret != 0) { if (ret != 0) {
return ret; return ret;
} }
@ -124,28 +113,40 @@ static krb5_error_code make_pac(krb5_context context,
return ret; return ret;
} }
/* Given the right private pointer from hdb_samba4, get a PAC from the attached ldb messages */ static bool princ_needs_pac(struct hdb_entry_ex *princ)
static krb5_error_code samba_kdc_get_pac(void *priv,
krb5_context context,
struct hdb_entry_ex *client,
krb5_pac *pac)
{ {
krb5_error_code ret;
NTSTATUS nt_status; struct hdb_samba4_private *p = talloc_get_type(princ->ctx, struct hdb_samba4_private);
struct auth_serversupplied_info *server_info;
struct hdb_samba4_private *p = talloc_get_type(client->ctx, struct hdb_samba4_private);
TALLOC_CTX *mem_ctx = talloc_named(p, 0, "samba_get_pac context");
unsigned int userAccountControl; unsigned int userAccountControl;
if (!mem_ctx) {
return ENOMEM;
}
/* The user account may be set not to want the PAC */ /* The service account may be set not to want the PAC */
userAccountControl = ldb_msg_find_attr_as_uint(p->msg, "userAccountControl", 0); userAccountControl = ldb_msg_find_attr_as_uint(p->msg, "userAccountControl", 0);
if (userAccountControl & UF_NO_AUTH_DATA_REQUIRED) { if (userAccountControl & UF_NO_AUTH_DATA_REQUIRED) {
*pac = NULL; return false;
return 0; }
return true;
}
static NTSTATUS samba_kdc_get_pac_blob(TALLOC_CTX *mem_ctx,
struct hdb_entry_ex *client,
DATA_BLOB **_pac_blob)
{
struct hdb_samba4_private *p = talloc_get_type(client->ctx, struct hdb_samba4_private);
struct auth_serversupplied_info *server_info;
DATA_BLOB *pac_blob;
NTSTATUS nt_status;
/* The user account may be set not to want the PAC */
if ( ! princ_needs_pac(client)) {
*_pac_blob = NULL;
return NT_STATUS_OK;
}
pac_blob = talloc_zero(mem_ctx, DATA_BLOB);
if (!pac_blob) {
return NT_STATUS_NO_MEMORY;
} }
nt_status = authsam_make_server_info(mem_ctx, p->samdb, nt_status = authsam_make_server_info(mem_ctx, p->samdb,
@ -159,10 +160,65 @@ static krb5_error_code samba_kdc_get_pac(void *priv,
if (!NT_STATUS_IS_OK(nt_status)) { if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(0, ("Getting user info for PAC failed: %s\n", DEBUG(0, ("Getting user info for PAC failed: %s\n",
nt_errstr(nt_status))); nt_errstr(nt_status)));
return nt_status;
}
nt_status = get_logon_info_pac_blob(mem_ctx,
p->iconv_convenience,
server_info, pac_blob);
if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(0, ("Building PAC failed: %s\n",
nt_errstr(nt_status)));
return nt_status;
}
*_pac_blob = pac_blob;
return NT_STATUS_OK;
}
static NTSTATUS samba_kdc_update_pac_blob(TALLOC_CTX *mem_ctx,
krb5_context context,
struct smb_iconv_convenience *ic,
krb5_pac *pac, DATA_BLOB *pac_blob)
{
struct auth_serversupplied_info *server_info;
krb5_error_code ret;
NTSTATUS nt_status;
ret = kerberos_pac_to_server_info(mem_ctx, ic, *pac,
context, &server_info);
if (ret) {
return NT_STATUS_UNSUCCESSFUL;
}
nt_status = samba_get_logon_info_pac_blob(mem_ctx, ic,
server_info, pac_blob);
return nt_status;
}
/* Given the right private pointer from hdb_samba4, get a PAC from the attached ldb messages */
static krb5_error_code samba_kdc_get_pac(void *priv, krb5_context context,
struct hdb_entry_ex *client,
krb5_pac *pac)
{
TALLOC_CTX *mem_ctx;
DATA_BLOB *pac_blob;
krb5_error_code ret;
NTSTATUS nt_status;
mem_ctx = talloc_named(client->ctx, 0, "samba_get_pac context");
if (!mem_ctx) {
return ENOMEM; return ENOMEM;
} }
ret = make_pac(context, mem_ctx, p->iconv_convenience, server_info, pac); nt_status = samba_kdc_get_pac_blob(mem_ctx, client, &pac_blob);
if (!NT_STATUS_IS_OK(nt_status)) {
talloc_free(mem_ctx);
return EINVAL;
}
ret = make_krb5_pac(context, pac_blob, pac);
talloc_free(mem_ctx); talloc_free(mem_ctx);
return ret; return ret;
@ -175,40 +231,42 @@ static krb5_error_code samba_kdc_reget_pac(void *priv, krb5_context context,
struct hdb_entry_ex *client, struct hdb_entry_ex *client,
struct hdb_entry_ex *server, krb5_pac *pac) struct hdb_entry_ex *server, krb5_pac *pac)
{ {
krb5_error_code ret;
unsigned int userAccountControl;
struct hdb_samba4_private *p = talloc_get_type(server->ctx, struct hdb_samba4_private); struct hdb_samba4_private *p = talloc_get_type(server->ctx, struct hdb_samba4_private);
TALLOC_CTX *mem_ctx = talloc_named(p, 0, "samba_kdc_reget_pac context");
struct auth_serversupplied_info *server_info_out; DATA_BLOB *pac_blob;
krb5_error_code ret;
TALLOC_CTX *mem_ctx = talloc_named(p, 0, "samba_get_pac context"); NTSTATUS nt_status;
if (!mem_ctx) { if (!mem_ctx) {
return ENOMEM; return ENOMEM;
} }
/* The service account may be set not to want the PAC */ pac_blob = talloc_zero(mem_ctx, DATA_BLOB);
userAccountControl = ldb_msg_find_attr_as_uint(p->msg, "userAccountControl", 0); if (!pac_blob) {
if (userAccountControl & UF_NO_AUTH_DATA_REQUIRED) {
talloc_free(mem_ctx); talloc_free(mem_ctx);
*pac = NULL; return ENOMEM;
return 0;
} }
ret = kerberos_pac_to_server_info(mem_ctx, p->iconv_convenience, /* The user account may be set not to want the PAC */
*pac, context, &server_info_out); if ( ! princ_needs_pac(server)) {
talloc_free(mem_ctx);
return EINVAL;
}
/* We will compleatly regenerate this pac */ nt_status = samba_kdc_update_pac_blob(mem_ctx, context,
p->iconv_convenience,
pac, pac_blob);
if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(0, ("Building PAC failed: %s\n",
nt_errstr(nt_status)));
talloc_free(mem_ctx);
return EINVAL;
}
/* We now completly regenerate this pac */
krb5_pac_free(context, *pac); krb5_pac_free(context, *pac);
if (ret) { ret = make_krb5_pac(context, pac_blob, pac);
talloc_free(mem_ctx);
return ret;
}
ret = make_pac(context, mem_ctx, p->iconv_convenience, server_info_out, pac);
talloc_free(mem_ctx); talloc_free(mem_ctx);
return ret; return ret;