From 82a80b7f71d549e93995603a20ba119003c923fa Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Tue, 26 Jan 2010 11:09:32 -0500 Subject: s4:PAC Streamline pac-glue step 2 Split functions so that no assumption is made about which plugin is using them --- source4/kdc/pac-glue.c | 168 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 113 insertions(+), 55 deletions(-) (limited to 'source4/kdc/pac-glue.c') diff --git a/source4/kdc/pac-glue.c b/source4/kdc/pac-glue.c index 9f82f6f3b2..eb5f284d83 100644 --- a/source4/kdc/pac-glue.c +++ b/source4/kdc/pac-glue.c @@ -50,7 +50,7 @@ static NTSTATUS get_logon_info_pac_blob(TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *ic, struct auth_serversupplied_info *info, - DATA_BLOB pac_data) + DATA_BLOB *pac_data) { struct netr_SamInfo3 *info3; 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; - 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, (ndr_push_flags_fn_t)ndr_push_PAC_INFO); 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; } -static krb5_error_code make_pac(krb5_context context, - TALLOC_CTX *mem_ctx, - struct smb_iconv_convenience *iconv_convenience, - struct auth_serversupplied_info *server_info, - krb5_pac *pac) +static krb5_error_code make_krb5_pac(krb5_context context, + DATA_BLOB *pac_blob, + krb5_pac *pac) { krb5_data pac_data; - DATA_BLOB pac_out; - NTSTATUS nt_status; krb5_error_code ret; - nt_status = get_logon_info_pac_blob(mem_ctx, - 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); + ret = krb5_data_copy(&pac_data, pac_blob->data, pac_blob->length); if (ret != 0) { return ret; } @@ -124,28 +113,40 @@ static krb5_error_code make_pac(krb5_context context, return ret; } -/* 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) +static bool princ_needs_pac(struct hdb_entry_ex *princ) { - krb5_error_code ret; - NTSTATUS nt_status; - 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"); + + struct hdb_samba4_private *p = talloc_get_type(princ->ctx, struct hdb_samba4_private); 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); if (userAccountControl & UF_NO_AUTH_DATA_REQUIRED) { - *pac = NULL; - return 0; + return false; + } + + 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, @@ -159,10 +160,65 @@ static krb5_error_code samba_kdc_get_pac(void *priv, if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(0, ("Getting user info for PAC failed: %s\n", 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; } - 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); 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 *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 auth_serversupplied_info *server_info_out; - - TALLOC_CTX *mem_ctx = talloc_named(p, 0, "samba_get_pac context"); + TALLOC_CTX *mem_ctx = talloc_named(p, 0, "samba_kdc_reget_pac context"); + DATA_BLOB *pac_blob; + krb5_error_code ret; + NTSTATUS nt_status; if (!mem_ctx) { return ENOMEM; } - /* The service account may be set not to want the PAC */ - userAccountControl = ldb_msg_find_attr_as_uint(p->msg, "userAccountControl", 0); - if (userAccountControl & UF_NO_AUTH_DATA_REQUIRED) { + pac_blob = talloc_zero(mem_ctx, DATA_BLOB); + if (!pac_blob) { talloc_free(mem_ctx); - *pac = NULL; - return 0; + return ENOMEM; } - ret = kerberos_pac_to_server_info(mem_ctx, p->iconv_convenience, - *pac, context, &server_info_out); - - /* We will compleatly regenerate this pac */ - krb5_pac_free(context, *pac); + /* The user account may be set not to want the PAC */ + if ( ! princ_needs_pac(server)) { + talloc_free(mem_ctx); + return EINVAL; + } - if (ret) { + 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 ret; + return EINVAL; } - ret = make_pac(context, mem_ctx, p->iconv_convenience, server_info_out, pac); + /* We now completly regenerate this pac */ + krb5_pac_free(context, *pac); + + ret = make_krb5_pac(context, pac_blob, pac); talloc_free(mem_ctx); return ret; -- cgit