title: Authentify a user through a C++ program with ldap or pam
body: <p>My program has to authenticate people, the current machine on which it is running identify users through an ldap server.</p>
  
  <p>I had succesfully tested this code on a simple computer :</p>
  
  <pre><code>#include &lt;stdlib.h&gt;
  #include &lt;iostream&gt;
  #include &lt;fstream&gt;
  #include &lt;security/pam_appl.h&gt;
  #include &lt;unistd.h&gt;
  
  // To build this:
  // g++ pam.cc -lpam -o test
  
  struct pam_response *reply;
  
  //function used to get user input
  int function_conversation(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr)
  {
      *resp = reply;
      return PAM_SUCCESS;
  }
  
  int main(int argc, char** argv)
  {
      if(argc != 2) {
          fprintf(stderr, "Usage: check_user &lt;username&gt;\n");
          exit(1);
      }
      const char *username;
      username = argv[1];
  
      const struct pam_conv local_conversation = { function_conversation, NULL };
    pam_handle_t *local_auth_handle = NULL; // this gets set by pam_start
  
    int retval;
  
    // local_auth_handle gets set based on the service
    retval = pam_start("common-auth", username, &amp;local_conversation, &amp;local_auth_handle);
  
    if (retval != PAM_SUCCESS)
    {
      std::cout &lt;&lt; "pam_start returned " &lt;&lt; retval &lt;&lt; std::endl;
      exit(retval);
    }
  
    reply = (struct pam_response *)malloc(sizeof(struct pam_response));
  
    // *** Get the password by any method, or maybe it was passed into this function.
    reply[0].resp = getpass("Password: ");
    reply[0].resp_retcode = 0;
  
    retval = pam_authenticate(local_auth_handle, 0);
  
    if (retval != PAM_SUCCESS)
    {
      if (retval == PAM_AUTH_ERR)
      {
          std::cout &lt;&lt; "Authentication failure." &lt;&lt; std::endl;
      }
      else
      {
          std::cout &lt;&lt; "pam_authenticate returned " &lt;&lt; retval &lt;&lt; std::endl;
      }
      exit(retval);
    }
  
    std::cout &lt;&lt; "Authenticated." &lt;&lt; std::endl;
  
    retval = pam_end(local_auth_handle, retval);
  
    if (retval != PAM_SUCCESS)
    {
      std::cout &lt;&lt; "pam_end returned " &lt;&lt; retval &lt;&lt; std::endl;
      exit(retval);
    }
  
    return retval;
  }
  </code></pre>
  
  <p>But it won't work on the ldap one. It will just say "Authentification failure" I have therefore tried this thinking ldap was the issue :</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;ldap.h&gt;
  /* LDAP Server settings */
  #define LDAP_SERVER "ldap://annuaire.upmc.fr:389"
  
  int
  main( int argc, char **argv )
  {
      LDAP        *ld;
      int        rc;
      char        bind_dn[100];
  
  /* Get username and password */
      if( argc != 3 )
      {
          perror( "invalid args, required: username password" );
          return( 1 );
      }
      sprintf( bind_dn, "uid=%s,ou=people,dc=upmc,dc=fr", argv[1] );
      printf( "Connecting as %s...\n", bind_dn );
  
  /* Open LDAP Connection */
      if( ldap_initialize( &amp;ld, LDAP_SERVER ) )
      {
          perror( "ldap_initialize" );
          return( 1 );
      }
  
  
  /* User authentication (bind) */
      rc = ldap_simple_bind_s( ld, bind_dn, argv[2] );
      if( rc != LDAP_SUCCESS )
      {
          fprintf(stderr, "ldap_simple_bind_s: %s\n", ldap_err2string(rc) );
          return( 1 );
      }
      printf( "Successful authentication\n" );
      ldap_unbind( ld );
      return( 0 );
  }
  </code></pre>
  
  <p>However i got this error trying to log in : </p>
  
  <pre><code>ldap_simple_bind_s: Invalid credentials.
  </code></pre>
  
  <p>It looks like the server is found but cannot authenticate me.</p>
  
  <p>My questions are : What are the differences between pam and ldap, is pam a more general way of authentificate someont ? Can i achieve authentification for ldap with the pam program or if not what is wrong with my ldap testing code ?</p>