10afbe39cb81a1810dba486c4b8e46578bb300bbStephen Gallagher Pam Proxy Child
10afbe39cb81a1810dba486c4b8e46578bb300bbStephen Gallagher Sumit Bose <sbose@redhat.com>
10afbe39cb81a1810dba486c4b8e46578bb300bbStephen Gallagher Copyright (C) 2010 Red Hat
10afbe39cb81a1810dba486c4b8e46578bb300bbStephen Gallagher This program is free software; you can redistribute it and/or modify
10afbe39cb81a1810dba486c4b8e46578bb300bbStephen Gallagher it under the terms of the GNU General Public License as published by
10afbe39cb81a1810dba486c4b8e46578bb300bbStephen Gallagher the Free Software Foundation; either version 3 of the License, or
10afbe39cb81a1810dba486c4b8e46578bb300bbStephen Gallagher (at your option) any later version.
10afbe39cb81a1810dba486c4b8e46578bb300bbStephen Gallagher This program is distributed in the hope that it will be useful,
10afbe39cb81a1810dba486c4b8e46578bb300bbStephen Gallagher but WITHOUT ANY WARRANTY; without even the implied warranty of
10afbe39cb81a1810dba486c4b8e46578bb300bbStephen Gallagher MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10afbe39cb81a1810dba486c4b8e46578bb300bbStephen Gallagher GNU General Public License for more details.
10afbe39cb81a1810dba486c4b8e46578bb300bbStephen Gallagher You should have received a copy of the GNU General Public License
10afbe39cb81a1810dba486c4b8e46578bb300bbStephen Gallagher along with this program. If not, see <http://www.gnu.org/licenses/>.
e07d700ed9daf0cf96607fa2d72978cb2431b794Pavel Březina#include "providers/proxy/proxy_iface_generated.h"
10afbe39cb81a1810dba486c4b8e46578bb300bbStephen Gallagherstatic int proxy_internal_conv(int num_msg, const struct pam_message **msgm,
10afbe39cb81a1810dba486c4b8e46578bb300bbStephen Gallagher auth_data = talloc_get_type(appdata_ptr, struct authtok_conv);
10afbe39cb81a1810dba486c4b8e46578bb300bbStephen Gallagher reply = (struct pam_response *) calloc(num_msg,
10afbe39cb81a1810dba486c4b8e46578bb300bbStephen Gallagher sizeof(struct pam_response));
10afbe39cb81a1810dba486c4b8e46578bb300bbStephen Gallagher for (i=0; i < num_msg; i++) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "Conversation message: [%s]\n", msgm[i]->msg);
9acfb09f7969a69f58bd45c856b01700541853caLukas Slebodnik ret = sss_authtok_get_password(auth_data->authtok,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "Conversation style %d not supported.\n",
35c70c767d366fc82a50f6f29793ab7f1477f79dStephen Gallagherstatic int proxy_chauthtok_conv(int num_msg, const struct pam_message **msgm,
35c70c767d366fc82a50f6f29793ab7f1477f79dStephen Gallagher auth_data = talloc_get_type(appdata_ptr, struct authtok_conv);
35c70c767d366fc82a50f6f29793ab7f1477f79dStephen Gallagher reply = (struct pam_response *) calloc(num_msg,
35c70c767d366fc82a50f6f29793ab7f1477f79dStephen Gallagher sizeof(struct pam_response));
35c70c767d366fc82a50f6f29793ab7f1477f79dStephen Gallagher for (i=0; i < num_msg; i++) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "Conversation message: [%s]\n", msgm[i]->msg);
35c70c767d366fc82a50f6f29793ab7f1477f79dStephen Gallagher /* The first prompt will be asking for the old authtok */
9acfb09f7969a69f58bd45c856b01700541853caLukas Slebodnik ret = sss_authtok_get_password(auth_data->authtok,
35c70c767d366fc82a50f6f29793ab7f1477f79dStephen Gallagher /* Subsequent prompts are looking for the new authtok */
9acfb09f7969a69f58bd45c856b01700541853caLukas Slebodnik ret = sss_authtok_get_password(auth_data->newauthtok,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "Conversation style %d not supported.\n",
10afbe39cb81a1810dba486c4b8e46578bb300bbStephen Gallagherstatic errno_t call_pam_stack(const char *pam_target, struct pam_data *pd)
10afbe39cb81a1810dba486c4b8e46578bb300bbStephen Gallagher auth_data = talloc_zero(pd, struct authtok_conv);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n");
545f49b72cdf8453fb0b85c9d87e7d4711da57daLukas Slebodnik auth_data->authtok = sss_authtok_new(auth_data);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "sss_authtok_new failed.\n");
545f49b72cdf8453fb0b85c9d87e7d4711da57daLukas Slebodnik auth_data->newauthtok = sss_authtok_new(auth_data);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "sss_authtok_new failed.\n");
526d4d5e5a916cf30a043836cba14eab529cb7b1Jakub Hrozek ret = sss_parse_internal_fqname(auth_data, pd->user, &shortname, NULL);
526d4d5e5a916cf30a043836cba14eab529cb7b1Jakub Hrozek ret = pam_start(pam_target, shortname, &conv, &pamh);
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "Pam transaction started with service name [%s].\n",
10afbe39cb81a1810dba486c4b8e46578bb300bbStephen Gallagher ret = pam_set_item(pamh, PAM_TTY, pd->tty);
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Setting PAM_TTY failed: %s.\n",
10afbe39cb81a1810dba486c4b8e46578bb300bbStephen Gallagher ret = pam_set_item(pamh, PAM_RUSER, pd->ruser);
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Setting PAM_RUSER failed: %s.\n",
10afbe39cb81a1810dba486c4b8e46578bb300bbStephen Gallagher ret = pam_set_item(pamh, PAM_RHOST, pd->rhost);
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Setting PAM_RHOST failed: %s.\n",
9acfb09f7969a69f58bd45c856b01700541853caLukas Slebodnik sss_authtok_copy(pd->authtok, auth_data->authtok);
9acfb09f7969a69f58bd45c856b01700541853caLukas Slebodnik sss_authtok_copy(pd->authtok, auth_data->authtok);
9acfb09f7969a69f58bd45c856b01700541853caLukas Slebodnik sss_authtok_copy(pd->newauthtok, auth_data->newauthtok);
9acfb09f7969a69f58bd45c856b01700541853caLukas Slebodnik sss_authtok_copy(pd->authtok, auth_data->authtok);
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "unknown PAM call\n");
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CONF_SETTINGS, "Pam result: [%d][%s]\n", pam_status,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Cannot terminate pam transaction.\n");
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Failed to initialize pam transaction.\n");
07e941c1bbdc752142bbd3b838c540bc7ecd0ed7Stef Walterstatic int pc_pam_handler(struct sbus_request *dbus_req, void *user_data)
10afbe39cb81a1810dba486c4b8e46578bb300bbStephen Gallagher pc_ctx = talloc_get_type(user_data, struct pc_ctx);
d9577dbd92555b0755881e37724019ef9c578404Stef Walter reply = dbus_message_new_method_return(dbus_req->message);
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "dbus_message_new_method_return failed, "
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "cannot send reply.\n");
d9577dbd92555b0755881e37724019ef9c578404Stef Walter ret = dp_unpack_pam_request(dbus_req->message, pc_ctx, &pd, &dbus_error);
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE,"Failed, to parse message!\n");
10afbe39cb81a1810dba486c4b8e46578bb300bbStephen Gallagher pd->domain = talloc_strdup(pd, pc_ctx->domain->name);
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CONF_SETTINGS, "Got request with the following data\n");
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG_PAM_DATA(SSSDBG_CONF_SETTINGS, pd);
10afbe39cb81a1810dba486c4b8e46578bb300bbStephen Gallagher ret = call_pam_stack(pc_ctx->pam_target, pd);
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "call_pam_stack failed.\n");
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CONF_SETTINGS, "Sending result [%d][%s]\n",
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Failed to generate dbus reply\n");
10afbe39cb81a1810dba486c4b8e46578bb300bbStephen Gallagher /* We'll return the message and let the
10afbe39cb81a1810dba486c4b8e46578bb300bbStephen Gallagher * parent process kill us.
e07d700ed9daf0cf96607fa2d72978cb2431b794Pavel Březinastatic void proxy_child_id_callback(DBusPendingCall *pending, void *ptr)
e07d700ed9daf0cf96607fa2d72978cb2431b794Pavel Březina reply = dbus_pending_call_steal_reply(pending);
e07d700ed9daf0cf96607fa2d72978cb2431b794Pavel Březina /* reply should never be null. This function shouldn't be called
e07d700ed9daf0cf96607fa2d72978cb2431b794Pavel Březina * until reply is valid or timeout has occurred. If reply is NULL
e07d700ed9daf0cf96607fa2d72978cb2431b794Pavel Březina * here, something is seriously wrong and we should bail out.
e07d700ed9daf0cf96607fa2d72978cb2431b794Pavel Březina DEBUG(SSSDBG_FATAL_FAILURE, "Severe error. A reply callback was "
e07d700ed9daf0cf96607fa2d72978cb2431b794Pavel Březina "called but no reply was received and no timeout occurred\n");
e07d700ed9daf0cf96607fa2d72978cb2431b794Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get ID ack [%d]: %s\n",
e07d700ed9daf0cf96607fa2d72978cb2431b794Pavel Březina DEBUG(SSSDBG_TRACE_FUNC, "Got id ack from proxy child\n");
e07d700ed9daf0cf96607fa2d72978cb2431b794Pavel Březinastatic errno_t proxy_child_send_id(struct sbus_connection *conn, uint32_t id)
e07d700ed9daf0cf96607fa2d72978cb2431b794Pavel Březina msg = sbus_create_message(NULL, NULL, PROXY_CHILD_PATH, IFACE_PROXY_CLIENT,
e07d700ed9daf0cf96607fa2d72978cb2431b794Pavel Březina DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory?!\n");
e07d700ed9daf0cf96607fa2d72978cb2431b794Pavel Březina DEBUG(SSSDBG_TRACE_FUNC, "Sending ID to Proxy Backend: (%"PRIu32")\n", id);
e07d700ed9daf0cf96607fa2d72978cb2431b794Pavel Březina ret = sbus_conn_send(conn, msg, 30000, proxy_child_id_callback, NULL, NULL);
10afbe39cb81a1810dba486c4b8e46578bb300bbStephen Gallagherstatic int proxy_cli_init(struct pc_ctx *ctx)
e07d700ed9daf0cf96607fa2d72978cb2431b794Pavel Březina static struct iface_proxy_auth iface_proxy_auth = {
10afbe39cb81a1810dba486c4b8e46578bb300bbStephen Gallagher sbus_address = talloc_asprintf(ctx, "unix:path=%s/%s_%s",
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n");
b46c4c0d3e364636af1b42683cd3229ffa0b77cbFabiano Fidêncio ret = sbus_client_init(ctx, ctx->ev, sbus_address, NULL, &ctx->conn);
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "sbus_client_init failed.\n");
e07d700ed9daf0cf96607fa2d72978cb2431b794Pavel Březina ret = sbus_conn_register_iface(ctx->conn, &iface_proxy_auth.vtable,
07e941c1bbdc752142bbd3b838c540bc7ecd0ed7Stef Walter DEBUG(SSSDBG_FATAL_FAILURE, "Failed to export proxy.\n");
e07d700ed9daf0cf96607fa2d72978cb2431b794Pavel Březina ret = proxy_child_send_id(ctx->conn, ctx->id);
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_FATAL_FAILURE, "dp_common_send_id failed.\n");
10afbe39cb81a1810dba486c4b8e46578bb300bbStephen Gallagherint proxy_child_process_init(TALLOC_CTX *mem_ctx, const char *domain,
10afbe39cb81a1810dba486c4b8e46578bb300bbStephen Gallagher struct tevent_context *ev, struct confdb_ctx *cdb,
10afbe39cb81a1810dba486c4b8e46578bb300bbStephen Gallagher ctx = talloc_zero(mem_ctx, struct pc_ctx);
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_FATAL_FAILURE, "fatal error initializing pc_ctx\n");
10afbe39cb81a1810dba486c4b8e46578bb300bbStephen Gallagher ctx->pam_target = talloc_steal(ctx, pam_target);
10afbe39cb81a1810dba486c4b8e46578bb300bbStephen Gallagher ctx->conf_path = talloc_asprintf(ctx, CONFDB_DOMAIN_PATH_TMPL, domain);
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory!?\n");
10afbe39cb81a1810dba486c4b8e46578bb300bbStephen Gallagher ret = confdb_get_domain(cdb, domain, &ctx->domain);
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "fatal error retrieving domain configuration\n");
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_FATAL_FAILURE, "fatal error setting up server bus\n");
10afbe39cb81a1810dba486c4b8e46578bb300bbStephen Gallagher {"domain", 0, POPT_ARG_STRING, &domain, 0,
10afbe39cb81a1810dba486c4b8e46578bb300bbStephen Gallagher _("Domain of the information provider (mandatory)"), NULL },
10afbe39cb81a1810dba486c4b8e46578bb300bbStephen Gallagher _("Child identifier (mandatory)"), NULL },
4a9c1047354dbe5a4ed41e5951ae623e3772e113René Genz /* Set debug level to invalid value so we can decide if -d 0 was used. */
10afbe39cb81a1810dba486c4b8e46578bb300bbStephen Gallagher pc = poptGetContext(argv[0], argc, argv, long_options, 0);
10afbe39cb81a1810dba486c4b8e46578bb300bbStephen Gallagher fprintf(stderr, "\nInvalid option %s: %s\n\n",
10afbe39cb81a1810dba486c4b8e46578bb300bbStephen Gallagher "--domain is a mandatory option.\n\n");
10afbe39cb81a1810dba486c4b8e46578bb300bbStephen Gallagher "--id is a mandatory option.\n\n");
4a9c1047354dbe5a4ed41e5951ae623e3772e113René Genz /* set up things like debug, signals, daemonization, etc. */
10afbe39cb81a1810dba486c4b8e46578bb300bbStephen Gallagher debug_log_file = talloc_asprintf(NULL, "proxy_child_%s", domain);
10afbe39cb81a1810dba486c4b8e46578bb300bbStephen Gallagher srv_name = talloc_asprintf(NULL, "sssd[proxy_child[%s]]", domain);
10afbe39cb81a1810dba486c4b8e46578bb300bbStephen Gallagher conf_entry = talloc_asprintf(NULL, CONFDB_DOMAIN_PATH_TMPL, domain);
ac40d2f2b2b2fc35c95389f5e28febd580bd2b7aJakub Hrozek ret = server_setup(srv_name, 0, 0, 0, conf_entry, &main_ctx);
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_FATAL_FAILURE, "Could not set up mainloop [%d]\n", ret);
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Failed to unset _SSS_LOOPS, "
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "pam modules might not work as expected.\n");
10afbe39cb81a1810dba486c4b8e46578bb300bbStephen Gallagher ret = confdb_get_string(main_ctx->confdb_ctx, main_ctx, conf_entry,
10afbe39cb81a1810dba486c4b8e46578bb300bbStephen Gallagher CONFDB_PROXY_PAM_TARGET, NULL, &pam_target);
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_FATAL_FAILURE, "Error reading from confdb (%d) [%s]\n",
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Missing option proxy_pam_target.\n");
10afbe39cb81a1810dba486c4b8e46578bb300bbStephen Gallagher /* This is not fatal, don't return */
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "Could not set up to exit when parent process does\n");
10afbe39cb81a1810dba486c4b8e46578bb300bbStephen Gallagher ret = proxy_child_process_init(main_ctx, domain, main_ctx->event_ctx,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "Could not initialize proxy child [%d].\n", ret);
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "Proxy child for domain [%s] started!\n", domain);
10afbe39cb81a1810dba486c4b8e46578bb300bbStephen Gallagher /* loop on main */