Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C# IIS WCF
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.
 
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 15-Jun-12 14:38pm
Edited 15-Jun-12 17:58pm
v2
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

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?
  Permalink  
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

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_ 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
 
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
 
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
    }
}
  Permalink  
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 3

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.
  Permalink  

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

  Print Answers RSS
0 OriginalGriff 195
1 Afzaal Ahmad Zeeshan 132
2 ProgramFOX 130
3 Maciej Los 105
4 Sergey Alexandrovich Kryukov 75
0 OriginalGriff 6,564
1 Sergey Alexandrovich Kryukov 6,048
2 DamithSL 5,228
3 Manas Bhardwaj 4,657
4 Maciej Los 4,150


Advertise | Privacy | Mobile
Web03 | 2.8.1411022.1 | Last Updated 18 Jun 2012
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100