nicko       2004/11/25 15:02:50

  Modified:    src/Appender SmtpPickupDirAppender.cs
  Log:
  Added SecurityContext used to impersonate around file access
  
  Revision  Changes    Path
  1.5       +97 -24    logging-log4net/src/Appender/SmtpPickupDirAppender.cs
  
  Index: SmtpPickupDirAppender.cs
  ===================================================================
  RCS file: /home/cvs/logging-log4net/src/Appender/SmtpPickupDirAppender.cs,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- SmtpPickupDirAppender.cs  22 Nov 2004 02:09:07 -0000      1.4
  +++ SmtpPickupDirAppender.cs  25 Nov 2004 23:02:50 -0000      1.5
  @@ -132,7 +132,27 @@
                public string PickupDir
                {
                        get { return m_pickupDir; }
  -                     set { m_pickupDir = ConvertToFullPath(value.Trim()); }
  +                     set { m_pickupDir = value; }
  +             }
  +
  +             /// <summary>
  +             /// Gets or sets the <see cref="SecurityContext"/> used to 
write to the pickup directory.
  +             /// </summary>
  +             /// <value>
  +             /// The <see cref="SecurityContext"/> used to write to the 
pickup directory.
  +             /// </value>
  +             /// <remarks>
  +             /// <para>
  +             /// Unless a <see cref="SecurityContext"/> specified here for 
this appender
  +             /// the <see cref="SecurityContextProvider.DefaultProvider"/> 
is queried for the
  +             /// security context to use. The default behavior is to use the 
security context
  +             /// of the current thread.
  +             /// </para>
  +             /// </remarks>
  +             public SecurityContext SecurityContext 
  +             {
  +                     get { return m_securityContext; }
  +                     set { m_securityContext = value; }
                }
   
                #endregion Public Instance Properties
  @@ -153,34 +173,51 @@
                        // Note: this code already owns the monitor for this
                        // appender. This frees us from needing to synchronize 
again.
                        try 
  -                     {         
  -                             using(StreamWriter writer = 
File.CreateText(Path.Combine(m_pickupDir, SystemInfo.NewGuid().ToString("N"))))
  -                             {
  -                                     writer.WriteLine("To: " + m_to);
  -                                     writer.WriteLine("From: " + m_from);
  -                                     writer.WriteLine("Subject: " + 
m_subject);
  -                                     writer.WriteLine("");
  +                     {
  +                             string filePath = null;
  +                             StreamWriter writer = null;
   
  -                                     string t = Layout.Header;
  -                                     if (t != null)
  -                                     {
  -                                             writer.Write(t);
  -                                     }
  +                             // Impersonate to open the file
  +                             using(SecurityContext.Impersonate(this))
  +                             {
  +                                     filePath = Path.Combine(m_pickupDir, 
SystemInfo.NewGuid().ToString("N"));
  +                                     writer = File.CreateText(filePath);
  +                             }
   
  -                                     for(int i = 0; i < events.Length; i++) 
  +                             if (writer == null)
  +                             {
  +                                     ErrorHandler.Error("Failed to create 
output file for writing ["+filePath+"]", null, ErrorCode.FileOpenFailure);
  +                             }
  +                             else
  +                             {
  +                                     using(writer)
                                        {
  -                                             // Render the event and append 
the text to the buffer
  -                                             RenderLoggingEvent(writer, 
events[i]);
  -                                     }
  +                                             writer.WriteLine("To: " + m_to);
  +                                             writer.WriteLine("From: " + 
m_from);
  +                                             writer.WriteLine("Subject: " + 
m_subject);
  +                                             writer.WriteLine("");
  +
  +                                             string t = Layout.Header;
  +                                             if (t != null)
  +                                             {
  +                                                     writer.Write(t);
  +                                             }
  +
  +                                             for(int i = 0; i < 
events.Length; i++) 
  +                                             {
  +                                                     // Render the event and 
append the text to the buffer
  +                                                     
RenderLoggingEvent(writer, events[i]);
  +                                             }
  +
  +                                             t = Layout.Footer;
  +                                             if (t != null)
  +                                             {
  +                                                     writer.Write(t);
  +                                             }
   
  -                                     t = Layout.Footer;
  -                                     if (t != null)
  -                                     {
  -                                             writer.Write(t);
  +                                             writer.WriteLine("");
  +                                             writer.WriteLine(".");
                                        }
  -
  -                                     writer.WriteLine("");
  -                                     writer.WriteLine(".");
                                }
                        } 
                        catch(Exception e) 
  @@ -194,6 +231,37 @@
                #region Override implementation of AppenderSkeleton
   
                /// <summary>
  +             /// Activate the options on this appender. 
  +             /// </summary>
  +             /// <remarks>
  +             /// <para>
  +             /// This is part of the <see cref="IOptionHandler"/> delayed 
object
  +             /// activation scheme. The <see cref="ActivateOptions"/> method 
must 
  +             /// be called on this object after the configuration properties 
have
  +             /// been set. Until <see cref="ActivateOptions"/> is called this
  +             /// object is in an undefined state and must not be used. 
  +             /// </para>
  +             /// <para>
  +             /// If any of the configuration properties are modified then 
  +             /// <see cref="ActivateOptions"/> must be called again.
  +             /// </para>
  +             /// </remarks>
  +             override public void ActivateOptions() 
  +             {       
  +                     base.ActivateOptions();
  +
  +                     if (m_securityContext == null)
  +                     {
  +                             m_securityContext = 
SecurityContextProvider.DefaultProvider.CreateSecurityContext(this);
  +                     }
  +
  +                     using(SecurityContext.Impersonate(this))
  +                     {
  +                             m_pickupDir = 
ConvertToFullPath(m_pickupDir.Trim());
  +                     }
  +             }
  +
  +             /// <summary>
                /// This appender requires a <see cref="Layout"/> to be set.
                /// </summary>
                /// <value><c>true</c></value>
  @@ -247,6 +315,11 @@
                private string m_from;
                private string m_subject;
                private string m_pickupDir;
  +
  +             /// <summary>
  +             /// The security context to use for privileged calls
  +             /// </summary>
  +             private SecurityContext m_securityContext;
   
                #endregion Private Instance Fields
        }
  
  
  

Reply via email to