The branch, master has been updated via 28eae08 gensec_krb5: Implement smb_krb5_rd_req_decoded() with MIT Kerberos via 64b2b0d gensec_krb5: Create a MIT Kerberos gensec_krb5_session_info() via 32ae672 s3: winbind: refresh_sequence_number is only ever called with 'false'. via a5264b1 mit: make it possible to build with MIT kerberos and --picky-developer via cad43f2 lib: Annotate well known SID names from ccfba25 s3: auth: Use wbcAuthenticateUserEx to prime the caches.
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 28eae08ef71094f9ce053ca27a35f91e040d983c Author: Andreas Schneider <a...@samba.org> Date: Thu Aug 11 11:29:53 2016 +0200 gensec_krb5: Implement smb_krb5_rd_req_decoded() with MIT Kerberos Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Guenther Deschner <g...@samba.org> Autobuild-User(master): Günther Deschner <g...@samba.org> Autobuild-Date(master): Thu Sep 29 11:56:41 CEST 2016 on sn-devel-144 commit 64b2b0dacd1491c1801a6e3dc147afe023630dae Author: Andreas Schneider <a...@samba.org> Date: Fri Aug 12 09:21:42 2016 +0200 gensec_krb5: Create a MIT Kerberos gensec_krb5_session_info() Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Guenther Deschner <g...@samba.org> commit 32ae6721cf02412af3c5a82d5da4806f4d931bcd Author: Jeremy Allison <j...@samba.org> Date: Wed Sep 28 10:12:36 2016 -0700 s3: winbind: refresh_sequence_number is only ever called with 'false'. Remove redundant parameter. Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Ira Cooper <i...@samba.org> Reviewed-by: Guenther Deschner <g...@samba.org> commit a5264b187b9b9c777c567c8bbb39c1259c03ab9d Author: Günther Deschner <g...@samba.org> Date: Wed Sep 28 19:19:06 2016 +0200 mit: make it possible to build with MIT kerberos and --picky-developer Guenther Signed-off-by: Guenther Deschner <g...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit cad43f2cd49956a386a2911424da2854a4a1f06e Author: Steve French <smfre...@gmail.com> Date: Mon Sep 26 21:12:07 2016 -0500 lib: Annotate well known SID names Add Samba specific well known SIDs for Unix UID and GID owner. Signed-off-by: Steve French <smfre...@gmail.com> Reviewed-by: Guenther Deschner <g...@samba.org> ----------------------------------------------------------------------- Summary of changes: auth/credentials/credentials_krb5.c | 3 +- auth/kerberos/gssapi_pac.c | 3 +- libcli/security/util_sid.c | 36 +++++++++- librpc/idl/security.idl | 4 ++ source3/librpc/crypto/gse.c | 3 +- source3/winbindd/winbindd_cache.c | 37 +++++----- source4/auth/gensec/gensec_krb5.c | 123 +++++++++++++++++++++++++++++++++- source4/auth/gensec/gensec_krb5_mit.c | 102 ++++++++++++++++++++++++++++ source4/auth/gensec/wscript_build | 8 ++- 9 files changed, 293 insertions(+), 26 deletions(-) create mode 100644 source4/auth/gensec/gensec_krb5_mit.c Changeset truncated at 500 lines: diff --git a/auth/credentials/credentials_krb5.c b/auth/credentials/credentials_krb5.c index 36c8a32..4c903f2 100644 --- a/auth/credentials/credentials_krb5.c +++ b/auth/credentials/credentials_krb5.c @@ -520,6 +520,7 @@ _PUBLIC_ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred, struct ccache_container *ccache; #ifdef HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X gss_buffer_desc empty_buffer = GSS_C_EMPTY_BUFFER; + gss_OID oid = discard_const(GSS_KRB5_CRED_NO_CI_FLAGS_X); #endif krb5_enctype *etypes = NULL; @@ -645,7 +646,7 @@ _PUBLIC_ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred, * http://krbdev.mit.edu/rt/Ticket/Display.html?id=6938 */ maj_stat = gss_set_cred_option(&min_stat, &gcc->creds, - GSS_KRB5_CRED_NO_CI_FLAGS_X, + oid, &empty_buffer); if (maj_stat) { talloc_free(gcc); diff --git a/auth/kerberos/gssapi_pac.c b/auth/kerberos/gssapi_pac.c index bcc1ba4..253976a 100644 --- a/auth/kerberos/gssapi_pac.c +++ b/auth/kerberos/gssapi_pac.c @@ -112,10 +112,11 @@ NTSTATUS gssapi_obtain_pac_blob(TALLOC_CTX *mem_ctx, &pac_buffer, &pac_display_buffer, &more); if (gss_maj != 0) { + gss_OID oid = discard_const(gss_mech_krb5); DBG_NOTICE("obtaining PAC via GSSAPI gss_get_name_attribute " "failed: %s\n", gssapi_error_string(mem_ctx, gss_maj, gss_min, - gss_mech_krb5)); + oid)); return NT_STATUS_ACCESS_DENIED; } else if (authenticated && complete) { /* The PAC blob is returned directly */ diff --git a/libcli/security/util_sid.c b/libcli/security/util_sid.c index ab3018a..2f3fceb 100644 --- a/libcli/security/util_sid.c +++ b/libcli/security/util_sid.c @@ -34,85 +34,119 @@ */ +/* S-1 */ const struct dom_sid global_sid_World_Domain = /* Everyone domain */ { 1, 0, {0,0,0,0,0,1}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +/* S-1-1 */ const struct dom_sid global_sid_World = /* Everyone */ { 1, 1, {0,0,0,0,0,1}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +/* S-1-2 */ const struct dom_sid global_sid_Local_Authority = /* Local Authority */ { 1, 0, {0,0,0,0,0,2}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +/* S-1-3 */ const struct dom_sid global_sid_Creator_Owner_Domain = /* Creator Owner domain */ { 1, 0, {0,0,0,0,0,3}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +/* S-1-5 */ const struct dom_sid global_sid_NT_Authority = /* NT Authority */ { 1, 0, {0,0,0,0,0,5}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +/* S-1-5-18 */ const struct dom_sid global_sid_System = /* System */ { 1, 1, {0,0,0,0,0,5}, {18,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +/* S-1-0 */ const struct dom_sid global_sid_NULL = /* NULL sid */ { 1, 1, {0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +/* S-1-5-11 */ const struct dom_sid global_sid_Authenticated_Users = /* All authenticated rids */ { 1, 1, {0,0,0,0,0,5}, {11,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; #if 0 -/* for documentation */ +/* for documentation S-1-5-12 */ const struct dom_sid global_sid_Restriced = /* Restriced Code */ { 1, 1, {0,0,0,0,0,5}, {12,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; #endif +/* S-1-18 */ const struct dom_sid global_sid_Asserted_Identity = /* Asserted Identity */ { 1, 0, {0,0,0,0,0,18}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +/* S-1-18-1 */ const struct dom_sid global_sid_Asserted_Identity_Service = /* Asserted Identity Service */ { 1, 1, {0,0,0,0,0,18}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +/* S-1-18-2 */ const struct dom_sid global_sid_Asserted_Identity_Authentication_Authority = /* Asserted Identity Authentication Authority */ { 1, 1, {0,0,0,0,0,18}, {2,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +/* S-1-5-2 */ const struct dom_sid global_sid_Network = /* Network rids */ { 1, 1, {0,0,0,0,0,5}, {2,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +/* S-1-3 */ const struct dom_sid global_sid_Creator_Owner = /* Creator Owner */ { 1, 1, {0,0,0,0,0,3}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +/* S-1-3-1 */ const struct dom_sid global_sid_Creator_Group = /* Creator Group */ { 1, 1, {0,0,0,0,0,3}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +/* S-1-3-4 */ const struct dom_sid global_sid_Owner_Rights = /* Owner Rights */ { 1, 1, {0,0,0,0,0,3}, {4,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +/* S-1-5-7 */ const struct dom_sid global_sid_Anonymous = /* Anonymous login */ { 1, 1, {0,0,0,0,0,5}, {7,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +/* S-1-5-9 */ const struct dom_sid global_sid_Enterprise_DCs = /* Enterprise DCs */ { 1, 1, {0,0,0,0,0,5}, {9,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +/* S-1-5-32 */ const struct dom_sid global_sid_Builtin = /* Local well-known domain */ { 1, 1, {0,0,0,0,0,5}, {32,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +/* S-1-5-32-544 */ const struct dom_sid global_sid_Builtin_Administrators = /* Builtin administrators */ { 1, 2, {0,0,0,0,0,5}, {32,544,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +/* S-1-5-32-545 */ const struct dom_sid global_sid_Builtin_Users = /* Builtin users */ { 1, 2, {0,0,0,0,0,5}, {32,545,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +/* S-1-5-32-546 */ const struct dom_sid global_sid_Builtin_Guests = /* Builtin guest users */ { 1, 2, {0,0,0,0,0,5}, {32,546,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +/* S-1-5-32-547 */ const struct dom_sid global_sid_Builtin_Power_Users = /* Builtin power users */ { 1, 2, {0,0,0,0,0,5}, {32,547,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +/* S-1-5-32-548 */ const struct dom_sid global_sid_Builtin_Account_Operators = /* Builtin account operators */ { 1, 2, {0,0,0,0,0,5}, {32,548,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +/* S-1-5-32-549 */ const struct dom_sid global_sid_Builtin_Server_Operators = /* Builtin server operators */ { 1, 2, {0,0,0,0,0,5}, {32,549,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +/* S-1-5-32-550 */ const struct dom_sid global_sid_Builtin_Print_Operators = /* Builtin print operators */ { 1, 2, {0,0,0,0,0,5}, {32,550,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +/* S-1-5-32-551 */ const struct dom_sid global_sid_Builtin_Backup_Operators = /* Builtin backup operators */ { 1, 2, {0,0,0,0,0,5}, {32,551,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +/* S-1-5-32-552 */ const struct dom_sid global_sid_Builtin_Replicator = /* Builtin replicator */ { 1, 2, {0,0,0,0,0,5}, {32,552,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +/* S-1-5-32-554 */ const struct dom_sid global_sid_Builtin_PreWin2kAccess = /* Builtin pre win2k access */ { 1, 2, {0,0,0,0,0,5}, {32,554,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +/* S-1-22-1 */ const struct dom_sid global_sid_Unix_Users = /* Unmapped Unix users */ { 1, 1, {0,0,0,0,0,22}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +/* S-1-22-2 */ const struct dom_sid global_sid_Unix_Groups = /* Unmapped Unix groups */ { 1, 1, {0,0,0,0,0,22}, {2,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; /* * http://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx */ +/* S-1-5-88 */ const struct dom_sid global_sid_Unix_NFS = /* MS NFS and Apple style */ { 1, 1, {0,0,0,0,0,5}, {88,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +/* S-1-5-88-1 */ const struct dom_sid global_sid_Unix_NFS_Users = /* Unix uid, MS NFS and Apple style */ { 1, 2, {0,0,0,0,0,5}, {88,1,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +/* S-1-5-88-2 */ const struct dom_sid global_sid_Unix_NFS_Groups = /* Unix gid, MS NFS and Apple style */ { 1, 2, {0,0,0,0,0,5}, {88,2,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +/* S-1-5-88-3 */ const struct dom_sid global_sid_Unix_NFS_Mode = /* Unix mode */ { 1, 2, {0,0,0,0,0,5}, {88,3,0,0,0,0,0,0,0,0,0,0,0,0,0}}; /* Unused, left here for documentary purposes */ diff --git a/librpc/idl/security.idl b/librpc/idl/security.idl index 2ef4587..5930f44 100644 --- a/librpc/idl/security.idl +++ b/librpc/idl/security.idl @@ -278,6 +278,10 @@ interface security const string SID_BUILTIN_EVENT_LOG_READERS = "S-1-5-32-573"; const string SID_BUILTIN_CERT_SERV_DCOM_ACCESS = "S-1-5-32-574"; + /* UID/GID mapping Samba style */ + const string SID_SAMBA_UNIX_USER_OWNER = "S-1-22-1"; + const string SID_SAMBA_UNIX_GROUP_OWNER = "S-1-22-2"; + /* SECURITY_NT_SERVICE */ const string NAME_NT_SERVICE = "NT SERVICE"; diff --git a/source3/librpc/crypto/gse.c b/source3/librpc/crypto/gse.c index 7ec2cec..01ace37 100644 --- a/source3/librpc/crypto/gse.c +++ b/source3/librpc/crypto/gse.c @@ -207,6 +207,7 @@ static NTSTATUS gse_init_client(TALLOC_CTX *mem_ctx, gss_OID_set_desc mech_set; #ifdef HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X gss_buffer_desc empty_buffer = GSS_C_EMPTY_BUFFER; + gss_OID oid = discard_const(GSS_KRB5_CRED_NO_CI_FLAGS_X); #endif NTSTATUS status; @@ -281,7 +282,7 @@ static NTSTATUS gse_init_client(TALLOC_CTX *mem_ctx, * http://krbdev.mit.edu/rt/Ticket/Display.html?id=6938 */ gss_maj = gss_set_cred_option(&gss_min, &gse_ctx->creds, - GSS_KRB5_CRED_NO_CI_FLAGS_X, + oid, &empty_buffer); if (gss_maj) { DEBUG(0, ("gss_set_cred_option(GSS_KRB5_CRED_NO_CI_FLAGS_X), " diff --git a/source3/winbindd/winbindd_cache.c b/source3/winbindd/winbindd_cache.c index b921b75..2bce12d 100644 --- a/source3/winbindd/winbindd_cache.c +++ b/source3/winbindd/winbindd_cache.c @@ -518,11 +518,10 @@ static bool store_cache_seqnum( struct winbindd_domain *domain ) } /* - refresh the domain sequence number. If force is true - then always refresh it, no matter how recently we fetched it + refresh the domain sequence number on timeout. */ -static void refresh_sequence_number(struct winbindd_domain *domain, bool force) +static void refresh_sequence_number(struct winbindd_domain *domain) { NTSTATUS status; unsigned time_diff; @@ -545,7 +544,7 @@ static void refresh_sequence_number(struct winbindd_domain *domain, bool force) time_diff = t - domain->last_seq_check; /* see if we have to refetch the domain sequence number */ - if (!force && (time_diff < cache_time) && + if ((time_diff < cache_time) && (domain->sequence_number != DOM_SEQUENCE_NONE) && NT_STATUS_IS_OK(domain->last_status)) { DEBUG(10, ("refresh_sequence_number: %s time ok\n", domain->name)); @@ -719,7 +718,7 @@ static struct cache_entry *wcache_fetch(struct winbind_cache *cache, return NULL; } - refresh_sequence_number(domain, false); + refresh_sequence_number(domain); va_start(ap, format); smb_xvasprintf(&kstr, format, ap); @@ -1567,7 +1566,7 @@ do_query: (retry++ < 5)); /* and save it */ - refresh_sequence_number(domain, false); + refresh_sequence_number(domain); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -1679,7 +1678,7 @@ do_query: } } /* and save it */ - refresh_sequence_number(domain, false); + refresh_sequence_number(domain); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -1784,7 +1783,7 @@ do_query: } } /* and save it */ - refresh_sequence_number(domain, false); + refresh_sequence_number(domain); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -1899,7 +1898,7 @@ static NTSTATUS name_to_sid(struct winbindd_domain *domain, } } /* and save it */ - refresh_sequence_number(domain, false); + refresh_sequence_number(domain); if (domain->online && (NT_STATUS_IS_OK(status) || NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED))) { @@ -2013,7 +2012,7 @@ static NTSTATUS sid_to_name(struct winbindd_domain *domain, } } /* and save it */ - refresh_sequence_number(domain, false); + refresh_sequence_number(domain); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -2238,7 +2237,7 @@ static NTSTATUS rids_to_names(struct winbindd_domain *domain, return result; } - refresh_sequence_number(domain, false); + refresh_sequence_number(domain); for (i=0; i<num_rids; i++) { struct dom_sid sid; @@ -2399,7 +2398,7 @@ static NTSTATUS query_user(struct winbindd_domain *domain, } } /* and save it */ - refresh_sequence_number(domain, false); + refresh_sequence_number(domain); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -2517,7 +2516,7 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain, goto skip_save; /* and save it */ - refresh_sequence_number(domain, false); + refresh_sequence_number(domain); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -2670,7 +2669,7 @@ static NTSTATUS lookup_useraliases(struct winbindd_domain *domain, } } /* and save it */ - refresh_sequence_number(domain, false); + refresh_sequence_number(domain); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -2806,7 +2805,7 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain, } } /* and save it */ - refresh_sequence_number(domain, false); + refresh_sequence_number(domain); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -2829,7 +2828,7 @@ skip_save: /* find the sequence number for a domain */ static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32_t *seq) { - refresh_sequence_number(domain, false); + refresh_sequence_number(domain); *seq = domain->sequence_number; @@ -3007,7 +3006,7 @@ do_query: } } /* and save it */ - refresh_sequence_number(domain, false); + refresh_sequence_number(domain); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -3079,7 +3078,7 @@ do_query: } } /* and save it */ - refresh_sequence_number(domain, false); + refresh_sequence_number(domain); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -3344,7 +3343,7 @@ void cache_name2sid(struct winbindd_domain *domain, const char *domain_name, const char *name, enum lsa_SidType type, const struct dom_sid *sid) { - refresh_sequence_number(domain, false); + refresh_sequence_number(domain); wcache_save_name_to_sid(domain, NT_STATUS_OK, domain_name, name, sid, type); } diff --git a/source4/auth/gensec/gensec_krb5.c b/source4/auth/gensec/gensec_krb5.c index 1dcbb91..e1ac7367 100644 --- a/source4/auth/gensec/gensec_krb5.c +++ b/source4/auth/gensec/gensec_krb5.c @@ -664,6 +664,7 @@ static NTSTATUS gensec_krb5_update(struct gensec_security *gensec_security, &gensec_krb5_state->keyblock); if (ret) { + DBG_WARNING("smb_krb5_rd_req_decoded failed\n"); return NT_STATUS_LOGON_FAILURE; } unwrapped_out.data = (uint8_t *)outbuf.data; @@ -724,6 +725,7 @@ static NTSTATUS gensec_krb5_session_key(struct gensec_security *gensec_security, return NT_STATUS_OK; } +#ifdef SAMBA4_USES_HEIMDAL static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx, struct auth_session_info **_session_info) @@ -734,7 +736,7 @@ static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security struct auth_session_info *session_info = NULL; krb5_principal client_principal; - char *principal_string; + char *principal_string = NULL; DATA_BLOB pac_blob, *pac_blob_ptr = NULL; krb5_data pac_data; @@ -831,6 +833,125 @@ static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security talloc_free(tmp_ctx); return NT_STATUS_OK; } +#else /* MIT KERBEROS */ +static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + struct auth_session_info **psession_info) +{ + NTSTATUS status = NT_STATUS_UNSUCCESSFUL; + struct gensec_krb5_state *gensec_krb5_state = + (struct gensec_krb5_state *)gensec_security->private_data; + krb5_context context = gensec_krb5_state->smb_krb5_context->krb5_context; + struct auth_session_info *session_info = NULL; + + krb5_principal client_principal; + char *principal_string = NULL; + + krb5_authdata **auth_pac_data = NULL; + DATA_BLOB pac_blob, *pac_blob_ptr = NULL; + + krb5_error_code code; + + TALLOC_CTX *tmp_ctx; + + tmp_ctx = talloc_new(mem_ctx); + if (tmp_ctx == NULL) { + return NT_STATUS_NO_MEMORY; + } + + code = krb5_copy_principal(context, + gensec_krb5_state->ticket->enc_part2->client, + &client_principal); + if (code != 0) { + DBG_INFO("krb5_copy_principal failed to copy client " + "principal: %s\n", + smb_get_krb5_error_message(context, code, tmp_ctx)); + talloc_free(tmp_ctx); + return NT_STATUS_NO_MEMORY; + } + + code = krb5_unparse_name(context, client_principal, &principal_string); + if (code != 0) { + DBG_WARNING("Unable to parse client principal: %s\n", + smb_get_krb5_error_message(context, code, tmp_ctx)); + krb5_free_principal(context, client_principal); + talloc_free(tmp_ctx); + return NT_STATUS_NO_MEMORY; + } + + code = krb5_find_authdata(context, + gensec_krb5_state->ticket->enc_part2->authorization_data, + NULL, + KRB5_AUTHDATA_WIN2K_PAC, + &auth_pac_data); + if (code != 0) { + /* NO pac */ + DBG_INFO("krb5_find_authdata failed to find PAC: %s\n", + smb_get_krb5_error_message(context, code, tmp_ctx)); + } else { + krb5_timestamp ticket_authtime = + gensec_krb5_state->ticket->enc_part2->times.authtime; + + /* Found pac */ + pac_blob = data_blob_talloc(tmp_ctx, + auth_pac_data[0]->contents, + auth_pac_data[0]->length); + krb5_free_authdata(context, auth_pac_data); + if (pac_blob.data == NULL) { + free(principal_string); + krb5_free_principal(context, client_principal); + talloc_free(tmp_ctx); + return NT_STATUS_NO_MEMORY; + } + + /* decode and verify the pac */ + status = kerberos_decode_pac(gensec_krb5_state, + pac_blob, + context, + NULL, + gensec_krb5_state->keyblock, + client_principal, + ticket_authtime, + NULL); + + if (!NT_STATUS_IS_OK(status)) { + free(principal_string); + krb5_free_principal(context, client_principal); + talloc_free(tmp_ctx); + return status; + } + + pac_blob_ptr = &pac_blob; + } + krb5_free_principal(context, client_principal); + + status = gensec_generate_session_info_pac(tmp_ctx, + gensec_security, + gensec_krb5_state->smb_krb5_context, + pac_blob_ptr, + principal_string, + gensec_get_remote_address(gensec_security), + &session_info); + SAFE_FREE(principal_string); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(tmp_ctx); + return status; + } + + status = gensec_krb5_session_key(gensec_security, -- Samba Shared Repository