I am using SharePoint Server 2007 Enterprise with Windows Server 2008 Enterprise. I have deployed a publishing portal. I am developing a ASP.Net web application using VSTS 2008 + C# + .Net 3.5 + ASP.Net + SharePoint Server 2007 SDK.
I found sometimes we need to use SPWebApplication.FormDigestSettings.Enabled = false in order to walk around, e.g. using SharePoint API to create a site in a site collection. I want to know why we need to execute SPWebApplication.FormDigestSettings.Enabled = false? What is the reason behind the scene?
thanks in advance,
George
Does the user that is executing the commands have permissions to run the commands? Based on documentation, it appears that you are disabling security validation when you set that property to false.
A better way to get "super user" permissions to execute a command that the current user doesn't have permissions to run is to use SPSecurity.RunWithElevatedPrivileges
SPSecurity.RunWithElevatedPrivileges(delegate()
{
// Note: It's important that you create all new SPSite and SPWeb
// objects in the elevated context in order to actually use elevated
// privileges. Failure to do so will cause your code to execute
// without elevated privileges.
using(SPSite site = new SPSite(SPContext.Current.Site.ID))
{
using(SPWeb web = site.OpenWeb(SPContext.Current.Web.ID))
{
// run code here that requires elevated privileges.
}
}
});
Related
Right now i am using an web application with code to read from and write to the registry. While debugging in Visual studio everything went fine but on the online test server it didn't run. the error exception message i am getting is:
System.Security.SecurityException: Requested registry access is not
allowed.
This is the code i am using:
private RegistryKey GetWritableBaseRegistryKey(string extendedPath)
{
var path = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
return RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Default).OpenSubKey($"{path}\\{extendedPath}", true);
}
The sollutions i found where:
Solution 1
you will not be able to set AppPoolIdentity to a specific group, but
you can
create a local user (compmgmt.msc)
add the user to the administrator group (compmgmt.msc)
Set the application pool to run under that user, under Advanced Settings.
Obviously you know this is a very bad idea from a security
perspective, and should never ever ever be performed on a forward
facing server.
source
Solution 2
Create a separate console application to run the service in admin
modus so you could access the registry. This solution was performance
heavy because you need to run 2 separate applications.
Solution 3
Use this code to allow access to the registry.
RegistryPermission perm1 = new RegistryPermission(RegistryPermissionAccess.AllAccess, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall");
perm1.Demand();
Or this code
RegistrySecurity rs = new RegistrySecurity();
string currentUserStr = Environment.UserDomainName + "\\" + Environment.UserName;
RegistryAccessRule accessRule = new RegistryAccessRule(currentUserStr, RegistryRights.WriteKey | RegistryRights.ReadKey | RegistryRights.Delete | RegistryRights.FullControl, AccessControlType.Allow);
rs.AddAccessRule(accessRule);
But these didn't work on the server however while debugging in visual studio the code ran fine.
In order for the web application to access the registry it must have sufficient permission. Consequently Solution 1 is the only one likely to work. It describes setting the web sites application pool to a user in the local administrators group. Its misses the steps about actually setting your IIS web site to use the newly created App Pool, which is why it might not work for you.
The technical process of reading a restricted registry, especially the application Uninstall registry key, inside a web server is really unlikely to be useful to you. Of what possible use is allowing a web server to access the servers own Application uninstall list going to be ?
I suspect you intend to open that registry key on the client's PC (my speculation) which is not going to be possible.
The goal is to have a web user interface with the option to create new site collections with new Content Database.
With the admin user I can manually in the CA create new Content Databases. I can also create a new site collection in this content database.
The idea was to create an event receiver (C#). If the user adds data to a table, the mentioned actions are to be executed.
Experiments:
a) Console application - works!
using (SPSite site = new SPSite("http://sp2013")) {
using (SPWeb spWeb = site.OpenWeb()) {
SPWebApplication elevatedWebApp = spWeb.Site.WebApplication;
elevatedWebApp.ContentDatabases.Add("sp2013", "WSS_Content_80_" + DateTime.Now.ToString("yyyymmddhhMMss"), null, null, 10, 15, 0);
}
}
b) Event Receiver - Only create site collections works, creation of content databases does not work! Error: Access Denied.
c) Web Service - Does not work! Error: Access Denied.
So, why do I get the error Access Denied when I can create site collections, but only content databases creation not go?
Finally I executed PS Script - but this also doesn´t work.
# AUTHOR: Paul Kotlyar
# CONTACT: unclepaul84#gmail.com
# DESCRIPTION: sets an option on content web service that allows updating of SP Administration objects such as SPJobDefinition from content web applications
function Set-RemoteAdministratorAccessDenied-False()
{
# load sharepoint api libs
[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
# update the web service
$contentService.Update()
}
Maybe somebody knows a solution?
I asked the same question in Stackexchange.
This is a permissions problem, but not for clients account. The client user is irrelevant. The problem is that for content database creation your code need farm administrator privileges. However, running code with elevated privileges is insufficient, because when you execute code in this way, SharePoint impersonate with application pool user of correspondent web application.
If the app pool user for "http://sp2013" do not have farm admin privileges, you cannot create content database with an event receiver (maybe for this reason you have an Access Denied error for your event receiver and your webservice code). The problem is giving farm admin privileges to an app pool or service user it's a very bad idea.
I recommend to you implement this solution as timer job. You can create a SharePoint farm solution, and make a timer job, because normally timer jobs are executed with a farm admin account. In this way, you could create a content database.
I have an ASP.NET MVC 3 application which uses PowerShell to connect to Office 365 to retrieve some details about user licenses.
The code itself works in many cases:
The project in my local IIS works
A piece of code in LINQPad using the library works on my machine
A piece of code in LINQPad using the library works on the target server
And where it doesn't work is of course the only place it really should work: The IIS on the target server.
I always get an Exception when calling the Connect-MsolService cmdlet. The problem is that the Exception doesn't tell me anything.
The Exception type is
Microsoft.Online.Administration.Automation.MicrosoftOnlineException
and the message is
Exception of type 'Microsoft.Online.Administration.Automation.MicrosoftOnlineException' was thrown
which is pretty useless.
The Office 365 user account I use in my code is always the same. The user account used to start the IIS is always the same, too (Local System).
I wrapped the PowerShell code execution in a class named PowerShellInvoker. Its code can be found here.
And here is the code that connects to Office 365:
var cred = new PSCredential(upn, password);
_psi = new PowerShellInvoker("MSOnline");
_psi.ExecuteCommand("Connect-MsolService", new { Credential = cred });
There is no Exception actually thrown, the error is found in the Error property of the pipeline. (See lines 50ff. of the PowerShellInvoker class.)
The problem is that I don't know what could be wrong, especially because the same code works when I use LINQPad. The search results by Google couldn't help me either.
The server runs on Windows Server 2008 R2 Datacenter SP1 with IIS 7.5.
I found the solution!
I don't know the reason, but on the target server, the app pool's advanced settings for my app had set Load User Profile to False. I changed it back to True (which should be default) and voilà, it works!
Edit: The Load User Profile setting was apparently automatically set to False by default because the IIS 6.0 Manager was installed and False was the default behavior until IIS 6.0.
While I am trying to upload a registry in my registries using the C# code , the application is throwing the error "a required privilege is not held by the client". If I am using the same code on some other machine it is working fine but not particularly on my machine
I am using below mentioned code to upload the registry files
Process my_p = new Process();
my_p.StartInfo.FileName = "reg";
my_p.StartInfo.Arguments = "load HKLM\TEST C:\Documents and Settings\Administrator\NTUSER.DAT";
my_p.Start();
my_p.WaitForExit();
System.IO.StreamReader srOutPut = my_p.StandardOutput;
System.IO.StreamReader srError = my_p.StandardError;
my_p.Close();
results = srOutPut.ReadToEnd().Trim();
Errors = srError.ReadToEnd().Trim();
Moreover One thing I have noticed that the above code I am using in http based web site, but when I am using it in a File Syatem based web site it is working fine. Please help I am not getting the error.
Regards,
Vikram
You can load RegLoadKey function directly to load the hive as a subkey. Another API is RegLoadAppKey but it works only starting from Windows Vista. Different versions of Reg.exe use the API. How you can read in the description the RegLoadKey you need have SE_RESTORE_NAME and SE_BACKUP_NAME privileges and enable these (see http://msdn.microsoft.com/en-us/library/ms717797.aspx). If you are in the Group of Administrators or Backup Operators you have these privileges. One more problem can be if Reg.exe use RegLoadKey function and you have a local administrative rights, but you start on Vista or Windows 7 a command without admin rights because of UAC (User Account Control).
I have the following C# code
using (RunspaceInvoke invoker = new RunspaceInvoke())
{
invoker.Invoke("Set-ExecutionPolicy Unrestricted");
// ...
}
which gives me the exception
Access to the registry key
'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell'
is denied.
According to this, the solution is to start PowerShell as an administrator.
Ordinarily, this can be accomplished by right-clicking PowerShell and selecting "Run as Administrator". Is there a way to do this programmatically?
I know this is an old post, but we ran into this same problem recently.
We had to scope the execution policy on the machine running the C# code by running the following from PowerShell...
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Unrestricted
When we had done this previously, without scoping, we were setting the execution policy for Administrator. Visual Studio \ C# was running as the current user, causing it to fail with insufficient permissions.
Check this out
You need to impersonate as an administrator to do it (you will of course need administrator credentials)
Check that article, that also comes with code ready to use (I've used it and it works great)
Basically, you need to do this:
using ( new Impersonator( "myUsername", "myDomainname", "myPassword" ) )
{
using (RunspaceInvoke invoker = new RunspaceInvoke())
{
invoker.Invoke("Set-ExecutionPolicy Unrestricted");
}
}
Administrative privileges are at the application level. The app that needs admin access in this case is yours. Creating runspaces in C# in a custom app does not invoke powershell the application - it just loads some assemblies into your application.
That said, you can elevate as the other poster said although embedding admin usernames and passwords into source code make me feel ill.
-Oisin
I think an alternative model would be to wrap the powershell executor into a simple asp.net webapi webservice.
The webservice could then be configured to run with the required permissions needed to do it's job. It can provide it's own security to determine which clients can call it.
To execute a script, you would just call webservice methods. You could make the method quite general - script name and params.
It's a bit more work, but a lot more secure (see x0n's thoughts).
Strictly for DEV environment
This is relatively very old post.
But I have found a new way to do this.
I am hosting the C# web api on IIS 8 having some powershell code that I want to run with administrator privileges.
So I provided the admin credentials in the Application pool identity setting.
Just set administrator account in app pool identity.
Hope this helps to anyone. :)