Merge branch 'master' of https://code.google.com/p/plexi.fs
diff --git a/src/com/google/enterprise/adaptor/fs/WindowsAclFileAttributeViews.java b/src/com/google/enterprise/adaptor/fs/WindowsAclFileAttributeViews.java
index b70e455..f71296c 100644
--- a/src/com/google/enterprise/adaptor/fs/WindowsAclFileAttributeViews.java
+++ b/src/com/google/enterprise/adaptor/fs/WindowsAclFileAttributeViews.java
@@ -432,7 +432,7 @@
}
@VisibleForTesting
- interface Mpr extends StdCallLibrary {
+ public static interface Mpr extends StdCallLibrary {
Mpr INSTANCE = (Mpr) Native.loadLibrary("Mpr", Mpr.class,
W32APIOptions.UNICODE_OPTIONS);
diff --git a/test/com/google/enterprise/adaptor/fs/UnsupportedNetapi32.java b/test/com/google/enterprise/adaptor/fs/UnsupportedNetapi32.java
new file mode 100644
index 0000000..e6252ee
--- /dev/null
+++ b/test/com/google/enterprise/adaptor/fs/UnsupportedNetapi32.java
@@ -0,0 +1,153 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.enterprise.adaptor.fs;
+
+import com.google.enterprise.adaptor.fs.WinApi.Netapi32Ex;
+
+import com.sun.jna.Native;
+import com.sun.jna.Pointer;
+import com.sun.jna.Structure;
+import com.sun.jna.platform.win32.Netapi32;
+import com.sun.jna.platform.win32.DsGetDC.PDOMAIN_CONTROLLER_INFO;
+import com.sun.jna.platform.win32.Guid.GUID;
+import com.sun.jna.platform.win32.NTSecApi.PLSA_FOREST_TRUST_INFORMATION;
+import com.sun.jna.ptr.IntByReference;
+import com.sun.jna.ptr.PointerByReference;
+import com.sun.jna.win32.StdCallLibrary;
+import com.sun.jna.win32.W32APIOptions;
+
+/**
+ * An implementation of the Netapi32 Interface that throws
+ * UnsupportedOperationException for everything. Tests may
+ * subclass this and override those methods used by the object
+ * under test.
+ */
+public class UnsupportedNetapi32 implements Netapi32, Netapi32Ex {
+
+ @Override
+ public int NetShareGetInfo(String serverName, String netName, int level,
+ PointerByReference bufptr) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int NetDfsGetSecurity(String dfsEntryPath, int securityInformation,
+ PointerByReference ppSecurityDescriptor,
+ IntByReference lpcbSecurityDescriptor) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int NetDfsGetInfo(String dfsEntryPath, String serverName,
+ String shareName, int Level, PointerByReference buffer) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int NetGetJoinInformation(String lpServer,
+ PointerByReference lpNameBuffer, IntByReference bufferType) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int NetApiBufferFree(Pointer buffer) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int NetLocalGroupEnum(String serverName, int level,
+ PointerByReference bufptr, int prefmaxlen,
+ IntByReference entriesRead, IntByReference totalEntries,
+ IntByReference resumeHandle) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int NetGetDCName(String serverName, String domainName,
+ PointerByReference bufptr) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int NetGroupEnum(String servername, int level,
+ PointerByReference bufptr, int prefmaxlen, IntByReference entriesRead,
+ IntByReference totalEntries, IntByReference resumeHandle) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int NetUserEnum(String serverName, int level, int filter,
+ PointerByReference bufptr, int prefmaxlen, IntByReference entriesRead,
+ IntByReference totalEntries, IntByReference resumeHandle) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int NetUserGetGroups(String serverName, String userName, int level,
+ PointerByReference bufptr, int prefmaxlen,
+ IntByReference entriesRead, IntByReference totalEntries) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int NetUserGetLocalGroups(String serverName, String userName,
+ int level, int flags, PointerByReference bufptr, int prefmaxlen,
+ IntByReference entriesRead, IntByReference totalEntries) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int NetUserAdd(String serverName, int level,
+ Structure buf, IntByReference parmError) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int NetUserDel(String serverName, String userName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int NetUserChangePassword(String domainName, String userName,
+ String oldPassword, String newPassword) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int NetUserGetInfo( String serverName, String userName,
+ int level, PointerByReference bufptr ) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int DsGetDcName(String computerName, String domainName,
+ GUID domainGuid, String siteName, int flags,
+ PDOMAIN_CONTROLLER_INFO domainControllerInfo) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int DsGetForestTrustInformation(String serverName,
+ String trustedDomainName, int flags,
+ PLSA_FOREST_TRUST_INFORMATION dorestTrustInfo) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int DsEnumerateDomainTrusts(String serverName, int flags,
+ PointerByReference domains, IntByReference domainCount) {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/test/com/google/enterprise/adaptor/fs/WindowsAclFileAttributeViewsTest.java b/test/com/google/enterprise/adaptor/fs/WindowsAclFileAttributeViewsTest.java
index 8852150..dddbc93 100644
--- a/test/com/google/enterprise/adaptor/fs/WindowsAclFileAttributeViewsTest.java
+++ b/test/com/google/enterprise/adaptor/fs/WindowsAclFileAttributeViewsTest.java
@@ -29,6 +29,7 @@
import com.google.enterprise.adaptor.fs.WinApi.Netapi32Ex;
import com.google.enterprise.adaptor.fs.WinApi.Shlwapi;
+import com.google.enterprise.adaptor.fs.WindowsAclFileAttributeViews.Mpr;
import org.junit.*;
import org.junit.rules.ExpectedException;
@@ -41,17 +42,20 @@
import com.sun.jna.platform.win32.Advapi32;
import com.sun.jna.platform.win32.Advapi32Util.Account;
import com.sun.jna.platform.win32.Kernel32;
+import com.sun.jna.platform.win32.LMErr;
import com.sun.jna.platform.win32.W32Errors;
import com.sun.jna.platform.win32.Win32Exception;
import com.sun.jna.platform.win32.WinError;
import com.sun.jna.platform.win32.WinNT;
import com.sun.jna.platform.win32.WinNT.SID_NAME_USE;
import com.sun.jna.ptr.IntByReference;
+import com.sun.jna.ptr.PointerByReference;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
+import java.nio.file.Paths;
import java.nio.file.attribute.AclEntry;
import java.nio.file.attribute.AclEntryFlag;
import java.nio.file.attribute.AclEntryPermission;
@@ -365,6 +369,36 @@
private AclFileAttributeViews getAclViews(WinNT.ACCESS_ACEStructure... aces)
throws Exception {
+ final byte[] dacl = buildDaclMemory(aces);
+ Kernel32 kernel32 = new UnsupportedKernel32() {
+ @Override
+ public int GetLastError() {
+ // For when GetFileSecurity returns false.
+ return W32Errors.ERROR_INSUFFICIENT_BUFFER;
+ }
+ };
+ Advapi32 advapi32 = new UnsupportedAdvapi32() {
+ @Override
+ public boolean GetFileSecurity(WString lpFileName,
+ int RequestedInformation, Pointer pointer, int nLength,
+ IntByReference lpnLengthNeeded) {
+ if (nLength < dacl.length) {
+ lpnLengthNeeded.setValue(dacl.length);
+ return false;
+ } else {
+ pointer.write(0, dacl, 0, nLength);
+ return true;
+ }
+ }
+ };
+
+ WindowsAclFileAttributeViews wafav =
+ new TestAclFileAttributeViews(advapi32, kernel32, null, null, null);
+ return wafav.getAclViews(newTempFile("test"));
+ }
+
+ private byte[] buildDaclMemory(WinNT.ACCESS_ACEStructure... aces)
+ throws Exception {
WinNT.ACL acl = new WinNT.ACL();
WinNT.SECURITY_DESCRIPTOR_RELATIVE securityDescriptor =
new WinNT.SECURITY_DESCRIPTOR_RELATIVE();
@@ -391,32 +425,7 @@
ace.getPointer().read(0, buffer, offset, ace.AceSize);
offset += ace.AceSize;
}
-
- Kernel32 kernel32 = new UnsupportedKernel32() {
- @Override
- public int GetLastError() {
- // For when GetFileSecurity returns false.
- return W32Errors.ERROR_INSUFFICIENT_BUFFER;
- }
- };
- Advapi32 advapi32 = new UnsupportedAdvapi32() {
- @Override
- public boolean GetFileSecurity(WString lpFileName,
- int RequestedInformation, Pointer pointer, int nLength,
- IntByReference lpnLengthNeeded) {
- if (nLength < buffer.length) {
- lpnLengthNeeded.setValue(buffer.length);
- return false;
- } else {
- pointer.write(0, buffer, 0, nLength);
- return true;
- }
- }
- };
-
- WindowsAclFileAttributeViews wafav =
- new TestAclFileAttributeViews(advapi32, kernel32, null, null, null);
- return wafav.getAclViews(newTempFile("test"));
+ return buffer;
}
/**
@@ -468,6 +477,237 @@
wafav.getAclViews(newTempFile("test"));
}
+ @Test
+ public void testGetShareAclViewLocalDrive() throws Exception {
+ Shlwapi shlwapi = new Shlwapi() {
+ @Override
+ public boolean PathIsNetworkPath(String pszPath) {
+ return false;
+ }
+ @Override
+ public boolean PathIsUNC(String pszPath) {
+ return false;
+ }
+ };
+ WindowsAclFileAttributeViews wafav =
+ new TestAclFileAttributeViews(null, null, null, null, shlwapi);
+ AclFileAttributeView aclView = wafav.getShareAclView(newTempDir("test"));
+ assertNotNull(aclView);
+ assertTrue(aclView.getAcl().isEmpty());
+ }
+
+ @Test
+ public void testGetShareAclViewUncPath() throws Exception {
+ TestHelper.assumeOsIsWindows();
+ Shlwapi shlwapi = new Shlwapi() {
+ @Override
+ public boolean PathIsNetworkPath(String pszPath) {
+ return false;
+ }
+ @Override
+ public boolean PathIsUNC(String pszPath) {
+ return true;
+ }
+ };
+ Path share = Paths.get("\\\\server\\share");
+ testGetShareAclView(share, shlwapi, null);
+ }
+
+ @Test
+ public void testGetShareAclViewBadUncPath() throws Exception {
+ TestHelper.assumeOsIsWindows();
+ Shlwapi shlwapi = new Shlwapi() {
+ @Override
+ public boolean PathIsNetworkPath(String pszPath) {
+ return false;
+ }
+ @Override
+ public boolean PathIsUNC(String pszPath) {
+ return true;
+ }
+ };
+ thrown.expect(IOException.class);
+ testGetShareAclView(newTempDir("test"), shlwapi, null);
+ }
+
+
+ @Test
+ public void testGetShareAclViewNetworkPath() throws Exception {
+ TestHelper.assumeOsIsWindows();
+ Shlwapi shlwapi = new Shlwapi() {
+ @Override
+ public boolean PathIsNetworkPath(String pszPath) {
+ return true;
+ }
+ @Override
+ public boolean PathIsUNC(String pszPath) {
+ return false;
+ }
+ };
+ Mpr mpr = new Mpr() {
+ @Override
+ public int WNetGetUniversalNameW(String lpLocalPath, int dwInfoLevel,
+ Pointer lpBuffer, IntByReference lpBufferSize) {
+ Mpr.UNIVERSAL_NAME_INFO info = new Mpr.UNIVERSAL_NAME_INFO();
+ info.lpUniversalName = "\\\\server\\share";
+ info.write();
+ // Force a reallocation, even though we do not need it.
+ if (lpBufferSize.getValue() != info.size()) {
+ lpBufferSize.setValue(info.size());
+ return WinNT.ERROR_MORE_DATA;
+ }
+ byte[] buf = new byte[info.size()];
+ info.getPointer().read(0, buf, 0, buf.length);
+ lpBuffer.write(0, buf, 0, buf.length);
+ return WinNT.NO_ERROR;
+ }
+ };
+ testGetShareAclView(newTempDir("test"), shlwapi, mpr);
+ }
+
+ @Test
+ public void testGetShareAclViewNetworkPathFailure() throws Exception {
+ TestHelper.assumeOsIsWindows();
+ Shlwapi shlwapi = new Shlwapi() {
+ @Override
+ public boolean PathIsNetworkPath(String pszPath) {
+ return true;
+ }
+ @Override
+ public boolean PathIsUNC(String pszPath) {
+ return false;
+ }
+ };
+ Mpr mpr = new Mpr() {
+ @Override
+ public int WNetGetUniversalNameW(String lpLocalPath, int dwInfoLevel,
+ Pointer lpBuffer, IntByReference lpBufferSize) {
+ return WinNT.ERROR_INVALID_PARAMETER;
+ }
+ };
+ thrown.expect(IOException.class);
+ testGetShareAclView(newTempDir("test"), shlwapi, mpr);
+ }
+
+ private void testGetShareAclView(Path share, Shlwapi shlwapi, Mpr mpr)
+ throws Exception {
+ AclFileAttributeView expectedAcl = new AclView(
+ group("Everyone").type(ALLOW).perms(GENERIC_READ)
+ .flags(FILE_INHERIT, DIRECTORY_INHERIT),
+ group("Administrators").type(ALLOW).perms(GENERIC_ALL)
+ .flags(FILE_INHERIT, DIRECTORY_INHERIT));
+ byte[] dacl = buildDaclMemory(
+ new AceBuilder()
+ .setSid(AccountSid.group("Everyone", null))
+ .setPerms(WinNT.GENERIC_READ)
+ .setFlags(WinNT.OBJECT_INHERIT_ACE, WinNT.CONTAINER_INHERIT_ACE)
+ .build(),
+ new AceBuilder()
+ .setSid(AccountSid.group("Administrators", null))
+ .setPerms(WinNT.GENERIC_ALL)
+ .setFlags(WinNT.OBJECT_INHERIT_ACE, WinNT.CONTAINER_INHERIT_ACE)
+ .build());
+
+ Memory memory = new Memory(dacl.length);
+ memory.write(0, dacl, 0, dacl.length);
+ final Netapi32Ex.SHARE_INFO_502 info = new Netapi32Ex.SHARE_INFO_502();
+ info.shi502_security_descriptor = memory;
+ info.write();
+
+ Netapi32Ex netapi = new UnsupportedNetapi32() {
+ @Override
+ public int NetShareGetInfo(String serverName, String netName, int level,
+ PointerByReference bufptr) {
+ bufptr.setValue(info.getPointer());
+ return WinError.ERROR_SUCCESS;
+ }
+ @Override
+ public int NetApiBufferFree(Pointer buf) {
+ return WinError.ERROR_SUCCESS;
+ }
+ };
+
+ WindowsAclFileAttributeViews wafav =
+ new TestAclFileAttributeViews(null, null, mpr, netapi, shlwapi);
+
+ AclFileAttributeView aclView = wafav.getShareAclView(share);
+ assertNotNull(aclView);
+ assertEquals(expectedAcl.getAcl(), aclView.getAcl());
+ }
+
+ @Test
+ public void testGetShareAclViewNetSareGetInfoFailureAccessDenied()
+ throws Exception {
+ TestHelper.assumeOsIsWindows();
+ testGetShareAclViewNetSareGetInfoFailure(WinError.ERROR_ACCESS_DENIED);
+ }
+
+ @Test
+ public void testGetShareAclViewNetSareGetInfoFailureInvalidLevel()
+ throws Exception {
+ TestHelper.assumeOsIsWindows();
+ testGetShareAclViewNetSareGetInfoFailure(WinError.ERROR_INVALID_LEVEL);
+ }
+
+ @Test
+ public void testGetShareAclViewNetSareGetInfoFailureInvalidParameter()
+ throws Exception {
+ TestHelper.assumeOsIsWindows();
+ testGetShareAclViewNetSareGetInfoFailure(WinError.ERROR_INVALID_PARAMETER);
+ }
+
+ @Test
+ public void testGetShareAclViewNetSareGetInfoFailureInsufficientMemory()
+ throws Exception {
+ TestHelper.assumeOsIsWindows();
+ testGetShareAclViewNetSareGetInfoFailure(WinError.ERROR_NOT_ENOUGH_MEMORY);
+ }
+
+ @Test
+ public void testGetShareAclViewNetSareGetInfoFailureNetNameNotFound()
+ throws Exception {
+ TestHelper.assumeOsIsWindows();
+ testGetShareAclViewNetSareGetInfoFailure(LMErr.NERR_NetNameNotFound);
+ }
+
+ @Test
+ public void testGetShareAclViewNetSareGetInfoFailureOther()
+ throws Exception {
+ TestHelper.assumeOsIsWindows();
+ testGetShareAclViewNetSareGetInfoFailure(WinError.ERROR_NOT_READY);
+ }
+
+ private void testGetShareAclViewNetSareGetInfoFailure(final int error)
+ throws Exception {
+ Shlwapi shlwapi = new Shlwapi() {
+ @Override
+ public boolean PathIsNetworkPath(String pszPath) {
+ return false;
+ }
+ @Override
+ public boolean PathIsUNC(String pszPath) {
+ return true;
+ }
+ };
+ Netapi32Ex netapi = new UnsupportedNetapi32() {
+ @Override
+ public int NetShareGetInfo(String serverName, String netName, int level,
+ PointerByReference bufptr) {
+ return error;
+ }
+ @Override
+ public int NetApiBufferFree(Pointer buf) {
+ return WinError.ERROR_SUCCESS;
+ }
+ };
+ WindowsAclFileAttributeViews wafav =
+ new TestAclFileAttributeViews(null, null, null, netapi, shlwapi);
+ Path share = Paths.get("\\\\server\\share");
+
+ thrown.expect(IOException.class);
+ AclFileAttributeView aclView = wafav.getShareAclView(share);
+ }
+
static class AceBuilder {
private byte type;
private byte flags;