Showing posts with label Maintenance. Show all posts
Showing posts with label Maintenance. Show all posts

Saturday, September 8, 2012

Max number of nesting forests in cross-forest membership in AD groups

Some time ago we needed to determine what is the maximum number of nesting forests in cross-forest AD groups membership. There are 3 types of AD group scopes:

  • Universal
  • Global
  • Domain local

Group scope determines what members group may have and to what domains in the forest/tree you may assign permissions to this group. In the following technet article there is a summary table which describes possible members for each group scope, target domains where you can set permissions and to what group scope each of them can be converted:

Group scope Group can include as members…

Group can be assigned permissions in…

Group scope can be converted to…
Universal

Accounts from any domain within the forest in which this Universal Group resides

Global groups from any domain within the forest in which this Universal Group resides

Universal groups from any domain within the forest in which this Universal Group resides

Any domain or forest

Domain local

Global (as long as no other universal groups exist as members)

Global

Accounts from the same domain as the parent global group

Global groups from the same domain as the parent global group

Member permissions can be assigned in any domain Universal (as long as it is not a member of any other global groups)
Domain local

Accounts from any domain

Global groups from any domain

Universal groups from any domain

Domain local groups but only from the same domain as the parent domain local group

Member permissions can be assigned only within the same domain as the parent domain local group Universal (as long as no other domain local groups exist as members)

Based on this table we may make interesting conclusion: cross-forest membership is possible for one level of nesting only (one hop). Only Domain local groups may have members from another forest: user accounts, Global and Universal groups, but not Domain local groups. Domain local groups may have as members another Domain local groups only if these child groups are from the same domain as parent group. At the same time Global and Universal groups may have members only from their own domain/forest. So maximum number of different nesting forests in cross-forest membership is 1. You may add groups from many forests into Domain local group, but nesting level is not greater than 1. Probably MS did it consciously in order to limit the complexity of maintenance and avoid circular dependency problems (e.g. if it would be possible to add into Domain local group from forest A as members Domain local groups from forest B then there will be possible that groups have each other as a member). This information may be useful if you work with multi-forest environments and need to plan security membership.

Sunday, September 2, 2012

Debug issues on production Sharepoint farm

In Sharepoint development it is not unusual when you have multiple working environments: development, QA, production. Development environment in most cases is single-farm environment, while QA is similar to production and has several WFEs, app and db server. Also in multi-vendors project it may be so that you as software provider don’t have access to QA and production: it is under control of another company responsible for IT infrastructure.

Such projects require more accurate development and quality assurance. However it still may happens that solution works properly on dev env, but after deploying it to QA problem occurs. What to do in such situation? How to troubleshoot issues if you even don’t have remote desktop access?

You need mechanism which is powerful and flexible enough to figure out where problem comes from and doesn’t require a lot of efforts from infrastructure maintenance company. One of the most efficient way to troubleshoot in such situation which I found during working over many multi-vendor projects is to create custom application layouts page, ask administrator from infrastructure company to copy it to 14/layouts subfolder on one of WFE and open it here in context of production site.

Page itself may have any logic implemented via server code. Code may be embedded into aspx page as server-side script:

   1: <%@ Page Language="C#" %>
   2: <%@ Assembly Name="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
   3: <%@ Import Namespace="Microsoft.SharePoint" %>
   4: <%@ Import Namespace="System.Web" %>
   5:  
   6: <%
   1:  
   2:     this.lbl.Text = SPContext.Current.Web.CurrentUser.Name;
%>
   7:  
   8: CurrentUser:&nbsp;<asp:Label ID="lbl" runat="server" />

By default you may use C# 2.0 in server-side scripts. In one of my previous posts I wrote how to enable C# 3.0 in application layouts pages: see Use C# 3.0 features in application layout pages in Sharepoint.

If you need to test a lot of code it may require time to embed the codebehind code to aspx page. There is another way to execute server code: with it you will have aspx page and separate .cs file with the logic. The method is based on CodeFile attribute for Page directive. In this case codebehind class will be compiled in runtime by ASP.Net. You need to specify path to .cs file in this attribute and then in Inherits attribute specify page class from this .cs file. Here is example:

   1: <%@ Page Language="C#" CodeFile="~/_layouts/test/Test.aspx.cs" Inherits="MyNamespace.Test" %>
   2: <%@ Assembly Name="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
   3: <%@ Import Namespace="Microsoft.SharePoint" %>
   4: <%@ Import Namespace="System.Web" %>
   5:  
   6: CurrentUser:<asp:Label ID="lbl" runat="server" />

In Test.aspx.cs you need to specify base class of the page:

   1: using System;
   2: using System.IO;
   3: using System.Web;
   4: using Microsoft.SharePoint;
   5:  
   6: namespace MyNamespace
   7: {
   8:     public partial class Test : LayoutsPageBase
   9:     {
  10:         public override void OnLoad(EventArgs e)
  11:         {
  12:             this.lbl.Text = SPContext.Current.Web.CurrentUser.Name;
  13:         }
  14:     }
  15: }

Note that there is no need to specify protected controls variables in page class. They will be added automatically in runtime by ASP.Net compiler in partial class (that’s why you need to make your custom page class partial as it is shown in example above). This is quite powerful technique which will allow to test existing application layout pages almost without changing them. Also it requires minimum actions from farm administrator from infrastructure maintenance company which in real life is very important advantage.

Saturday, January 14, 2012

One problem with cross-projects project items references in Sharepoint 2010 VS template

Often when working on Sharepoint projects there are several projects of Sharepoint 2010 VS project template in single solution. E.g. if you develop Internet and Extranet you may have 3 wsp packages (and 3 projects in VS):

  • Common – contains common functionality for Internet and Extranet
  • Internet – contains only Internet-specific functionality
  • Extranet – contains only Extranet-specific functionality

Doing like that if customer have different environments for Internet and Extranet, it will be possible to deploy Common and Internet packages on Internet environment, and Common and Extranet – on Extranet environment.

Visual studio allows you to include Sharepoint project items from different Sharepoint projects. E.g. if you have MOPages module in Common project, you can add this module into the feature from Internet or Extranet projects. It will work, however there is one side effect: in this case assembly which is build from Common project (Common.dll) will be included to the Internet.wsp and Extranet.wsp packages as well. In our example it most probably won’t cause problems, because we anyway need deploy Common package at the same time when Internet or Extranet packages will be deployed. In this case Common.dll will be installed to GAC first time from Common.wsp, and then from Internet.wsp or Extranet.wsp (depends in what order you deploy packages).

But if it may cause problems if you have some base library package in your company (e.g. Sharepoint.Base.wsp) which you use in many projects and control releases of this package (because you don’t want that changes made in newest version will break something on the existing environments of different customers). If you will include project items (PI) from Sharepoint.Base.csproj into your project (you may do it if will include Sharepoint.Base.csproj into your solution), then Internet.wsp (or Extranet.wsp) will also contain Sharepoint.Base.dll, regardless of the fact do you use C# code from it or not. I.e. as I mentioned above you may add module project item from Sharepoint.Base.csproj which doesn’t technically require adding reference to Sharepoint.Base in VS (solution will be compiled without it anyway), but Sharepoint.Base.dll will be anyway added to your wsp.

What will happen when you will deploy Internet.wsp (which contains now Internet.dll, Common.dll and Sharepoint.Base.dll)? All 3 dlls will be updated in GAC, including Sharepoint.Base.dll. It breaks policy with controlled releases – because now it will be hard to control what version of the Sharepoint.Base.dll is installed on production (because it will be updated when you deploy Internet.wsp and when you deploy Sharepoint.Base.wsp). If you will deploy latest version of the Sharepoint.Base.wsp to the production while other sites depend on old version, they may stop working. It may cause to version inconsistency and will lead to maintenance hell.

In order to avoid this problem do not make cross-projects references of project items when use Sharepoint 2010 VS project templates. Add functionality from base project by including on feature level (e.g. by adding features from base package into your onet.xml files) or use it as is. If these features contain a lot of another functionality which you don’t need in your projects, it is better to just copy necessary artifacts from it. In this case some functionality will be duplicated, but maintenance will be still controlled.

Recently Koen Vosters from MS wrote about similar problem in his blog: Unexpected DLL in a WSP package. (Hi Koen, and thanks one more time for the great help which you made for us in Finland! :) ). I hope that my post will be more popular in search engines :)) Just kidding ;)