Why passing SPBasePermissions.FullMask to SPContext.Current.Web.DoesUserHavePermissions() instead of SPBasePermissions.ManageWeb when you’re trying to determine if a user is a SPWeb administrator, is a bad idea…

Written by Cornelius J. van Dyk on . Posted in Blog

OK, so the title of this post could also have been “Best Practices for Determining if a User is a SPWeb Administrator”, but then the search engines wouldn’t catch the post for all those unfortunate enough to be searching for FullMask or DoesUserHavePermissions() in the future.  The Problem OK, OK, in all seriousness though.  There are a lot of content out there that recommend that people simply use SPContext.Current.Web.DoesUserHavePermissions(SPBasePermissions.FullMask) when trying to determine if the current user has Administrator rights to the current web site (SPWeb).  This is all good and well, but it assumed that you have NEVER customized your web application available permissions list i.e. your effective base permissions.  So what’s the problem, you may be wondering… The problem is in the way SharePoint behaves when you do indeed customize your permissions for the web app.  If you dive into SharePoint Central Administration under Central Administration > Application Management > Permissions for Web Application you will find all the SharePoint base permissions and the ability to turn any one of these permissions off by simply unchecking it’s checkbox and then clicking the OK button… all except for one… FullMask.  If you were to uncheck say UseClientIntegration (in order to disable desktop apps such as Office or SPD from editing content directly on the server) and then save that state, SharePoint will do two things.

  1. It will remove the UseClientIntegration bit flag from the permissions bit mask and
  2. because total full control is no longer possible for the web app, it will also remove the FullMask bit flag from the mask.
That’s all fine and dandy until you go and add the permissions back again.  If you now recheck the UseClientIntegration checkbox and clicked OK, you’d expect SharePoint to add the bit flag back to the permissions mask again and it does do that, but for the UseClientIntegration flag only.  If you’re expecting it to also reset the FullMask flag, you’ll be disappointed.   This appears, at least in my mind, to be a bug in the SharePoint core code.  Yes, yes, I know it’s most probably “working as designed” or “behaving as intended”   , but in my mind the absence of any UI way to reset the FullMask flag, as well as the sparse documentation surrounding it, this just feels like a bug and not an intended feature.  So to be clear… SharePoint does not reset the FullMask security bit once permissions on the web app was customized! Now as far as SharePoint UI and everything else an end user sees is concerned, everything is working perfectly as per usual with no ill effects.  It’s only when you drop into the world of the SharePoint developer that things can become hairy.  In case you were wondering, here’s the base permissions bit mask as returned when the FullMask bit is set: 7FFFFFFFFFFFFFFF And once customized, even with all permissions enabled again, the bit mask returns rather as a union of all aggregated permissions and looks like this: 400001F07FFF1BFF If a SharePoint developer used the DoesUserHavePermissions() method and passed the FullMask flag to it in hopes of identifying an admin user, the method will always return False because the FullMask bit is never reset again.  So using SPContext.Current.Web.DoesUserHavePermissions(SPBasePermissions.FullMask)simply isn’t reliable for admin checking in code.  Fortunately, the failure occurs on the safe side i.e. it is reporting an Admin to simply not be an Admin rather than reporting a User to be an Admin so most probably your app doesn’t break, but is simply not quite working as expected. The Solution So then, you ask, what exactly would be the best practice for determining if the current user is an admin? You may be tempted to use code like this ((ISecurableObject)SPContext.Current.Web).DoesUserHavePermissions((SPBasePermissions)Microsoft.SharePoint.SPPermissionGroup.WebDesigner)) and then use SPPermissionGroup.Administrator as the target, but since the value of Administrator in this case is –1 and the DoesUserHavePermissions() method is looking for aulong value, it will epically fail on you, even if you were to “duck punch” it with up/down casts like (SPBasePermissions)(Object)… Rather, the proper way to check if a user has admin rights to the current SPWeb, regardless of source (web, site collection or CA policy), is as follows: ((ISecurableObject)SPContext.Current.Web).DoesUserHavePermissions(SPBasePermissions.ManageWeb) By checking if the user has the ManageWeb security bit set, you will always get the proper result back.  Using FullMask is akin to trying to remove a wart with a canon.  ManageWeb is more like a scalpel. OK, I broke it.  Now what? If you’re in the boat where you’ve already “broken” the FullMask bit, don’t despair.  There is indeed hope.  Luckily some smart people like MOSS MVP Gary LaPointe, have struggled with this problem before and have created clever workarounds for this. To reset the FullMask security bit, you can use the following code courtesy of Gary:
SPWebApplication wa = SPWebApplication.Lookup(new Uri(url)); 
wa.RightsMask = wa.RightsMask | SPBasePermissions.FullMask;
wa.Update()
If you’re adventurous, you can go ahead and write an app or even your own STSADM extension for that, but if you’re like me, you’ll be happy to know that Gary already did that!  Simply go and get his MOSS or WSS extension methods for STSADM package from his Download Page.  It comes all nicely packaged in a .wsp ready for deployment into your SharePoint environment.  The STSADM operation you need is: gl-enableuserpermissionforwebapp and the proper syntax for it is as follows: stsadm -o gl-enableuserpermissionforwebapp -fullmask -url http://YourWebAppURL So there you go.  The best practice for determining if a user is an administrator for a site and a way to fix it if your code is using FullMask and broke because someone played with permissions. Enjoy…

Cheers
C




image

Tags: , , , ,

Trackback from your site.

Cornelius J. van Dyk

Born and raised in South Africa during the 70's I got my start in computers when a game on my Sinclair ZX Spectrum crashed, revealing it's BASIC source code. The ZX had a whopping 48K of memory which was considered to be a lot in the Commodore Vic20 era, but more importantly, it had BASIC built into the soft touch keyboard. Teaching myself to program, I coded my first commercial program at age 15.

After graduating high school at 17, I joined the South African Air Force, graduating the Academy and becoming a Pilot with the rank of First Lieutenant by age 20. After serving my country for six years, I made my way back into computer software.

Continuing my education, I graduated Suma Cum Laude from the Computer Training Institute before joining First National Bank where my work won the Smithsonian Award for Technological Innovation in the field of Banking and Insurance. Soon I met Will Coleman from Amdahl SA, who introduced me to a little known programming language named Huron/ObjectStar. As fate would have it, this unknown language and Y2K brought me to the USA in 1998.

I got involved with SharePoint after playing around with the Beta for SharePoint Portal Server 2003. Leaving my career at Rexnord to become a consultant in 2004, I was first awarded the Microsoft Most Valuable Professional Award for SharePoint in 2005, becoming only the 9th MVP for WSS at the time. I fulfilled a life long dream by pledging allegiance to the Flag as a US citizen in 2006. I met the love of my life and became a private consultant in 2008. I was honored to receive my ninth MVP award for SharePoint Server in 2013.

Leave a comment

You must be logged in to post a comment.