Bug 866714

Summary: Ownership of /var/lib/dhcpd/dhcpd.leases reverts to root:root on every dhcpd start
Product: [Fedora] Fedora Reporter: Bojan Smojver <bojan>
Component: dhcpAssignee: Jiri Popelka <jpopelka>
Status: CLOSED CURRENTRELEASE QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: medium Docs Contact:
Priority: low    
Version: 17CC: amessina, eddie, jik, jpopelka, thozza
Target Milestone: ---   
Target Release: ---   
Hardware: x86_64   
OS: Linux   
Fixed In Version: dhcp-4.2.4-19.P2.fc18 Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2012-12-06 23:21:42 EST Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---
Bug Depends On: 867291    
Bug Blocks:    

Description Bojan Smojver 2012-10-15 20:14:24 EDT
Description of problem:
On ever start, dhcpd reverts ownership of /var/lib/dhcpd/dhcpd.leases to root:root, where it should be dhcpd:dhcpd. This is then causing messages like this:
Oct 15 10:50:43 beauty dhcpd: Can't backup lease database /var/lib/dhcpd/dhcpd.leases to /var/lib/dhcpd/dhcpd.leases~: Operation not permitted

The daemon is running with correct settings (default):
/usr/sbin/dhcpd -f -cf /etc/dhcp/dhcpd.conf -user dhcpd -group dhcpd --no-pid

Version-Release number of selected component (if applicable):

How reproducible:

Steps to Reproduce:
1. Stop dhcpd service.
2. chown dhcpd:dhcpd /var/lib/dhcpd/dhcpd.leases
3. Start dhcpd service.
4. Watch ownership of /var/lib/dhcpd/dhcpd.leases changed to root:root.
Actual results:
Ownership changed to root:root.

Expected results:
Should stay as dhcpd:dhcpd.

Additional info:
/etc/sysconfig/dhcpd has not been modified.
Comment 1 Bojan Smojver 2012-10-16 00:33:25 EDT
Also in dhcp-4.2.4-16.P2.fc17.x86_64.
Comment 2 Tomáš Hozza 2012-10-16 01:56:06 EDT
This bug is a duplicate of Bug #837474.
Comment 3 Bojan Smojver 2012-10-16 02:35:50 EDT
(In reply to comment #2)
> This bug is a duplicate of Bug #837474.

Well, that bug was closed without the real fix.
Comment 4 Jiri Popelka 2012-10-16 05:35:53 EDT
Yes and as I already mentioned twice in that bug report, I've had no idea how to better fix this.

dhcpd first starts as root, then writes (as root:root) leases file and then it de-roots itself. After that it finally runs as user:group set with -user and -group parameters.

When I had changed the sequence and had made dhcpd write leases file after de-rooting itself (so the leases file had correct ownership) it resulted in bug #765967 which was quite a serious problem.

This is a duplicate of bug #837474 indeed, but we can leave it open until we have some better solution.
Comment 5 Bojan Smojver 2012-10-16 05:58:42 EDT
OK, I'll have a look at the source. No promises though...
Comment 6 Jiri Popelka 2012-10-16 06:14:31 EDT
Great. I actually already have one idea.

From time to time dhcpd makes (server/db.c::new_lease_file() I think) a backup leases~ file and creates new leases file (this time with correct user:group being dhcpd:dhcpd).
If we could do this directly after the de-rooting (server/dhcpd.c line 816) then the time of leases file having wrong ownership would be minimal.
Comment 7 Bojan Smojver 2012-10-16 06:41:00 EDT
I'm thinking, maybe db_startup() needs to get set_uid and set_gid arguments, pass them to new_lease_file() which then fchown()'s after open()?
Comment 8 Bojan Smojver 2012-10-16 06:54:25 EDT
The snippet below is junk, but you'll get what I mean:
diff -ruN dhcp-4.2.4-P2-vanilla/server/db.c dhcp-4.2.4-P2/server/db.c
--- dhcp-4.2.4-P2-vanilla/server/db.c	2012-08-28 12:13:03.000000000 +1000
+++ dhcp-4.2.4-P2/server/db.c	2012-10-16 21:49:26.036638351 +1100
@@ -36,6 +36,11 @@
 #include <ctype.h>
 #include <errno.h>
+#if defined (PARANOIA)
+#  include <sys/types.h>
+#  include <unistd.h>
+#endif /* PARANOIA */
 static isc_result_t write_binding_scope(FILE *db_file, struct binding *bnd,
@@ -1027,8 +1032,11 @@
 	return (1);
-void db_startup (testp)
-	int testp;
+#if defined (PARANOIA)
+void db_startup (int testp, uid_t set_user, gid_t set_group)
+void db_startup (int testp)
+#endif /* PARANOIA */
 	isc_result_t status;
@@ -1052,7 +1060,11 @@
 	   append it, so we create one immediately (maybe this isn't
 	   the best solution... */
 	if (trace_playback ()) {
+#if defined (PARANOIA)
+		new_lease_file (set_uid, set_gid);
 		new_lease_file ();
+#endif /* PARANOIA */
 	if (!testp) {
@@ -1066,7 +1078,11 @@
+#if defined (PARANOIA)
+		new_lease_file (set_uid, set_gid);
 		new_lease_file ();
+#endif /* PARANOIA */
@@ -1080,7 +1096,11 @@
+#if defined (PARANOIA)
+int new_lease_file (uid_t set_uid, gid_t set_gid)
 int new_lease_file ()
+#endif /* PARANOIA */
 	char newfname [512];
 	char backfname [512];
@@ -1109,6 +1129,14 @@
 		log_error ("Can't create new lease file: %m");
 		return 0;
+#if defined (PARANOIA)
+	if (fchown(db_fd, set_uid, set_gid)) {
+		log_fatal ("Can't chown new lease file: %m");
+		close(db_fd);
+		goto fdfail;
+	}
+#endif /* PARANOIA */
 	if ((new_db_file = fdopen(db_fd, "w")) == NULL) {
 		log_error("Can't fdopen new lease file: %m");

The function new_lease_file() gets called quite a bit, so all invocations would have to have all that changed, including the functions that calls that call new_lease_file() etc. I didn't even bother compiling this - just tossing ideas around...
Comment 9 Jiri Popelka 2012-10-16 11:05:33 EDT
Yes, that's even better, great.
Can you test this scratch-build ?

You need to 'setenforce 0', because we need to tweak selinux-policy - I'll fill a bug.
Comment 10 Bojan Smojver 2012-10-16 16:59:57 EDT
(In reply to comment #9)
> Yes, that's even better, great.
> Can you test this scratch-build ?
> http://koji.fedoraproject.org/koji/taskinfo?taskID=4595257
> You need to 'setenforce 0', because we need to tweak selinux-policy - I'll
> fill a bug.

Hmm, missing dependencies:
# yum --nogpgcheck --enablerepo=updates-testing localinstall dhcp-4.2.4-17.P2.fc17.x86_64.rpm dhcp-libs-4.2.4-17.P2.fc17.x86_64.rpm dhcp-common-4.2.4-17.P2.fc17.x86_64.rpm 
Loaded plugins: fastestmirror, langpacks, presto, refresh-packagekit
Examining dhcp-4.2.4-17.P2.fc17.x86_64.rpm: 12:dhcp-4.2.4-17.P2.fc17.x86_64
Marking dhcp-4.2.4-17.P2.fc17.x86_64.rpm as an update to 12:dhcp-4.2.4-16.P2.fc17.x86_64
Examining dhcp-libs-4.2.4-17.P2.fc17.x86_64.rpm: 12:dhcp-libs-4.2.4-17.P2.fc17.x86_64
Marking dhcp-libs-4.2.4-17.P2.fc17.x86_64.rpm as an update to 12:dhcp-libs-4.2.4-16.P2.fc17.x86_64
Examining dhcp-common-4.2.4-17.P2.fc17.x86_64.rpm: 12:dhcp-common-4.2.4-17.P2.fc17.x86_64
Marking dhcp-common-4.2.4-17.P2.fc17.x86_64.rpm as an update to 12:dhcp-common-4.2.4-16.P2.fc17.x86_64
Resolving Dependencies
--> Running transaction check
---> Package dhcp.x86_64 12:4.2.4-16.P2.fc17 will be updated
---> Package dhcp.x86_64 12:4.2.4-17.P2.fc17 will be an update
--> Processing Dependency: libdns-export.so.93()(64bit) for package: 12:dhcp-4.2.4-17.P2.fc17.x86_64
Loading mirror speeds from cached hostfile
 * fedora: mirror.optus.net
 * updates: mirror.optus.net
 * updates-testing: mirror.optus.net
--> Processing Dependency: libisc-export.so.90()(64bit) for package: 12:dhcp-4.2.4-17.P2.fc17.x86_64
---> Package dhcp-common.x86_64 12:4.2.4-16.P2.fc17 will be updated
--> Processing Dependency: dhcp-common = 12:4.2.4-16.P2.fc17 for package: 12:dhclient-4.2.4-16.P2.fc17.x86_64
---> Package dhcp-common.x86_64 12:4.2.4-17.P2.fc17 will be an update
---> Package dhcp-libs.x86_64 12:4.2.4-16.P2.fc17 will be updated
--> Processing Dependency: dhcp-libs(x86-64) = 12:4.2.4-16.P2.fc17 for package: 12:dhclient-4.2.4-16.P2.fc17.x86_64
---> Package dhcp-libs.x86_64 12:4.2.4-17.P2.fc17 will be an update
--> Finished Dependency Resolution
Error: Package: 12:dhcp-4.2.4-17.P2.fc17.x86_64 (/dhcp-4.2.4-17.P2.fc17.x86_64)
           Requires: libdns-export.so.93()(64bit)
           Available: 32:bind-libs-lite-9.9.0-4.fc17.x86_64 (InstallMedia)
           Available: 32:bind-libs-lite-9.9.1-9.P3.fc17.x86_64 (updates)
           Installed: 32:bind-libs-lite-9.9.2-2.fc17.x86_64 (@updates-testing)
               Not found
Error: Package: 12:dhclient-4.2.4-16.P2.fc17.x86_64 (@updates-testing)
           Requires: dhcp-common = 12:4.2.4-16.P2.fc17
           Removing: 12:dhcp-common-4.2.4-16.P2.fc17.x86_64 (@updates-testing)
               dhcp-common = 12:4.2.4-16.P2.fc17
           Updated By: 12:dhcp-common-4.2.4-17.P2.fc17.x86_64 (/dhcp-common-4.2.4-17.P2.fc17.x86_64)
               dhcp-common = 12:4.2.4-17.P2.fc17
           Available: 12:dhcp-common-4.2.4-0.4.rc1.fc17.x86_64 (InstallMedia)
               dhcp-common = 12:4.2.4-0.4.rc1.fc17
           Available: 12:dhcp-common-4.2.4-13.P2.fc17.x86_64 (updates)
               dhcp-common = 12:4.2.4-13.P2.fc17
Error: Package: 12:dhcp-4.2.4-17.P2.fc17.x86_64 (/dhcp-4.2.4-17.P2.fc17.x86_64)
           Requires: libisc-export.so.90()(64bit)
           Available: 32:bind-libs-lite-9.9.0-4.fc17.x86_64 (InstallMedia)
           Available: 32:bind-libs-lite-9.9.1-9.P3.fc17.x86_64 (updates)
           Installed: 32:bind-libs-lite-9.9.2-2.fc17.x86_64 (@updates-testing)
               Not found
Error: Package: 12:dhclient-4.2.4-16.P2.fc17.x86_64 (@updates-testing)
           Requires: dhcp-libs(x86-64) = 12:4.2.4-16.P2.fc17
           Removing: 12:dhcp-libs-4.2.4-16.P2.fc17.x86_64 (@updates-testing)
               dhcp-libs(x86-64) = 12:4.2.4-16.P2.fc17
           Updated By: 12:dhcp-libs-4.2.4-17.P2.fc17.x86_64 (/dhcp-libs-4.2.4-17.P2.fc17.x86_64)
               dhcp-libs(x86-64) = 12:4.2.4-17.P2.fc17
           Available: 12:dhcp-libs-4.2.4-0.4.rc1.fc17.x86_64 (InstallMedia)
               dhcp-libs(x86-64) = 12:4.2.4-0.4.rc1.fc17
           Available: 12:dhcp-libs-4.2.4-13.P2.fc17.x86_64 (updates)
               dhcp-libs(x86-64) = 12:4.2.4-13.P2.fc17
 You could try using --skip-broken to work around the problem
 You could try running: rpm -Va --nofiles --nodigest

I see this:
# rpm -q --provides bind-libs-lite
bind-libbind-devel = 31:9.3.3-4.fc7
bind-libs-lite = 32:9.9.2-2.fc17
bind-libs-lite(x86-64) = 32:9.9.2-2.fc17

Did you build this against some other version of bind?
Comment 11 Bojan Smojver 2012-10-16 17:20:27 EDT
Ah, I see what's going on - this was built against current stable bind.

Yep, I can confirm that after using the RPMs from the scratch build, the leases file indeed stays owned by dhcpd:dhcpd.

This is the SELinux policy requirement:
require {
	type dhcpd_t;
	class capability chown;

#============= dhcpd_t ==============
allow dhcpd_t self:capability chown;
Comment 12 Bojan Smojver 2012-10-17 19:35:39 EDT
Could you place an official build in F-17 testing repo? Give it super high karma requirement, if you wish, so it cannot be pushed into stable by accident.
Comment 13 Jiri Popelka 2012-10-18 02:40:16 EDT
In most cases karma comes from people having only dhclient installed so I usually can't rely on somebody testing dhcpd. But I'll do it (if Miroslav changes the selinux-policy for F17) because you provided the original idea & patch ;-)
Comment 14 Jonathan Kamens 2012-10-22 20:28:37 EDT
I am encountering this issue, and I am happy to test any fix and give karma to it if it works and doesn't seem to cause any other issues.
Comment 15 Fedora Update System 2012-11-30 09:55:14 EST
dhcp-4.2.4-23.P2.fc18 has been submitted as an update for Fedora 18.
Comment 16 Fedora Update System 2012-11-30 15:34:05 EST
Package dhcp-4.2.4-23.P2.fc18:
* should fix your issue,
* was pushed to the Fedora 18 testing repository,
* should be available at your local mirror within two days.
Update it with:
# su -c 'yum update --enablerepo=updates-testing dhcp-4.2.4-23.P2.fc18'
as soon as you are able to.
Please go to the following url:
then log in and leave karma (feedback).
Comment 17 Fedora Update System 2012-12-06 23:21:44 EST
dhcp-4.2.4-23.P2.fc18 has been pushed to the Fedora 18 stable repository.  If problems still persist, please make note of it in this bug report.