Bug 10656 - Samba DC does not allow a regular Domain User to domain join a machine to the Domain.
Summary: Samba DC does not allow a regular Domain User to domain join a machine to the...
Status: NEW
Alias: None
Product: Samba 4.1 and newer
Classification: Unclassified
Component: AD: LDB/DSDB/SAMDB (show other bugs)
Version: 4.1.6
Hardware: All All
: P1 enhancement (vote)
Target Milestone: 4.3
Assignee: Andrew Bartlett
QA Contact: Samba QA Contact
URL:
Keywords:
: 9978 (view as bug list)
Depends on: 11552
Blocks:
  Show dependency treegraph
 
Reported: 2014-06-11 02:40 UTC by lexiwright1788
Modified: 2018-03-20 22:44 UTC (History)
7 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description lexiwright1788 2014-06-11 02:40:26 UTC
The Samba DC does not allow a user belonging to the group "Domain Users" to domain join a Windows machine to the domain. I verified that Windows AD allows a default domain user to join up to a max of 10 machines to the domain. 

The following were the steps taken to reproduce the issue:

1. Provisioned a Samba domain on a linux machine.
2. Domain joined a Windows machine to the above domain using the Domain admin account.
3. Launched ADUC from machine joined in (2) and created a few users (they belong to the group Domain Users)
4. Tried to domain join another Windows machine using one of the accounts created   in (3) 

I verified that this was happening with other versions of Samba as well (I tried Samba-4.1.6 and Samba-4.1.8)

I did a little debugging myself and figured out that the method sec_access_check_ds() always returns an NT_STATUS_ACCESS_DENIED which in turn results in an LDB_ERR_INSUFFICIENT_RIGHTS error being thrown from the dsdb_check_access_on_dn_internal(). The field 'bits_remaining' in the access check implementation, always ends up getting a value 1. My best guess is we need to revisit the access check algorithm implementation and also verify the access mask.

Here are the log statements:

[2014/06/03 02:00:31.011163,  0, pid=3420, effective(0, 0), real(0, 0)] ../source4/dsdb/common/util_samr.c:185(dsdb_add_user)
  Failed to create user record CN=DOMJOINSYS,CN=Computers,DC=new,DC=testdomain,DC=org: dsdb_access: Access check failed on CN=Computers,DC=new,DC=testdomain,DC=org
[2014/06/03 02:00:31.011303,  1, pid=3420, effective(0, 0), real(0, 0)] ../librpc/ndr/ndr.c:333(ndr_print_function_debug)
       samr_CreateUser2: struct samr_CreateUser2
          out: struct samr_CreateUser2
              user_handle              : *
                  user_handle: struct policy_handle
                      handle_type              : 0x00000000 (0)
                      uuid                     : 00000000-0000-0000-0000-000000000000
              access_granted           : *
                  access_granted           : 0x00000000 (0)
              rid                      : *
                  rid                      : 0x00000000 (0)
              result                   : NT_STATUS_ACCESS_DENIED
[2014/06/03 02:00:31.014276,  1, pid=3420, effective(0, 0), real(0, 0)] ../librpc/ndr/ndr.c:333(ndr_print_function_debug)
       samr_Close: struct samr_Close
          in: struct samr_Close
              handle                   : *
                  handle: struct policy_handle
                      handle_type              : 0x00000001 (1)
                      uuid                     : abaeda9a-63a2-4048-a9d6-e8b506125527
[2014/06/03 02:00:31.014513,  1, pid=3420, effective(0, 0), real(0, 0)] ../librpc/ndr/ndr.c:333(ndr_print_function_debug)
       samr_Close: struct samr_Close
          out: struct samr_Close
              handle                   : *
                  handle: struct policy_handle
                      handle_type              : 0x00000000 (0)
                      uuid                     : 00000000-0000-0000-0000-000000000000
              result                   : NT_STATUS_OK


Some more log statements:

(0)
                                 0: SEC_ACE_FLAG_SUCCESSFUL_ACCESS
                                 0: SEC_ACE_FLAG_FAILED_ACCESS
                          size                     : 0x0014 (20)
                          access_mask              : 0x000f01ff (983551)
                          object                   : union security_ace_object_ctr(case 0)
                          trustee                  : S-1-5-18
                      aces: struct security_ace
                          type                     : SEC_ACE_TYPE_ACCESS_ALLOWED (0)
                          flags                    : 0x00 (0)
                                 0: SEC_ACE_FLAG_OBJECT_INHERIT
                                 0: SEC_ACE_FLAG_CONTAINER_INHERIT
                                 0: SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
                                 0: SEC_ACE_FLAG_INHERIT_ONLY
                                 0: SEC_ACE_FLAG_INHERITED_ACE
                              0x00: SEC_ACE_FLAG_VALID_INHERIT (0)
                                 0: SEC_ACE_FLAG_SUCCESSFUL_ACCESS
                                 0: SEC_ACE_FLAG_FAILED_ACCESS
                          size                     : 0x0014 (20)
                          access_mask              : 0x00020094 (131220)
                          object                   : union security_ace_object_ctr(case 0)
                          trustee                  : S-1-5-11
                      aces: struct security_ace
                          type                     : SEC_ACE_TYPE_ACCESS_ALLOWED (0)
                          flags                    : 0x12 (18)
                                 0: SEC_ACE_FLAG_OBJECT_INHERIT
                                 1: SEC_ACE_FLAG_CONTAINER_INHERIT
                                 0: SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
                                 0: SEC_ACE_FLAG_INHERIT_ONLY
                                 1: SEC_ACE_FLAG_INHERITED_ACE
                              0x02: SEC_ACE_FLAG_VALID_INHERIT (2)
                                 0: SEC_ACE_FLAG_SUCCESSFUL_ACCESS
                                 0: SEC_ACE_FLAG_FAILED_ACCESS
                          size                     : 0x0024 (36)
                          access_mask              : 0x000f01ff (983551)
                          object                   : union security_ace_object_ctr(case 0)
                          trustee                  : S-1-5-21-1626187744-3519532614-1945399972-519
                      aces: struct security_ace
                          type                     : SEC_ACE_TYPE_ACCESS_ALLOWED (0)
                          flags                    : 0x12 (18)
                                 0: SEC_ACE_FLAG_OBJECT_INHERIT
                                 1: SEC_ACE_FLAG_CONTAINER_INHERIT
                                 0: SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
                                 0: SEC_ACE_FLAG_INHERIT_ONLY
                                 1: SEC_ACE_FLAG_INHERITED_ACE
                              0x02: SEC_ACE_FLAG_VALID_INHERIT (2)
                                 0: SEC_ACE_FLAG_SUCCESSFUL_ACCESS
 0: SEC_ACE_FLAG_FAILED_ACCESS
                          size                     : 0x0024 (36)
                          access_mask              : 0x000f01bd (983485)
                          object                   : union security_ace_object_ctr(case 0)
                          trustee                  : S-1-5-21-1626187744-3519532614-1945399972-512

[2014/06/03 02:00:29.543018, 10, pid=3424, effective(0, 0), real(0, 0), class=ldb] ../lib/ldb-samba/ldb_wrap.c:71(ldb_wrap_debug)
  ldb: ldb_asprintf/set_errstring: dsdb_access: Access check failed on CN=Windows NT,CN=Services,CN=Configuration,DC=new,DC=testdomain,DC=org
[2014/06/03 02:00:29.543128, 10, pid=3424, effective(0, 0), real(0, 0), class=ldb] ../lib/ldb-samba/ldb_wrap.c:71(ldb_wrap_debug)


Thanks,
Lexi
Comment 1 Andrew Bartlett 2014-06-11 21:42:00 UTC
If the issue is that critical to you, please contact a commercial support provider to quote on adding the enhancement.  Sadly this just isn't supported right now.

Sorry,

Andrew Bartlett
Comment 2 lexiwright1788 2014-06-11 21:49:47 UTC
Hi Andrew,

Sure. It would be great if you could confirm if it's a bug in the access check algorithm implementation or if it's an incorrect security token issue. I did some investigation around this too. 

Thanks & Regards,
Lexi

> If the issue is that critical to you, please contact a commercial support
> provider to quote on adding the enhancement.  Sadly this just isn't supported
> right now.
> 
> Sorry,
> 
> Andrew Bartlett
Comment 3 Andrew Bartlett 2014-06-12 07:28:10 UTC
There simply is no code in Samba to implement the 10-machine quota, or to allow anyone other than a domain admin to add machine accounts (the natural outcome of the standard ACL checks)
Comment 4 lexiwright1788 2014-06-12 16:05:18 UTC
Thank you Andrew for confirming. I didn't know this was a missing feature altogether. I would like to try and look into this myself too.  Would it help if I try to align the access check algorithm implementation with the algorithm here : http://msdn.microsoft.com/en-us/library/cc230290.aspx ? I did try playing around with it and noticed a few differences. It would be great if you could give me any suggestion on where I could begin. Is there any other function that I might need to look into?  The nTSecurityDescriptor for the default groups in the Builtin container are different from that in AD and hence the permissions are incorrect. Likewise, if there is anything different about the tokens for the groups in the Users container, we might need to fix that too. 

Thank you once again for your time.


Thanks & Regards,
Lexi
Comment 5 Marc Muehlfeld 2014-12-03 16:30:29 UTC
(In reply to Andrew Bartlett from comment #3)
> There simply is no code in Samba to implement the 10-machine quota, or to allow 
> anyone other than a domain admin to add machine accounts (the natural outcome 
> of the standard ACL checks)


Even if we don't have code for that (yet), it is possible by using delegations. I described this here:
http://wiki.samba.org/index.php/Delegating_Administration_Permissions#Delegating_.27Joining_Computers_to_the_domain.27-permissions
Usually admins want to disable the allow-users-to-join-up-to-10-machines funtion and then delegate permissions to a group of technicians.

This is at least a workaround for the OP.
Comment 6 Mike (dead mail address) 2015-02-10 16:55:25 UTC
In a windows domain, only domain admins can join a PC to the domain... sounds like normal behavior.
Comment 7 Louis 2015-04-30 10:23:57 UTC
Please read : 

https://technet.microsoft.com/en-us/library/cc770919(v=ws.10).aspx 

To join a computer to a domain, you must be logged on to the computer with the local Administrator account or, if you are logged on to the computer with a user account that does not have local computer administrative credentials, you must provide the credentials for the local Administrator account during the process of joining the computer to the domain. In addition, you must have a user account in the domain to which you want to join the computer. During the process of joining the computer to the domain, you will be prompted for your domain account credentials (user name and password).


so in these steps. 

1. Provisioned a Samba domain on a linux machine.
2. Domain joined a Windows machine to the above domain using the Domain admin account.
3. Launched ADUC from machine joined in (2) and created a few users (they belong to the group Domain Users)
4. Tried to domain join another Windows machine using one of the accounts created   in (3) 

where is the "Domain User" assigned to a "Local Admin" group on the pc. 

Looks to me this works as it should.
Comment 8 Andrew Bartlett 2015-10-13 21:23:29 UTC
*** Bug 9978 has been marked as a duplicate of this bug. ***
Comment 9 Alexey Vekshin 2018-03-20 16:25:21 UTC
BTW, to delegate permissions from command line one could use "samba-tool dsacl set" with hairy looking SSDL like this:

======================================================================================
GID=$(getent group | awk -F: '/support-group/ {print $3}')
SID=$(wbinfo -G $GID)
DN='OU=clients-test,OU=all-computers,DC=adtest3,DC=maxidom,DC=ru'
samba-tool dsacl set --objectdn="$DN" --action=allow --sddl="\
(OA;CI;CCDC;BF967A86-0DE6-11D0-A285-00AA003049E2;;$SID)\
(OA;CIIO;RPWP;4C164200-20C0-11D0-A768-00AA006E0529;BF967A86-0DE6-11D0-A285-00AA003049E2;$SID)\
(OA;CIIO;CR;00299570-246D-11D0-A768-00AA006E0529;BF967A86-0DE6-11D0-A285-00AA003049E2;$SID)\
(OA;CIIO;RPWPSW;F3A64788-5306-11D1-A9C5-0000F80367C1;BF967A86-0DE6-11D0-A285-00AA003049E2;$SID)\
(OA;CIIO;RPWPSW;72E39547-7B18-11D1-ADEF-00C04FD8D5CD;BF967A86-0DE6-11D0-A285-00AA003049E2;$SID)"
======================================================================================

I'm using this in ansible playbook to provision and manage AD permissions on OUs with reasonable success, like
======================================================================================
# vars:

samba_sddl_acls_ou_write:
  - OA;CI;CCDC;BF967A86-0DE6-11D0-A285-00AA003049E2;
  - OA;CIIO;RPWP;4C164200-20C0-11D0-A768-00AA006E0529;BF967A86-0DE6-11D0-A285-00AA003049E2
  - OA;CIIO;CR;00299570-246D-11D0-A768-00AA006E0529;BF967A86-0DE6-11D0-A285-00AA003049E2
  - OA;CIIO;RPWPSW;F3A64788-5306-11D1-A9C5-0000F80367C1;BF967A86-0DE6-11D0-A285-00AA003049E2
  - OA;CIIO;RPWPSW;72E39547-7B18-11D1-ADEF-00C04FD8D5CD;BF967A86-0DE6-11D0-A285-00AA003049E2

samba_domain_groups:
  - name: Domain Server Joiners
    description: "Users and programs able to join members to domain"
    gidNumber: 101002
    members:
      - "{{ samba_joiner_user }}"

samba_domain_org_units:
  all-computers:
    name: "Top-level container for computers"
    children:
      servers:
        name: "Domain members: servers and infrastructure"
        writers: ['Domain Server Joiners']
      workstations:
        name: "User workstations"

# tasks

- name: (conf_domain) get security descriptors list for OUs
  shell: >
    ldbsearch -H /var/lib/samba/private/sam.ldb
    -b '{{ item }}'
    -s base nTSecurityDescriptor --show-binary
    | awk -F': ' '/trustee  / {print $2}'
    | sort
    | uniq
  register: ou_writers_sids_res
  with_items: "{{ samba_domain_org_units | json_query('[?writers].dn') }}"
  changed_when: false
  check_mode: false

- name: (conf_domain) map secrity groups to SIDs
  shell: "wbinfo -G {{ groups_by_name[item].gidNumber }}"
  register: group_to_sid_res
  with_items: "{{ samba_domain_org_units | json_query('[?writers].writers | []') }}"
  vars:
    - groups_by_name: "{{ samba_domain_groups | to_dict('name') }}"
  changed_when: false
  check_mode: false

- name: (conf_domain) add missed rights
  command: >
    samba-tool dsacl set
    --objectdn='{{ item.0.dn }}'
    --action=allow
    --sddl={{ samba_sddl_acls_ou_write
      | map('regex_replace', '^(.*)$', '(\1;' + group_sid_by_name[item.1] + ')')
      | join('')
      | quote }}
  with_subelements:
    - "{{ samba_domain_org_units | json_query('[?writers]') }}"
    - writers
  when: group_sid_by_name[item.1] not in acl_sids_by_dn[item.0.dn]
  vars:
    # OU (partial) dn -> [SIDs with (some) rights on it]
    acl_sids_by_dn: "{{ ou_writers_sids_res | json_query('results[*].[item, stdout_lines]') | to_dict_flat }}"
    # group name -> group sid
    group_sid_by_name: "{{ group_to_sid_res | json_query('results[*].[item, stdout]') | to_dict_flat }}"
======================================================================================

Sadly, samba-tool currently has no option to remove dsacls (I've made a patch for that, maybe later I'll make it into a pull request).