diff -up ntp-4.2.6p5/html/drivers/driver28.html.shmperm ntp-4.2.6p5/html/drivers/driver28.html --- ntp-4.2.6p5/html/drivers/driver28.html.shmperm 2009-12-09 08:36:37.000000000 +0100 +++ ntp-4.2.6p5/html/drivers/driver28.html 2015-02-09 15:57:57.450877311 +0100 @@ -18,7 +18,8 @@ Driver ID: SHM

Description

-

This driver receives its reference clock info from a shared memory-segment. The shared memory-segment is created with owner-only access for unit 0 and 1, and world access for unit 2 and 3

+

This driver receives its reference clock info from a shared memory-segment. The shared memory-segment is created with owner-only access for unit 0 and 1, and world access for other units unless the mode word is set for owner-only access.

+

Structure of shared memory-segment

struct shmTime {
@@ -94,6 +95,40 @@ Here is a sample showing the GPS recepti
 54364 85700.160 127.127.28.0  65   0  65   0   0
 
+

The 'mode' word

+ +

+ Some aspects of the driver behavior can be adjusted by setting bits of + the 'mode' word in the server configuration line:
+   server 127.127.28.x mode Y +

+ + + + + + + + + + + + + + + + + + + + + + + +
mode word bits and bit groups
BitDecHexMeaning
011The SHM segment is private (mode 0600). This is the fixed + default for clock units 0 and 1; clock units >1 are mode + 0666 unless this bit is set for the specific unit.
1-31--reserved -- do not use
+

Fudge Factors

time1 time @@ -112,9 +147,64 @@ Here is a sample showing the GPS recepti
Not used by this driver.
flag4 0 | 1
If flag4 is set, clockstats records will be written when the driver is polled. -

Additional Information

-

Reference Clock Drivers

+ +

Public vs. Private SHM segments

+ +

The driver attempts to create a shared memory segment with an + identifier depending on the unit number. This identifier (which can be + a numeric value or a string) clearly depends on the method used, which + in turn depends on the host operating system:

+ + + +

There's no support for POSIX shared memory yet.

+ +

NTPD is started as root on most POSIX-like operating systems + and uses the setuid/setgid system API to run under reduced rights once + the initial setup of the process is done. One consequence out of this + is that the allocation of SHM segments must be done early during the + clock setup. The actual polling of the clock is done as the run-time + user; deferring the creation of the SHM segment to this point will + create a SHM segment owned by the runtime-user account. The internal + structure of NTPD does not permit the use of a fudge flag if + this is to be avoided; this is the reason why a mode bit is used for + the configuration of a public segment. +

+ +

When running under Windows, the chosen user account must be able to + create a SHM segment in the global object name space for SHM clocks with + public access. Otherwise the session isolation used by Windows kernels + after WinXP will get into the way if the client program does not run in + the same session. +

+ +

Additional Information

+

Reference Clock Drivers

+
diff -up ntp-4.2.6p5/ntpd/refclock_shm.c.shmperm ntp-4.2.6p5/ntpd/refclock_shm.c --- ntp-4.2.6p5/ntpd/refclock_shm.c.shmperm 2015-02-09 15:52:06.131877933 +0100 +++ ntp-4.2.6p5/ntpd/refclock_shm.c 2015-02-09 15:52:06.137877933 +0100 @@ -52,6 +52,11 @@ #define NSAMPLES 3 /* stages of median filter */ /* + * Mode flags + */ +#define SHM_MODE_PRIVATE 0x0001 + +/* * Function prototypes */ static int shm_start (int unit, struct peer *peer); @@ -99,6 +104,7 @@ struct shmTime { struct shmunit { struct shmTime *shm; /* pointer to shared memory segment */ + int forall; /* access for all UIDs? */ /* debugging/monitoring counters - reset when printed */ int ticks; /* number of attempts to read data*/ @@ -109,9 +115,12 @@ struct shmunit { }; -struct shmTime *getShmTime(int); - -struct shmTime *getShmTime (int unit) { +static struct shmTime* +getShmTime( + int unit, + int/*BOOL*/ forall + ) +{ #ifndef SYS_WINNT int shmid=0; @@ -119,8 +128,8 @@ struct shmTime *getShmTime (int unit) { * Big units will give non-ascii but that's OK * as long as everybody does it the same way. */ - shmid=shmget (0x4e545030+unit, sizeof (struct shmTime), - IPC_CREAT|(unit<2?0600:0666)); + shmid=shmget(0x4e545030 + unit, sizeof (struct shmTime), + IPC_CREAT | (forall ? 0666 : 0600)); if (shmid==-1) { /*error */ msyslog(LOG_ERR,"SHM shmget (unit %d): %s",unit,strerror(errno)); return 0; @@ -199,7 +208,9 @@ shm_start( memset(up, 0, sizeof(*up)); pp->unitptr = (caddr_t)up; - up->shm = getShmTime(unit); + up->forall = (unit >= 2) && !(peer->ttl & SHM_MODE_PRIVATE); + + up->shm = getShmTime(unit, up->forall); /* * Initialize miscellaneous peer variables @@ -314,7 +325,7 @@ int shm_peek( if (up->shm == 0) { /* try to map again - this may succeed if meanwhile some- body has ipcrm'ed the old (unaccessible) shared mem segment */ - up->shm = getShmTime(unit); + up->shm = getShmTime(unit, up->forall); } shm = up->shm; if (shm == 0) {