1

I'm handling the WebProvisioned event in order to add and deploy a solution that's relevant to the site being created. The solution is being created dynamically based on parameters of the site but for simplicity let's assume it's just one specific solution that I need to deploy - the problems I'm having are reproduced in this scenario too.

In the event receiver code I call:

SPSolution mySolution = SPFarm.Local.Solutions.Add(@"<path>\SampleSolution.wsp");

And I get:

System.Security.SecurityException: Access denied. at Microsoft.SharePoint.Administration.SPPersistedObject.BaseUpdate() at Microsoft.SharePoint.Administration.SPPersistedChildCollection1.Add(T newObj, Boolean ensure) at Microsoft.SharePoint.Administration.SPPersistedChildCollection1.Add(T newObj) at Microsoft.SharePoint.Administration.SPSolutionCollection.Add(String path, String name, UInt32 lcid, Boolean isRestore) at Microsoft.SharePoint.Administration.SPSolutionCollection.Add(String path) at DOASiteInitReceiver.DOASiteProvisioned.DOASiteProvisionedReceiver.DeployAndActivate(String featurePath, String packageFilename, Guid featureId, SPWeb web) at DOASiteInitReceiver.DOASiteProvisioned.DOASiteProvisionedReceiver.InitFormLib(SPWeb web) The Zone of the assembly that failed was: MyComputer

The event receiver assembly is GAC-deployed, so CAS shouldn't be an issue. I set trust level to FULL in the web.config under wwwroot\wss\virtualdirectories\80\ - no change.

The account under which the opration runs (which is the app pool account) has the rights to create a solution - the exact same code works when executed from a windows application running in the context of the same user. Further, out of desperation I have endowed the account with all kinds of superpowers - so it's not a genuine access denied stuff.

This was with a farm-deployed solution. I tried sandboxed and I got a different error, this time it can't find the SPSolution class at all:

Unhandled exception was thrown by the sandboxed code wrapper's Execute method in the partial trust app domain: An unexpected error has occurred. Monitored process "ipc://be3b864b-5d78-4417-8ecf-903230c467e5:7000" has encountered an unhandled exception while executing user code. Inner Exception: Microsoft.SharePoint.UserCode.SPUserCodeSolutionProxiedException: Could not load type 'Microsoft.SharePoint.Administration.SPSolution' from assembly 'Microsoft.SharePoint, Version=14.900.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c'. Server stack trace: at TestEventReceiver.TestEventReceiver.TestEventReceiver.WebProvisioned(SPWebEventProperties properties) at Microsoft.SharePoint.UserCode.SPUserCodeEventHandlerWrapper.ExecuteInternal(Object userCodeObject, SPUserCodeRemoteExecutionContext context) at Microsoft.SharePoint.UserCode.SPUserCodeRemoteExecutionWrapper.Execute(SPUserCodeExecutionContext executionContext) at Microsoft.SharePoint.UserCode.SPUserCodeApplicationHostAppDomainRef.ExecuteWrapper(SPUserCodeWrapper wrapper, SPUserCodeExecutionContext executionContext) at System.Runtime.Remoting.Messaging.StackBuilderSink._PrivateProcessMessage(IntPtr md, Object[] args, Object server, Int32 methodPtr, Boolean fExecuteInContext, Object[]& outArgs) at System.Runtime.Remoting.Messaging.StackBuilderSink.AsyncProcessMessage(IMessage msg, IMessageSink replySink) Exception rethrown at [0]: at System.Runtime.Remoting.Proxies.RealProxy.EndInvokeHelper(Message reqMsg, Boolean bProxyCase) at System.Runtime.Remoting.Proxies.RemotingProxyInvoke(Object NotUsed, MessageData& msgData) at Microsoft.SharePoint.UserCode.SPUserCodeApplicationHostAppDomainRef.CodeToExecuteWrapper.EndInvoke(IAsyncResult result) at Microsoft.SharePoint.UserCode.SPUserCodeApplicationHostAppDomainRef.Execute(Type userCodeWrapperType, SPUserCodeCachedAssemblyGroup userAssemblyGroup, Guid siteCollectionId, Byte[] binaryUserCodeToken, Byte[] proxyOperationToken, SPUserCodeExecutionContext executionContext)

I created a sample solution that reproduces the problem and is stripped from pretty much anything that's not relevant - just a package with one text file to create a sample WSP, and an event receiver feature to run Solutions.Add(...) with it - you can play with it if you wish: DeploySolutionTest.rar There are two event receivers, esentially the same - one is farm solution and the other is sandboxed.

I tried calling stsadm and PowerShell programmatically - didn't work, and I couldn't get any output so I don't know exactly what went wrong there. I tested the code in a windows app - works fine, but when I plug it into the feature receiver I get a blank string as output, no exception, no result. I don't know if it's the same underlying problem or something inherent to calling stsadm/PS from within SharePoint. So, how can I achieve this functionality - any hints? Should I delve further into the missing stsadm/PS output?

Somehow I don't feel it makes sense to use stunts like stsadm and PS from within SharePoint when I have a one liner in the API that is supposed to get the job done - but I guess I won't have a choice if I can't make it work. And the alternatives are not trouble-free either, so I'll appreciate advise on the workarounds too. I haven't tried PS yet - maybe it will be smoother sailing there.

3
  • This seems like a really weird way to do things to me. If you know a WSP needs to be used why is it not already installed on the server? To actually address the issue though, are you creating the web app, site collection, or whatever it is (what is it?) as an account that has access to add solutions? If not, are you elevating privileges? Sep 13, 2012 at 13:48
  • See also: stackoverflow.com/questions/536965/… Sep 13, 2012 at 13:50
  • Everything is working under the app pool account, although I did try SPSecurity.RunWithElevatedPrivileges as well as the other suggestions from the linked thread - nothing worked I updated the description to make it clearer - the whole thing needs to happen in an event receiver as the solution package is created on the fly. The background on the requirements is discussed in another question here: stackoverflow.com/questions/10813871/… Sep 13, 2012 at 14:24

1 Answer 1

1

You are using the new WebProvisioned handler that SharePoint 2010 introduced to handle the creation of a new subsite in a sitecollection - as far as I know that event runs in the contex of the site collection you are working on.

Now you are trying to add a solution to the farm from a site-collection/web site scope event. Based on the error you are getting, and since you ARE using an account that should have the sufficient permission to add the solution, I belive that you are experiencing the effect of the RemoteAdministratorAccessDenied setting.

Taken from Microsoft:

This feature explicitly blocks any modifications to the objects inheriting from SPPersistedObject in the Microsoft.SharePoint.Administration namespace and does not allow the content web applications to update the configuration database

As you can see the error you are getting are related to Microsoft.SharePoint.Administration.SPPersistedObject.BaseUpdate(), which would somehow confirm my thesis.

This powershell script

function Set-RemoteAdministratorAccessDenied-False() {
  [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint") > $null 
  [System.Reflection.Assembly]::LoadWithPartialName
  ("Microsoft.SharePoint.Administration") > $null # get content web service
  $contentService = [Microsoft.SharePoint.Administration.SPWebService]::ContentService 
  # turn off remote administration security 
  $contentService.RemoteAdministratorAccessDenied = $false $contentService.Update()
}

Set-RemoteAdministratorAccessDenied-False

will disable the security setting, allowing you to check if this is indeed the cause of your problem. Just remember that disabling the setting on a production environment could pose a security threat, so you will need to develop some workaround if you need to follow this road.

As for the sandboxed version of the solution... most of the Administration namespace ISN'T available in sandboxed solution, so that is a no-go. Check this page - as you can see the SPSolution class is not available in sandbox. Just think about it: if you could just add a farm solution from a sandboxed one, then it would be trivial to "excape the sandbox".. That said, I belive that you could workaround the problem by building a full trust proxy.

I would suggest that you try to find another solution to you problem, but I fear that you may have good reason to do so.. after all you said that the solution is dinamically generated.

Care to elaborate more on what you are attempting to do? maybee we can find another solution. In the meantime try the script: it would at least allow us to check if the problem is indeed with the RemoteAdministratorAccessDenied param.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.