Bug 951028 - Fix NTFS permissions when a file is moved to a different directory. r=yoric,bbondy

This commit is contained in:
Masatoshi Kimura 2014-01-23 02:33:48 +09:00
parent 8186f23261
commit 3d9b1531fe
3 changed files with 87 additions and 0 deletions

View File

@ -28,6 +28,7 @@
#if defined(XP_WIN)
#include <windows.h>
#include <accctrl.h>
#endif // defined(XP_WIN)
#include "jsapi.h"
@ -680,6 +681,11 @@ static const dom::ConstantSpec gWinProperties[] =
// GetFileAttributes error constant
INT_CONSTANT(INVALID_FILE_ATTRIBUTES),
// GetNamedSecurityInfo and SetNamedSecurityInfo constants
INT_CONSTANT(UNPROTECTED_DACL_SECURITY_INFORMATION),
INT_CONSTANT(SE_FILE_OBJECT),
INT_CONSTANT(DACL_SECURITY_INFORMATION),
// Errors
INT_CONSTANT(ERROR_ACCESS_DENIED),
INT_CONSTANT(ERROR_DIR_NOT_EMPTY),

View File

@ -39,6 +39,7 @@
let SysAll = require("resource://gre/modules/osfile/osfile_win_allthreads.jsm");
let LOG = SharedAll.LOG.bind(SharedAll, "Unix", "back");
let libc = SysAll.libc;
let advapi32 = new SharedAll.Library("advapi32", "advapi32.dll");
let Const = SharedAll.Constants.Win;
/**
@ -121,9 +122,30 @@
Type.zero_or_nothing =
Type.int.withName("zero_or_nothing");
/**
* A C integer holding flags related to NTFS security.
*/
Type.SECURITY_ATTRIBUTES =
Type.void_t.withName("SECURITY_ATTRIBUTES");
/**
* A C integer holding pointers related to NTFS security.
*/
Type.PSID =
Type.voidptr_t.withName("PSID");
Type.PACL =
Type.voidptr_t.withName("PACL");
Type.PSECURITY_DESCRIPTOR =
Type.voidptr_t.withName("PSECURITY_DESCRIPTOR");
/**
* A C integer holding Win32 local memory handle.
*/
Type.HLOCAL =
Type.voidptr_t.withName("HLOCAL");
Type.FILETIME =
new SharedAll.Type("FILETIME",
ctypes.StructType("FILETIME", [
@ -356,6 +378,34 @@
/*return*/ Type.zero_or_nothing,
/*fileName*/ Type.path,
/*fileAttributes*/ Type.DWORD);
advapi32.declareLazyFFI(SysFile, "GetNamedSecurityInfo",
"GetNamedSecurityInfoW", ctypes.winapi_abi,
/*return*/ Type.DWORD,
/*objectName*/ Type.path,
/*objectType*/ Type.DWORD,
/*securityInfo*/ Type.DWORD,
/*sidOwner*/ Type.PSID.out_ptr,
/*sidGroup*/ Type.PSID.out_ptr,
/*dacl*/ Type.PACL.out_ptr,
/*sacl*/ Type.PACL.out_ptr,
/*securityDesc*/ Type.PSECURITY_DESCRIPTOR.out_ptr);
advapi32.declareLazyFFI(SysFile, "SetNamedSecurityInfo",
"SetNamedSecurityInfoW", ctypes.winapi_abi,
/*return*/ Type.DWORD,
/*objectName*/ Type.path,
/*objectType*/ Type.DWORD,
/*securityInfo*/ Type.DWORD,
/*sidOwner*/ Type.PSID,
/*sidGroup*/ Type.PSID,
/*dacl*/ Type.PACL,
/*sacl*/ Type.PACL);
declareLazyFFI(SysFile, "LocalFree", libc,
"LocalFree", ctypes.winapi_abi,
/*return*/ Type.HLOCAL,
/*mem*/ Type.HLOCAL);
};
exports.OS.Win = {

View File

@ -516,6 +516,37 @@
throw_on_zero("move",
WinFile.MoveFileEx(sourcePath, destPath, flags)
);
// Inherit NTFS permissions from the destination directory
// if possible.
if (Path.dirname(sourcePath) === Path.dirname(destPath)) {
// Skip if the move operation was the simple rename,
return;
}
// The function may fail for various reasons (e.g. not all
// filesystems support NTFS permissions or the user may not
// have the enough rights to read/write permissions).
// However we can safely ignore errors. The file was already
// moved. Setting permissions is not mandatory.
let dacl = new ctypes.voidptr_t();
let sd = new ctypes.voidptr_t();
WinFile.GetNamedSecurityInfo(destPath, Const.SE_FILE_OBJECT,
Const.DACL_SECURITY_INFORMATION,
null /*sidOwner*/, null /*sidGroup*/,
dacl.address(), null /*sacl*/,
sd.address());
// dacl will be set only if the function succeeds.
if (!dacl.isNull()) {
WinFile.SetNamedSecurityInfo(destPath, Const.SE_FILE_OBJECT,
Const.DACL_SECURITY_INFORMATION |
Const.UNPROTECTED_DACL_SECURITY_INFORMATION,
null /*sidOwner*/, null /*sidGroup*/,
dacl, null /*sacl*/);
}
// sd will be set only if the function succeeds.
if (!sd.isNull()) {
WinFile.LocalFree(Type.HLOCAL.cast(sd));
}
};
/**