When Unix based user and group synchronization is enabled in Ranger, UnixUserGroupBuilder periodically checks whether one of the /etc/passwd or /etc/group files is modified or not to trigger a synchronization.
However, while checking the modification of a file, the UnixUserGroupBuilder uses java.io.File.lastModified() to check whether the file is updated after the latest synchronization time.
java.io.File.lastModified() function, however, returns the latest modified timestamp in the time granularity of seconds. That means each timestamp ends with 000 independent of the millisecond precision.
This can cause UnixUserGroupBuilder to fail to detect the update on the file if the file modification check happens between the two consecutive updates within the same second. Assume the following scenario with the corresponding timestamps where UnixUserGroupBuilder checks the updates per minute.
the latest modification of users and group files are at t0 (00:00:00.111), which have a corresponding timestamp of 1529539200111, denoted by T0
Now, consider the following scenario.
- At time t1 (01:00:00.123), T1 (1529542800123): /etc/group file is updated and a new group called group01 is added.
- At time t2 (01:00:00.345), T2 (1529542800345): UnixUserGroupBuilder threads wakes up and detects the update on the group file and performed the synchronization. After the synchronization, the latest modification time for the group is updated from the File.lastModified() function. latest modification of group file = File.lastModified(t1) = 1529542800000. Please note that the last 3 digits corresponding to the milliseconds is truncated to 000 with File.lastModified() function.
- At time t3 (01:00:00.567), T3 (1529542800567): /etc/group file is updated and a user membership is added to one of the groups (e.g., user user01 becomes a member of group group01).
- At time t4 (01:01:00.345), T4 (1529542860345): UnixUserGroupBuilder thread wakes up and couldn't detect any changes since the timestamp generated from the File.lastModified() function returns the same timestamp for t1 and t3. Recall that the latest modification time of the group file becomes 1529542800000 at t2 and File.lastModified(t3) returns 1529542800000 as well. Since both File.lastModified(t1) = File.lastModified(t3), UnixUserGroupBuilder could not detect the modification on the file at t4, assumes there is no update, and then, sleeps again without syncing the changes.
At time t4, UnixUserGroupBuilder is supposed to sync the user group membership but if fails to detect the update. If there is no any further update on one of these files, the user01 will never be part of group01 in Ranger.