Wallet::Server(3pm)

πŸ“¦ version 1.7, in debian trixie, ubuntu resolute, ubuntu stonking

Wallet::Server(3pm) πŸ’–βœ¨

okay bestie, so this is Wallet::Server β€” it's a Perl manpage, from the User Contributed Perl Documentation section of the manual, section 3pm (that's "library functions" for my besties keeping track). and like… it's the server implementation of the wallet system, which is a whole thing. let's get into it 🫢


✨ NAME ✨

Wallet::Server β€” the wallet system's server implementation, no cap πŸ’…


🌸 SYNOPSIS 🌸

use Wallet::Server;
my $server = Wallet::Server->new ($user, $host);
$server->create ('keytab', 'host/example.com@EXAMPLE.COM');

see? three lines. that's the whole vibe check right there πŸ¦‹


πŸŽ€ DESCRIPTION πŸŽ€

okay so Wallet::Server is the top-level class β€” like, the main character of the whole wallet server situation πŸ‘‘. the wallet is a system for storing, generating, and retrieving secure information, stuff like Kerberos keytabs. and the server is the one doing the work:

  • it maintains the metadata about the objects
  • it checks access against ACLs
  • it dispatches requests for objects to backend implementations for that object type

lowkey it's a whole traffic controller 🚦

so Wallet::Server is normally instantiated and used by wallet-backend, which is a thin wrapper around this object β€” it figures out the authenticated remote user, gets user input, and then calls the appropriate method of this object. so like, wallet-backend is the front desk and Wallet::Server is the person actually doing stuff πŸ’

to use this object, several configuration variables must be set β€” at minimum the database configuration. for info on those variables and how to set them, go see Wallet::Config.


πŸ‘‘ CLASS METHODS πŸ‘‘

new(PRINCIPAL, HOSTNAME)

creates a new wallet server object, for actions coming from the user PRINCIPAL connecting from HOSTNAME. both PRINCIPAL and HOSTNAME get used for logging history information for all subsequent operations, so they matter fr fr.

new() opens the database β€” using the database configuration as set by Wallet::Config β€” and makes sure that the "ADMIN" ACL exists. that ACL is the one used to authorize privileged operations πŸ‘‘

on any error, this method throws an exception. not a vibe, but it's what happens. πŸ’€

πŸ’… INSTANCE METHODS πŸ’…

heads up bestie: for all methods that can fail, the caller should call error() after a failure to get the error message. that's the move, always. πŸ™ˆ


acl(TYPE, NAME, ACL [, ID])

gets or sets the ACL type ACL to ID for the object identified by TYPE and NAME.

ACL should be one of "get", "store", "show", "destroy", or "flags". πŸ’«

if ID is not given: returns the current setting of that ACL as the name of the ACL, or undef if that ACL isn't set, or undef on failure. to tell the difference between "ACL isn't set" and "we failed to retrieve the ACL", the caller should call error() after an undef return. if error() also returns undef, then that ACL wasn't set; otherwise, error() will return the error message. mystery solved πŸ”

if ID is given: sets the specified ACL to ID, which can be either the name of an ACL or a numeric ACL ID. to clear the ACL, pass in an empty string as the ID. and to set or clear an ACL, the current user must be authorized by the "ADMIN" ACL. returns true for success, false for failure.

ACL settings are checked before the owner and override the owner setting. periodt. πŸ’…

acl_add(ID, SCHEME, IDENTIFIER)

adds an ACL entry with scheme SCHEME and identifier IDENTIFIER to the ACL identified by ID.

ID may be either the ACL name or the numeric ACL ID. SCHEME must be a valid ACL scheme for which the wallet system has an ACL verifier implementation β€” so no making up schemes, bestie πŸ™ˆ

to add an entry to an ACL, the current user must be authorized by the "ADMIN" ACL. returns true for success, false for failure.


acl_create(NAME)

creates a new ACL with the specified NAME, which must not be all-numeric. the newly created ACL will be empty β€” a blank slate, a fresh start, main character energy ✨

to create an ACL, the current user must be authorized by the "ADMIN" ACL. returns true on success, false on failure.


acl_destroy(ID)

destroys the ACL identified by ID, which may be either the ACL name or its numeric ID.

this call will fail if the ACL is still referenced by any object. also the "ADMIN" ACL may not be destroyed. 🚫

to destroy an ACL, the current user must be authorized by the "ADMIN" ACL. returns true on success, false on failure.


acl_history(ID)

returns the history of the ACL identified by ID, which may be either the ACL name or its numeric ID. to see the history of an ACL, the current user must be authorized by the "ADMIN" ACL.

every change that modifies the ACL β€” not counting changes in the name of the ACL β€” gets represented by two lines:

  1. the first line has a timestamp of the change followed by a description of the change
  2. the second line gives the user who made the change and the host from which the change was made

returns undef on failure. 😭


acl_remove(ID, SCHEME, IDENTIFIER)

removes from the ACL identified by ID the entry matching SCHEME and IDENTIFIER. ID may be either the name of the ACL or its numeric ID.

the last entry in the "ADMIN" ACL cannot be removed. so don't even try it πŸ’€

to remove an entry from an ACL, the current user must be authorized by the "ADMIN" ACL. returns true on success, false on failure.


acl_rename(OLD, NEW)

renames the ACL identified by OLD to NEW.

this changes the human-readable name, not the underlying numeric ID β€” so the ACL's associations with objects will be unchanged. it's giving "glow up, same soul" πŸ¦‹

the "ADMIN" ACL may not be renamed. OLD may be either the current name or the numeric ID. NEW must not be all-numeric.

to rename an ACL, the current user must be authorized by the "ADMIN" ACL. returns true on success, false on failure.


acl_replace(OLD, NEW)

moves any object owned by the ACL identified by OLD to instead be owned by NEW.

this goes through all objects owned by OLD and individually changes the owner, along with history updates for each one. OLD and NEW may be either the name or the numeric ID.

to replace an ACL, the current user must be authorized by the "ADMIN" ACL. returns true on success, false on failure.


acl_show(ID)

returns a human-readable description, including membership, of the ACL identified by ID, which may be either the ACL name or its numeric ID.

to show an ACL, the current user must be authorized by the "ADMIN" ACL β€” although be aware that anyone with show access to an object can see the membership of ACLs associated with that object through the show() method. iykyk πŸ‘€

returns the human-readable description on success and undef on failure.


attr(TYPE, NAME, ATTRIBUTE [, VALUE ...])

sets or retrieves a given object attribute. attributes are used to store backend-specific information for a particular object type, and ATTRIBUTE must be an attribute type known to the underlying object implementation.

if VALUE is not given: returns the values of that attribute, if any, as a list. on error, returns the empty list. to distinguish between an error and an empty return, call error() afterward β€” it is guaranteed to return undef unless there was an error. to retrieve an attribute setting, the user must be authorized by the "ADMIN" ACL, the show ACL if set, or the owner ACL if the show ACL is not set.

if VALUE is given: sets the given ATTRIBUTE values to VALUE, which is one or more attribute values. pass the empty string as the only VALUE to clear the attribute values. returns true on success, false on failure. to set an attribute value, the user must be authorized by the "ADMIN" ACL, the store ACL if set, or the owner ACL if the store ACL is not set.


autocreate(TYPE, NAME)

creates a new object of type TYPE and name NAME. TYPE must be a recognized type for which the wallet system has a backend implementation. returns true on success, false on failure.

to create an object using this method, the current user must be authorized by the default owner as determined by the wallet configuration. for more info on how to map new objects to default owners, see Wallet::Config(3).

wallet administrators should use the create() method to create objects. just saying. πŸ’…

check(TYPE, NAME)

checks whether an object of type TYPE and name NAME exists. πŸ”

returns:

  • 1 if it does
  • 0 if it doesn't
  • undef if some error occurred while checking for the existence of the object

comment(TYPE, NAME, [COMMENT])

gets or sets the comment for the object identified by TYPE and NAME.

if COMMENT is not given: returns the current comment, or undef if no comment is set, or undef on an error. to distinguish between an expiration that isn't set and a failure to retrieve the expiration, the caller should call error() after an undef return. if error() also returns undef, no comment was set; otherwise, error() will return the error message. πŸ•΅οΈ

if COMMENT is given: sets the comment to COMMENT. pass in the empty string for COMMENT to clear the comment. to set a comment, the current user must be the object owner or be on the "ADMIN" ACL. returns true for success, false for failure.


create(TYPE, NAME)

creates a new object of type TYPE and name NAME. TYPE must be a recognized type for which the wallet system has a backend implementation. returns true on success, false on failure.

to create an object using this method, the current user must be authorized by the "ADMIN" ACL. use autocreate() to create objects based on the default owner as determined by the wallet configuration. pick your fighter πŸ₯Š


destroy(TYPE, NAME)

destroys the object identified by TYPE and NAME.

this is a whole big deal, bestie β€” here's everything it does:

  • it destroys any data that the wallet had saved about the object
  • it may remove the underlying object from other external systems
  • it destroys the wallet database entry for the object
⚠️ that's data gone forever. not a vibe check, a vibe end. πŸ’€

to destroy an object, the current user must be a member of the "ADMIN" ACL, authorized by the destroy ACL, or authorized by the owner ACL; however, if the destroy ACL is set, the owner ACL will not be checked.

returns true on success, false on failure.


dbh()

returns the database handle of a Wallet::Server object.

this is used mostly for testing; normally, clients should perform all actions through the Wallet::Server object to make sure that authorization and history logging is done properly. don't be sneaky, bestie πŸ™ˆ

error()

returns the error of the last failing operation, or undef if no operations have failed.

callers should call this function to get the error message after an undef return from any other instance method. it's the "what went wrong" hotline πŸ“ž


expires(TYPE, NAME [, EXPIRES])

gets or sets the expiration for the object identified by TYPE and NAME.

if EXPIRES is not given: returns the current expiration, or undef if no expiration is set, or undef on an error. to distinguish between an expiration that isn't set and a failure to retrieve the expiration, the caller should call error() after an undef return. if error() also returns undef, the expiration wasn't set; otherwise, error() will return the error message. ⏰

(and that's where part 1 wraps up β€” part 2 is right behind this one, keep reading bestie 🫢)

so if EXPIRES is given, it sets the expiration to EXPIRES. πŸ’– And EXPIRES has to be in the format "YYYY-MM-DD +HH:MM:SS", though ngl the time portion can just be omitted if you're not feeling it. Want to wipe the expiration date clean? Pass in the empty string for EXPIRES. 🫧 To set an expiration, the current user must be authorized by the ADMIN ACL. Returns true for success and false for failure. that's the whole vibe.


🚩 flag_clear(TYPE, NAME, FLAG) 🚩

Clears the flag FLAG on the object identified by TYPE and NAME. To clear a flag, the current user must be authorized by the ADMIN ACL or the flags ACL on the object. no cap, those are the only two ways in. πŸ’…

πŸŽ€ flag_set(TYPE, NAME, FLAG) πŸŽ€

Sets the flag FLAG on the object identified by TYPE and NAME. To set a flag, the current user must be authorized by the ADMIN ACL or the flags ACL on the object. same energy, opposite direction bestie. ✨

πŸ“ get(TYPE, NAME) πŸ“

Returns the data associated with the object identified by TYPE and NAME. Depending on the object TYPE, this may generate new data and invalidate any existing data, or it may return data previously stored or generated. Heads up: this data may be binary and may contain nul characters, so don't go treating it like a cute little text string. 😭 To get an object, the current user must either be authorized by the owner ACL or authorized by the get ACL β€” however, if the get ACL is set, the owner ACL will not be checked. And being a member of the ADMIN ACL does not provide any special privileges to get objects. sorry to the admins, that's just how it is. πŸ’€

Returns undef on failure. The caller should be careful to distinguish between undef and the empty string, which is valid object data. like. the empty string is real data. undef is a whole different thing. don't mix them up bestie. πŸ™ˆ

πŸ“œ history(TYPE, NAME) πŸ“œ

Returns (as a string) the human-readable history of the object identified by TYPE and NAME, or undef on error. To see the object history, the current user must be a member of the ADMIN ACL, authorized by the show ACL, or authorized by the owner ACL β€” however, if the show ACL is set, the owner ACL will not be checked. okay so that "however" is doing a lot of work, stay woke. πŸ‘‘

πŸ‘‘ owner(TYPE, NAME [, OWNER]) πŸ‘‘

Gets or sets the owner for the object identified by TYPE and NAME.

If OWNER is not given, returns the current owner as the name of the ACL, or undef if no owner is set or on an error. πŸ˜΅β€πŸ’« To distinguish between an owner that isn't set and a failure to retrieve the owner, the caller should call error() after an undef return. If error() also returns undef, that ACL wasn't set; otherwise, error() will return the error message. so like, two undefs = nobody's home, one undef + an error message = something went wrong. ✨

If OWNER is given, sets the owner to OWNER, which may be either the name of an ACL or a numeric ACL ID. To set an owner, the current user must be authorized by the ADMIN ACL. Returns true for success and false for failure.

The owner of an object is permitted to get, store, and show that object, but cannot destroy or set flags on that object without being listed on those ACLs as well. like, owner privileges are cute but they are not unlimited bestie. 🫢

🧚 schema() 🧚

Returns the DBIx::Class schema object. that's it. that's the whole method. iconic. πŸ’–

🌈 show(TYPE, NAME) 🌈

Returns (as a string) a human-readable representation of the metadata stored for the object identified by TYPE and NAME, or undef on error. Included is the metadata and entries of any ACLs associated with the object. To show an object, the current user must be a member of the ADMIN ACL, authorized by the show ACL, or authorized by the owner ACL β€” however, if the show ACL is set, the owner ACL will not be checked. yes this is the exact same little clause as history, it's giving consistency. πŸ’…

πŸ’Ύ store(TYPE, NAME, DATA) πŸ’Ύ

Stores DATA for the object identified with TYPE and NAME for later retrieval with get. Not all object types support this. πŸ‘€ Note that DATA may be binary and may contain nul characters. To store an object, the current user must either be authorized by the owner ACL or authorized by the store ACL β€” however, if the store ACL is set, the owner ACL is not checked. And being a member of the ADMIN ACL does not provide any special privileges to store objects. Returns true on success and false on failure. periodt. ✨


πŸ” SEE ALSO πŸ”

This module is part of the wallet system. The current version is available from <https://www.eyrie.org/~eagle/software/wallet/>. 🌐 go peek, it's right there.


πŸ’œ AUTHORS πŸ’œ

  • Russ Allbery <eagle@eyrie.org>
  • Bill MacAllister <bill@ca-zephyr.org>

and that's a wrap on the whole page bestie!! πŸŽ€ this one shipped as perl v5.40.0 back on 2024-11-12, and the manpage itself is Wallet::Server(3pm). go forth and ACL responsibly. πŸ¦‹πŸ’–βœ¨

πŸ“¦ where this page comes from