Complete SharePoint and .NET

Blog on ASP.NET, SharePoint (WSS 2.0, WSS 3.0, SPS 2003, MOSS 2007) and other Microsoft Web Technologies.

Sharepoint IIS Error - You are not authorized to view this page

clock October 9, 2009 12:06 by author Admin

INTRODUCTION

I can access my Sharepoint site from remote machine's browser but not from the Sharepoint machine that hosts that site. I keep getting authentication box whenever I tried to access the Sharepoint site and its sub-sites/sub-folders/pages.

The fix is actually to disable security check on loopback in registry.

http://support.microsoft.com/kb/896861

 

Hope this helps,

Tommy



Sharepoint Farm - Document Library Returns Incorrect Document Version on One WFE but OK on Another WFE

clock October 9, 2009 12:04 by author Admin

INTRODUCTION

I'm currently working at a client site who has the following Sharepoint Intranet farm configuration:
- 2 Web Front End (WFE) servers
- 1 Central Admin server
- 1 Indexing server
- 1 Database

There is a load balancer that should balance the load between the 2 WFE however it doesn't work properly. Somehow, the load balancer always points to the first WFE. Therefore, if you access http://intranet/ it always points to the first WFE.

The Intranet works OK everyday until one point few months ago it started to return the incorrect version of the document. For example, you upload a document and check-in as version 0.1. When you navigate to the document via the URL directly (eg. http://intranet/DocumentLibrary/MyDoc.doc) it returns you version 0.1 which is correct. Then you upload a new version of the document, override the old version and check-in to become version 0.2. Now, when you navigate directly to the URL of the document, somehow Sharepoint returns it with version 0.1. What's strange is, this only happens on the first WFE. If you force-point http://intranet/ to the second WFE via editing HOSTS file, you get the correct version of the document!

We have looked at this problem for quiet some time now and we finally resolve it after few weeks of investigation. We know that there must be something different (configuration, etc) on first WFE compared to the second one because the second WFE always returns the correct version of the document. Therefore, this is what we've done:
- Checking and comparing IIS settings
- Checking and comparing web.config settings
- Checking Sharepoint cache settings
- Checking load balancer cache settings
- Checking the actual document data in SP database! Yep, we actually went into Sharepoint DB and looked for that particular document in AllDocs table and the data that is stored in the DB is actually correct (ie. the newer version is stored correctly)

 

SOLUTION

So, what's the problem then? The DB clearly stores the latest version of the document so there is no reason for Sharepoint to return the incorrect version of the document. After further investigation we actually found out that the problem was actually with the BLOB CACHE settings! In web.config someone has turned on BLOBCACHE and somehow the cached documents in first WFE aren't synced with second WFE's. When we clear the BLOB CACHE folder of first WFE, it starts to return the CORRECT version of the document! So from this moment on, we will ensure that the blob cache folder content is synched between first WFE and second WFE.

If anyone has ever had the same problem, this may help.

 

Cheers,
Tommy



Renaming Sharepoint Virtual Machines (VPC, VM, Hyper-V)

clock October 9, 2009 04:03 by author Admin

INTRODUCTION

Hi everyone, I've read several blogs about using virtualised environment (VE) for Sharepoint development which I totally agree. I'm not currently using it because I'm using a laptop and you know what the VE performance is like on laptops. But anyway, having said that, few days ago I was asked to create VE image which can be distributed to developers. I'm working at a client site where I have to use powerful desktops (hence VE is a viable solution).

I've got no problem at all creating the image until I need to distribute it to the developers. If the developers turn on the image at the same time and they set the network settings of VPC/VM/Hyper-V to allow the image to be visible on the network, we will then have a lot of computer name collisions! The developer who turns on the image first will win of course.

So, we have to go through the VE machine renaming process. I've read several blogs such as http://www.bloggix.com/blogs/microsoft/archive/2009/05/18/rename-your-moss-installed-virtual-machine-vpc-vmware.aspx. but I couldn't get it working. In this opportunity I want to share the steps I took (especially the steps that were not described in that blog article) and if you guys have done it differently, please share them as well.

Note: My VE image on this blog article is at the step where I was just finished install MOSS and even not yet activating services, creating sites for SSP and My Site and creating SSP itself.

 

THE STEPS

- Login to VE image using the account you installed MOSS/Sharepoint in the first place, mine is OLDMACHINENAME\SP_Admin. The account I was using as the farm service information was OLDMACHINENAME\SP_Farm.

- Go to Central Admin -> Operations -> Alternate Access Mappings and set the web application to Central Admin. Set the URL (mine is http://oldmachinename:6000/) to the new machine name (http://newmachinename:6000/).

- Run stsadm -o renameserver -oldservername oldmachinename -newservername newmachinename

- Go to My Computer -> Right click, Properties -> Change the computer name to newmachinename

- Restart

- Run stsadm -o updatefarmcredentials -userlogin NEWMACHINENAME\sp_admin -password yourspadminpassword

- Go to SQL Management Studio and open Security -> Logins folder. You will see groups/users with OLDMACHINENAME reference such as OLDMACHINENAME\SQLServer2005MSFTEUser$OLDMACHINENAME$MSSQLSERVER. Rename all of them to use NEWMACHINENAME as the domain information (Note: Do NOT modify the name, just modify the domain).

- Remove and re-add NEWMACHINENAME\SP_Farm from Central Admin Content DB and Sharepoint_Config database.

- Open Registry Editor (regedit.exe) then go to HKLM\Software\Microsoft\Microsoft SQL Server\90\Machines and modify the OriginalMachineNameKey value to the new machine name.

- Open Central Admin and go to Operations -> Update Farm Administrators. Remove and re-add NEWMACHINENAME\SP_Farm and NEWMACHINENAME\SP_Admin. When doing this you will see the display name is still using old machine name. That's OK but the account reference is now referencing the new machine name. Just click on SP_Admin or SP_Farm user and you will see that the reference has now been updated to NEWMACHINENAME\SP_Admin and NEWMACHINENAME\SP_Farm respectively.

- Go to Application Management -> Site Collection Administrators. Modify the Central Admin web application's site collection administrator to NEWMACHINENAME\SP_Admin. This setting is used by Sharepoint to create SSP. If you don't update this, your SSP creation will fail.

- Go to Operations -> Services on server and Activate all services (search, etc)

- Create 2 Sharepoint websites for SSP and MySite

- Create SSP --> I used to get a failed message when I didn't do these steps correctly. Therefore, if you get a Successful message after this point then you're good.

 

Hope this helps,
Tommy



MOSS Manual Navigation Links Are Static - DANGEROUS

clock October 9, 2009 04:02 by author Admin

INTRODUCTION

We just completed a MOSS server rebuild project which we managed to align both Production and Test environments with exactly the same topology and configurations. We installed using the exactly the same user accounts, configurations and even the list of features and solutions. After we configured the farm, we then took Production's latest database backup and restore it in Test. Everything worked perfectly except one thing:

The manual links in navigation menu items are not updated.

You know that in MOSS you can go to Site Actions -> Site Settings -> Modify Navigation, right? And we can create external/manual links, correct? The problem is, some of the users have created links that point to a document/page within MOSS but using static URL instead of relative. The problem is, these manual/static links are NOT updated after database restore to a different environment.

For example:
http://intranet/Pages/Home.aspx is meant to be updated to http://test-intranet/Pages/Home.aspx.

This will create a huge risk because we've actually had problem before when user thought they're still in Test but they're actually in Production. And guess what...he deleted a site that he thought was in Test.

SOLUTION

Anyway, to cut the long story short, I've managed to come up with a very simple SQL statement (which some of you must have known anyway) that can allow us to modify static links into relative links:

update navnodes set url = REPLACE ( url , 'http://intranet' , '' ) where url like '%http://intranet%'

The above statement will update ALL static links in navnodes table (which is the table used by MOSS navigation control) and remove any static reference to any page/document within MOSS.

 

WHAT LINKS ARE UPDATED BY DB RESTORE?

- Links within content query web-part or page content field

- Automatic links that are created by MOSS in navigation items as a result of creating a page/sub-site

 

WHAT LINKS ARE NOT UPDATED?

- Manual/static links in MOSS Navigation Items although they may point to a page/document within Sharepoint itself

 

Hope this helps,
Tommy



MOSS BDC, Search and Web Service: Modifying Search Results Web-Part

clock October 9, 2009 04:01 by author Admin

INTRODUCTION

This post is related to my other post regarding securing search results for currently-logged-in user in Sharepoint when querying BDC Web Service entity:
http://www.sharepointblogs.com/tommysegoro/archive/2008/09/17/moss-bdc-search-and-web-service-securing-the-search-results-for-particular-user.aspx

I'm now interested in how I can modify the search results web-part to display the actual entity name. OOTB it will give you EntityType.aspx. So if your entity type is called FileEntity the search results web-part will render FileEntity.aspx everywhere! I want to render Filename1.aspx, Filename2.aspx, etc.

OOTB:

 

THE SOLUTION

1. Add a meta-data property mapping in SSP. Let's give it a name: TommyFilename and add mapping to the BDC crawled property. 

2. Edit the Search Core Results Web-Part -> Results Query Options -> Selected Columns. Add your custom managed-property in here.

<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">    <Columns>        <Column Name="TommyFilename"/><Column Name="WorkId"/>        <Column Name="Rank"/>        <Column Name="Title"/>        <Column Name="Author"/>        <Column Name="Size"/>        <Column Name="Path"/>        <Column Name="Description"/>        <Column Name="Write"/>        <Column Name="SiteName"/>        <Column Name="CollapsingStatus"/>        <Column Name="HitHighlightedSummary"/>        <Column Name="HitHighlightedProperties"/>        <Column Name="ContentClass"/>        <Column Name="IsDocument"/>        <Column Name="PictureThumbnailURL"/>    </Columns>    </root>   

3. Edit the Search Core Results Web-Part XSL under Data View Properties. Go to around line 111:

OOTB:
  <span class="srch-Title">
   <a href="{$url}" id="{concat('CSR_',$id)}" title="{$url}">
    <xsl:choose>
     <xsl:when test="hithighlightedproperties/HHTitle[. != '']">
         <xsl:call-template name="HitHighlighting">
          <xsl:with-param name="hh" select="hithighlightedproperties/HHTitle" />
         </xsl:call-template>  
     </xsl:when>
     <xsl:otherwise><xsl:value-of select="title"/></xsl:otherwise>
    </xsl:choose>
   </a>
    <br/>
   </span>

Modify that to:
  <span class="srch-Title">
   <a href="{$url}" id="{concat('CSR_',$id)}" title="{$url}">
    <xsl:choose>
     <xsl:when test="tommyfilename[. != '']">
         <xsl:value-of select="tommyfilename"/>
     </xsl:when>
     <xsl:otherwise><xsl:value-of select="title"/></xsl:otherwise>
    </xsl:choose>
   </a>
    <br/>
   </span>

NOTE: The property name HAS TO BE LOWER CASE! Remember we named it TommyFilename before, didn't we? It won't work if you use TommyFilename but it will work if you use tommyfilename.

That's it! You can then see below:

 

APPENDIX

To check what XML it returns, edit that XSL Data-View Properties again and replace the content with:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="
http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<xsl:copy-of select="*"/>
</xsl:template>
</xsl:stylesheet>

Save the web-part then view HTML Source of the page then you can see something like below:

<All_Results>
  <Result>
    <id>1</id>
    <tommyfilename>charlie_and_the_chocolate_factory_06.jpg</tommyfilename>
    <workid>5</workid>
    <rank>819</rank>
    <title>FileEntity.aspx</title>
    <author></author>
    <size>0</size>

...................

The custom property is actually recognized using ALL lower case naming convention. That is why TommyFilename will not work.

 

Hope this helps,
Tommy



MOSS 2007 Search Crawling Error - Access Denied

clock October 9, 2009 04:00 by author Admin

INTRODUCTION

Last week I had this problem where search service couldn't index my Sharepoint site. It said that access is denied and asked me to make sure that I'm using the correct content access account. The exact error message was as below:

Access is denied. Check that the Default Content Access Account has access to this content, or add a crawl rule to crawl this content. (The item was deleted because it was either not found or the crawler was denied access to it.)

I have done the following:
- Add the default content access account as a Farm Administrator
- Add the default content access account as a Site Collection Administrator
- Add the default content access account as SYSADMIN on ALL Sharepoint-related tables in SQL Server (including Sharepoint_Config)
- Add the default content access account as a local Administrator

I've done everything and given full access to the default content access account to everything but yet I still couldn't get rid of the problem.

 

SOLUTION

The solution is somehow something not too related to Sharepoint. Please check out http://support.microsoft.com/kb/896861.

That's it!

I've got the following infrastructure configuration
- Proxy is set in Internet Explorer for Internet access although accessing the Intranet should bypass proxy.
- To access local resource (ie. Sharepoint instance on my local machine) I can't edit the HOSTS file freely simply because we have proxy setup. Therefore, I have to use mydomain.local suffix (eg. http://intranet-devlocal.mydomain.local/).
- When I configure the content source to use http://intranet-devlocal.mydomain.local/, it says that it can't find the Sharepoint site.
- So I had to then create an alternate access mapping with the name http://intranet-devlocal/. It could then find the Sharepoint site but I then had that access denied error.

 

Hope that this helps everyone who experiences the same problem.

Tommy



Microsoft.Office.Server.UserProfiles.UserProfileException: Failed to obtain crawl status

clock October 9, 2009 03:58 by author Admin

INTRODUCTION

The client I'm currently working has the following farm configuration:
- 1 WFE
- 1 Central Admin + Indexing
- 1 DB

They have both Test and Prod environments configured with the same number of servers.

After a while, the client starts to find out that although User Profile Import service is running successfully nightly and the data is updated correctly from AD, but somehow the WSS Profile Page is not updated with the latest AD data. There is someone whose job title is updated in AD and it hasn't been replicated in WSS Profile Page although this person's My Site page and search results page are already updated with the correct data. This problem happens in both Test and Prod.

After a day worth of investigation I found out that the secure certificate for Office Server Web Services web site needs updating.

Below are some of the warnings in Event Viewer:

==

 

 

 

==

 

WHAT DOES IT CAUSE?

With MOSS there are two profile "area" that needs to be updated, MOSS Profile and WSS Profile page.

My Sites and search results page are displaying information from MOSS Profile Page but Contact Details web-part and People And Groups -> All People display information from WSS Profile Page.

Because of this issue, the WSS Profile Page is not updated and causing Contact Details web-part to display incorrect (old) information about someone's profile.

 

HOW DO YOU SOLVE IT?

After reading some blogs about the error, I finally came up with a solution:

1. Use SelfSSL to update Office Server Web Services web site. Run the following command:
selfssl /S:<site ID of Office Web Services - mine is 951338967> /V:999999

2. Perform full User Profile import in SSP

3. Run stsadm -o sync -deleteolddatabases 0 --> This is to remove the failed-to-sync database information (don't worry it's safe. It's not deleting the actual content database or anything like that)

3. Run stsadm -o sync -sweeptiming m:2 -synctiming m:3 --> This is to sync the WSS Profile Page every 2 minutes, we'll change this later to every day or every 12 hours once we've known that we've solved the problem.

4. Wait for 2-3 minutes.

5. Open Event Viewer and you shouldn't see any more of the above warnings.

6. Go to Central Admin -> Operations -> Timer Job Status -> Profile Synchronization and Quick Profile Synchronization, they will run successfully.

7. DONE, run stsadm -o sync -sweeptiming h:12 -synctiming h:12 --> To set the WSS Profile Update every 12 hours.

 

That's it.

Hope this helps,
Tommy

 

Microsoft.Office.Server.UserProfiles.UserProfileException: Failed to obtain crawl status. ---> System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a send. ---> System.IO.IOException: Authentication failed because the remote party has closed the transport stream.

Microsoft.Office.Server.UserProfiles.UserProfileException: Failed to obtain crawl status. ---> System.Net.WebException: The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel. ---> System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure.



Managing Risks in Sharepoint 3 - Solutions and Features Deployment

clock October 8, 2009 22:37 by author Admin

INTRODUCTION

This is a series:
- Managing Risks in Sharepoint 1 - Aligning the Environments
- Managing Risks in Sharepoint 2 - User Permissions

In the previous articles I've discussed about aligning the environments and ensuring user permissions. In this opportunity I would like to discuss more on the development side of things in terms of how you should structure your project, etc.

When writing custom code for Sharepoint (be it web-parts, custom controls, etc), there is a chance for developers to use third party DLLs. Not only that, you may actually download the whole third party's WSPs. In this article, I will discuss how we should develop our code including how we should manage third party DLLs and solutions. Once again, please also share your experience.

I've been in a project where no one actually knows what version of the code deployed in Production is. Even the third party DLLs/controls, when I tried to get latest version from vendor's website, they actually appear to be a different version than the ones deployed in Prod.

What's even worse is, I've tried "Get Latest" from Visual Source Safe hoping that I downloaded the right code, but it's actually not! The previous developer has managed to modify the code only on his local machine (and disconnected it from VSS) and deploy it straight away to Prod without re-checking the code back in. The machine that this developer was using was wiped out because he was only a temporary contractor. So then we had to use Reflector to open the DLL in Prod and made necessary changes in VSS.

Having all these experience, I think it's important to discuss how we can minimize development and deployment risks.

Managing Risks in Sharepoint 3 - Solutions and Features Deployment

Whenever I do Sharepoint customization project, I will always go down the Solutions and Features Deployment path. I've discussed about this in my other development articles. I know it can be a more complicated process than just doing everything straight from the GUI but it will save us time later on maintaining it. And in fact, throughout my experience, it can minimize the risk of deploying/storing incorrect version of code. There are things that we have to get right though but let me explain more.

We're minimizing risks (and not removing risks, there are always risks) when:

1. Our deployment document is tight

The very first step to minimize development risk is to get our deployment document tight. Make sure that we write down what we're developing and what we're planning to deploy and also where to get the deployment files from. This information includes (and not limited to):
- The custom solutions we're developing
- Shared DLLs/assemblies that we reference within our project
- Third party DLLs/assemblies that we reference within our project
- Third party WSP/features that we may deploy

I normally come up with two documents for every deployment: Deployment Manual and Release Manual.

The Deployment Manual document contains information on HOW TO DEPLOY the code (it will mention the stsadm command to perform, etc). Imagine if you're purchasing Microsoft Word, there is a help manual on how to install ie (ie. double click on the exe, follow the prompts, etc). That's exactly it.

The Release Manual document contains HOW TO GET the code to deploy. This document will be for internal use only. It will mention something like "Get Latest from VSS on the such and such node, open in Visual Studio and click Build" or "Go to http://thirdpartywebsite.com/Downloads and download Version 3.0 of ControlX", etc.

If we can get these documents produced every time we do deployment then everyone will have the knowledge on what is actually deployed in Production and where to get the files from. This way, we have minimized deployment risks.

2. We structure our TFS/VSS correctly 

I've mentioned to you above that there was a developer who disconnected from VSS and start modifying the code directly then deploy that code to Prod without re-adding back to VSS. His reason was he needed to make a small change to current production code and didn't want to create a new branch in VSS because the current code in VSS has already got new functionalities and it will confuse the team later on if he created too many nodes of the same code (it actually confuses everyone afterwards anyway). In VSS we don't have such a good merging system unfortunately, but in TFS we do and using the merging functionality of TFS, it can help us handling the typical scenario above. I normally structure my TFS like this (for every project):

Project Root
------ Development
------ Main
------ Production
---------- v1.0
---------- v1.1
---------- v1.2
etc

- I normally do the development in Development node then when it's ready for Iteration 1 testing, I branch to Main.
- I keep developing more and more functionalities in Development while the code from Main is tested by Testers/Project Managers.
- When the bug report comes, I fix the bugs in Main.
- I then merge from Main to Development so that Development now contains new functionalities plus bug fixes from Iteration 1 report.
- When I'm ready for Iteration 2 testing, I merge from Development back to Main so that now Main contains new functionalities and bug fixes and it's ready for Iteration 2 testing.
- The process repeats over and over again until it's ready for release.
- When it's ready for release to Production, I would branch from Main to Production -> Version node.

My Release Manual will then include information on how to build the code in Production/Version node and my Deployment Manual will then include information on how to deploy the built code. After I do this, I'm pretty comfortable that I've now captured all information about a particular release including what version of code is currently in Prod, etc.

When I need to do another major release, I will create a new branch under Production with a new Version number and I will update my Release Manual and Deployment Manual. You can find this TFS structure in Microsoft's website. I found by structuring my TFS right, I minimize my development and deployment risks and it's pretty clear which node in TFS has the latest source, etc and I know exactly which part of the Production branch is currently in Prod.

Going back to VSS, since it doesn't have any merging capabilities, labelling would be the way to go. With VSS it's a bit tricky to create versions of the code and I don't think it's possible to perform Dev, Main, Prod branch/merge as TFS.

3. Our customization code ALWAYS lives in Visual Studio and Source Control and always strong-name your assemblies

I will ALWAYS deploy Sharepoint customizations using Features and Solutions because it means that all Sharepoint customizations I'm developing live in source control application which then makes it easier to maintain and share. Please read my Development Best Practice articles. Customization code includes:
- My code
- Third party code
- Third party images, CSS, javascripts
- etc that is not Sharepoint OOTB

Strong naming your assemblies is always a good practice even when you're doing development with general .NET application. Sharepoint makes a huge use of assemblies in GAC and you can only deploy your DLLs in GAC if they're strong named (including third parties'). What's interesting is, not all third party assemblies are strong-named. Therefore, ensure that you strong name all assemblies that need to be deployed to your farm including third parties'.

To strong-name third party assemblies:
http://social.msdn.microsoft.com/Forums/en-US/clr/thread/35930958-9775-4e56-bd38-0362d124ffc4

4. Always guard your code from memory-leaks

Whenever you reference SPSite and SPWeb instance ALWAYS guard them with "using" statement from memory leaks. For example:

using(SPSite site = new SPSite(http://url/))
{
       using(SPWeb web = site.OpenWeb())
       {

       }
}

There are exceptions though:

If you're referencing SPWeb, SPSite or RootWeb from SPContext.Current, do NOT dispose or you'll get an error. The following code does NOT have memory leaks anyway:

SPWeb web = SPContext.Current.Web; --> GOOD
SPSite site = web.Site; --> GOOD
SPWeb rootWeb = web.Site.RootWeb; --> GOOD

Use SPDisposeCheck tool (http://blogs.msdn.com/sharepoint/archive/2008/11/12/announcing-spdisposecheck-tool-for-sharepoint-developers.aspx) to check for memory leaks within your custom assemblies.

5. Always check that you're NOT deploying ANY of Microsoft's DLL (such as Search DLL, etc)

When you're adding a reference to Microsoft.Sharepoint.dll in Visual Studio, it's going to add reference to Microsoft.Sharepoint.Search.dll.

If you're adding reference to Microsoft.Sharepoint.Publishing.dll, it's going to add reference to Microsoft.Office.Server.Search.dll, Microsoft.Sharepoint.Portal.SingleSignOn.dll and ssocli.dll.

Make sure you REMOVE all of them from your WSP (if they're included by your automated built commands such as STSDEV, WSPBuilder, etc) otherwise your farm will break because these DLLs are overridden by update patches in the future and if you deploy them, Sharepoint will get confused in terms of which version to use.

 

CONCLUSION

They're so far the things that I will be aware of when doing Sharepoint development and deployment. Please share your thoughts.

Tommy



Managing Risks in Sharepoint 2 - User Permissions

clock October 8, 2009 22:35 by author Admin

INTRODUCTION

This is a series:
- Managing Risks in Sharepoint 1 - Aligning the Environments

In the previous article I mentioned about how quickly the content in our development/Test environments will be outdated. Sharepoint content database consists of:
- Sites
- User accounts added to Sharepoint
- Site Settings
- Pages
- Documents and list items
- Content types
- Meta-data
- Features activated
- etc

Within a day there may be a lot of activities happening in your Sharepoint farm including users uploading new documents, sub-sites are created, users are added/removed to/from SP, etc. In this opportunity I want to discuss about user permissions because if we are not careful, assigning correct permission to the wrong users will end up creating risks for your Sharepoint environment (or even breaking it).

 

Managing Risks in Sharepoint 2 - User Permissions

1. "Deny all then allow" rather than "allow all then deny"

By default I would deny EVERYONE then I would start giving permission to those who need to have access to Sharepoint.

 

2. Using AD Group and not "authenticated users"

Thou shall NOT give NT_AUTHORITY\authenticated_users a READ access to your portal. Why? Because it means that every domain user (ie. all users who have an AD account) will have read access to your portal. This can be dangerous.

For example, user A is a contractor, he has a temporary AD account. Logically, you would disable his account once his contract is finished but in this scenario you can't because you are using a third-party software or application that requires his AD account to be active. Since his AD account is still active, he will still be able access your portal. You want to remove him from everything else (including Portal) except the application that requires his AD account to be active. You can't do that, because at the moment you have "authenticated users" added as the Reader of your portal. If you remove "authenticated users" you would deny other people's access. I'm speaking from my own experience. At the moment, the farm I'm managing is a bit of a nightmare. We've had several complaints from people who suddenly lost their access simply because we tried to remove "authenticated users" from the Readers group.

So, if I'm given a second chance to rebuild the Portal, I would start with creating an Employees group in AD. Let's say it's called MYDOMAIN\Employees. Within it I will add ALL employees' AD accounts (including contractors'). I would then add this domain group to Sharepoint. When there is a contractor who's just finished his contract, I can simply remove him from this AD group and he will no longer have access to the Sharepoint portal.

Note: Making sure that you "wrap" your AD group in a Sharepoint group. Sometimes you would have a nested AD Group within an AD group. Sharepoint will have problems (especially with the Audience functionality) if this is the case. There is a patch that Microsoft releases that will fix this nested AD group problem but for it to work you have to add the AD group (that has nested AD groups) into a Sharepoint group.

So, I would create an Employees Sharepoint group that has READ permission then I'll add the MYDOMAIN\Employees group to this SP group.

 

3. Don't let user modifying your content types and meta-data

ALL custom meta-data and content-types HAVE TO BE - in some way - DOCUMENTED! It can be done either through manual documentation or deployed through Visual Studio using solutions/features deployment. I personally use feature and solution deployment for all of my custom content types and features. I will NOT give general users (even site/department owners/managers) permission to add content-types and meta-data. From my experience with Sharepoint, content-types and meta-data are the core part of your farm. I've had lots of problems before when content-types and meta-data are not defined correctly.

At this very moment, I can no longer use the "Add from existing site column" functionality from the GUI because I got an error message whenever I'm trying to do so. The error message is something like "An object cannot have the same ID" or something like that. At the moment, whenever I want to attach an existing site column to an existing content type, I have to use the object model.

Once again I'm speaking through my experience. I will not let general employees (unless SP developers/administrators) access to add custom content-type and meta-data.

 

4. Break permission inheritance

Based on the "deny all then allow" principal, I would not hesitant to break permission inheritance for departmental sites. This means that ALL other users (other than deparmental users) are denied access unless stated otherwise. For example, I created a HR site, I will deny ALL users but HR people. I will only give general users access to some (or little) part of HR site that are meant to be shown to public.

Once again, always use an AD group wrapped in a Sharepoint group. I would never add an individual user to Sharepoint unless it's very-very needed because security maintenance will not be easy (ie. you won't know/remember who has access to what if you start adding individual users to Sharepoint).

Note: It's better to accidentally hide public documents rather than deliberately - by default - show private documents. Your documentation (in terms of who has access to what) needs to also be very complete and tight.

 

CONCLUSIONS

So there you go. Please share your experience. On the next series I would talk more about the development side of things.

 

Cheers,
Tommy



Managing Risks in Sharepoint 1 - Aligning the Environments

clock October 8, 2009 22:33 by author Admin

INTRODUCTION

I just want to share with you my experience in managing Sharepoint environments (both server and custom code). Before, I came from a development background and purely think as a developer. As a developer, I used to think that as long as my code is bug-free and memory-leak-free then I'm safe.

Now, I've got some experience in managing the servers, I can share with you the things that we have to be aware of more than just having a bug-free and memory-leak-free code. This article will (as usual) come in series so if you're interested, please stay tuned and read the series. I also would also like to see comments and sharings from you so that we can all learn from each other.

 

MANAGING RISKS 1: KEEP YOUR ENVIRONMENTS ALIGNED

The Sharepoint environment I'm currently working on has the following server topology:

- 1 DB
- 2 WFE
- 1 Central Admin
- 1 Indexing Server

The same topology was also created for Test (yes, it's EXTREMELY important to have a Test environment for Sharepoint just like general .NET development). The goal is whenever we deploy things (code, solutions, features, etc) to Test, we would expect the same results in Production (ie. if it fails in Test then it will fail in Prod and vice-versa).

The idea is great but the problem is, this client's Test and Production weren't installed by the same person. One person setup the Prod and another person setup Test. Hence, we now have different settings and configurations in both Test and Prod.

This will create a huge risk, because if we deploy things in Test, we can never guarantee that the same would succeed in Production even if they successfully pass testings in Test.

Therefore, the very-very first step I would do is to ensure that both Test and Production are aligned. These are (and not limited to):
- The server topology
- The user accounts used to run MOSS/Sharepoint services (Search, SSP, etc etc)
- The configurations (SSP config, Central Admin config, email settings, etc)
- The solutions installed
- The features activated
- The code and DLL deployed (even third party DLLs such as stsadm extensions, etc)
- Web.config settings
- IIS settings
- SQL server settings
- AD settings for each user account used in Test and Prod
- The resource settings for both Prod and Test (RAM, Hard Disks, Processor Utilization, etc)

By ensuring that the settings above are the same for both Test and Prod, we can now expect that the deployment results will be exactly the same. If your deployment breaks in Test then it will most likely break in Production.

 

TAKE IT FURTHER

I would actually like to take this further. Even the developers' machine - although it's impossible to create the topology within each developer's machine - is at least installed using Test/Prod user accounts and configured using exactly the same configuration. This has worked really-really well for me. I can now be very confident that whatever fails on my machine will also fail in Test and Prod and vice versa (whatever succeeds on my machine will also succeed in Test and Prod).

 

DOCUMENTATION

This is the bit that I HATE! :) As a developer, there is nothing worse than writing a documentation. Anyway, it's EXTREMELY important to document the setup process for both Test and Prod. Take screenshots as you go through each step and document them. You can use MS Word to Copy Paste things easily or even OneNote with its screen clipping feature. It's really-really handy. Just like taking your wedding photographs for memory, that's how valuable documentation is for us.

From my experience, I will forget within one day what steps I took to setup MOSS. So guys...get your documentation tight.

 

STILL THERE IS ONE RISK LEFT

The CONTENT DATABASE is the major risk. You would never be able to always align content database. You will be surprised how quickly the content in your machine and in Test are outdated. People will upload more and more documents in Prod and even worse, some of the users are stupid enough to create content types and meta-data directly in Prod!

I'll discuss about this more later.

 

Hope this helps and please stay tuned for next series,
Tommy