You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4net-dev@logging.apache.org by Nicko Cadell <ni...@neoworks.com> on 2004/09/12 21:12:52 UTC

RE: Allow log4net to impersonate a user via app-specific mechanism.

Doug,

You make some good points here. Appenders need to have a mechanism to
utilise thread level impersonation to obtain access to system resources.
The impersonation must be configurable on an appender by appender basis.

I think that this needs to be a generalised extensibility point for
impersonation that can be used by the following appenders:
AdoNetAppender, EventLogAppender, FileAppender, NetSendAppender,
RollingFileAppender, and SmtpPickupDirAppender.

I don't see that this requires the abstraction of the file system
services into a IFileFactory interface (although there may be other
benefits to doing this).

A simple interface such as:

public interface IExternalCredential
{
	public void Impersonate();
	public void Revert();
}

should do the job. The appenders would need to be updated to call
Impersonate/Revert around calls that have access control constraints.
This should also allow for the appender to make informed decisions about
when to impersonate rather than impersonating for each file system call.
Coarser grained impersonation should not harm performance as much as
fine grained impersonation.

What are your thoughts on this?

Nicko

> 2)  Allow log4net to impersonate a user via app-specific mechanism.
> 
> 	Currently, log4net opens files as the user who logs a message.
> This means on a site with
> 	lots of users, in order to ensure fail-safe logging, all users
must 
> have full permissions
> 	to the folder where logging occurs.  This is problematic, since 
> customers are reluctant
> 	to open up folders will full access, and when they are willing,
it is 
> still tough to keep
> 	permissions on the folder in-sync with all the site users.  If
even 
> one user doesn't have
> 	full permissions, logging can fail (and stop
> thereafter) for all users.
> 
> 	Impact would be to the RollingFileAppender and the FileAppender 
> classes.
> 
> 	How?  
> 
> 	Introduce a FileFactory mechanism, and specify the type via the
XML 
> config file.
> 	Most users would see no difference, but this would give us a
point of 
> flexibility
> 	to control how file I/O is done.
> 
> 	Default factory does what log4net currently does (all file I/O
done 
> as current user)
> 	When there is no XML override, then it falls back to using the 
> current approach of file I/O,
> 	using a 'default' factory (which would do raw file I/O).
> 
> 	Our application could could override via config XML
> 
> 		<log4net>
> 			<fileFactory
> type="Customer.Specified.MyFileFactory,mydll" />
> 		</log4net>
> 
> 	Our application's file factory could implement IFileFactory
> 
> 		public interface IFileFactory
> 		{
> 			void CreateDirectory( string directoryToFile );
> 
> 			StreamWriter OpenFile( string fileName, bool
append, string 
> encoding );
> 
> 			IFileInfo NewFileInfo( string fileName );
> 		}
> 
> 	Then, when the IFileFactory methods are called, we could do 
> impersonation around the file
> 	I/O, allowing the logfile to be created using a single account.
> By ensuring that one account
> 	has full permissions on the log folder, it is easier to ensure 
> logging will always succeed
> 	for all users.
> 
> 	Note that the messages themselves would still be logged as the 
> windows identity of the user that
> 	was running when the message was logged.  Only the file creation
(or 
> deletion) would go through a
> 	factory, allowing those operations to be done differently if
needed.
> 	
> 	Need to impersonate for the FileInfo.Delete, FileInfo.MoveTo
checks, 
> as well as the OpenFile call,
> 	and FileInfo.Directory.GetFiles
> 
> 	Since FileInfo is sealed, need to create wrapper interfaces for 
> common file actions:
> 
> 		public interface IFileInfo
> 		{
> 			bool Exists { get; }
> 
> 			long Length { get; }
> 
> 			string DirectoryName { get; }
> 
> 			IDirectoryInfo Directory { get; }
> 
> 			DateTime LastWriteTime { get; }
> 
> 			void Delete();
> 
> 			void MoveTo( string destinationFile );
> 		}
> 
> 		public interface IDirectoryInfo
> 		{
> 			bool Exists { get; }
> 
> 			IFileInfo[] GetFiles( string wildcardPattern );
> 		}