Backport #7886

Not recognizing unix group permissions for Mac OS X (Mountain Lion) when user account have >16 groups

Added by Alfred Fazio about 1 year ago. Updated about 1 year ago.

[ruby-core:52537]
Status:Closed
Priority:Normal
Assignee:Tomoyuki Chikanaga

Description

The following bug occurs in 1.9.3 p374 and also in 1.8.7 p371

When using a Active Directory mobile account in Mac OS X (only tested thus far with Mountain Lion), Ruby does not honor Unix group membership when testing file permissions.

Let me give an example:

% whoami
afazio

I am in the "rvm" group:

% groups
rvm

Let's create a simple file:

% touch test-file
% sudo chown root:rvm test-file
% sudo chmod 660 test-file

% ls -l test-file
-rw-rw---- 1 root rvm 4 Feb 19 11:43 test-file

At this moment only root and members of "rvm" group can modify test-file

OS recognizes I have correct permissions:

% echo "test data" >> test-file
% cat test-file
test data

However, Ruby does not:

% irb
1.9.3-p374 :001 > File.exists?("test-file")
=> true
1.9.3-p374 :002 > File.writable?("test-file")
=> false

To further illustrate, I can write to this file in Ruby:

pry(main)> File.open("test-file", "w") do |f|
pry(main)* f.write("wee")

pry(main)* end

3
pry(main)> quit

% cat test-file
wee

ruby-rb_group_member-ngroups.patch Magnifier (345 Bytes) Alfred Fazio, 02/21/2013 06:04 AM

Associated revisions

Revision 39588
Added by Tomoyuki Chikanaga about 1 year ago

merge revision(s) 39349,39374: [Backport #7886]

* file.c (rb_group_member): get rid of NGROUPS dependency.
  [Bug #7886] 

History

#1 Updated by Motohiro KOSAKI about 1 year ago

File.writable?() behavior depend on access(2). So, I suspect this is a bug of access(2) on OS X.

#2 Updated by Koichi Sasada about 1 year ago

  • Category set to core
  • Status changed from Open to Feedback
  • Assignee set to Nobuyoshi Nakada
  • Target version set to next minor

afazio,
Could you try in C using access(2)?

#3 Updated by Alfred Fazio about 1 year ago

Thank you for the quick feedback.

I implemented a quick C program to test the results of access(). You can see the source at: https://gist.github.com/afazio/4998363

Running this program as an AD user in Mac OS X on the same file as created in the original bug report, access() returns that I DO have write permission, whereas Ruby returns that I do NOT have write permission per File.writable?()

Here is the output of running the application:

% ./main /Users/afazio/access/test-file
Checking write permissions for /Users/afazio/access/test-file:
User DOES have write permissions.

% irb
irb> File.exists?("/Users/afazio/access/test-file")
=> true
irb> File.writable?("/Users/afazio/access/test-file")
=> false

#4 Updated by Alfred Fazio about 1 year ago

Looking at ruby/file.c shows that File.writable? (or rather rbfilewritable_p()) calls "eaccess", not "access".

eaccess is defined on line 1061 of ruby/file.c in ruby-trunk.

Because S_IXGRP is defined in OS X (in sys/stat.h), the block of code in eaccess between

#ifdef USE_GETEUID
....
#else

is executed rather than access().

It appears that the call to rbgroupmember() in this code block is ultimately what is returning false when it should return true.

#5 Updated by Alfred Fazio about 1 year ago

OK, I see the issue.

rbgroupmember looks at the following constants:

sys/syslimits.h:#define NGROUPSMAX 16
sys/param.h:#define NGROUPS NGROUPS
MAX

What's going on is that rbgroupmember is only iterating over 16 groups (because NGROUPSMAX is set to 16 groups.) However, my user account is a member of 31 groups. Therefore rbgroup_member() never checks all of my groups. It only checks a subset of them.

#6 Updated by Alfred Fazio about 1 year ago

So, to summarize, this is not a problem with AD. This is an issue for any user that is a member of more than 16 groups in OS X.

It just so happened that my AD user account has many NTDOMAIN groups that it is a member of, which inflated my group membership to well over 16.

I propose that the minimum NGROUPS be set at 32. I'm sure there are other ways to solve the issue, however.

I've attached a patch for the rbgroupmember() function in file.c that ensures a minimum of 32 for NGROUPS.

I've compiled Ruby with this patch and it indeed fixes the issue.

#7 Updated by Alfred Fazio about 1 year ago

Here is some more info on the NGROUPS and NGROUPS_MAX constants as defined by various operating systems:

http://www.j3e.de/ngroups.html

It appears that 16 is an especially important limit when utilizing NFS. However I am clearly able to be a member of more than 16 groups in OS X without problems. I am not using NFS.

#8 Updated by Motohiro KOSAKI about 1 year ago

  • Subject changed from Not recognizing unix group permissions for Mac OS X (Mountain Lion) Active Directory (AD) mobile accounts to Not recognizing unix group permissions for Mac OS X (Mountain Lion) when user account have >16 groups
  • Status changed from Feedback to Assigned
  • Assignee changed from Nobuyoshi Nakada to Motohiro KOSAKI
  • Priority changed from High to Normal

Fully understand. Thank you for investigation.

This is definitely Mac bug. It has broken NGROUPS definition. It is NOT only NFS specific issue.
However, I think we can implement some workaround code. I'm willing thinking about it.

#9 Updated by Motohiro KOSAKI about 1 year ago

  • Status changed from Assigned to Closed
  • % Done changed from 0 to 100

This issue was solved with changeset r39349.
Alfred, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


  • file.c (rbgroupmember): get rid of NGROUPS dependency. [Bug #7886]

#10 Updated by Motohiro KOSAKI about 1 year ago

I hope backport r39349, r39352 and r39353.

#11 Updated by Motohiro KOSAKI about 1 year ago

  • Tracker changed from Bug to Backport
  • Project changed from ruby-trunk to Backport200
  • Category deleted (core)
  • Status changed from Closed to Assigned
  • Assignee changed from Motohiro KOSAKI to Tomoyuki Chikanaga
  • Target version deleted (next minor)

#12 Updated by Motohiro KOSAKI about 1 year ago

The backport is needed to 1.9.3 and 2.0pX (not 2.0p0).

#13 Updated by Alfred Fazio about 1 year ago

Thank you!!

#14 Updated by Tomoyuki Chikanaga about 1 year ago

  • Status changed from Assigned to Closed

This issue was solved with changeset r39588.
Alfred, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


merge revision(s) 39349,39374: [Backport #7886]

* file.c (rb_group_member): get rid of NGROUPS dependency.
  [Bug #7886] 

Also available in: Atom PDF