How to deal with security permissions when creating a file/folder from plugin - plugins

I am trying to create a folder on my local computer from plugin' my code is :
string currentFIlePath = "C://myGeneralFile";
bool isFileInDir = Directory.Exists(currentFIlePath);
if (!isFileInDir)
{
System.IO.Directory.CreateDirectory(currentFIlePath);
}
FileInfo fInfo = new FileInfo(currentFIlePath);
fInfo.IsReadOnly = false;
return currentFIlePath;
At the line : System.IO.Directory.CreateDirectory(currentFIlePath); I get an error
Request for the permission of type 'System.Security.Permissions.FileIOPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=' SOME NUMBER ' failed.
What can I do to solve this?

This might not work for a few reasons.
If your plugin is registered to run within the sandbox access to the server disk is prevented. If you are on-premise you can register your plugin outside of the sandbox which will allow you to write to the server disk.
If you are trying to write to your local machine disk (and not the server disk). This will never work, the plugin runs on the server and has no access to your local disk.

Related

AWS MobileAnalyticsManager access to folder 'AWS Mobile Services\M4SP' is denied

I am trying to add the AWSSDK DLL into my C# code to collect my event data and pass the data to the AWS bucket. My C# code is created with VS Share point template. The project contains WSP files. The following code indicates how I use the AWSSDK :
using Amazon;
using Amazon.CognitoIdentity;
using Amazon.MobileAnalytics.MobileAnalyticsManager;
CognitoAWSCredentials credentials = new CognitoAWSCredentials(
"us-east-1:xxxxxx",//PoolID
RegionEndpoint.USEast1
);
Amazon.AWSConfigs.ApplicationName = "M4SP";
AWSConfigs.LoggingConfig.LogMetrics = true;
AWSConfigs.LoggingConfig.LogResponses = ResponseLoggingOption.Always;
AWSConfigs.LoggingConfig.LogMetricsFormat = LogMetricsFormatOption.JSON;
MobileAnalyticsManager manager = MobileAnalyticsManager.GetOrCreateInstance(
"xxxxxxxxxxxxxxxxxxx",//AppID
credentials,
RegionEndpoint.USEast1 // Region
);
CustomEvent customEvent = new CustomEvent("TestRecordEvent");
customEvent.AddAttribute("label", "M4SP");
customEvent.AddAttribute("action", "invoke");
customEvent.AddAttribute("details", "run the workflow test");
manager.RecordEvent(customEvent);
I found the code inside AWSSDK DLL was trying to log the data to local folder before passing it to AWS database. The location of the folder is C:\Users\[userid]\AppData\Roaming\AWS Mobile Services.
There is no problem in a standalone project since it always uses current user’s identity to run the application so it has access to the folder. But, because of the authentication mechanism of SharePoint solutions, it uses Application Pool Identity to access the folder and it gets access denied issue and the whole process fails.
Here is the error:
"Access to the path 'AWS Mobile Services\M4SP' is denied."
I modified the access right of Share point Application Pool Identity (in my case, it is “network service” account) but it still can’t access the folder .
Does anyone have a solution for this issue? Thanks very much for the help!!

Service is not running when OS is upgraded from Windows 8.1 to Windows 10

We have upgraded windows from 8.1 to 10.
Now in Windows 10 services installed by us are not running.
The same services are running properly if we install these services on Windows 8.1.
ON windows 10, we tried below things which didn't solve the problem.
services-> select service -> properties -> Set [Log on] as LOCAL SERVICE
Set full permission to "perticuler" user or "everyone" user for the folder where service files exist.
Change owner of folder as "everyone", "system" or "perticuler" user where service files exist.
Below is a workaround which works but not feasible for us since it requires password and actually we want to know the actual reason behind this problem.
workaround :
1. services-> select service -> properties -> Set [Log on] as "This account" where user can be selected and it also requires password. Refer attached image.
Please note that the service is a dot net(c#) service and it runs internally a jar file. if it is able to run jar file then only service starts successfully.
Thanks in advance
I have found the cause and solution.
[Cause of problem]
Service unable to understand that, to run JAR file, which program should be run.
[Detail]
I tried to debug the code.
At the location where process is started, popup message like shown in below image is occurred.
location : processSample.Start()
It means that atleast once user need to select the program.
If we select [Java(TM) Platform SE binary] once, then after that the
service always runs successfully.
This behavior is in Windows 10 only.
In addition to program selection, user setting shown in image in question is also required to run the service.
I want to say that, in default program setting already correct program is selected for .jar files as shown in below image, but still windows 10 asks user to select program once.
[Solution]
Run JAR file from windows(c#) service with settings below :
sampleProcess.StartInfo.FileName = "javaw.exe";
sampleProcess.StartInfo.Arguments = "-jar Sample.jar";
sampleProcess.StartInfo.WorkingDirectory = #"C:\SampleFolder";
sampleProcess.StartInfo.UseShellExecute = false;
sampleProcess.EnableRaisingEvents = true;
sampleProcess.StartInfo.CreateNoWindow = false;
Here working directory is the location where the [Sample.jar] does exist.
additinally a Path environment variable must be set in order to execure "javaw.exe".
Before fix I had implementation as below which is not proper for every system environment :
sampleProcess.StartInfo.FileName = "Sample.jar";
sampleProcess.StartInfo.WorkingDirectory = #"C:\SampleFolder";
sampleProcess.EnableRaisingEvents = true;
sampleProcess.StartInfo.CreateNoWindow = false;

How to deploy with Release Management to remote datacenter

We are running TFS and Release Management on premises, and i want to deploy my applications to a remote datacenter.
Access is over the internet, so there is no windows shares available.
I am using the vNext templates, and afaik RM seems to only support unc paths over windows shares.
How can i use Release Management to deploy software to this datacenter?
Im working on this solution:
Use WebDav on a IIS located inside the datacenter.
RM server and Target can use the WebDav client built into windows and access it by an unc path.
I haven't gotten this to work yet, as RM won't use the correct credentials to logon to the webdav server.
Updated with my solution
This is only a proof of concept, and is not production tested.
Setup a WebDav site accessible from both RM server and Target server
Install the feature "Desktop experience" on both servers
Make the following DLL
using System;
using System.ComponentModel.Composition;
using System.Diagnostics;
using System.IO;
using Microsoft.TeamFoundation.Release.Common.Helpers;
using Microsoft.TeamFoundation.Release.Composition.Definitions;
using Microsoft.TeamFoundation.Release.Composition.Services;
namespace DoTheNetUse
{
[PartCreationPolicy(CreationPolicy.Shared)]
[Export(typeof(IThreadSafeService))]
public class DoTheNetUse : BaseThreadSafeService
{
public DoTheNetUse() : base("DoTheNetUse")
{}
protected override void DoAction()
{
Logger.WriteInformation("DoAction: [DoTheNetUse]");
try
{
Logger.WriteInformation("# DoTheNetUse.Start #");
Logger.WriteInformation("{0}, {1}", Environment.UserDomainName, Environment.UserName);
{
Logger.WriteInformation("Net use std");
var si = new ProcessStartInfo("cmd.exe", #"/c ""net use \\sharedwebdavserver.somewhere\DavWWWRoot\ /user:webdavuser webdavuserpassword""");
si.UseShellExecute = false;
si.RedirectStandardOutput = true;
si.RedirectStandardError = true;
var p = Process.Start(si);
p.WaitForExit();
Logger.WriteInformation("Net use output std:" + p.StandardOutput.ReadToEnd());
Logger.WriteInformation("Net use output err:" + p.StandardError.ReadToEnd());
}
//##########################################################
Logger.WriteInformation("# Done #");
}
catch (Exception e)
{
Logger.WriteError(e);
}
}
}
}
Name it "ReleaseManagementMonitor2.dll"
Place it in the a subfolder to The service "ReleaseManagementMonitor"
Configure the shared path as the solution below states.
DO NOT OVERWITE THE EXISTING "ReleaseManagementMonitor2.dll"
The reason that this works is MEF.
The ReleaseManagementMonitor service tries to load the dll "ReleaseManagementMonitor2.dll" from all subfolders.
This dll implements a service interface that RM recognises.
It the runs "net use" to apply the credentials to the session that the service runs under, and thereby grants access to the otherwise inaccessible webdav server.
This solution is certified "Works on my machine"
RM does work only with UNC, you are right on that.
You can leverage that to make your scenario work -
In Theory
Create a boundary machine on the RM domain, where your drops can be copied.
The deploy action running on your datacenter can then copy bits from this boundary machine, using credentials that have access on that domain. (These credentials are provided by you in the WPF console)
How this works
1. Have a dedicated machine on the RM server domain (say D1) that will be used as a boundary machine.
2. Define this machine as a boundary machine in RM by specifying a shared path that will be used by your data centre. Go to settings tab in your WPF console, create a new variable - { Key = RMSharedUNCPath, Value = \\BoundaryMachine\DropsLocation }. RM now understands you want to use this machine as your boundary machine.
3. Make sure you take care of these permissions
RM Server should have write permissions on the \\BoundaryMachine\DropsLocation share.
Pass down credentials of domain D1 to the target machine in the data centre (Domain D2), that can be used to access the share.
4. Credentials can be passed down fron the WPF console, you will have to define the following two config variables in the settings tab again.
Key = RMSharedUNCPathUser ; Value = domain D1 user name
Key = RMSharedUNCPathPwd ; Value = password for the user defined above.
PS - Variable names are case sensitive.
Also, to let RM know that you want to use the SharedUNC mechanism, check the corresponding checkbox for the RM server and connect to it via IP and not DNS name as these must be in different domains, i.e.
Try to use Get-Content on local-server then Set-Content on the remote server passing the file contents over;
Could package everything into an archive of some kind.
The Release Management is copying VisualStudioRemoteDeployer.exe to C:\Windows\DtlDownloads\VisualStudioRemoteDeployer folder on the target server then is copying the scripts from the specified location to target server using robocopy.
So you have to give permissions from your target server to your scripts location.
Release Management update 4 supports "Build drops stored on TFS servers"
http://blogs.msdn.com/b/visualstudioalm/archive/2014/11/11/what-s-new-in-release-management-for-vs-2013-update-4.aspx

Powershell DSC xWebsite is failing

I am trying to use the xWebsite resource in powershell DSC but it keeps failing to Set-TargetResource. the error is
PowerShell provider MSFT_xWebsite failed to execute Set-TargetResource functionality with error message:
+ CategoryInfo : InvalidOperation: (:) [], CimException
+ FullyQualifiedErrorId : ProviderOperationExecutionFailure
The resource looks like
WindowsFeature IIS
{
Ensure = “Present”
Name = “Web-Server”
}
xWebsite Website
{
Ensure = "Present"
Name = "Website"
PhysicalPath = "E:\www\site"
State = "Started"
BindingInfo = MSFT_xWebBindingInformation
{
Protocol = 'HTTP'
Port = 7777
HostName = '*'
}
DependsOn = "[WindowsFeature]IIS"
}
I just copied it from one of the DSC examples, and initially it did not return the above error. I do not know what changed, but now it cannot create the website on subsequent runs. There is not a lot of troubleshooting content on DSC yet either, and I am hoping that someone else has run into this problem as well.
Regarding the initial run not returning an error
This may be related to this bug.
Regarding the error itself
Let's check the obvious stuff first:
All components of the PhysicalPath must exist; the resource won't create any of those paths. So use a File resource to create them if needed then make xWebsite depend on it.
Make sure a different web site is not using the port.
You show a DependsOn but don't show the rest of your configuration. Make sure that you're actually specifying a WindowsFeature resource in your config for it to depend on.
If those don't help
Post the rest of your config (if there is more).
Check out the xDscDiagnostics module in the DSC Resource Kit. It's not a resource, it's 2 functions that help you turn on the diagnostic and debug logs for DSC and then retrieve the events related to a specific run. This should help you figure out the actual underlying error.
I ran into problems trying to use the xWebsite resource on Windows Server 2008 R2 too. Then I noticed that at the bottom of the documentation page, it says:
Verified on the following platforms
Windows Server 2012: Yes
Windows Server 2008 R2: No
I ended up debugging through the module code outside of DSC. I found that there were several bits that didn't work on 2008R2, and so had to create my own version of the module that worked on that operating system.
Sorry - no easy fix!

Entity Framework Code First ignoring connection string, using IIS instead

I have a web app that I've created using Entity Framework Code First. In setting it up I have managed to match my DB connection string to my DBContext by specifying the full namespace and class of the DBContext as the name of the connection string.
<add name="MyClassProject.EfDbContext" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=MyDatabase;Integrated Security=true;User Id=MyUsername;Password=MyPassword;" providerName="System.Data.SqlClient"/>
Initially when I set up the project, I just had it created in c:\inetpub\wwwroot, and just ran it through Visual Studio. Everything worked fine.
Now I'm trying to have the code build to a separate website folder, and have the website run as it's own website and app pool in IIS. I've set up the website, and my hosts file but when I went to run it I received the following error.
Cannot open database "MyDatabase" requested by the login. The login failed.
Login failed for user 'IIS APPPOOL\MyAppPool'.
I'm wondering why this is happening, as I seem to be specifying the security username and password to use for the DB in my connection string....so why is it trying to connect as the app pool that my website is running in?
Also, how can I fix this, without having to give MyAppPool (or Network Service if I changed it to that) DB permissions in SQL Server?
Update: I should've mentioned that I initialise my DBContext class using:
namespace MyClassProject
{
public class EfDbContext : DbContext
{
public EfDbContext() : base ("MyDatabase")
{
}
}
}
I found the issue.
When I initialise my DBContext class with : base("MyDatabase"), it overrides the connection string specified in the web.config.
Removing that from my DBContext class, with the database already existing, the site now works in IIS.
However, if I don't have the database created already, (or if I have my database initialiser use DropCreateDatabaseWhenModelChanges or DropCreateDatabaseAlways so that it'll needs to recreate the DB), the initialiser will fail, as it'll try to use an SQL user that doesn't have permissions to create the DB.
My way around it is to use the : base("MyDatabase") and run from Visual Studio initially so the database is created.
Then remove it from code, add the specified user to the DB security in SQL Server, and it'll allow my site to run in IIS thereafter.
Remove Integrated Security=true;. That is the setting that passes the current user off.
When using Integrated Security, the DB is given a token from the user who is currently running the process. In all likelihood, you run Visual Studio from your user account, which likely has Admin permissions on your SQL Server instance.
When IIS runs your app, it uses something called an Application Pool (or App pool). You can have multiple apps in a single pool to be managed together. The app pool also runs under a special user account named for the pool. App pool users exist under a container called "IIS AppPool", so the local user for the DefaultAppPool is IIS AppPool\DefaultAppPool. If you want to grant access to a resource on your local system (including file permissions), you can also grant it to the app pool user or local group IIS_IUSRS to grant it to all app pools.
Remember that these are local accounts, so they will not cross network boundaries. To grant permissions on a different server, you'll need to either use a domain user (or even better, a domain Managed Service Account) or you can set the app pool user to NETWORK SERVICE and then you can grant permissions to MyDomain\MyWebServer$ (the dollar sign is important).
You can use Web.config Transform to have Local connection stirng different from Remote (say in Release mode). To start using it you need to publish your Web App using One-Click Publish from Visual Studio. That's really very handy way to publish web apps!
Looks like that's what you're looking for.
Or set connection string name base on a condition:
public EfDbContext() : base (GetConnectionStringName())
{
}
private static GetConnectionStringName()
{
return RunLocally() : "LocalDatabase" : "RemoteDatabase";
}
private static bool RunLocally()
{
// implement some how
}