* 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>
|
||||
|
||||
* 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;
|
||||
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_cat2(ret, " (ucred)");
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
@ -393,38 +394,71 @@ anc_inspect_passcred_credentials(int level, int type, VALUE data, VALUE ret)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(SCM_CREDS) && defined(HAVE_TYPE_STRUCT_SOCKCRED) /* NetBSD */
|
||||
#if defined(SCM_CREDS)
|
||||
#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) {
|
||||
if (level != SOL_SOCKET && type != SCM_CREDS)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* FreeBSD has struct cmsgcred and struct sockcred.
|
||||
* They use both SOL_SOCKET/SCM_CREDS in the ancillary message.
|
||||
* They are not ambiguous from the view of the caller
|
||||
* because struct sockcred is sent if and only if the caller sets LOCAL_CREDS socket option.
|
||||
* But inspect method doesn't know it.
|
||||
* So they are ambiguous from the view of inspect.
|
||||
* This function distinguish them by the size of the ancillary message.
|
||||
* This heuristics works well except when sc_ngroups == CMGROUP_MAX.
|
||||
*/
|
||||
|
||||
#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 = "=";
|
||||
rb_str_cat2(ret, " groups");
|
||||
for (i = 0; i < cred0.sc_ngroups; i++) {
|
||||
rb_str_catf(ret, "%s%u", sep, cred->sc_groups[i]);
|
||||
for (i = 0; i < cred.cmcred_ngroups; i++) {
|
||||
rb_str_catf(ret, "%s%u", sep, cred.cmcred_groups[i]);
|
||||
sep = ",";
|
||||
}
|
||||
}
|
||||
rb_str_cat2(ret, " (cmsgcred)");
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
#endif
|
||||
#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
|
||||
|
||||
|
@ -309,6 +309,7 @@ have_type("struct in6_pktinfo", headers) {|src|
|
||||
}
|
||||
|
||||
have_type("struct sockcred", headers)
|
||||
have_type("struct cmsgcred", headers)
|
||||
|
||||
$distcleanfiles << "constants.h" << "constdefs.*"
|
||||
|
||||
|
@ -296,7 +296,7 @@ class TestUNIXSocket < Test::Unit::TestCase
|
||||
}
|
||||
end
|
||||
|
||||
def test_cred_linux
|
||||
def test_cred_ucred
|
||||
return if /linux/ !~ RUBY_PLATFORM
|
||||
Dir.mktmpdir {|d|
|
||||
sockpath = "#{d}/sock"
|
||||
@ -306,15 +306,17 @@ class TestUNIXSocket < Test::Unit::TestCase
|
||||
s.setsockopt(:SOCKET, :PASSCRED, 1)
|
||||
c.print "a"
|
||||
msg, cliend_ai, rflags, cred = s.recvmsg
|
||||
inspect = cred.inspect
|
||||
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=#{$$} /, inspect)
|
||||
assert_match(/ uid=#{Process.uid} /, inspect)
|
||||
assert_match(/ gid=#{Process.gid}>/, inspect)
|
||||
assert_match(/ \(ucred\)/, inspect)
|
||||
}
|
||||
end
|
||||
|
||||
def test_cred_netbsd
|
||||
return if /netbsd/ !~ RUBY_PLATFORM
|
||||
def test_cred_sockcred
|
||||
return if /netbsd|freebsd/ !~ RUBY_PLATFORM
|
||||
Dir.mktmpdir {|d|
|
||||
sockpath = "#{d}/sock"
|
||||
serv = Socket.unix_server_socket(sockpath)
|
||||
@ -324,10 +326,33 @@ class TestUNIXSocket < Test::Unit::TestCase
|
||||
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)
|
||||
inspect = cred.inspect
|
||||
p inspect
|
||||
assert_match(/ uid=#{Process.uid} /, 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
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user