From e960cf417abc5b3c2fef8271412fcfc9c2c32607 Mon Sep 17 00:00:00 2001 From: akr Date: Sun, 8 Feb 2009 11:36:18 +0000 Subject: * ext/socket/extconf.rb: check struct sockcred. * ext/socket/ancdata.c (anc_inspect_socket_creds): new function to show SCM_CREDS on NetBSD. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@22126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 7 +++++++ ext/socket/ancdata.c | 38 ++++++++++++++++++++++++++++++++++++++ ext/socket/extconf.rb | 2 ++ test/socket/test_unix.rb | 25 +++++++++++++++++++++---- 4 files changed, 68 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index e532d25e11..cc27dc3cff 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +Sun Feb 8 20:30:29 2009 Tanaka Akira + + * ext/socket/extconf.rb: check struct sockcred. + + * ext/socket/ancdata.c (anc_inspect_socket_creds): new function to + show SCM_CREDS on NetBSD. + Sun Feb 8 19:05:24 2009 Nobuyoshi Nakada * include/ruby/backward/rubysig.h: extern "C" was missing. diff --git a/ext/socket/ancdata.c b/ext/socket/ancdata.c index 012f8d34b7..c2606fb366 100644 --- a/ext/socket/ancdata.c +++ b/ext/socket/ancdata.c @@ -393,6 +393,41 @@ anc_inspect_passcred_credentials(int level, int type, VALUE data, VALUE ret) } #endif +#if defined(SCM_CREDS) && defined(HAVE_TYPE_STRUCT_SOCKCRED) /* NetBSD */ +#define INSPECT_SCM_CREDS +static int +anc_inspect_socket_creds(int level, int type, VALUE data, VALUE ret) +{ + int i; + if (level == SOL_SOCKET && type == SCM_CREDS && + RSTRING_LEN(data) >= SOCKCREDSIZE(0)) { + struct sockcred cred0, *cred; + memcpy(&cred0, RSTRING_PTR(data), SOCKCREDSIZE(0)); + if (RSTRING_LEN(data) != SOCKCREDSIZE(cred0.sc_ngroups)) { + return -1; + } + cred = (struct sockcred *)ALLOCA_N(char, SOCKCREDSIZE(cred0.sc_ngroups)); + memcpy(cred, RSTRING_PTR(data), SOCKCREDSIZE(cred0.sc_ngroups)); + rb_str_catf(ret, " uid=%u", cred->sc_uid); + rb_str_catf(ret, " euid=%u", cred->sc_euid); + rb_str_catf(ret, " gid=%u", cred->sc_gid); + rb_str_catf(ret, " egid=%u", cred->sc_egid); + if (cred0.sc_ngroups) { + char *sep = "="; + rb_str_cat2(ret, " groups"); + for (i = 0; i < cred0.sc_ngroups; i++) { + rb_str_catf(ret, "%s%u", sep, cred->sc_groups[i]); + sep = ","; + } + } + return 0; + } + else { + return -1; + } +} +#endif + #if defined(IPPROTO_IP) && defined(IP_RECVDSTADDR) /* 4.4BSD */ static int anc_inspect_ip_recvdstaddr(int level, int type, VALUE data, VALUE ret) @@ -516,6 +551,9 @@ ancillary_inspect(VALUE self) # endif # if defined(SCM_CREDENTIALS) /* GNU/Linux */ case SCM_CREDENTIALS: if (anc_inspect_passcred_credentials(level, type, data, ret) == -1) goto dump; break; +# endif +# if defined(INSPECT_SCM_CREDS) /* NetBSD */ + case SCM_CREDS: if (anc_inspect_socket_creds(level, type, data, ret) == -1) goto dump; break; # endif default: goto dump; } diff --git a/ext/socket/extconf.rb b/ext/socket/extconf.rb index a0a4f8e9f7..ad36112926 100644 --- a/ext/socket/extconf.rb +++ b/ext/socket/extconf.rb @@ -308,6 +308,8 @@ have_type("struct in6_pktinfo", headers) {|src| "#else\n" << "#error\n" << ">>>>>> no in6_pktinfo <<<<<<\n" << "#endif\n" } +have_type("struct sockcred", headers) + $distcleanfiles << "constants.h" << "constdefs.*" if have_func(test_func) diff --git a/test/socket/test_unix.rb b/test/socket/test_unix.rb index e783faff3b..4d6aa23e40 100644 --- a/test/socket/test_unix.rb +++ b/test/socket/test_unix.rb @@ -306,11 +306,28 @@ class TestUNIXSocket < Test::Unit::TestCase s.setsockopt(:SOCKET, :PASSCRED, 1) c.print "a" msg, cliend_ai, rflags, cred = s.recvmsg - p cred assert_equal("a", msg) - assert_match(/pid=#{$$} /, cred.inspect) - assert_match(/uid=#{Process.uid} /, cred.inspect) - assert_match(/gid=#{Process.gid}>/, cred.inspect) + assert_match(/ pid=#{$$} /, cred.inspect) + assert_match(/ uid=#{Process.uid} /, cred.inspect) + assert_match(/ gid=#{Process.gid}>/, cred.inspect) + } + end + + def test_netbsd_cred + return if /netbsd/ !~ RUBY_PLATFORM + Dir.mktmpdir {|d| + sockpath = "#{d}/sock" + serv = Socket.unix_server_socket(sockpath) + c = Socket.unix(sockpath) + s, = serv.accept + s.setsockopt(0, Socket::LOCAL_CREDS, 1) + c.print "a" + msg, cliend_ai, rflags, cred = s.recvmsg + assert_equal("a", msg) + assert_match(/ uid=#{Process.uid} /, cred.inspect) + assert_match(/ euid=#{Process.euid} /, cred.inspect) + assert_match(/ gid=#{Process.gid} /, cred.inspect) + assert_match(/ egid=#{Process.egid} /, cred.inspect) } end -- cgit v1.2.3