pamsrv_p11.c revision 0a8024af282b271ad2185f68703d9f4e766d2bdc
/*
SSSD
PAM Responder - certificate realted requests
Copyright (C) Sumit Bose <sbose@redhat.com> 2015
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <time.h>
#include "providers/data_provider.h"
#include "util/child_common.h"
#include "util/strtonum.h"
#ifndef SSSD_LIBEXEC_PATH
#error "SSSD_LIBEXEC_PATH not defined"
#endif /* SSSD_LIBEXEC_PATH */
#define P11_CHILD_LOG_FILE "p11_child"
struct cert_auth_info {
char *cert;
char *token_name;
char *module_name;
char *key_id;
struct ldb_result *cert_user_objs;
struct cert_auth_info *prev;
struct cert_auth_info *next;
};
const char *sss_cai_get_cert(struct cert_auth_info *i)
{
}
const char *sss_cai_get_token_name(struct cert_auth_info *i)
{
}
const char *sss_cai_get_module_name(struct cert_auth_info *i)
{
}
const char *sss_cai_get_key_id(struct cert_auth_info *i)
{
}
{
}
{
}
void sss_cai_set_cert_user_objs(struct cert_auth_info *i,
struct ldb_result *cert_user_objs)
{
if (i->cert_user_objs != NULL) {
}
}
{
struct cert_auth_info *c;
struct cert_auth_info *tmp;
size_t cert_count = 0;
size_t cert_user_count = 0;
struct ldb_result *user_objs;
cert_count++;
} else {
DLIST_REMOVE(*list, c);
}
}
if (_cert_count != NULL) {
}
if (_cert_user_count != NULL) {
}
return;
}
{
}
{
size_t c;
"gdm-password", "kdm", "sudo", "sudo-i",
"gnome-screensaver", NULL };
return false;
}
return false;
}
return false;
}
/* TODO: make services configurable */
return false;
}
for (c = 0; sc_services[c] != NULL; c++) {
break;
}
}
if (sc_services[c] == NULL) {
"Smartcard authentication for service [%s] not supported.\n",
return false;
}
return true;
}
{
int ret;
return EINVAL;
}
case SSS_AUTHTOK_TYPE_SC_PIN:
return ret;
}
return EINVAL;
}
return ENOMEM;
}
break;
/* Nothing to send */
len = 0;
break;
default:
return EINVAL;
}
return EOK;
}
struct cert_auth_info **_cert_list)
{
int ret;
uint8_t *p;
struct cert_auth_info *cert_auth_info;
if (buf_len < 0) {
"Error occurred while reading data from p11_child.\n");
return EIO;
}
if (buf_len == 0) {
goto done;
}
return ENOMEM;
}
p = buf;
do {
if (cert_auth_info == NULL) {
return ENOMEM;
}
"Missing new-line in p11_child response.\n");
return EINVAL;
}
if (pn == p) {
"Missing counter in p11_child response.\n");
return EINVAL;
}
(pn - p));
goto done;
}
p = ++pn;
"Missing new-line in p11_child response.\n");
goto done;
}
if (pn == p) {
"Missing module name in p11_child response.\n");
goto done;
}
(pn - p));
goto done;
}
p = ++pn;
"Missing new-line in p11_child response.\n");
goto done;
}
if (pn == p) {
"Missing key id in p11_child response.\n");
goto done;
}
(pn - p));
goto done;
}
p = ++pn;
"Missing new-line in p11_child response.\n");
goto done;
}
if (pn == p) {
goto done;
}
(pn - p));
goto done;
}
p = ++pn;
done:
}
*_cert_list = cert_list;
}
return ret;
}
struct pam_check_cert_state {
int child_status;
struct sss_child_ctx_old *child_ctx;
struct tevent_timer *timeout_handler;
struct tevent_context *ev;
struct child_io_fds *io;
struct cert_auth_info *cert_list;
};
struct tevent_timer *te,
struct tevent_context *ev,
int child_debug_fd,
const char *nss_db,
const char *verify_opts,
{
struct tevent_req *req;
struct tevent_req *subreq;
struct pam_check_cert_state *state;
size_t write_buf_len = 0;
const char *module_name = NULL;
const char *token_name = NULL;
return NULL;
}
goto done;
}
/* extra_args are added in revers order */
arg_c = 0;
if (verify_opts != NULL) {
}
goto done;
}
}
}
}
}
case SSS_AUTHTOK_TYPE_SC_PIN:
break;
break;
default:
goto done;
}
} else {
goto done;
}
goto done;
}
if (ret == -1) {
goto done;
}
if (ret == -1) {
goto done;
}
if (child_debug_fd == -1) {
}
if (child_pid == 0) { /* child */
/* We should never get here */
} else if (child_pid > 0) { /* parent */
/* Set up SIGCHLD handler */
ret = ERR_P11_CHILD;
goto done;
}
/* Set up timeout handler */
ret = ERR_P11_CHILD;
goto done;
}
"get_p11_child_write_buffer failed.\n");
goto done;
}
}
if (write_buf_len != 0) {
ret = ERR_P11_CHILD;
goto done;
}
} else {
ret = ERR_P11_CHILD;
goto done;
}
}
/* Now either wait for the timeout to fire or the child
* to finish
*/
} else { /* error */
goto done;
}
done:
}
return req;
}
{
struct tevent_req);
struct pam_check_cert_state);
int ret;
return;
}
return;
}
}
{
struct tevent_req);
struct pam_check_cert_state);
int ret;
return;
}
return;
}
return;
}
struct tevent_timer *te,
{
struct pam_check_cert_state *state =
}
struct cert_auth_info **cert_list)
{
struct cert_auth_info *tmp_cert_auth_info;
struct pam_check_cert_state *state =
}
}
return EOK;
}
struct cert_auth_info *cert_info,
{
const char *token_name;
const char *module_name;
const char *key_id;
const char *username = "";
if (sysdb_username != NULL) {
}
return ENOMEM;
}
}
}
return EOK;
}
/* The PKCS11_LOGIN_TOKEN_NAME environment variable is e.g. used by the Gnome
* Settings Daemon to determine the name of the token used for login but it
* should be only set if SSSD is called by gdm-smartcard. Otherwise desktop
* components might assume that gdm-smartcard PAM stack is configured
* correctly which might not be the case e.g. if Smartcard authentication was
* used when running gdm-password. */
#define PKCS11_LOGIN_TOKEN_ENV_NAME "PKCS11_LOGIN_TOKEN_NAME"
struct cert_auth_info *cert_info,
enum response_type type)
{
int ret;
return EINVAL;
}
return EINVAL;
}
/* sysdb_username is a fully-qualified name which is used by pam_sss when
* prompting the user for the PIN and as login name if it wasn't set by
* the PAM caller but has to be determined based on the inserted
* Smartcard. If this type of name is irritating at the PIN prompt or the
* re_expression config option was set in a way that user@domain cannot be
* handled anymore some more logic has to be added here. But for the time
* being I think using sysdb_username is fine. */
return ret;
}
"pam_add_response failed to add certificate info.\n");
return ret;
}
return ENOMEM;
}
"pam_add_response failed to add environment variable.\n");
return ret;
}
}
return ret;
}