offering limited pop access

Andreas Winkelmann ml at awinkelmann.de
Thu Oct 30 15:28:21 EDT 2008


Am Donnerstag 30 Oktober 2008 18:51:23 schrieb Wesley Craig:

> On 30 Oct 2008, at 12:54, Andreas Winkelmann wrote:
> > Service-Name itself is the given name of the Daemon from
> > cyrus.conf. It is not
> > the service Name from Cyrus-SASL. Separating Options between the
> > Daemons is
> > not a Cyrus-SASL Feature it is a Cyrus-IMAP Feature. You can use it
> > for other
> > Options than Cyrus-SASL Options in imapd.conf, too.
>
> I notice that pop3d.c doesn't seem to use the sasl_service from
> pop3_protocol.  Instead, it appears to be hard coded in imap/pop3d.c
> service_main() around line 510:
>
>      if (sasl_server_new("pop", config_servername, NULL, NULL, NULL,
>                          NULL, 0, &popd_saslconn) != SASL_OK)

This is the Cyrus-SASL Service Name. But not related to the Service Name which 
prepends to the Options in imapd.conf. 

The Cyrus SASL Service Name is hard-coded. In case of pop3 it is "pop".

> I believe that first argument is the one that's passed to the
> callbacks below as plugin_name.  I could be wrong, I haven't tested
> this at all, I've only been looking over the code, in order to answer
> the earlier question of "how could I know about this hard to find
> option".

In case of the "plugin_name" you are looking at a Call Back which is called 
every time, the Cyrus-SASL Library tries to resolve an option. For common 
Cyrus-SASL Options like pwcheck_method, mech_list, saslauthd_path, ... 
plugin_name is NULL. 

> Again, looking at the code, I see two places when the config option
> is not constant, i.e., it's built from components.  The first is in
> imap/global.c:
>
> /* this is a wrapper to call the cyrus configuration from SASL */
> int mysasl_config(void *context __attribute__((unused)),
>                    const char *plugin_name,
>                    const char *option,
>                    const char **result,
>                    unsigned *len)
> {
> ...
>          if (plugin_name) {
>              /* first try it with the plugin name */
>              strlcpy(opt, "sasl_", sizeof(opt));
>              strlcat(opt, plugin_name, sizeof(opt));
>              strlcat(opt, "_", sizeof(opt));
>              strlcat(opt, option, sizeof(opt));
>              *result = config_getoverflowstring(opt, NULL);
>          }
>
>          if (*result == NULL) {
>              /* try without the plugin name */
>              strlcpy(opt, "sasl_", sizeof(opt));
>              strlcat(opt, option, sizeof(opt));
>              *result = config_getoverflowstring(opt, NULL);
>          }
> ...

Because plugin_name is NULL in most cases, the interesting part here is 
config_getoverflowstring()@lib/libconfig.c:

const char *config_getoverflowstring(const char *key, const char *def)
{
    char buf[256];
    char *ret = NULL;

    /* First lookup <ident>_key, to see if we have a service-specific
     * override */

    if(config_ident) {
        if(snprintf(buf,sizeof(buf),"%s_%s",config_ident,key) == -1)
            fatal("key too long in config_getoverflowstring", EC_TEMPFAIL);

        ret = hash_lookup(buf, &confighash);
    }

    /* No service-specific override, check the actual key */
    if(!ret)
        ret = hash_lookup(key, &confighash);

    /* Return what we got or the default */
    return ret ? ret : def;
}

config_ident is filled from master with the first column from cyrus.conf of 
the assoiciated Service. So in the case of pop3 Cyrus-IMAP tries first to 
lookup the Option with "pop3_sasl_..."

> The sasl_<someoption> seems to be pretty well described in the man
> page for imapd.conf.  The method with the plugin_name
> (sasl_<plugin_name>_<someoption>) wasn't in the documentation that I
> could find.  

A few examples for plugin_name "SQL", "ldapdb", "DIGEST-MD5", "GSSAPI", "SRP", 
NULL. The environment of the related option from Cyrus-SASL specifies the 
plugin_name. All ldapdb_ Options have "ldapdb", "sql_*" "SQL" and so on...

> The second place is in imap/backend.c:
>
> static int backend_authenticate(struct backend *s, struct protocol_t
> *prot,
>                                  char **mechlist, const char *userid,
>                                  sasl_callback_t *cb, const char
> **status)
> {
> ...
>          strlcpy(optstr, s->hostname, sizeof(optstr));
>          p = strchr(optstr, '.');
>          if (p) *p = '\0';
>          strlcat(optstr, "_password", sizeof(optstr));
>          pass = config_getoverflowstring(optstr, NULL);
>          if(!pass) pass = config_getstring(IMAPOPT_PROXY_PASSWORD);
> ...
>      /* Get SASL mechanism list.  We can force a particular
>         mechanism using a <shorthost>_mechs option */
>      strcpy(buf, s->hostname);
>      p = strchr(buf, '.');
>      if (p) *p = '\0';
>      strcat(buf, "_mechs");
>      mech_conf = config_getoverflowstring(buf, NULL);
> ...
>
> Using <hostname>_mech and <hostname>_password both seem to be pretty
> well documented, tho there was a discussion two weeks ago that the
> short hostname is not well defined and that perhaps the configured
> hostname should also be tried.

--
Andreas


More information about the Info-cyrus mailing list