s4:s3compat Provide a replacement for ads_verify_ticket() that uses GENSEC
authorAndrew Bartlett <abartlet@samba.org>
Thu, 6 May 2010 06:45:53 +0000 (16:45 +1000)
committerAndrew Bartlett <abartlet@samba.org>
Thu, 3 Jun 2010 01:12:33 +0000 (11:12 +1000)
This should allow Samba3 to use Samba4's keytab when accepting
connections, while matching the behaviour (except for the time_t
time_offset and realm) of Samba3.

Andrew Bartlett

source4/s3compat/s3compat_authenticate.c
source4/s3compat/wscript_build

index feba4b93ac178eca8ad10621fa9fa47257254537..faf19d97a82896ce369a681a9b4db1f0de8f1c45 100644 (file)
@@ -26,6 +26,9 @@
 #include "s3_smbd_proto.h"
 #include "s3compat_authenticate.h"
 #include "smbd/service.h"
+#include "auth/credentials/credentials.h"
+#include "auth/gensec/gensec.h"
+#include "libcli/security/dom_sid.h"
 
 NTSTATUS s3compat_authenticate(TALLOC_CTX *mem_ctx, uint8_t chall[8], const struct auth_usersupplied_info *user_info, struct netr_SamInfo3 **info3) 
 {
@@ -49,7 +52,98 @@ NTSTATUS s3compat_authenticate(TALLOC_CTX *mem_ctx, uint8_t chall[8], const stru
        nt_status = auth_convert_server_info_saminfo3(mem_ctx,
                                                      server_info,
                                                      info3);
+       if (NT_STATUS_IS_OK(nt_status)) {
+               /* We need the strings from the server_info to be valid as long as the info3 is around */
+               talloc_steal(*info3, server_info);
+       }
        talloc_free(auth_context);
        return nt_status;
 }
 
+_PUBLIC_ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx,
+                                   const char *realm,
+                                   time_t time_offset,
+                                   const DATA_BLOB *ticket,
+                                   char **principal,
+                                   struct PAC_LOGON_INFO **logon_info,
+                                   DATA_BLOB *ap_rep,
+                                   DATA_BLOB *session_key,
+                                   bool use_replay_cache)
+{
+        struct stream_connection *samba3_conn;
+        struct cli_credentials *server_credentials;
+        struct auth_session_info *session_info;
+        struct gensec_security *gensec_server_context;
+        struct netr_SamInfo3 *info3;
+        NTSTATUS nt_status;
+
+        TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
+        NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
+       
+       /* This context pointer helps us get at loadparm etc */
+       samba3_conn = s3compat_get_conn();
+
+       /* Get the keytab from the credentials subsystem */
+       server_credentials = cli_credentials_init(tmp_ctx);
+       NT_STATUS_HAVE_NO_MEMORY_AND_FREE(server_credentials, tmp_ctx);
+       
+       cli_credentials_set_conf(server_credentials, samba3_conn->lp_ctx);
+       nt_status = cli_credentials_set_machine_account(server_credentials, samba3_conn->lp_ctx);
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               DEBUG(1, ("Failed to obtain server credentials, can not validate a Kerberos ticket: %s\n", nt_errstr(nt_status)));
+               talloc_free(tmp_ctx);
+               return nt_status;
+       }
+
+       /* Start up GENSEC in the same way a native Samba4 task would */
+       nt_status = samba_server_gensec_start(tmp_ctx,
+                                             samba3_conn->event.ctx,
+                                             samba3_conn->msg_ctx,
+                                             samba3_conn->lp_ctx,
+                                             server_credentials,
+                                             "cifs",
+                                             &gensec_server_context);
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               DEBUG(1, (__location__ "Failed to start server-side GENSEC for to validate a Kerberos ticket: %s\n", nt_errstr(nt_status)));
+               talloc_free(tmp_ctx);
+               return nt_status;
+       }
+
+       /* This authentication is by 'raw' krb5 because the layers
+        * above us have stripped it of it's SPNEGO and GSSAPI
+        * wrapping already */
+       nt_status = gensec_start_mech_by_name(gensec_server_context, "krb5");
+       NT_STATUS_NOT_OK_RETURN_AND_FREE(nt_status, tmp_ctx);
+
+       /* Do a client-server update dance */
+       nt_status = gensec_update(gensec_server_context, tmp_ctx, *ticket, ap_rep);
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               DEBUG(1, ("Client requested a Kerberos option that requires more processing.  Not supported in s3compat"));
+               NT_STATUS_NOT_OK_RETURN_AND_FREE(nt_status, tmp_ctx);
+       }
+
+       /* Now return the session key and PAC information to the callers */
+       nt_status = gensec_session_key(gensec_server_context, session_key);
+       NT_STATUS_NOT_OK_RETURN_AND_FREE(nt_status, tmp_ctx);
+
+       nt_status = gensec_session_info(gensec_server_context, &session_info);
+       NT_STATUS_NOT_OK_RETURN_AND_FREE(nt_status, tmp_ctx);
+       
+       *logon_info = talloc_zero(tmp_ctx, struct PAC_LOGON_INFO);
+       NT_STATUS_HAVE_NO_MEMORY_AND_FREE(*logon_info, tmp_ctx);
+       nt_status = auth_convert_server_info_saminfo3(*logon_info,
+                                                     session_info->server_info,
+                                                     &info3);
+       NT_STATUS_NOT_OK_RETURN_AND_FREE(nt_status, tmp_ctx);
+
+       *principal = talloc_asprintf(mem_ctx, "%s@%s", info3->base.account_name.string, info3->base.domain.string);
+       NT_STATUS_HAVE_NO_MEMORY_AND_FREE(*principal, tmp_ctx);
+
+       /* I know this structure assignment sucks, but at least the talloc tree is reasonable, as logon_info is used as the talloc context */
+       (*logon_info)->info3 = *info3;
+
+       talloc_steal(mem_ctx, tmp_ctx);
+
+       return NT_STATUS_OK;
+}
+
index 5de23ff2f6d3a936be42cd6f748225e69f9c84be..0bd7af521658b330ba3476a9a9966e4b4762cc02 100644 (file)
@@ -201,10 +201,6 @@ LIBADS_SRC = '''libads/ldap.c libads/ldap_printer.c
              libads/disp_sec.c libads/ads_utils.c libads/ldap_utils.c
              libads/ldap_schema.c libads/util.c libads/ndr.c'''
 
-LIBADS_SERVER_SRC = '''libads/kerberos_verify.c libads/authdata.c
-                    ../librpc/ndr/ndr_krb5pac.c
-                    ../librpc/gen_ndr/ndr_krb5pac.c'''
-
 SECRETS_SRC = '''librpc/gen_ndr/ndr_secrets.c'''
 
 LIBNBT_SRC = '''../libcli/nbt/nbtname.c
@@ -645,7 +641,6 @@ WINBINDD_SRC = '''${WINBINDD_SRC1}
                   ${LIBADS_SRC} ${KRBCLIENT_SRC} ${POPT_LIB_SRC}
                   ${DCUTIL_SRC} ${IDMAP_SRC} ${NSS_INFO_SRC}
                   ${AFS_SRC} ${AFS_SETTOKEN_SRC}
-                  ${LIBADS_SERVER_SRC}
                   ${TDB_VALIDATE_SRC}'''
 
 LIBNET_SRC = 'libnet/libnet_join.c libnet/libnet_keytab.c librpc/gen_ndr/ndr_libnet_join.c'
@@ -725,7 +720,7 @@ SMBD_SRC_BASE = '''${LIBADS_SRC} ${SMBD_SRC_SRV}
                 ${OPLOCK_SRC} ${NOTIFY_SRC} ${FNAME_UTIL_SRC}
                 ${LIBMSRPC_SRC}
                 ${LIBMSRPC_GEN_SRC} ${AVAHI_SRC}
-                ${KRBCLIENT_SRC} ${LIBADS_SERVER_SRC} ${REG_FULL_SRC}
+                ${KRBCLIENT_SRC} ${REG_FULL_SRC}
                 ${POPT_LIB_SRC} ${SMBLDAP_SRC}
                 ${LIBNET_SRC}
                 ${RPC_LSA_SRC}