Blame compat/pam_get_authtok.c

Packit 6bd9ab
/*
Packit 6bd9ab
   pam_get_authtok.c - replacement function for pam_get_authtok()
Packit 6bd9ab
Packit 6bd9ab
   Copyright (C) 2009, 2010, 2012 Arthur de Jong
Packit 6bd9ab
   Copyright (C) 2010 Symas Corporation
Packit 6bd9ab
Packit 6bd9ab
   This library is free software; you can redistribute it and/or
Packit 6bd9ab
   modify it under the terms of the GNU Lesser General Public
Packit 6bd9ab
   License as published by the Free Software Foundation; either
Packit 6bd9ab
   version 2.1 of the License, or (at your option) any later version.
Packit 6bd9ab
Packit 6bd9ab
   This library is distributed in the hope that it will be useful,
Packit 6bd9ab
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6bd9ab
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 6bd9ab
   Lesser General Public License for more details.
Packit 6bd9ab
Packit 6bd9ab
   You should have received a copy of the GNU Lesser General Public
Packit 6bd9ab
   License along with this library; if not, write to the Free Software
Packit 6bd9ab
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
Packit 6bd9ab
   02110-1301 USA
Packit 6bd9ab
*/
Packit 6bd9ab
Packit 6bd9ab
#include "config.h"
Packit 6bd9ab
Packit 6bd9ab
#include <stdlib.h>
Packit 6bd9ab
#include <stdio.h>
Packit 6bd9ab
#include <string.h>
Packit 6bd9ab
#include <errno.h>
Packit 6bd9ab
#include <syslog.h>
Packit 6bd9ab
#include <unistd.h>
Packit 6bd9ab
#include <sys/types.h>
Packit 6bd9ab
Packit 6bd9ab
#include "compat/attrs.h"
Packit 6bd9ab
#include "compat/pam_compat.h"
Packit 6bd9ab
Packit 6bd9ab
/* warning: this version assumes that try_first_pass is specified */
Packit 6bd9ab
Packit 6bd9ab
int pam_get_authtok(pam_handle_t *pamh, int item, const char **authtok,
Packit 6bd9ab
                    const char *prompt)
Packit 6bd9ab
{
Packit 6bd9ab
  int rc;
Packit 6bd9ab
  char *passwd = NULL, *retype_passwd = NULL;
Packit 6bd9ab
  const void *oldauthtok;
Packit 6bd9ab
  char retype_prompt[80];
Packit 6bd9ab
  /* first try to see if the value is already on the stack */
Packit 6bd9ab
  *authtok = NULL;
Packit 6bd9ab
  rc = pam_get_item(pamh, item, (PAM_ITEM_CONST void **)authtok);
Packit 6bd9ab
  if ((rc == PAM_SUCCESS) && (*authtok != NULL))
Packit 6bd9ab
    return PAM_SUCCESS;
Packit 6bd9ab
  /* check what to prompt for and provide default prompt */
Packit 6bd9ab
  *retype_prompt = '\0';
Packit 6bd9ab
  if (item == PAM_OLDAUTHTOK)
Packit 6bd9ab
    prompt = (prompt != NULL) ? prompt : "Old Password: ";
Packit 6bd9ab
  else
Packit 6bd9ab
  {
Packit 6bd9ab
    rc = pam_get_item(pamh, PAM_OLDAUTHTOK, (PAM_ITEM_CONST void **)&oldauthtok);
Packit 6bd9ab
    if ((rc == PAM_SUCCESS) && (oldauthtok != NULL))
Packit 6bd9ab
    {
Packit 6bd9ab
      prompt = (prompt != NULL) ? prompt : "New Password: ";
Packit 6bd9ab
      snprintf(retype_prompt, sizeof(retype_prompt), "Retype %s", prompt);
Packit 6bd9ab
      retype_prompt[sizeof(retype_prompt) - 1] = '\0';
Packit 6bd9ab
    }
Packit 6bd9ab
    else
Packit 6bd9ab
      prompt = (prompt != NULL) ? prompt : "Password: ";
Packit 6bd9ab
  }
Packit 6bd9ab
  /* prepare prompt and get password */
Packit 6bd9ab
  rc = pam_prompt(pamh, PAM_PROMPT_ECHO_OFF, &passwd, "%s", prompt);
Packit 6bd9ab
  if (rc != PAM_SUCCESS)
Packit 6bd9ab
    return rc;
Packit 6bd9ab
  /* if a second prompt should be presented, do it */
Packit 6bd9ab
  if (*retype_prompt)
Packit 6bd9ab
  {
Packit 6bd9ab
    rc = pam_prompt(pamh, PAM_PROMPT_ECHO_OFF, &retype_passwd, "%s",
Packit 6bd9ab
                    retype_prompt);
Packit 6bd9ab
    /* check passwords */
Packit 6bd9ab
    if ((rc == PAM_SUCCESS) && (strcmp(retype_passwd, passwd) != 0))
Packit 6bd9ab
      rc = PAM_AUTHTOK_RECOVERY_ERR;
Packit 6bd9ab
  }
Packit 6bd9ab
  /* store the password if everything went ok */
Packit 6bd9ab
  if (rc == PAM_SUCCESS)
Packit 6bd9ab
    rc = pam_set_item(pamh, item, passwd);
Packit 6bd9ab
  /* clear and free any password information */
Packit 6bd9ab
  memset(passwd, 0, strlen(passwd));
Packit 6bd9ab
  free(passwd);
Packit 6bd9ab
  if (retype_passwd != NULL)
Packit 6bd9ab
  {
Packit 6bd9ab
    memset(retype_passwd, 0, strlen(retype_passwd));
Packit 6bd9ab
    free(retype_passwd);
Packit 6bd9ab
  }
Packit 6bd9ab
  if (rc != PAM_SUCCESS)
Packit 6bd9ab
    return rc;
Packit 6bd9ab
  /* return token from the stack */
Packit 6bd9ab
  return pam_get_item(pamh, item, (PAM_ITEM_CONST void **)authtok);
Packit 6bd9ab
}