Author: mturk Date: Sat May 23 16:24:09 2009 New Revision: 777950 URL: http://svn.apache.org/viewvc?rev=777950&view=rev Log: Implement File set owner
Modified: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/File.java commons/sandbox/runtime/trunk/src/main/native/os/unix/file.c commons/sandbox/runtime/trunk/src/main/native/os/win32/file.c commons/sandbox/runtime/trunk/src/main/native/shared/descriptor.c commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestFile.java Modified: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/File.java URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/File.java?rev=777950&r1=777949&r2=777950&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/File.java (original) +++ commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/File.java Sat May 23 16:24:09 2009 @@ -19,6 +19,9 @@ import java.io.IOException; import java.net.URI; import java.util.EnumSet; +import org.apache.commons.runtime.Descriptor; +import org.apache.commons.runtime.Group; +import org.apache.commons.runtime.User; /** * An abstract representation of file and directory pathnames that @@ -38,6 +41,9 @@ throws IOException, SecurityException; private static native boolean fprot1(String pathname, int prot) throws IOException, SecurityException; + private static native boolean fprot2(String pathname, + Descriptor user, Descriptor group) + throws IOException, SecurityException; private static native boolean mkslink0(String target, String link) throws IOException, SecurityException, UnsupportedOperationException; @@ -193,6 +199,24 @@ return fprot1(getPath(), FileProtection.bitmapOf(prot)); } + public boolean setFileOwner(User user, Group group) + throws IOException, SecurityException + { + return fprot2(getPath(), user.Id, group.Id); + } + + public boolean setFileOwner(User user) + throws IOException, SecurityException + { + return fprot2(getPath(), user.Id, null); + } + + public boolean setFileOwner(Group group) + throws IOException, SecurityException + { + return fprot2(getPath(), null, group.Id); + } + /** * Returns {...@code true} if the file denoted by this abstract * pathname is symbolic link. Modified: commons/sandbox/runtime/trunk/src/main/native/os/unix/file.c URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/unix/file.c?rev=777950&r1=777949&r2=777950&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/main/native/os/unix/file.c (original) +++ commons/sandbox/runtime/trunk/src/main/native/os/unix/file.c Sat May 23 16:24:09 2009 @@ -19,6 +19,7 @@ #include "acr_arch.h" #include "acr_error.h" #include "acr_string.h" +#include "acr_descriptor.h" #include "acr_file.h" /** @@ -333,3 +334,32 @@ else return JNI_TRUE; } + +ACR_IO_EXPORT_DECLARE(jboolean, File, fprot2)(ACR_JNISTDARGS, jstring pathname, + jobject usr, jobject grp) +{ + int rc = EINVAL; + + UNREFERENCED_O; + WITH_CSTR(pathname) { + DWORD sec = 0; + uid_t susr = ACR_DescriptorGetInt(_E, usr); + gid_t sgrp = ACR_DescriptorGetInt(_E, grp); + + if (chown(J2S(pathname), susr, sgrp)) + rc = errno; + else + rc = 0; + } END_WITH_CSTR(pathname); + + if (rc) { + rc = ACR_FROM_OS_ERROR(rc); + if (ACR_STATUS_IS_EACCES(rc)) + ACR_ThrowException(_E, THROW_NMARK, ACR_EX_ESECURITY, 0); + else + ACR_ThrowException(_E, THROW_NMARK, ACR_EX_EIO, rc); + return JNI_FALSE; + } + else + return JNI_TRUE; +} Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/file.c URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/file.c?rev=777950&r1=777949&r2=777950&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/main/native/os/win32/file.c (original) +++ commons/sandbox/runtime/trunk/src/main/native/os/win32/file.c Sat May 23 16:24:09 2009 @@ -19,6 +19,7 @@ #include "acr_error.h" #include "acr_memory.h" #include "acr_string.h" +#include "acr_descriptor.h" #include "acr_file.h" #define ACR_WANT_LATE_DLL @@ -620,3 +621,103 @@ else return JNI_TRUE; } + +static BOOL SetPrivilege(HANDLE hToken, LPCTSTR lpszPrivilege, + BOOL bEnablePrivilege) +{ + TOKEN_PRIVILEGES tp; + LUID luid; + + if (!LookupPrivilegeValue(NULL, + lpszPrivilege, + &luid)) { + return FALSE; + } + + tp.PrivilegeCount = 1; + tp.Privileges[0].Luid = luid; + if (bEnablePrivilege) + tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + else + tp.Privileges[0].Attributes = 0; + + /* Enable the privilege or disable all privileges. + */ + if (!AdjustTokenPrivileges(hToken, + FALSE, + &tp, + sizeof(TOKEN_PRIVILEGES), + NULL, + NULL)) { + return FALSE; + } + + if (GetLastError() == ERROR_NOT_ALL_ASSIGNED) { + /* The token does not have the specified privilege. */ + return FALSE; + } + + return TRUE; +} + + +ACR_IO_EXPORT_DECLARE(jboolean, File, fprot2)(ACR_JNISTDARGS, jstring pathname, + jobject usr, jobject grp) +{ + int rc = EINVAL; + HANDLE hToken = NULL; + + UNREFERENCED_O; + if (!OpenProcessToken(GetCurrentProcess(), + TOKEN_ADJUST_PRIVILEGES, + &hToken)) { + rc = ACR_GET_OS_ERROR(); + if (ACR_STATUS_IS_EACCES(rc)) + ACR_ThrowException(_E, THROW_NMARK, ACR_EX_ESECURITY, 0); + else + ACR_ThrowException(_E, THROW_NMARK, ACR_EX_EIO, rc); + return JNI_FALSE; + } + /* Enable the SE_TAKE_OWNERSHIP_NAME privilege. + */ + if (!SetPrivilege(hToken, SE_TAKE_OWNERSHIP_NAME, TRUE)) { + rc = ACR_GET_OS_ERROR(); + if (ACR_STATUS_IS_EACCES(rc)) + ACR_ThrowException(_E, THROW_NMARK, ACR_EX_ESECURITY, 0); + else + ACR_ThrowException(_E, THROW_NMARK, ACR_EX_EIO, rc); + CloseHandle(hToken); + return JNI_FALSE; + } + + + WITH_WSTR(pathname) { + DWORD sec = 0; + PSID susr = ACR_DescriptorGetPtr(_E, usr); + PSID sgrp = ACR_DescriptorGetPtr(_E, grp); + + if (susr) + sec |= OWNER_SECURITY_INFORMATION; + if (sgrp) + sec |= GROUP_SECURITY_INFORMATION; + rc = SetNamedSecurityInfoW(J2W(pathname), + SE_FILE_OBJECT, + sec, + susr, + sgrp, + NULL, + NULL); + } END_WITH_WSTR(pathname); + SetPrivilege(hToken, SE_TAKE_OWNERSHIP_NAME, FALSE); + CloseHandle(hToken); + if (rc) { + rc = ACR_FROM_OS_ERROR(rc); + if (ACR_STATUS_IS_EACCES(rc)) + ACR_ThrowException(_E, THROW_NMARK, ACR_EX_ESECURITY, 0); + else + ACR_ThrowException(_E, THROW_NMARK, ACR_EX_EIO, rc); + return JNI_FALSE; + } + else + return JNI_TRUE; +} Modified: commons/sandbox/runtime/trunk/src/main/native/shared/descriptor.c URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/shared/descriptor.c?rev=777950&r1=777949&r2=777950&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/main/native/shared/descriptor.c (original) +++ commons/sandbox/runtime/trunk/src/main/native/shared/descriptor.c Sat May 23 16:24:09 2009 @@ -251,6 +251,8 @@ ACR_DECLARE(void *) ACR_DescriptorGetPtr(ACR_JNISTDARGS) { + if (_O == NULL) + return NULL; if (_clazzn.i && J4MID(0000)) { return GET_IFIELD_V(0001, _O, void *); } @@ -262,6 +264,8 @@ ACR_DECLARE(int) ACR_DescriptorGetInt(ACR_JNISTDARGS) { + if (_O == NULL) + return -1; if (_clazzn.i && J4MID(0000)) { return GET_IFIELD_I(0000, _O); } Modified: commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestFile.java URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestFile.java?rev=777950&r1=777949&r2=777950&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestFile.java (original) +++ commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestFile.java Sat May 23 16:24:09 2009 @@ -192,4 +192,28 @@ f.delete(); } + public void testSetUserOwner() + throws Exception + { + File f = new File("ffoo"); + f.createNewFile(); + User u = User.getEffective(); + + + f.setFileOwner(u); + f.delete(); + } + + public void testSetGroupOwner() + throws Exception + { + File f = new File("ffoo"); + f.createNewFile(); + Group g = Group.getEffective(); + + f.setFileOwner(g); + f.delete(); + } + + }