I need to access Network Manager functionality from PHP code by exec()-ing the "nmcli" command. However, when run from PHP code, "nmcli" command returns the error message "Network Manager is not running" and does nothing.
Network Manager is running and I can successfully run "nmcli" command from the command line even as the Apache user. I suspected it has something to do with the lack of DBUS_SESSION_BUS_ADDRESS environment variable in the environment in which PHP is running (and of course lack of the actual socket this variable points to) but probably it's not that issue, because when I run the "nmcli" command from command line with strace, I can see that it doesn't access that socket at all.
I suspected some SELinux issue, but I don't see any recent denials in the audit logs.
I don't know where to search. It's a standard Apache/PHP (FPM) installation on a RHEL10 OS.
Edit: The problem is not only in PHP. I wrote a simple CGI shell script that tries to run "nmcli" and it gives the same error message run directly by Apache webserver.
So it looks that both services (Apache and PHP-FPM) don't "see" something that is needed to connect to Network Manager. What is that "something" and how to make the services "see" it?
Edit 2: With regard to @sofia 's answer below, output of the commands systemctl status NetworkManager and busctl list differs in CGI script run within Apache and in PHP.
In CGI script systemctl displays Failed to get properties: Access denied, and busctl shows basically nothing:
NAME PID PROCESS USER CONNECTION UNIT SESSION DESCRIPTION
:1.2 - - - - - - -
org.freedesktop.NetworkManager - - - - - - -
(I'm including :1.2 because that's the endpoint that seems to be actually assigned to Network Manager when busctl is run from the shell - as I show later).
Also I see a denial in ausearch -m avc -ts recent output regarding to systemctl process and a lot of denials regarding to busctl process. There are no denials regarding to nmcli, however (which is also run within the script).
In PHP, it's the same Failed to get properties: Access denied message from systemctl, but busctl output is different:
NAME PID PROCESS USER CONNECTION UNIT SESSION DESCRIPTION
:1.2 2403 n/a root :1.2 - - -
org.freedesktop.NetworkManager 2403 n/a root :1.2 - - -
This time, there are no denials in ausearch output.
sudo -u apache nmcli run from the shell works correctly, as well as sudo -u apache busctl. This time the output is (the same as with busctl run directly from root):
NAME PID PROCESS USER CONNECTION UNIT SESSION DESCRIPTION
:1.2 2403 NetworkManager root :1.2 NetworkManager.service - -
org.freedesktop.NetworkManager 2403 NetworkManager root :1.2 NetworkManager.service - -
Obviously NetworkManager service is visible when busctl is run from the shell, but is not visible when it's run either from PHP or from Apache directly (in the latter case it may be due to SELinux denials, in the former no denials are reported).
systemctl cat httpd shows a lot of sandboxing options active (I included all that I suppose may have impact, I'm not sure if all of them actually do):
DevicePolicy=closed
KeyringMode=private
LockPersonality=yes
MemoryDenyWriteExecute=yes
PrivateDevices=yes
PrivateTmp=true
ProtectClock=yes
ProtectControlGroups=yes
ProtectHome=read-only
ProtectHostname=yes
ProtectKernelLogs=yes
ProtectKernelModules=yes
ProtectKernelTunables=yes
ProtectSystem=yes
RestrictNamespaces=yes
RestrictRealtime=yes
RestrictSUIDSGID=yes
In systemctl cat php-fpm however, the only such option is PrivateTmp=true, which probably has no impact.
I don't care about Apache itself, the CGI script has been run only for test, what I really need is to run nmcli from PHP. I see no restrictions here.
I did strace in both cases you indicated, but the traces are too long to include here. However, in case when nmcli is run directly from the shell, strace doesn't show any access to any sockets. After loading all the libraries, locales etc. resources the process just does a lot of futex() calls, then displays output.
When it's run from PHP, after similar loading of libraries etc. there is a bunch of futex(), mprotect() and mmap() calls, of which quite a few seem probably unsuccessful(?), as they have the <unfinished> comment in strace output. Then there's open of the socket /run/dbus/system_bus_socket and an exchange on that socket which looks probably(?) like enumeration of services available on the bus. After several queries and replies, the following message is visible coming from the socket:
231390 recvmsg(6, {msg_name=NULL, msg_namelen=0, msg_iov=[{iov_base="\5\1u\0\n\0\0\0\7\1s\0\24\0\0\0org.freedesktop.DBus\0\0\0\0\4\1s\0'\0\0\0org.freedesktop
.DBus.Error.AccessDenied\0\10\1g\0\1s\0\0\6\1s\0\7\0\0\0:1.5089\0(\0\0\0Sender is not authorized to send message\0", iov_len=157}], msg_iovlen=1, msg_control
len=0, msg_flags=MSG_CMSG_CLOEXEC}, MSG_CMSG_CLOEXEC) = 157
after which nmcli writes the Network Manager is not running message and exits.
There's also the log message in /var/log/messages:
Jun 12 11:50:26 xymon dbus-broker[2402]: A security policy denied :1.5460 to sen
d method call /org/freedesktop:org.freedesktop.DBus.ObjectManager.GetManagedObje
cts to :1.2.
So that's probably the root cause why PHP cannot access network Manager. How to modify this security policy?