In a domain with AD Sites and Services configured is it possible to get the Site of a computer from LDAP? Is it stored as an attribute?
Unless this has changed over the last couple of years outside of my knowledge, there is not. Historically this was never done as AD site knowledge was ephemeral...the assumption was that computers move around so storing where they are is silly. Plus there was no global need for the knowledge.
You could of course add this. By this i mean, you could do something like, extend the schema with a new attribute for this and set a start-up script on your domain-joined machines to write this (if it has changed since they last wrote) to the directory. Obviously you'll want to test this well to ensure it doesn't create more problems than it solves...
On the Win32 point of view you've got the DsAddressToSiteNamesEx API. I don't know how to find it using pure LDAP.
Related
I have been assigned a task to export the AD Attributes than find out what systems are using these attributes. I have not had much luck in scripting or a tool that can provide just that. Is this feasible and if so how? I have already exported attributes. Just need to find what systems are using them.
This isn't possible with any reasonable accuracy, especially if "using" isn't defined for you.
The event logs on the domain controllers will tell you where login events are coming from, but only by IP. That doesn't tell you which application is authenticating. You would have to do monitoring on that computer and see which application is making the connection. But then the logs would be cluttered with connections made by Windows itself, or Exchange (if you use Exchange for email). It it would be very difficult to identify what is coming from an 3rd-party application rather than Windows itself.
Also, applications can request more information than they need. It's very easy when programming with LDAP to request every attribute for an object, even if you only intend to use one. For example, take this C# code:
var de = new DirectoryEntry("LDAP://example.com");
Console.WriteLine(de.Properties["name"].Value);
That only "uses" the name attribute. But because of the way LDAP works, it actually requests every non-constructed attribute that has a value. (there is a way to specifically ask for only one attribute, but you have to know that and use that)
So even if you could find logs saying that "this IP requested all of these attributes", and then figure out which application made that request, that doesn't mean it "used" all of those attributes.
I am currently trying to find out AD users password expiry date.
Using the methods described on numerous pages for e.g. here work fine until a user or group in AD is using a fine grained password policy that does not follow the users domain password policy.
I found a property called msDS-UserPasswordExpiryTimeComputed that figures that all out without trying to do any calculations.
This works well, until we are using a global catalog since this property is not replicated by default. When I attempting to replicate the msDS-UserPasswordExpiryTimeComputed property in my global catalog, I get the following error:
Is there anyway to replicate this property or is something wrong with my setup that is not allowing me to replicate this property? Is there a better way to calculate user password expiry to take into account the fine grained password policy?
I suspect you can't. I can't find any authoritative documentation saying it is not possible, but here are the reasons I think it's not possible:
The attribute is constructed, meaning it's not stored, but it's calculated at the time you ask for it.
The date depends on the policy on the domain, thus the server returning the data needs to know the policy on the domain of the user.
Since a GC may not be on the domain of the user you find, it may not have the information needed to be able to calculate the value.
As a workaround, you can just rebind to a DC to get the value. You didn't say which language you're working with, but usually you can take the path of the object you found, which will start with "GC://", and just replace that with "LDAP://". Then grab the msDS-UserPasswordExpiryTimeComputed value.
OK, so I did the dumb thing and released production code (C#, VS2010) that targeted our development database (SQL Server 2008 R2). Luckily we are not using the production database yet so I didn't have the pain of trying to recover and synchronize everything...
But, I want to prevent this from happening again when it could be much more painful. My idea is to add a table I can query at startup and determine what database I am connected to by the value returned. Production would return "PROD" and dev and test would return other values, for example.
If it makes any difference, the application talks to a WCF service to access the database so I have endpoints in the config file, not actual connection strings.
Does this make sense? How have others addressed this problem?
Thanks,
Dave
The easiest way to solve this is to not have access to production accounts. Those are stored in the Machine.config file for our .net applications. In non-.net applications this is easily duplicated, by having a config file in a common location, or (dare I say) a registry entry which holds the account information.
Most of our servers are accessed through aliases too, so no one really needs to change the connection string from environment to environment. Just grab the user from the config and the server alias in the hosts file points you to the correct server. This also removes the headache from us having to update all our config files when we switch db instances (change hardware etc.)
So even with the click once deployment and the end points. You can publish the a new endpoint URI in a machine config on the end users desktop (I'm assuming this is an internal application), and then reference that in the code.
If you absolutely can't do this, as this might be a lot of work (last place I worked had 2000 call center people, so this push was a lot more difficult, but still possible). You can always have an automated build server setup which modifies the app.config file for you as a last step of building the application for you. You then ALWAYS publish the compiled code from the automated build server. Never have the change in the app.config for something like this be a manual step in the developer's process. This will always lead to problems at some point.
Now if none of this works, your final option (done this one too), which I hated, but it worked is to look up the value off of a mapped drive. Essentially, everyone in the company has a mapped drive to say R:. This is where you have your production configuration files etc. The prod account people map to one drive location with the production values, and the devs etc. map to another with the development values. I hate this option compared to the others, but it works, and it can save you in a pinch with others become tedious and difficult (due to say office politics, setting up a build server etc.).
I'm assuming your production server has a different name than your development server, so you could simply SELECT ##SERVERNAME AS ServerName.
Not sure if this answer helps you in a assumed .net environment, but within a *nix/PHP environment, this is how I handle the same situation.
OK, so I did the dumb thing and released production code
There are a times where some app behavior is environment dependent, as you eluded to. In order to provide this ability to check between development and production environments I added the following line to global /etc/profile/profile.d/custom.sh config (CentOS):
SERVICE_ENV=dev
And in code I have a wrapper method which will grab an environment variable based on name and localize it's value making it accessible to my application code. Below is a snippet demonstrating how to check the current environment and react accordingly (in PHP):
public function __call($method, $params)
{
// Reduce chatter on production envs
// Only display debug messages if override told us to
if (($method === 'debug') &&
(CoreLib_Api_Environment_Package::getValue(CoreLib_Api_Environment::VAR_LABEL_SERVICE) === CoreLib_Api_Environment::PROD) &&
(!in_array(CoreLib_Api_Log::DEBUG_ON_PROD_OVERRIDE, $params))) {
return;
}
}
Remember, you don't want to pepper your application logic with environment checks, save for a few extreme use cases as demonstrated with snippet. Rather you should be controlling access to your production databases using DNS. For example, within your development environment the following db hostname mydatabase-db would resolve to a local server instead of your actual production server. And when you push your code to the production environment, your DNS will correctly resolve the hostname, so your code should "just work" without any environment checks.
After hours of wading through textbooks and tutorials on MSBuild and app.config manipulation, I stumbled across something called SlowCheetah - XML Transforms http://visualstudiogallery.msdn.microsoft.com/69023d00-a4f9-4a34-a6cd-7e854ba318b5 that did what I needed it to do in less than hour after first stumbling across it. Definitely recommended! From the article:
This package enables you to transform your app.config or any other XML file based on the build configuration. It also adds additional tooling to help you create XML transforms.
This package is created by Sayed Ibrahim Hashimi, Chuck England and Bill Heibert, the same Hashimi who authored THE book on MSBuild. If you're looking for a simple ubiquitous way to transform your app.config, web.config or any other XML fie based on the build configuration, look no further -- this VS package will do the job.
Yeah I know I answered my own question but I already gave points to the answer that eventually pointed me to the real answer. Now I need to go back and edit the question based on my new understanding of the problem...
Dave
I' assuming yout production serveur has a different ip address. You can simply use
SELECT CONNECTIONPROPERTY('local_net_address') AS local_net_address
Has anyone made any headway with coming up with a single sign on solution
with Domain access to date for Drupal 7? I've been looking closely at two old
modules, one no longer maintained (SSO for D6) and one still maintained (CAS). I've also read that SAML might be a key to unlocking this, but am uncertain.
Facebook's FBConnect might be another option too or another way could be integrating OpenID from what I've read, and experienced on StackOverflow's sub sites.
I know that OpenID can do this since we are logged into all of *Overflows sub sites at the same time using one login. The question is how does it cross DNS servers? Does it handshake with one half of a matching hash? I cannot find any documentation on this, so am at a loss.
So, are there any solutions that are known to date, or information on what to start
looking into? I think I've made a good point at the possibilities. I read this thread, Domain Access SSO but am uncertain to what version it pertains to (Drupal. DA, SSO or otherwise). It looks like the "Solution" is to create a master table set with users and permissions, then share those across the domains? How might this work if there are already multiple sites created under Domain Access? Would you clone and rebuild the entire installation, or would you need to start from scratch? It really raises more questions than answers. I contacted the author with no response, so the questions still stand.
Any opinions out there on the who what or why would be greatly appreciated, I just need a start point to get the ball rolling. Thanks everyone.
I'm the author of the Domain Access SSO article mentioned in the original question. I don't recall being contacted about it, but then again I recently learned that my "contact" page on bleen.net hasn't been working in a while... but anyway, here is a bit of info:
That post referred to Drupal 6, SSO Module 6.x-1.0-rc1, and Domain Access module 6.x-2.0 (I think). That solution basically revolves around creating two separate drupal installs, one the master and one the client (there can be multiple clients). Basically, what happens is the necessary user tables for all teh clients are pointed instead to the master. In doing so, the master becomes (essentially) a shell site that does nothing but hold and verify user data.
Hope that makes sense and/or helps... to be honest i havent looked at that code in a long while now.
SAML is a good option. Check this module to integrate it with drupal:
http://drupal.org/project/simplesamlphp_auth
If you need a demo with this plugin working check this.
I'm asking your opinions about my next project..
I'm planning to make website which offers services where all users would be have own subdomain (user.mydomain.com) and own website.
First I was thinking to really make real subdomain, generating automatically website code into their folder, creating own database etc..
Question #1: When I need some information from all subdomains databases in my main page (mydomain.com), how can I fetch those?
Would it be better way just use one database and dynamic code what all users are using but then re-write address like it would be subdomain (mydomain.com?user=myuser -> myuser.mydomain.com)
If someone have experience with something like what I was planning, would be nice to have tips and tricks do it right! :)
Thanks!
It will be alot of less code to maintain in you have one common codebase for all users, that just reads the domain name and uses that information.
Imagine that you discover an error in the code that was generated for one of the subdomains.
Either you would have one place to correct, or you would have 1 place + the number of users to correct.
You'll probably want all of the subdomains to point to the same codebase and treat the subdomain as an argument that is pulled out and identifies which instance of this application it is. You'll need a table in your db that will store information about each instance and then user accounts, user data, etc will all be tied back to a specific instance.