summaryrefslogtreecommitdiff
path: root/ruby
diff options
context:
space:
mode:
authorRuss Allbery <rra@stanford.edu>2011-09-26 17:28:59 -0700
committerRuss Allbery <rra@stanford.edu>2011-09-26 17:28:59 -0700
commit00677072c1f512ae058a7031cab164a5518e0bd0 (patch)
treeda41280b745f626c786abb001e597e9962fa69bc /ruby
parentd27cab3132eef0f614efbe7208cab265cf8e281d (diff)
Add ccache class variable to the Ruby bindings
Diffstat (limited to 'ruby')
-rw-r--r--ruby/README9
-rw-r--r--ruby/remctl.c49
-rw-r--r--ruby/test_remctl.rb.in16
3 files changed, 71 insertions, 3 deletions
diff --git a/ruby/README b/ruby/README
index 95f3b78..2271048 100644
--- a/ruby/README
+++ b/ruby/README
@@ -99,6 +99,15 @@ FULL INTERFACE
not given, the library default (host/<host> with the realm
determined by the domain-realm mapping) is used.
+ To override the credential cache used by GSS-API, assign the
+ credential cache (as a string) to Remctl.ccache before calling
+ Remctl.new. Be aware that this will usually change the default
+ credential cache for all uses of GSS-API in the same process,
+ including other remctl objects, rather than just this remctl object
+ due to a limitation in the GSS-API. Some GSS-API implementations do
+ not support setting the credential cache, in which case Remctl.new
+ will throw a Remctl::Error exception if this variable is set.
+
Normally, the source IP used to connect to the server is assigned by
the kernel. To use a specific source IP, assign that IP address (as
a string) to Remctl.source_ip before calling Remctl.new.
diff --git a/ruby/remctl.c b/ruby/remctl.c
index f6a3f6d..8ec587a 100644
--- a/ruby/remctl.c
+++ b/ruby/remctl.c
@@ -61,7 +61,7 @@ void Init_remctl(void);
static VALUE cRemctl, cRemctlResult, eRemctlError, eRemctlNotOpen;
/* Since we can't have @ in our names here... */
-static ID AAdefault_port, AAdefault_principal, AAsource_ip;
+static ID AAdefault_port, AAdefault_principal, AAccache, AAsource_ip;
static ID Ahost, Aport, Aprincipal;
/* Map the remctl_output type constants to strings. */
@@ -233,6 +233,39 @@ rb_remctl_default_principal_set(VALUE self UNUSED, VALUE new)
/* call-seq:
+ * Remctl.ccache -> nil
+ *
+ * Return the last set credential cache location for new remctl connections.
+ * This will only return values set through the remctl library, not query
+ * GSS-API for its underlying setting.
+ */
+static VALUE
+rb_remctl_ccache_get(VALUE self UNUSED)
+{
+ return rb_cvar_get(cRemctl, AAccache);
+}
+
+
+/* call-seq:
+ * Remctl.ccahe = '/path/to/some/file' -> 0
+ *
+ * Change the credential cache used for new remctl connections. This will
+ * also, with most GSS-API implementations, affect all other GSS-API
+ * connections in the same process, including other remctl objects, once the
+ * value is used during open.
+ */
+static VALUE
+rb_remctl_ccache_set(VALUE self UNUSED, VALUE new)
+{
+ if (NIL_P(new))
+ rb_cvar_set(cRemctl, AAccache, Qnil);
+ else
+ rb_cvar_set(cRemctl, AAccache, StringValue(new));
+ return rb_cvar_get(cRemctl, AAccache);
+}
+
+
+/* call-seq:
* Remctl.source_ip -> nil
*
* Return the default source IP used for a Remctl complex connection. A value
@@ -315,7 +348,7 @@ static VALUE
rb_remctl_reopen(VALUE self)
{
struct remctl *r;
- VALUE vhost, vport, vprinc, vdefsource;
+ VALUE vhost, vport, vprinc, vdefccache, vdefsource;
char *host, *princ;
unsigned int port;
@@ -326,6 +359,12 @@ rb_remctl_reopen(VALUE self)
if (r == NULL)
rb_raise(rb_eNoMemError, "remctl");
+ /* Set the credential cache if needed. */
+ vdefccache = rb_cvar_get(cRemctl, AAccache);
+ if (!NIL_P(vdefccache))
+ if (!remctl_set_ccache(r, StringValuePtr(vdefccache)))
+ rb_raise(eRemctlError, "%s", remctl_error(r));
+
/* Set the source IP if needed. */
vdefsource = rb_cvar_get(cRemctl, AAsource_ip);
if (!NIL_P(vdefsource))
@@ -476,6 +515,7 @@ Init_remctl(void)
*/
AAdefault_port = rb_intern("@@default_port");
AAdefault_principal = rb_intern("@@default_principal");
+ AAccache = rb_intern("@@ccache");
AAsource_ip = rb_intern("@@source_ip");
Ahost = rb_intern("@host");
Aport = rb_intern("@port");
@@ -484,6 +524,7 @@ Init_remctl(void)
/* Default values for class variables. */
rb_cvar_set(cRemctl, AAdefault_port, UINT2NUM(0));
rb_cvar_set(cRemctl, AAdefault_principal, Qnil);
+ rb_cvar_set(cRemctl, AAccache, Qnil);
rb_cvar_set(cRemctl, AAsource_ip, Qnil);
/* Getter and setter methods for class variables. */
@@ -495,6 +536,10 @@ Init_remctl(void)
rb_remctl_default_principal_get, 0);
rb_define_singleton_method(cRemctl, "default_principal=",
rb_remctl_default_principal_set, 1);
+ rb_define_singleton_method(cRemctl, "ccache",
+ rb_remctl_ccache_get, 0);
+ rb_define_singleton_method(cRemctl, "ccache=",
+ rb_remctl_ccache_set, 1);
rb_define_singleton_method(cRemctl, "source_ip",
rb_remctl_source_ip_get, 0);
rb_define_singleton_method(cRemctl, "source_ip=",
diff --git a/ruby/test_remctl.rb.in b/ruby/test_remctl.rb.in
index 497113e..6c37e3b 100644
--- a/ruby/test_remctl.rb.in
+++ b/ruby/test_remctl.rb.in
@@ -186,6 +186,20 @@ class TC_RemctlFull < Test::Unit::TestCase
assert_equal(output[4], 5)
end
+ def test_full_ccache
+ unless configured? then return end
+ ENV['KRB5CCNAME'] = 'nonexistent-file'
+ assert_raise Remctl::Error do
+ Remctl.new('127.0.0.1', 14373, @principal)
+ end
+ Remctl.ccache = 'data/test.cache'
+ begin
+ Remctl.new('127.0.0.1', 14373, @principal)
+ rescue Remctl::Error
+ assert_equal('setting credential cache not supported', $!.to_s)
+ end
+ end
+
def test_full_source_ip
unless configured? then return end
Remctl.source_ip = '127.0.0.1'
@@ -193,7 +207,7 @@ class TC_RemctlFull < Test::Unit::TestCase
r.close
Remctl.source_ip = '::1'
assert_raise Remctl::Error do
- Remctl.new('127.0.0.1', 14374, @principal)
+ Remctl.new('127.0.0.1', 14373, @principal)
end
Remctl.source_ip = nil
end