Print this page
NEX-17589 Get "too high" smbd error when copy big file to cifs share
Reviewed by: Joyce McIntosh <joyce.mcintosh@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
NEX-17795 SMB logon should tolerate idmap problems
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Joyce McIntosh <joyce.mcintosh@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-9497 SMB should bypass ACL traverse checking
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@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-2461 smb_split_sid uses wrong allocation size
NEX-1810 extended security Kerberos (inbound)
SMB-126 Unable to map share from win2003/win2003R2 client ...
SMB-107 Unable to map network drive in workgroup mode using Windows XP...
SMB-68 NTLM(v1) inbound with Extended Session Security
SMB-56 extended security NTLMSSP, inbound

@@ -18,12 +18,12 @@
  *
  * CDDL HEADER END
  */
 /*
  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
  * Copyright (c) 2016 by Delphix. All rights reserved.
+ * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
  */
 
 #include <unistd.h>
 #include <strings.h>
 #include <pwd.h>

@@ -127,10 +127,14 @@
 
 /*
  * smb_token_sids2ids
  *
  * This will map all the SIDs of the access token to UIDs/GIDs.
+ * However, if there are some SIDs we can't map to UIDs/GIDs,
+ * we don't want to fail the logon, and instead just log the
+ * SIDs we could not map and continue as best we can.
+ * The flag SMB_IDMAP_SKIP_ERRS below does that.
  *
  * Returns 0 upon success.  Otherwise, returns -1.
  */
 static int
 smb_token_sids2ids(smb_token_t *token)

@@ -146,11 +150,12 @@
         if (token->tkn_flags & SMB_ATF_ANON)
                 nmaps = token->tkn_win_grps.i_cnt + 1;
         else
                 nmaps = token->tkn_win_grps.i_cnt + 3;
 
-        stat = smb_idmap_batch_create(&sib, nmaps, SMB_IDMAP_SID2ID);
+        stat = smb_idmap_batch_create(&sib, nmaps,
+            SMB_IDMAP_SID2ID | SMB_IDMAP_SKIP_ERRS);
         if (stat != IDMAP_SUCCESS)
                 return (-1);
 
         stat = smb_token_idmap(token, &sib);
         if (stat != IDMAP_SUCCESS) {

@@ -321,10 +326,20 @@
                  * This privilege is required to view/edit SACL
                  */
                 smb_privset_enable(privs, SE_SECURITY_LUID);
         }
 
+        /*
+         * Members of "Authenticated Users" (!anon) should normally get
+         * "Bypass traverse checking" privilege, though we allow this
+         * to be disabled (see smb.4).  For historical reasons, the
+         * internal privilege name is "SeChangeNotifyPrivilege".
+         */
+        if ((token->tkn_flags & SMB_ATF_ANON) == 0 &&
+            smb_config_getbool(SMB_CI_BYPASS_TRAVERSE_CHECKING))
+                smb_privset_enable(privs, SE_CHANGE_NOTIFY_LUID);
+
         return (privs);
 }
 
 static void
 smb_token_set_flags(smb_token_t *token)

@@ -415,10 +430,11 @@
  *
  * The dispatched functions must only update the user_info status if they
  * attempt to authenticate the user.
  *
  * On success, a pointer to a new access token is returned.
+ * On failure, NULL return and status in user_info->lg_status
  */
 smb_token_t *
 smb_logon(smb_logon_t *user_info)
 {
         static smb_logonop_t    ops[] = {

@@ -431,11 +447,10 @@
         smb_domain_t            domain;
         int                     n_op = (sizeof (ops) / sizeof (ops[0]));
         int                     i;
 
         user_info->lg_secmode = smb_config_get_secmode();
-        user_info->lg_status = NT_STATUS_NO_SUCH_USER;
 
         if (smb_domain_lookup_name(user_info->lg_e_domain, &domain))
                 user_info->lg_domain_type = domain.di_type;
         else
                 user_info->lg_domain_type = SMB_DOMAIN_NULL;

@@ -444,23 +459,44 @@
                 syslog(LOG_ERR, "logon[%s\\%s]: %m",
                     user_info->lg_e_domain, user_info->lg_e_username);
                 return (NULL);
         }
 
+        /*
+         * If any logonop function takes significant action
+         * (logon or authoratative failure) it will change
+         * this status field to something else.
+         */
+        user_info->lg_status = NT_STATUS_NO_SUCH_USER;
         for (i = 0; i < n_op; ++i) {
                 (*ops[i])(user_info, token);
 
                 if (user_info->lg_status == NT_STATUS_SUCCESS)
                         break;
         }
 
         if (user_info->lg_status == NT_STATUS_SUCCESS) {
                 if (smb_token_setup_common(token))
-                        return (token);
+                        return (token); /* success */
+                /*
+                 * (else) smb_token_setup_common failed, which usually
+                 * means smb_token_sids2ids() failed to map some SIDs to
+                 * Unix IDs.  This indicates an idmap config problem.
+                 */
+                user_info->lg_status = NT_STATUS_INTERNAL_ERROR;
         }
 
         smb_token_destroy(token);
+
+        /*
+         * Any unknown user or bad password should result in
+         * NT_STATUS_LOGON_FAILURE (so we don't give hints).
+         */
+        if (user_info->lg_status == NT_STATUS_NO_SUCH_USER ||
+            user_info->lg_status == NT_STATUS_WRONG_PASSWORD)
+                user_info->lg_status = NT_STATUS_LOGON_FAILURE;
+
         return (NULL);
 }
 
 /*
  * If the user has an entry in the local database, attempt local authentication.