893N/A/*
2362N/A * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
893N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
893N/A *
893N/A * This code is free software; you can redistribute it and/or modify it
893N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
893N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
893N/A *
893N/A * This code is distributed in the hope that it will be useful, but WITHOUT
893N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
893N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
893N/A * version 2 for more details (a copy is included in the LICENSE file that
893N/A * accompanied this code).
893N/A *
893N/A * You should have received a copy of the GNU General Public License version
893N/A * 2 along with this work; if not, write to the Free Software Foundation,
893N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
893N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
893N/A */
893N/A
893N/Apackage sun.nio.fs;
893N/A
893N/Aimport static sun.nio.fs.WindowsNativeDispatcher.*;
893N/Aimport static sun.nio.fs.WindowsConstants.*;
893N/A
893N/A/**
893N/A * Security related utility methods.
893N/A */
893N/A
893N/Aclass WindowsSecurity {
893N/A private WindowsSecurity() { }
893N/A
893N/A // opens process token for given access
893N/A private static long openProcessToken(int access) {
893N/A try {
893N/A return OpenProcessToken(GetCurrentProcess(), access);
893N/A } catch (WindowsException x) {
893N/A return 0L;
893N/A }
893N/A }
893N/A
893N/A /**
893N/A * Returns the access token for this process with TOKEN_DUPLICATE access
893N/A */
893N/A static final long processTokenWithDuplicateAccess =
893N/A openProcessToken(TOKEN_DUPLICATE);
893N/A
893N/A /**
893N/A * Returns the access token for this process with TOKEN_QUERY access
893N/A */
893N/A static final long processTokenWithQueryAccess =
893N/A openProcessToken(TOKEN_QUERY);
893N/A
893N/A /**
893N/A * Returned by enablePrivilege when code may require a given privilege.
893N/A * The drop method should be invoked after the operation completes so as
893N/A * to revert the privilege.
893N/A */
893N/A static interface Privilege {
893N/A void drop();
893N/A }
893N/A
893N/A /**
893N/A * Attempts to enable the given privilege for this method.
893N/A */
893N/A static Privilege enablePrivilege(String priv) {
893N/A final long pLuid;
893N/A try {
893N/A pLuid = LookupPrivilegeValue(priv);
893N/A } catch (WindowsException x) {
893N/A // indicates bug in caller
893N/A throw new AssertionError(x);
893N/A }
893N/A
893N/A long hToken = 0L;
893N/A boolean impersontating = false;
893N/A boolean elevated = false;
893N/A try {
893N/A hToken = OpenThreadToken(GetCurrentThread(),
893N/A TOKEN_ADJUST_PRIVILEGES, false);
893N/A if (hToken == 0L && processTokenWithDuplicateAccess != 0L) {
893N/A hToken = DuplicateTokenEx(processTokenWithDuplicateAccess,
893N/A (TOKEN_ADJUST_PRIVILEGES|TOKEN_IMPERSONATE));
893N/A SetThreadToken(0L, hToken);
893N/A impersontating = true;
893N/A }
893N/A
893N/A if (hToken != 0L) {
893N/A AdjustTokenPrivileges(hToken, pLuid, SE_PRIVILEGE_ENABLED);
893N/A elevated = true;
893N/A }
893N/A } catch (WindowsException x) {
893N/A // nothing to do, privilege not enabled
893N/A }
893N/A
893N/A final long token = hToken;
893N/A final boolean stopImpersontating = impersontating;
893N/A final boolean needToRevert = elevated;
893N/A
893N/A return new Privilege() {
893N/A @Override
893N/A public void drop() {
6091N/A if (token != 0L) {
6091N/A try {
6091N/A if (stopImpersontating)
6091N/A SetThreadToken(0L, 0L);
6091N/A else if (needToRevert)
893N/A AdjustTokenPrivileges(token, pLuid, 0);
6091N/A } catch (WindowsException x) {
6091N/A // should not happen
6091N/A throw new AssertionError(x);
6091N/A } finally {
6091N/A CloseHandle(token);
893N/A }
893N/A }
893N/A }
893N/A };
893N/A }
6091N/A
6091N/A /**
6091N/A * Check the access right against the securityInfo in the current thread.
6091N/A */
6091N/A static boolean checkAccessMask(long securityInfo, int accessMask,
6091N/A int genericRead, int genericWrite, int genericExecute, int genericAll)
6091N/A throws WindowsException
6091N/A {
6091N/A int privilegies = TOKEN_QUERY;
6091N/A long hToken = OpenThreadToken(GetCurrentThread(), privilegies, false);
6091N/A if (hToken == 0L && processTokenWithDuplicateAccess != 0L)
6091N/A hToken = DuplicateTokenEx(processTokenWithDuplicateAccess,
6091N/A privilegies);
6091N/A
6091N/A boolean hasRight = false;
6091N/A if (hToken != 0L) {
6091N/A try {
6091N/A hasRight = AccessCheck(hToken, securityInfo, accessMask,
6091N/A genericRead, genericWrite, genericExecute, genericAll);
6091N/A } finally {
6091N/A CloseHandle(hToken);
6091N/A }
6091N/A }
6091N/A return hasRight;
6091N/A }
6091N/A
893N/A}