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-13644 File access audit logging
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
NEX-15558 SMB logon fails during 1st second after service start
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-15558 SMB logon fails during 1st second after service start
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-8707 smb/server in 4.0.x does not accept username@hostname
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
NEX-4083 Upstream changes from illumos 5917 and 5995
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
SMB-149 mount.cifs RedHat\Centos 6 doesn't work with default security options
        
*** 18,28 ****
   *
   * CDDL HEADER END
   */
  /*
   * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
!  * Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
   */
  
  #include <sys/types.h>
  #include <errno.h>
  #include <synch.h>
--- 18,28 ----
   *
   * CDDL HEADER END
   */
  /*
   * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
!  * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
   */
  
  #include <sys/types.h>
  #include <errno.h>
  #include <synch.h>
*** 74,124 ****
  static smb_audit_t *smbd_audit_unlink(uint32_t);
  
  
  /*
   * Invoked at user logon due to SmbSessionSetupX.  Authenticate the
!  * user, start an audit session and audit the event.
   */
  smb_token_t *
  smbd_user_auth_logon(smb_logon_t *user_info)
  {
          smb_token_t *token;
-         smb_audit_t *entry;
-         adt_session_data_t *ah;
-         adt_event_data_t *event;
          smb_logon_t tmp_user;
!         au_tid_addr_t termid;
!         char sidbuf[SMB_SID_STRSZ];
!         char *username;
!         char *domain;
!         uid_t uid;
!         gid_t gid;
!         char *sid;
!         int status;
!         int retval;
  
          if (user_info->lg_username == NULL ||
              user_info->lg_domain == NULL ||
              user_info->lg_workstation == NULL) {
                  return (NULL);
          }
  
          tmp_user = *user_info;
          if (tmp_user.lg_username[0] == '\0') {
                  tmp_user.lg_flags |= SMB_ATF_ANON;
                  tmp_user.lg_e_username = "anonymous";
          } else {
                  tmp_user.lg_e_username = tmp_user.lg_username;
          }
          tmp_user.lg_e_domain = tmp_user.lg_domain;
  
!         if ((token = smb_logon(&tmp_user)) == NULL) {
                  uid = ADT_NO_ATTRIB;
                  gid = ADT_NO_ATTRIB;
                  sid = NT_NULL_SIDSTR;
!                 username = tmp_user.lg_e_username;
!                 domain = tmp_user.lg_e_domain;
                  status = ADT_FAILURE;
                  retval = ADT_FAIL_VALUE_AUTH;
          } else {
                  uid = token->tkn_user.i_id;
                  gid = token->tkn_primary_grp.i_id;
--- 74,182 ----
  static smb_audit_t *smbd_audit_unlink(uint32_t);
  
  
  /*
   * Invoked at user logon due to SmbSessionSetupX.  Authenticate the
!  * user.
!  *
!  * On error, returns NULL, and status in user_info->lg_status
   */
  smb_token_t *
  smbd_user_auth_logon(smb_logon_t *user_info)
  {
          smb_token_t *token;
          smb_logon_t tmp_user;
!         char *p;
!         char *buf = NULL;
  
          if (user_info->lg_username == NULL ||
              user_info->lg_domain == NULL ||
              user_info->lg_workstation == NULL) {
+                 user_info->lg_status = NT_STATUS_INVALID_PARAMETER;
                  return (NULL);
          }
  
+         /*
+          * Avoid modifying the caller-provided struct because it
+          * may or may not point to allocated strings etc.
+          * Copy to tmp_user, auth, then copy the (out) lg_status
+          * member back to the caller-provided struct.
+          */
          tmp_user = *user_info;
          if (tmp_user.lg_username[0] == '\0') {
                  tmp_user.lg_flags |= SMB_ATF_ANON;
                  tmp_user.lg_e_username = "anonymous";
          } else {
                  tmp_user.lg_e_username = tmp_user.lg_username;
          }
+ 
+         /* Handle user@domain format. */
+         if (tmp_user.lg_domain[0] == '\0' &&
+             (p = strchr(tmp_user.lg_e_username, '@')) != NULL) {
+                 buf = strdup(tmp_user.lg_e_username);
+                 p = buf + (p - tmp_user.lg_e_username);
+                 *p = '\0';
+                 tmp_user.lg_e_domain = p + 1;
+                 tmp_user.lg_e_username = buf;
+         } else {
                  tmp_user.lg_e_domain = tmp_user.lg_domain;
+         }
  
!         token = smb_logon(&tmp_user);
!         user_info->lg_status = tmp_user.lg_status;
! 
!         if (token == NULL) {
!                 if (user_info->lg_status == 0) /* should not happen */
!                         user_info->lg_status = NT_STATUS_INTERNAL_ERROR;
!         }
! 
!         if (!smbd_logon_audit(token, &user_info->lg_clnt_ipaddr,
!             tmp_user.lg_e_username, tmp_user.lg_e_domain)) {
!                 user_info->lg_status = NT_STATUS_AUDIT_FAILED;
!                 goto errout;
!         }
! 
!         if (token) {
!                 smb_autohome_add(token);
!         }
! 
!         if (buf != NULL)
!                 free(buf);
! 
!         return (token);
! 
! errout:
!         if (buf != NULL)
!                 free(buf);
!         smb_token_destroy(token);
!         return (NULL);
! }
! 
! /* Start an audit session and audit the event. */
! boolean_t
! smbd_logon_audit(smb_token_t *token, smb_inaddr_t *ipaddr, char *username,
!     char *domain)
! {
!         smb_audit_t *entry;
!         adt_session_data_t *ah = NULL;
!         adt_event_data_t *event;
!         au_tid_addr_t termid;
!         char sidbuf[SMB_SID_STRSZ];
!         uid_t uid;
!         gid_t gid;
!         char *sid;
!         int status;
!         int retval;
! 
!         if (username == NULL)
!                 username = "";
! 
!         if (token == NULL) {
                  uid = ADT_NO_ATTRIB;
                  gid = ADT_NO_ATTRIB;
                  sid = NT_NULL_SIDSTR;
!                 /* use the 'default' username and domain we were given */
                  status = ADT_FAILURE;
                  retval = ADT_FAIL_VALUE_AUTH;
          } else {
                  uid = token->tkn_user.i_id;
                  gid = token->tkn_primary_grp.i_id;
*** 130,170 ****
                  retval = ADT_SUCCESS;
          }
  
          if (adt_start_session(&ah, NULL, 0)) {
                  syslog(LOG_AUTH | LOG_ALERT, "adt_start_session: %m");
!                 smb_token_destroy(token);
!                 return (NULL);
          }
  
          if ((event = adt_alloc_event(ah, ADT_smbd_session)) == NULL) {
                  syslog(LOG_AUTH | LOG_ALERT,
                      "adt_alloc_event(ADT_smbd_session): %m");
!                 (void) adt_end_session(ah);
!                 smb_token_destroy(token);
!                 return (NULL);
          }
  
          (void) memset(&termid, 0, sizeof (au_tid_addr_t));
!         termid.at_port = user_info->lg_local_port;
  
!         if (user_info->lg_clnt_ipaddr.a_family == AF_INET) {
!                 termid.at_addr[0] = user_info->lg_clnt_ipaddr.a_ipv4;
                  termid.at_type = AU_IPv4;
          } else {
!                 bcopy(&user_info->lg_clnt_ipaddr.a_ip, termid.at_addr,
                      sizeof (in6_addr_t));
                  termid.at_type = AU_IPv6;
          }
          adt_set_termid(ah, &termid);
  
          if (adt_set_user(ah, uid, gid, uid, gid, NULL, ADT_NEW)) {
                  syslog(LOG_AUTH | LOG_ALERT, "adt_set_user: %m");
                  adt_free_event(event);
!                 (void) adt_end_session(ah);
!                 smb_token_destroy(token);
!                 return (NULL);
          }
  
          event->adt_smbd_session.domain = domain;
          event->adt_smbd_session.username = username;
          event->adt_smbd_session.sid = sid;
--- 188,223 ----
                  retval = ADT_SUCCESS;
          }
  
          if (adt_start_session(&ah, NULL, 0)) {
                  syslog(LOG_AUTH | LOG_ALERT, "adt_start_session: %m");
!                 goto errout;
          }
  
          if ((event = adt_alloc_event(ah, ADT_smbd_session)) == NULL) {
                  syslog(LOG_AUTH | LOG_ALERT,
                      "adt_alloc_event(ADT_smbd_session): %m");
!                 goto errout;
          }
  
          (void) memset(&termid, 0, sizeof (au_tid_addr_t));
!         termid.at_port = 445;
  
!         if (ipaddr->a_family == AF_INET) {
!                 termid.at_addr[0] = ipaddr->a_ipv4;
                  termid.at_type = AU_IPv4;
          } else {
!                 bcopy(&ipaddr->a_ip, termid.at_addr,
                      sizeof (in6_addr_t));
                  termid.at_type = AU_IPv6;
          }
          adt_set_termid(ah, &termid);
  
          if (adt_set_user(ah, uid, gid, uid, gid, NULL, ADT_NEW)) {
                  syslog(LOG_AUTH | LOG_ALERT, "adt_set_user: %m");
                  adt_free_event(event);
!                 goto errout;
          }
  
          event->adt_smbd_session.domain = domain;
          event->adt_smbd_session.username = username;
          event->adt_smbd_session.sid = sid;
*** 175,201 ****
          adt_free_event(event);
  
          if (token) {
                  if ((entry = malloc(sizeof (smb_audit_t))) == NULL) {
                          syslog(LOG_ERR, "smbd_user_auth_logon: %m");
!                         (void) adt_end_session(ah);
!                         smb_token_destroy(token);
!                         return (NULL);
                  }
  
                  entry->sa_handle = ah;
                  entry->sa_uid = uid;
                  entry->sa_gid = gid;
                  entry->sa_username = strdup(username);
                  entry->sa_domain = strdup(domain);
  
-                 smb_autohome_add(token);
                  smbd_audit_link(entry);
                  token->tkn_audit_sid = entry->sa_audit_sid;
          }
  
!         return (token);
  }
  
  /*
   * Logon due to a subsequent SmbSessionSetupX on an existing session.
   * The user was authenticated during the initial session setup.
--- 228,259 ----
          adt_free_event(event);
  
          if (token) {
                  if ((entry = malloc(sizeof (smb_audit_t))) == NULL) {
                          syslog(LOG_ERR, "smbd_user_auth_logon: %m");
!                         goto errout;
                  }
  
                  entry->sa_handle = ah;
                  entry->sa_uid = uid;
                  entry->sa_gid = gid;
                  entry->sa_username = strdup(username);
                  entry->sa_domain = strdup(domain);
  
                  smbd_audit_link(entry);
                  token->tkn_audit_sid = entry->sa_audit_sid;
+                 adt_get_auid(ah, &token->tkn_auid);
+                 adt_get_mask(ah, &token->tkn_amask);
+                 adt_get_asid(ah, &token->tkn_asid);
          }
  
!         return (B_TRUE);
! errout:
!         if (ah != NULL)
!                 (void) adt_end_session(ah);
! 
!         return (B_FALSE);
  }
  
  /*
   * Logon due to a subsequent SmbSessionSetupX on an existing session.
   * The user was authenticated during the initial session setup.