RS and NS

  • Anonymous access in SQL RS 2008 - Part 2

    Recently I received a few questions on Anonymous authentication. For anonymous auth in SSRS2005, I always had the question about how to give administrative permission to some users, while giving read permissions to the mass. Now I have my question answered. A duplicate RM/RS virtual directory was configured for anonymous authentication. Extranet users connect to the anonymous auth enabled vdir. Intranet users connect to the windows auth enabled vdir.

    I am actually not 100% sure on the supportability of such deployments. But customers have found ways to do it. Unfortunately SSRS2008 does not allow you to create virtual directories. My suggestions was

    "Unfortunately there isn't an easy alternative in SSRS2008. If you can afford to install a second instance and configure a web farm, you can make the second instance anonymous. Another solution is to create a front end application using the viewer control, and enable anonymous authentication there."

     I guess there are always some IIS configuration that we won't be able to support. However, anonymous auth seems to be a common request from customers. We do not want to make RS an all-purpose web server. I a still wondering what is the best way to support something like this ...

    You can find the original discussion here: http://forums.microsoft.com/msdn/ShowPost.aspx?PostID=3995702&SiteID=1 

  • 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;

                }

            }

        }

    }

     

  • Foreword on Reporting Services Katmai "Rehosting"

    The upcoming major release of SQL Server Reporting Services (or RS) brings about many changes. If you had played with a CTP version, you will undoubtedly notice significant changes to the way RS is configured. You would probably be surprised to find that IIS is no longer required. In fact, most of the configuration changes are the result of removing the IIS dependency.

    This is a very interesting area that comes with many questions and challenges. First of all, why we did it? Initially the motivation was to reduce configuration complexity. IIS management involves a set of tools (UI, metabase, ADSI and WMI). IIS7 is a totally different beast. Hosting a web service like RS require much less than what IIS can offer. Second, an administrator may not want IIS on the server. One may argue that in terms of attack surface, hosting a web service in another process is just as bad as hosting it in IIS, since they require the same port to be open to public. This is true to some degree. Without getting into the details, it can be said that Katmai RS can choose to listen on a more restrictive set of urls, thereby reducing surface area.

    Writing a hosting process for RS presented a universe of opportunities for better memory/resource management and better scheduling algorithm. Thanks to the support from SQL server engine folks, RS now fully embrace the SQL OS infrastructure, including SQL CLR and SNI (SQL Networking Interface). This is where the "rehosted" solution really shines. Although RS doesn't currently take full advantage of SQL OS, it is the right path for a server process to follow.

    I will end the preamble here. I hope to find enough time to go into the specifics of rehosting. If there are particular areas that are of interest to you, feel free to leave me a note.


© 2009 Microsoft Corporation. All rights reserved. Terms of Use  |  Trademarks  |  Privacy Statement
Microsoft
Page view tracker