Click here to Skip to main content
15,885,914 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
I need to delete files after I am done with them in my wcf email service built in c# .net 4.0, but my delete method can't do that, to explain how my process works, I use a console app to call my wcf service hosted on IIS 7.x on another/remote server, that remote server would create this file on c:\log where the service needs to delete the file after it is done with it. I even tried to test my wcf service on my PC which is hosted on IIS 6 but still get the same error, I am not sure if I know how to define the user name used in remoting into the remote system, or is there something wrong in my control access.

Here is the error I capture:
Failed to delete, msg: Some or all identity references could not be translated. Inner Excep:  Stack trace:    at System.Security.Principal.NTAccount.Translate(IdentityReferenceCollection sourceAccounts, Type targetType, Boolean forceSuccess)
   at System.Security.Principal.NTAccount.Translate(Type targetType)
   at System.Security.AccessControl.CommonObjectSecurity.ModifyAccess(AccessControlModification modification, AccessRule rule, Boolean& modified)
   at System.Security.AccessControl.CommonObjectSecurity.SetAccessRule(AccessRule rule)
   at System.Security.AccessControl.FileSystemSecurity.SetAccessRule(FileSystemAccessRule rule)


Here is the code to delete the file(s):
No matter what I do, I do not seem to be able to accross this point (ignore the wiered name of lockFilename, it is just the file name, and I dont use tmpPathname because the path is part of lockFilename.

C#
public static void RemoveFile(string tmpPathname, string lockFilename)
        {
            try
            {
                FileInfo tmpFilename = new FileInfo(@tmpPathname + lockFilename);

                string User = System.Environment.UserDomainName + "\\" + "IUSR_servernamehere";

                string directory = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
                string filePath = Path.Combine("c:\\log\\");                 FileSecurity fSecurity = File.GetAccessControl(filePath);
                FileSystemAccessRule rule = new FileSystemAccessRule(User, FileSystemRights.FullControl, AccessControlType.Allow);
                fSecurity.SetAccessRule(rule);
                File.SetAccessControl(filePath, fSecurity);

                if (tmpFilename.Exists)
                {
                    File.Delete(@tmpPathname + lockFilename);
                }
            }
            catch (Exception e)
            {
                log.Info("Failed to delete, msg: " + e.Message + " Inner Excep: " + e.InnerException + " Stack trace: " + e.StackTrace);
            }
        }
Posted
Updated 15-Jun-12 16:58pm
v2

It seems to me that the username you are trying to pass is wrong. Trace it, since I am not sure, that Environment is populated in a WCF service as you expect. If I see your intentions correctly, you want the current user. Than you better try WindowsIdentity.GetCurrent().Name.
But why are you trying to change the ACL before you delete the file? If you have the right to do so you will also have the right to delete file. Dump the ACLs of the file you try to delete, and check what effective right this user has. Who is the owner/creator of the file - the same user?
 
Share this answer
 
As the stack traces says you are not able to access that folder, so the basic solution is provide access to the particular folder .

follow these steps ;

1. Right Click on log folder --> properties --> security --> edit -- > add --> now add everyone in the list.
2. if it is a hosted application add IUSER_<machinename> in security tab mentioned above.
3. If above 2 steps doesnt work try to impersonate the current user by some other user.
you can achieve this by refering the below

C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Runtime.InteropServices;
using System.Security.Principal;

namespace WebApplication1
{    
    public class ImpersonationService
    {        
        #region Consts

        public const int LOGON32_LOGON_INTERACTIVE = 2;
        public const int LOGON32_PROVIDER_DEFAULT = 0;

        #endregion

        #region External API 
        [DllImport("advapi32.dll", SetLastError = true)]        
        public static extern int LogonUser(
            string lpszUsername, string lpszDomain,
            string lpszPassword, int dwLogonType,
            int dwLogonProvider, out IntPtr phToken
            );
 
        [DllImport("advapi32.dll", SetLastError = true)]        
        public static extern bool RevertToSelf();

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern int CloseHandle(IntPtr hObject); 

        #endregion

        #region Methods 

        public void PerformImpersonatedTask(string username, string domain,
            string password, int logonType, int logonProvider, Action methodToPerform)
        {
            IntPtr token = IntPtr.Zero;
            if (RevertToSelf())
            {
                if (LogonUser(username, domain, password, logonType,
                    logonProvider, out token) != 0)
                {
                    var identity = new WindowsIdentity(token);
                    var impersonationContext = identity.Impersonate();
                    if (impersonationContext != null)
                    {
                        methodToPerform.Invoke();
                        impersonationContext.Undo();
                    }
                }
                else
                {
                    // do logging
                }
            }
            if (token != IntPtr.Zero)
            {
                CloseHandle(token);
            }
        }
 
        #endregion
    }
}



Use this class as

C#
using System;
using System.IO;

namespace WebApplication1
{
    public partial class _Default : System.Web.UI.Page
    {
        #region Page Events

        private void Page_Load(object sender, System.EventArgs e)
        {
            var service = new ImpersonationService();
            service.PerformImpersonatedTask("username", "domain", "password",
                ImpersonationService.LOGON32_LOGON_INTERACTIVE,
                ImpersonationService.LOGON32_PROVIDER_DEFAULT,
                new Action(MethodToPerform));
        }
 
        #endregion 

        #region Methods 
        public void MethodToPerform()
        {
            var serverPath = @"\\ServerName\test";            
            var dirInfo = new DirectoryInfo(serverPath);
            Response.Write(dirInfo.Exists);
        }

        #endregion
    }
}
 
Share this answer
 
Thank you for the solutions given, I did find out that when running my service, since it is hosted by IIS the app would use the IIS user = IUSR/DefaultAppPool (sorry I am new in IIS), after given that user full control, things started to look better. It looks like my main issue was that I was trying the one file that was opened for fil steam by the test client.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900