Path: blob/master/src/java.base/windows/classes/sun/nio/fs/WindowsAclFileAttributeView.java
41139 views
/*1* Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.nio.fs;2627import java.nio.file.ProviderMismatchException;28import java.nio.file.attribute.*;29import java.util.*;30import java.io.IOException;3132import static sun.nio.fs.WindowsNativeDispatcher.*;33import static sun.nio.fs.WindowsConstants.*;3435/**36* Windows implementation of AclFileAttributeView.37*/3839class WindowsAclFileAttributeView40extends AbstractAclFileAttributeView41{42/**43* typedef struct _SECURITY_DESCRIPTOR {44* BYTE Revision;45* BYTE Sbz1;46* SECURITY_DESCRIPTOR_CONTROL Control;47* PSID Owner;48* PSID Group;49* PACL Sacl;50* PACL Dacl;51* } SECURITY_DESCRIPTOR;52*/53private static final short SIZEOF_SECURITY_DESCRIPTOR = 20;5455private final WindowsPath file;56private final boolean followLinks;5758WindowsAclFileAttributeView(WindowsPath file, boolean followLinks) {59this.file = file;60this.followLinks = followLinks;61}6263// permission check64private void checkAccess(WindowsPath file,65boolean checkRead,66boolean checkWrite)67{68@SuppressWarnings("removal")69SecurityManager sm = System.getSecurityManager();70if (sm != null) {71if (checkRead)72sm.checkRead(file.getPathForPermissionCheck());73if (checkWrite)74sm.checkWrite(file.getPathForPermissionCheck());75sm.checkPermission(new RuntimePermission("accessUserInformation"));76}77}7879// invokes GetFileSecurity to get requested security information80static NativeBuffer getFileSecurity(String path, int request)81throws IOException82{83// invoke get to buffer size84int size = 0;85try {86size = GetFileSecurity(path, request, 0L, 0);87} catch (WindowsException x) {88x.rethrowAsIOException(path);89}90assert size > 0;9192// allocate buffer and re-invoke to get security information93NativeBuffer buffer = NativeBuffers.getNativeBuffer(size);94try {95for (;;) {96int newSize = GetFileSecurity(path, request, buffer.address(), size);97if (newSize <= size)98return buffer;99100// buffer was insufficient101buffer.release();102buffer = NativeBuffers.getNativeBuffer(newSize);103size = newSize;104}105} catch (WindowsException x) {106buffer.release();107x.rethrowAsIOException(path);108return null;109}110}111112@Override113public UserPrincipal getOwner()114throws IOException115{116checkAccess(file, true, false);117118// GetFileSecurity does not follow links so when following links we119// need the final target120String path = WindowsLinkSupport.getFinalPath(file, followLinks);121NativeBuffer buffer = getFileSecurity(path, OWNER_SECURITY_INFORMATION);122try {123// get the address of the SID124long sidAddress = GetSecurityDescriptorOwner(buffer.address());125if (sidAddress == 0L)126throw new IOException("no owner");127return WindowsUserPrincipals.fromSid(sidAddress);128} catch (WindowsException x) {129x.rethrowAsIOException(file);130return null;131} finally {132buffer.release();133}134}135136@Override137public List<AclEntry> getAcl()138throws IOException139{140checkAccess(file, true, false);141142// GetFileSecurity does not follow links so when following links we143// need the final target144String path = WindowsLinkSupport.getFinalPath(file, followLinks);145146// ALLOW and DENY entries in DACL;147// AUDIT entries in SACL (ignore for now as it requires privileges)148NativeBuffer buffer = getFileSecurity(path, DACL_SECURITY_INFORMATION);149try {150return WindowsSecurityDescriptor.getAcl(buffer.address());151} finally {152buffer.release();153}154}155156@Override157public void setOwner(UserPrincipal obj)158throws IOException159{160if (obj == null)161throw new NullPointerException("'owner' is null");162if (!(obj instanceof WindowsUserPrincipals.User))163throw new ProviderMismatchException();164WindowsUserPrincipals.User owner = (WindowsUserPrincipals.User)obj;165166// permission check167checkAccess(file, false, true);168169// SetFileSecurity does not follow links so when following links we170// need the final target171String path = WindowsLinkSupport.getFinalPath(file, followLinks);172173// ConvertStringSidToSid allocates memory for SID so must invoke174// LocalFree to free it when we are done175long pOwner = 0L;176try {177pOwner = ConvertStringSidToSid(owner.sidString());178} catch (WindowsException x) {179throw new IOException("Failed to get SID for " + owner.getName()180+ ": " + x.errorString());181}182183// Allocate buffer for security descriptor, initialize it, set184// owner information and update the file.185try {186NativeBuffer buffer = NativeBuffers.getNativeBuffer(SIZEOF_SECURITY_DESCRIPTOR);187try {188InitializeSecurityDescriptor(buffer.address());189SetSecurityDescriptorOwner(buffer.address(), pOwner);190// may need SeRestorePrivilege to set the owner191WindowsSecurity.Privilege priv =192WindowsSecurity.enablePrivilege("SeRestorePrivilege");193try {194SetFileSecurity(path,195OWNER_SECURITY_INFORMATION,196buffer.address());197} finally {198priv.drop();199}200} catch (WindowsException x) {201x.rethrowAsIOException(file);202} finally {203buffer.release();204}205} finally {206LocalFree(pOwner);207}208}209210@Override211public void setAcl(List<AclEntry> acl) throws IOException {212checkAccess(file, false, true);213214// SetFileSecurity does not follow links so when following links we215// need the final target216String path = WindowsLinkSupport.getFinalPath(file, followLinks);217WindowsSecurityDescriptor sd = WindowsSecurityDescriptor.create(acl);218try {219SetFileSecurity(path, DACL_SECURITY_INFORMATION, sd.address());220} catch (WindowsException x) {221x.rethrowAsIOException(file);222} finally {223sd.release();224}225}226}227228229