/*
SSSD
IPA Subdomains Module - server mode
Authors:
Sumit Bose <sbose@redhat.com>
Copyright (C) 2015 Red Hat
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 "providers/ldap/sdap_async.h"
#include "providers/ldap/sdap_idmap.h"
#include "providers/ipa/ipa_subdomains.h"
#include "providers/ipa/ipa_common.h"
/* These constants are defined in MS-ADTS 6.1.6.7.1
*/
{
return talloc_asprintf(mem_ctx,
}
const char *forest_realm,
struct sss_domain_info *sd)
{
return NULL;
}
}
struct ldb_context *ldb_ctx,
struct sysdb_attrs *attrs)
{
/* Shouldn't happen, but let's try system keytab in this case */
"Cannot determine subdomain DN, falling back to two-way trust\n");
}
if (ipa_subdom_is_member_dom(dn) == true) {
/* It's expected member domains do not have the direction */
direction = 0;
} else {
/* Old server? Default to 2way trust */
}
return direction;
}
struct ldb_context *ldb_ctx,
{
int ret;
/* Just store the AD value in SYSDB, we will check it while we're
* trying to use the trust */
} else {
return ret;
}
*_direction = direction;
return EOK;
}
{
&& (direction & LSA_TRUST_DIRECTION_INBOUND)) {
return "two-way trust";
} else if (direction & LSA_TRUST_DIRECTION_OUTBOUND) {
return "one-way outbound: local domain is trusted by remote domain";
} else if (direction & LSA_TRUST_DIRECTION_INBOUND) {
return "one-way inbound: local domain trusts the remote domain";
} else if (direction == 0) {
return "not set";
}
return "unknown";
}
#ifndef IPA_GETKEYTAB_TIMEOUT
#endif /* IPA_GETKEYTAB_TIMEOUT */
static struct ad_options *
const char *forest,
const char *forest_realm,
struct sss_domain_info *subdom)
{
char *keytab;
char *principal;
const char *ad_domain;
return NULL;
}
if (ad_options == NULL) {
return NULL;
}
return ad_options;
}
struct sss_domain_info *subdom)
{
const char *forest;
const char *forest_realm;
/* Trusts are only established with forest roots */
if (direction & LSA_TRUST_DIRECTION_OUTBOUND) {
NULL);
} else if (direction & LSA_TRUST_DIRECTION_INBOUND) {
} else {
ad_options = NULL;
}
if (ad_options == NULL) {
return NULL;
}
return ad_options;
}
static errno_t
struct ipa_id_ctx *id_ctx,
struct sss_domain_info *subdom,
struct ad_id_ctx **_ad_id_ctx)
{
const char *gc_service_name;
const char *service_name;
const char *ad_domain;
const char *ad_site_override;
const char *extra_attrs;
if (ad_options == NULL) {
return ENOMEM;
}
if (extra_attrs != NULL) {
"Setting extra attrs for subdomain [%s] to [%s].\n", ad_domain,
return ret;
}
return ret;
}
} else {
}
if (gc_service_name == NULL) {
return ENOMEM;
}
if (service_name == NULL) {
return ENOMEM;
}
/* Set KRB5 realm to same as the one of IPA when IPA
* is able to attach PAC. For testing, use hardcoded. */
return ret;
}
return ENOMEM;
}
/* use AD plugin */
return ENOMEM;
}
return ret;
}
return EFAULT;
}
sdom,
return ret;
}
/* Set up the ID mapping object */
*_ad_id_ctx = ad_id_ctx;
return EOK;
}
struct ipa_getkeytab_state {
int child_status;
};
static void ipa_getkeytab_exec(const char *ccache,
const char *server,
const char *principal,
const char *keytab_path);
static void ipa_getkeytab_done(int child_status,
struct tevent_signal *sige,
void *pvt);
struct tevent_timer *te,
struct tevent_context *ev,
const char *ccache,
const char *server,
const char *principal,
const char *keytab)
{
return NULL;
}
goto done;
}
"Retrieving keytab for %s from %s into %s using ccache %s\n",
if (child_pid == 0) { /* child */
} else if (child_pid > 0) { /* parent */
/* Set up SIGCHLD handler */
goto done;
}
/* Set up timeout handler */
goto done;
}
/* Now either wait for the timeout to fire or the child
* to finish
*/
} else { /* error */
goto done;
}
done:
}
return req;
}
const char *server,
const char *principal,
const char *keytab_path)
{
int debug_fd;
if (debug_level >= SSSDBG_TRACE_LIBS) {
if (ret == -1) {
/* stderr is not fatal */
}
}
exit(1);
}
/* ipa-getkeytab cannot add keys to an empty file, let's unlink it and only
* use the filename */
if (ret == -1) {
"Failed to unlink the temporary ccname [%d][%s]\n",
exit(1);
}
errno = 0;
gkt_env);
"execle returned %d, this shouldn't happen!\n", ret);
/* The child should never end up here */
exit(1);
}
struct tevent_signal *sige,
void *pvt)
{
"ipa-getkeytab failed with status [%d]\n", child_status);
return;
}
if (WIFSIGNALED(child_status)) {
"ipa-getkeytab was terminated by signal [%d]\n",
return;
}
}
struct tevent_timer *te,
{
}
{
if (child_status) {
}
return EOK;
}
{
goto done;
if (kt_owner_uid) {
}
} else {
}
}
goto done;
}
done:
return ret;
}
struct ipa_server_trusted_dom_setup_state {
const char *forest;
const char *keytab;
char *new_keytab;
const char *principal;
const char *forest_realm;
const char *ccache;
};
struct tevent_req *
struct tevent_context *ev,
struct ipa_id_ctx *id_ctx,
struct sss_domain_info *subdom)
{
struct ipa_server_trusted_dom_setup_state);
return NULL;
}
/* Trusts are only established with forest roots */
goto immediate;
}
goto immediate;
}
"Trust direction of subdom %s from forest %s is: %s\n",
/* Use system keytab, nothing to do here */
goto immediate;
/* Need special keytab */
/* In progress.. */
return req;
/* Keytab available, shortcut */
goto immediate;
}
} else {
/* Even unset is an error at this point */
"Subdomain %s has trust direction %d\n",
}
"Could not add trusted subdomain %s from forest %s\n",
} else {
}
return req;
}
{
const char *hostname;
return EIO;
}
return ENOMEM;
}
return ret;
}
return EIO;
}
state->new_keytab);
return ENOMEM;
}
return EAGAIN;
}
{
struct tevent_req);
/* Do not fail here, but try to check and use the previous keytab,
* if any */
} else {
}
if (ret == -1) {
return;
}
"Trying to recover and use the previous keytab, if available\n");
"The previous keytab %s contains the expected principal\n",
} else {
"Cannot use the old keytab: %d\n", ret);
/* Nothing we can do now */
return;
}
}
}
{
return EOK;
}
struct ipa_server_create_trusts_state {
};
struct tevent_req *
struct tevent_context *ev,
struct ipa_id_ctx *id_ctx,
struct sss_domain_info *parent)
{
struct ipa_server_create_trusts_state);
return NULL;
}
goto immediate;
}
return req;
} else {
}
return req;
}
{
/* Check if we already have an ID context for this subdomain */
break;
}
}
/* Newly detected trust */
if (trust_iter == NULL) {
return ENOMEM;
}
return EAGAIN;
}
}
return EOK;
}
{
struct tevent_req);
return;
}
return;
}
return;
return;
}
/* Will cycle back */
}
{
return ret;
}
return ENOMEM;
}
return EOK;
}
{
return EOK;
}
struct ipa_id_ctx *id_ctx,
struct sss_domain_info *subdom)
{
IPA_SERVER_MODE) == false) {
return;
}
}
return;
}
/* terminate all requests for this subdomain so we can free it */
}
struct ipa_ad_subdom_reinit_state {
};
{
"ipa_server_create_trusts_send request failed [%d]: %s\n",
}
}
struct tevent_immediate *imm,
void *pvt)
{
return;
}
return;
}
struct tevent_context *ev,
struct ipa_id_ctx *id_ctx,
struct sss_domain_info *parent)
{
return ENOMEM;
}
IPA_SERVER_MODE) == false) {
return EOK;
}
return ENOMEM;
}
return EOK;
}
struct ipa_id_ctx *id_ctx)
{
char *realm;
char *hostname;
IPA_SERVER_MODE) == false) {
return EOK;
}
/* The IPA code relies on the default FQDN format to unparse user
* names. Warn loudly if the full_name_format was customized on the
* IPA server
*/
CONFDB_DEFAULT_FULL_NAME_FORMAT_INTERNAL) != 0)) {
"lookups of subdomain users will likely fail!\n",
"lookups of subdomain users will likely fail!\n",
/* Attempt to continue */
}
return EINVAL;
}
return EINVAL;
}
return ENOMEM;
}
if (getuid() == 0) {
/* We need to handle keytabs created by IPA oddjob script gracefully
* even if we're running as root and IPA creates them as the SSSD user
*/
}
}
return ret;
}
return EOK;
}