Patch to handle the FILE_OPEN_FOR_BACKUP_INTENT portion of Se{Backup, Restore}Privilege
Richard Sharpe
realrichardsharpe at gmail.com
Tue May 1 17:42:10 MDT 2012
Hi folks,
Here is the patch that I have created for Samba 3.5.x to handle
FILE_OPEN_FOR_BACKUP_INTENT. It does not deal with the races that
Jeremy mentioned yesterday and might still have other flaws, but I am
sending it out for discussion.
I have attached it as well.
Briefly, I add a flag, backup_intent to smbd_check_access_rights and
remove any checking of SeBackupPrivilege from se_access_check. This
checking is now done in smbd_check_access_rights.
All the callers of smbd_check_access_rights either compute
backup_intent from create_options or pass in False (in the case of
those internal callers who are simply checking whether or not the user
has permission to do what they want.)
diff -ur -x '*.o' samba-3.5.14/source3.cpy/include/privileges.h
samba-3.5.14/source3/in
clude/privileges.h
--- samba-3.5.14/source3.cpy/include/privileges.h 2012-04-25
13:53:09.555197842 -
0700
+++ samba-3.5.14/source3/include/privileges.h 2012-04-25
14:29:50.361486308 -0700
@@ -72,6 +72,7 @@
extern const SE_PRIV se_disk_operators;
extern const SE_PRIV se_remote_shutdown;
extern const SE_PRIV se_restore;
+extern const SE_PRIV se_backup;
extern const SE_PRIV se_take_ownership;
extern const SE_PRIV se_security;
diff -ur -x '*.o' samba-3.5.14/source3.cpy/include/proto.h
samba-3.5.14/source3/include
/proto.h
--- samba-3.5.14/source3.cpy/include/proto.h 2012-04-25
13:53:09.388651013 -0700
+++ samba-3.5.14/source3/include/proto.h 2012-04-25
14:26:01.391280836 -0700
@@ -6606,7 +6606,8 @@
uint32_t *access_mask_out);
NTSTATUS smbd_check_access_rights(struct connection_struct *conn,
const struct smb_filename *smb_fname,
- uint32_t access_mask);
+ uint32_t access_mask,
+ bool backup_intent);
NTSTATUS fd_close(files_struct *fsp);
void change_file_owner_to_parent(connection_struct *conn,
const char *inherit_from_dir,
diff -ur -x '*.o' samba-3.5.14/source3.cpy/lib/privileges_basic.c
samba-3.5.14/source3/
lib/privileges_basic.c
--- samba-3.5.14/source3.cpy/lib/privileges_basic.c 2012-04-25
13:52:53.682273764 -
0700
+++ samba-3.5.14/source3/lib/privileges_basic.c 2012-04-25
14:28:58.079567761 -0700
@@ -45,6 +45,7 @@
const SE_PRIV se_disk_operators = SE_DISK_OPERATOR;
const SE_PRIV se_remote_shutdown = SE_REMOTE_SHUTDOWN;
const SE_PRIV se_restore = SE_RESTORE;
+const SE_PRIV se_backup = SE_BACKUP;
const SE_PRIV se_take_ownership = SE_TAKE_OWNERSHIP;
const SE_PRIV se_security = SE_SECURITY;
diff -ur -x '*.o' samba-3.5.14/source3.cpy/lib/util_seaccess.c
samba-3.5.14/source3/lib
/util_seaccess.c
--- samba-3.5.14/source3.cpy/lib/util_seaccess.c 2012-04-25
13:52:54.484805985 -
0700
+++ samba-3.5.14/source3/lib/util_seaccess.c 2012-04-25
14:55:05.215611345 -0700
@@ -233,11 +233,6 @@
}
}
- if ((bits_remaining & SEC_STD_DELETE) &&
- user_has_privileges(token, &se_restore)) {
- bits_remaining &= ~SEC_STD_DELETE;
- }
-
if ((bits_remaining & SEC_STD_WRITE_OWNER) &&
user_has_privileges(token, &se_take_ownership)) {
bits_remaining &= ~SEC_STD_WRITE_OWNER;
diff -ur -x '*.o' samba-3.5.14/source3.cpy/smbd/file_access.c
samba-3.5.14/source3/smbd
/file_access.c
--- samba-3.5.14/source3.cpy/smbd/file_access.c 2012-04-25
13:53:02.348877139 -0700
+++ samba-3.5.14/source3/smbd/file_access.c 2012-04-25
14:43:52.876584480 -0700
@@ -124,7 +124,8 @@
ret = NT_STATUS_IS_OK(smbd_check_access_rights(conn,
smb_fname_parent,
- FILE_DELETE_CHILD));
+ FILE_DELETE_CHILD,
+ False));
out:
TALLOC_FREE(dname);
TALLOC_FREE(smb_fname_parent);
@@ -140,7 +141,8 @@
{
return NT_STATUS_IS_OK(smbd_check_access_rights(conn,
smb_fname,
- FILE_WRITE_DATA));
+ FILE_WRITE_DATA,
+ False));
}
/****************************************************************************
diff -ur -x '*.o' samba-3.5.14/source3.cpy/smbd/open.c
samba-3.5.14/source3/smbd/open.c
--- samba-3.5.14/source3.cpy/smbd/open.c 2012-04-25
13:53:01.989072703 -0700
+++ samba-3.5.14/source3/smbd/open.c 2012-04-25 14:38:41.064324895 -0700
@@ -71,7 +71,8 @@
NTSTATUS smbd_check_access_rights(struct connection_struct *conn,
const struct smb_filename *smb_fname,
- uint32_t access_mask)
+ uint32_t access_mask,
+ bool backup_intent)
{
/* Check if we have rights to open. */
NTSTATUS status;
@@ -147,10 +148,29 @@
nt_errstr(status) ));
if (!NT_STATUS_IS_OK(status)) {
- if (DEBUGLEVEL >= 10) {
- DEBUG(10,("smbd_check_access_rights: acl for %s is:\n",
- smb_fname_str_dbg(smb_fname) ));
+ bool backup_intent_override = False;
+
+ /* Check for backup_intent and the access rights it grants */
+ if (backup_intent) {
+ DEBUG(10, ("Checking if SeBackupPrivilege or "
+ "SeRestorePrivilege applies\n"));
+ if ((!(rejected_mask & ~(FILE_GENERIC_READ |
SEC_STD_READ_CONTR
OL) &&
+
user_has_privileges(conn->server_info->ptok, &se_backup
)) ||
+ (!(rejected_mask & ~(FILE_GENERIC_WRITE |
SEC_STD_WRITE_DAC
| SEC_STD_WRITE_OWNER)) &&
+
user_has_privileges(conn->server_info->ptok, &se_restor
e)))) {
+ status = NT_STATUS_OK;
+ backup_intent_override = True;
+ DEBUG(10, ("SeBackupPrivilege or
SeRestorePrivilege use
d to override lack of access\n"));
+ }
+
+ }
+
+ if (!backup_intent_override) {
+ if (DEBUGLEVEL >= 10) {
+ DEBUG(10,("smbd_check_access_rights:
acl for %s is:\n",
+ smb_fname_str_dbg(smb_fname) ));
+ NDR_PRINT_DEBUG(security_descriptor, sd);
+ }
}
}
@@ -512,7 +532,8 @@
int flags,
mode_t unx_mode,
uint32 access_mask, /* client requested
access mask. */
- uint32 open_access_mask) /* what we're
actually using in the
open. */
+ uint32 open_access_mask, /* what we're
actually using in the
open. */
+ bool backup_intent)
{
struct smb_filename *smb_fname = fsp->fsp_name;
NTSTATUS status = NT_STATUS_OK;
@@ -615,7 +636,8 @@
if (file_existed) {
status = smbd_check_access_rights(conn,
smb_fname,
- access_mask);
+ access_mask,
+ backup_intent);
+ backup_intent);
} else if (local_flags & O_CREAT){
status = check_parent_access(conn,
smb_fname,
@@ -660,7 +682,8 @@
status = smbd_check_access_rights(conn,
smb_fname,
- access_mask);
+ access_mask,
+ backup_intent);
if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) &&
fsp->posix_open &&
@@ -1877,7 +1900,7 @@
if (((can_access_mask & FILE_WRITE_DATA) &&
!CAN_WRITE(conn)) ||
!NT_STATUS_IS_OK(smbd_check_access_rights(conn,
- smb_fname, can_access_mask))) {
+ smb_fname,
can_access_mask, False))) {
can_access = False;
}
@@ -1965,7 +1988,8 @@
fsp_open = open_file(fsp, conn, req, parent_dir,
flags|flags2, unx_mode, access_mask,
- open_access_mask);
+ open_access_mask,
+ create_options & FILE_OPEN_FOR_BACKUP_INTENT);
if (!NT_STATUS_IS_OK(fsp_open)) {
if (lck != NULL) {
@@ -2554,7 +2578,10 @@
}
if (info == FILE_WAS_OPENED) {
- status = smbd_check_access_rights(conn, smb_dname, access_mask);
+ status = smbd_check_access_rights(conn,
+ smb_dname,
+ access_mask,
+ create_options &
FILE_OPEN_FOR_BACKUP
_INTENT);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(10, ("open_directory:
smbd_check_access_rights on "
"file %s failed with %s\n",
diff -ur -x '*.o' samba-3.5.14/source3.cpy/smbd/dir.c
samba-3.5.14/source3/smbd/dir.c
--- samba-3.5.14/source3.cpy/smbd/dir.c 2012-04-27 15:19:15.359465001 -0700
+++ samba-3.5.14/source3/smbd/dir.c 2012-04-27 15:19:44.794158117 -0700
@@ -454,7 +454,8 @@
}
status = smbd_check_access_rights(conn,
smb_dname,
- SEC_DIR_LIST);
+ SEC_DIR_LIST,
+ False);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
@@ -1158,7 +1159,8 @@
return NT_STATUS_IS_OK(smbd_check_access_rights(conn,
smb_fname,
- FILE_READ_DATA));
+ FILE_READ_DATA,
+ False));
}
/*******************************************************************
diff -ur -x '*.o' samba-3.5.14/source3.cpy/smbd/trans2.c
samba-3.5.14/source3/smbd/tran
s2.c
--- samba-3.5.14/source3.cpy/smbd/trans2.c 2012-04-27
16:45:00.010797341 -0700
+++ samba-3.5.14/source3/smbd/trans2.c 2012-04-27 16:45:36.970964492 -0700
@@ -56,7 +56,8 @@
} else {
NTSTATUS status = smbd_check_access_rights(conn,
smb_fname,
- access_mask);
+ access_mask,
+ False);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
--
Regards,
Richard Sharpe
(何以解憂?唯有杜康。--曹操)
More information about the samba-technical
mailing list