|
Hello, I have been working on a application to help us better manage our network. The application is for myself and one other person at our agency. Everything is working fine, but doing this one thing (getting list of users) from LDAP remotely is very slow. Now I know it will be slower than normal, but how I have coded it might freak some of you out, and see how I could make what I am trying to do quicker.
I have used alot of the LDAP/AD coding from an article on this site (codeproject).
Thanks to:
http://www.codeproject.com/KB/system/everythingInAD.aspx[^]
First,
I have a ListView control that populates with every user. Every user has a icon (man icon) that either has a lock symbol (if the user is locked), a X symbol on it (if the user is disabled), or nothing if the user does not have either one of those.
1. Here is what it is doing when Adding to the ListView Control:
private delegate void AddListItemDelegate();
void AddListItem()
{
if (listViewUsers.InvokeRequired)
{
listViewUsers.Invoke(new AddListItemDelegate(AddListItem));
}
else
{
if (!UseAuth) adPrincipalContext = new PrincipalContext(ContextType.Domain, Properties.Settings.Default.LDAP);
else adPrincipalContext = new PrincipalContext(ContextType.Domain, Properties.Settings.Default.LDAP,
(string)Encoding.Unicode.GetString(Convert.FromBase64String((string)Properties.Settings.Default.LDAPusername)),
(string)Encoding.Unicode.GetString(Convert.FromBase64String((string)Properties.Settings.Default.LDAPpassword)));
UserPrincipal user = new UserPrincipal(adPrincipalContext);
user.Name = "*";
PrincipalSearcher pS = new PrincipalSearcher();
pS.QueryFilter = user;
PrincipalSearchResult<Principal> results = pS.FindAll();
listViewUsers.Items.Clear();
ListViewItem listItem;
foreach (Principal result in results)
{
AD newAD = new AD(result.Name);
bool Locked = newAD.IsLocked();
bool Enabled = newAD.IsEnabled();
string Branch = newAD.branch;
listItem = new ListViewItem(result.Name);
listItem.ToolTipText = "Sid: " + result.Sid;
if (Enabled)
{
if (Locked) listItem.ImageIndex = 1;
else listItem.ImageIndex = 0;
}
else listItem.ImageIndex = 2;
bool found = false;
if (String.IsNullOrEmpty(Branch)) Branch = "Unknown";
foreach (ListViewGroup g in listViewUsers.Groups)
{
if (g.Header == Branch) {
found = true;
listItem.Group = g;
break;
}
}
if (!found)
{
ListViewGroup g = new ListViewGroup(Branch, Branch);
listViewUsers.Groups.Add(g);
listItem.Group = g;
}
listViewUsers.Items.Add(listItem);
}
}
}
So what I have this doing is getting a list of users from AD, but also going to my AD class to see if the user is LOCKED or DISABLED. This is what is happening behind the AD class:
try
{
using (DirectoryEntry root = new DirectoryEntry())
{
root.Path = LDAP;
if (UseAuth)
{
root.Username = (string)Encoding.Unicode.GetString(Convert.FromBase64String((string)Properties.Settings.Default.LDAPusername));
root.Password = (string)Encoding.Unicode.GetString(Convert.FromBase64String((string)Properties.Settings.Default.LDAPpassword));
}
using (DirectorySearcher searcher = new DirectorySearcher())
{
searcher.SearchRoot = root;
searcher.SearchScope = SearchScope.Subtree;
searcher.Filter = "(&(objectClass=user)(name=" + this.userName + "))";
searcher.PropertiesToLoad.Add("mail");
searcher.PropertiesToLoad.Add("department");
searcher.PropertiesToLoad.Add("company");
searcher.PropertiesToLoad.Add("physicalDeliveryOfficeName");
searcher.PropertiesToLoad.Add("telephoneNumber");
SearchResultCollection results = searcher.FindAll();
if (results != null)
{
foreach (SearchResult result in results)
{
ResultPropertyCollection props = result.Properties;
foreach (string propName in result.Properties.PropertyNames)
{
if (propName == "mail") mail = props[propName][0].ToString();
else if (propName == "department") branch = props[propName][0].ToString();
else if (propName == "company") division = props[propName][0].ToString();
else if (propName == "physicalDeliveryOfficeName") office = props[propName][0].ToString();
else if (propName == "telephoneNumber") officenumber = props[propName][0].ToString();
else if (propName == "adspath") adspath = props[propName][0].ToString();
}
}
}
searcher.Dispose();
root.Close();
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
So what I am doing here is using the username provided from the previous class and passing it to here to set the username and password. If you look in the previous code you will see this:
AD newAD = new AD(result.Name);
bool Locked = newAD.IsLocked();
bool Enabled = newAD.IsEnabled();
The code I have for checking if it is locked:
public bool IsLocked()
{
try
{
DirectoryEntry uEntry;
if (UseAuth) uEntry = new DirectoryEntry(this.adspath, (string)Encoding.Unicode.GetString(Convert.FromBase64String((string)Properties.Settings.Default.LDAPusername)), (string)Encoding.Unicode.GetString(Convert.FromBase64String((string)Properties.Settings.Default.LDAPpassword)));
else uEntry = new DirectoryEntry(this.adspath);
bool Locked = Convert.ToBoolean(uEntry.InvokeGet("IsAccountLocked"));
uEntry.Close();
if (Locked) return true;
else return false;
}
catch (DirectoryServicesCOMException ex)
{
return false;
}
}
and
public bool IsEnabled()
{
DirectoryEntry uEntry;
if (UseAuth) uEntry = new DirectoryEntry(this.adspath, (string)Encoding.Unicode.GetString(Convert.FromBase64String((string)Properties.Settings.Default.LDAPusername)), (string)Encoding.Unicode.GetString(Convert.FromBase64String((string)Properties.Settings.Default.LDAPpassword)));
else uEntry = new DirectoryEntry(this.adspath);
int val = (int)uEntry.Properties["userAccountControl"].Value;
uEntry.Close();
if (val == (val & ~0x2)) return true;
else return false;
}
So basically what I am doing is querying LDAP, getting a list of users, then going through each user and querying LDAP AGAIN for all of that USERS information, THEN with that information, querying LDAP again to see if the accounts unlocked, THEN querying LDAP again to see if the account is DISABLED.
So my question is... how exactly would I clean this up? I am new to using C# with AD and trying to make it work. Well it does work fine when on the internal network, its slow outside. I know it can be coded better and I'm not asking anyone to do it, just point me (or shove me) in the right direction to what I should change LOL.
Thanks in advanced!
|
|
|
|
|
Jacob Dixon wrote: how exactly would I clean this up?
what is that you want to clean up?
Yusuf
Oh didn't you notice, analogous to square roots, they recently introduced rectangular, circular, and diamond roots to determine the size of the corresponding shapes when given the area. Luc Pattyn[^]
|
|
|
|
|
Well, the code works. I just think there would be an easier way / quicker way to get the information. Basically I am getting if the account is locked out, disabled, and the name and department. How I am doing this involves calling DirectoryEntry multiple times. When going through each name I'm wondering if I can get this information from the same DirectoryEntry all at the same time.
|
|
|
|
|
Ok I have modified it to do it all in one method... but its pulling computer objects too????
void AddListItemTest()
{
using (DirectoryEntry root = new DirectoryEntry())
{
root.Path = "LDAP://" + Properties.Settings.Default.LDAP;
root.Username = "****";
root.Password = "*****";
using (DirectorySearcher searcher = new DirectorySearcher())
{
searcher.SearchRoot = root;
searcher.SearchScope = SearchScope.Subtree;
searcher.Filter = "(&(objectClass=user))";
searcher.PropertiesToLoad.Add("department");
searcher.PropertiesToLoad.Add("name");
searcher.PropertiesToLoad.Add("userAccountControl");
searcher.PropertiesToLoad.Add("lockoutTime");
SearchResultCollection results = searcher.FindAll();
if (results != null)
{
foreach (SearchResult result in results)
{
ResultPropertyCollection props = result.Properties;
string Branch = "Unknown";
string Name = "";
int val = 0;
long ticks = 0;
foreach (string propName in result.Properties.PropertyNames)
{
if (propName == "name") Name = props[propName][0].ToString();
else if (propName == "department") Branch = props[propName][0].ToString();
else if (propName == "useraccountcontrol") val = (int)props[propName][0];
else if (propName == "lockouttime") ticks = (long)props[propName][0];
}
ListViewItem listItem = new ListViewItem(Name);
bool Locked;
if (ticks > 0) Locked = true;
else Locked = false;
if (val != (val & ~0x2)) listItem.ImageIndex = 2;
else if (Locked) listItem.ImageIndex = 1;
else listItem.ImageIndex = 0;
bool found = false;
foreach (ListViewGroup g in listViewUsers.Groups)
{
if (g.Header == Branch)
{
found = true;
listItem.Group = g;
break;
}
}
if (!found)
{
ListViewGroup g = new ListViewGroup(Branch, Branch);
listViewUsers.Groups.Add(g);
listItem.Group = g;
}
listViewUsers.Items.Add(listItem);
}
}
}
}
}
|
|
|
|
|
Ok what I did was change the filter to:
(&(objectcategory=person)(objectclass=user))
from
(&(objectClass=user))
Why would coputer objects show in the user class?
|
|
|
|
|
Exactly what would be the best way to test if the LDAP server exist? I see the DirectoryEntry.Exist, but its pretty slow to come back with an answer. Should I use TCP?
|
|
|
|
|
I amusing windows 2003 server in that lotus
I am writing a code in c# VS05 for email sending and receiving via lotus notes and dominal server but.....
SMTP not getting configurated...?
giving error as-
Error is Root is not finding...
Whats the actual problem....?
modified on Saturday, March 21, 2009 4:47 PM
|
|
|
|
|
Why are you asking this question in a C# Forum?
There is no Lotus Notes Forum, but you might have tried the Notes help Forum. ON THE NOTES SITE.
Henry Minute
Do not read medical books! You could die of a misprint. - Mark Twain
Girl: (staring) "Why do you need an icy cucumber?"
“I want to report a fraud. The government is lying to us all.”
|
|
|
|
|
I have RSA public key for encyption, and plain data size (8 byte).
How do I calculate the size of encrypted data?
Please help!
|
|
|
|
|
It would help to suggest an answer if you said why you want to know the size of the encrypted data?
Henry Minute
Do not read medical books! You could die of a misprint. - Mark Twain
Girl: (staring) "Why do you need an icy cucumber?"
“I want to report a fraud. The government is lying to us all.”
|
|
|
|
|
Hello,
How we can Convert String to set it on richBox, i try for MailMessage2.Text = "eeeeeeee"; but there are an exception : Object reference not set to an instance of an object, thank you verry mutch.
|
|
|
|
|
Have you actually created an instance of MailMessage2?
DaveBTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)Visual Basic is not used by normal people so we're not covering it here. (Uncyclopedia)
|
|
|
|
|
no, how i van make this?? thank you verry mutch.
|
|
|
|
|
This is very basic stuff - you really should work through some online getting started articles/blogs and buy a book or ten.
Assuming MailMessage2 is your RichTextBox:
RichTextBox MailMessage2 = new RichTextBox();
DaveBTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)Visual Basic is not used by normal people so we're not covering it here. (Uncyclopedia)
|
|
|
|
|
Does your code look like this:
public Form1()
{
MailMessage2.Text = "eeeeeeee";
InitializeComponent();
}?
change it to
public Form1()
{
InitializeComponent();
MailMessage2.Text = "eeeeeeee";
}
If it' stuck, DO NOT pull harder!
|
|
|
|
|
abbd wrote: thank you verry mutch.
"Thank you very much."
I've noticed it on all you're posts.
hmmm pie
|
|
|
|
|
I'm just starting to look at creating a Rijndael encryption library to encrypt strings and files (input and output file name). However, since this is just for my personal use the key is stored right in the library. I'm trying to look into a way to be able to use this library but store the encryption key securely to use for encryption, and decryption. Or would asymmetric encryption be better? What articles would you recommend to look at for either case for key, and possibly init vector storage either on CodeProject or elsewhere?
I've been trying to find some simple articles that are very good, but maybe I'm not using the correct search terms.
Thanks
Revolutionary: Disk drives go round and round.
|
|
|
|
|
1. Rijndael algorithm is already implemented in C# Stdlib.
2. The whole purpose of having key is to NOT writing it down. For example you can generate it from password. Lets say you have a password "foobar". To encrypt data you get hashcode from you password and you use it as key, then to decrypt the data, you will just get hash from password again. So, what's the point of keeping key?
|
|
|
|
|
Right, I was just starting to research this topic. I'm new to this so I was trying to get it to work any way I could at first and then as I learn more, the library would become more mature and secure. I will look into generated a key from a password. It seems there is an object type called PasswordDerivedBytes as I searched a little last night. I am looking for a way to keep the key secure as I know it's not good to store it. So now when I use this with a website or program, the password will simply need to be passed in to generate the key in the code for encrypting decrypting if I am understanding this correctly. Thanks for that suggestion, I will attempt to put it to use.
Hope you had a great weekend.
Revolutionary: Disk drives go round and round.
|
|
|
|
|
Hello, i try for this :
<br />
System.Windows.Forms.TextBox To;<br />
mail_message.To = To.Text;<br />
<br />
But i have this error :An object reference is required for the non-static field, method, or property , can uou help me? thank you verry mutch.
|
|
|
|
|
System.Windows.Forms.TextBox To = new System.Windows.Forms.TextBox();
DaveBTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)Visual Basic is not used by normal people so we're not covering it here. (Uncyclopedia)
|
|
|
|
|
Hello i have this error : Error 6 The name 'Invoke' does not exist in the current context i do this :
<br />
if (statusStrip.InvokeRequired)<br />
{<br />
ConnectEventHandler con = new ConnectEventHandler(smtp_ConnectionEstablished);<br />
Invoke(con, new object[] { sender, Server, Port });<br />
}<br />
Help me please, thank you verry mutch.
|
|
|
|
|
You are trying to call Invoke on the class that this code is in.
It appears you might mean statusStrip.Invoke(...
DaveBTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)Visual Basic is not used by normal people so we're not covering it here. (Uncyclopedia)
|
|
|
|
|
HOW TO SEND A MESSAGE BY CHANGING THEIR VALUES ACCORDING TO THE PERMUTATION values.
|
|
|
|
|
Great subject. What does that mean?
Same goes with the post. Be descriptive and adhere to the rules.
जय हिंद
|
|
|
|