title: Using EXTERNAL mechanism with Cyrus SASL
body: <p>Does the Cyrus SASL api not support the EXTERNAL mechanism?  I'm trying to 
  use it as a client, but it returns <code>SASL_NOMECH</code> when asked.</p>
  
  <pre><code>% cat cyrus_sal_ex.c
  /* cyrus_sasl_ex.c: Example of using the Cyrus SASL api */
  #include &lt;stdio.h&gt;      /* for printf() */
  #include &lt;sasl/sasl.h&gt;  /* for sasl_client_*(), SASL_*, sasl_*_t */
  
  static char const * SASL_return_code(int const code) 
  {
    switch(code) 
    {
      /* ... */
      case SASL_OK:     return "SASL_OK[0]: successful result";
      /* ... */
      case SASL_NOMECH: return "SASL_NOMECH[-4]: mechanism not supported";
      /* ... */
    }
    return "unrecognized";
  }
  
  int main()
  {
    char const *  output = NULL;
    unsigned      outlen = 0;
    char const *  mechanism = NULL;
    sasl_conn_t * conn;
  
  # define PRINT_RESULT( x ) do\
    {\
      int const __result = (x);\
      printf("%s == %d\n\t%s\n", #x, __result, SASL_return_code(__result));\
      if (__result &lt; 0) goto done;\
    }\
    while (0)
  
    PRINT_RESULT( sasl_client_init( NULL ) );
    PRINT_RESULT( sasl_client_new( "fake", "fakey.mcfaker.ton", "127.0.0.1", "127.255.255.1", NULL, 0, &amp;conn) );
    PRINT_RESULT( sasl_client_start( conn, "EXTERNAL", NULL, &amp;output, &amp;outlen, &amp;mechanism) );
  
  done:
  # undef PRINT_RESULT
    printf("output: [%d bytes] : %s\n", outlen, (output ? output : "NULL") );
    printf("mechanism: %s\n", (mechanism ? mechanism : "NULL"));
  
    return 0;
  }
  % gcc -I/sw/include -L/sw/lib -lsasl2 cyrus_sasl_ex.c -o cyrus_sasl_ex # your header/library locations may vary
  % ./cyrus_sasl_ex
  sasl_client_init( NULL ) == 0
          SASL_OK[0]: successful result
  sasl_client_new( "fake", "fakey.mcfaker.ton", "127.0.0.1", "127.255.255.1", NULL, 0, &amp;conn) == 0
          SASL_OK[0]: successful result
  sasl_client_start( conn, "EXTERNAL", NULL, &amp;output, &amp;outlen, &amp;mechanism) == -4
          SASL_NOMECH[-4]: mechanism not supported
  output: [0 bytes] : NULL
  mechanism: EXTERNAL
  %
  </code></pre>
  
  <p>I browsed through the <a href="http://asg.web.cmu.edu/sasl/sasl-library.html" rel="nofollow noreferrer">source</a> though, and it looks like all the clients should support the EXTERNAL mechanism:</p>
  
  <pre><code>cyrus-sasl-2.1.22/lib/client.c:
  196 int sasl_client_init(const sasl_callback_t *callbacks)
  197 {
  ...
  227
  228   sasl_client_add_plugin("EXTERNAL", &amp;external_client_plug_init);
  229
  </code></pre>
  
  <p>So I'm guessing I'm doing something wrong here.  I tried adding all the <code>sasl_callback_t</code>s I could think of to <code>sasl_client_*()</code>, but 
  none of them even got called.  Is there some argument I should pass that asserts that EXTERNAL is an acceptable mechanism?
  Or is SASL_NOMECH always returned for EXTERNAL - b/c that doesn't seem right.</p>
  
  <p>Can anyone help me out?</p>