LDAP Call in ASP page no longer works - asp-classic

I have a Classic ASP page that made an LDAP call to our Domain Controllers to find out the group membership of the logged on user. Since our Network Admin demoted the two old Windows Server 2003 Domain Controllers and promoted two Windows Server 2008 R2 servers the page now fails at Set CurrentUser = GetObject("LDAP://" & ADSysInfo.UserName) (see code) with the error 800704bc.
Dim Strgroups
Const STAFF_GROUP = "cn=staff"
Const STUDENT_GROUP = "cn=student"
Set ADSysInfo = CreateObject("ADSystemInfo")
Set CurrentUser = GetObject("LDAP://" & ADSysInfo.UserName)
If IsArray(CurrentUser.MemberOf) Then
strGroups = LCase(Join(CurrentUser.MemberOf))
Else
strGroups = LCase(CurrentUser.MemberOf)
End If
Any help is appreciated. Thanks in advance.

I'm guessing it's not the code that's the problem, but rather a something to do with the new servers (obviously).
I don't know what error 800704bc is, but check and see that ADSysInfo is actually getting instantiated. If not, then maybe there's a module missing on the server or something.

Not sure why but I needed to open the high ports (1024+) on the firewall between the server and the DCs. Must be an RPC thing.

Do the new servers block unencrypted binds? If so, then this would make sense as you bind as LDAP not LDAPS nor StartTLS.

Related

Why won't OAuth work on web server?

I have an ASP.Net web application running on Windows Server 2012, and need to make calls to social networking sites using oauth to generate some of the page content. Everything works on my development machine, but I can't even get a single response back ("unable to connect to the remote server" error).
I disabled the firewall to test that. No luck. I created a console application to test it that way. A simple HttpWebRequest will get the html for any page I throw at it, but not any oauth request. I've used different libraries to try to achieve this, including Linq2Twitter, Spring.Social, and HigLabo. All work locally, but not on the server. I've found nothing useful in the server event log.
Can anyone give me some clues what might be happening?
EDIT: Here's some code I'm using with the HigLabo library to try to retrieve the user timeline.
using HigLabo.Net.Twitter;
var cl = new TwitterClient(consumerKey, consumerSecret, accessToken, accessTokenSecret);
var rr = cl.GetHomeTimeline();
foreach (var r in rr)
{
//Console.WriteLine(r.CreatedAt + ":" + r.Text);
}
I'm aware that accessToken & accessTokenSecret aren't/shouldn't be necessary for a simple timeline read, but this is just to make sure it works first.
This turned out to be a firewall issue, as had been suspected. But not the server firewall. This was a problem with the ISP. They had an internal firewall that was blocking all traffic to/from the social network sites. They were able to resolve it quickly with a phonecall, but it was not a coding or configuration error on my part.

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.

Directory.CreateDirectory failed on Remote Server

I am working on a small project, in asp.net mvc3, that would copy the deployment files from a local drive to a share drive on a window server 2008 R2 server. I am connected using WMI, and the connection is successful. However, I tried to create a folder, and I receive the message "Logon failure: unknown user name or bad password." Here is a sample code:
bool isConnected = false;
options.Username = user.Name.Trim();
options.Password = user.password.Trim();
mScope = new ManagementScope("\\\\xxx.xxx.xxx.xxx\\root\\cimv2", options);
mScope.Connect();
if (mScope.IsConnected == true)
{
//I've gotten to this point. Then, the code below throw the exception
Directory.CreateDirectory(#"\\\\xxx.xxx.xxx.xxx\Tester\shareFile.txt");
isConnected = true;
}
I'd like to know what am I doing? Is that the right way of doing it?
it is the correct way however it will be the current user you are trying to access that gets passed to the remote computer to create the directory. The management scope at this point has nothing to do with Directory.CreateDirectory. These are 2 different "worlds". you do give the creds to ManagementScope but this has no affect on Directory.CreateDirectory. you could use impersonation to do what you are wanting to:
How do you do Impersonation in .NET?
it is unclear though if you are doing this in ASP.NET/MVC or a different platform. your tags indicate ASP.NET MVC but not your main question.
remember, if you are using ASP.NET/MVC, the credentials of the app pool are being used to perform such actions.

How to use SharpSVN in ASP.NET?

Trying to use use SharpSVN in an ASP.NET app. So far, it's been nothing but trouble. First, I kept getting permission errors on "lock" files (that don't exist), even though NETWORK SERVICE has full permissions on the directories. Finally in frustration I just granted Everyone full control. Now I get a new error:
OPTIONS of 'https://server/svn/repo': authorization failed: Could not authenticate to server: rejected Basic challenge (https://server)
This happens whether I have the DefaultCredentials set below or not:
using (SvnClient client = new SvnClient())
{
//client.Authentication.DefaultCredentials = new System.Net.NetworkCredential("user", "password");
client.LoadConfiguration(#"C:\users\myuser\AppData\Roaming\Subversion");
SvnUpdateResult result;
client.Update(workingdir, out result);
}
Any clues? I wish there was SOME documentation with this library, as it seems so useful.
The user you need to grant permission is most likely the ASPNET user, as that's the user the ASP.NET code runs as by default.
ASPNET user is a local account, preferably youd'd want to run this code in an Impersonate block, using a network account set up for this specific reason

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