As I mentioned in the last message, I want to run ntpd as a separate ntp user/group with only the necessary privileges.
To achieve this, I had to make a couple of changes: * Add a new ntp user and group to /etc/passwd and /etc/group. This will probably have to be handled via the OS/Net consolidation, since SUNWntp* will be part of the base system. It would be nicest to use uid/gid 123 :-), but I think uids > 100 are reserved for the user. I have no idea how such new daemon uid's/gid's are allocated. * I changed /var/ntp, /var/ntp/ntpstats to use that uid/gid. This needs to be done during an upgrade, too. (Actually, I only did this after the initial privilege debugging step.) * After that, I modified the ntp SMF manifest to run the start method as user ntp, but with all privileges, and used Darren Moffat's privdebug script to investigate the privileges used. At first, I had to modify ntpd.c to remove the check for uid 0 (Bug 644) so ntpd runs as non-root at all. Here's what I found: ntpd: file_dac_write for /var/ntp/ntp.drift, ntpstats/* (were owned by root:sys before) net_privaddr for bind to port 123 proc_fork resolving process (in basic set) proc_exec for method script (in basic set) proc_lock_memory for memcntl sys_net_config strange udp-internal use, see below sys_time for ntp_adjtime ntpdate: net_privaddr for bind to port 123 proc_priocntl for setpriority file_dac_write is unnecessary when /var/ntp and below properly belong to ntp:ntp, so they can be dropped. net_privaddr may perhaps be dropped (at least temporarily) after startup, though it will be needed later with runtime configuration. proc_exec should be dropped by ntpd after startup, and may become unnecessary if we can avoid the method script alltogether and just start ntpd directly. proc_lock_memory (used by mlockall) can be dropped after startup as well. sys_net_config was strange: at first I thought it was needed for sendto with a source port of 123, although net_privaddr should handle that. I had modified privdebug to include a ustack() so I could see at what point in the user code the privilege was needed. Inspection of the kernel code revealed that it is used in udp.c (udp_bind_hash_report and udp_status_report). I doesn't seem to be necessary for ntpd to run successfully, so the privdebug output can be confusing and result in too many privileges being granted. I'll probably report this to Darren. sys_time is obviously needed for ntp_adjtime and cannot be dropped at all ntpdate needs proc_priocntl additionaly, due to its use of setpriority. ntpd would need it as well if invoked with -N. Apart from that, some privileges from the basic set aren't needed and should thus be dropped: file_link_any, proc_info, proc_session. So here's the relevant section of the modified ntp SMF manifest: <exec_method type='method' name='start' exec='/lib/svc/method/ntp' timeout_seconds='1800' > <method_context> <!-- privileges: from the basic set, only proc_fork and proc_exec need to be retained so the method script can run. net_privaddr is necessary to bind to privileged port 123, proc_lock_memory is needed for mlockall, sys_time is of course necessary for ntp_adjtime, proc_priocntl is needed by ntpdate (setpriority) --> <method_credential user='ntp' group='ntp' privileges='basic,!file_link_any,!proc_info,!proc_session,net_privaddr,proc_lock_memory,sys_time,proc_priocntl' /> </method_context> </exec_method> We need three groups of code changes to ntpd, though: * Checking for <sys/priv.h> and allowing the daemon to run as non-root at all (which is currently avoided by a hack to #if 0 the check in ntpd.c). * Dropping all privileges which are only needed during startup after the daemon is up. * Temporarily dropping net_privaddr while it isn't needed. I'll go for the first group initially and implement more (perhaps for ntp-dev) as time permits. Rainer ----------------------------------------------------------------------------- Rainer Orth, Faculty of Technology, Bielefeld University