* ext/socket/extconf.rb: check struct cmsgcred.
* ext/socket/ancdata.c (anc_inspect_passcred_credentials): add "(ucred)". (anc_inspect_socket_creds): show struct cmsgcred too, for FreeBSD. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@22129 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
c79dac1c3e
commit
411e9997d2
@ -1,3 +1,11 @@
|
|||||||
|
Sun Feb 8 21:47:50 2009 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
|
* ext/socket/extconf.rb: check struct cmsgcred.
|
||||||
|
|
||||||
|
* ext/socket/ancdata.c (anc_inspect_passcred_credentials): add
|
||||||
|
"(ucred)".
|
||||||
|
(anc_inspect_socket_creds): show struct cmsgcred too, for FreeBSD.
|
||||||
|
|
||||||
Sun Feb 8 21:05:35 2009 Tanaka Akira <akr@fsij.org>
|
Sun Feb 8 21:05:35 2009 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
* lib/drb/extservm.rb (DRb::ExtServManager#invoke_service_command):
|
* lib/drb/extservm.rb (DRb::ExtServManager#invoke_service_command):
|
||||||
|
@ -385,6 +385,7 @@ anc_inspect_passcred_credentials(int level, int type, VALUE data, VALUE ret)
|
|||||||
struct ucred cred;
|
struct ucred cred;
|
||||||
memcpy(&cred, RSTRING_PTR(data), sizeof(struct ucred));
|
memcpy(&cred, RSTRING_PTR(data), sizeof(struct ucred));
|
||||||
rb_str_catf(ret, " pid=%u uid=%u gid=%u", cred.pid, cred.uid, cred.gid);
|
rb_str_catf(ret, " pid=%u uid=%u gid=%u", cred.pid, cred.uid, cred.gid);
|
||||||
|
rb_str_cat2(ret, " (ucred)");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -393,38 +394,71 @@ anc_inspect_passcred_credentials(int level, int type, VALUE data, VALUE ret)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(SCM_CREDS) && defined(HAVE_TYPE_STRUCT_SOCKCRED) /* NetBSD */
|
#if defined(SCM_CREDS)
|
||||||
#define INSPECT_SCM_CREDS
|
#define INSPECT_SCM_CREDS
|
||||||
static int
|
static int
|
||||||
anc_inspect_socket_creds(int level, int type, VALUE data, VALUE ret)
|
anc_inspect_socket_creds(int level, int type, VALUE data, VALUE ret)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
if (level == SOL_SOCKET && type == SCM_CREDS &&
|
if (level != SOL_SOCKET && type != SCM_CREDS)
|
||||||
RSTRING_LEN(data) >= SOCKCREDSIZE(0)) {
|
return -1;
|
||||||
struct sockcred cred0, *cred;
|
|
||||||
memcpy(&cred0, RSTRING_PTR(data), SOCKCREDSIZE(0));
|
/*
|
||||||
if (RSTRING_LEN(data) != SOCKCREDSIZE(cred0.sc_ngroups)) {
|
* FreeBSD has struct cmsgcred and struct sockcred.
|
||||||
return -1;
|
* They use both SOL_SOCKET/SCM_CREDS in the ancillary message.
|
||||||
}
|
* They are not ambiguous from the view of the caller
|
||||||
cred = (struct sockcred *)ALLOCA_N(char, SOCKCREDSIZE(cred0.sc_ngroups));
|
* because struct sockcred is sent if and only if the caller sets LOCAL_CREDS socket option.
|
||||||
memcpy(cred, RSTRING_PTR(data), SOCKCREDSIZE(cred0.sc_ngroups));
|
* But inspect method doesn't know it.
|
||||||
rb_str_catf(ret, " uid=%u", cred->sc_uid);
|
* So they are ambiguous from the view of inspect.
|
||||||
rb_str_catf(ret, " euid=%u", cred->sc_euid);
|
* This function distinguish them by the size of the ancillary message.
|
||||||
rb_str_catf(ret, " gid=%u", cred->sc_gid);
|
* This heuristics works well except when sc_ngroups == CMGROUP_MAX.
|
||||||
rb_str_catf(ret, " egid=%u", cred->sc_egid);
|
*/
|
||||||
if (cred0.sc_ngroups) {
|
|
||||||
|
#if defined(HAVE_TYPE_STRUCT_CMSGCRED) /* FreeBSD */
|
||||||
|
if (RSTRING_LEN(data) == sizeof(struct cmsgcred)) {
|
||||||
|
struct cmsgcred cred;
|
||||||
|
memcpy(&cred, RSTRING_PTR(data), sizeof(struct cmsgcred));
|
||||||
|
rb_str_catf(ret, " pid=%u", cred.cmcred_pid);
|
||||||
|
rb_str_catf(ret, " uid=%u", cred.cmcred_uid);
|
||||||
|
rb_str_catf(ret, " euid=%u", cred.cmcred_euid);
|
||||||
|
rb_str_catf(ret, " gid=%u", cred.cmcred_gid);
|
||||||
|
if (cred.cmcred_ngroups) {
|
||||||
char *sep = "=";
|
char *sep = "=";
|
||||||
rb_str_cat2(ret, " groups");
|
rb_str_cat2(ret, " groups");
|
||||||
for (i = 0; i < cred0.sc_ngroups; i++) {
|
for (i = 0; i < cred.cmcred_ngroups; i++) {
|
||||||
rb_str_catf(ret, "%s%u", sep, cred->sc_groups[i]);
|
rb_str_catf(ret, "%s%u", sep, cred.cmcred_groups[i]);
|
||||||
sep = ",";
|
sep = ",";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
rb_str_cat2(ret, " (cmsgcred)");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else {
|
#endif
|
||||||
return -1;
|
#if defined(HAVE_TYPE_STRUCT_SOCKCRED) /* FreeBSD, NetBSD */
|
||||||
|
if (RSTRING_LEN(data) >= SOCKCREDSIZE(0)) {
|
||||||
|
struct sockcred cred0, *cred;
|
||||||
|
memcpy(&cred0, RSTRING_PTR(data), SOCKCREDSIZE(0));
|
||||||
|
if (RSTRING_LEN(data) == SOCKCREDSIZE(cred0.sc_ngroups)) {
|
||||||
|
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 = ",";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rb_str_cat2(ret, " (sockcred)");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -309,6 +309,7 @@ have_type("struct in6_pktinfo", headers) {|src|
|
|||||||
}
|
}
|
||||||
|
|
||||||
have_type("struct sockcred", headers)
|
have_type("struct sockcred", headers)
|
||||||
|
have_type("struct cmsgcred", headers)
|
||||||
|
|
||||||
$distcleanfiles << "constants.h" << "constdefs.*"
|
$distcleanfiles << "constants.h" << "constdefs.*"
|
||||||
|
|
||||||
|
@ -296,7 +296,7 @@ class TestUNIXSocket < Test::Unit::TestCase
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_cred_linux
|
def test_cred_ucred
|
||||||
return if /linux/ !~ RUBY_PLATFORM
|
return if /linux/ !~ RUBY_PLATFORM
|
||||||
Dir.mktmpdir {|d|
|
Dir.mktmpdir {|d|
|
||||||
sockpath = "#{d}/sock"
|
sockpath = "#{d}/sock"
|
||||||
@ -306,15 +306,17 @@ class TestUNIXSocket < Test::Unit::TestCase
|
|||||||
s.setsockopt(:SOCKET, :PASSCRED, 1)
|
s.setsockopt(:SOCKET, :PASSCRED, 1)
|
||||||
c.print "a"
|
c.print "a"
|
||||||
msg, cliend_ai, rflags, cred = s.recvmsg
|
msg, cliend_ai, rflags, cred = s.recvmsg
|
||||||
|
inspect = cred.inspect
|
||||||
assert_equal("a", msg)
|
assert_equal("a", msg)
|
||||||
assert_match(/ pid=#{$$} /, cred.inspect)
|
assert_match(/ pid=#{$$} /, inspect)
|
||||||
assert_match(/ uid=#{Process.uid} /, cred.inspect)
|
assert_match(/ uid=#{Process.uid} /, inspect)
|
||||||
assert_match(/ gid=#{Process.gid}>/, cred.inspect)
|
assert_match(/ gid=#{Process.gid}>/, inspect)
|
||||||
|
assert_match(/ \(ucred\)/, inspect)
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_cred_netbsd
|
def test_cred_sockcred
|
||||||
return if /netbsd/ !~ RUBY_PLATFORM
|
return if /netbsd|freebsd/ !~ RUBY_PLATFORM
|
||||||
Dir.mktmpdir {|d|
|
Dir.mktmpdir {|d|
|
||||||
sockpath = "#{d}/sock"
|
sockpath = "#{d}/sock"
|
||||||
serv = Socket.unix_server_socket(sockpath)
|
serv = Socket.unix_server_socket(sockpath)
|
||||||
@ -324,10 +326,33 @@ class TestUNIXSocket < Test::Unit::TestCase
|
|||||||
c.print "a"
|
c.print "a"
|
||||||
msg, cliend_ai, rflags, cred = s.recvmsg
|
msg, cliend_ai, rflags, cred = s.recvmsg
|
||||||
assert_equal("a", msg)
|
assert_equal("a", msg)
|
||||||
assert_match(/ uid=#{Process.uid} /, cred.inspect)
|
inspect = cred.inspect
|
||||||
assert_match(/ euid=#{Process.euid} /, cred.inspect)
|
p inspect
|
||||||
assert_match(/ gid=#{Process.gid} /, cred.inspect)
|
assert_match(/ uid=#{Process.uid} /, inspect)
|
||||||
assert_match(/ egid=#{Process.egid} /, cred.inspect)
|
assert_match(/ euid=#{Process.euid} /, inspect)
|
||||||
|
assert_match(/ gid=#{Process.gid} /, inspect)
|
||||||
|
assert_match(/ egid=#{Process.egid} /, inspect)
|
||||||
|
assert_match(/ \(sockcred\)/, inspect)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_cred_cmsgcred
|
||||||
|
return if /freebsd/ !~ RUBY_PLATFORM
|
||||||
|
Dir.mktmpdir {|d|
|
||||||
|
sockpath = "#{d}/sock"
|
||||||
|
serv = Socket.unix_server_socket(sockpath)
|
||||||
|
c = Socket.unix(sockpath)
|
||||||
|
s, = serv.accept
|
||||||
|
c.sendmsg("a", 0, nil, [:SOCKET, Socket::SCM_CREDS, ""])
|
||||||
|
msg, cliend_ai, rflags, cred = s.recvmsg
|
||||||
|
assert_equal("a", msg)
|
||||||
|
inspect = cred.inspect
|
||||||
|
p inspect
|
||||||
|
assert_match(/ pid=#{$$} /, inspect)
|
||||||
|
assert_match(/ uid=#{Process.uid} /, inspect)
|
||||||
|
assert_match(/ euid=#{Process.euid} /, inspect)
|
||||||
|
assert_match(/ gid=#{Process.gid} /, inspect)
|
||||||
|
assert_match(/ \(cmsgcred\)/, inspect)
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user