Hi Guys,
I'm once again after some advice. . .
I've recently updated some code to use a FileStream. The reason for this is I encounterred an exception due to a file being deleted by a seperate application between calling an
XmlDocument.Save(path)
method and calling my
SetOwner(path, impersonator)
method (below). Using the file stream with the
FileShare.None option specified would allow me to lock the file until all operations had successfully completed.
However, after changing the code I get a
System.UnauthorizedAccessException
exception. On investigation it seems to be the SetAccessControl method which is throwing the exception. I've included the relevant code below, as well as showing in comments how the working method can be called.
Any idea why the FileStream.SetAccessControl throws an access exception when the File.SetAccessControl doesn't?
Thanks in advance,
JB
public void WriteFile(string path, Impersonator impersonator, XmlDocument xmlFile)
{
impersonator.Impersonate();
using (FileStream fs = new FileStream(path, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.None))
{
xmlFile.Save(fs);
SetOwner(fs, impersonator);
fs.Close();
}
impersonator.StopImpersonating();
}
void SetOwner(string path, Impersonator impersonator)
{
System.Security.AccessControl.FileSecurity security = File.GetAccessControl(path);
IdentityReference owner = new NTAccount(SecurityManager.JoinAccount(impersonator.Domain, impersonator.User));
security.SetOwner(owner);
File.SetAccessControl(path,security);
}
void SetOwner(FileStream fileStream, Impersonator impersonator)
{
System.Security.AccessControl.FileSecurity security = fileStream.GetAccessControl();
IdentityReference owner = new NTAccount(SecurityManager.JoinAccount(impersonator.Domain, impersonator.User));
security.SetOwner(owner);
fileStream.SetAccessControl(security);
}
More info on the Impersonator class can be found here, should it be of relevance (the code has changed a little since then, but the basics are the same).
http://www.codeproject.com/Messages/3656550/Re-Impersonation-using-Csharp.aspx[
^]
The exception stack trace is (editted to remove my company name from the namespace):
System.UnauthorizedAccessException: Attempted to perform an unauthorized operation.
at System.Security.AccessControl.Win32.SetSecurityInfo(ResourceType type, String name, SafeHandle handle, SecurityInfos securityInformation, SecurityIdentifier owner, SecurityIdentifier group, GenericAcl sacl, GenericAcl dacl)
at System.Security.AccessControl.NativeObjectSecurity.Persist(String name, SafeHandle handle, AccessControlSections includeSections, Object exceptionContext)
at System.Security.AccessControl.NativeObjectSecurity.Persist(SafeHandle handle, AccessControlSections includeSections, Object exceptionContext)
at System.Security.AccessControl.FileSystemSecurity.Persist(SafeFileHandle handle, String fullPath)
at MyCompanyName.IO.FileSecurity.SetOwner(FileStream fileStream, Impersonator impersonator) in C:\Projects\MyCompanyName.InterfaceApp.Services\MyCompanyName.IO\FileSecurity.cs:line 87
at MyCompanyName.IO.FileSecurity.WriteFile(String path, Impersonator impersonator, XmlDocument xmlFile) in C:\Projects\MyCompanyName.InterfaceApp.Services\MyCompanyName.IO\FileSecurity.cs:line 29
at MyCompanyName.IO.FileSecurity.WriteFile(String path, String account, XmlDocument xmlFile) in C:\Projects\MyCompanyName.InterfaceApp.Services\MyCompanyName.IO\FileSecurity.cs:line 19
at MyCompanyName.InterfaceAppLite.Port.XmlFileSystemSendPort.SendData(InterfaceData data) in C:\Projects\MyCompanyName.InterfaceApp.Services\MyCompanyName.Port\XmlFileSystemSendPort.cs:line 91
at MyCompanyName.InterfaceAppLite.Port.AbstractSendPort.Process() in C:\Projects\MyCompanyName.InterfaceApp.Services\MyCompanyName.Port\AbstractSendPort.cs:line 31
at MyCompanyName.InterfaceAppLite.Common.AbstractProcess.Run() in C:\Projects\MyCompanyName.InterfaceApp.Services\MyCompanyName.InterfaceAppLite.Common\AbstractProcess.cs:line 50