Print this page
NEX-18907 File Access Auditing does not work with SMB Kerberos authentication
Review by: Gordon Ross <gordon.ross@nexenta.com>
Review by: Evan Layton <evan.layton@nexenta.com>
NEX-3080 SMB1 signing problem with Kerberos auth.
Reviewed by: Bayard Bell <bayard.bell@nexenta.com>
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
Reviewed by: Matt Barden <Matt.Barden@nexenta.com>
NEX-1810 extended security Kerberos (inbound)
SMB-56 extended security NTLMSSP, inbound

@@ -8,11 +8,11 @@
  * source.  A copy of the CDDL is also available via the Internet at
  * http://www.illumos.org/license/CDDL.
  */
 
 /*
- * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
+ * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
  */
 
 /*
  * SPNEGO back-end for Kerberos.  See [MS-KILE]
  */

@@ -117,10 +117,11 @@
         OM_uint32 major, minor, ret_flags;
         gss_OID name_type = GSS_C_NULL_OID;
         gss_OID mech_type = GSS_C_NULL_OID;
         krb5_error_code kerr;
         uint32_t status;
+        smb_token_t *token = NULL;
 
         intok.length = ctx->ctx_ibodylen;
         intok.value  = ctx->ctx_ibodybuf;
         bzero(&outtok, sizeof (gss_buffer_desc));
         bzero(&namebuf, sizeof (gss_buffer_desc));

@@ -131,10 +132,13 @@
                 smbd_report("krb5ssp, krb5_init_ctx: %s",
                     krb5_get_error_message(be->be_kctx, kerr));
                 return (NT_STATUS_INTERNAL_ERROR);
         }
 
+        free(be->be_username);
+        be->be_username = NULL;
+
         major = gss_accept_sec_context(&minor, &be->be_gssctx,
             GSS_C_NO_CREDENTIAL, &intok,
             GSS_C_NO_CHANNEL_BINDINGS, &gname, &mech_type, &outtok,
             &ret_flags, NULL, NULL);
 

@@ -156,11 +160,12 @@
                 smbd_report("krb5ssp: gss_accept_sec_context, "
                     "mech=0x%x, major=0x%x, minor=0x%x",
                     (int)mech_type, major, minor);
                 smbd_report(" krb5: %s",
                     krb5_get_error_message(be->be_kctx, minor));
-                return (NT_STATUS_WRONG_PASSWORD);
+                status = NT_STATUS_WRONG_PASSWORD;
+                goto out;
         }
 
         switch (major) {
         case GSS_S_COMPLETE:
                 break;

@@ -168,13 +173,15 @@
                 if (outtok.length > 0) {
                         ctx->ctx_orawtype = LSA_MTYPE_ES_CONT;
                         /* becomes NT_STATUS_MORE_PROCESSING_REQUIRED */
                         return (0);
                 }
-                return (NT_STATUS_WRONG_PASSWORD);
+                status = NT_STATUS_WRONG_PASSWORD;
+                goto out;
         default:
-                return (NT_STATUS_WRONG_PASSWORD);
+                status = NT_STATUS_WRONG_PASSWORD;
+                goto out;
         }
 
         /*
          * OK, we got GSS_S_COMPLETE.  Get the name so we can use it
          * in log messages if we get failures decoding the PAC etc.

@@ -196,48 +203,65 @@
          * Extract the KRB5_AUTHDATA_WIN2K_PAC data.
          */
         status = get_authz_data_pac(be->be_gssctx,
             &be->be_authz_pac);
         if (status)
-                return (status);
+                goto out;
 
         kerr = krb5_pac_parse(be->be_kctx, be->be_authz_pac.value,
             be->be_authz_pac.length, &be->be_kpac);
         if (kerr) {
                 smbd_report("krb5ssp, krb5_pac_parse: %s",
                     krb5_get_error_message(be->be_kctx, kerr));
-                return (NT_STATUS_UNSUCCESSFUL);
+                status = NT_STATUS_UNSUCCESSFUL;
+                goto out;
         }
 
         kerr = krb5_pac_get_buffer(be->be_kctx, be->be_kpac,
             PAC_LOGON_INFO, &be->be_pac);
         if (kerr) {
                 smbd_report("krb5ssp, krb5_pac_get_buffer: %s",
                     krb5_get_error_message(be->be_kctx, kerr));
-                return (NT_STATUS_UNSUCCESSFUL);
+                status = NT_STATUS_UNSUCCESSFUL;
+                goto out;
         }
 
         ctx->ctx_token = calloc(1, sizeof (smb_token_t));
-        if (ctx->ctx_token == NULL)
-                return (NT_STATUS_NO_MEMORY);
-
+        if (ctx->ctx_token == NULL) {
+                status = NT_STATUS_NO_MEMORY;
+                goto out;
+        }
         status = smb_decode_krb5_pac(ctx->ctx_token, be->be_pac.data,
             be->be_pac.length);
         if (status)
-                return (status);
+                goto out;
 
         status = get_ssnkey(ctx);
         if (status)
-                return (status);
+                goto out;
 
-        if (!smb_token_setup_common(ctx->ctx_token))
-                return (NT_STATUS_UNSUCCESSFUL);
+        if (!smb_token_setup_common(ctx->ctx_token)) {
+                status = NT_STATUS_UNSUCCESSFUL;
+                goto out;
+        }
 
         /* Success! */
         ctx->ctx_orawtype = LSA_MTYPE_ES_DONE;
 
-        return (0);
+        status = 0;
+        token = ctx->ctx_token;
+
+        /*
+         * Before we return, audit successful and failed logons.
+         * We only audit logons where we should have a username.
+         */
+out:
+        if (!smbd_logon_audit(token, &ctx->ctx_clinfo.lci_clnt_ipaddr,
+            be->be_username, "") && status == 0)
+                return (NT_STATUS_AUDIT_FAILED);
+
+        return (status);
 }
 
 /*
  * See: GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_OID
  * and: KRB5_AUTHDATA_WIN2K_PAC