Ubuntu, LXD, Samba and the dreaded “sys_setgroups failed” error

Sometimes, errors produced by Samba can be really annoying. In such cases, they sure as hell depend on your actual configuration, environment, kernel and Samba versions and so on. If you are unlucky enough to have a comparatively rarely used configuration, you might either find outdated forum threads, forum posts with no replies or bug reports that have been marked as “Closed” with a comment that “it is impossible to reproduce the problem”. And yet, in your particular case, the problem is there and you have no clue what have you done wrong to be punished so hard.

Just like in this case.

First of all, there is a need to describe the particular environment. We have a host, let’s call it “server01“, which happens to run Ubuntu 14.04 LTS and LXD, and an LXD container, let’s call it “dev1“, which happens to run Ubuntu 16.04 LTS. We have Active Directory provisioned in our network, with RFC2307 (Unix extensions). For users/groups where Unix UIDs and GIDs are not defined, we use the TDB backend of idmap, for “normal” users and groups we use the AD backend with RFC2307 to get our UIDs and GIDs so that they would be consistent across all the *nix machines on the network. Having consistent UIDs and GIDs is good and helps with file transfers, migration of complicated access lists and other issues.

Having Samba installed and configured in the container, dev1, it was found that it is impossible to connect to it using any client, be it the cifs filesystem driver on Linux, smbclient or a Windows workstation. We would get this error with smbclient, for instance:

root@dev1:~# smbclient -Ualvils -Wdevlat //dev1/alvils
Enter alvils's password:
Domain=[DEVLAT] OS=[Windows 6.1] Server=[Samba 4.3.11-Ubuntu]
tree connect failed: NT_STATUS_CONNECTION_DISCONNECTED

In the same time, in /var/log/samba/log.smbd the following would appear:

[2016/10/05 12:14:37.813685,  0] ../lib/util/become_daemon.c:124(daemon_ready)
  STATUS=daemon 'smbd' finished starting up and ready to serve connections
[2016/10/05 12:14:51.277701,  0] ../source3/lib/util.c:789(smb_panic_s3)
  PANIC (pid 796): sys_setgroups failed
[2016/10/05 12:14:51.278618,  0] ../source3/lib/util.c:900(log_stack_trace)
  BACKTRACE: 26 stack frames:
   #0 /usr/lib/x86_64-linux-gnu/samba/libsmbregistry.so.0(log_stack_trace+0x1a) [0x7ff6256d871a]
   #1 /usr/lib/x86_64-linux-gnu/samba/libsmbregistry.so.0(smb_panic_s3+0x20) [0x7ff6256d87f0]
   #2 /usr/lib/x86_64-linux-gnu/libsamba-util.so.0(smb_panic+0x2f) [0x7ff626461f1f]
   #3 /usr/lib/x86_64-linux-gnu/samba/libsmbd-base.so.0(+0xffb0a) [0x7ff626016b0a]
   #4 /usr/lib/x86_64-linux-gnu/samba/libsmbd-base.so.0(+0xffb85) [0x7ff626016b85]
   #5 /usr/lib/x86_64-linux-gnu/samba/libsmbd-base.so.0(+0xec66e) [0x7ff62600366e]
   #6 /usr/lib/x86_64-linux-gnu/samba/libsmbd-base.so.0(+0x117fe1) [0x7ff62602efe1]
   #7 /usr/lib/x86_64-linux-gnu/samba/libsmbd-base.so.0(+0x118a11) [0x7ff62602fa11]
   #8 /usr/lib/x86_64-linux-gnu/samba/libsmbd-base.so.0(make_connection+0x220) [0x7ff62602ff10]
   #9 /usr/lib/x86_64-linux-gnu/samba/libsmbd-base.so.0(reply_tcon_and_X+0x651) [0x7ff625fde831]
   #10 /usr/lib/x86_64-linux-gnu/samba/libsmbd-base.so.0(+0x1121d7) [0x7ff6260291d7]
   #11 /usr/lib/x86_64-linux-gnu/samba/libsmbd-base.so.0(+0x113f23) [0x7ff62602af23]
   #12 /usr/lib/x86_64-linux-gnu/samba/libsmbd-base.so.0(+0x11558c) [0x7ff62602c58c]
   #13 /usr/lib/x86_64-linux-gnu/libsmbconf.so.0(run_events_poll+0x167) [0x7ff62434b917]
   #14 /usr/lib/x86_64-linux-gnu/libsmbconf.so.0(+0x2cb77) [0x7ff62434bb77]
   #15 /usr/lib/x86_64-linux-gnu/libtevent.so.0(_tevent_loop_once+0x8d) [0x7ff622f7ad3d]
   #16 /usr/lib/x86_64-linux-gnu/libtevent.so.0(tevent_common_loop_wait+0x1b) [0x7ff622f7aedb]
   #17 /usr/lib/x86_64-linux-gnu/samba/libsmbd-base.so.0(smbd_process+0x718) [0x7ff62602d8e8]
   #18 /usr/sbin/smbd(+0x8e12) [0x55d529fcae12]
   #19 /usr/lib/x86_64-linux-gnu/libsmbconf.so.0(run_events_poll+0x167) [0x7ff62434b917]
   #20 /usr/lib/x86_64-linux-gnu/libsmbconf.so.0(+0x2cb77) [0x7ff62434bb77]
   #21 /usr/lib/x86_64-linux-gnu/libtevent.so.0(_tevent_loop_once+0x8d) [0x7ff622f7ad3d]
   #22 /usr/lib/x86_64-linux-gnu/libtevent.so.0(tevent_common_loop_wait+0x1b) [0x7ff622f7aedb]
   #23 /usr/sbin/smbd(main+0x1899) [0x55d529fc9099]
   #24 /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0) [0x7ff622bc7830]
   #25 /usr/sbin/smbd(_start+0x29) [0x55d529fc9199]
[2016/10/05 12:14:51.281561,  0] ../source3/lib/dumpcore.c:303(dump_core)
  dumping core in /var/log/samba/cores/smbd

You see, the problem is visible in line 4:

PANIC (pid 796): sys_setgroups failed

Some outdated forum posts and bug reports could be found, but they all were related to Samba version 3.x and Linux 3.5. When kernel 3.5 came out, it implemented some changes in how the sys_setgroups() function worked, returning an error if GID -1 was passed to it, and Samba happened to do just that. Yet, this issue is old (dating back from year 2012) and has long been patched, so it shouldn’t appear in modern incarnations.

Some “widow posts” were also found that were more or less recent, but they had no replies or replies like “Yeah, I also have this problem. Somebody help, please!”

So, it seemed that there will be no problem with that. Quite logically, having read about past issues with Samba not willing to cooperate with the kernel, a decision was made to upgrade the host’s kernel to the latest 16.04 LTS hardware enablement stack. That was easy, that’s a good thing to do in any case, and it turned out not to help at all, but, should you wish to do so, you can read about it in Ubuntu’s Wiki page.

Then, some brainstorming was done about what and how doesn’t work here. You see, the sys_setgroups function performs a kind of “resolving” task – you pass it a list of group IDs and it returns you which users belong to it. So, it would seem that some group IDs cannot be resolved and/or seem “illegal” to the kernel, so an error is returned instead, causing the smbd process to crash.

While there are no actual practical limits on UID and GID use in a “normal” Linux system, we have to remember that we are running in an LXD container. For security reasons, as the filesystem is shared between the host and the containers, each user who launches containers has its own namespace – that is, a base value from which its “internal” UIDs and GIDs start. For instance, normally, the UID for the root user is 0. Should a particular user’s namespace start with, say, 100000, the root user within the container would still be 0, but from the host’s point of view it would be UID of 100000. Container’s UID 1000 would be 101000 and so on. These values are configured in two files on the host, /etc/subuid and /etc/subgid. After taking a look at these 2 files, it was discovered they look like this:

/etc/subuid:
lxd:231072:65536

/etc/subgid:
lxd:231072:65536

That is, containers launched by the “lxd” user have the base of 231072 and the containers have a maximum of 65536 UIDs and GIDs allowed. This could be easily tested within the container:

root@dev1:~# touch test
root@dev1:~# chown 65535 test
root@dev1:~# ls -all test
-rw-r--r-- 1 65535 root 0 Oct  5 12:16 test
root@dev1:~# chown 65536 test
chown: changing ownership of 'test': Invalid argument
root@dev1:~# ls -all test
-rw-r--r-- 1 65535 root 0 Oct  5 12:16 test

That is, we first create an empty file called “test“, then set its owner to UID 65535. Remember that we can have 65536 UIDs and GIDs, numbered from 0 to 65535. We could successfully set the UID to 65535, but not to 65536 which in our case is “out of range”. Hmm, this is a clue, but what UIDs and GIDs could our beloved Samba want to use? This could easily be spotted in the /etc/samba/smb.conf file; the relevant part is here:

idmap config DEVLAT:backend = ad
idmap config DEVLAT:schema_mode = rfc2307
idmap config DEVLAT:range = 500-4000000
idmap config DEVLAT:default = yes
idmap config *:backend = tdb
idmap config *:range = 4000001-5000000

We see that we have a range of 500-4000000 reserved for the AD backend, and 4000001 to 5000000 reserved for the TDB backend. While users with their Unix attributes set certainly have UIDs less than 65536, groups such as BUILTIN\administrators or BUILTIN\users have their GIDs calculated by the TDB backend. This means that we simply need to extend the allowed UID and GID range for our container.

The container was shut down and the /etc/subuid and /etc/subgid files were changed accordingly:

/etc/subuid:
lxd:231072:5000000

/etc/subgid:
lxd:231072:5000000

Then, the LXD daemon was restarted to take the new configuration into account, after which the container was fired up:

root@server01:~# service lxd stop
root@server01:~# service lxd start
root@server01:~# lxc start dev1

Within the container, we can now set the UIDs and GIDs to much higher values:

root@dev1:~# touch test
root@dev1:~# chown 65536 test
root@dev1:~# ls -all test
-rw-r--r-- 1 65536 root 0 Oct  5 12:21 test
root@dev1:~# chown 200000 test
root@dev1:~# ls -all test
-rw-r--r-- 1 200000 root 0 Oct  5 12:21 test

Also, smbclient now works:

root@dev1:~# smbclient -I10.5.1.16 -Ualvils -Wdevlat //dev1/alvils
WARNING: The "acl check permissions" option is deprecated
Enter alvils's password:
Domain=[DEVLAT] OS=[Windows 6.1] Server=[Samba 4.3.11-Ubuntu]
smb: \>

To summarize all of this, the problem of that bizarre Samba crash was caused by several factors:

  • Active Directory environment
  • The particular Samba configuration with large UID/GID ranges
  • Running in an LXD container which had the default range for UIDs/GIDs, i.e. 65536, while Samba wanted a range of 5000000.

As can be seen, such cases are not obvious and require deeper analysis of the issue at hand, and the solution is not as obvious as it might seem at the start. Yet, with enough knowledge about the topic and some brainstorming they can be solved. This article was written to help others who might run into this issue – feel free to link to this post.