]> eyrie.org Git - kerberos/perl-kerberos.git/commitdiff
Add has_attribute method call for ::Kadmin::Entry
authorRuss Allbery <rra@cpan.org>
Mon, 21 Apr 2014 23:08:23 +0000 (16:08 -0700)
committerRuss Allbery <rra@cpan.org>
Mon, 21 Apr 2014 23:08:23 +0000 (16:08 -0700)
This returns true if the entry has the given attribute, and false
otherwise.  Needed for fast checking of whether a given Kerberos
database entry is disabled.

lib/Authen/Kerberos/Kadmin.xs
lib/Authen/Kerberos/Kadmin/Entry.pm
t/kadmin/heimdal.t

index cdcb39dd8a20356d9b5e176c7423028ee356b8cd..0b4ca5bea71ac3ebe87fe675358dc83316d8e93b 100644 (file)
@@ -72,8 +72,8 @@ typedef struct {
  * are the Heimdal names, not the MIT Kerberos names (which are generally just
  * the constant names without the leading KRB5_KDB).
  */
-struct attribute_name {
-    int attribute;
+struct {
+    unsigned long attribute;
     const char *name;
 } attribute_names[] = {
     { KRB5_KDB_ALLOW_DIGEST,           "allow-digest"           },
@@ -117,6 +117,22 @@ handle_from_sv(SV *handle_sv, const char *type)
 }
 
 
+/*
+ * Given an attribute name, return the corresponding attribute code, or 0 if
+ * that attribute name is not recognized.
+ */
+static unsigned long
+attribute_name_to_code(const char *name)
+{
+    size_t i;
+
+    for (i = 0; attribute_names[i].attribute != 0; i++)
+        if (strcmp(name, attribute_names[i].name) == 0)
+            return attribute_names[i].attribute;
+    return 0;
+}
+
+
 /* XS code below this point. */
 
 MODULE = Authen::Kerberos::Kadmin       PACKAGE = Authen::Kerberos::Kadmin
@@ -424,6 +440,28 @@ attributes(self)
 }
 
 
+void
+has_attribute(self, attribute)
+    Authen::Kerberos::Kadmin::Entry self
+    const char *attribute
+  PREINIT:
+    unsigned long code;
+  PPCODE:
+{
+    CROAK_NULL_SELF(self, "Authen::Kerberos::Kadmin::Entry", "has_attribute");
+    if (attribute == NULL || attribute[0] == '\0')
+        croak("attribute is undefined or empty in"
+              " Authen::Kerberos::Kadmin::Entry::has_attribute");
+    code = attribute_name_to_code(attribute);
+    if (code == 0)
+        croak("unknown Kerberos entry attribute %s", attribute);
+    if (self->ent->attributes & code)
+        XSRETURN_YES;
+    else
+        XSRETURN_UNDEF;
+}
+
+
 krb5_timestamp
 last_password_change(self)
     Authen::Kerberos::Kadmin::Entry self
index 320f8b57b5c54ac8bb271be4627cc64b0585c791..99e29a9dcbfa8d94e9178df16641e14aaecfa81b 100644 (file)
@@ -210,6 +210,12 @@ Not used, but included for completeness since the flags are defined.
 
 =back
 
+=item has_attribute(ATTRIBUTE)
+
+Returns true if this database entry has that attribute set, false
+otherwise.  ATTRIBUTE should be a string chosen from the list of valid
+attributes as documented under the attributes() method.
+
 =item last_password_change()
 
 Returns the last password change time for this database entry in seconds
@@ -220,9 +226,10 @@ available.
 
 Returns the password expiration time for this database entry in seconds
 since UNIX epoch, or C<0> if this principal does not have a password
-expiration set.  If the TIME argument is given, sets the password
-expiration time to TIME, which is in the same format, and returns the
-value that was set.
+expiration set.
+
+If the TIME argument is given, sets the password expiration time to TIME,
+which is in the same format, and returns the value that was set.
 
 =back
 
index 07e93996712e87a31f87af645a938a4b41eb2799..5acd585c914fd862d028c470bc66ac970365f535 100755 (executable)
@@ -31,7 +31,7 @@ use warnings;
 
 use File::Copy qw(copy);
 
-use Test::More tests => 22;
+use Test::More tests => 28;
 
 BEGIN {
     use_ok('Authen::Kerberos::Kadmin');
@@ -95,6 +95,21 @@ my @attributes = $entry->attributes;
 is_deeply(\@attributes, \@wanted, 'kadmin/changepw has correct attributes');
 is($entry->attributes, join(q{, }, @attributes), '...and in scalar context');
 
+# Check has_attribute for known attributes.
+is($entry->has_attribute('disallow-postdated'), 1, 'Has disallow-postdated');
+is($entry->has_attribute('disallow-all-tix'),
+    undef, 'Does not have disallow-all-tix');
+
+# Check behavior for invalid has_attribute calls.
+ok(!eval { $entry->has_attribute(q{}) }, 'has_attribute("") fails');
+like($@, qr{ \A attribute [ ] is [ ] undefined }xms, '...with correct error');
+ok(!eval { $entry->has_attribute('foo') }, 'has_attribute("foo") fails');
+like(
+    $@,
+    qr{ \A unknown [ ] Kerberos [ ] entry [ ] attribute [ ] foo }xms,
+    '...with correct error'
+);
+
 # Test password change.  At the moment, we don't check whether the password
 # change is performed in the database.  We'll do that later.
 ok(eval { $kadmin->chpass('test@TEST.EXAMPLE.COM', 'some password') },