Large uid's with Etc.getpwnam

I beleve there is a bug in Etc.getpwnam. On our OS X server running
10.4 with ruby 1.8.2 (2004-12-25) [powerpc-darwin8.0] we use AD for user
management.
The two id’s the one that is my real id i got from ls -ln and the one
from getpwnam differ only in the sign bit, so it looks like ruby is
treating it as a 1’s compliment number when it is an unsigned int. i
could change if you take -566183520 & 0x7FFFFFFF in ruby it will return
the proper number 1581300128. The same happens for all users with
larger id’s in our AD system.

irb(main):016:0> Etc.getpwuid(1581300128)
=> #<struct Struct::Passwd name=“mcgoverp”, passwd="********",
uid=-566183520, gid=513, gecos=“Ryan McGovern”,
dir="/Network/Servers/ucfilespace.uc.edu/Home/m/mcgoverp",
shell="/usr/local/profile", change=0, uclass="", expire=0>

irb(main):017:0> uinf=Etc.getpwnam(“mcgoverp”)
=> #<struct Struct::Passwd name=“mcgoverp”, passwd="********",
uid=-566183520, gid=513, gecos=“Ryan McGovern”,
dir="/Network/Servers/ucfilespace.uc.edu/Home/m/mcgoverp",
shell="/usr/local/profile", change=0, uclass="", expire=0>

irb(main):019:0> Etc.getpwuid(-566183520)
ArgumentError: can’t find user for -566183520
from (irb):19:in `getpwuid’
from (irb):19
from :0

irb(main):005:0> Etc.getpwnam(“monkir”)
=> #<struct Struct::Passwd name=“monkir”, passwd=“",
uid=-476125468, gid=513, gecos=“Ian Monk”,
dir="/Network/Servers/ucfilespace.uc.edu/Home/m/monkir",
shell="/bin/bash", change=0, uclass="", expire=0>
irb(main):006:0> Etc.getpwnam(“monkir”).uid & 0x7FFFFFFF
=> 1671358180
irb(main):007:0> Etc.getpwuid(1671358180)
=> #<struct Struct::Passwd name=“monkir”, passwd="
”,
uid=-476125468, gid=513, gecos=“Ian Monk”,
dir="/Network/Servers/ucfilespace.uc.edu/Home/m/monkir",
shell="/bin/bash", change=0, uclass="", expire=0>

Hi,

At Tue, 27 Jun 2006 00:06:18 +0900,
Ryan McGovern wrote in [ruby-talk:199102]:

I beleve there is a bug in Etc.getpwnam. On our OS X server
running 10.4 with ruby 1.8.2 (2004-12-25) [powerpc-darwin8.0]
we use AD for user management.

Does this help?

  • ext/etc/etc.c (setup_passwd, setup_group): allow bignum uid, gid and
    so on. [ruby-talk:199102]

Index: ext/etc/etc.c

RCS file: /cvs/ruby/src/ruby/ext/etc/etc.c,v
retrieving revision 1.22
diff -p -u -2 -r1.22 etc.c
— ext/etc/etc.c 20 Jun 2006 18:02:14 -0000 1.22
+++ ext/etc/etc.c 26 Jun 2006 16:53:48 -0000
@@ -77,6 +77,6 @@ setup_passwd(struct passwd *pwd)
safe_setup_str(pwd->pw_passwd),
#endif

  •   	 INT2FIX(pwd->pw_uid),
    
  •   	 INT2FIX(pwd->pw_gid),
    
  •   	 PW_UID2VAL(pwd->pw_uid),
    
  •   	 PW_GID2VAL(pwd->pw_gid),
    

#ifdef HAVE_ST_PW_GECOS
safe_setup_str(pwd->pw_gecos),
@@ -85,8 +85,8 @@ setup_passwd(struct passwd *pwd)
safe_setup_str(pwd->pw_shell),
#ifdef HAVE_ST_PW_CHANGE

  •   	 INT2FIX(pwd->pw_change),
    
  •   	 INT2NUM(pwd->pw_change),
    

#endif
#ifdef HAVE_ST_PW_QUOTA

  •   	 INT2FIX(pwd->pw_quota),
    
  •   	 INT2NUM(pwd->pw_quota),
    

#endif
#ifdef HAVE_ST_PW_AGE
@@ -100,5 +100,5 @@ setup_passwd(struct passwd *pwd)
#endif
#ifdef HAVE_ST_PW_EXPIRE

  •   	 INT2FIX(pwd->pw_expire),
    
  •   	 INT2NUM(pwd->pw_expire),
    

#endif
0 /dummy/
@@ -302,5 +302,5 @@ setup_group(struct group *grp)
safe_setup_str(grp->gr_passwd),
#endif

  •   	 INT2FIX(grp->gr_gid),
    
  •   	 PW_GID2VAL(grp->gr_gid),
      	 mem);
    

}
Index: ext/etc/extconf.rb

RCS file: /cvs/ruby/src/ruby/ext/etc/extconf.rb,v
retrieving revision 1.6
diff -p -u -2 -r1.6 extconf.rb
— ext/etc/extconf.rb 6 Sep 2005 23:35:15 -0000 1.6
+++ ext/etc/extconf.rb 26 Jun 2006 17:05:23 -0000
@@ -25,5 +25,18 @@ if a or b or c
have_struct_member(‘struct passwd’, ‘pw_passwd’, ‘pwd.h’)
have_struct_member(‘struct group’, ‘gr_passwd’, ‘grp.h’)

  • have_type(“uid_t”);
  • have_header(“lastlog.h”) and have_header(“paths.h”)
  • [%w"uid_t pwd.h", %w"gid_t grp.h"].each do |t, h|
  • if have_type(t, [“sys/types.h”, h])
  •  if try_static_assert("sizeof(#{t}) > sizeof(long)")
    
  • f = “LL2NUM”
  •  else
    
  • f = “INT2NUM”
  •  end
    
  •  if try_static_assert("(#{t})-1 > 0")
    
  • f = “U#{f}”
  •  end
    
  •  $defs.push("-DPW_#{t.chomp('_t').upcase}2VAL=#{f}")
    
  • end
  • end
    create_makefile(“etc”)
    end

Hi,

At Tue, 27 Jun 2006 02:08:15 +0900,
[email protected] wrote in [ruby-talk:199131]:

At Tue, 27 Jun 2006 00:06:18 +0900,
Ryan McGovern wrote in [ruby-talk:199102]:

I beleve there is a bug in Etc.getpwnam. On our OS X server
running 10.4 with ruby 1.8.2 (2004-12-25) [powerpc-darwin8.0]
we use AD for user management.

Does this help?

Sorry, the patch for extconf.rb was wrong.

  • ext/etc/etc.c (setup_passwd, setup_group): allow bignum uid, gid and
    so on. [ruby-talk:199102]

Index: ext/etc/etc.c

RCS file: /cvs/ruby/src/ruby/ext/etc/etc.c,v
retrieving revision 1.22
diff -p -u -2 -r1.22 etc.c
— ext/etc/etc.c 20 Jun 2006 18:02:14 -0000 1.22
+++ ext/etc/etc.c 26 Jun 2006 16:53:48 -0000
@@ -77,6 +77,6 @@ setup_passwd(struct passwd *pwd)
safe_setup_str(pwd->pw_passwd),
#endif

  •   	 INT2FIX(pwd->pw_uid),
    
  •   	 INT2FIX(pwd->pw_gid),
    
  •   	 PW_UID2VAL(pwd->pw_uid),
    
  •   	 PW_GID2VAL(pwd->pw_gid),
    

#ifdef HAVE_ST_PW_GECOS
safe_setup_str(pwd->pw_gecos),
@@ -85,8 +85,8 @@ setup_passwd(struct passwd *pwd)
safe_setup_str(pwd->pw_shell),
#ifdef HAVE_ST_PW_CHANGE

  •   	 INT2FIX(pwd->pw_change),
    
  •   	 INT2NUM(pwd->pw_change),
    

#endif
#ifdef HAVE_ST_PW_QUOTA

  •   	 INT2FIX(pwd->pw_quota),
    
  •   	 INT2NUM(pwd->pw_quota),
    

#endif
#ifdef HAVE_ST_PW_AGE
@@ -100,5 +100,5 @@ setup_passwd(struct passwd *pwd)
#endif
#ifdef HAVE_ST_PW_EXPIRE

  •   	 INT2FIX(pwd->pw_expire),
    
  •   	 INT2NUM(pwd->pw_expire),
    

#endif
0 /dummy/
@@ -302,5 +302,5 @@ setup_group(struct group *grp)
safe_setup_str(grp->gr_passwd),
#endif

  •   	 INT2FIX(grp->gr_gid),
    
  •   	 PW_GID2VAL(grp->gr_gid),
      	 mem);
    

}
Index: ext/etc/extconf.rb

RCS file: /cvs/ruby/src/ruby/ext/etc/extconf.rb,v
retrieving revision 1.6
diff -p -u -2 -r1.6 extconf.rb
— ext/etc/extconf.rb 6 Sep 2005 23:35:15 -0000 1.6
+++ ext/etc/extconf.rb 26 Jun 2006 17:05:23 -0000
@@ -25,5 +25,18 @@ if a or b or c
have_struct_member(‘struct passwd’, ‘pw_passwd’, ‘pwd.h’)
have_struct_member(‘struct group’, ‘gr_passwd’, ‘grp.h’)

  • have_type(“uid_t”);
  • [%w"uid_t pwd.h", %w"gid_t grp.h"].each do |t, *h|
  • h << “sys/types.h”
  • if have_type(t, h)
  •  if try_static_assert("sizeof(#{t}) > sizeof(long)", h)
    
  • f = “LL2NUM”
  •  else
    
  • f = “INT2NUM”
  •  end
    
  •  if try_static_assert("(#{t})-1 > 0", h)
    
  • f = “U#{f}”
  •  end
    
  •  $defs.push("-DPW_#{t.chomp('_t').upcase}2VAL=#{f}")
    
  • end
  • end
    create_makefile(“etc”)
    end

Hi,

In message “Re: Large uid’s with Etc.getpwnam”
on Tue, 27 Jun 2006 02:22:36 +0900, [email protected] writes:

|* ext/etc/etc.c (setup_passwd, setup_group): allow bignum uid, gid and
| so on. [ruby-talk:199102]

Commit the fix please.

						matz.