From: mayayana on 11 Sep 2009 00:38 It's hard to post clear code here and my full code is not getting through, so I've uploaded a sample project. The more testing, the better. I've got a class and a form where one can set or get permissions for a folder or reg key. Textboxes report the function error codes, standard rights flags, and generic rights flags. (As noted, generic rights are always 0.) A couple of notes: There's a method to revoke rights. It works, without needing to set a new ACE. There's also a method to clear all ACEs for the specified user/group. I've found that's necessary in at least some cases due to the odd way that Windows reads ACEs in the DACL. Details are in my code: www.jsware.net/jsware/zips/ntfsdemo.zip
From: Eduardo on 11 Sep 2009 01:33 mayayana escribi�: > It's hard to post clear code here and my full code > is not getting through, so I've uploaded a sample > project. The more testing, the better. > I've got a class and a form where one can set or get > permissions for a folder or reg key. Textboxes > report the function error codes, standard rights flags, > and generic rights flags. (As noted, generic rights > are always 0.) > > A couple of notes: There's a method to revoke rights. > It works, without needing to set a new ACE. There's > also a method to clear all ACEs for the specified > user/group. I've found that's necessary in at least some > cases due to the odd way that Windows reads ACEs > in the DACL. Details are in my code: > > www.jsware.net/jsware/zips/ntfsdemo.zip Something is not working... If I create a folder under Program files, for the folder I gell all permissions with your code and mine. If I put a file in the folder, and check for the file permissions, I also get all permissions with both codes. I'm testing with the compiled programs, because the IDE runs as admin. But if I try to delete the file from VB code, from the IDE I can, because it runs as admin, but compiled I get error 75, error in acces to file or folder. So? And if I manually delete the file, the UAC pops up for confirmation.
From: mayayana on 11 Sep 2009 10:53 > But if I try to delete the file from VB code, from the IDE I can, > because it runs as admin, but compiled I get error 75, error in acces to > file or folder. > > So? > > And if I manually delete the file, the UAC pops up for confirmation. > I got to looking at your code last night, and also testing further on Win7. What I've found is this: On Win7 with UAC set high I get access denied (error 5) when trying to set permissions for Users. With UAC set low it works. In both cases it's Admin. If I use right-click Run As Admin it works OK. While UAC is messing things up, the permissions values I get when checking permissions is accurate, and the error 5 coming from SetNamedSecurityInfo provides a way to tell whether there are not sufficient rights to change permissions. For my own purposes that works well. I can set permissions...if it errors I can show a message that it didn't work and advise someone installing my software to restart setup with Run As Admin. I'm not sure whether that relates to what you're seeing, but it sounds like both are cases of UAC just blocking rather than prompting. I assume that's due to not having a run-as-admin manifest. After working with your code I finally figured out what was going on there. MapGenericMask sets up the flags in a long to And with the ACCESS_MASK. The values, as you have them in accord with standard practice, are like so: READ 1179785 120089 00010010 0000 0000 1000 1001 WRITE 1179926 120116 00010010 0000 0001 0001 0110 EXECUTE 1179808 1200A0 00000010 0000 0000 1010 0000 ALL 2032127 1F01FF 00011111 0000 0001 1111 1111 (That shows the long, hex version, standard rights byte, and specific rights byte.) Here's the ACCESS_MASK for Users on a folder: 1179817 1200A9 00010010 0000 0000 1010 1001 And here it is for Admin: 203217 1F01FF 00011111 0000 0001 1111 1111 So far, so good. When you use MapGenericMask and then And that with the returned ACCESS_MASK, you get the right results. (Read/Execute for Users, All permissions for Admin.) But it turns out that the constants FILE_ALL_ACCESS, FILE_GENERIC_READ, etc. only works for files/folders. Here's the ACCESS_MASK value returnd for a Registry key: Admin: 983103 00001111 0000 0000 0011 1111 Users: 131097 00000010 0000 0000 0001 1001 Note that the SYNCHRONIZE bit is never set for Registry keys. (The H10 flag -- 5th bit up -- in the standard rights byte.) And the specific flags are different. If I read the standard flags then I get accurate results with both folders and Reg. keys. But if I use the official MS method with MapGenericMask on a Registry key I find that I have no rights at all, no matter who I am! Because the And doesn't return a match, even though the standard rights flags are set. So it appears that using MapGenericMask would require a different set of constants for the mask with each object type. As you noted before, the reall difference between rights and no rights is whether the write bits (WRITE_DAC, WRITE_OWNER) are set: 0000**00 0000 0000 0000 0000 And that holds true *at least* for folders and Reg. keys.
From: Eduardo on 11 Sep 2009 11:55 mayayana escribi�: Hi mayayana: I'm also reading about this issue... from: http://www.teamdev.com/downloads/jniwrapper/winpack/javadoc/com/jniwrapper/win32/system/AccessOptions.html WRITE_OWNER: Provides the right to modify owner of the object. I doesn't seem to me that it means that you have the rights to write to the file. It's something about users I think. What does it mean that someone "is owner of the object"? Or "take ownership", that I also have read somewhere? -*-*-* About the ACCESS_MASK, I think you already know, but anyway I'll mention: It's a 32 bit value. So, if you declare it as long it has 32 bits in a long, and if you declare: Private Type ACCESS_MASK SpecRights As Integer StandardRights As Byte GenericRights As Byte End Type You have also 32 bits, but 16 in a integer, 8 in a byte and the other 8 in another byte. The difference is, that for example the bit 16, the flag DELETE, if you use the ACCESS_MASK, its value is 1 and you have to check it in the StandardRights, but if you use just a long, its value will be &H1FF About the MapGenericMask I really dont understand very well what it does with that conversion. And my guess is that if we knew the bits to check in the ACCESS_MASK, it shouldn't be neccesary. And I think that my code is not working, as I said in my other post. Another test that I just performed now, is open with Notepad a file in Program files\folder\file.txt and modify it, then when I try to save it, I can't. But your code and mine tell me that I have all rights over the file and over the folder where it's contained. from here: http://www.grimes.demon.co.uk/workshops/secWSNine.htm "ACEs will contain the rights that are allowed or denied (or will be audited). There are three types of rights: specific rights which apply to a certain type of object, like reading from a file or being able to terminate a process; standard rights are things that can apply to all objects like the ability to read the DACL or change the object's owner; finally, generic rights are combinations of standard and specific rights. Note that to read the security descriptor (and hence the DACL and ACEs) your account must have the READ_CONTROL right. Generic rights may mean different things depending on the object they are applied to. For example, GENERIC_READ for a file is mapped to the standard rights READ_CONTROL and SYNCHRONIZE and the specific rights to read file data, directories and file and directory attributes." I believe the most important, at least for folders and files are the Specific rights. The generics rights I think may be ignored for what we are doing. About SYNCHRONIZE, I have not idea what it means. My next step would be to start testing differents folders with different rigths and see what bits are set. I see that you already started doing this. And for what I needed, I have my problem solved several days ago, I needed to set rights for "everyone" and remove them, and that part is working perfectly. I was trying to help to get the actual rights of the CU. It's also interesting because it's like a riddle, and a treasure hunt (I don't know if this game is known there but it's a game where you have to find some pieces of information, try to deduce what they mean, then they points you to the next step where there are other pieces of information, and so, until you get the treasure). Of course it would be much easier if we read a book about security LOL.
From: mayayana on 11 Sep 2009 12:52
> WRITE_OWNER: Provides the right to modify owner of the object. > > I doesn't seem to me that it means that you have the rights to write to > the file. > It doesn't seem to be the same as permission to write. As the generic flags indicate, noraml write permission sets sepecific flags along with only the read and synchronize flags of the standard set. But when full permissions are set, WRITE_OWNER and WRITE_DAC are set. I guess the standard rights are an adequate check for our purposes, but they could leave out a case of someone with write permission. On the other hand, I wonder if it's ever the case that people have been assigned FILE_WRITE_DATA rights without full control. That seems unlikely. If we only check for that then a flag of FILE_WRITE_EA Or FILE_APPEND_DATA seems adequate. For what it's worth, I found explanations for most of the flags under the MSDN heading for ZwCreateFile. > About the MapGenericMask I really dont understand very > well what it does > with that conversion. It just fills in the flags of a long variable based on the constants that you provide. That then gets And-ed with the ACCESS_MASK value. It's not very intuitive. '-- Private Const FILE_GENERIC_READ As Long = STANDARD_RIGHTS_READ _ Or FILE_READ_DATA Or FILE_READ_ATTRIBUTES Or _ FILE_READ_EA Or SYNCHRONIZE iGenericAccess = GENERIC_READ iMap.GenericRead = FILE_GENERIC_READ MapGenericMask iGenericAccess, iMap '-- So you set the flag in a long (ACCESS_MASK) for GENERIC_READ, defined what flags constitute GENERIC_READ in the map, then pass the long and the map to MapGenericMask. It looks at the generic flag and sets the bits accordingly based on your FILE_GENERIC_READ constant. I think the confusing part is that the generic flags are not permission indicators. They're operation flags for MapGenericMask. It's all just an automated way to check several flags at once in the ACCESS_MASK. The problem, though, is that the relevant flags are different for different things. > And my guess is that if we knew the bits to check in the ACCESS_MASK, it > shouldn't be neccesary. Yes. > Another test that I just performed now, is open with Notepad a file in > Program files\folder\file.txt and modify it, then when I try to save it, > I can't. > > But your code and mine tell me that I have all rights over the file and > over the folder where it's contained. > Yes, but you're not really Admin unless you've elevated, right? I really don't know how anybody gets anything done, other than diddling on Facebook, running as fake Admin with UAC enabled. :) |