diff --git hadoop-common-project/hadoop-common/src/main/native/src/org/apache/hadoop/io/nativeio/NativeIO.c hadoop-common-project/hadoop-common/src/main/native/src/org/apache/hadoop/io/nativeio/NativeIO.c index df57e0e..76928ea 100644 --- hadoop-common-project/hadoop-common/src/main/native/src/org/apache/hadoop/io/nativeio/NativeIO.c +++ hadoop-common-project/hadoop-common/src/main/native/src/org/apache/hadoop/io/nativeio/NativeIO.c @@ -1236,6 +1236,55 @@ done: #endif } +/* + * Class: Java_org_apache_hadoop_yarn_server_nodemanager_WindowsSecureContainerExecutor_elevatedSetOwner + * Method: createTaskAsUser + * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V + */ +JNIEXPORT void JNICALL +Java_org_apache_hadoop_yarn_server_nodemanager_WindowsSecureContainerExecutor_elevatedSetOwner(JNIEnv* env, + jclass clazz, jstring jpath, jstring juser, jstring jgroup) { +#ifdef UNIX + THROW(env, "java/io/IOException", + "The function elevatedSetOwner is not supported on Unix"); + return NULL; +#endif + +#ifdef WINDOWS + + LPCWSTR path = NULL, user = NULL, group = NULL; + DWORD dwError; + + path = (LPCWSTR) (*env)->GetStringChars(env, jpath, NULL); + if (!path) goto done; // exception was thrown + + if (juser) { + user = (LPCWSTR) (*env)->GetStringChars(env, juser, NULL); + if (!user) goto done; // exception was thrown + } + + if (jgroup) { + group = (LPCWSTR) (*env)->GetStringChars(env, jgroup, NULL); + if (!group) goto done; // exception was thrown + } + + dwError = RpcCall_WinutilsChown(path, user, group); + + if (dwError != ERROR_SUCCESS) { + throw_ioe (env, dwError); + } + + +done: + if (path) (*env)->ReleaseStringChars(env, jpath, path); + if (user) (*env)->ReleaseStringChars(env, juser, user); + if (group) (*env)->ReleaseStringChars(env, jgroup, group); + +#endif + +} + + /** * vim: sw=2: ts=2: et: diff --git hadoop-common-project/hadoop-common/src/main/winutils/chown.c hadoop-common-project/hadoop-common/src/main/winutils/chown.c index 1be8121..d124f73 100644 --- hadoop-common-project/hadoop-common/src/main/winutils/chown.c +++ hadoop-common-project/hadoop-common/src/main/winutils/chown.c @@ -18,93 +18,6 @@ #include "winutils.h" //---------------------------------------------------------------------------- -// Function: ChangeFileOwnerBySid -// -// Description: -// Change a file or directory ownership by giving new owner and group SIDs -// -// Returns: -// ERROR_SUCCESS: on success -// Error code: otherwise -// -// Notes: -// This function is long path safe, i.e. the path will be converted to long -// path format if not already converted. So the caller does not need to do -// the converstion before calling the method. -// -static DWORD ChangeFileOwnerBySid(__in LPCWSTR path, - __in_opt PSID pNewOwnerSid, __in_opt PSID pNewGroupSid) -{ - LPWSTR longPathName = NULL; - INT oldMode = 0; - - SECURITY_INFORMATION securityInformation = 0; - - DWORD dwRtnCode = ERROR_SUCCESS; - - // Convert the path the the long path - // - dwRtnCode = ConvertToLongPath(path, &longPathName); - if (dwRtnCode != ERROR_SUCCESS) - { - goto ChangeFileOwnerByNameEnd; - } - - // Get a pointer to the existing owner information and DACL - // - dwRtnCode = FindFileOwnerAndPermission(longPathName, FALSE, NULL, NULL, &oldMode); - if (dwRtnCode != ERROR_SUCCESS) - { - goto ChangeFileOwnerByNameEnd; - } - - // We need SeTakeOwnershipPrivilege to set the owner if the caller does not - // have WRITE_OWNER access to the object; we need SeRestorePrivilege if the - // SID is not contained in the caller's token, and have the SE_GROUP_OWNER - // permission enabled. - // - if (EnablePrivilege(L"SeTakeOwnershipPrivilege") != ERROR_SUCCESS) - { - fwprintf(stdout, L"INFO: The user does not have SeTakeOwnershipPrivilege.\n"); - } - if (EnablePrivilege(L"SeRestorePrivilege") != ERROR_SUCCESS) - { - fwprintf(stdout, L"INFO: The user does not have SeRestorePrivilege.\n"); - } - - assert(pNewOwnerSid != NULL || pNewGroupSid != NULL); - - // Set the owners of the file. - // - if (pNewOwnerSid != NULL) securityInformation |= OWNER_SECURITY_INFORMATION; - if (pNewGroupSid != NULL) securityInformation |= GROUP_SECURITY_INFORMATION; - dwRtnCode = SetNamedSecurityInfoW( - longPathName, - SE_FILE_OBJECT, - securityInformation, - pNewOwnerSid, - pNewGroupSid, - NULL, - NULL); - if (dwRtnCode != ERROR_SUCCESS) - { - goto ChangeFileOwnerByNameEnd; - } - - // Set the permission on the file for the new owner. - // - dwRtnCode = ChangeFileModeByMask(longPathName, oldMode); - if (dwRtnCode != ERROR_SUCCESS) - { - goto ChangeFileOwnerByNameEnd; - } - -ChangeFileOwnerByNameEnd: - LocalFree(longPathName); - return dwRtnCode; -} - -//---------------------------------------------------------------------------- // Function: Chown // // Description: @@ -130,9 +43,6 @@ int Chown(__in int argc, __in_ecount(argc) wchar_t *argv[]) LPWSTR groupName = NULL; size_t groupNameLen = 0; - PSID pNewOwnerSid = NULL; - PSID pNewGroupSid = NULL; - DWORD dwRtnCode = 0; int ret = EXIT_FAILURE; @@ -210,48 +120,16 @@ int Chown(__in int argc, __in_ecount(argc) wchar_t *argv[]) goto ChownEnd; } - if (userName != NULL) - { - dwRtnCode = GetSidFromAcctNameW(userName, &pNewOwnerSid); - if (dwRtnCode != ERROR_SUCCESS) - { - ReportErrorCode(L"GetSidFromAcctName", dwRtnCode); - fwprintf(stderr, L"Invalid user name: %s\n", userName); - goto ChownEnd; - } - } - - if (groupName != NULL) - { - dwRtnCode = GetSidFromAcctNameW(groupName, &pNewGroupSid); - if (dwRtnCode != ERROR_SUCCESS) - { - ReportErrorCode(L"GetSidFromAcctName", dwRtnCode); - fwprintf(stderr, L"Invalid group name: %s\n", groupName); - goto ChownEnd; - } - } - - if (wcslen(pathName) == 0 || wcsspn(pathName, L"/?|><:*\"") != 0) - { - fwprintf(stderr, L"Incorrect file name format: %s\n", pathName); - goto ChownEnd; - } - - dwRtnCode = ChangeFileOwnerBySid(pathName, pNewOwnerSid, pNewGroupSid); - if (dwRtnCode != ERROR_SUCCESS) - { - ReportErrorCode(L"ChangeFileOwnerBySid", dwRtnCode); - goto ChownEnd; - } + dwRtnCode = ChownImpl(userName, groupName, pathName); + if (dwRtnCode) { + goto ChownEnd; + } ret = EXIT_SUCCESS; ChownEnd: LocalFree(userName); LocalFree(groupName); - LocalFree(pNewOwnerSid); - LocalFree(pNewGroupSid); return ret; } diff --git hadoop-common-project/hadoop-common/src/main/winutils/client.c hadoop-common-project/hadoop-common/src/main/winutils/client.c index bc8efcd..36907fa 100644 --- hadoop-common-project/hadoop-common/src/main/winutils/client.c +++ hadoop-common-project/hadoop-common/src/main/winutils/client.c @@ -44,37 +44,148 @@ VOID ReportClientError(LPWSTR lpszLocation, DWORD dwError) { if (NULL != debugMsg) LocalFree(debugMsg); } +DWORD PrepareRpcBindingHandle( + __out RPC_BINDING_HANDLE* pHadoopWinutilsSvcBinding) { + DWORD dwError = EXIT_FAILURE; + RPC_STATUS status; + LPWSTR lpszStringBinding = NULL; + ULONG ulCode; + RPC_SECURITY_QOS_V3 qos; + PSID pLocalSystemSid = NULL; + SID_IDENTIFIER_AUTHORITY authNT = SECURITY_NT_AUTHORITY; + BOOL rpcBindingInit = FALSE; + + if (!AllocateAndInitializeSid(&authNT, 1, + SECURITY_LOCAL_SYSTEM_RID, + 0, 0, 0, 0, 0, 0, 0, + &pLocalSystemSid)) { + dwError = GetLastError(); + ReportClientError(L"AllocateAndInitializeSid", dwError); + goto done; + } + + ZeroMemory(&qos, sizeof(qos)); + qos.Version = RPC_C_SECURITY_QOS_VERSION_3; + qos.Capabilities = RPC_C_QOS_CAPABILITIES_LOCAL_MA_HINT | RPC_C_QOS_CAPABILITIES_MUTUAL_AUTH; + qos.IdentityTracking = RPC_C_QOS_IDENTITY_DYNAMIC; + qos.ImpersonationType = RPC_C_IMP_LEVEL_DEFAULT; + qos.Sid = pLocalSystemSid; + + status = RpcStringBindingCompose(NULL, + SVCBINDING, + NULL, + SVCNAME, + NULL, + &lpszStringBinding); + if (RPC_S_OK != status) { + ReportClientError(L"RpcStringBindingCompose", status); + dwError = status; + goto done; + } + + status = RpcBindingFromStringBinding(lpszStringBinding, pHadoopWinutilsSvcBinding); + + if (RPC_S_OK != status) { + ReportClientError(L"RpcBindingFromStringBinding", status); + dwError = status; + goto done; + } + rpcBindingInit = TRUE; + + status = RpcBindingSetAuthInfoEx( + *pHadoopWinutilsSvcBinding, + NULL, + RPC_C_AUTHN_LEVEL_PKT_PRIVACY, // AuthnLevel + RPC_C_AUTHN_WINNT, // AuthnSvc + NULL, // AuthnIdentity (self) + RPC_C_AUTHZ_NONE, // AuthzSvc + &qos); + if (RPC_S_OK != status) { + ReportClientError(L"RpcBindingSetAuthInfoEx", status); + dwError = status; + goto done; + } + + dwError = ERROR_SUCCESS; + +done: + + if (dwError && rpcBindingInit) RpcBindingFree(pHadoopWinutilsSvcBinding); + + if (pLocalSystemSid) FreeSid(pLocalSystemSid); + + if (NULL != lpszStringBinding) { + status = RpcStringFree(&lpszStringBinding); + if (RPC_S_OK != status) { + ReportClientError(L"RpcStringFree", status); + } + } + + return dwError; +} + +DWORD RpcCall_WinutilsChown( + __in LPCWSTR filePath, + __in_opt LPCWSTR ownerName, + __in_opt LPCWSTR groupName) { + + DWORD dwError = EXIT_FAILURE; + ULONG ulCode; + DWORD dwSelfPid = GetCurrentProcessId(); + CHOWN_REQUEST request; + RPC_BINDING_HANDLE hHadoopWinutilsSvcBinding; + BOOL rpcBindingInit = FALSE; + + dwError = PrepareRpcBindingHandle(&hHadoopWinutilsSvcBinding); + if (dwError) { + ReportClientError(L"PrepareRpcBindingHandle", dwError); + goto done; + } + rpcBindingInit = TRUE; + + ZeroMemory(&request, sizeof(request)); + request.filePath = filePath; + request.ownerName = ownerName; + request.groupName = groupName; + + RpcTryExcept { + dwError = WinutilsChown(hHadoopWinutilsSvcBinding, &request); + } + RpcExcept(1) { + ulCode = RpcExceptionCode(); + ReportClientError(L"RpcExcept", ulCode); + dwError = (DWORD) ulCode; + } + RpcEndExcept; + +done: + if (rpcBindingInit) RpcBindingFree(&hHadoopWinutilsSvcBinding); + + LogDebugMessage(L"RpcCall_WinutilsChown: %s %s %s :%d\n", + ownerName, groupName, filePath, dwError); + + return dwError; +} + DWORD RpcCall_TaskCreateAsUser( LPCWSTR cwd, LPCWSTR jobName, LPCWSTR user, LPCWSTR pidFile, LPCWSTR cmdLine, HANDLE* phProcess, HANDLE* phThread, HANDLE* phStdIn, HANDLE* phStdOut, HANDLE* phStdErr) { DWORD dwError = EXIT_FAILURE; - RPC_STATUS status; - LPWSTR lpszStringBinding = NULL; ULONG ulCode; DWORD dwSelfPid = GetCurrentProcessId(); CREATE_PROCESS_REQUEST request; CREATE_PROCESS_RESPONSE *response = NULL; - RPC_SECURITY_QOS_V3 qos; - PSID pLocalSystemSid = NULL; - SID_IDENTIFIER_AUTHORITY authNT = SECURITY_NT_AUTHORITY; - - if (!AllocateAndInitializeSid(&authNT, 1, - SECURITY_LOCAL_SYSTEM_RID, - 0, 0, 0, 0, 0, 0, 0, - &pLocalSystemSid)) { - dwError = GetLastError(); - ReportClientError(L"AllocateAndInitializeSid", dwError); + RPC_BINDING_HANDLE hHadoopWinutilsSvcBinding; + BOOL rpcBindingInit = FALSE; + + dwError = PrepareRpcBindingHandle(&hHadoopWinutilsSvcBinding); + if (dwError) { + ReportClientError(L"PrepareRpcBindingHandle", dwError); goto done; } - - ZeroMemory(&qos, sizeof(qos)); - qos.Version = RPC_C_SECURITY_QOS_VERSION_3; - qos.Capabilities = RPC_C_QOS_CAPABILITIES_LOCAL_MA_HINT | RPC_C_QOS_CAPABILITIES_MUTUAL_AUTH; - qos.IdentityTracking = RPC_C_QOS_IDENTITY_DYNAMIC; - qos.ImpersonationType = RPC_C_IMP_LEVEL_DEFAULT; - qos.Sid = pLocalSystemSid; + rpcBindingInit = TRUE; ZeroMemory(&request, sizeof(request)); request.cwd = cwd; @@ -83,42 +194,8 @@ DWORD RpcCall_TaskCreateAsUser( request.pidFile = pidFile; request.cmdLine = cmdLine; - status = RpcStringBindingCompose(NULL, - SVCBINDING, - NULL, - SVCNAME, - NULL, - &lpszStringBinding); - if (RPC_S_OK != status) { - ReportClientError(L"RpcStringBindingCompose", status); - dwError = status; - goto done; - } - - status = RpcBindingFromStringBinding(lpszStringBinding, &hHadoopWinutilsSvcBinding); - - if (RPC_S_OK != status) { - ReportClientError(L"RpcBindingFromStringBinding", status); - dwError = status; - goto done; - } - - status = RpcBindingSetAuthInfoEx( - hHadoopWinutilsSvcBinding, - NULL, - RPC_C_AUTHN_LEVEL_PKT_PRIVACY, // AuthnLevel - RPC_C_AUTHN_WINNT, // AuthnSvc - NULL, // AuthnIdentity (self) - RPC_C_AUTHZ_NONE, // AuthzSvc - &qos); - if (RPC_S_OK != status) { - ReportClientError(L"RpcBindingSetAuthInfoEx", status); - dwError = status; - goto done; - } - RpcTryExcept { - dwError = WinutilsCreateProcessAsUser(dwSelfPid, &request, &response); + dwError = WinutilsCreateProcessAsUser(hHadoopWinutilsSvcBinding, dwSelfPid, &request, &response); } RpcExcept(1) { ulCode = RpcExceptionCode(); @@ -135,27 +212,13 @@ DWORD RpcCall_TaskCreateAsUser( *phStdErr = response->hStdErr; } - // From here on forward we do no change dwError even on RPC cleanup errors - status = RpcBindingFree(&hHadoopWinutilsSvcBinding); - if (RPC_S_OK != status) { - ReportClientError(L"RpcBindingFree", status); - goto done; - } - done: - if (pLocalSystemSid) FreeSid(pLocalSystemSid); - + if (rpcBindingInit) RpcBindingFree(&hHadoopWinutilsSvcBinding); + if (NULL != response) { MIDL_user_free(response); } - if (NULL != lpszStringBinding) { - status = RpcStringFree(&lpszStringBinding); - if (RPC_S_OK != status) { - ReportClientError(L"RpcStringFree", status); - } - } - return dwError; } diff --git hadoop-common-project/hadoop-common/src/main/winutils/hadoopwinutilsvc.idl hadoop-common-project/hadoop-common/src/main/winutils/hadoopwinutilsvc.idl index 2285178..c5090f8 100644 --- hadoop-common-project/hadoop-common/src/main/winutils/hadoopwinutilsvc.idl +++ hadoop-common-project/hadoop-common/src/main/winutils/hadoopwinutilsvc.idl @@ -1,35 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + import "oaidl.idl"; import "ocidl.idl"; [ - uuid(0492311C-1718-4F53-A6EB-86AD7039988D), - version(1.0), - pointer_default(unique), - implicit_handle(handle_t hHadoopWinutilsSvcBinding), - endpoint("ncalrpc:[hadoopwinutilsvc]"), + uuid(0492311C-1718-4F53-A6EB-86AD7039988D), + version(1.0), + pointer_default(unique), + //implicit_handle(handle_t hHadoopWinutilsSvcBinding), + endpoint("ncalrpc:[hadoopwinutilsvc]"), +#ifndef __midl + explicit_handle +#endif ] interface HadoopWinutilSvc { - typedef struct { - [string] const wchar_t* cwd; - [string] const wchar_t* jobName; - [string] const wchar_t* user; - [string] const wchar_t* pidFile; - [string] const wchar_t* cmdLine; - } CREATE_PROCESS_REQUEST; + typedef struct { + [string] const wchar_t* cwd; + [string] const wchar_t* jobName; + [string] const wchar_t* user; + [string] const wchar_t* pidFile; + [string] const wchar_t* cmdLine; + } CREATE_PROCESS_REQUEST; + + typedef struct { + LONG_PTR hProcess; + LONG_PTR hThread; + LONG_PTR hStdIn; + LONG_PTR hStdOut; + LONG_PTR hStdErr; + } CREATE_PROCESS_RESPONSE; + + typedef struct { + [string] const wchar_t* filePath; + [string] const wchar_t* ownerName; + [string] const wchar_t* groupName; + } CHOWN_REQUEST; - typedef struct { - LONG_PTR hProcess; - LONG_PTR hThread; - LONG_PTR hStdIn; - LONG_PTR hStdOut; - LONG_PTR hStdErr; - } CREATE_PROCESS_RESPONSE; - + error_status_t WinutilsChown( + [in] CHOWN_REQUEST *request); - error_status_t WinutilsCreateProcessAsUser( - [in] int nmPid, - [in] CREATE_PROCESS_REQUEST *request, - [out] CREATE_PROCESS_RESPONSE **response); - -} \ No newline at end of file + error_status_t WinutilsCreateProcessAsUser( + [in] int nmPid, + [in] CREATE_PROCESS_REQUEST *request, + [out] CREATE_PROCESS_RESPONSE **response); + +} diff --git hadoop-common-project/hadoop-common/src/main/winutils/include/winutils.h hadoop-common-project/hadoop-common/src/main/winutils/include/winutils.h index 51835b6..5d529d2 100644 --- hadoop-common-project/hadoop-common/src/main/winutils/include/winutils.h +++ hadoop-common-project/hadoop-common/src/main/winutils/include/winutils.h @@ -185,6 +185,15 @@ DWORD UnloadProfileForLogon(__in HANDLE logonHandle, __in PROFILEINFO * pi); DWORD RunService(__in int argc, __in_ecount(argc) wchar_t *argv[]); void ServiceUsage(); + +DWORD ChangeFileOwnerBySid(__in LPCWSTR path, + __in_opt PSID pNewOwnerSid, __in_opt PSID pNewGroupSid); + +DWORD ChownImpl( + __in_opt LPCWSTR userName, + __in_opt LPCWSTR groupName, + __in LPCWSTR pathName); + LPCWSTR GetSystemTimeString(); VOID LogDebugMessage(LPCWSTR format, ...); diff --git hadoop-common-project/hadoop-common/src/main/winutils/libwinutils.c hadoop-common-project/hadoop-common/src/main/winutils/libwinutils.c index 19aae4c..ec11316 100644 --- hadoop-common-project/hadoop-common/src/main/winutils/libwinutils.c +++ hadoop-common-project/hadoop-common/src/main/winutils/libwinutils.c @@ -2068,6 +2068,148 @@ done: } +//---------------------------------------------------------------------------- +// Function: ChangeFileOwnerBySid +// +// Description: +// Change a file or directory ownership by giving new owner and group SIDs +// +// Returns: +// ERROR_SUCCESS: on success +// Error code: otherwise +// +// Notes: +// This function is long path safe, i.e. the path will be converted to long +// path format if not already converted. So the caller does not need to do +// the converstion before calling the method. +// +DWORD ChangeFileOwnerBySid(__in LPCWSTR path, + __in_opt PSID pNewOwnerSid, __in_opt PSID pNewGroupSid) +{ + LPWSTR longPathName = NULL; + INT oldMode = 0; + + SECURITY_INFORMATION securityInformation = 0; + + DWORD dwRtnCode = ERROR_SUCCESS; + + // Convert the path the the long path + // + dwRtnCode = ConvertToLongPath(path, &longPathName); + if (dwRtnCode != ERROR_SUCCESS) + { + goto ChangeFileOwnerByNameEnd; + } + + // Get a pointer to the existing owner information and DACL + // + dwRtnCode = FindFileOwnerAndPermission(longPathName, FALSE, NULL, NULL, &oldMode); + if (dwRtnCode != ERROR_SUCCESS) + { + goto ChangeFileOwnerByNameEnd; + } + + // We need SeTakeOwnershipPrivilege to set the owner if the caller does not + // have WRITE_OWNER access to the object; we need SeRestorePrivilege if the + // SID is not contained in the caller's token, and have the SE_GROUP_OWNER + // permission enabled. + // + if (EnablePrivilege(L"SeTakeOwnershipPrivilege") != ERROR_SUCCESS) + { + fwprintf(stdout, L"INFO: The user does not have SeTakeOwnershipPrivilege.\n"); + } + if (EnablePrivilege(L"SeRestorePrivilege") != ERROR_SUCCESS) + { + fwprintf(stdout, L"INFO: The user does not have SeRestorePrivilege.\n"); + } + + assert(pNewOwnerSid != NULL || pNewGroupSid != NULL); + + // Set the owners of the file. + // + if (pNewOwnerSid != NULL) securityInformation |= OWNER_SECURITY_INFORMATION; + if (pNewGroupSid != NULL) securityInformation |= GROUP_SECURITY_INFORMATION; + dwRtnCode = SetNamedSecurityInfoW( + longPathName, + SE_FILE_OBJECT, + securityInformation, + pNewOwnerSid, + pNewGroupSid, + NULL, + NULL); + if (dwRtnCode != ERROR_SUCCESS) + { + goto ChangeFileOwnerByNameEnd; + } + + // Set the permission on the file for the new owner. + // + dwRtnCode = ChangeFileModeByMask(longPathName, oldMode); + if (dwRtnCode != ERROR_SUCCESS) + { + goto ChangeFileOwnerByNameEnd; + } + +ChangeFileOwnerByNameEnd: + LocalFree(longPathName); + return dwRtnCode; +} + + + +DWORD ChownImpl( + __in_opt LPCWSTR userName, + __in_opt LPCWSTR groupName, + __in LPCWSTR pathName) { + + DWORD dwError; + + PSID pNewOwnerSid = NULL; + PSID pNewGroupSid = NULL; + + if (userName != NULL) + { + dwError = GetSidFromAcctNameW(userName, &pNewOwnerSid); + if (dwError != ERROR_SUCCESS) + { + ReportErrorCode(L"GetSidFromAcctName", dwError); + fwprintf(stderr, L"Invalid user name: %s\n", userName); + goto done; + } + } + + if (groupName != NULL) + { + dwError = GetSidFromAcctNameW(groupName, &pNewGroupSid); + if (dwError != ERROR_SUCCESS) + { + ReportErrorCode(L"GetSidFromAcctName", dwError); + fwprintf(stderr, L"Invalid group name: %s\n", groupName); + goto done; + } + } + + if (wcslen(pathName) == 0 || wcsspn(pathName, L"/?|><:*\"") != 0) + { + fwprintf(stderr, L"Incorrect file name format: %s\n", pathName); + goto done; + } + + dwError = ChangeFileOwnerBySid(pathName, pNewOwnerSid, pNewGroupSid); + if (dwError != ERROR_SUCCESS) + { + ReportErrorCode(L"ChangeFileOwnerBySid", dwError); + goto done; + } +done: + LocalFree(pNewOwnerSid); + LocalFree(pNewGroupSid); + + return dwError; +} + + + LPCWSTR GetSystemTimeString() { __declspec(thread) static WCHAR buffer[1024]; DWORD dwError; diff --git hadoop-common-project/hadoop-common/src/main/winutils/service.c hadoop-common-project/hadoop-common/src/main/winutils/service.c index 70c2a1d..7afaf46 100644 --- hadoop-common-project/hadoop-common/src/main/winutils/service.c +++ hadoop-common-project/hadoop-common/src/main/winutils/service.c @@ -637,6 +637,7 @@ VOID ReportSvcStatus( DWORD dwCurrentState, // The actual S4U work occurs in the spawned process, run and monitored by the NM // error_status_t WinutilsCreateProcessAsUser( + /* [in] */ handle_t IDL_handle, /* [in] */ int nmPid, /* [in] */ CREATE_PROCESS_REQUEST *request, /* [out] */ CREATE_PROCESS_RESPONSE **response) { @@ -866,6 +867,22 @@ done: return dwError; } + +error_status_t WinutilsChown( + /* [in] */ handle_t IDL_handle, + /* [in] */ CHOWN_REQUEST *request) { + DWORD dwError; + dwError = ChownImpl(request->ownerName, request->groupName, request->filePath); + if (dwError) { + ReportSvcCheckError(EVENTLOG_ERROR_TYPE, SERVICE_CATEGORY, + dwError, L"ChownImpl"); + } + LogDebugMessage(L"WinutilsChown: %s %s %s :%d\n", + request->ownerName, request->groupName, request->filePath, dwError); + return dwError; +} + + //---------------------------------------------------------------------------- // Function: ServiceUsage // diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/WindowsSecureContainerExecutor.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/WindowsSecureContainerExecutor.java index baa0b58..09784b8 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/WindowsSecureContainerExecutor.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/WindowsSecureContainerExecutor.java @@ -209,28 +209,30 @@ protected LocalWrapperScriptBuilder getLocalWrapperScriptBuilder( return new WindowsSecureWrapperScriptBuilder(containerWorkDir); } + private static native void elevatedSetOwner(String file, String owner, String group); + @Override protected void copyFile(Path src, Path dst, String owner) throws IOException { super.copyFile(src, dst, owner); - lfs.setOwner(dst, owner, nodeManagerGroup); + elevatedSetOwner(dst.toString(), owner, nodeManagerGroup); } @Override protected void createDir(Path dirPath, FsPermission perms, boolean createParent, String owner) throws IOException { super.createDir(dirPath, perms, createParent, owner); - lfs.setOwner(dirPath, owner, nodeManagerGroup); + elevatedSetOwner(dirPath.toString(), owner, nodeManagerGroup); } @Override protected void setScriptExecutable(Path script, String owner) throws IOException { super.setScriptExecutable(script, null); - lfs.setOwner(script, owner, nodeManagerGroup); + elevatedSetOwner(script.toString(), owner, nodeManagerGroup); } @Override public void localizeClasspathJar(Path classpathJar, String owner) throws IOException { - lfs.setOwner(classpathJar, owner, nodeManagerGroup); + elevatedSetOwner(classpathJar.toString(), owner, nodeManagerGroup); } @Override