1

I am using C# to create new computer accounts. My goal is to allow IT helpdesk personnel to add computers to the domain safely in the right OU. The way I intended to do this was to have them use a tool that would take the relevant information and create the account in Active Directory. So far, this all works great. There is only one snag - I can't figure out how to grant my workers the rights to join the computer to the domain. Normally in Active Directory you could change the group that is allowed to join the new computer to the domain. I am using DirectoryServices.AccountManagement and I cannot figure out how to do the same in code.

Here is my code:

PrincipalContext oPrincipalContext = GetPrincipalContext(sOU);

//The password is just a random construction.
//The computer SAM Account Name must end with a dollar sign in order for it
//to be usable.
ComputerPrincipal oComputerPrincipal = new ComputerPrincipal(oPrincipalContext, 
                                                             sComputerName + "$", 
                                                             RandomPassword(), 
                                                             true);

//You actually need to save the record before it is actually created
oComputerPrincipal.Save();

This creates the computer accounts and puts them in the correct OU. However, you still need to be granted the rights to add a computer to the domain in order to hook a computer up to this account. I can't find the code to do so.

As a side note, I understand that I could grant my helpdesk personnel the permission to join computers to the domain. The problem, though, is that they would be able to do so without using this tool. They wouldn't realize that when they do that, they are sending the computers to the wrong OUs.

Update

Here is an updated picture to show you what I am trying to accomplish in code. As you can see in the image below, I am attempting to change the bottom box (via code) when I create a new computer account in code. See how it allows you to specify who can add this specific computer to the domain?

New Computer dialog

IAmTimCorey
  • 16,412
  • 5
  • 39
  • 75
  • @marc_s - The computer account creation itself (the above code) is done using a service account, not the user's account. That isn't the problem. The problem is when they are on the machine itself and trying to join it to the domain once they have done the above steps - the object exists in AD, but they still don't have permission to join the computer they are on to that object. This is the problem I am trying to rectify. – IAmTimCorey Oct 27 '11 at 15:28

2 Answers2

0

In order to do this, you need to grant the Reset Password right at a minimum on the computer account. I don't think you need anything else but I don't recall offhand.

You can use the ActiveDirectoryAccessRule class to build the ACE and add it to the ACL. You'll want to do something like this:

var rule = new ActiveDirectoryAccessRule(<user to delegate to>, ActiveDirectoryRights.ExtendedRight, AccessControlType.Allow, new Guid("00299570-246d-11d0-a768-00aa006e0529")

Brian Desmond
  • 4,473
  • 1
  • 13
  • 11
  • I could be wrong but isn't this just overall delegation? I don't want to do delegation, I just want to grant rights for that one computer. In the end, it could be that I would allow anyone to add their computer to the domain, which would mean that everyone would need to have that right then. I updated my posting above to better illustrate what I am looking for. I want my code to be able to mimic the bottom box (where I put Guest User). – IAmTimCorey Nov 04 '11 at 21:18
0

Here is a place to find ExtendedRightAccessRule.

And here is a simple example that allow the domain user 'user1' to reset password for users presents in OU 'ForUser1'. You just have to allow your user to add a computer to an OU. @Brian Desmon give you the GUID.

/* Connection to Active Directory 
 */ 
DirectoryEntry workingOU = new DirectoryEntry(); 
workingOU.Options.SecurityMasks = SecurityMasks.Owner | SecurityMasks.Group | SecurityMasks.Dacl | SecurityMasks.Sacl; 
workingOU.Path = "LDAP://WM2008R2ENT:389/ou=ForUser1,dc=dom,dc=fr"; 

/* Retreive Obect security 
 */ 
ActiveDirectorySecurity adsOUSec = workingOU.ObjectSecurity; 

/* Ellaborate the user to delegate 
 */ 
NTAccount ntaToDelegate = new NTAccount("dom", "user1"); 
SecurityIdentifier sidToDelegate = (SecurityIdentifier)ntaToDelegate.Translate (typeof(SecurityIdentifier)); 

/* Specils Guids 
 */ 
Guid UserForceChangePassword = new Guid("00299570-246d-11d0-a768-00aa006e0529"); 
Guid userSchemaGuid = new Guid("BF967ABA-0DE6-11D0-A285-00AA003049E2"); 
Guid pwdLastSetSchemaGuid = new Guid("bf967a0a-0de6-11d0-a285-00aa003049e2"); 

/* Ellaborate ACEs 
 */ 
ExtendedRightAccessRule erarResetPwd = new ExtendedRightAccessRule(ntaToDelegate, AccessControlType.Allow, UserForceChangePassword, ActiveDirectorySecurityInheritance.Descendents, userSchemaGuid); 
PropertyAccessRule parPwdLastSetW = new PropertyAccessRule(ntaToDelegate, AccessControlType.Allow, PropertyAccess.Write, pwdLastSetSchemaGuid, ActiveDirectorySecurityInheritance.Descendents, userSchemaGuid); 
PropertyAccessRule parPwdLastSetR = new PropertyAccessRule(ntaToDelegate, AccessControlType.Allow, PropertyAccess.Read, pwdLastSetSchemaGuid, ActiveDirectorySecurityInheritance.Descendents, userSchemaGuid); 
adsOUSec.AddAccessRule(erarResetPwd); 
adsOUSec.AddAccessRule(parPwdLastSetW); 
adsOUSec.AddAccessRule(parPwdLastSetR); 

workingOU.CommitChanges(); 

Edited (2011-11-04)

In my understanding the thing you want to do is a kind of delegation; Inside Active-Directory delegation becomes reality with rights on objects. In your case you you want to allow a user to create a computer account. Most of the time administrators do that for the whole domain :

enter image description hereenter image description here

If you try it you'll see a new ACE (Access Control Entry) in the domain nod ACL (Access Control List). In the example I just delegate the right in one OU.


Second Edition (2011-11-04)

He re is the proof of what I'am writting :

enter image description here

If you look at security tab

enter image description here

JPBlanc
  • 70,406
  • 17
  • 130
  • 175
  • Wouldn't this just give my user rights to add the computer to the OU? I don't want to modify OU rights, I just want to allow that user to connect a specific computer to the newly created computer object. – IAmTimCorey Nov 03 '11 at 23:15
  • I want to illustrate the answer to your comment, so I edit the main answer. – JPBlanc Nov 04 '11 at 04:55
  • I updated my own post with what I am looking for. What you are specifying here is delegation. I don't want to do delegation, even for just one OU. Instead, I want to grant a user the rights to associate a computer to the new account that we created in code on the domain (see my screenshot above). As you can see, if I were to create the computer account using the AD GUI, I could specify that the Guest account can have access to associate a computer to the newly-created computer account in AD. This is what I want to do in code. – IAmTimCorey Nov 04 '11 at 21:16
  • I think you are wrong, you are talking about delegation, begining from your screen I edit my answer to show you the proof. – JPBlanc Nov 04 '11 at 21:42
  • Sorry for the really late response on this. I forgot to come back to it. In any event, it looks like you have things reversed. If you delegate permissions to the OU, you will have the rights to add the computer to the domain. However, if you were to remove the delegated rights you specified above, you could still select user1 as the person able to add that computer to the domain. That is what I want. It does not require delegation when you use the GUI. I don't want to (can't) use delegation for my code. – IAmTimCorey Mar 26 '12 at 18:04
  • Make your test again, the user or group you choose is in ACL of the computer. The entry field is just au shortcut. – JPBlanc Mar 26 '12 at 18:29