Enumerating domains in a forest (windows networks) - winapi

I looking for an API method that retrieve the info that "net view /domain" does.
namely, I'm looking for a way to enumerate the visible domains within a forest, using win32api (in C environment)
thanks.
Update:
it seems that DsEnumerateDomainTrusts can do what I need, however, it doesn't looks like net.exe importing it, so I'd still like to know of other options.
Update2:
as it's name imply, the function only enumerate trusted domain, even when DS_DOMAIN_IN_FOREST is specified,
so I'm in square 1.

I think that in your case the best way is to interrogate Active directory.
You will find in this answer the way to get all the domains in your directory, first requesting "rootDSE" to find the configuration naming context, second requesting for crossRef with nETBIOSName to retreive domain entries
As you are interested in how to interrogate active directory from native code, you may have a look to LDAP C-Binding API as discribed in RFC 1823 specifies, Microsoft support it, see MS Strategy for Lightweight Directory Access Protocol (LDAP). You'll find the using and reference manuals of the Microsoft API in Lightweight Directory Access Protocol.

Related

Using Wildcard in Windows Firewall

We are using Turbo.net for Publishing applications. One of this application (designed by our own Company) uses a Broadcast to find devices in the Network and then get a reply by a dynamic UDP Port (30000 - 50000). Opening all These ports on the Windows Firewall is not an Option.
I have therefore tried to specify the exe file in the Windows Firewall. That works but the Problem is, I Need to do this for 200 users. So I want to do this by GPO. Unfortunately the path to the exe is something like this:
%userprofile%\AppData\Local\Spoon\Servers\apps.elpro.com\Users\Firstname.Lastname.Domain\Sandboxes\ECOLOGPROModuleConfigurator__1-4-8-420__en-us__Default__AnyCpu\local\stubexe\0x4D80DB43F65B57C8\ PROModuleConfigurator.exe
The problem is "\Firstname.Lastname.Domain\". I was not able to find a way to use a wildcard for this in the Windows Firewall.
It seems that Windows-Firewall does not allow Wildcards.
Is there an easy fix for this or do I Need to script something and if how?
Thank you!
The fact that it can handle %userprofile% tells you that it's okay with Windows variables, so the thing to do would be to set up more such variables, to pass this path as %userprofile%\AppData\Local\Spoon\Servers\apps.elpro.com\Users\%Firstname%.%Lastname%.Domain\...
Sorry there's not a copy-paste solution for you. It would take some scripting on your end to pull this name data out of Active Directory (or some Linux/Unix LDAP server – whatever your organization is using) and fill these variables on a per-user basis. On the up-side, the variables could have other uses once you get them set up, like naming backup directories on a NAS in %Lastname%, %Firstname% format, and so on.
Exactly how to do this will vary by coding language, by OS version, and by directory service type. The information about this is scattered far and wide, so you'll have to search around a bit. E.g., for how to get an AD user's real names with C# under dotNet 3.0+, see this StackOverflow thread. And there are lots of SO threads with info on using Get-ADUser in Powershell to find and filter by user's IDs and names. This thread on SpiceWorks might also be of interest.
You'll almost certainly need Remote Server Administration Tools (RSAT) for Windows (see that page for installation details, which are totally different depending on OS version, even within Windows 10!). Tools that deal with ActiveDirectory need the AD stuff in RSAT to do their work, including both Powershell and C#.Net. RSAT requires Windows Pro or Enterprise (on the machine you're going to use to do the AD work; user workstations can be any version). But AD itself requires Windows Server.
This is only going to be doable with an Active Directory or other LDAP server, in which this user firstname/lastname information, as such, is even stored. Local accounts do not have this information at all except when they inherit it in munged "full name" form, e.g. from Microsoft.com account credentials. In Powershell, you can run 'Get-LocalUser | Select *', or follow the more "deep dive" local-ADSI method demonstrated here, and you'll find no first and last name data. It's just not part of an account, absent some systemic means (AD, or Microsoft online account connection, or Microsoft Family Group management, etc.) of injecting it. There are multiple ways of manually adding "full name", but even doing this across a bunch of users probably would not help you, since human names are not easily software-parseable into first name and last name (Many people have two last names, and many have two or more given names; so what is "Pat Morgan Otero"? And of course given-name versus family-name order varies culturally.) There appears to be no way to add separate first and last name fields to local accounts; tools like Set-LocalUser cannot do it.
[aside]There's no connection between Windows user data and Windows Subsystem for Linux user data (even the usernames can be different), so that's no help. If you have a network-wide unified user ID system via LDAP or whatever, and it has an end result of everyone's user IDs and their real names being in account information under any Linux/Unix system on your network (print server, NAS, anything you can get privileged shell access to), then you might have an easier go of it, given the text-processing tools available to bash in Linux/Unix (including macOS), like grep and sed and awk. All you'd need is a command-line tool for accessing LDAP (or whatever) to run directory queries, then parse the results for name information. Or that name info might even already exist in that Linux box's passwd file. This was how I did something similar for one client, but it was a Linux-heavy shop. If you have any (or most) users isolated from Linux in a Windows-only sphere of users, then this approach would not work.[/aside]
It looks like accessing AD data (or LDAP, whatever) in Windows with Windows-based scripting/programming is the only certain way to do what you want to do. Even then, it will only work if the data is present and correct. You'd need group policy that doesn't permit people to change their names (e.g. by removing their surname) once their account is configured, and human procedural rules that admins must enter this data when setting up accounts, and that it be correct and complete (not missing surname, and not be placeholder or role data that might be substituted out later or might even occur on multiple machines).
PS: Ultimately, I think you should write to the creators of that software and ask them to stop using first and last names in paths, as it breaks the administrability of their product.

How to programmatically find the domain controller/primary domain controller?

I'd like to know how to determine, in a running application, the domain controller/primary domain controller of the Windows workstation or server on which the application is running, using Win32 APIs.
In particular, given a machine's hostname, I want to find the name of the authoritative source of resolving that hostname to a particular machine. (I think that's the domain controller; my knowledge of this area is pretty weak so I may be asking the question the wrong way.).
I've seen a C# code fragment that purportedly does this, but don't know if there is any relation to Win32 APIs. There's lots of "how to get DC" web pages, but they are all invoking command scripts, not the APIs.
Happy to have code, but willing to do the homework on extracting the steps, if somebody points me in the right direction.
Is there an analog in Linux? (e.g., native calls to find a name server? I'm not assuming a Linux context with a Windows domain controller).
(Aha... just discovered this question: Get the domain name of a computer from Windows API. Will dig into it some more. EDIT: Maybe the function I want is NetDCName? Where do I get the parameters that it wants?).
EDIT April 19: I coded/tested NetDCName using Eric's hints. Yes, it produces the domain controller name when there is one,
and an error signal when there is not, which is just the right functional behavior.
However, the function call seems to take several seconds! Why would that be?
That puts an unacceptable, user-visible delay in a check I'm trying to do.
NetGetDCName is one option; if you need more functionality, DsGetDcName is also an option.
The MSDN documentation clearly states that NULL is used to indicate the default, so
nStatus = NetGetDCName(NULL, NULL, (LPBYTE *) &lpDcName);
would return the domain controller for the default domain on the local computer.

How can I execute a WHOIS query for all domains registered in a given time period in a given TLD using Ruby?

I'm trying to understand how WHOIS works. I know there are third-parties and Gems that abstract this functionality, but I want to have some basic understanding of what goes on. Thus, I'm interested in how to do this in the most direct manner using only standard Ruby libraries and going straight to the direct source. As a test use case, I'd like to be able to pull the 10 most recent .COM domains registered which would give me a model to understand how to query for a list of all the domain names registered in a given time period on a given TLD. It is my understanding that IANA would point me to Verisign for a .COM query, so, if that is correct and I should be querying Versign, what do I ask Verisign and how would I execute this query in Ruby? As well, what documentation or reference could I have used to figure this out myself (I ask because I had trouble finding any). Thanks.
Normally, you can't know the last N domains created for a specific .TLD unless the registry authority for that specific TLD provides you access to this information.
And AFAIK, this is a feature that no registry currently provide.
Some registries gives the ability to download a list of all registered domains for a TLD to some authorized partners. This feature is normally very expensive and useful only if you need to know at any time what and how many domains exist for a specific TLD.
Keep in mind this authorization is really expensive and it must be approved by the registry, given that the TLD you want to monitor belongs to a registry that supports this feature.
You cited Verisign. Verisign provides a TLD ZONE FILE ACCESS PROGRAM, but this is not something you have access for free through their public WHOIS interface.

List of Win32 APIs that require administrative privilege

I'm trying to find a list of Win32 API functions that require the process that uses them to have heightened administrative privileges in order to use them. Does anyone know where I could find a list of these functions? Thanks!
Such a list simply does not and can not exist. Because an API alone does not determine what privileges are required (it can, but in most cases it doesn't).
For example take one of the oldest and most used APIs there is: CreateFile.
Reading a file in the windows directory is allowed for normal users, writing/creating one however isn't.
Using the API to create a local pipe
is allowed for normal users, creating
a global pipe or networked pipe
usually isn't (depends on further
security settings/group policies).
And many more examples.

Best practice for storing cross domain web service access credentials?

I'm working on an application that will connect to various remote servers using a Web Service to retrieve some status information about those ( Windows ) machines.
It works well within a single domain where we can just use Windows Authentication and ensure that the user calling the services has the correct credentials. However if we are working across domains that is not going to work- we're going to need to store a set of credentials for a user with the requisite rights on the application side.
Is there a standard way of storing credentials for these purposes, some kind of central password store in Windows or a handy built in library to provide this kind of functionality? If not, what is the best approach to keeping the passwords on the central machine safe and make sure the remote machine credentials are available when those services need to be called?
I would expect this application to mostly be installed on one of the Windows Server operating systems- 2003 or 2008 - if that makes any difference to what is available.
I suggest you have a look at "Windows Identity Foundation". It may be overkill for you, or the prerequisite may not match, but it's anyway worth reading as its very instructive in terms of claims based architecture with Microsoft technology.
The two principal white papers for developers are:
Overview of the Claims Based Architecture
Microsoft Windows Identity Foundation (WIF) Whitepaper for Developers
I assume that this is not a question of Silverlight or Flash application, those would have some special things...
I have used authentication system by Federation of Finnish Financial Services (used by all major Finnish banks). It goes like this:
Both your client and server have a secret key (or 2 keys).
You can store it e.g. to a custom place in Windows registry (which is easy with .NET and you can control the registry access). Don't hard-code the key to code, because otherwise someone could use reflection to get it. Also a custom xml-file in a folder could be dangerous, if the platform is not secure enough.
Then, we have the request, let's say WebService REST Url and there is some id:
http://myserver/MyItems/15
Now, we need to use a timestamp and an one-way hash-algorithm.
There are lot of available ones like md5, SHA1, SHA512, ...
(also built-in to the Microsoft .NET library).
We calculate a hash-value over the id and timestamp (and maybe some other parameters).
To simplify a bit, those algorithms work like modulo-algorithm: Let's say that my id is 11, secret key is 3, then modulo 11 % 3 = 2, now the hash would be 2, and if you know the id (11) and hash (2), you can't get the secret key.
The real request would be like this:
http://myserver/MyItems/15?timestamp=20110304171900&hash=89A234BA645FD56
The service will check the hash. If some hackers would have enough time, they could guess valid requests.
But the service will also check if the timestamp is ok, like between 5min past and 5min future.
So you can't adjust the request because it would modify the hash.
And of course one more thing is to use the SSL protocol. Otherwise your requests could be read from a random proxy server.
I would also recommend the Windows Identity Foundation, but this is another option.

Resources