processone / ejabberd

Robust, Ubiquitous and Massively Scalable Messaging Platform (XMPP, MQTT, SIP Server)
https://www.process-one.net/en/ejabberd/
Other
6k stars 1.5k forks source link

Compile option enable-group does not work as documented #4135

Closed nandlab closed 6 months ago

nandlab commented 6 months ago

I compiled ejabberd with the following options: ./configure --enable-group=ejabberd --enable-user=ejabberd After I install ejabberd, ejabberdctl can only be executed by root and the ejabberd user, but it cannot be executed by another user in the ejabberd group. I think this is a bug.

licaon-kter commented 6 months ago

What error did you get?

Does that user have the special .cookie file?

nandlab commented 6 months ago

I added www-data to the ejabberd group. /var/www/.erlang.cookie, /root/.erlang.cookie and /home/ejabberd/.erlang.cookie all have the same value. If www-data tries to run ejabberdctl: ERROR: This command can only be run by root or the user ejabberd

badlop commented 6 months ago

It took me quite a while to understand what was going wrong... the problem is the feature documentation which is misleading, and doesn't reflect the original purpose.

First of all, looking at ejabberdctl: if you provided --enable-user, then ejabberdctl wants you to use that account (or root) to start ejabberd.

Then what's the purpose of --enable-group?

If found the clue checking the relevant commits:

The source code author explains in the original PR https://github.com/processone/ejabberd/pull/1429 :

I have added the --enable-group flag because --enable-user fails when you have a group that is different from user.

So, --enable-group is not desgined to allow a wide range of accounts to run ejabberdctl. That feature is designed to allow the desired account run ejabberctl when that account has a custom group name. Let's see what problem it addresses:

Normally a user has as username, and its group name is identical to the username. This works correctly:

sudo adduser ejauser1

./autogen.sh
./configure --enable-user=ejauser1 --prefix=/tmp/eja1
make
sudo make install
...
sudo -u ejauser1 /tmp/eja1/sbin/ejabberdctl live
...  [info] ejabberd 23.10.77 is started in the node ejabberd@localhost in 1.16s

However, what happens when the account does not have a group with the same name as its username?

sudo addgroup ejagroup2
sudo adduser --ingroup ejagroup2 ejauser2

./autogen.sh
./configure --enable-user=ejauser2 --prefix=/tmp/eja2
make
sudo make install
...
/usr/bin/install -c -d -m 750 -g ejauser2 /tmp/eja2/etc/ejabberd
/usr/bin/install: invalid group 'ejauser2'

Here comes --enable-group to the rescue. This works correctly:

sudo addgroup ejagroup3
sudo adduser --ingroup ejagroup3 ejauser3

./autogen.sh
./configure --enable-user=ejauser3 --enable-group=ejagroup3 --prefix=/tmp/eja3
make
sudo make install
...
sudo -u ejauser3 /tmp/eja3/sbin/ejabberdctl live
...  [info] ejabberd 23.10.77 is started in the node ejabberd@localhost in 1.16s

In summary:

If you want to run ejabberd using www-data, then that's a different feature. If the existing method does not set privileges as you need in your case, maybe you can try producing an OTP release, install that one in the system, and grant the desired privileges.

nandlab commented 6 months ago

@badlop Thank you for the analysis! For my use case I have already found a workaround: Add the line www-data ALL=(ejabberd) NOPASSWD: /usr/sbin/ejabberdctl to the /etc/sudoers file with visudo. Then www-data can run sudo /usr/sbin/ejabberdctl restart, for example. I would appreciate it if the enable-group option is described correctly in the documentation. It would be nice, if there was another option to allow other users from a certain group, e.g. ejabberd, to also run ejabberdctl. AFAIK this is the more canonical way in the Linux world. For example, there is the dialout group to access serial ports or wireshark group to be able to capture network packets. However, for now, the sudo method works well enough for me.

badlop commented 6 months ago

How could the documentation be rephrased to be more precise?

Right now it says:

./configure --help

--enable-user[[[=USER]]]                allow this system user to start ejabberd (default: no)
--enable-group[[[=GROUP]]]         allow this system group to start ejabberd (default: no)

What about this change?

--enable-group[=GROUP]  define the group of the account defined in enable-user (default: no)

The Docs site says right now:

--enable-group[=GROUP]:
Similar to the previous option, but for system groups.

What about this?

--enable-group[=GROUP]:
Use this option additionally to --enable-user when that account is
in a group that doesn't coincide with its username
nandlab commented 6 months ago

Sounds good :+1:

badlop commented 6 months ago

Ok, both the ./configure help and Docs site are updated