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