|
-
Aug 7th, 2008, 12:24 PM
#1
Thread Starter
Frenzied Member
Trying to understand accessing AD through VB.NET...
...and failing miserably...
I am trying to get to data in a group called _All Employees that is under Users, and I have no idea how to do it. I can see Users, but I don't understand how I drill down to the next level.
Code:
deDirectoryEntry = New DirectoryEntry
deDirectoryEntry.Path = "LDAP://ADServer/CN=Users;DC=MyDomain,DC=com"
deDirectoryEntry.Username = "MyDomain\ReadOnlyUser"
deDirectoryEntry.Password = "password"
Dim oSearcher As New DirectorySearcher
Dim srcResults As SearchResultCollection
oSearcher.SearchRoot = deDirectoryEntry
oSearcher.Filter = "(&(objectClass=user) (cn=" & strUserName & "))"
srcResults = oSearcher.FindAll()
For Each result As SearchResult In srcResults
...
And so on. I don't really understand the navigation here. How do I get down to the _All Employees group beneath this which has the user info I need. Any help would be appreciated. This stuff confuses the hell out of me.
Last edited by SeanGrebey; Aug 14th, 2008 at 12:43 PM.
Sean
Some days when I think about the next 30 years or so of my life I am going to spend writing code, I happily contemplate stepping off a curb in front of a fast moving bus.
-
Aug 7th, 2008, 12:50 PM
#2
Re: Trying to understand accessing AD through VB.NET...
For a start, can you put your code in CODE tags or HIGHLIGHT="vb.net" tags so that its a bit more readable 
Anyway yeah, are you just trying to get a list of users that are in a specific group or something? I mean, at the moment you are searching for User accounts only so thats not going to find a Group for you...Tell me exactly what you want to retrieve and I'll try help you out
-
Aug 7th, 2008, 01:04 PM
#3
Thread Starter
Frenzied Member
Re: Trying to understand accessing AD through VB.NET...
 Originally Posted by chris128
For a start, can you put your code in CODE tags or HIGHLIGHT="vb.net" tags so that its a bit more readable
Anyway yeah, are you just trying to get a list of users that are in a specific group or something? I mean, at the moment you are searching for User accounts only so thats not going to find a Group for you...Tell me exactly what you want to retrieve and I'll try help you out 
There is a group under Users called _All Employees. So if I look at Active Directory, it is MyDomain.Com->Users->_All Employees
The _All Employees group has records with all the employee information in it. I am trying to extract phone numbers from those records to post to our intranet site.
Sean
Some days when I think about the next 30 years or so of my life I am going to spend writing code, I happily contemplate stepping off a curb in front of a fast moving bus.
-
Aug 7th, 2008, 01:22 PM
#4
Re: Trying to understand accessing AD through VB.NET...
OK so you want to find all of the users from a specific group, then for each user in that group you want to extract the phone number attribute yeah? Also, is this a distribution list group or a normal security group?
-
Aug 7th, 2008, 01:30 PM
#5
Re: Trying to understand accessing AD through VB.NET...
OK, this will find all of the members of a specific group, you just need to change the lines that I have added a comment above to suit your AD. Getting the phone number attribute of each user shouldnt be difficult now that you have the full distinguished name (path) of each user account.
vb Code:
Dim GroupSearcher As New DirectorySearcher
'<<<<< Change the line below to your domain and your domain admin details >>>>>>
Dim GroupSearchRoot As New DirectoryEntry("LDAP://CN=Users,DC=yourdomainname,DC=local", "Your_Domain_Admin", "Admin_Password")
With GroupSearcher
.SearchRoot = GroupSearchRoot
.Filter = "(&(ObjectClass=Group)(CN=_All Employees))"
End With
Dim Members As Object = GroupSearcher.FindOne.GetDirectoryEntry.Invoke("Members", Nothing)
For Each Member As Object In CType(Members, IEnumerable)
Dim CurrentMember As New DirectoryEntry(Member)
ListBox1.Items.Add(CurrentMember.Name.Remove(0, 3))
Next
Notice that I'm just adding the list of users to a listbox named Listbox1 so if you wanted to try my code out you would need to add a listbox with the same name to your form.
OK so as you said you were trying to understand how this works, I'll give you a bit of an explanation 
This first 2 lines of the code are just declaring the search object and the root of the search and passing in the username/password.
In the next part of the code, I am just setting a couple of properties of the searcher object. Namely, the SearchRoot property so that it knows where to look in AD (this saves it from searching all of the containers and OUs). The other property, Filter, is used to construct an LDAP filter that tells the searcher we only want to look for objects that are Groups and that we only want to look for objects that have a CN (Common Name) that matches our group name. Pretty simple stuff yeah?
The next line:
Code:
Dim Members As Object = GroupSearcher.FindOne.GetDirectoryEntry.Invoke("Members", Nothing)
is what actually gets the list of members from the object that was returned by the search. We could make this look a bit simpler by doing something like this instead but it still acheives the exact same result:
vb Code:
Dim Result As SearchResult = GroupSearcher.FindOne
Dim Members = Result.GetDirectoryEntry.Invoke("Members", Nothing)
Then all we do is loop through the collection of members and create a new DirectoryEntry object for each one, which then allows us to use the DirectoryEntry's Name property to retrieve the user's CN (common name).
Oh and in case your wondering - The Name property always has "CN=" prefixed to it so thats why I use Name.Remove(0,3) instead of just Name when adding it to the listbox.
So! I've done the hard work for you, now if you want to get all of the users telephone numbers then all you need to do is use the collection of CNs that you retrieve from my code. Instead of adding the Name property to a listbox, you would use the Properties property (confusing huh) to find specific attributes on the AD account. I'll give you a tip, the phone number attribute's exact name is just "telephoneNumber" and the mobile phone number attribute is just "mobile".
That help? 
Chris
Last edited by chris128; Aug 7th, 2008 at 01:48 PM.
-
Aug 7th, 2008, 01:49 PM
#6
Re: Trying to understand accessing AD through VB.NET...
<<Updated my last post with an explanation of how the code works>>
-
Aug 7th, 2008, 01:53 PM
#7
Thread Starter
Frenzied Member
Re: Trying to understand accessing AD through VB.NET...
 Originally Posted by chris128
OK so you want to find all of the users from a specific group, then for each user in that group you want to extract the phone number attribute yeah? Also, is this a distribution list group or a normal security group?
Yep, that's it. Security group.
Sean
Some days when I think about the next 30 years or so of my life I am going to spend writing code, I happily contemplate stepping off a curb in front of a fast moving bus.
-
Aug 7th, 2008, 01:56 PM
#8
Re: Trying to understand accessing AD through VB.NET...
 Originally Posted by SeanGrebey
Yep, that's it. Security group.
I just wrote a gigantic post explaining what you need to do and did pretty much 70% of the work for you ... I'm not doing the rest too
-
Aug 7th, 2008, 01:56 PM
#9
Thread Starter
Frenzied Member
Re: Trying to understand accessing AD through VB.NET...
 Originally Posted by chris128
OK, this will find all of the members of a specific group, you just need to change the lines that I have added a comment above to suit your AD. Getting the phone number attribute of each user shouldnt be difficult now that you have the full distinguished name (path) of each user account.
vb Code:
Dim GroupSearcher As New DirectorySearcher
'<<<<< Change the line below to your domain and your domain admin details >>>>>>
Dim GroupSearchRoot As New DirectoryEntry("LDAP://CN=Users,DC=yourdomainname,DC=local", "Your_Domain_Admin", "Admin_Password")
With GroupSearcher
.SearchRoot = GroupSearchRoot
.Filter = "(&(ObjectClass=Group)(CN=_All Employees))"
End With
Dim Members As Object = GroupSearcher.FindOne.GetDirectoryEntry.Invoke("Members", Nothing)
For Each Member As Object In CType(Members, IEnumerable)
Dim CurrentMember As New DirectoryEntry(Member)
ListBox1.Items.Add(CurrentMember.Name.Remove(0, 3))
Next
Notice that I'm just adding the list of users to a listbox named Listbox1 so if you wanted to try my code out you would need to add a listbox with the same name to your form.
OK so as you said you were trying to understand how this works, I'll give you a bit of an explanation
This first 2 lines of the code are just declaring the search object and the root of the search and passing in the username/password.
In the next part of the code, I am just setting a couple of properties of the searcher object. Namely, the SearchRoot property so that it knows where to look in AD (this saves it from searching all of the containers and OUs). The other property, Filter, is used to construct an LDAP filter that tells the searcher we only want to look for objects that are Groups and that we only want to look for objects that have a CN (Common Name) that matches our group name. Pretty simple stuff yeah?
The next line:
Code:
Dim Members As Object = GroupSearcher.FindOne.GetDirectoryEntry.Invoke("Members", Nothing)
is what actually gets the list of members from the object that was returned by the search. We could make this look a bit simpler by doing something like this instead but it still acheives the exact same result:
vb Code:
Dim Result As SearchResult = GroupSearcher.FindOne
Dim Members = Result.GetDirectoryEntry.Invoke("Members", Nothing)
Then all we do is loop through the collection of members and create a new DirectoryEntry object for each one, which then allows us to use the DirectoryEntry's Name property to retrieve the user's CN (common name).
Oh and in case your wondering - The Name property always has "CN=" prefixed to it so thats why I use Name.Remove(0,3) instead of just Name when adding it to the listbox.
So! I've done the hard work for you, now if you want to get all of the users telephone numbers then all you need to do is use the collection of CNs that you retrieve from my code. Instead of adding the Name property to a listbox, you would use the Properties property (confusing huh) to find specific attributes on the AD account. I'll give you a tip, the phone number attribute's exact name is just "telephoneNumber" and the mobile phone number attribute is just "mobile".
That help?
Chris
That's a huge help Chris, thank you so much.
Sean
Some days when I think about the next 30 years or so of my life I am going to spend writing code, I happily contemplate stepping off a curb in front of a fast moving bus.
-
Aug 7th, 2008, 02:07 PM
#10
Re: Trying to understand accessing AD through VB.NET...
Ah, I'm guessing you didnt see that post before you posted your previous post then
Glad it helped, rating would be nice :P
-
Aug 7th, 2008, 02:10 PM
#11
Thread Starter
Frenzied Member
Re: Trying to understand accessing AD through VB.NET...
 Originally Posted by chris128
I'll give you a tip, the phone number attribute's exact name is just "telephoneNumber" and the mobile phone number attribute is just "mobile".
How do I find these property names if I need to? Thanks!
Sean
Some days when I think about the next 30 years or so of my life I am going to spend writing code, I happily contemplate stepping off a curb in front of a fast moving bus.
-
Aug 7th, 2008, 02:13 PM
#12
Re: Trying to understand accessing AD through VB.NET...
 Originally Posted by SeanGrebey
How do I find these property names if I need to? Thanks!
I'm sure Microsoft have a list somewhere but I use this: http://www.wisesoft.co.uk/Scripts/ac...oryschema.aspx
Just click a part of the image that you want to know the atribute name for, then give it a second to load and scroll down the page a bit to see all the info you need. You will see lots of similar looking things for the same attribute but its the first row of the grid that you want (I think its labelled Attribute Name). You'll see what I mean when you go on it.
-
Aug 7th, 2008, 02:18 PM
#13
Thread Starter
Frenzied Member
Re: Trying to understand accessing AD through VB.NET...
 Originally Posted by chris128
I'm sure Microsoft have a list somewhere but I use this: http://www.wisesoft.co.uk/Scripts/ac...oryschema.aspx
Just click a part of the image that you want to know the atribute name for, then give it a second to load and scroll down the page a bit to see all the info you need. You will see lots of similar looking things for the same attribute but its the first row of the grid that you want (I think its labelled Attribute Name). You'll see what I mean when you go on it.
Ah that's killer. Thanks.
Sean
Some days when I think about the next 30 years or so of my life I am going to spend writing code, I happily contemplate stepping off a curb in front of a fast moving bus.
-
Aug 7th, 2008, 02:22 PM
#14
Re: Trying to understand accessing AD through VB.NET...
 Originally Posted by SeanGrebey
Ah that's killer. Thanks.
Do I deserve a rating yet then :P lol actually I dont think you can rate me yet anyway cos you rated me the other day lol ah well.
-
Aug 7th, 2008, 02:34 PM
#15
Thread Starter
Frenzied Member
Re: Trying to understand accessing AD through VB.NET...
 Originally Posted by chris128
Do I deserve a rating yet then :P lol actually I dont think you can rate me yet anyway cos you rated me the other day lol ah well.
Yeah, I tried and it says I can't rate you again yet.
Sean
Some days when I think about the next 30 years or so of my life I am going to spend writing code, I happily contemplate stepping off a curb in front of a fast moving bus.
-
Aug 7th, 2008, 02:36 PM
#16
Re: Trying to understand accessing AD through VB.NET...
Ah well, no worries. You managed to get the telephone numbers from each member of that group yet? (if so, dont forget to mark the thread resolved )
-
Aug 8th, 2008, 08:50 AM
#17
Thread Starter
Frenzied Member
Re: Trying to understand accessing AD through VB.NET...
 Originally Posted by chris128
Ah well, no worries. You managed to get the telephone numbers from each member of that group yet? (if so, dont forget to mark the thread resolved  )
I did, but my network guy being the helpful person that he is decided to arrange AD differently. He added a "Security Groups - Telecom" at the same level as Users, and added a "Telecom-Employee Lists" group below that. Which has gotten me confused again.
In your example I think I would change it like this:
Code:
Dim GroupSearcher As New DirectorySearcher'
<<<<< Change Users to Security Groups - Telecom >>>>>>
Dim GroupSearchRoot As New DirectoryEntry("LDAP://CN=Security Groups - Telecom,DC=yourdomainname,DC=local", "Your_Domain_Admin", "Admin_Password")
With GroupSearcher
.SearchRoot = GroupSearchRoot
<<<<< Change _All Employees to Telcom-Employee Lists-
.Filter = "(&(ObjectClass=Group)(CN=Telcom-Employee Lists)
End With
<<<<< But it blows up on this line with no such object on this Server >>>>>
Dim Members As Object = GroupSearcher.FindOne.GetDirectoryEntry.Invoke("Members", Nothing)
For Each Member As Object In CType(Members, IEnumerable)
Dim CurrentMember As New DirectoryEntry(Member)
ListBox1.Items.Add(CurrentMember.Name.Remove(0, 3))
Next
Do the spaces mess it up?
Sean
Some days when I think about the next 30 years or so of my life I am going to spend writing code, I happily contemplate stepping off a curb in front of a fast moving bus.
-
Aug 8th, 2008, 09:10 AM
#18
Re: Trying to understand accessing AD through VB.NET...
Spaces wont brake it so your code should work. The only reason it would not work is if you have typed the group's common name in wrong or if you have typed the LDAP path wrong. Check in your AD to see if the Security Groups - Telecom 'folder' is an OU or a Container. If its an OU it will have a different icon to the default top level containers (like Users, Computers, Builtin etc etc). If it IS an OU then you need to change your LDAP path to this:
vb Code:
LDAP://OU=Security Groups - Telecom,DC=yourdomainname,DC=local"
EDIT: Also, is this: CN=Telcom-Employee Lists supposed to be Telecom instead of Telcom?
-
Aug 8th, 2008, 09:45 AM
#19
Thread Starter
Frenzied Member
Re: Trying to understand accessing AD through VB.NET...
 Originally Posted by chris128
Spaces wont brake it so your code should work. The only reason it would not work is if you have typed the group's common name in wrong or if you have typed the LDAP path wrong. Check in your AD to see if the Security Groups - Telecom 'folder' is an OU or a Container. If its an OU it will have a different icon to the default top level containers (like Users, Computers, Builtin etc etc). If it IS an OU then you need to change your LDAP path to this:
vb Code:
LDAP://OU=Security Groups - Telecom,DC=yourdomainname,DC=local"
EDIT: Also, is this: CN=Telcom-Employee Lists supposed to be Telecom instead of Telcom?
How can I tell what it is? It has a different Icon than Users. Users has a plain yellow Microsoft folder, Security Groups - Telecom has a folder with an image on it. I tried changing the com to local, and it fails at the same place with a different error: "A referral was returned from the server."
The Telecom/Telcom is a mispelling in AD, not in the code. I'll have to go back and have him fix it once I figure this out.
Here is my LDAP:
Code:
LDAP://ADServer/CN=Security Groups - Telecom;DC=local
it was
Code:
LDAP://ADServer/CN=Security Groups - Telecom;DC=MyDomain,DC=com
And my filter:
Code:
.Filter = "(&(ObjectClass=Group)(CN=Telcom-Employee Lists))"
Sean
Some days when I think about the next 30 years or so of my life I am going to spend writing code, I happily contemplate stepping off a curb in front of a fast moving bus.
-
Aug 8th, 2008, 09:48 AM
#20
Re: Trying to understand accessing AD through VB.NET...
No what I meant when I said change the LDAP path was change the CN to an OU. Forget about the local or com bit at the end, just set that to whatever your domain is. So, now that you have confirmed that this folder has a different icon to the Users container, that means it is an OU. So for example if your domain was named test.com then you would use this LDAP path:
vb Code:
LDAP://OU=Security Groups - Telecom,DC=test,DC=com
Notice the OU letters infront of Security Groups instead of CN.
CN is used if you are accessing a Container such as Users or Computers, where as OU is used if you are accessing an OU (Organizational Unit) - which is what your Security Groups - Telecom folder is.
Understand what I mean now?
-
Aug 8th, 2008, 09:53 AM
#21
Thread Starter
Frenzied Member
Re: Trying to understand accessing AD through VB.NET...
Ah, ok, I got you. Yeah, that was it, thanks so much Chris, you've saved me a lot of headaches.
Sean
Some days when I think about the next 30 years or so of my life I am going to spend writing code, I happily contemplate stepping off a curb in front of a fast moving bus.
-
Aug 8th, 2008, 09:57 AM
#22
Re: Trying to understand accessing AD through VB.NET... [Resolved]
So is it all working as you want now? Dont forget to mark the thread resolved if thats the case
-
Aug 8th, 2008, 10:04 AM
#23
Thread Starter
Frenzied Member
Re: Trying to understand accessing AD through VB.NET... [Resolved]
 Originally Posted by chris128
So is it all working as you want now?  Dont forget to mark the thread resolved if thats the case 
For the moment....until the network guy decides to reorganize AD again...
Sean
Some days when I think about the next 30 years or so of my life I am going to spend writing code, I happily contemplate stepping off a curb in front of a fast moving bus.
-
Aug 14th, 2008, 12:53 PM
#24
Thread Starter
Frenzied Member
Re: Trying to understand accessing AD through VB.NET...
I'll keep using the same thread, keep it all in one place, but...
Ok now the Network guy wants me to be able to read contacts out of AD also.
The contact is in an Organizationa Unit, so to use the existing code:
Code:
Dim GroupSearcher As New DirectorySearcher
Dim GroupSearchRoot As New DirectoryEntry("LDAP://MyADServer/OU=Test-UPDATE;DC=MyDomain,DC=com")
With GroupSearcher
.SearchRoot = GroupSearchRoot
<<<<< I would think this way but it doesn't like it
.Filter = "(&(ObjectClass=Contact)(CN=test phone list)
End With
<<<<< Blows up here >>>>>
Dim Contacts As Object = oSearcher.FindOne.GetDirectoryEntry.Invoke("Contacts", Nothing)
So the filter has to be different for a contact I am guessing?
Sean
Some days when I think about the next 30 years or so of my life I am going to spend writing code, I happily contemplate stepping off a curb in front of a fast moving bus.
-
Aug 14th, 2008, 01:13 PM
#25
Re: Trying to understand accessing AD through VB.NET...
I dont know off the top of my head but I will try it out... you should do the same lol if your not sure whether or not something is going to work - try it and see. Often it will be quicker than waiting for someone to reply on here. I'm sure it will take me a few trial and error attempts before I get it working so there's no reason why you cant do the same thing.
One thing I would say about your existing code though is that you are trying to invoke a method which does not exist, hence the exception being thrown.
The Invoke method is used to perform API functions in AD that do things that we couldnt do very easily in .NET. For example, if you look back at the original code I gave you, to get the members of a group we used Invoke("Members", Nothing). We use that because there is no attribute that we can access that just gives us a list of members, so we have to 'invoke' the Members function to return a list of members for us. That is my understanding of it anyway.
Soooo - back to your code - you are trying to use Invoke to invoke a function called Contacts... which doesnt exist.
Now after reading your code again and the comments in it, I'm a little puzzled as to what exactly you are trying to do. I mean you said initially that the network guy has asked you to read data from a contact. Thats fine, I can show you how to do that. The problem is that from your code comments and the code you are using it looks as if you are treating the contact as if it is a list that contains lots of contacts.... so can you just confirm whether or not you want to read data from a single contact in AD on its own, or if you want to get a list of contacts from a distribution list? (if its the latter, then you would do pretty much exactly the same thing as you were doing before to get a list of user accounts from a group)
-
Aug 14th, 2008, 01:38 PM
#26
Thread Starter
Frenzied Member
Re: Trying to understand accessing AD through VB.NET...
 Originally Posted by chris128
I dont know off the top of my head but I will try it out... you should do the same lol if your not sure whether or not something is going to work - try it and see. Often it will be quicker than waiting for someone to reply on here. I'm sure it will take me a few trial and error attempts before I get it working so there's no reason why you cant do the same thing.
One thing I would say about your existing code though is that you are trying to invoke a method which does not exist, hence the exception being thrown.
The Invoke method is used to perform API functions in AD that do things that we couldnt do very easily in .NET. For example, if you look back at the original code I gave you, to get the members of a group we used Invoke("Members", Nothing). We use that because there is no attribute that we can access that just gives us a list of members, so we have to 'invoke' the Members function to return a list of members for us. That is my understanding of it anyway.
Soooo - back to your code - you are trying to use Invoke to invoke a function called Contacts... which doesnt exist.
Now after reading your code again and the comments in it, I'm a little puzzled as to what exactly you are trying to do. I mean you said initially that the network guy has asked you to read data from a contact. Thats fine, I can show you how to do that. The problem is that from your code comments and the code you are using it looks as if you are treating the contact as if it is a list that contains lots of contacts.... so can you just confirm whether or not you want to read data from a single contact in AD on its own, or if you want to get a list of contacts from a distribution list? (if its the latter, then you would do pretty much exactly the same thing as you were doing before to get a list of user accounts from a group)
Hah, I am trying. Actually I think I got it figured out.
Code:
Dim oSearcher As New DirectorySearcher
Dim srcResults As SearchResultCollection
Dim boolResult As Boolean = False
deDirectoryEntry = New DirectoryEntry
deDirectoryEntry.Path = "LDAP://MyServer/OU=Test-UPDATE;DC=MyDomain,DC=com"
deDirectoryEntry.Username = "MyUser"
deDirectoryEntry.Password = "MyPassword"
Try
oSearcher.SearchRoot = deDirectoryEntry
oSearcher.Filter = "(&(objectClass=Contact) (cn=" & strContact & "))"
srcResults = oSearcher.FindAll()
For Each result As SearchResult In srcResults
Dim de As DirectoryEntry = result.GetDirectoryEntry()
oListBox1.Items.Add(de.Name.Remove(0, 3)
Next
Catch ex As Exception
m_strLastError = ex.Message
End Try
Return boolResult
I think he is going to have an OU with a bunch of individual contacts in it with non-user contacts (e.g. Main line, help line, etc). Thanks for the input though as always.
Sean
Some days when I think about the next 30 years or so of my life I am going to spend writing code, I happily contemplate stepping off a curb in front of a fast moving bus.
-
Aug 14th, 2008, 02:55 PM
#27
Re: Trying to understand accessing AD through VB.NET...
Yeah well what you have got there should work if thats the case 
EDIT: just one tiny thing - you are declaring this:
Code:
Dim boolResult As Boolean = False
but never assinging anything to it after that so it will always be false
-
Aug 14th, 2008, 03:11 PM
#28
Thread Starter
Frenzied Member
Re: Trying to understand accessing AD through VB.NET...
 Originally Posted by chris128
Yeah well what you have got there should work if thats the case
EDIT: just one tiny thing - you are declaring this:
Code:
Dim boolResult As Boolean = False
but never assinging anything to it after that so it will always be false 
Lol yeah I cleaned up the code a bit, I had a check in there to see if any records were found that set it to true and some other stuff that didn't seem relevant to this post.
Sean
Some days when I think about the next 30 years or so of my life I am going to spend writing code, I happily contemplate stepping off a curb in front of a fast moving bus.
-
Aug 14th, 2008, 03:17 PM
#29
Re: Trying to understand accessing AD through VB.NET...
Ahh I see, fair enough. Let me know if you run into any further problems
-
Aug 15th, 2008, 08:25 AM
#30
Thread Starter
Frenzied Member
Re: Trying to understand accessing AD through VB.NET...
Sean
Some days when I think about the next 30 years or so of my life I am going to spend writing code, I happily contemplate stepping off a curb in front of a fast moving bus.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|