/// <summary>
        /// Initializes a new instance of the <Typ>LearningStore</Typ> class.
        /// </summary>
        /// <param name="connectionString">The connection used to access the SQL server
        ///     database. The string is the same format as a connection string passed to
        ///     <Typ>/System.Data.SqlClient.SqlConnection</Typ></param>
        /// <param name="userKey">The unique key of the user accessing the database.</param>
        /// <param name="impersonationBehavior">Identifies which <c>WindowsIdentity</c> is used to
        ///     access the database when impersonation is involved.</param>
        /// <param name="disableSecurityChecks">True if security checks should be skipped when performing operations
        ///     in the database.</param>
        /// <exception cref="ArgumentNullException"><paramref name="connectionString"/> or <paramref name="userKey"/>
        ///     is a null reference.</exception>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="impersonationBehavior"/>
        ///     has an invalid value</exception>
        /// <example>The following code opens the store located in the "Mls"
        /// database of the "Learning" server with the user key "Bob".  The original (non-impersonated)
        /// identity is used when accessing the database:
        /// <code language="C#">
        /// WindowsIdentity applicationIdentity = ...
        /// LearningStore store = new LearningStore("Server=Learning;Database=Mls;Integrated Security=true", "Bob", ImpersonationBehavior.UseOriginalIdentity, false);
        /// </code>
        /// </example>
        public LearningStore(string connectionString, string userKey, ImpersonationBehavior impersonationBehavior, bool disableSecurityChecks)
        {
            // Check the input parameters
            if (connectionString == null)
            {
                throw new ArgumentNullException("connectionString");
            }
            if (userKey == null)
            {
                throw new ArgumentNullException("userKey");
            }
            if ((impersonationBehavior != ImpersonationBehavior.UseImpersonatedIdentity) &&
                (impersonationBehavior != ImpersonationBehavior.UseOriginalIdentity))
            {
                throw new ArgumentOutOfRangeException("impersonationBehavior");
            }

            // Save the passed-in values
            m_connectionString      = connectionString;
            m_userKey               = userKey;
            m_impersonationBehavior = impersonationBehavior;
            m_disableSecurityChecks = disableSecurityChecks;

            // Default locale is the current thread locale
            m_locale = CultureInfo.CurrentCulture;
        }
Beispiel #2
0
 /// <summary>
 /// This method throws an exception of the user does not have the right
 /// to switch to the identity.  This must be Disposed of
 /// when we are finished with it. If the identity is null, this method has no effect.
 /// </summary>
 public ImpersonateIdentity(ImpersonationBehavior impersonationBehavior)
 {
     if (impersonationBehavior == ImpersonationBehavior.UseOriginalIdentity)
     {
         m_context = WindowsIdentity.Impersonate(IntPtr.Zero);
     }
 }
Beispiel #3
0
        /// <summary>
        /// Constructor that creates a FileSystemPackageStore.
        /// </summary>
        /// <param name="learningStore">The <c>LearningStore</c> where packages in this store
        /// are kept.</param>
        /// <param name="basePath">The base path to which files should be 'stored'. That is, the
        /// Microsoft Learning Components
        /// core schema defines a base path for all packages. When packages are imported
        /// into LearningStore, they are copied to a subdirectory of this basePath directory.Every
        /// package is given a unique directory for its files when the package is added to the system.
        /// The application should not modify files in this directory. The directory must exist
        /// before calling this constructor.
        /// </param>
        /// <param name="impersonationBehavior">A user that has read/write access to the <P>basePath</P>
        /// location. In some cases, the identity must also have permission to remove files from the <P>basePath</P>.
        /// The constructor does not verify all the permissions are available. If the identity does not have the
        /// appropriate permissions, an exception may be thrown from other methods as those permissions are required.
        /// </param>
        /// <exception cref="ArgumentNullException">Thrown if any of the arguments is null.</exception>
        /// <exception cref="DirectoryNotFoundException">Thrown if <P>basePath</P> is not an absolute path
        /// to an existing directory.</exception>
        /// <exception cref="UnauthorizedAccessException">Thrown if <P>impersonationBehavior</P> does not have FileSystemRights.Read to the
        /// <P>basePath</P> directory.</exception>
        public FileSystemPackageStore(LearningStore learningStore, string basePath, ImpersonationBehavior impersonationBehavior)
            : base(learningStore)
        {
            Utilities.ValidateParameterNonNull("basePath", basePath);
            Utilities.ValidateParameterNonNull("learningStore", learningStore);

            basePath = basePath.Trim();
            Utilities.ValidateParameterNotEmpty("basePath", basePath);

            // The outer try/catch block is there for security reasons. Search MSDN for
            // "WrapVulnerableFinallyClausesInOuterTry" to see details.
            try
            {
                using (ImpersonateIdentity id = new ImpersonateIdentity(impersonationBehavior))
                {
                    if (!Directory.Exists(basePath))
                    {
                        throw new DirectoryNotFoundException(String.Format(CultureInfo.CurrentCulture, PackageResources.FSPS_BasePathDirNotFound, basePath));
                    }

                    // Test that the identity has read access to the directory. This will throw security exception if it
                    // does not.
                    Directory.GetFiles(basePath);
                }
            }
            catch
            {
                throw;
            }

            m_basePath = basePath;
            m_impersonationBehavior = impersonationBehavior;
        }
Beispiel #4
0
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope")]    // the writer is disposed for all code paths
        internal static void CopyStream(Stream fromStream, ImpersonationBehavior readImpersonationBehavior, Stream toStream, ImpersonationBehavior writeImpersonationBehavior)
        {
            // An addition revert during write operations is required if the setting for reading and writing
            // is not the same
            bool requiresWriteRevert = (readImpersonationBehavior != writeImpersonationBehavior);

            using (ImpersonateIdentity readId = new ImpersonateIdentity(readImpersonationBehavior))
            {
                byte[] bytesIn = new byte[65536];
                int    bytesRead;
                while ((bytesRead = fromStream.Read(bytesIn, 0, bytesIn.Length)) != 0)
                {
                    // If we have to impersonate to write, then do it. Otherwise skip it.
                    if (requiresWriteRevert)
                    {
                        using (ImpersonateIdentity id = new ImpersonateIdentity(writeImpersonationBehavior))
                        {
                            toStream.Write(bytesIn, 0, bytesRead);
                        }
                    }
                    else
                    {
                        toStream.Write(bytesIn, 0, bytesRead);
                    }
                }
            }
        }
        /// <summary>
        /// Create settings for a class that manages a cache of SharePoint files.
        /// </summary>
        /// <param name="cachePath">The path to the folder containing the cached files.</param>
        /// <param name="expirationTime">The maximum amount of time that packages are stored in the cache. After this time has passed,
        /// the package will be removed from the cache if it has not been accessed. If not provided, files will never be removed from the
        /// cache.</param>
        /// <param name="impersonationBehavior">The identity used to access the cache. </param>
        /// <param name="cacheInvalidPackageAsFile">If true, a package that is invalid will be cached as a file. While it
        /// cannot be read as a package in this case, setting this to true may improve performance.</param>
        /// <remarks>
        /// This class does not verify that the <paramref name="cachePath"/>
        /// directory exists, however, when the settings are passed to SharePointPackageReader or SharePointPackageStore, those
        /// classes will require the directory to exist.</remarks>
        public SharePointCacheSettings(string cachePath, TimeSpan?expirationTime, ImpersonationBehavior impersonationBehavior, bool cacheInvalidPackageAsFile)
        {
            Utilities.ValidateParameterNotEmpty("cachePath", cachePath);

            m_cachePath                 = cachePath;
            m_expirationTime            = expirationTime;
            m_impersonationBehavior     = impersonationBehavior;
            m_cacheInvalidPackageAsFile = cacheInvalidPackageAsFile;
        }
        /// <summary>
        /// Gets the directory that the package (specified by packageLocation)
        /// would be cached into.
        /// </summary>
        /// <param name="cachePath">The folder to use for a cache of all SharePoint files.</param>
        /// <param name="impersonationBehavior">The impersonation behaviour to use.</param>
        /// <param name="packageLocation">The package loacation in LearningStore format.</param>
        /// <returns>The directory path to the cached package.</returns>
        internal static string GetCacheDirectory(string cachePath, ImpersonationBehavior impersonationBehavior, string packageLocation)
        {
            SharePointFileLocation location;

            if (!SharePointFileLocation.TryParse(packageLocation, out location))
            {
                throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, Resources.SPFormatInvalid, packageLocation));
            }

            return(SharePointPackageReader.GetCacheDirectory(cachePath, impersonationBehavior, location));
        }
        FileSystemPackageReader m_fsPackageReader;  // the PackageReader to read resource files

        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="packageBasePath">The absolute path to the location where the packages
        /// are located in the filesystem.</param>
        /// <param name="packageStore">The PackageStore that contains information about the package.</param>
        /// <param name="packageId">The package id of the package to load.</param>
        /// <param name="packageLocation">The location of the package, as defined in
        /// LearningStore PackageItem.Location column. This cannot be null.</param>
        /// <param name="impersonationBehavior">The user who has access to the file system related to the store.</param>
        /// <remarks></remarks>
        internal FileSystemPackageStoreReader(string packageBasePath, FileSystemPackageStore packageStore,
                                              PackageItemIdentifier packageId, string packageLocation, ImpersonationBehavior impersonationBehavior)
        {
            m_store                 = packageStore;
            m_packageId             = packageId;
            m_impersonationBehavior = impersonationBehavior;

            m_packageBasePath = PackageReader.SafePathCombine(packageBasePath, packageLocation);

            // This does not verify that m_packageBasePath actually exists
            m_fsPackageReader = new FileSystemPackageReader(m_packageBasePath, m_impersonationBehavior);
        }
Beispiel #8
0
 /// <summary>
 /// Shared helper function to read a file from the package location and wrap the resulting exceptions
 /// to be consistent within MLC.
 /// </summary>
 /// <param name="packagePath">The path to the root folder of the package.</param>
 /// <param name="filePath">The package-relative path of the file within the package.</param>
 /// <param name="impersonationBehavior">Indicates which identity to use when reading the file.</param>
 /// <returns>A stream containing the file.</returns>
 internal static Stream ReadFile(string packagePath, string filePath, ImpersonationBehavior impersonationBehavior)
 {
     Stream stream = null;
     try
     {
         using (ImpersonateIdentity id = new ImpersonateIdentity(impersonationBehavior))
         {
             stream = File.OpenRead(SafePathCombine(packagePath, filePath));
         }
     }
     catch (UnauthorizedAccessException)
     {
         // don't wrap the inner exception to obfuscate any system file info that might exist
         throw new UnauthorizedAccessException(String.Format(CultureInfo.InvariantCulture, Resources.UnauthorizedAccess, filePath));
     }
     catch (FileNotFoundException)
     {
         // don't wrap the inner exception to obfuscate any system file info that might exist
         throw new FileNotFoundException(Resources.PackageFileNotFound, filePath);
     }
     catch (DirectoryNotFoundException)
     {
         // don't wrap the inner exception to obfuscate any system file info that might exist
         throw new DirectoryNotFoundException(String.Format(CultureInfo.InvariantCulture, Resources.DirectoryNotFound, filePath));
     }
     return stream;
 }
Beispiel #9
0
        /// <summary>
        /// Initializes a new instance of the <c>FileSystemPackageReader</c> class with the
        /// package that is stored in the specified file system path. Uses the specified identity 
        /// to access files in the package.
        /// </summary>
        /// 
        /// <param name="packageBasePath">The path to the directory that is the base of the package, and
        /// contains the manifest for the package.</param>
        /// <param name="impersonationBehavior">The identity which has read access to the files in the located in 
        /// <paramref name="packageBasePath"/>. </param>
        /// 
        /// <exception cref="ArgumentException"><paramref name="packageBasePath"/> contains invalid characters
        /// such as ", &lt;, &gt;, or |.</exception>
        /// <exception cref="SecurityException">The caller does not have the required permission.</exception>
        /// <exception cref="PathTooLongException">The specified path exceeds the 
        /// system-defined maximum length. For example, on Windows-based platforms, paths must be less 
        /// than 248 characters, and file names must be less than 260 characters. The specified path
        /// is too long.</exception>
        /// <exception cref="ArgumentNullException"><paramref name="packageBasePath"/> is a null
        /// reference.</exception>
        /// 
        /// <remarks>
        /// The package should be exploded (not in zip format) on the file system.  Zipped packages can be
        /// read with the <Typ>ZipPackageReader</Typ>.  Learning Resource packages can be read with the
        /// <Typ>LrmPackageReader</Typ>.
        /// <para>
        /// This constructor does not check if a directory exists. This constructor is a placeholder 
        /// for a string that is used to access the disk in subsequent operations.
        /// </para>
        /// <para>
        /// The <paramref name="packageBasePath"/> parameter can be a directory on a network file share accessible
        /// via a mapped drive letter or UNC path.
        /// </para>
        /// </remarks>
        /// 
        public FileSystemPackageReader(string packageBasePath, ImpersonationBehavior impersonationBehavior)
        {
            // Modeling this after the DirectoryInfo constructor.  The DirectoryInfo constructor throws
            // the exceptions noted above.  The overhead of creating and destroying the DirectoryInfo
            // structure is made up for by the robustness of using an established .NET object for
            // checking for these exceptions.
            m_packageBasePath = new DirectoryInfo(packageBasePath).FullName;

            m_impersonationBehavior = impersonationBehavior;
        }
Beispiel #10
0
        /// <summary>
        /// Recursively copy from one folder to another by reading the files into memory. 
        /// </summary>
        /// <param name="fromDir">The folder to copy from.</param>
        /// <param name="fromImpersonationBehavior">The identity that has rights to read the <paramref name="fromDir"/>.</param>
        /// <param name="toDir">The folder to write to. Writing is not done in an impersonation block.</param>
        private static void RecursiveCopyStreams(DirectoryInfo fromDir, ImpersonationBehavior fromImpersonationBehavior, DirectoryInfo toDir)
        {
            FileInfo[] files;

            using (ImpersonateIdentity id = new ImpersonateIdentity(fromImpersonationBehavior))
            {
                files = fromDir.GetFiles();
            }
            foreach (FileInfo file in files)
            {
                using(Disposer disposer = new Disposer())
                {
                    FileStream fromStream;
                    using (ImpersonateIdentity id = new ImpersonateIdentity(fromImpersonationBehavior))
                    {
                         fromStream = file.OpenRead();
                         disposer.Push(fromStream);
                    }
                    string toPath = PackageReader.SafePathCombine(toDir.FullName, file.Name);
                    FileInfo toFileInfo = new FileInfo(toPath);
                    FileStream toStream = toFileInfo.OpenWrite();
                    disposer.Push(toStream);

                    Utilities.CopyStream(fromStream, fromImpersonationBehavior, toStream, ImpersonationBehavior.UseImpersonatedIdentity);
                }
            }
            foreach (DirectoryInfo sub in fromDir.GetDirectories())
            {
                DirectoryInfo newSub = Directory.CreateDirectory(Path.Combine(toDir.FullName, sub.Name));
                RecursiveCopy(sub, newSub);
            }
        }
Beispiel #11
0
        /// <summary>
        /// Recursively copy all package files from one directory to another.
        /// </summary>
        /// <param name="from">Directory to copy from.</param>
        /// <param name="to">Directory to copy to.</param>
        /// <param name="impersonationBehavior">The identity that can read the files in the <paramref name="from"/> folder.
        /// If this identity can also write to the <paramref name="to"/> folder, the method performs faster
        /// than if it does not have write permissions.</param>
        internal static void RecursiveCopy(DirectoryInfo from, DirectoryInfo to, ImpersonationBehavior impersonationBehavior)
        {
            bool copySucceeded = false;
            try
            {
                using (ImpersonateIdentity id = new ImpersonateIdentity(impersonationBehavior))
                {
                    try
                    {
                        to.Create();
                    }
                    catch (IOException ex)
                    {
                        throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture,
                            Resources.PackageDirectoryAlreadyExists, to.FullName), ex);
                    }

                    RecursiveCopy(from, to);
                    copySucceeded = true;
                }
            }
            catch (UnauthorizedAccessException)
            {
                // This means the identity probably did not have write privileges to the 'to' folder.
                // So, try continue and try loading files into memory before writing them to the output folder.
            }

            if (!copySucceeded)
            {
                // Load files into memory before writing them to the output
                RecursiveCopyStreams(from, impersonationBehavior, to);
            }
        }
Beispiel #12
0
        /// <summary>
        /// Initializes a new instance of the <c>ZipPackageReader</c> class with the specified zipped package. Uses the 
        /// specified user's credentials to access package files.
        /// </summary>
        /// 
        /// <param name="filePath">The path to the zipped file containing the package, e.g. "C:\Foo\Bar.zip".</param>
        /// <param name="impersonationBehavior">The identity to use when accessing package files. </param>
        /// 
        /// <remarks>
        /// <para>
        /// This constructor does not check if the file exists. This constructor is a placeholder 
        /// for a string that is used to access the file in subsequent operations.
        /// </para>
        /// <para>
        /// The <paramref name="filePath"/> parameter can be a directory on a network file share accessible
        /// via a mapped drive letter or UNC path.
        /// </para>
        /// </remarks>
        /// <exception cref="ArgumentNullException"><paramref name="filePath"/> is a null reference.</exception>
        /// <exception cref="SecurityException">The caller does not have the required permission.</exception>
        /// <exception cref="ArgumentException">The file name is empty, contains only white spaces, or contains invalid characters.</exception>
        /// <exception cref="PathTooLongException">The specified path, file name, or both exceed the system-defined maximum length. For example, on Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260 characters.</exception>
        /// <exception cref="NotSupportedException"><paramref name="filePath"/> contains a colon (:) in the middle of the string.</exception>
        public ZipPackageReader(string filePath, ImpersonationBehavior impersonationBehavior)
        {
            Utilities.ValidateParameterNonNull("filePath", filePath);
            Utilities.ValidateParameterNotEmpty("filePath", filePath);

            m_zip = new FileInfo(filePath);
            m_impersonationBehavior = impersonationBehavior;
        }
Beispiel #13
0
 /// <summary>
 /// Gets the directory that the package (specified by site, web, file, etc)
 /// would be cached into.
 /// </summary>
 /// <param name="cachePath">The folder to use for a cache of all SharePoint files.</param>
 /// <param name="impersonationBehavior">The impersonation behaviour to use.</param>
 /// <param name="packageLocation">The location of the package in SharePoint.</param>
 /// <returns>The directory path to the cached package.</returns>
 internal static string GetCacheDirectory(string cachePath, ImpersonationBehavior impersonationBehavior, SharePointFileLocation packageLocation)
 {
     return(CachedPackage.GetCacheDirectory(cachePath, packageLocation, impersonationBehavior));
 }
 /// <summary>
 /// Initializes a new instance of the <Typ>LearningStore</Typ> class.
 /// </summary>
 /// <param name="connectionString">The connection used to access the SQL server
 ///     database. The string is the same format as a connection string passed to
 ///     <Typ>/System.Data.SqlClient.SqlConnection</Typ></param>
 /// <param name="userKey">The unique key of the user accessing the database.</param>
 /// <param name="impersonationBehavior">Identifies which <c>WindowsIdentity</c> is used to
 ///     access the database when impersonation is involved.</param>
 /// <exception cref="ArgumentNullException"><paramref name="connectionString"/> or <paramref name="userKey"/>
 ///     is a null reference.</exception>
 /// <exception cref="ArgumentOutOfRangeException"><paramref name="impersonationBehavior"/>
 ///     has an invalid value</exception>
 /// <example>The following code opens the store located in the "Mls"
 /// database of the "Learning" server with the user key "Bob".  The original (non-impersonated)
 /// identity is used when accessing the database:
 /// <code language="C#">
 /// LearningStore store = new LearningStore("Server=Learning;Database=Mls;Integrated Security=true", "Bob", ImpersonationBehavior.UseOriginalIdentity);
 /// </code>
 /// </example>
 public LearningStore(string connectionString, string userKey, ImpersonationBehavior impersonationBehavior) :
     this(connectionString, userKey, impersonationBehavior, false)
 {
 }
 /// <summary>Initializes the reader with the cache directory.</summary>
 protected void Initialize(DirectoryInfo cacheDirectory, ImpersonationBehavior impersonationBehavior)
 {
     CacheDirectory             = cacheDirectory;
     this.impersonationBehavior = impersonationBehavior;
 }
        /// <summary>
        /// Get the schema information for this store from the cache or from the database.
        /// </summary>
        /// <param name="connectionString">Connection string used to access the store.</param>
        /// <param name="impersonationBehavior">Identifies which <c>WindowsIdentity</c> is used to
        ///     access the database when impersonation is involved.</param>
        /// <param name="debugLog">Location to which the debug log should be written, or
        ///     null if there isn't a debug log.</param>
        /// <returns>The schema information.</returns>
        private static LearningStoreSchema GetSchemaInformationFromCache(string connectionString,
                                                                         ImpersonationBehavior impersonationBehavior, TextWriter debugLog)
        {
            // Try to find the connection in the cache
            lock (s_allSchemasLock)
            {
                LearningStoreSchema schema;
                if (s_allSchemas.TryGetValue(connectionString, out schema))
                {
                    return(schema);
                }
            }

            // Not found in the cache -- so go get it from the database

            // This try/catch block is here for security reasons. Search MSDN for
            // "WrapVulnerableFinallyClausesInOuterTry" to see details.
            try
            {
                WindowsImpersonationContext impersonationContext = null;

                try
                {
                    // Impersonate if necessary
                    if (impersonationBehavior == ImpersonationBehavior.UseOriginalIdentity)
                    {
                        // Not adding it to the disposer, since that could fail (e.g., OutOfMemoryException),
                        // which could cause a security hole.  Instead, we'll clean it up manually later.
                        impersonationContext = WindowsIdentity.Impersonate(IntPtr.Zero);
                    }

                    using (Microsoft.LearningComponents.Disposer disposer = new Microsoft.LearningComponents.Disposer())
                    {
                        // Create a connection
                        SqlConnection connection = new SqlConnection(connectionString);
                        disposer.Push(connection);
                        connection.Open();

                        // Create a command to retrieve information from the configuration table
                        LogableSqlCommand command = new LogableSqlCommand(connection, debugLog);
                        disposer.Push(command);

                        // Execute
                        command.Execute(
                            "SELECT EngineVersion,\r\n" +
                            "    SchemaDefinition\r\n" +
                            "FROM Configuration\r\n");

                        // Read return values from the database
                        if (!command.Read())
                        {
                            throw new LearningComponentsInternalException("LSTR1500");
                        }
                        if (command.GetFieldCount() != 2)
                        {
                            throw new LearningComponentsInternalException("LSTR1510");
                        }
                        int           engineVersion = command.GetInt32(0);
                        SqlXml        schemaXml     = command.GetSqlXml(1);
                        XPathDocument schemaDoc;
                        using (XmlReader reader = schemaXml.CreateReader())
                        {
                            schemaDoc = new XPathDocument(reader);
                        }
                        LearningStoreSchema newSchema = LearningStoreSchema.CreateSchema(schemaDoc);
                        if (command.Read())
                        {
                            throw new LearningComponentsInternalException("LSTR1520");
                        }
                        if (command.NextResult())
                        {
                            throw new LearningComponentsInternalException("LSTR1530");
                        }

                        // Fail if a different engine created this
                        if (engineVersion != LearningStore.EngineVersion)
                        {
                            throw new InvalidOperationException(LearningStoreStrings.IncompatibleEngineVersion);
                        }

                        // Save it in the cache
                        lock (s_allSchemasLock)
                        {
                            LearningStoreSchema schema;
                            if (s_allSchemas.TryGetValue(connectionString, out schema))
                            {
                                return(schema);
                            }
                            s_allSchemas.Add(connectionString, newSchema);
                        }

                        return(newSchema);
                    }
                }
                finally
                {
                    if (impersonationContext != null)
                    {
                        impersonationContext.Dispose();
                    }
                }
            }
            catch
            {
                throw;
            }
        }
Beispiel #17
0
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope")]    // the writer is disposed for all code paths
        internal static void CopyStream(Stream fromStream, ImpersonationBehavior readImpersonationBehavior, Stream toStream, ImpersonationBehavior writeImpersonationBehavior)
        {
            using (Disposer disposer = new Disposer())
            {
                DetachableStream dsToStream = new DetachableStream(toStream);
                disposer.Push(dsToStream);

                BinaryWriter writer = new BinaryWriter(dsToStream);
                disposer.Push(writer);

                // An addition revert during write operations is required if the setting for reading and writing
                // is not the same
                bool requiresWriteRevert = (readImpersonationBehavior != writeImpersonationBehavior);

                using (ImpersonateIdentity readId = new ImpersonateIdentity(readImpersonationBehavior))
                {
                    byte[] bytesIn = new byte[65536];
                    int bytesRead;
                    while ((bytesRead = fromStream.Read(bytesIn, 0, bytesIn.Length)) != 0)
                    {
                        // If we have to impersonate to write, then do it. Otherwise skip it.
                        if (requiresWriteRevert)
                        {
                            using (ImpersonateIdentity id = new ImpersonateIdentity(writeImpersonationBehavior))
                            {
                                writer.Write(bytesIn, 0, bytesRead);
                            }
                        }
                        else
                        {
                            writer.Write(bytesIn, 0, bytesRead);
                        }
                    }
                }
                dsToStream.Detach();
            }
        }
Beispiel #18
0
 /// <summary>
 /// This method throws an exception of the user does not have the right
 /// to switch to the identity.  This must be Disposed of
 /// when we are finished with it. If the identity is null, this method has no effect.
 /// </summary>
 public ImpersonateIdentity(ImpersonationBehavior impersonationBehavior)
 {
     if (impersonationBehavior == ImpersonationBehavior.UseOriginalIdentity)
         m_context = WindowsIdentity.Impersonate(IntPtr.Zero);
 }