Anonymous access in SQL RS 2008

So what happened to the good old anonymous authentication is RS 2005? The short answer is that it is no longer supported. There were good technical reasons: anonymous accounts (the IUSER_* and IWAM_* accounts) are managed by windows security system. We decided not to trot into that space, nor did we want to add a new configuration setting for anonymous accounts, and having to manage the username and password of the anonymous user account. This may seem like a flop, but think about it from another angle: why would you want everyone on the internet to be able to view/update/overwrite your stuff on the report server?

With so little said about best practices, I shouldn't really be telling people how to enable anonymous authentication. So here is the disclaimer again:

DO NOT USE ANONYMOUS AUTH!

NEVER USE IT IN PRODUCTION ENVIRONMENT!

But if you are still undeterred, thinking you have a super secure environment and your servers are never exposed to malicious users, here is the solution for the reckless :). This is an adaptation of the RS Forms auth sample, so the easiest thing to do is to replace code in the sample with the code at the bottom of this blog post.

·         Change authentication mode in rereportserver.config to “Custom”:

                <Authentication>

                                <AuthenticationTypes>

                                                <Custom/>

                                </AuthenticationTypes>

                                <EnableAuthPersistence>true</EnableAuthPersistence>

                </Authentication>

·         Change auth mode in report server and report manager web.config file to “None”. Set impersonation property to “false”:

    <authentication mode="None" />

    <identity impersonate="false"/>

·         Compile the code below into Microsoft.Samples.ReportingServices.AnonymousSecurity.dll .

·         Drop Microsoft.Samples.ReportingServices.AnonymousSecurity.dll into report server bin folder (e.g. D:\Program Files\Microsoft SQL Server\MSRS10.MSSQLSERVER\Reporting Services\ReportServer\bin)

·         Add the extension to rereportserver.config file:

                                <Security>

                                                <Extension Name="None" Type="Microsoft.Samples.ReportingServices.AnonymousSecurity.Authorization, Microsoft.Samples.ReportingServices.AnonymousSecurity" />

                                </Security>

                                <Authentication>

                                                <Extension Name="None" Type="Microsoft.Samples.ReportingServices.AnonymousSecurity.AuthenticationExtension, Microsoft.Samples.ReportingServices.AnonymousSecurity" />

                                </Authentication>

·         Configure code access security. Add the following into rssrvpolicy.config. Since my project had no strong name, I used url membership:

                            <CodeGroup

                                    class="UnionCodeGroup"

                                    version="1"

                                    PermissionSetName="FullTrust"

                                    Name="Private_assembly"

                                    Description="This code group grants custom code full trust. ">

                                <IMembershipCondition

                                        class="UrlMembershipCondition"

                                        version="1"

                                        Url="D:\Program Files\Microsoft SQL Server\MSRS10.MSSQLSERVER\Reporting Services\ReportServer\bin\Microsoft.Samples.ReportingServices.AnonymousSecurity.dll"

                                />

                            </CodeGroup>

·         Restart report server and now you have anonymous authentication.

Code:

namespace Microsoft.Samples.ReportingServices.AnonymousSecurity

{

    public class AuthenticationExtension : IAuthenticationExtension

    {

        /// <summary>

        /// You must implement SetConfiguration as required by IExtension

        /// </summary>

      /// <param name="configuration">Configuration data as an XML

        /// string that is stored along with the Extension element in

        /// the configuration file.</param>

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]

        public void SetConfiguration(String configuration)

        {

            // No configuration data is needed for this extension

        }

        /// <summary>

        /// You must implement LocalizedName as required by IExtension

        /// </summary>

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]

        public string LocalizedName

    {

            get

            {

                return null;

            }

        }

        /// <summary>

        /// Indicates whether a supplied username and password are valid.

        /// </summary>

        /// <param name="userName">The supplied username</param>

        /// <param name="password">The supplied password</param>

        /// <param name="authority">Optional. The specific authority to use to

        /// authenticate a user. For example, in Windows it would be a Windows

        /// Domain</param>

        /// <returns>true when the username and password are valid</returns>

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]

        public bool LogonUser(string userName, string password, string authority)

        {

            return true;

        }

        /// <summary>

        /// Required by IAuthenticationExtension. The report server calls the

        /// GetUserInfo methodfor each request to retrieve the current user

        /// identity.

        /// </summary>

        /// <param name="userIdentity">represents the identity of the current

        /// user. The value of IIdentity may appear in a user interface and

        /// should be human readable</param>

        /// <param name="userId">represents a pointer to a unique user identity

        /// </param>

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]

        public void GetUserInfo(out IIdentity userIdentity, out IntPtr userId)

        {

            userIdentity = new GenericIdentity("dummy user");

            userId = IntPtr.Zero;

        }

        /// <summary>

        /// The IsValidPrincipalName method is called by the report server when

        /// the report server sets security on an item. This method validates

        /// that the user name is valid for Windows.The principal name needs to

        /// be a user, group, or builtin account name.

        /// </summary>

        /// <param name="principalName">A user, group, or built-in account name

        /// </param>

        /// <returns>true when the principle name is valid</returns>

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]

        public bool IsValidPrincipalName(string principalName)

        {

            return true;

        }

    }

}

 

namespace Microsoft.Samples.ReportingServices.AnonymousSecurity

{

    public class Authorization : IAuthorizationExtension

    {

        static Authorization()

        {

            InitializeMaps();

        }

        /// <summary>

        /// Returns a security descriptor that is stored with an individual

        /// item in the report server database.

        /// </summary>

        /// <param name="acl">The access code list (ACL) created by the report

        /// server for the item. It contains a collection of access code entry

        /// (ACE) structures.</param>

        /// <param name="itemType">The type of item for which the security

        /// descriptor is created.</param>

        /// <param name="stringSecDesc">Optional. A user-friendly description

        /// of the security descriptor, used for debugging. This is not stored

        /// by the report server.</param>

        /// <returns>Should be implemented to return a serialized access code

        /// list for the item.</returns>

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]

        public byte[] CreateSecurityDescriptor(

            AceCollection acl,

            SecurityItemType itemType,

            out string stringSecDesc)

        {

            stringSecDesc = null;

            return null;

        }

        public bool CheckAccess(

            string userName,

            IntPtr userToken,

       byte[] secDesc,

            ModelItemOperation modelItemOperation)

        {

            return true;

        }

        public bool CheckAccess(

            string userName,

            IntPtr userToken,

            byte[] secDesc,

            ModelOperation modelOperation)

        {

            return true;

        }

        /// <summary>

        /// Indicates whether a given user is authorized to access the item

        /// for a given catalog operation.

        /// </summary>

        /// <param name="userName">The name of the user as returned by the

        /// GetUserInfo method.</param>

        /// <param name="userToken">Pointer to the user ID returned by

        /// GetUserInfo.</param>

        /// <param name="secDesc">The security descriptor returned by

        /// CreateSecurityDescriptor.</param>

        /// <param name="requiredOperation">The operation being requested by

        /// the report server for a given user.</param>

        /// <returns>True if the user is authorized.</returns>

        public bool CheckAccess(

            string userName,

            IntPtr userToken,

            byte[] secDesc,

            CatalogOperation requiredOperation)

        {

            return true;

        }

        // Overload for array of catalog operations

        public bool CheckAccess(

            string userName,

            IntPtr userToken,

            byte[] secDesc,

            CatalogOperation[] requiredOperations)

        {

            return true;

        }

        // Overload for Report operations

        public bool CheckAccess(

            string userName,

            IntPtr userToken,

            byte[] secDesc,

            ReportOperation requiredOperation)

        {

            return true;

  }

        // Overload for Folder operations

        public bool CheckAccess(

            string userName,

            IntPtr userToken,

            byte[] secDesc,

            FolderOperation requiredOperation)

        {

            return true;

  }

        // Overload for an array of Folder operations

        public bool CheckAccess(

            string userName,

            IntPtr userToken,

            byte[] secDesc,

            FolderOperation[] requiredOperations)

        {

            return true;

        }

        // Overload for Resource operations

        public bool CheckAccess(

            string userName,

            IntPtr userToken,

            byte[] secDesc,

            ResourceOperation requiredOperation)

        {

            return true;

        }

        // Overload for an array of Resource operations

        public bool CheckAccess(

            string userName,

            IntPtr userToken,

            byte[] secDesc,

            ResourceOperation[] requiredOperations)

        {

            return true;

        }

        // Overload for Datasource operations

        public bool CheckAccess(

            string userName,

            IntPtr userToken,

            byte[] secDesc,

            DatasourceOperation requiredOperation)

        {

            return true;

        }

        /// <summary>

        /// Returns the set of permissions a specific user has for a specific

        /// item managed in the report server database. This provides underlying

        /// support for the Web service method GetPermissions().

        /// </summary>

        /// <param name="userName">The name of the user as returned by the

        /// GetUserInfo method.</param>

        /// <param name="userToken">Pointer to the user ID returned by

        /// GetUserInfo.</param>

        /// <param name="itemType">The type of item for which the permissions

        /// are returned.</param>

        /// <param name="secDesc">The security descriptor associated with the

        /// item.</param>

        /// <returns></returns>

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]

        public StringCollection GetPermissions(string userName, IntPtr userToken,

         SecurityItemType itemType, byte[] secDesc)

        {

            return m_fullPermissions;

        }

        private static Hashtable m_ModelItemOperNames;

        private static Hashtable m_ModelOperNames;

        private static Hashtable m_CatOperNames;

        private static Hashtable m_FldOperNames;

        private static Hashtable m_RptOperNames;

        private static Hashtable m_ResOperNames;

        private static Hashtable m_DSOperNames;

        private static StringCollection m_fullPermissions = new StringCollection();

        private const int NrRptOperations = 27;

        private const int NrFldOperations = 10;

        private const int NrResOperations = 7;

        private const int NrDSOperations = 7;

        private const int NrCatOperations = 16;

        private const int NrModelOperations = 11;

        private const int NrModelItemOperations = 1;

        // Utility method used to create mappings to the various

        // operations in Reporting Services. These mappings support

        // the implementation of the GetPermissions method.

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2201:DoNotRaiseReservedExceptionTypes"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2201:DoNotRaiseReservedExceptionTypes"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2201:DoNotRaiseReservedExceptionTypes"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2201:DoNotRaiseReservedExceptionTypes"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2201:DoNotRaiseReservedExceptionTypes"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2201:DoNotRaiseReservedExceptionTypes"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2201:DoNotRaiseReservedExceptionTypes")]

        private static void InitializeMaps()

        {

            // create model operation names data

            m_ModelItemOperNames = new Hashtable();

            m_ModelItemOperNames.Add(ModelItemOperation.ReadProperties,

               OperationNames.OperReadProperties);

            if (m_ModelItemOperNames.Count != NrModelItemOperations)

            {

                //Model item name mismatch

      throw new Exception("Model item name mismatch");

            }

            // create model operation names data

            m_ModelOperNames = new Hashtable();

            m_ModelOperNames.Add(ModelOperation.Delete,

               OperationNames.OperDelete);

            m_ModelOperNames.Add(ModelOperation.ReadAuthorizationPolicy,

              OperationNames.OperReadAuthorizationPolicy);

            m_ModelOperNames.Add(ModelOperation.ReadContent,

              OperationNames.OperReadContent);

            m_ModelOperNames.Add(ModelOperation.ReadDatasource,

              OperationNames.OperReadDatasources);

            m_ModelOperNames.Add(ModelOperation.ReadModelItemAuthorizationPolicies,

              OperationNames.OperReadModelItemSecurityPolicies);

            m_ModelOperNames.Add(ModelOperation.ReadProperties,

              OperationNames.OperReadProperties);

            m_ModelOperNames.Add(ModelOperation.UpdateContent,

              OperationNames.OperUpdateContent);

            m_ModelOperNames.Add(ModelOperation.UpdateDatasource,

              OperationNames.OperUpdateDatasources);

            m_ModelOperNames.Add(ModelOperation.UpdateDeleteAuthorizationPolicy,

              OperationNames.OperUpdateDeleteAuthorizationPolicy);

            m_ModelOperNames.Add(ModelOperation.UpdateModelItemAuthorizationPolicies,

              OperationNames.OperUpdateModelItemSecurityPolicies);

            m_ModelOperNames.Add(ModelOperation.UpdateProperties,

              OperationNames.OperUpdatePolicy);

            if (m_ModelOperNames.Count != NrModelOperations)

            {

                //Model name mismatch

                throw new Exception("Model name mismatch");

    }

            // create operation names data

            m_CatOperNames = new Hashtable();

            m_CatOperNames.Add(CatalogOperation.CreateRoles,

               OperationNames.OperCreateRoles);

            m_CatOperNames.Add(CatalogOperation.DeleteRoles,

               OperationNames.OperDeleteRoles);

            m_CatOperNames.Add(CatalogOperation.ReadRoleProperties,

               OperationNames.OperReadRoleProperties);

            m_CatOperNames.Add(CatalogOperation.UpdateRoleProperties,

  OperationNames.OperUpdateRoleProperties);

            m_CatOperNames.Add(CatalogOperation.ReadSystemProperties,

               OperationNames.OperReadSystemProperties);

            m_CatOperNames.Add(CatalogOperation.UpdateSystemProperties,

  OperationNames.OperUpdateSystemProperties);

            m_CatOperNames.Add(CatalogOperation.GenerateEvents,

               OperationNames.OperGenerateEvents);

            m_CatOperNames.Add(CatalogOperation.ReadSystemSecurityPolicy,

               OperationNames.OperReadSystemSecurityPolicy);

            m_CatOperNames.Add(CatalogOperation.UpdateSystemSecurityPolicy,

               OperationNames.OperUpdateSystemSecurityPolicy);

            m_CatOperNames.Add(CatalogOperation.CreateSchedules,

               OperationNames.OperCreateSchedules);

            m_CatOperNames.Add(CatalogOperation.DeleteSchedules,

               OperationNames.OperDeleteSchedules);

            m_CatOperNames.Add(CatalogOperation.ReadSchedules,

               OperationNames.OperReadSchedules);

            m_CatOperNames.Add(CatalogOperation.UpdateSchedules,

               OperationNames.OperUpdateSchedules);

            m_CatOperNames.Add(CatalogOperation.ListJobs,

               OperationNames.OperListJobs);

  m_CatOperNames.Add(CatalogOperation.CancelJobs,

               OperationNames.OperCancelJobs);

            m_CatOperNames.Add(CatalogOperation.ExecuteReportDefinition,

             OperationNames.ExecuteReportDefinition);

            if (m_CatOperNames.Count != NrCatOperations)

            {

                //Catalog name mismatch

                throw new Exception("Catalog name mismatch");

            }

            m_FldOperNames = new Hashtable();

            m_FldOperNames.Add(FolderOperation.CreateFolder,

               OperationNames.OperCreateFolder);

            m_FldOperNames.Add(FolderOperation.Delete,

               OperationNames.OperDelete);

            m_FldOperNames.Add(FolderOperation.ReadProperties,

               OperationNames.OperReadProperties);

            m_FldOperNames.Add(FolderOperation.UpdateProperties,

               OperationNames.OperUpdateProperties);

            m_FldOperNames.Add(FolderOperation.CreateReport,

               OperationNames.OperCreateReport);

            m_FldOperNames.Add(FolderOperation.CreateResource,

               OperationNames.OperCreateResource);

            m_FldOperNames.Add(FolderOperation.ReadAuthorizationPolicy,

               OperationNames.OperReadAuthorizationPolicy);

            m_FldOperNames.Add(FolderOperation.UpdateDeleteAuthorizationPolicy,

               OperationNames.OperUpdateDeleteAuthorizationPolicy);

            m_FldOperNames.Add(FolderOperation.CreateDatasource,

               OperationNames.OperCreateDatasource);

            m_FldOperNames.Add(FolderOperation.CreateModel,

               OperationNames.OperCreateModel);

            if (m_FldOperNames.Count != NrFldOperations)

            {

                //Folder name mismatch

               throw new Exception("Folder name mismatch");

            }

            m_RptOperNames = new Hashtable();

            m_RptOperNames.Add(ReportOperation.Delete,

               OperationNames.OperDelete);

            m_RptOperNames.Add(ReportOperation.ReadProperties,

               OperationNames.OperReadProperties);

            m_RptOperNames.Add(ReportOperation.UpdateProperties,

               OperationNames.OperUpdateProperties);

            m_RptOperNames.Add(ReportOperation.UpdateParameters,

               OperationNames.OperUpdateParameters);

            m_RptOperNames.Add(ReportOperation.ReadDatasource,

               OperationNames.OperReadDatasources);

            m_RptOperNames.Add(ReportOperation.UpdateDatasource,

               OperationNames.OperUpdateDatasources);

            m_RptOperNames.Add(ReportOperation.ReadReportDefinition,

               OperationNames.OperReadReportDefinition);

            m_RptOperNames.Add(ReportOperation.UpdateReportDefinition,

               OperationNames.OperUpdateReportDefinition);

            m_RptOperNames.Add(ReportOperation.CreateSubscription,

               OperationNames.OperCreateSubscription);

            m_RptOperNames.Add(ReportOperation.DeleteSubscription,

               OperationNames.OperDeleteSubscription);

            m_RptOperNames.Add(ReportOperation.ReadSubscription,

               OperationNames.OperReadSubscription);

            m_RptOperNames.Add(ReportOperation.UpdateSubscription,

               OperationNames.OperUpdateSubscription);

            m_RptOperNames.Add(ReportOperation.CreateAnySubscription,

               OperationNames.OperCreateAnySubscription);

            m_RptOperNames.Add(ReportOperation.DeleteAnySubscription,

               OperationNames.OperDeleteAnySubscription);

            m_RptOperNames.Add(ReportOperation.ReadAnySubscription,

               OperationNames.OperReadAnySubscription);

            m_RptOperNames.Add(ReportOperation.UpdateAnySubscription,

               OperationNames.OperUpdateAnySubscription);

            m_RptOperNames.Add(ReportOperation.UpdatePolicy,

               OperationNames.OperUpdatePolicy);

            m_RptOperNames.Add(ReportOperation.ReadPolicy,

               OperationNames.OperReadPolicy);

            m_RptOperNames.Add(ReportOperation.DeleteHistory,

               OperationNames.OperDeleteHistory);

            m_RptOperNames.Add(ReportOperation.ListHistory,

               OperationNames.OperListHistory);

            m_RptOperNames.Add(ReportOperation.ExecuteAndView,

               OperationNames.OperExecuteAndView);

            m_RptOperNames.Add(ReportOperation.CreateResource,

               OperationNames.OperCreateResource);

            m_RptOperNames.Add(ReportOperation.CreateSnapshot,

               OperationNames.OperCreateSnapshot);

            m_RptOperNames.Add(ReportOperation.ReadAuthorizationPolicy,

               OperationNames.OperReadAuthorizationPolicy);

            m_RptOperNames.Add(ReportOperation.UpdateDeleteAuthorizationPolicy,

               OperationNames.OperUpdateDeleteAuthorizationPolicy);

            m_RptOperNames.Add(ReportOperation.Execute,

               OperationNames.OperExecute);

            m_RptOperNames.Add(ReportOperation.CreateLink,

               OperationNames.OperCreateLink);

            if (m_RptOperNames.Count != NrRptOperations)

            {

                //Report name mismatch

                throw new Exception("Report name mismatch");

            }

            m_ResOperNames = new Hashtable();

            m_ResOperNames.Add(ResourceOperation.Delete,

               OperationNames.OperDelete);

            m_ResOperNames.Add(ResourceOperation.ReadProperties,

               OperationNames.OperReadProperties);

            m_ResOperNames.Add(ResourceOperation.UpdateProperties,

               OperationNames.OperUpdateProperties);

            m_ResOperNames.Add(ResourceOperation.ReadContent,

               OperationNames.OperReadContent);

            m_ResOperNames.Add(ResourceOperation.UpdateContent,

               OperationNames.OperUpdateContent);

            m_ResOperNames.Add(ResourceOperation.ReadAuthorizationPolicy,

               OperationNames.OperReadAuthorizationPolicy);

            m_ResOperNames.Add(ResourceOperation.UpdateDeleteAuthorizationPolicy,

               OperationNames.OperUpdateDeleteAuthorizationPolicy);

            if (m_ResOperNames.Count != NrResOperations)

            {

                //Resource name mismatch

                throw new Exception("Resource name mismatch");

            }

            m_DSOperNames = new Hashtable();

            m_DSOperNames.Add(DatasourceOperation.Delete,

               OperationNames.OperDelete);

            m_DSOperNames.Add(DatasourceOperation.ReadProperties,

               OperationNames.OperReadProperties);

            m_DSOperNames.Add(DatasourceOperation.UpdateProperties,

               OperationNames.OperUpdateProperties);

            m_DSOperNames.Add(DatasourceOperation.ReadContent,

               OperationNames.OperReadContent);

            m_DSOperNames.Add(DatasourceOperation.UpdateContent,

               OperationNames.OperUpdateContent);

            m_DSOperNames.Add(DatasourceOperation.ReadAuthorizationPolicy,

               OperationNames.OperReadAuthorizationPolicy);

            m_DSOperNames.Add(DatasourceOperation.UpdateDeleteAuthorizationPolicy,

               OperationNames.OperUpdateDeleteAuthorizationPolicy);

            if (m_DSOperNames.Count != NrDSOperations)

       {

                //Datasource name mismatch

                throw new Exception("Datasource name mismatch");

            }

            // Initialize permission collection.

            foreach (CatalogOperation oper in m_CatOperNames.Keys)

          {

                if (!m_fullPermissions.Contains((string)m_CatOperNames[oper]))

                    m_fullPermissions.Add((string)m_CatOperNames[oper]);

            }

            foreach (ModelItemOperation oper in m_ModelItemOperNames.Keys)

            {

                if (!m_fullPermissions.Contains((string)m_ModelItemOperNames[oper]))

                    m_fullPermissions.Add((string)m_ModelItemOperNames[oper]);

            }

            foreach (ModelOperation oper in m_ModelOperNames.Keys)

            {

                if (!m_fullPermissions.Contains((string)m_ModelOperNames[oper]))

                    m_fullPermissions.Add((string)m_ModelOperNames[oper]);

            }

            foreach (CatalogOperation oper in m_CatOperNames.Keys)

            {

                if (!m_fullPermissions.Contains((string)m_CatOperNames[oper]))

                    m_fullPermissions.Add((string)m_CatOperNames[oper]);

            }

            foreach (ReportOperation oper in m_RptOperNames.Keys)

            {

                if (!m_fullPermissions.Contains((string)m_RptOperNames[oper]))

                    m_fullPermissions.Add((string)m_RptOperNames[oper]);

            }

            foreach (FolderOperation oper in m_FldOperNames.Keys)

  {

                if (!m_fullPermissions.Contains((string)m_FldOperNames[oper]))

                    m_fullPermissions.Add((string)m_FldOperNames[oper]);

            }

            foreach (ResourceOperation oper in m_ResOperNames.Keys)

         {

                if (!m_fullPermissions.Contains((string)m_ResOperNames[oper]))

                    m_fullPermissions.Add((string)m_ResOperNames[oper]);

            }

            foreach (DatasourceOperation oper in m_DSOperNames.Keys)

            {

                if (!m_fullPermissions.Contains((string)m_DSOperNames[oper]))

                    m_fullPermissions.Add((string)m_DSOperNames[oper]);

            }

        }

        /// <summary>

        /// You must implement SetConfiguration as required by IExtension

        /// </summary>

        /// <param name="configuration">Configuration data as an XML

        /// string that is stored along with the Extension element in

        /// the configuration file.</param>

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2201:DoNotRaiseReservedExceptionTypes"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2201:DoNotRaiseReservedExceptionTypes")]

        public void SetConfiguration(string configuration)

        {

        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]

        public string LocalizedName

        {

            get

            {

                // Return a localized name for this extension

                return null;

            }

        }

    }

}