Web Server Accessing DFS Share - asp-classic

I'm using the following code in a VB6 DLL (Middleware on an ASP Classic Site) to create a drive mapping to a network share in order to copy files to and fro:
Set ws = CreateObject("WScript.Network")
ws.MapNetworkDrive strDrive, strPath, False, strUser, strPass
At the moment, this works if the share is a normal file server, e.g. \server\share\foo but if I move to a DFS namespace it no longer works, e.g. \mydomain.local\share\foo.
It works in the VB IDE (running as me but using same credentials as the service would) but once compiled and running under the web server the error returned is Error -2147023584 - A specified logon session does not exist. It may already have been terminated.
Most sites I have searched suggest the the local system policy "Network access: Do not allow storage of passwords and credentials for network authentication" be disabled, this is already the case on my machine, I even enabled it then disabled it again to make sure.
Another site suggested connecting to the root node of the DFS first, that didn't work either.
(Windows 7, IIS 7.5)

Related

Virtual Directory Physical Path Credentials for Specific User Getting Bad Data Error as This Portal No Longer Window Authentication

I have this portal that contains applications that range from classic asp to asp.net 4x. The transition from WIA to Forms Authentication has been accomplished manually as this delicate monstrosity will not accept any other way. I have only one hurdle left and this is accessing the virtual directory that stores images and documents for one of the apps and which no longer have the physical path credentials supplied by window authentication.
There is no application to control this virtual directory and I need to transition from Application user(pass-through authentication) to Specific user in IIS 7.0
I have tried to Set Credentials for a generic user and my own admin account but get the Bad Data error 0x80090005 which generally tells me there is no encrypted credentials in applicationHost.config
I assume that the logon type is clear text and these keys should be in the applicationHost.config.
Any hints at how to create these keys would be appreciated.
I ran the command that Lex Li pointed me to:
appcmd set vdir /vdir.name:"ExampleSite/ExamplePathDir" /userName:"username" /password:"XXXXXXXX"
And received the Bad Data error:
ERROR ( hresult:80090005, message:Failed to commit configuration changes.
Bad Data.

The remote server returned an error: (401) Unauthorized. Using CSOM in ASP.NET

I'm tried to pull some SharePoint 2013 list data I created which works fine when running locally on my machine and when run locally one the server. I'm user the same credentials when running both locally and locally on the server. The issue is when I publish and navigate to my ASP.NET app on the server I get the "The remote server returned an error: (401) Unauthorized." Error...
I've looked at a bunch of the posts on stackoverflow and some other articles on the web
This points out that the context seems to be using IUSR:
http://blogs.msdn.com/b/sridhara/archive/2014/02/06/sharepoint-2013-csom-call-from-web-part-fails-with-401-for-all-users.aspx
This one mentions to try setting the default network credentials:
https://sharepoint.stackexchange.com/questions/10364/http-401-unauthorized-using-the-managed-client-object-model
I've tried using the fixes mentioned in the article as well as trying to force the context to use DefaultNetworkCredentials but no luck. I would like for the app to use the credentials of the logged in user and not the machine...
Here is the code I'm using:
SP.ClientContext context = new SP.ClientContext("MySPDevInstance");
context.Credentials = CredentialCache.DefaultNetworkCredentials;
Entity entity = context.Web.GetEntity(collectionNamespace, collectionName);
LobSystem lobSystem = entity.GetLobSystem();
LobSystemInstanceCollection lobSystemInstanceCollection = lobSystem.GetLobSystemInstances();
context.Load(lobSystemInstanceCollection);
context.ExecuteQuery();
LobSystemInstance lobSystemInstance = lobSystemInstanceCollection[0];
FilterCollection filterCollection = entity.GetFilters(filter);
filterCollection.SetFilterValue("LimitFilter", 0, 1000);
EntityInstanceCollection items = entity.FindFiltered(filterCollection, filter, lobSystemInstance);
The server is running IIS 6.0
Any advice would be much appreciated!
Thank you
I presume your ASP.NET web site is using Windows Integrated (NTLM) authentication. A user authenticated this way cannot authenticate to a second location from the server side (the web server.) You are experiencing what is known as the "double-hop" (1) limitation of NTLM. You must use a dedicated account on the server side, or if you really do want to use the logged-in user's identity, you must use an authentication scheme that permits delegation, such as Kerberos.
If you really need the user's identity to access SharePoint data and you cannot change the authentication scheme, then the best way to do this is to use the JavaScript CSOM. This means the user is authenticating directly to the SharePoint server (a single hop, not double) and your ASP.NET site serves the page containing this script to the user.
(1) http://blogs.msdn.com/b/knowledgecast/archive/2007/01/31/the-double-hop-problem.aspx
Use Default Credentials worked for me:
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest.UseDefaultCredentials = true;
Setup the crendentials by code:
SP.ClientContext context = new SP.ClientContext("MySPDevInstance");
context.Credentials = new NetworkCredential("username", "password");
You should put this at the configuration file to change it without publishing or recompiling the application.
Just to add one more setting that I encountered. If the account is restricted to access only certain servers than add the client machine to that account as well. For example if a web application is hosted on Server A and trying to connect to SharePoint 2010 on Server B with account ABC then make sure that account has access to Server A in Active Directory. Normally the AD account doesn't have restrictions to connect to machines but in my case the account was restricted to only certain machines. I added my web application hosted server to the account and it worked.

Classic asp "An error occurred when verifying security for the message." iis7 transport level security

On II7 we host a WCF/asp.net based API. In order to allow users of a classic asp application to connect to the API we had to publish a version we refer to as "transport". This Transport version is written in asp.net too, it points to the same assembly , its just the security layer is different to allow classic asp to authenticate. Transport level security is used as opposed to message based security.
When using a browser to load the service reference i can loading the svcutil.exe ... WDSL page.
When using my test asp page to call a web method from this reference i get the following returned:
Finished calling Web Service.
Status = Internal Server Error
ResponseText = a:InvalidSecurityAn error occurred when verifying security for the message.
This suggests that the authentication is failing. When testing using asp.net or the application WCF storm to contact the normal API everything works well.
The API was recently migrated , it would appear something has not been setup correctly but i am at a loss to explain what.
I can browse to the svcutil.exe ... WDSL service reference, when selecting it via the browser i get the expect XML response.
The USER NAME and password utilised work when using the non-classic asp publicaiton of the API using the message based secuirty.
Would it be possible to post some troubleshooting tip that may help diagnoise the issue please specifically regarding transport level security fault finding and setup ?
Thank you
Scott
EDITED TO ADD THE FOLLOWING UPDATE:
Attempted to use the Default App Pool and a new App Pool but same problem persists.
My test page error: ResponseText = a:InvalidSecurityAn error occurred when verifying security for the message.
IIS LOG shows:
v3/transport/testclassicasptransportwcfservice.asp ( 200 0 0 ) (i.e iis 200)
/V3/Transport/DeviceService.svc/DeviceService (500 0 0) (i.e iis error 500)
note: virtual dir defined on TRANSPORT and V3. V3 works ok using .net as opposed to classic asp to authenticate.
EVENT LOG:
The Template Persistent Cache initialization failed for Application Pool 'transport' because of the following error: Could not create a Disk Cache Sub-directory for the Application Pool. The data may have additional error codes.
This reference appears to suggest a fix but many of the DIR paths and references in "appcmd" dont exist.
_http://theether.net/kb/100127
REF http://theether.net/kb/100127
load cmd prompt
CD to C:\Windows\System32\inetsrv
enter: appcmd list config -section:system.webServer/asp
the following path is displayed: c:\inetpub\conf\temp\ASP compiled templates
check path exists (it does)
Check if the NETWORK SERVICE has permissions to access "ASP compiled templates" If not from appcmd execute;
icacls "c:\inetpub\conf\temp\ASP Compiled Templates" /grant "NETWORK SERVICE:(OI)(CI)(M)"
should read "sucessfully processed 1 files"
restarted app pool.
THE "InvalidSecurityAn error occurred when verifying security for the message" problem still persists but the "COULD NOT CREATE A DISK CACHE SUB-DIRECORY .... " error from the eventlog is no longer occurring.
Sorry another update. The network service permission change DID NOT resolve the issue , changeing to the DEFAULT APP POOL solved the problem.
Got a lead at last. Examined:
ServiceSecurityAudit set in service behaviour. Ref http://intrepiddeveloper.wordpress.com/2008/08/07/security-event-logging-auditing/#
IIS logs (simply shows the non-specific error 500.)
Fault tracing enabled( also shows error 500).
Custom errors were off
Friendly IE messages were off
Asp client side and server side debugging on
ProcessMon running , no errors.
Web.config httpErrors errorMode="Detailed" /> +
ServiceSecurityAudit found me an "Object reference not set to an instance of an object" so sounds like our app has a bug.
Follow up (17/08/11):
Service Security Audit documented here:
http://intrepiddeveloper.wordpress.com/2008/08/07/security-event-logging-auditing/
Was the key for us to resolve this issue. Uncovered the Object Reference Error which indicated out Business Objects and Data Access dlls were out of alignment. Using CLASSIC ASP to contact the WCF.NET API using TRANSPORT AUTHENTICATION there was abolutely no indication of this error until Service Security Audit was enavled on the behaviour.config file in the WCF deployment.

changing aspnet user to the domain user to access iis

I'm running IIS5.0 and I am trying to change the ASP.NET process account to my domain user account.
I have followed everything possible here.
When I browse the .svc file (this is a wcf service) I am getting this error:
Server Application Unavailable The
web application you are attempting to
access on this web server is currently
unavailable. Please hit the "Refresh"
button in your web browser to retry
your request.
Administrator Note: An error message
detailing the cause of this specific
request failure can be found in the
application event log of the web
server. Please review this log entry
to discover what caused this error to
occur.
Eventlog says:
aspnet_wp.exe could not be started.
The error code for the failure is
80070522. This error can be caused when the worker process account has
insufficient rights to read the .NET
Framework files. Please ensure that
the .NET Framework is correctly
installed and that the ACLs on the
installation directory allow access to
the configured account.
When I run the client, I get the following error:
The content type text/html;
charset=utf-8 of the response message
does not match the content type of the
binding (application/soap+xml;
charset=utf-8). If using a custom
encoder, be sure that the
IsContentTypeSupported method is
implemented properly. The first 872
bytes of the response were: '
From ASP.NET 2.0 onwards, the correct method to ensure that a user account has the correct rights to run as the worker process identity is to run this command:
aspnet_regiis -ga [account]
You need to run the aspnet_regiis command that matches the ASP.NET version you plan on running:
ASP.NET 2.0 -
%SYSTEMROOT%\Microsoft.NET\Framework\v2.0.50727\aspnet_regiis.exe -ga [account]
ASP.NET 4.0 -
%SYSTEMROOT%\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis.exe -ga [account]
If you put your Domain Account under IIS_WPG group, it should ideally work. If it doesn't work, there is a sure shot way of fixing it.
In IIS 6... step 1 is applicable... since you are on IIS 5, ignore step 1
Run it with Local System to begin with. If the applications runs, it means your IIS is configured well and you can proceed with the step 2.
Change the account to your domain account, and ensure that you have put the account in IIS_WPG as well. After that, run the tool called Process Monitor http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx
Browse the application now. If you still get the error, switch to the Process Monitor and stop capture [menu option].
Search for Access denied and fix it. Link

Access Denied errors accessing IIS WMI provider from ASP

I have a Windows 2003 server running IIS 6 and have some scripts that do automated setup and creation of websites. They are not working on a new server I cam commissioning (they already work happily on 3 other W2K3 servers). The problem appear to boil down to WMI security on the IIS provider. The ASP code below represents the problem (although it is not the original code that causes the problem - this is a simplified demonstration of the problem).
Set wmiProvider = GetObject("winmgmts:\\.\root\MicrosoftIISv2")
If wmiProvider is Nothing Then
Response.Write "Failed to get WMI provider MicrosoftIISv2<br>"
End If
Response.Write "Querying for IISWebService...<br>"
Set colItems = wmiProvider.ExecQuery("Select * From IISWebServer",,0)
Response.Write "Error: " & Hex(Err.Number) & " (" & Err.Description & ")<br>"
If I run this in my browser, I get an access denied error reported after the ExecQuery call. I have set WMI access for the IUSR_ user from the Root branch all the way down. In fact, I can query for IP address information using the CIMV2 provider quite happily. If I put the IUSR user in the machine admins group it all works, but I don't really want to do that.
This must be a DCOM/WMI security problem, but I can't work out what else there is. Can anyone shed any light?
After reading G. Stoynev's comment asking if any events were logged in the Windows Logs, I checked the event logs on the server to which I'm attempting to access IIS remotely via WMI, and lo and behold I found an event with the following text:
Access to the root\WebAdministration namespace was denied because the namespace is marked with RequiresEncryption but the script or application attempted to connect to this namespace with an authentication level below Pkt_Privacy. Change the authentication level to Pkt_Privacy and run the script or application again.
See the code in this answer to the related SO question c# - "Access is denied" Exception with WMI.
Here's some example C# code that I added that seemed to resolve this issue for me:
ConnectionOptions options = new ConnectionOptions();
options.Authentication = AuthenticationLevel.PacketPrivacy;
ManagementScope managementScope = new ManagementScope(#"\\remote-server\root\WebAdministration", options);
// ...
If this is something that you intend to run as a tool for yourself or your admin (as opposed to the unwashed anonymous masses), here is a way I have used in the past (YMMV):
Set up a new directory in your website (e.g. /SiteCreate) and place your WMI scripts there
Configure a Windows user that has appropriate rights (probably admin in this case but you should use whatever is pertinent to your app)
Turn off the anonymous access to the directory you created in step 1 and then set the security to allow access only to the user you created in step 2 (turn on the authentication for that directory)
Now, when you navigate to that directory in your browser, you should get a login prompt. When you enter the username/password you created in step 2 your script will have the appropriate rights to perform your WMI requests.
Not a DCOM issue, more so a WMI security and encryption issue. Try changing the GetObject moniker to include impersonation and pktPrivacy, eg:
Set wmiProvider = GetObject("winmgmts:{impersonationLevel=impersonate;authenticationLevel=pktPrivacy}!\root\MicrosoftIISv2")
Refer to the follow MS article for more info:
http://msdn.microsoft.com/en-us/library/aa393618(v=vs.85).aspx

Resources