InPlaceHostingManager Hosted in IIS, Access is denied error - iis

I am using the InPlaceHostingManager class to integrate the manifest file for some click once applications hosted in IIS, I am trying to get the version number. See code below
try
{
iphm = new InPlaceHostingManager(new Uri(deployManifestUriStr), false);
iphm.GetManifestCompleted += new EventHandler<GetManifestCompletedEventArgs>(iphm_GetManifestCompleted);
iphm.GetManifestAsync();
}
catch (UriFormatException uriEx)
{
this._logger.Fatal(uriEx, $"Unable to load Applicaition Versions (Invalid Uri) for uri : {deployManifestUriStr}");
}
catch (PlatformNotSupportedException platformEx)
{
this._logger.Fatal(platformEx, $"Unable to load Applicaition Versions (Platform Not Supported Exception) for uri : {deployManifestUriStr}");
}
catch (ArgumentException argumentEx)
{
this._logger.Fatal(argumentEx, $"Unable to load Applicaition Versions (Argument Exception) for uri : {deployManifestUriStr}");
}
catch (UnauthorizedAccessException ex)
{
this._logger.Fatal(ex);
this._logger.Fatal(ex.InnerException);
this._logger.Fatal(ex, $"Unable to load Applicaition Versions (Unauthorized Access Exception) for uri: {deployManifestUriStr}");
}
catch (Exception ex)
{
this._logger.Fatal(ex, $"Unable to load Applicaition Versions (Exception) for uri : {deployManifestUriStr}");
}
I am getting the following error
System.UnauthorizedAccessException: Access to the path 'Deployment' is denied.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.Directory.InternalCreateDirectory(String fullPath, String path, Object dirSecurityObj, Boolean checkHost)
at System.IO.Directory.InternalCreateDirectoryHelper(String path, Boolean checkHost)
at System.Deployment.Application.SubscriptionStore..ctor(String deployPath, String tempPath, ComponentStoreType storeType)
at System.Deployment.Application.SubscriptionStore.get_CurrentUser()
at System.Deployment.Application.DeploymentManager..ctor(Uri deploymentSource, Boolean isUpdate, Boolean isConfirmed, DownloadOptions downloadOptions, AsyncOperation optionalAsyncOp)
at System.Deployment.Application.InPlaceHostingManager..ctor(Uri deploymentManifest, Boolean launchInHostProcess)
at Logging.ApplicaitionVersionManifestHelper.Read(String deployManifestUriStr) in
The applicaition pool is running as network service. Does anyone know where the Deployment folder is?

I had a look inside InPlaceHostingManager > DeploymentManager > SubscriptionStore > Get_CurrentUser (CurrentUSer) I Found the following
public static SubscriptionStore CurrentUser
{
get
{
if (_userStore == null)
{
lock (_currentUserLock)
{
if (_userStore == null)
{
string folderPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
string deployPath = Path.Combine(folderPath, "Deployment");
string tempPath = Path.Combine(Path.GetTempPath(), "Deployment");
_userStore = new SubscriptionStore(deployPath, tempPath, ComponentStoreType.UserStore);
}
}
}
return _userStore;
}
}
After copying the code to some where I could debug it, I found the following.
string folderPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
The above line returns nothing. This lead me to the following
Stackoverflow Post
This change fixed it for me
Open your %WINDIR%\System32\inetsrv\config\applicationHost.config and look for <applicationPoolDefaults>. Under <processModel>, make sure you have the following attributes loadUserProfile="true" setProfileEnvironment="true"

You can use Process Monitor to see which is the Deployment folder.
About how to use the Process Monitor you can refer to this link:
Process Monitor

Related

Replace file when exists not working in Spring Integration Smb

I'm trying to write files to smb folder, it works fine for the first write but when the same file is written again it throws error
Caused by: org.springframework.core.NestedIOException: Failed to rename [/remote-target-dir/smbTest.test.writing] to [/remote-target-dir/smbTest.test].; nested exception is jcifs.smb.SmbException: Cannot create a file when that file already exists.
Im' using the FileTransferringMessageHandler which has FileExistsMode.REPLACE as default file exists mode but still it fails to replace.
I debugged into the SmbSession class, when flow reaches to this code in rename(String _pathFrom, String _pathTo) method
if (this.smbShare.isReplaceFile() && smbFileTo.exists()) {
smbFileTo.delete();
}
I see that the smbShare's isReplaceFile() is false, which is why I assume it is unable to delete the previous file with the same name
Here is the full code:
Connection:
#Bean
public SmbSessionFactory smbSessionFactory() {
SmbSessionFactory smbSession = new SmbSessionFactory();
smbSession.setHost("localhost");
smbSession.setPort(445);
smbSession.setDomain("DESKTOP-07O79IT");
smbSession.setUsername("Dell");
smbSession.setPassword("changeIt");
smbSession.setShareAndDir("Users\\DELL\\Desktop\\Shared");
smbSession.setSmbMinVersion(DialectVersion.SMB210);
smbSession.setSmbMaxVersion(DialectVersion.SMB311);
return smbSession;
}
Outbound to send files to smb:
#ServiceActivator(inputChannel = "storeToSmb")
#Bean
public MessageHandler smbMessageHandler(SmbSessionFactory smbSessionFactory) {
FileTransferringMessageHandler<SmbFile> handler =
new FileTransferringMessageHandler<>(smbSessionFactory);
handler.setRemoteDirectoryExpression(
new LiteralExpression("/remote-target-dir"));
handler.setFileNameGenerator(m -> "smbTest.test");
handler.setAutoCreateDirectory(true);
return handler;
}
Gateway:
#Override
public void run(ApplicationArguments args) throws Exception {
File file = new File("smbFile.txt");
try(FileWriter writer = new FileWriter(file)){
writer.write("This is sample smb write");
messageGateway.storeToSmb(file);
}catch (IOException e){
System.out.println("Error: "+e);
}
}
Can you please help with this issue?
The SmbSessionFactory must come with the setReplaceFile(true). The FileTransferringMessageHandler does nothing about its dependency and can't mutate it although it has its own logic about that FileExistsMode.REPLACE.

Class exception when trying to move a email using the spring integration message payload

Hi I have configured the default filter as below and if some emails have a certain subject or from address I try to move them to specific folders using java mail api as below:
Filter implementation:
#Bean(name = ImapAdaptersUtil.DEFAULT_FILTER_BEAN_NAME)
#Scope(WebApplicationContext.SCOPE_APPLICATION)
public MessageSelector defaultFilter() {
return message -> {
if (message.getPayload() instanceof MimeMessage) {
try {
String from = Optional.ofNullable(((InternetAddress) ((MimeMessage) message.getPayload()).getFrom()[0]).getAddress()).orElse(GeneralConst.EMPTY_STRING);
String subject = Optional.ofNullable(((MimeMessage) message.getPayload()).getSubject()).orElse(GeneralConst.EMPTY_STRING);
if (!from.matches(DELIVERY_ERROR_FROM)
&& !from.matches(SPAM_FROM)
&& !subject.matches(DELIVERY_ERROR_SUBJECT)
&& !subject.matches(OUT_OF_OFFICE)
&& !subject.matches(SPAM_SUBJECT)) {
return true;
}
} catch (MessagingException me) {
throw new ApplicationBusinessException(ApplicationBusinessException.ApplicationBusinessExceptionType.FUNCTIONAL_VIOLATION,
"Could not filter incoming email: " + me.getMessage());
}
}
try {
this.moveMessage(((MimeMessage) message.getPayload()));
} catch (MessagingException me) {
throw new ApplicationBusinessException(ApplicationBusinessException.ApplicationBusinessExceptionType.FUNCTIONAL_VIOLATION,
"Could not move incoming email: " + me.getMessage());
}
return false;
};
}
Move to folder implementation:
private void moveMessage(MimeMessage message) throws MessagingException {
Folder folder = message.getFolder();
Store store = folder.getStore();
Folder[] folders = store.getDefaultFolder().list("*");
for (Folder folder1 : folders) {
LOGGER.info("folder name {}", folder1.getName());
}
Folder deliveryErrorFolder = store.getFolder("Delivery error");
if (!deliveryErrorFolder.exists()) {
if (deliveryErrorFolder.create(Folder.HOLDS_MESSAGES)) {
deliveryErrorFolder.setSubscribed(true);
move(message, folder, deliveryErrorFolder);
LOGGER.info("Delivery error created");
}
} else {
move(message, folder, deliveryErrorFolder);
}
}
private void move(MimeMessage message, Folder folder, Folder spamFolder) throws MessagingException {
List<javax.mail.Message> tempList = new ArrayList<>();
tempList.add(message);
javax.mail.Message[] tempMessageArray = tempList.toArray(new javax.mail.Message[0]);
folder.copyMessages(tempMessageArray, spamFolder);
LOGGER.info("message moved");
}
ImapMailReceiver configured as an Integration flow :
public static IntegrationFlow getImapAdapterIntegrationFlow(String imapsUrl, MessageSelector filter, QueueChannelSpec channelSpec) {
return IntegrationFlows
.from(Mail.imapInboundAdapter(imapsUrl)
.userFlag("testSIUserFlag")
.simpleContent(false)
.autoCloseFolder(false)
.shouldMarkMessagesAsRead(true)
.javaMailProperties(getPropertiesBuilderConsumer()),
e -> e.autoStartup(true)
.poller(p -> p.fixedDelay(1000)))
.filter(filter)
.channel(channelSpec)
.get();
}
I get this exception :
Caused by: java.lang.ClassCastException: class org.springframework.integration.mail.AbstractMailReceiver$IntegrationMimeMessage cannot be cast to class com.sun.mail.imap.IMAPMessage (org.springframework.integration.mail.AbstractMailReceiver$IntegrationMimeMessage and com.sun.mail.imap.IMAPMessage are in unnamed module of loader 'app')
at com.sun.mail.imap.Utility.toMessageSet(Utility.java:85)
Yeah... What you are looking for is available starting with version 5.4: https://docs.spring.io/spring-integration/docs/current/reference/html/mail.html#mail-inbound
Starting with version 5.4, it is possible now to return a MimeMessage as is without any conversion or eager content loading. This functionality is enabled with this combination of options: no headerMapper provided, the simpleContent property is false and the autoCloseFolder property is false.
So, all good in your config - only what you need to to upgrade your project to the latest Spring Integration. Directly with the 5.4.5 or via respective latest Spring Boot.

View cloudinary images/vid through android app

I have looked in so many places on a lead on how or if it is possible to view images uploaded to cloudinary, by a specific tag through Android studio app i am trying to build.
I was able to implement the upload option by user, with adding a tag to the images, and public id, also retrieving these information, but i cant find anything on how to view these images, for example i want the app to be able to view all images with a specific tag ( username ) to the user that uploaded the pictures, and could delete them ? and also view other images uploaded by other user with no other permission.
Is it possible and how !?
I ended up with this code, and i encountered a problem;
#Override
public void onClick(View v) {
new JsonTask().execute("http://res.cloudinary.com/cloudNAme/video/list/xxxxxxxxxxxxxxxxxxx.json");
// uploadExtract();
}
});
public class JsonTask extends AsyncTask<String ,String,String> {
#Override
protected String doInBackground(String... params) {
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
StringBuffer buffer = new StringBuffer();
String line = "";
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
return buffer.toString();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect();
}
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
In the log i get the following;
03-28 12:36:14.726 20333-21459/net.we4x4.we4x4 W/System.err: java.io.FileNotFoundException: http://res.cloudinary.com/we4x4/video/list/3c42f867-8c3a-423b-89e8-3fb777ab76f8.json
i am not sure if my understanding is correct of the method or i am doing something wrong ? since in the Admin API Docs. or cloudinary the syntax for the HTML request and also in the suggested page by Nadav:
https://support.cloudinary.com/hc/en-us/articles/203189031-How-to-retrieve-a-list-of-all-resources-sharing-the-same-tag-
this should've returned a JSON ?
The following feature allows you to retrieve a JSON formatted list of resources that which share a common tag:
https://support.cloudinary.com/hc/en-us/articles/203189031-How-to-retrieve-a-list-of-all-resources-sharing-the-same-tag-
Note that image removal will coerce you to use server-side code (e.g. JAVA), since deleting via Cloudinary requires a signature that is based on your API_SECRET.

Changing GUID change program behaviour

I'm currently working on creating a namespace extension.
So I want to create an entry in Computer, and had explorer.exe calling my IShellFolder implementation.
I had it working for few minutes (I stupidly decided to clean up the code before commiting), so I'm somewhere near.
But I noticed something very strange: changing the GUID value of the Class change what I see in explorer.exe
I found that question which tells me I am not doing something bad
Here's the code:
AssemblyInfo.cs:
[assembly: ComVisible(false)]
[assembly: Guid("007C5100-4251-47BE-8141-D2AD3F496E6A")]
RootFolder.cs:
[ClassInterface(ClassInterfaceType.None)
[Guid("007C5101-4251-47BE-8141-D2AD3F496E6A"), ComVisible(true)]
public class RootFolder : IShellFolder, IShellFolder2, IPersistFolder, IPersistFolder2 {
private const String _mountPoint = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MyComputer\\NameSpace\\{0}";
private const String _mountName = "CLSID\\{0}";
#region Shell Extension Registration
[ComRegisterFunction()]
public static void Register(Type t)
{
Console.WriteLine("Registering {0}...", t.GUID);
try {
if (t.GUID == null)
throw new ArgumentException("CLSID must not be null");
using (RegistryKey key = Registry.CurrentUser.CreateSubKey(String.Format(_mountPoint, t.GUID.ToString("B")))) {
key.SetValue(null, "RootFolder");
}
using (RegistryKey key = Registry.ClassesRoot.OpenSubKey(String.Format(_mountName, t.GUID.ToString("B")), true)) {
key.SetValue(null, "RootFolder");
using (RegistryKey shFolder = key.CreateSubKey("ShellFolder")) {
shFolder.SetValue("Attributes", 0x78000040);
shFolder.SetValue("WantsFORPARSING", "");
}
}
using (RegistryKey key = Registry.LocalMachine.CreateSubKey(#"Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved")) {
key.SetValue(t.GUID.ToString("B"), "RootFolder");
}
IntPtr pidl = NativeMethod.SHGetKnownFolderIDList(KnownFolder.ComputerFolder.clsid, 0, IntPtr.Zero);
NativeMethod.SHChangeNotify(NativeMethod.FSNotification.UpdateDir, NativeMethod.ItemMeaning.IDList, pidl, IntPtr.Zero);
} catch (Exception ex) {
Logger.Write(Logger.Severity.Fatal, "Registration error: {0}", ex.Message);
throw; // Re-throw the exception
}
}
[ComUnregisterFunction()]
public static void Unregister(Type t)
{
try {
if (t.GUID == null)
throw new ArgumentException("CLSID must not be null");
Registry.CurrentUser.DeleteSubKey(String.Format(_mountPoint, t.GUID.ToString("B")), false);
using (RegistryKey k = Registry.ClassesRoot.OpenSubKey(String.Format(_mountName, t.GUID.ToString("B")), true)) {
if (k != null)
k.DeleteSubKey("ShellFolder");
}
using (RegistryKey key = Registry.LocalMachine.CreateSubKey(#"Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved")) {
if (key != null)
key.DeleteValue(t.GUID.ToString("B"), false);
}
IntPtr pidl = NativeMethod.SHGetKnownFolderIDList(KnownFolder.ComputerFolder.clsid, 0, IntPtr.Zero);
NativeMethod.SHChangeNotify(NativeMethod.FSNotification.UpdateDir, NativeMethod.ItemMeaning.IDList, pidl, IntPtr.Zero);
} catch (Exception ex) {
Logger.Write(Logger.Severity.Critical, "Registration error: {0}", ex.Message);
throw; // Re-throw the exception
}
}
#endregion
#region IShellFolder2 Inheritance
[All the methods looks like that, this is just a test]
public IEnumIDList EnumObjects(IntPtr hwndOwner, EnumObject flags)
{
Logger.Write("Tracing....");
throw new NotImplementedException();
}
#endregion
#region IPersistFolder2 Inheritance
[Ditto]
#endregion
}
I use the range 007C5{100...120}-4251-47BE-8141-D2AD3F496E6A for my GUIDs
When my extension has GUID 007C5101, it just shows "RootFolder" without any attributes.
When it has 007C5100 (same as assembly), or 007C5102, or 007C5103, it is shown as "System Folder" (even though it doesnt call my DLL).
I'm a little puzzled by this behaviour, how in the world can changing a GUID lead to this change ?
Note: I ran a search through the registry for 4251-47BE-8141-D2AD3F496E6A (the immutable part of my GUID), and couldn't find anything after unregistration.

Accessing the file share from Azure Worker Role

We want migrate our FTP servers in Windows Azure. We created clean virtual machine image and installed FTP Server there. Now, to be able to process the files resided in the FTP directory ,directly from Windows Azure data center, we created the file share and endpoints (port 445 TCP and UDP). If we are trying to access the FTP Server's file share from the Worker Role we are getting usually 'Access to the path '...' is denied.'. We are able to access the FTP Server's file share over the remote desktop from the Worker Role, what mean the Firewall and FTP configuration are correct. Can a worker role access the file shares in the Windows Azure data center?
The code:
try
{
const string networkShare = #"...";
Directory.GetFiles(networkShare).ToList().ForEach(file => Trace.TraceInformation(file));
Thread.Sleep(10000);
Trace.WriteLine("Working", "Information");
}
catch (Exception ex)
{
Trace.TraceError(ex.ToString());
}
The exception:
Exception thrown on running: System.UnauthorizedAccessException: Access to the path '...' is denied.
Server stack trace:
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileSystemEnumerableIterator`1.CommonInit()
at System.IO.FileSystemEnumerableIterator`1..ctor(String path, String originalUserPath, String searchPattern, SearchOption searchOption, SearchResultHandler`1 resultHandler, Boolean checkHost)
at System.IO.Directory.InternalGetFileDirectoryNames(String path, String userPathOriginal, String searchPattern, Boolean includeFiles, Boolean includeDirs, SearchOption searchOption, Boolean checkHost)
at System.IO.Directory.InternalGetFiles(String path, String searchPattern, SearchOption searchOption)
at KALCIK.NET.Plugin.ReadFromShare.ReadFromSharePlugin.Manipulate(String valueToManipulate)
at System.Runtime.Remoting.Messaging.StackBuilderSink._PrivateProcessMessage(IntPtr md, Object[] args, Object server, Object[]& outArgs)
at System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage(IMessage msg)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at KALCIK.NET.Plugin.Contracts.TextManipulationPluginBase.Manipulate(String valueToManipulate)
at KALCIK.NET.CloudServices.WorkerRole.BusinessLayers.WorkOrderProcessing.ProcessWorkOrder(Tuple`2 workOrder) in c:\Development\Samples\CloudServicesPlugInSample\CloudServices.WorkerRole\BusinessLayers\WorkOrderProcessing.cs:line 56
at KALCIK.NET.CloudServices.WorkerRole.WorkOrderProcessorService.Run() in c:\Development\Samples\CloudServicesPlugInSample\CloudServices.WorkerRole\WorkOrderProcessorService.cs:line 67; TraceSource 'WaWorkerHost.exe' event
Yes the problem seems to be the user, under the host process is running. To resolve this issue you can create the new user with the administrator privileges (for example with the help of start up task, when the role is starting) and impersonate the executed code. You can see the sample implementation here.
public class WorkerRole : RoleEntryPoint
{
public sealed class SafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid
{
private SafeTokenHandle() : base(true) { }
[DllImport("kernel32.dll")]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool CloseHandle(IntPtr handle);
protected override bool ReleaseHandle()
{
return CloseHandle(handle);
}
}
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, out SafeTokenHandle phToken);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public extern static bool CloseHandle(IntPtr handle);
public override void Run()
{
// This is a sample worker implementation. Replace with your logic.
Trace.WriteLine("TestWorkerRole entry point called", "Information");
while (true)
{
try
{
SafeTokenHandle safeTokenHandle;
var returnValue = LogonUser("username", Environment.MachineName, "password", 2, 0, out safeTokenHandle);
if (returnValue)
{
using (safeTokenHandle)
{
using (var impersonatedUser = WindowsIdentity.Impersonate(safeTokenHandle.DangerousGetHandle()))
{
const string networkSharePath = #"UNCPath";
Directory.GetFiles(networkSharePath).ToList().ForEach(file => Trace.TraceInformation(file));
}
}
}
Thread.Sleep(10000);
Trace.WriteLine("Working", "Information");
}
catch (Exception ex)
{
Trace.TraceError(ex.ToString());
}
}
}
}
I think it's a security issue: the user (under which the Working Role runs) is not able to authenticate on the network share. Try a "net use" before your Directory.GetFiles
"net use" from C# : Access a Remote Directory from C#

Resources