]> eyrie.org Git - kerberos/perl-kerberos.git/commitdiff
Store an Authen::Kerberos object in the ::Kadmin object
authorRuss Allbery <rra@cpan.org>
Wed, 16 Apr 2014 05:34:36 +0000 (22:34 -0700)
committerRuss Allbery <rra@cpan.org>
Wed, 16 Apr 2014 05:34:36 +0000 (22:34 -0700)
Instead of storing a bare krb5_context object, store a wrapped
Authen::Kerberos object in the Authen::Kerberos::Kadmin object.
This will allow us to return other Authen::Kerberos::* objects
from Authen::Kerberos::Kadmin methods, with an underlying
Authen::Kerberos object to keep them alive.  It will also make it
easier later to allow the caller to provide an Authen::Kerberos
context.

lib/Authen/Kerberos/Kadmin.pm
lib/Authen/Kerberos/Kadmin.xs

index 79594e127e5ad4ec57f52cee935fed01f2bf565e..0e10b8b5e20b65f4f8b5550337135ea25ca2abec 100644 (file)
@@ -40,6 +40,7 @@ use warnings;
 
 use base qw(DynaLoader);
 
+use Authen::Kerberos;
 use Authen::Kerberos::Exception;
 use Exporter qw(import);
 
index 32dcb92340e996c603acd1382c4490f04e8ca286..d351916f276fea340f394869f31a24b18b777d52 100644 (file)
 #include <kadm5/admin.h>
 #include <kadm5/kadm5_err.h>
 
+#include <util/util.h>
+
 /*
  * Define a struct that wraps the kadmin API handle so that we can include
  * some other data structures and configuration parameters that we need to
- * use.
+ * use.  Stores the corresponding Kerberos context as an Authen::Kerberos
+ * object.
  */
 typedef struct {
     void *handle;
-    krb5_context ctx;
+    SV *ctx;
     bool quality;
 } *Authen__Kerberos__Kadmin;
 
@@ -142,7 +145,7 @@ new(class, args)
         krb5_free_context(ctx);
         croak("cannot allocate memory");
     }
-    self->ctx = ctx;
+    self->ctx = sv_setref_pv(newSV(0), "Authen::Kerberos", ctx);
     self->handle = handle;
     self->quality = quality;
     RETVAL = self;
@@ -159,7 +162,7 @@ DESTROY(self)
     if (self == NULL)
         return;
     kadm5_destroy(self->handle);
-    krb5_free_context(self->ctx);
+    SvREFCNT_dec(self->ctx);
     free(self);
 }
 
@@ -170,15 +173,17 @@ chpass(self, principal, password)
     const char *principal
     const char *password
   PREINIT:
+    krb5_context ctx;
     krb5_error_code code;
     krb5_principal princ = NULL;
     krb5_data pwd_data;
     const char *reason;
   CODE:
 {
-    code = krb5_parse_name(self->ctx, principal, &princ);
+    ctx = krb5_context_from_sv(SvRV(self->ctx), "Authen::Kerberos::Kadmin");
+    code = krb5_parse_name(ctx, principal, &princ);
     if (code != 0)
-        krb5_croak(self->ctx, code, "krb5_parse_name", FALSE);
+        krb5_croak(ctx, code, "krb5_parse_name", FALSE);
 
     /*
      * If configured to do quality checking, we need to do that manually,
@@ -187,18 +192,18 @@ chpass(self, principal, password)
     if (self->quality) {
         pwd_data.data = (char *) password;
         pwd_data.length = strlen(password);
-        reason = kadm5_check_password_quality(self->ctx, princ, &pwd_data);
+        reason = kadm5_check_password_quality(ctx, princ, &pwd_data);
         if (reason != NULL) {
-            krb5_set_error_message(self->ctx, KADM5_PASS_Q_DICT, "%s", reason);
-            krb5_croak(self->ctx, KADM5_PASS_Q_DICT,
-                         "kadm5_check_password_quality", FALSE);
+            krb5_set_error_message(ctx, KADM5_PASS_Q_DICT, "%s", reason);
+            krb5_croak(ctx, KADM5_PASS_Q_DICT, "kadm5_check_password_quality",
+                       FALSE);
         }
     }
 
     /* Do the actual password change. */
     code = kadm5_chpass_principal(self->handle, princ, password);
-    krb5_free_principal(self->ctx, princ);
+    krb5_free_principal(ctx, princ);
     if (code != 0)
-        krb5_croak(self->ctx, code, "kadm5_chpass_principal", FALSE);
+        krb5_croak(ctx, code, "kadm5_chpass_principal", FALSE);
     XSRETURN_YES;
 }