As I mentionned in my last post, part of the backend-agnostic maps was commited to OpenBSD's tree but they are now fully working and I moved things forward a bit to improve reliability.
Prior to that commit, maps were not really handled in a sane way. We'd store structs in aliases db and plaintext in secrets db, makemap being in charge of deciding what gets written and how based on a getopt flag. Each time we made a change to struct alias or to any of the struct it had as a member, the aliases db had to be rebuilt. On smtpd's side, the fact that we stored struct was not really helping as we still had to perform sanity checks which eventually cost as much as parsing the original alias entry into a struct alias.
Jacek and I discussed a while ago about a feature we wanted to have, where the map API would be aware of some data types we used through smtpd. For instance, since the aliases feature uses a struct alias, we should be able to have the map API return it instead of returning a string that the aliases API would parse. The code could then work with known structures and it would avoid bugs spreading in various places.
I came up with an idea that each "feature" would provide a simple parse function to turn a plaintext value into a struct for that feature. For example, autenticated relaying support provide a map_parse_credentials() function which parses a plaintext input of the form "user:password" into a struct map_credentials containing two members, one storing the username, the other storing the password. Since all backends store a plaintext representation, the parser will work no matter what backend is used. If a particular feature needs the raw value, it simply needs to mention it does not have a parser and things will work out of the box.
Prior to this, to retrieve credentials, the lka process had to call map_lookup(), retrieve the value, check if it was not NULL, check if value was correctly formed, fill a struct with it. Aliases was even worse since a value can in fact contain many values and each one can be parsed differently. Now, one can simply:
struct map_credentials *creds = map_lookup(env, map, "gmail.com", K_CREDENTIALS);
if (creds == NULL) {
// no credentials
}
else {
// creds->username and creds->password are guaranteed to be correct
free(creds);
}
same applies for aliases/virtual (or soon at least since i'm mostly done) and any feature requiring maps lookup.
Hopefully this can go in soon as it will help me cleanup the aliases resolution code path for good