diff options
author | Matt Barden <matt.barden@nexenta.com> | 2019-12-16 17:26:34 -0500 |
---|---|---|
committer | Gordon Ross <gordon.ross@tintri.com> | 2021-01-30 14:02:54 -0500 |
commit | 9e3ab9e9117808af4e738ea3ac45888be11e4045 (patch) | |
tree | f0bdc9fcc8ec00a108d592d479624d0707e3ee54 | |
parent | 0a73e6f973645e207d33a7012fed997991b4e531 (diff) | |
download | illumos-joyent-9e3ab9e9117808af4e738ea3ac45888be11e4045.tar.gz |
13442 SMB server should try harder to protect SACLs
Reviewed by: Evan Layton <elayton@tintri.com>
Reviewed by: Gordon Ross <gordon.ross@tintri.com>
Reviewed by: Roman Strashkin <rstrashkin@tintri.com>
Reviewed by: Andy Fiddaman <andy@omnios.org>
Approved by: Robert Mustacchi <rm@fingolfin.org>
-rw-r--r-- | usr/src/uts/common/fs/smbsrv/smb_common_open.c | 8 | ||||
-rw-r--r-- | usr/src/uts/common/fs/smbsrv/smb_fsops.c | 13 | ||||
-rw-r--r-- | usr/src/uts/common/fs/smbsrv/smb_user.c | 41 | ||||
-rw-r--r-- | usr/src/uts/common/smbsrv/smb_kproto.h | 1 |
4 files changed, 58 insertions, 5 deletions
diff --git a/usr/src/uts/common/fs/smbsrv/smb_common_open.c b/usr/src/uts/common/fs/smbsrv/smb_common_open.c index 24dda9a79d..454d48364c 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_common_open.c +++ b/usr/src/uts/common/fs/smbsrv/smb_common_open.c @@ -21,7 +21,7 @@ /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2019 Nexenta Systems, Inc. All rights reserved. + * Copyright 2020 Nexenta by DDN, Inc. All rights reserved. */ /* @@ -938,6 +938,12 @@ create: goto errout; } + if ((op->desired_access & ACCESS_SYSTEM_SECURITY) != 0 && + !smb_user_has_security_priv(sr->uid_user, sr->user_cr)) { + status = NT_STATUS_ACCESS_DENIED; + goto errout; + } + if (pn->pn_fname && smb_is_invalid_filename(pn->pn_fname)) { status = NT_STATUS_OBJECT_NAME_INVALID; goto errout; diff --git a/usr/src/uts/common/fs/smbsrv/smb_fsops.c b/usr/src/uts/common/fs/smbsrv/smb_fsops.c index 148f4ed6f9..4325d75282 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_fsops.c +++ b/usr/src/uts/common/fs/smbsrv/smb_fsops.c @@ -506,6 +506,10 @@ smb_fsop_create_file(smb_request_t *sr, cred_t *cr, */ secinfo = smb_sd_get_secinfo(op->sd); + if ((secinfo & SMB_SACL_SECINFO) != 0 && + !smb_user_has_security_priv(sr->uid_user, cr)) + return (EPERM); + smb_fssd_init(&fs_sd, secinfo, 0); status = smb_sd_tofs(op->sd, &fs_sd); @@ -652,6 +656,10 @@ smb_fsop_mkdir( */ secinfo = smb_sd_get_secinfo(op->sd); + if ((secinfo & SMB_SACL_SECINFO) != 0 && + !smb_user_has_security_priv(sr->uid_user, cr)) + return (EPERM); + smb_fssd_init(&fs_sd, secinfo, SMB_FSSD_FLAGS_DIR); status = smb_sd_tofs(op->sd, &fs_sd); @@ -1735,10 +1743,7 @@ smb_fsop_access(smb_request_t *sr, cred_t *cr, smb_node_t *snode, * it's not part of DACL. It's only granted via proper * privileges. */ - if ((sr->uid_user->u_privileges & - (SMB_USER_PRIV_BACKUP | - SMB_USER_PRIV_RESTORE | - SMB_USER_PRIV_SECURITY)) == 0) + if (!smb_user_has_security_priv(sr->uid_user, cr)) return (NT_STATUS_PRIVILEGE_NOT_HELD); faccess &= ~ACCESS_SYSTEM_SECURITY; diff --git a/usr/src/uts/common/fs/smbsrv/smb_user.c b/usr/src/uts/common/fs/smbsrv/smb_user.c index b46cad1b6f..332c6bc67d 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_user.c +++ b/usr/src/uts/common/fs/smbsrv/smb_user.c @@ -205,6 +205,8 @@ #include <sys/types.h> #include <sys/sid.h> #include <sys/priv_names.h> +#include <sys/priv.h> +#include <sys/policy.h> #include <smbsrv/smb_kproto.h> #include <smbsrv/smb_door.h> @@ -831,6 +833,45 @@ smb_user_setcred(smb_user_t *user, cred_t *cr, uint32_t privileges) #endif /* _KERNEL */ /* + * Determines whether a user can be granted ACCESS_SYSTEM_SECURITY + */ +boolean_t +smb_user_has_security_priv(smb_user_t *user, cred_t *cr) +{ + /* Need SeSecurityPrivilege to get/set SACL */ + if ((user->u_privileges & SMB_USER_PRIV_SECURITY) != 0) + return (B_TRUE); + +#ifdef _KERNEL + /* + * ACCESS_SYSTEM_SECURITY is also granted if the file is opened with + * BACKUP/RESTORE intent by a user with BACKUP/RESTORE privilege, + * which means we'll be using u_privcred. + * + * We translate BACKUP as DAC_READ and RESTORE as DAC_WRITE, + * to account for our various SMB_USER_* privileges. + */ + if (PRIV_POLICY_ONLY(cr, + priv_getbyname(PRIV_FILE_DAC_READ, 0), B_FALSE) || + PRIV_POLICY_ONLY(cr, + priv_getbyname(PRIV_FILE_DAC_WRITE, 0), B_FALSE)) + return (B_TRUE); +#else + /* + * No "real" privileges in fksmbsrv, so use the SMB privs instead. + */ + if ((user->u_privileges & + (SMB_USER_PRIV_BACKUP | + SMB_USER_PRIV_RESTORE | + SMB_USER_PRIV_READ_FILE | + SMB_USER_PRIV_WRITE_FILE)) != 0) + return (B_TRUE); +#endif + + return (B_FALSE); +} + +/* * Private function to support smb_user_enum. */ static int diff --git a/usr/src/uts/common/smbsrv/smb_kproto.h b/usr/src/uts/common/smbsrv/smb_kproto.h index 504cfc1ade..8bffe1b36a 100644 --- a/usr/src/uts/common/smbsrv/smb_kproto.h +++ b/usr/src/uts/common/smbsrv/smb_kproto.h @@ -739,6 +739,7 @@ cred_t *smb_cred_create(smb_token_t *); cred_t *smb_kcred_create(void); void smb_user_setcred(smb_user_t *, cred_t *, uint32_t); boolean_t smb_is_same_user(cred_t *, cred_t *); +boolean_t smb_user_has_security_priv(smb_user_t *, cred_t *); /* * SMB tree functions (file smb_tree.c) |