0N/A/*
0N/A * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
0N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
0N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
0N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
0N/A * or visit www.oracle.com if you need additional information or have any
0N/A * questions.
0N/A */
0N/A
0N/Apackage sun.nio.fs;
0N/A
0N/Aimport java.nio.file.ProviderMismatchException;
0N/Aimport java.nio.file.attribute.*;
0N/Aimport java.util.*;
0N/Aimport java.io.IOException;
0N/A
0N/Aimport static sun.nio.fs.WindowsNativeDispatcher.*;
0N/Aimport static sun.nio.fs.WindowsConstants.*;
0N/A
0N/A/**
233N/A * Windows implementation of AclFileAttributeView.
233N/A */
233N/A
233N/Aclass WindowsAclFileAttributeView
233N/A extends AbstractAclFileAttributeView
233N/A{
233N/A /**
233N/A * typedef struct _SECURITY_DESCRIPTOR {
233N/A * BYTE Revision;
233N/A * BYTE Sbz1;
233N/A * SECURITY_DESCRIPTOR_CONTROL Control;
233N/A * PSID Owner;
233N/A * PSID Group;
233N/A * PACL Sacl;
233N/A * PACL Dacl;
564N/A * } SECURITY_DESCRIPTOR;
0N/A */
0N/A private static final short SIZEOF_SECURITY_DESCRIPTOR = 20;
0N/A
0N/A private final WindowsPath file;
0N/A private final boolean followLinks;
0N/A
0N/A WindowsAclFileAttributeView(WindowsPath file, boolean followLinks) {
0N/A this.file = file;
0N/A this.followLinks = followLinks;
0N/A }
233N/A
233N/A // permision check
0N/A private void checkAccess(WindowsPath file,
114N/A boolean checkRead,
114N/A boolean checkWrite)
114N/A {
114N/A SecurityManager sm = System.getSecurityManager();
114N/A if (sm != null) {
114N/A if (checkRead)
0N/A sm.checkRead(file.getPathForPermissionCheck());
0N/A if (checkWrite)
0N/A sm.checkWrite(file.getPathForPermissionCheck());
0N/A sm.checkPermission(new RuntimePermission("accessUserInformation"));
0N/A }
0N/A }
0N/A
563N/A // invokes GetFileSecurity to get requested security information
563N/A static NativeBuffer getFileSecurity(String path, int request)
563N/A throws IOException
563N/A {
0N/A // invoke get to buffer size
422N/A int size = 0;
422N/A try {
422N/A size = GetFileSecurity(path, request, 0L, 0);
0N/A } catch (WindowsException x) {
422N/A x.rethrowAsIOException(path);
0N/A }
422N/A assert size > 0;
0N/A
0N/A // allocate buffer and re-invoke to get security information
0N/A NativeBuffer buffer = NativeBuffers.getNativeBuffer(size);
0N/A try {
0N/A for (;;) {
0N/A int newSize = GetFileSecurity(path, request, buffer.address(), size);
0N/A if (newSize <= size)
0N/A return buffer;
233N/A
233N/A // buffer was insufficient
233N/A buffer.release();
233N/A buffer = NativeBuffers.getNativeBuffer(newSize);
0N/A size = newSize;
0N/A }
0N/A } catch (WindowsException x) {
0N/A buffer.release();
0N/A x.rethrowAsIOException(path);
0N/A return null;
110N/A }
110N/A }
121N/A
0N/A @Override
0N/A public UserPrincipal getOwner()
0N/A throws IOException
0N/A {
0N/A checkAccess(file, true, false);
0N/A
0N/A // GetFileSecurity does not follow links so when following links we
0N/A // need the final target
0N/A String path = WindowsLinkSupport.getFinalPath(file, followLinks);
0N/A NativeBuffer buffer = getFileSecurity(path, OWNER_SECURITY_INFORMATION);
0N/A try {
0N/A // get the address of the SID
0N/A long sidAddress = GetSecurityDescriptorOwner(buffer.address());
0N/A if (sidAddress == 0L)
121N/A throw new IOException("no owner");
0N/A return WindowsUserPrincipals.fromSid(sidAddress);
0N/A } catch (WindowsException x) {
0N/A x.rethrowAsIOException(file);
0N/A return null;
0N/A } finally {
0N/A buffer.release();
0N/A }
511N/A }
0N/A
0N/A @Override
0N/A public List<AclEntry> getAcl()
0N/A throws IOException
0N/A {
0N/A checkAccess(file, true, false);
0N/A
0N/A // GetFileSecurity does not follow links so when following links we
0N/A // need the final target
0N/A String path = WindowsLinkSupport.getFinalPath(file, followLinks);
0N/A
0N/A // ALLOW and DENY entries in DACL;
0N/A // AUDIT entries in SACL (ignore for now as it requires privileges)
0N/A NativeBuffer buffer = getFileSecurity(path, DACL_SECURITY_INFORMATION);
185N/A try {
0N/A return WindowsSecurityDescriptor.getAcl(buffer.address());
0N/A } finally {
0N/A buffer.release();
0N/A }
0N/A }
0N/A
0N/A @Override
0N/A public void setOwner(UserPrincipal obj)
0N/A throws IOException
0N/A {
233N/A if (obj == null)
233N/A throw new NullPointerException("'owner' is null");
233N/A if (!(obj instanceof WindowsUserPrincipals.User))
0N/A throw new ProviderMismatchException();
0N/A WindowsUserPrincipals.User owner = (WindowsUserPrincipals.User)obj;
0N/A
121N/A // permission check
121N/A checkAccess(file, false, true);
0N/A
0N/A // SetFileSecurity does not follow links so when following links we
0N/A // need the final target
121N/A String path = WindowsLinkSupport.getFinalPath(file, followLinks);
0N/A
0N/A // ConvertStringSidToSid allocates memory for SID so must invoke
0N/A // LocalFree to free it when we are done
0N/A long pOwner = 0L;
0N/A try {
0N/A pOwner = ConvertStringSidToSid(owner.sidString());
0N/A } catch (WindowsException x) {
0N/A throw new IOException("Failed to get SID for " + owner.getName()
0N/A + ": " + x.errorString());
0N/A }
0N/A
0N/A // Allocate buffer for security descriptor, initialize it, set
0N/A // owner information and update the file.
0N/A try {
0N/A NativeBuffer buffer = NativeBuffers.getNativeBuffer(SIZEOF_SECURITY_DESCRIPTOR);
0N/A try {
0N/A InitializeSecurityDescriptor(buffer.address());
0N/A SetSecurityDescriptorOwner(buffer.address(), pOwner);
0N/A // may need SeRestorePrivilege to set the owner
0N/A WindowsSecurity.Privilege priv =
0N/A WindowsSecurity.enablePrivilege("SeRestorePrivilege");
0N/A try {
0N/A SetFileSecurity(path,
0N/A OWNER_SECURITY_INFORMATION,
0N/A buffer.address());
0N/A } finally {
0N/A priv.drop();
0N/A }
0N/A } catch (WindowsException x) {
0N/A x.rethrowAsIOException(file);
0N/A } finally {
0N/A buffer.release();
0N/A }
0N/A } finally {
0N/A LocalFree(pOwner);
109N/A }
109N/A }
109N/A
109N/A @Override
109N/A public void setAcl(List<AclEntry> acl) throws IOException {
109N/A checkAccess(file, false, true);
109N/A
109N/A // SetFileSecurity does not follow links so when following links we
110N/A // need the final target
109N/A String path = WindowsLinkSupport.getFinalPath(file, followLinks);
109N/A WindowsSecurityDescriptor sd = WindowsSecurityDescriptor.create(acl);
109N/A try {
109N/A SetFileSecurity(path, DACL_SECURITY_INFORMATION, sd.address());
109N/A } catch (WindowsException x) {
109N/A x.rethrowAsIOException(file);
0N/A } finally {
0N/A sd.release();
0N/A }
0N/A }
0N/A}
0N/A