Tech Off Thread

10 posts

Forum Read Only

This forum has been made read only by the site admins. No new threads or comments can be added.

Can't modify file in system root despite giving My acc/USER group Full access?

Back to Forum: Tech Off
  • User profile image
    androidi

    I made a program back in XP days that modifies an existing file in the system root (eg. C:\). (first run to create the file of course would need full Admin or uac promotion)  Since Vista the program hasn't been able to modify the file, despite manually adding the Full Access ACL for myself or anyone in USER to the file (neither worked).

     

    My "solution" since Vista has been to run the program as Admin but I'd like some good explanation why the ACL's seem to be entirely ignored in this case and is there anything besides running as admin or some down right hacking to get around this? I could special case the system drive for writing somewhere else (eg. isolated storage) but without going into what the app does that's not an intuitive fix. I didn't choose the drive root without much consideration.

     

    update:

    doing

    var f2 = new FileIOPermission(FileIOPermissionAccess.AllAccess, "c:\\thefile");
    
    f2.Demand();  
    f2.Assert(); 

     

    gives no error or exception. But upon write or SetAttributes I get UnauthorizedAccessException. This is Win7RC and to me something here seems to be a bit broken or unintuitive. Expert opinions?

  • User profile image
    AndyC

    The obvious question would be "Why not just write the temp file to the temp directory in the first place?"

     

    Putting that aside for a moment, the default ACLs on C:\ dont allow the creation of files, only folders. So if the file isn't pre-existing it's definitely going to fail without Administrator rights. Assuming you have pre-created the file, dumping the ACLs and posting them here in SDDL will probably mke it easier to figure out what's going on.

     

    It might also depend on how you're manipulating the file, attempting to write to it by recreating it might fall foul of the parent folder's NTFS permissions (though NT does some funky stuff to try to prevent that).

  • User profile image
    androidi

    AndyC said:

    The obvious question would be "Why not just write the temp file to the temp directory in the first place?"

     

    Putting that aside for a moment, the default ACLs on C:\ dont allow the creation of files, only folders. So if the file isn't pre-existing it's definitely going to fail without Administrator rights. Assuming you have pre-created the file, dumping the ACLs and posting them here in SDDL will probably mke it easier to figure out what's going on.

     

    It might also depend on how you're manipulating the file, attempting to write to it by recreating it might fall foul of the parent folder's NTFS permissions (though NT does some funky stuff to try to prevent that).

    Sorry I just realised my original post spoke about temp file (I named it blah.tmp originaly, better name is blah.cache) and I just edited out mentions of that.

     

    The operations I need to perform:

     

    Everytime, I'd like to do this without UAC popups to the file in the root:

     Stream stream = new FileStream(persistfile, FileMode.Open, FileAccess.Write, FileShare.None);

     

    The following isn't really mandatory but having it hidden shouldn't impede from modifying it afaik.

     

     ///.... modify content and close

     

    File.SetAttributes(persistfile, FileAttributes.Hidden | FileAttributes.NotContentIndexed);

  • User profile image
    androidi

    AndyC said:

    The obvious question would be "Why not just write the temp file to the temp directory in the first place?"

     

    Putting that aside for a moment, the default ACLs on C:\ dont allow the creation of files, only folders. So if the file isn't pre-existing it's definitely going to fail without Administrator rights. Assuming you have pre-created the file, dumping the ACLs and posting them here in SDDL will probably mke it easier to figure out what's going on.

     

    It might also depend on how you're manipulating the file, attempting to write to it by recreating it might fall foul of the parent folder's NTFS permissions (though NT does some funky stuff to try to prevent that).

    I don't know what util gives best output, here's the output from AccessChk -v thefile:

     

    High Mandatory Level [No-Write-Up]
      RW TST\MyAccount
            FILE_ALL_ACCESS
      RW BUILTIN\Users
            FILE_ALL_ACCESS
      RW BUILTIN\Administrators
            FILE_ALL_ACCESS
      RW NT AUTHORITY\SYSTEM
            FILE_ALL_ACCESS
      RW NT AUTHORITY\Authenticated Users
            FILE_ADD_FILE
            FILE_ADD_SUBDIRECTORY
            FILE_APPEND_DATA
            FILE_EXECUTE
            FILE_LIST_DIRECTORY
            FILE_READ_ATTRIBUTES
            FILE_READ_DATA
            FILE_READ_EA
            FILE_TRAVERSE
            FILE_WRITE_ATTRIBUTES
            FILE_WRITE_DATA
            FILE_WRITE_EA
            DELETE
            SYNCHRONIZE
            READ_CONTROL

  • User profile image
    Jorgie

    The root of the system drive is a 'SYSTEM' area. Modifiying files in it require UAC elevation. Period.

     

    You need to put your file in a better place.

  • User profile image
    figuerres

    Jorgie said:

    The root of the system drive is a 'SYSTEM' area. Modifiying files in it require UAC elevation. Period.

     

    You need to put your file in a better place.

    Seconded.

     

    there are standard folder names for stuff like per user files and data files etc....

     

    for one thing if you put files *only* in the proper \user\* folder then backup and restore can be done per user w/o having to backup the whole disk.

    this also helps make the app work better with things like terminal server or the user trasnfer tool - move my files to a new pc thing.

    it would also make the app work better in some corp. lans where users can not store files on the local drives and any files not in the users profile may be wiped at any time.

     

    and documenting where the files are so that folks know in case they have a false alarm from a malware scanner etc...

     

    see this in c#

    Application.UserAppDataPath

     or

    Application.LocalUserAppDataPath

    or

    Application.CommonAppDataPath   <- shared files for all users of this app.

     

    also using them takes case of the drive letter in case it's no C:

    and if the user or the admin move the user folders to a different drive or map them to a network share....

    then your app works better in more cases.

     

    this aint DOS or WIndows95 anymore.

     

    *PLEASE* follow the guildines on how apps are supposed to install and put files.

     

  • User profile image
    androidi

    figuerres said:
    Jorgie said:
    *snip*

    Seconded.

     

    there are standard folder names for stuff like per user files and data files etc....

     

    for one thing if you put files *only* in the proper \user\* folder then backup and restore can be done per user w/o having to backup the whole disk.

    this also helps make the app work better with things like terminal server or the user trasnfer tool - move my files to a new pc thing.

    it would also make the app work better in some corp. lans where users can not store files on the local drives and any files not in the users profile may be wiped at any time.

     

    and documenting where the files are so that folks know in case they have a false alarm from a malware scanner etc...

     

    see this in c#

    Application.UserAppDataPath

     or

    Application.LocalUserAppDataPath

    or

    Application.CommonAppDataPath   <- shared files for all users of this app.

     

    also using them takes case of the drive letter in case it's no C:

    and if the user or the admin move the user folders to a different drive or map them to a network share....

    then your app works better in more cases.

     

    this aint DOS or WIndows95 anymore.

     

    *PLEASE* follow the guildines on how apps are supposed to install and put files.

     

    The app I made needs to know where the file is and modify it even when putting in a hdd from another computer. So if I put in a system hdd from another computer it would be quite crappy to start figuring out where the file might be without access to environment variables etc. An ok compromise would be if I could elevate the program when needed at runtime instead of doing that on every run. I agree on your other points however that still leaves the question why the Demand/Assert gave no errors.

     

    re: Guidelines. Just following the same guideline as Microsoft when throwing these files in C:\ Smiley

     

    dd_depcheckdotnetfx30.txt
    dd_dotnetfx3error.txt
    dd_dotnetfx3install.txt
    dd_vcredistMSI782E.txt
    dd_vcredistUI782E.txt
    dd_VC_i64RuntimeMSI27F6.txt
    dd_VC_i64RuntimeUI27F6.txt
    dd_VC_x64RuntimeMSI27EF.txt
    dd_VC_x64RuntimeUI27EF.txt
    dd_VC_x86RuntimeMSI27E6.txt
    dd_VC_x86RuntimeUI27E6.txt

  • User profile image
    ManipUni

    Stop programming badly. Put it in their roaming profile, Program Files, or the system temp' directory.

     

     

  • User profile image
    AndyC

    androidi said:
    figuerres said:
    *snip*

    The app I made needs to know where the file is and modify it even when putting in a hdd from another computer. So if I put in a system hdd from another computer it would be quite crappy to start figuring out where the file might be without access to environment variables etc. An ok compromise would be if I could elevate the program when needed at runtime instead of doing that on every run. I agree on your other points however that still leaves the question why the Demand/Assert gave no errors.

     

    re: Guidelines. Just following the same guideline as Microsoft when throwing these files in C:\ Smiley

     

    dd_depcheckdotnetfx30.txt
    dd_dotnetfx3error.txt
    dd_dotnetfx3install.txt
    dd_vcredistMSI782E.txt
    dd_vcredistUI782E.txt
    dd_VC_i64RuntimeMSI27F6.txt
    dd_VC_i64RuntimeUI27F6.txt
    dd_VC_x64RuntimeMSI27EF.txt
    dd_VC_x64RuntimeUI27EF.txt
    dd_VC_x86RuntimeMSI27E6.txt
    dd_VC_x86RuntimeUI27E6.txt

    Whilst I 100% agree with everyone elses comments that it's the wrong place to put files and you absolutely should be using the correct location (for one thing, you app is going to break with Fast User Switching and numerous other scenarios), let's look beyond that and see what the problem is.

     

    In this case, I suspect it's the low level code for FileStream.Open and I don't think it's going to be easily worked around whilst continuing to write to the root of the drive, as it would imply it's caused by the permissions on C:\ itself and that's not something you want to try changing. The quickest solution at this point is to put a folder in the root of C:\ and then store your file inside it. That should get your app working again with the minimum amount of effort.

  • User profile image
    figuerres

    androidi said:
    figuerres said:
    *snip*

    The app I made needs to know where the file is and modify it even when putting in a hdd from another computer. So if I put in a system hdd from another computer it would be quite crappy to start figuring out where the file might be without access to environment variables etc. An ok compromise would be if I could elevate the program when needed at runtime instead of doing that on every run. I agree on your other points however that still leaves the question why the Demand/Assert gave no errors.

     

    re: Guidelines. Just following the same guideline as Microsoft when throwing these files in C:\ Smiley

     

    dd_depcheckdotnetfx30.txt
    dd_dotnetfx3error.txt
    dd_dotnetfx3install.txt
    dd_vcredistMSI782E.txt
    dd_vcredistUI782E.txt
    dd_VC_i64RuntimeMSI27F6.txt
    dd_VC_i64RuntimeUI27F6.txt
    dd_VC_x64RuntimeMSI27EF.txt
    dd_VC_x64RuntimeUI27EF.txt
    dd_VC_x86RuntimeMSI27E6.txt
    dd_VC_x86RuntimeUI27E6.txt

    if you need to get the file from a networked computer then the correct way is to save a config setting that lists the "standard" locations and add an option for UNC path

    if UNC then store a string for the path name to the network share.

     

    not hard to do.  and also will follow the standards for this kind of use.

Conversation locked

This conversation has been locked by the site admins. No new comments can be made.