#include <security/pam_appl.h>
#include <security/pam_modules.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <pwd.h>
#include <syslog.h>
#include <libintl.h>

#include "tacshell.h"

struct pam_conv         *pam_convp;

static pam_handle_t	*pam_h;

int
pam_sm_authenticate(
        pam_handle_t            *pamh,
        int                     flags,
        int                     argc,
        const char              **argv)
{
        char                    *user;
        int                     err;
        int                     debug = 0;

        if (debug)
                syslog(LOG_DEBUG, "Sample Authentication\n");

	pam_h = pamh;

	fprintf(stderr, "1\n");

	parse_config();
	fprintf(stderr, "2\n");

        err = pam_get_user(pamh, &user, NULL);
        if (err != PAM_SUCCESS)
                return (err);

        err = pam_get_item(pamh, PAM_CONV, (void**) &pam_convp);
        if (err != PAM_SUCCESS)
                return (err);

        //(void) pam_get_item(pamh, PAM_AUTHTOK, (void **) &firstpass);
	fprintf(stderr, "3\n");

	err = authenticate(getservername(server_name), user);
	fprintf(stderr, "4\n");
	cleanup();

	if (err)
	  return PAM_AUTH_ERR;
	else
	  return PAM_SUCCESS;

}

int
pam_sm_close_session(pam_handle_t *pamh, int flags, int argc, const char **argv)
{
        return (PAM_SUCCESS);
}

int
pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv)
{

        /*
         * Set the credentials
         */

        return (PAM_SUCCESS);
}

int
get_authtok(int (*conv_funp)(), char *messages, void *conv_apdp, struct pam_response **ret_respp)
{
        struct pam_message      *msg;
        struct pam_message      *m;
        int                     i;
        int                     retcode;

        i = 0;
	fprintf(stderr, "b1\n");

        msg = (struct pam_message *)calloc(1, sizeof (struct pam_message));
        if (msg == NULL) {
                return (PAM_CONV_ERR);
        }
        m = msg;

        /*
         * fill out the message structure to display error message
         */
        m->msg_style = PAM_PROMPT_ECHO_OFF;
        m->msg = (char *)malloc(PAM_MAX_MSG_SIZE);
        if (m->msg != NULL)
                (void) strcpy(m->msg, (char *)messages);
	fprintf(stderr, "b2\n");

        /*
         * Call conv function to display the prompt,
         * ignoring return value for now
         */
        retcode = conv_funp(1, &msg, ret_respp, conv_apdp);
	fprintf(stderr, "b3\n");

        if (msg) {
                free(m->msg);
                free(msg);
        }

        return (retcode);
}

char *get_pass(char *prompt)
{
  char *pass;

  struct pam_message msg[1], *pmsg[1];
  struct pam_response *resp;
  struct pam_conv *conv;
  int retval;

  /* set up conversation call */

  pmsg[0] = &msg[0];
  msg[0].msg_style = PAM_PROMPT_ECHO_OFF;
  msg[0].msg = "Password: ";
  resp = NULL;

  if ((retval = pam_get_item (pam_h, PAM_CONV, (const void **) &conv)) == PAM_SUCCESS)
    {
      retval = conv->conv (1, pmsg, &resp, conv->appdata_ptr);
      if (retval != PAM_SUCCESS)
        return NULL;
    }
  else
    {
      fprintf(stderr, "(pam_tacplus) converse failed to get pam_conv");
    }

  if (resp)
    {
      if (resp[0].resp == NULL)
        {
          _pam_log (LOG_DEBUG,
                    "pam_sm_authenticate: NULL authtok given");
        }
      pass = resp[0].resp;      /* remember this! */

      resp[0].resp = NULL;
    }

  free(resp);
  resp = NULL;

  return pass;
}


syntax highlighted by Code2HTML, v. 0.9.1