For a standard team site (STS#0) the GlobalNodes SPNavigationNodesCollection will contain three SPNavigationNode objects.

Home, Quick Launch and SharePoint Top Navigation Bar, these each have Ids of 1000, 1002 and 1025 respectively.

The problem occurs if you delete Quick Launch or SharePoint Top Navigation nodes. Even if you then add them back in a new ID is generated and SPWeb.Navigation.TopNavigationBar looks for child nodes under a node with an Id of 1002 (This is hard coded).

Through the API this means that SPWeb.Navigation.TopNavigationBar will always be null and through the SharePoint UI an error will be returned to the user (“Value does not exist in that range”).

The only ways I have found to fix this is to delete and re-create the site or (Microsoft please close your ears) get the site id and web id and query the NavNodes table in the content database the site collection sits in and add the following records

SiteId WebId Eid EidParent NumChildren RankChild ElementType Url DocId Name DateLastModified NodeMetaInfo NonNavPage NavSequence ChildOfSequence
C803FD13-27FA-475F-909C-2CE5B2048E1B A31E8093-1505-4E1C-B7CC-04D6B952A33F 1000 0 0 0 0 NULL A31414EE-953B-44CC-A37E-4D5D643B002A Home 2008-04-04 11:28:21.000 NULL False False False
C803FD13-27FA-475F-909C-2CE5B2048E1B A31E8093-1505-4E1C-B7CC-04D6B952A33F 1002 0 0 2 1 NULL NULL SharePoint Top Navigation 2008-04-04 11:28:21.000 NULL False True False
C803FD13-27FA-475F-909C-2CE5B2048E1B A31E8093-1505-4E1C-B7CC-04D6B952A33F 1025 0 0 1 1 NULL NULL Quick Launch 2008-04-04 11:28:21.000 NULL True True False

Comment and share

To match the ScopeId in the EventData property of the SPAuditEntry to a SPListItem you need to use the hidden column ScopeId and not the Id property of SPListItem.

Here is what I mean.

The following XML is returned in the EventData proprty for a SPAuditEventType of SecRoleBindUpdate. To match the Scope returned in the XML to SPSite, SPWeb and SPList object you would use the Id property of this object, but not for the SPListItem.

1
2
3
<roleid>1073741826</roleid>
<principalid>11</principalid>
<scope>72EEC412-B14B-4EFB-AB95-EA821A3A4C63</scope>

You need to use the ScopeId column of the SPListItem

So why can’t I just use the SPAuditQuery.RestrictToListItem method to return the audit entries for that SPListItem.

It doesn’t work, that’s why and this has been confirmed by MS Support.

Here is a workaround that will link the ScopeId to the SPListItem that triggered the audit entry

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
using System; 
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;

namespace ConsoleApplication1
{  
class Program  
{  
static void Main(string[] args)  
{
string siteUrl = "http://url";  
string listName = "TheList";  
string scopeIdFromItem = string.Empty;  
string scopeIdFromChange = string.Empty;

try  
{  
using (SPSite site = new SPSite(siteUrl))  
{  
using (SPWeb web = site.OpenWeb())  
{
SPList list = web.Lists[listName];
SPRegionalSettings regionalSettings = web.RegionalSettings;  
SPTimeZone timeZone = regionalSettings.TimeZone;
SPAuditQuery query = new SPAuditQuery(site);  
SPAuditEntryCollection auditEntries = site.Audit.GetEntries(query);

foreach (SPAuditEntry auditEntry in auditEntries)  
{  
if (IsSecurityEvent(auditEntry))  
{  
try  
{  
if (auditEntry.Event.ToString().ToUpper() == "SECROLEBINDUPDATE")  
{
// Should really do a proper XML query here, but for demo just do some string stuff
scopeIdFromChange = auditEntry.EventData.ToString().Substring((auditEntry.EventData.ToString().Length - 44), 36);
foreach (SPListItem item in list.Items)  
{ // Square brackets round the scope id need to be removed
scopeIdFromItem = item["ScopeId"].ToString().Substring(1, 36);

if (scopeIdFromChange == scopeIdFromItem)  
{  
Console.Write("Event Data : ");
Console.WriteLine(auditEntry.EventData.ToString());  
Console.Write("Occurred : ");
Console.WriteLine(timeZone.UTCToLocalTime(auditEntry.Occurred));

if (list.BaseType == SPBaseType.DocumentLibrary)  
{  
Console.WriteLine("Security changed on file: " + item.File.ToString());  
}  

if (list.BaseType == SPBaseType.GenericList)  
{  
Console.WriteLine("Security changed on item: " + item.Name.ToString());  
}  
}  
else  
{  
Console.WriteLine("No item found in list " + siteUrl + "/" + listName + " for " + auditEntry.EventData.ToString());  
}  
}  
}  
}  
catch (Exception ex)  
{  
Console.WriteLine(ex.Message.ToString());  
}
}  
}  
}  
}  
}  
catch (Exception ex)
{  
Console.WriteLine(ex.Message);  
}  
}

private static bool IsSecurityEvent(SPAuditEntry entryToTest)  
{  
SPAuditEventType[] SECURITY_EVENTS = new SPAuditEventType[]  
{  
SPAuditEventType.SecGroupCreate,  
SPAuditEventType.SecGroupDelete,  
SPAuditEventType.SecGroupMemberAdd,  
SPAuditEventType.SecGroupMemberDel,  
SPAuditEventType.SecRoleBindBreakInherit,  
SPAuditEventType.SecRoleBindInherit,  
SPAuditEventType.SecRoleBindUpdate,  
SPAuditEventType.SecRoleDefBreakInherit,  
SPAuditEventType.SecRoleDefCreate,  
SPAuditEventType.SecRoleDefDelete,  
SPAuditEventType.SecRoleDefModify  
};

foreach (SPAuditEventType eventType in SECURITY_EVENTS)  
{  
if (eventType == entryToTest.Event)
return true;  
}
return false;
}
}
}
}
}

Comment and share

We were getting an error on one of our Load balanced web servers.

First of all we got “Attempted to read write to protected memory” error followed by the “The path specified cannot be used at this time” which is then logged every minute in the event viewer on our server.

This then ends up using all the resources on that server, which then makes the server become unavailable. Once the machine becomes unavailable it will move onto the next server and kill that one.

This was reported to Microsoft support and they identified it as a bug that will be fixed in SP1.

In the meantime the following will need to be done to work around this problem.

  1. Install the following hotfix 923028
  2. Retype the password for the search service from The central administrator page.
  3. Run “services.msc” and select the Windows SharePoint Services Timer
  4. Make sure the service is running with a MOSS service account, if it is running with MOSS services account then stop the service, retype the password and then start the service account again.
  5. Install / script a tool that automatically restarts the Windows SharePoint Services Timer when the following Event IDs are raised; 6398, 6482 and 7076. Microsoft Support maybe able to provide you with this tool if you raise a support request with them.

This is a particularly scary bug to be appearing in a “Production” ready product, especially as it is only happening in the farm environment and can take down you whole farm.

I believe there needs to be more information on the whole way SharePoint propagates between servers in a farm, there seems to be little understanding of it presently.

Comment and share

This is the second part of a two part post. The first part can be seen here

Now that we have SSO setup and working, we now need to create and import the application definition.

I’m not going to go into to much detail on how to create a application definition, but there are various tools available that you can use (BDC Meta Manager, Microsoft Business Data Catalog Definition Editor which is part of the SharePoint Server 2007 SDK)

Here are the key parts of the application definition you need to be aware of.

I have added the full block of XML to the end of this post.

Below are the properties used by SharePoint to connect to the database. You need to use the SSO ID specified in Part One when you setup SSO

1
2
3
4
5
6
7
8
9
10
11
12
<LobSystemInstance Name="Persons">
<Properties>
<Property Name="AuthenticationMode" Type="System.String">RdbCredentials</Property>
<Property Name="DatabaseAccessProvider" Type="System.String">SqlServer</Property>
<Property Name="RdbConnection Data Source" Type="System.String">MyServerName</Property>
<Property Name="RdbConnection Initial Catalog" Type="System.String">MyDatabaseName</Property>
<Property Name="RdbConnection Integrated Security" Type="System.String">false</Property>
<Property Name="RdbConnection Pooling" Type="System.String">true</Property>
<Property Name="SsoApplicationId" Type="System.String">SSOAppId</Property>
<Property Name="SsoProviderImplementation" Type="System.String">Microsoft.SharePoint.Portal.SingleSignon.SpsSsoProvider, Microsoft.SharePoint.Portal.SingleSignon, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c</Property>
</Properties>
</LobSystemInstance>

If your primary source is going to be from your Active Directory (In most cases it will be). Your identifier needs to be in the format of DOMAIN\UserName

Once you have loaded your application you need to add both the search crawl account and the user crawl account and give them execute permission . In most cases this will be the same account, but if you have followed the least privilege configuration, these will be separate accounts and both will need to be added.

To add the BDC as secondary connection, go to the following link in SSP admin;

http://myserver/ssp/admin/_layouts/MgrDSServer.aspx

Or through Central Administration

Shared Services Administration: My SSP > User Profile and Properties > Manage Connections

From the screen:

  1. Click on the “Create New Connection” button and enter the information as below

  2. You need to match your UserNameFilter specified in the application definition file to the AccountName User Profile field

User Profile Import Settings

  1. Click OK and then schedule a full profile import.

Once the import has finished, check the import logs for any errors. This should always be your first port of call if it does not work.

Look for errors under the PEOPLE_DL_IMPORT content source and beginning with spsimport://$nonmaster$

Once the import has been run successfully, you will now be able to map the fields with the user profile properties in the “View Profile Properties” page.

Person App Definition XML

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
<?xml version="1.0" standalone="yes"?>
<LobSystem xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://schemas.microsoft.com/office/2006/03/BusinessDataCatalog BDCMetadata.XSD" xmlns="http://schemas.microsoft.com/office/2006/03/BusinessDataCatalog" Type="Database" Version="9.0.0.0" Name="Person2K6_LiteLOBSystem">
<Properties>
<Property Name="WildcardCharacter" Type="System.String">%</Property>
</Properties>
<LobSystemInstances>
<LobSystemInstance Name="Persons">
<Properties>
<Property Name="AuthenticationMode" Type="System.String">RdbCredentials</Property>
<Property Name="DatabaseAccessProvider" Type="System.String">SqlServer</Property>
<Property Name="RdbConnection Data Source" Type="System.String">MyServerName</Property>
<Property Name="RdbConnection Initial Catalog" Type="System.String">MyDatabaseName</Property>
<Property Name="RdbConnection Integrated Security" Type="System.String">false</Property>
<Property Name="RdbConnection Pooling" Type="System.String">true</Property>
<Property Name="SsoApplicationId" Type="System.String">SSOAppId</Property>
<Property Name="SsoProviderImplementation" Type="System.String">Microsoft.SharePoint.Portal.SingleSignon.SpsSsoProvider, Microsoft.SharePoint.Portal.SingleSignon, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c</Property>
</Properties>
</LobSystemInstance>
</LobSystemInstances>
<Entities>
<Entity EstimatedInstanceCount="0" Name="Person">
<Identifiers>
<Identifier Name="UserNameIdentifier" TypeName="System.String" />
</Identifiers>
<Methods>
<Method Name="GetPerson">
<Properties>
<Property Name="RdbCommandText" Type="System.String">SELECT UserName, PersonId, Title, FirstName, LastName, Location, EmailAddress, JobTitle, Extension, Fax, FROM PERSONS WHERE UserName LIKE @UserName</Property>
<Property Name="RdbCommandType" Type="System.Data.CommandType">Text</Property>
</Properties>
<FilterDescriptors>
<FilterDescriptor Type="Wildcard" Name="UserNameFilter" />
</FilterDescriptors>
<Parameters>
<Parameter Direction="In" Name="@UserName">
<TypeDescriptor TypeName="System.String" IdentifierName="UserNameIdentifier" AssociatedFilter="UserNameFilter" Name="UserNameParam">
<DefaultValues>
<DefaultValue MethodInstanceName="PersonFinder" Type="System.String">%</DefaultValue>
<DefaultValue MethodInstanceName="PersonspecificFinder" Type="System.String">%</DefaultValue>
</DefaultValues>
</TypeDescriptor>
</Parameter>
<Parameter Direction="Return" Name="Persons">
<TypeDescriptor TypeName="System.Data.IDataReader, System.Data, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" Name="PersonDataReader" IsCollection="true">
<TypeDescriptors>
<TypeDescriptor TypeName="System.Data.IDataRecord, System.Data, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" Name="PersonDataRecord">
<TypeDescriptors>
<TypeDescriptor TypeName="System.String" IdentifierName="UserNameIdentifier" Name="UserName" />
<TypeDescriptor TypeName="System.Int32" Name="PersonID" />
<TypeDescriptor TypeName="System.String" Name="Title" />
<TypeDescriptor TypeName="System.String" Name="FirstName" />
<TypeDescriptor TypeName="System.String" Name="LastName" />
<TypeDescriptor TypeName="System.String" Name="EmailAddress" />
<TypeDescriptor TypeName="System.String" Name="Location" />
<TypeDescriptor TypeName="System.String" Name="JobTitle" />
<TypeDescriptor TypeName="System.String" Name="Extension" />
<TypeDescriptor TypeName="System.String" Name="Fax" />
</TypeDescriptors>
</TypeDescriptor>
</TypeDescriptors>
</TypeDescriptor>
</Parameter>
</Parameters>
<MethodInstances>
<MethodInstance Name="PersonFinder" Type="Finder" ReturnParameterName="Persons" ReturnTypeDescriptorName="PersonDataReader" ReturnTypeDescriptorLevel="0" />
<MethodInstance Name="PersonspecificFinder" Type="SpecificFinder" ReturnParameterName="Persons" ReturnTypeDescriptorName="PersonDataReader" ReturnTypeDescriptorLevel="0" />
</MethodInstances>
</Method>
</Methods>
</Entity>
</Entities>
</LobSystem>

Comment and share

Here’s an odd one.

We had customized our master pages by adding in the Search WebPart, so we could customize some of the parameters

We changed the following:

1
<asp:ContentPlaceHolder id="PlaceHolderSearchArea" runat="server"></asp:ContentPlaceHolder>

To the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<asp:ContentPlaceHolder 
id="PlaceHolderSearchArea"
runat="server">
<SPSWC:SearchBoxEx
webpart="true"
runat="server"
__webpartid="{2883947B-2B5C-4A56-92B3-33B7383F7C0D}"
id="SearchBoxEx1">
<WebPart
xmlns:xsi="[http://www.w3.org/2001/XMLSchema-instance](http://www.w3.org/2001/XMLSchema-instance)"
xmlns:xsd="[http://www.w3.org/2001/XMLSchema](http://www.w3.org/2001/XMLSchema)"
xmlns="[http://schemas.microsoft.com/WebPart/v2](http://schemas.microsoft.com/WebPart/v2)">  
<Title />  
<FrameType>None</FrameType>  
<Description>Used to search document and items.</Description>  
<IsIncluded>true</IsIncluded>  
<ZoneID>ImportedPartZone</ZoneID>  
<PartOrder>0</PartOrder>  
<FrameState>Normal</FrameState>  
<Height />  
<Width />  
<AllowRemove>true</AllowRemove>  
<AllowZoneChange>true</AllowZoneChange>  
<AllowMinimize>true</AllowMinimize>  
<AllowConnect>true</AllowConnect>  
<AllowEdit>true</AllowEdit>  
<AllowHide>true</AllowHide>  
<IsVisible>true</IsVisible>  
<DetailLink />  
<HelpLink />  
<HelpMode>Modeless</HelpMode>  
<Dir>Default</Dir>  
<PartImageSmall />  
<MissingAssembly>Cannot import this Web Part.</MissingAssembly>  
<PartImageLarge />  
<IsIncludedFilter />  
<ExportControlledProperties>true</ExportControlledProperties>   <ConnectionID>00000000-0000-0000-0000-000000000000</ConnectionID>   <ID>g_455588d4_92a9_484e_9273_9221d7a9a97f</ID>  
<GoImageUrl xmlns="urn:schemas-microsoft-com:SearchBoxEx">/_layouts/images/gosearch.gif</GoImageUrl>  
<GoImageUrlRTL xmlns="urn:schemas-microsoft-com:SearchBoxEx">/_layouts/images/goRTL.gif</GoImageUrlRTL>   <GoImageActiveUrl xmlns="urn:schemas-microsoft-com:SearchBoxEx">/_layouts/images/gosearch.gif</GoImageActiveUrl> <GoImageActiveUrlRTL xmlns="urn:schemas-microsoft-com:SearchBoxEx">/_layouts/images/goRTL.gif</GoImageActiveUrlRTL>   <DropDownModeEx xmlns="urn:schemas-microsoft-com:SearchBoxEx">ShowDD_DefaultContextual</DropDownModeEx>   <AdvancedSearchPageURL xmlns="urn:schemas-microsoft-com:SearchBoxEx">/SearchCenter/Pages/advanced.aspx</AdvancedSearchPageURL>   <SearchResultPageURL xmlns="urn:schemas-microsoft-com:SearchBoxEx">/SearchCenter/Pages/results.aspx</SearchResultPageURL> <ScopeDisplayGroupName xmlns="urn:schemas-microsoft-com:SearchBoxEx">Search Dropdown</ScopeDisplayGroupName>   <RegisterStyles xmlns="urn:schemas-microsoft-com:SearchBoxEx">true</RegisterStyles>  
<ShouldTakeFocusIfEmpty xmlns="urn:schemas-microsoft-com:SearchBoxEx">false</ShouldTakeFocusIfEmpty>
</WebPart>
</SPSWC:SearchBoxEx>
</asp:ContentPlaceHolder>

We did this in all our master pages including the application.master page.

All was working fine until we tried to delete a column in a list and we go the “Unknown Error” message and the column wasn’t deleted.

The following error message was be ing logged

1
Application error when access /_layouts/mngfield.aspx, Error=Unable to validate data.   at System.Web.Configuration.MachineKeySection.GetDecodedData(Byte[] buf, Byte[] modifier, Int32 start, Int32 length, Int32& dataLength)     at System.Web.UI.ObjectStateFormatter.Deserialize(String inputString)

After of a month or so of investigation with Microsoft support, we discovered that the Search Webpart was causing the problem in the application.master page and causing a conflict in one of the application pages in the “Layouts” directory, specifically the mngfield.aspx page.

We have removed the Search WebPart from the application.master page and all seems to be working fine.

Comment and share

UPDATE

I have had an update from Microsoft on this issue, apparently the wording is wrong.

It will retain the number of major versions entered, but the number for minor versions is not to limit the number of minor versions, but to limit the number of major versions that have minor versions (Does that make sense?).

For example, if I set major versions to 10 and minor versions to 2, it will show me 10 major versions of which 10 and 9 will have minor versions still available.

The problem here is that I can still create 100 minor versions so this is not helping me limit the amount of versions my users keep and keep my storage costs down


In a document library under “Versioning Settings” you can choose to set the number of major and minor versions to retain.

Number of version to retain

This does not work! You are still able to create more than the number of versions specified in both major and minor

Version

I have spoken to Microsoft and they have confirmed this to be a “design limitation”. Has anyone ever got someone at Microsoft to say “bug”?

I’ll keep you updated if I get a fix for this.

Comment and share

There is currently a bug in MOSS 2007 search that automatically converts any URLs entered to lower-case.

We had a site hosted on a UNIX server that had a case sensitive URL, so when I entered http://server.net/Start/Welcome.html MOSS 2007 converted it to http://server.net/start/welcome.html and then tried to crawl this URL, but UNIX would return a “page could not be found” error.

Microsoft provided us with a hotfix for this, so if you have the same problem I suggest you raise a support request. :-)

Comment and share

I’m going to post a few articles about the process I went through to get this implemented.

There are a few things that aren’t documented that I wanted to catch in these posts, to prevent any further hair loss in the Sharepoint world.

In this first post I will detail how to install and configure SSO.

You will only need to configure SSO if you are using SQL authentication to connect to SQL Server.

Initial Setup

I used multiple service accounts for my MOSS 2007 farm, to prevent a single point of failure. It can make installation a little more complex, but will provide a stable environment in the long run.

Below is a brief overview of the accounts that are needed for the SSO installation and configuration (For full details on all the accounts needed for a MOSS 2007 installation have a look here.

http://technet2.microsoft.com/Office/en-us/library/798aa915-7025-4adc-a210-4f6ff14c43fc1033.mspx?mfr=true

mossuser-Setup

Used to run installs, you should use this account to log-on to your servers. It should be a local administrator of all your servers and have system administrator rights to the database.

mossuser-FarmAdmin

Used as the application pool for Central Administration and the process account for the Sharepoint Services Timer service. This account needs to be a member of the Logins, Dbcreator, Security Admin and DBO (for each database) roles

mossuser-SSPAppPool, mossuser-PortalAppPool, mossuser-OtherWebAppPool

All accounts that are used for web application pools will need to be able to administer SSO, this can be achieved by adding them to the mossgroup-SSOAdmin group.

mossuser-SSO

This account is used to run the SSO Service, it will need to be a local administrator of the master key server and have securityadministrator rights to the database *

mossgroup-FarmAdmin

This group should be added to the “Farm administrator’s group” and should have the the mossuser-SSO account as a member. (It’s worth while adding all users that need to administer the farm to this group for ease of management)

mossgroup-SSOAdmin

This group is used for the “Single Sign-On Administrator Account” and “Enterprise Application Definition Administrator Account” settings in “Manage Server Settings for Single Sign-On” page. This will need to have the following accounts as members; mossuser-FarmAdmin, mossuser-SSO, mossuser-Setup, mossuser-SSPAppPool, mossuser-PortalAppPool, mossuser-OtherWebAppPool.

Depending on how you manage your MOSS 2007 environment I would also add the mossgroup-FarmAdmin as a member, this means that all Farm administrators will also be able to administer SSO

Configuration

Configure the SSO Service

  1. Locate the “Microsoft Single Sign-on Service” in Services

    SSO Service

  2. Right click on the service and select properties

  3. On the “Log On” tab, select “This account” and enter the mossuser-SSO as the user in the format of Domain\User

SSO Service Props

  1. Click the Apply button and then OK

  2. Restart this service

  3. Update the service account through Central Administration

VERY IMPORTANT

I haven’t seen this documented anywhere, but you need to do this otherwise you will get the following error message when trying to configure SSO. This is only applicable if you are using multiple service accounts, if you are using one account that has local administrator rights and system administrator rights on the database this doesn’t occur

You do not have the rights to perfrom this action

In the event log the following error is logged

User DOMAIN\ mossuser-Setup failed to configure the single sign-on server. The error returned was 0x800708ad. Verify this account has sufficient permissions and try again.

  1. Go to the Central Administration site

  2. In the Central Administration site, go to “Operations” and under “Security Configuration”, click on “Service accounts”

  3. Select the “Windows Service” option and in the drop down, select “Single Sign-on Service”

  4. Select the “Configurable” option and enter the mossuser-SSO user and password

Service Account

  1. Click OK

Secondly if you get this error message

Failed to connect to the database server. Verify connectivity and rights for the configuration account and try again.

You need to follow these instruction from the following MS KB article: http://support.microsoft.com/kb/901203

Configure the SSO Server

  1. In the Central Administration site, go to “Operations” and under “Security Configuration”, click on “Manage settings for single sign-on” and then “Manage server settings”.

  2. Enter DOMAIN\mossgroup-SSOAdmin for the “Single Sign-On Administrator Account” in the “Account name” box

  3. Enter DOMAIN\mossgroup-SSOAdmin for the “Enterprise Application Definition Administrator Account” in the “Account name” box

  4. Enter the database server name and the SSO database name for the “Database Settings” in the “Server name”and “Database name” boxes

  5. Click OK

  6. Click on “Manage encryption key” and then click on the “Create Encryption Key” (You can also backup your encryption key here if you need to)

  7. Go back to the “Manage Single Sign-On” screen

  8. Click on “Manage settings for enterprise application definitions”

  9. Click on “New Item”

  10. Enter a display name for the application in the “Display Name” box

  11. Enter an application name for the application in the “Application name” box (You will use this name as the reference later on soI would make it small and easy to remember)

  12. In the “Field 1: Display Name” , enter “User ID” and set “Mask” to “No”

  13. In the “Field 2: Display Name”, enter “Password” and set “Mask” to “Yes”

  14. Click OK

    SSO App Admin

  15. Return back to the “Manage Single Sign-On” screen

  16. Click “Manage account information for enterprise application definitions”

  17. Enter the SQL account name in the “User ID” field

  18. Enter the password for the SQL account in the “Password” field

  19. Click OK

SSO App Def

VERY IMPORTANT

This is another task that I haven’t seen documented that needs to be done every time you create an encryption key

  1. Go to the Central Administration site

  2. Under “Upgrade and Migration”, click “Enable features on existing sites”

  3. Check “Enable all sites in this installation to use the following set of features” and click on OK. I think this must send out the new encryption key to the existing sites.

Summary

So I’m hoping now that you have SSO up and running!

In Part Two I will detail how to set up the BDC.

Configure SSO account

If you are unable to give your SSO account security administrator rights on your database then you will need to do the following

  • On a server that has MOSS 2007 installed, navigate to “C:\Program Files\Common Files\Microsoft Shared\Microsoft Office 12 Single Sign-on” and locate the sso_schema.sql file and take a copy.

  • Open up “Microsoft SQL Server Management Studio” and connect to your database server.

  • Create a database called SSO

  • Put the mossuser-SSO in the dbo role for this database

  • Make sure you have SSO selected as the database and then open the copied sso_schema.sql file.

  • Run the script

Comment and share

SSO Configuration

in admin

If you are getting errors when trying to configure SSO in MOSS 2007, something we discovered that solved this that is worth trying

  1. In Central Administration go to Operations·
  2. Under Secuirty Configuration, click on Service Accounts·
  3. Select “Windows service” option and then “Single Sign-on service” in the corresponding dropdown·
  4. Enter in the service account username and password·
  5. Click OK

Even though we had set this up through the “Services” console, doing this through the central administration screen fixed the problem.

Some of the errors we were getting was “Login failed for user: domain\user” in the event logs

Comment and share

I don’t know if anyone else has experienced this, but the Microsoft documentation provides this as an example for the above command

1
Psconfig –cmd configdb –create –server _servername_ –database _databasename_ –user _username_ –password _userpassword_ –admincontentdatabase _databasename_

I tried running this and kept getting the following error

1
The -create command is invalid

This drove me made until I removed the “-“ from the beginning of the create parameter and then I got the following error

1
The -server command is invalid

My amazing mind realized that a pattern was emerging and I went ahead and removed all the dashes from the parameters to end up with the following command.

1
Psconfig –cmd configdb create server _servername_ database _databasename_ user _username_ password _userpassword_ admincontentdatabase _databasename_

Hey Presto my “SharePoint Products and Technologies Configuration Wizard” began chugging away

Comment and share

Author's picture

Toby Statham

Independent Office 365 / SharePoint Specialist and an associate consultant at aiimi.com, an Information Management company.

Independent Office 365 / SharePoint Specialist

Brighton, UK