* 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" },
}
+/*
+ * 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
}
+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
=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
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
use File::Copy qw(copy);
-use Test::More tests => 22;
+use Test::More tests => 28;
BEGIN {
use_ok('Authen::Kerberos::Kadmin');
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') },