Bug 9060 - Domain User with SeMachineAccountPrivilege cannot net rpc join a DC
Summary: Domain User with SeMachineAccountPrivilege cannot net rpc join a DC
Status: RESOLVED INVALID
Alias: None
Product: Samba 3.6
Classification: Unclassified
Component: Domain Control (show other bugs)
Version: 3.6.6
Hardware: All All
: P5 normal
Target Milestone: ---
Assignee: Jeremy Allison
QA Contact: Samba QA Contact
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-07-23 16:02 UTC by Arvid Requate
Modified: 2012-08-13 17:50 UTC (History)
1 user (show)

See Also:


Attachments
level 10 logs (1.14 MB, text/plain)
2012-07-24 10:26 UTC, Arvid Requate
no flags Details
Test that will give me more info. (598 bytes, patch)
2012-08-07 00:08 UTC, Jeremy Allison
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Arvid Requate 2012-07-23 16:02:13 UTC
With samba 3.5.11 it was possible for regular users (not Domain Admins) to join a DC if the SeMachineAccountPrivilege was granted to them:

root@master:~# net rpc rights grant -U Administrator%password \
     bob SeMachineAccountPrivilege
root@master:~# net rpc join -U bob%password
Joined domain TESTDOM.


With samba 3.6.6 this does not work any more:

root@master:~# net rpc join -U bob%password
error setting trust account password: NT_STATUS_ACCESS_DENIED
Unable to join domain TESTDOM.
Comment 1 Jeremy Allison 2012-07-23 19:13:58 UTC
Can you get me a debug level 10 log from the command please ?

Jeremy.
Comment 2 Arvid Requate 2012-07-24 10:26:55 UTC
Created attachment 7718 [details]
level 10 logs
Comment 3 Jeremy Allison 2012-07-25 00:32:26 UTC
Ok, I'm looking into this - thanks for the logs. I have a theory, it's to do with mapping the max_desired_access not being done correctly when OpenUser is called as root...

Still working on this.

Jeremy.
Comment 4 Jeremy Allison 2012-08-06 23:41:53 UTC
Ok, my original theory was incorrect. I need more data here.

The problem is that the client is requesting samr_OpenUser() on the existing user machine account with a required access mask of "max desired access".

max desired access is being mapped to a desired access mask of 0x0002035b as we can see by this debug message in the log.

  se_map_generic(): mapped mask 0xa0000000 to 0x0002035b

This leads to a call of the access_check_object() function, which should check if the user token attached to the open RPC pipe contains the SEC_PRIV_MACHINE_ACCOUNT privilege, and if so it should add in the additional GENERIC_RIGHTS_USER_WRITE set of access bits, which contains :

        const int GENERIC_RIGHTS_USER_WRITE =
                (STANDARD_RIGHTS_WRITE_ACCESS           |
                 SAMR_USER_ACCESS_CHANGE_PASSWORD       |
                 SAMR_USER_ACCESS_SET_LOC_COM           |
                 SAMR_USER_ACCESS_SET_ATTRIBUTES        |
                 SAMR_USER_ACCESS_SET_PASSWORD          |
                 SAMR_USER_ACCESS_CHANGE_GROUP_MEMBERSHIP);     /* 0x000204e4 */

The required bit here is SAMR_USER_ACCESS_SET_PASSWORD, 0x80, which is the bit that the operation is being failed on. Now if access_check_object() adds in these extra access mask bits due to the user having the SEC_PRIV_MACHINE_ACCOUNT privilege, we should see the following debug message in the log:

   DEBUG(4,("access_check_object: user rights access mask [0x%x]\n",
           rights_mask));

We don't see this message, which means that the following code inside access_check_object() isn't finding that the user has the privilege:

        /* check privileges; certain SAM access bits should be overridden
           by privileges (mostly having to do with creating/modifying/deleting
           users and groups) */

        if ((needed_priv_1 != SEC_PRIV_INVALID && security_token_has_privilege(token, needed_priv_1)) ||
            (needed_priv_2 != SEC_PRIV_INVALID && security_token_has_privilege(token, needed_priv_2))) {
                priv_granted = true;
                saved_mask = (des_access & rights_mask);
                des_access &= ~saved_mask;

                DEBUG(4,("access_check_object: user rights access mask [0x%x]\n",
                        rights_mask));
        }

which basically means the user doesn't have the SEC_PRIV_MACHINE_ACCOUNT privilege, or at least Samba doesn't think so..
Comment 5 Jeremy Allison 2012-08-07 00:08:29 UTC
Created attachment 7740 [details]
Test that will give me more info.

Arvid, can you apply this patch and then re-run the net join command with debug level 10 log. This should show me what is wrong with the security token attached to the pipe struct (and maybe give me a clue as to why is doesn't have the SEC_PRIV_MACHINE_ACCOUNT privilege needed to make this work.

Thanks !

Jeremy.
Comment 6 Arvid Requate 2012-08-07 18:54:02 UTC
I had to adjust the patch to get some output: acb_info does not have ACB_WSTRUST set but (ACB_SVRTRUST|ACB_DOMTRUST) instead, so I added your debug code in that code block as well. This is the output:


=============================================================================[2011/12/17 07:38:35.417242, 10] rpc_server/samr/srv_samr_nt.c:2255(_samr_OpenUser)
  _samr_OpenUser: srvtrust/domtrust account open. user security token :
[2011/12/17 07:38:35.417277, 10] ../libcli/security/security_token.c:63(security_token_debug)
  Security token SIDs (9):
    SID[  0]: S-1-5-21-861941570-1634457251-3974523304-5010
    SID[  1]: S-1-5-21-861941570-1634457251-3974523304-513
    SID[  2]: S-1-1-0
    SID[  3]: S-1-5-2
    SID[  4]: S-1-5-11
    SID[  5]: S-1-22-1-2005
    SID[  6]: S-1-22-2-5001
    SID[  7]: S-1-22-2-5022
    SID[  8]: S-1-22-2-5020
   Privileges (0x              10):
    Privilege[  0]: SeMachineAccountPrivilege
   Rights (0x               0):
[2011/12/17 07:38:35.417489,  4] rpc_server/srv_access_check.c:104(access_check_object)
  _samr_OpenUser: access GRANTED (requested: 0x0002035b, granted: 0x0002035b)
=============================================================================

RID 5010 is the user. 2005 is the posix uid of the user, 5001 the posix gid assigned to the primary group, 5022 ist the posix gid assigned to "Everyone", and 5020 is the gid of "Authenticated Users" (all in passdb ldap).
In case it matters: The user has sambaAcctFlags: [U          ] and the machine account has sambaAcctFlags: [S          ].

Maybe it's important to note that I did this test on the PDC, where the following settings control the smb.conf:

        ; domain
        security = user
        domain logons = yes
        domain master = yes
        preferred master = yes
        local master = yes

In case you think I'm barking at the wrong tree, I may test this on a BDC or member if it helps.
Comment 7 Andrew Bartlett 2012-08-08 11:48:03 UTC
Jeremy,

Feel free to ping me on this if you want any assistance/review.
Comment 8 Jeremy Allison 2012-08-10 23:19:38 UTC
OK ! Progress. This :

"I had to adjust the patch to get some output: acb_info does not have
ACB_WSTRUST set but (ACB_SVRTRUST|ACB_DOMTRUST) instead"

tells me a lot !

You're trying to add a client machine into the domain as a domain member, not as a domain trust - correct ?

So the issue is that the abc_info is incorrect - it's already set to a trust account, not a workstation account. In the log you sent this machine account already exists - and isn't a workstation account.

Modifying trust accounts is restricted to members of Domain Admins, not regular users with SeMachineAccountPrivilege. So Samba seems to be doing the right thing here.

The token attached to the user connected to the SAMR pipe is perfectly correct, it has the SeMachineAccountPrivilege (which was what I was wondering about). It's the account type you're trying to modify that is incorrect.

When did this machine account get created ? How did it get created ? On the DC can you try removing this machine account before trying the domain join again from the client with that machine account name ?

Jeremy.
Comment 9 Arvid Requate 2012-08-13 15:35:51 UTC
> You're trying to add a client machine into the domain as a domain member,
> not as a domain trust - correct ?

Yes, my test case was trying to (re-)join a DC with "net rpc join".


> So the issue is that the abc_info is incorrect - it's already set to a trust
> account, not a workstation account. In the log you sent this machine account
> already exists - and isn't a workstation account.
> 
> Modifying trust accounts is restricted to members of Domain Admins, not 
> regular users with SeMachineAccountPrivilege. So Samba seems to be doing the
> right thing here.
> 
> The token attached to the user connected to the SAMR pipe is perfectly
> correct, it has the SeMachineAccountPrivilege (which was what I was wondering
> about). It's the account type you're trying to modify that is incorrect.

Ok, fine, I understand, I checked it, it works for Memberservers, regardless if the accounts exist or not. The change in behaviour I referred to here is, that it does not work any longer for DCs (neither initial nor re-join). As I understand your explanation, this is expected behaviour, and for my case that's currently enough.
Comment 10 Jeremy Allison 2012-08-13 17:50:39 UTC
Ok, thanks. Yes - the code is explicitly configured to only allow Domain Admins to modify DC and trust accounts, and I think that's what is intended.

Closing this one as INVALID.

Thanks !

Jeremy.