Login without password I'm in a project where the main login form must not have a password field. The user will login with a username and selecting a Country. This country field is configured within the user profile.
So far, I can manage to log in users checking their username and the selected countries, but I can't find anything not to require a password for login.

This is my code.

function hdp_form_alter(&amp;$form, &amp;$form_state, $form_id) {
  if ($form_id == 'user_login_block') {
    // Add country field to login form
    $form['pais'] = array(
      '#type' =&gt; 'select',
      '#title' =&gt; t('Pais'),
      '#options' =&gt; array(
        'Argentina' =&gt; t('Argentina'),
        'Chile' =&gt; t('Chile'),
        'Peru' =&gt; t('Peru'),
      ),
      '#required' =&gt; TRUE,
    );
    // Add validation to check country-username
    $form['#validate'][] = 'validacion';
  }
}

function validacion(&amp;$form, &amp;$form_state) {
  // Variables.
  $usuario_nombre = $form_state['values']['name'];
  $usuario_pais_seleccionado = $form_state['values']['pais'];

  // Search user countries by username. Username must not be duplicated.
  $uid = db_query("SELECT uid FROM {users} WHERE name IN ('$usuario_nombre')")-&gt;fetchField();
  if (!empty($uid)) {
    $paises = db_query("SELECT field_paises_value FROM {field_data_field_paises} WHERE entity_id IN ($uid)")-&gt;fetchAll();
    $paises_habilitados = NULL;
    foreach ($paises as $pais) {
    $paises_habilitados .= $pais-&gt;field_paises_value;
  }

  // Check if selected country is one of the user profile selected countries.
  $habilitado = strpos($paises_habilitados, $usuario_pais_seleccionado);
  if ($habilitado === false) {
    form_set_error('pais', 'Acceso denegado. Por favor revise su nombre de usuario y el país seleccionado.');
  }
}
If you don't require a password from your users, then you should:


Make the password form field not visible to the users (it is enough to set #access to FALSE)
Remove the form validation handlers that are not necessary


The form validation handlers that the user login block uses are the following:


user_login_name_validate() just checks the user account matching the username is not blocked 
user_login_authenticate_validate() checks the entered password matches the one set for the user account using that username
user_login_final_validate() checks the user didn't enter too much times the wrong password


What you need to do is removing 'user_login_authenticate_validate' and 'user_login_final_validate' from the array $form['#validate'].

Remember also that your form validation handler needs to set $form_state['uid'], since that is the value used from user_login_submit() to load the user object from the database.

As additional notes:


Your code is making assumptions about where/how the field data are saved; in particular, it is assuming the field data are saved in the database currently used by the Drupal site, which is not necessary true, since field data could be saved in MongoDB. I would rather use the following code.

$uid = db_query("SELECT uid FROM {users} WHERE name = :account_name", array(':account_name' =&gt; $usuario_nombre))-&gt;fetchField();
if (!empty($uid)) {
  $account = user_load($uid);
  if ($countries = field_get_items('user', $account, 'field_paises')) {
    // I assume users can just select a single country.
    $country = array_shift($countries);
    if ($country != $usuario_pais_seleccionado) {
      // Show the error message.
    }
  }
}

You cannot use user_authenticate(), since that requires the account password, which is not saved in the database. The database contains the password hash.
The string passed to t() should contain words in English, since the function is used to translate from English to the language currently set for the site. (Pais is not an English word; probably you meant Country.)
Instead of WHERE name IN ('$usuario_nombre'), you should use WHERE name = :username. Input from users should not be used directly in SQL queries, as that is a security issue. (See SQL injection.)
Functions implemented by a module should always have their names prefixed by the module name.


Talking of security issues, I hope you are using the authentication method you described in a very restricted, controlled environment. I would not use it in a public site where everybody can create an account, especially if the username and the country selected from users are visible to everybody. Even in the case the country is not visible, getting the right username/country combination is much easier than finding the right username/password combination that allows you to log in.