/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* This file has all of the PAM related code for sys-suspend. It is
* part of it's own file, as these could be part of some bigger item
* that can handle generic PAM facilities (certainly the getinput()
* function could be in a common library). However, as that does not
* yet exist, we replicate it here so we can get the job done.
*/
#include <errno.h>
#include <libgen.h>
#include <malloc.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <stropts.h>
#include <unistd.h>
#include <termio.h>
#include <security/pam_appl.h>
/* ARGSUSED 1 */
static void
interrupt(int x)
{
ctl_c = 1;
}
/*
* getinput -- read user input from stdin abort on ^C
*
* Entry noecho == TRUE, don't echo input.
*
* Exit User's input.
* If interrupted, send SIGINT to caller for processing.
*/
static char *
{
unsigned short tty_flags = 0;
int c;
int i = 0;
void (*sig)(int);
ctl_c = 0;
if (noecho) {
}
/* go to end, but don't overflow PAM_MAX_RESP_SIZE */
while (ctl_c == 0 &&
(c = getchar_unlocked()) != '\n' &&
c != '\r' &&
c != EOF) {
if (i < PAM_MAX_RESP_SIZE) {
input[i++] = (char)c;
}
}
input[i] = '\0';
if (noecho) {
}
if (ctl_c == 1)
}
/*
* Service modules don't clean up responses if an error is returned.
* Free responses here.
*/
static void
{
int i;
struct pam_response *r = pr;
return;
for (i = 0; i < num_msg; i++, r++) {
if (r->resp) {
/* clear before freeing -- may be a password */
}
}
}
/* ARGSUSED */
int
{
struct pam_message *m = *mess;
int i;
if (num_msg >= PAM_MAX_NUM_MSG) {
free(r);
return (PAM_CONV_ERR);
}
/* Talk it out */
*resp = r;
for (i = 0; i < num_msg; i++) {
int echo_off;
/* bad message from service module */
i, m->msg_style);
goto err;
}
/*
* fix up final newline:
* removed for prompts
* added back for messages
*/
r->resp_retcode = 0;
echo_off = 0;
switch (m->msg_style) {
case PAM_PROMPT_ECHO_OFF:
echo_off = 1;
/*FALLTHROUGH*/
case PAM_PROMPT_ECHO_ON:
break;
case PAM_ERROR_MSG:
break;
case PAM_TEXT_INFO:
break;
default:
/* error, service module won't clean up */
goto err;
}
goto err;
m++;
r++;
}
return (PAM_SUCCESS);
err:
free_resp(i, r);
return (PAM_CONV_ERR);
}