diff --git a/0001-AD-read-flat-name-and-SID-of-the-AD-domain.patch b/0001-AD-read-flat-name-and-SID-of-the-AD-domain.patch deleted file mode 100644 index c866125..0000000 --- a/0001-AD-read-flat-name-and-SID-of-the-AD-domain.patch +++ /dev/null @@ -1,702 +0,0 @@ -From 4cdaf239d4504966bed8ecd5e3fa07def74c7302 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Thu, 2 May 2013 20:28:30 +0200 -Subject: [PATCH 1/6] AD: read flat name and SID of the AD domain - -For various features either the flat/short/NetBIOS domain name or the -domain SID is needed. Since the responders already try to do a subdomain -lookup when and known domain name is encountered I added a subdomain -lookup to the AD provider which currently only reads the SID from the -base DN and the NetBIOS name from a reply of a LDAP ping. The results -are written to the cache to have them available even if SSSD is started -in offline mode. Looking up trusted domains can be added later. - -Since all the needed responder code is already available from the -corresponding work for the IPA provider this patch fixes - -https://fedorahosted.org/sssd/ticket/1468 ---- - Makefile.am | 2 + - src/config/etc/sssd.api.d/sssd-ad.conf | 2 + - src/man/sssd-ad.5.xml | 4 + - src/man/sssd.conf.5.xml | 4 + - src/providers/ad/ad_init.c | 31 ++ - src/providers/ad/ad_subdomains.c | 522 +++++++++++++++++++++++++++++++++ - src/providers/ad/ad_subdomains.h | 37 +++ - 7 files changed, 602 insertions(+) - create mode 100644 src/providers/ad/ad_subdomains.c - create mode 100644 src/providers/ad/ad_subdomains.h - -diff --git a/Makefile.am b/Makefile.am -index 3abea76c18f49df623ff9c38ebc5d604596d2516..b72384a77fe5bb3d2d40229026c463fefabc1387 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -1621,6 +1621,8 @@ libsss_ad_la_SOURCES = \ - src/providers/ad/ad_access.h \ - src/providers/ad/ad_opts.h \ - src/providers/ad/ad_srv.c \ -+ src/providers/ad/ad_subdomains.c \ -+ src/providers/ad/ad_subdomains.h \ - src/util/find_uid.c \ - src/util/user_info_msg.c \ - src/util/sss_krb5.c \ -diff --git a/src/config/etc/sssd.api.d/sssd-ad.conf b/src/config/etc/sssd.api.d/sssd-ad.conf -index b4b1d0ba11d600a8b9a300f15cc8058be470f422..3be25e8da05ee6b1bbdb947e919421358591cdde 100644 ---- a/src/config/etc/sssd.api.d/sssd-ad.conf -+++ b/src/config/etc/sssd.api.d/sssd-ad.conf -@@ -126,3 +126,5 @@ krb5_use_enterprise_principal = bool, None, false - [provider/ad/chpass] - krb5_kpasswd = str, None, false - krb5_backup_kpasswd = str, None, false -+ -+[provider/ad/subdomains] -diff --git a/src/man/sssd-ad.5.xml b/src/man/sssd-ad.5.xml -index c19607715dafd39f167c3066831ae7ad09ffe459..4dcd552d7f1fe3235af9c582c49c553441a014e9 100644 ---- a/src/man/sssd-ad.5.xml -+++ b/src/man/sssd-ad.5.xml -@@ -95,6 +95,10 @@ ldap_id_mapping = False - specified as the lower-case version of the long - version of the Active Directory domain. - -+ -+ The short domain name (also known as the NetBIOS -+ or the flat name) is autodetected by the SSSD. -+ - - - -diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml -index 04c699948b093c235762c0d9f8223911a6fd2ada..99337fbba9fb8d39a62eb84313c5b89761ee950d 100644 ---- a/src/man/sssd.conf.5.xml -+++ b/src/man/sssd.conf.5.xml -@@ -1481,6 +1481,10 @@ override_homedir = /home/%u - Regular expression for this domain that describes - how to parse the string containing user name and - domain into these components. -+ The "domain" can match either the SSSD -+ configuration domain name, or, in the case -+ of IPA trust subdomains and Active Directory -+ domains, the flat (NetBIOS) name of the domain. - - - Default for the AD and IPA provider: -diff --git a/src/providers/ad/ad_init.c b/src/providers/ad/ad_init.c -index 2f5a5da1510b0241a4bee12fc93da174fdd0d116..f90df2a6913222b023704e9e1d1dce9561772e98 100644 ---- a/src/providers/ad/ad_init.c -+++ b/src/providers/ad/ad_init.c -@@ -37,6 +37,7 @@ - #include "providers/ad/ad_id.h" - #include "providers/ad/ad_srv.h" - #include "providers/dp_dyndns.h" -+#include "providers/ad/ad_subdomains.h" - - struct ad_options *ad_options = NULL; - -@@ -361,3 +362,33 @@ ad_shutdown(struct be_req *req) - /* TODO: Clean up any internal data */ - sdap_handler_done(req, DP_ERR_OK, EOK, NULL); - } -+ -+int sssm_ad_subdomains_init(struct be_ctx *bectx, -+ struct bet_ops **ops, -+ void **pvt_data) -+{ -+ int ret; -+ struct ad_id_ctx *id_ctx; -+ const char *ad_domain; -+ -+ ret = sssm_ad_id_init(bectx, ops, (void **) &id_ctx); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_CRIT_FAILURE, ("sssm_ad_id_init failed.\n")); -+ return ret; -+ } -+ -+ if (ad_options == NULL) { -+ DEBUG(SSSDBG_CRIT_FAILURE, ("Global AD options not available.\n")); -+ return EINVAL; -+ } -+ -+ ad_domain = dp_opt_get_string(ad_options->basic, AD_DOMAIN); -+ -+ ret = ad_subdom_init(bectx, id_ctx, ad_domain, ops, pvt_data); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_CRIT_FAILURE, ("ad_subdom_init failed.\n")); -+ return ret; -+ } -+ -+ return EOK; -+} -diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c -new file mode 100644 -index 0000000000000000000000000000000000000000..1da343f8711b2b99a7afff6a4a398a1aa515a875 ---- /dev/null -+++ b/src/providers/ad/ad_subdomains.c -@@ -0,0 +1,522 @@ -+/* -+ SSSD -+ -+ AD Subdomains Module -+ -+ Authors: -+ Sumit Bose -+ -+ Copyright (C) 2013 Red Hat -+ -+ This program is free software; you can redistribute it and/or modify -+ 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 . -+*/ -+ -+#include "providers/ldap/sdap_async.h" -+#include "providers/ad/ad_subdomains.h" -+#include -+#include -+#include -+ -+#define AD_AT_OBJECT_SID "objectSID" -+#define AD_AT_DNS_DOMAIN "DnsDomain" -+#define AD_AT_NT_VERSION "NtVer" -+#define AD_AT_NETLOGON "netlogon" -+ -+#define MASTER_DOMAIN_SID_FILTER "objectclass=domain" -+ -+/* do not refresh more often than every 5 seconds for now */ -+#define AD_SUBDOMAIN_REFRESH_LIMIT 5 -+ -+/* refresh automatically every 4 hours */ -+#define AD_SUBDOMAIN_REFRESH_PERIOD (3600 * 4) -+ -+struct ad_subdomains_ctx { -+ struct be_ctx *be_ctx; -+ struct sdap_id_ctx *sdap_id_ctx; -+ struct sss_idmap_ctx *idmap_ctx; -+ char *domain_name; -+ -+ time_t last_refreshed; -+ struct tevent_timer *timer_event; -+}; -+ -+struct ad_subdomains_req_ctx { -+ struct be_req *be_req; -+ struct ad_subdomains_ctx *sd_ctx; -+ struct sdap_id_op *sdap_op; -+ -+ char *current_filter; -+ size_t base_iter; -+ -+ size_t reply_count; -+ struct sysdb_attrs **reply; -+ -+ char *master_sid; -+ char *flat_name; -+}; -+ -+static void ad_subdomains_get_conn_done(struct tevent_req *req); -+static errno_t ad_subdomains_get_master_sid(struct ad_subdomains_req_ctx *ctx); -+static void ad_subdomains_get_master_sid_done(struct tevent_req *req); -+static void ad_subdomains_get_netlogon_done(struct tevent_req *req); -+ -+static void ad_subdomains_retrieve(struct ad_subdomains_ctx *ctx, -+ struct be_req *be_req) -+{ -+ struct ad_subdomains_req_ctx *req_ctx = NULL; -+ struct tevent_req *req; -+ int dp_error = DP_ERR_FATAL; -+ int ret; -+ -+ req_ctx = talloc(be_req, struct ad_subdomains_req_ctx); -+ if (req_ctx == NULL) { -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ req_ctx->be_req = be_req; -+ req_ctx->sd_ctx = ctx; -+ req_ctx->current_filter = NULL; -+ req_ctx->base_iter = 0; -+ req_ctx->reply_count = 0; -+ req_ctx->reply = NULL; -+ -+ req_ctx->sdap_op = sdap_id_op_create(req_ctx, -+ ctx->sdap_id_ctx->conn_cache); -+ if (req_ctx->sdap_op == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, ("sdap_id_op_create failed.\n")); -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ req = sdap_id_op_connect_send(req_ctx->sdap_op, req_ctx, &ret); -+ if (req == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, ("sdap_id_op_connect_send failed: %d(%s).\n", -+ ret, strerror(ret))); -+ goto done; -+ } -+ -+ tevent_req_set_callback(req, ad_subdomains_get_conn_done, req_ctx); -+ -+ return; -+ -+done: -+ talloc_free(req_ctx); -+ if (ret == EOK) { -+ dp_error = DP_ERR_OK; -+ } -+ be_req_terminate(be_req, dp_error, ret, NULL); -+} -+ -+static void ad_subdomains_get_conn_done(struct tevent_req *req) -+{ -+ int ret; -+ int dp_error = DP_ERR_FATAL; -+ struct ad_subdomains_req_ctx *ctx; -+ -+ ctx = tevent_req_callback_data(req, struct ad_subdomains_req_ctx); -+ -+ ret = sdap_id_op_connect_recv(req, &dp_error); -+ talloc_zfree(req); -+ if (ret) { -+ if (dp_error == DP_ERR_OFFLINE) { -+ DEBUG(SSSDBG_MINOR_FAILURE, -+ ("No AD server is available, cannot get the " -+ "subdomain list while offline\n")); -+ } else { -+ DEBUG(SSSDBG_OP_FAILURE, -+ ("Failed to connect to AD server: [%d](%s)\n", -+ ret, strerror(ret))); -+ } -+ -+ goto fail; -+ } -+ -+ ret = ad_subdomains_get_master_sid(ctx); -+ if (ret == EAGAIN) { -+ return; -+ } else if (ret != EOK) { -+ goto fail; -+ } -+ -+ DEBUG(SSSDBG_OP_FAILURE, ("No search base available.\n")); -+ ret = EINVAL; -+ -+fail: -+ be_req_terminate(ctx->be_req, dp_error, ret, NULL); -+} -+ -+static errno_t ad_subdomains_get_master_sid(struct ad_subdomains_req_ctx *ctx) -+{ -+ struct tevent_req *req; -+ struct sdap_search_base *base; -+ const char *master_sid_attrs[] = {AD_AT_OBJECT_SID, NULL}; -+ -+ -+ base = ctx->sd_ctx->sdap_id_ctx->opts->search_bases[ctx->base_iter]; -+ if (base == NULL) { -+ return EOK; -+ } -+ -+ req = sdap_get_generic_send(ctx, ctx->sd_ctx->be_ctx->ev, -+ ctx->sd_ctx->sdap_id_ctx->opts, -+ sdap_id_op_handle(ctx->sdap_op), -+ base->basedn, LDAP_SCOPE_BASE, -+ MASTER_DOMAIN_SID_FILTER, master_sid_attrs, -+ NULL, 0, -+ dp_opt_get_int(ctx->sd_ctx->sdap_id_ctx->opts->basic, -+ SDAP_SEARCH_TIMEOUT), -+ false); -+ -+ if (req == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, ("sdap_get_generic_send failed.\n")); -+ return ENOMEM; -+ } -+ -+ tevent_req_set_callback(req, ad_subdomains_get_master_sid_done, ctx); -+ -+ return EAGAIN; -+} -+ -+static void ad_subdomains_get_master_sid_done(struct tevent_req *req) -+{ -+ int ret; -+ size_t reply_count; -+ struct sysdb_attrs **reply = NULL; -+ struct ad_subdomains_req_ctx *ctx; -+ struct ldb_message_element *el; -+ char *sid_str; -+ enum idmap_error_code err; -+ static const char *attrs[] = {AD_AT_NETLOGON, NULL}; -+ char *filter; -+ char *ntver; -+ -+ ctx = tevent_req_callback_data(req, struct ad_subdomains_req_ctx); -+ -+ ret = sdap_get_generic_recv(req, ctx, &reply_count, &reply); -+ talloc_zfree(req); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, ("sdap_get_generic_send request failed.\n")); -+ goto done; -+ } -+ -+ if (reply_count == 0) { -+ ctx->base_iter++; -+ ret = ad_subdomains_get_master_sid(ctx); -+ if (ret == EAGAIN) { -+ return; -+ } else if (ret != EOK) { -+ goto done; -+ } -+ } else if (reply_count == 1) { -+ ret = sysdb_attrs_get_el(reply[0], AD_AT_OBJECT_SID, &el); -+ if (ret != EOK || el->num_values != 1) { -+ DEBUG(SSSDBG_OP_FAILURE, ("sdap_attrs_get_el failed.\n")); -+ goto done; -+ } -+ -+ err = sss_idmap_bin_sid_to_sid(ctx->sd_ctx->idmap_ctx, -+ el->values[0].data, -+ el->values[0].length, -+ &sid_str); -+ if (err != IDMAP_SUCCESS) { -+ DEBUG(SSSDBG_MINOR_FAILURE, -+ ("Could not convert SID: [%s].\n", idmap_error_string(err))); -+ ret = EFAULT; -+ goto done; -+ } -+ -+ ctx->master_sid = talloc_steal(ctx, sid_str); -+ } else { -+ DEBUG(SSSDBG_OP_FAILURE, -+ ("More than one result for domain SID found.\n")); -+ ret = EINVAL; -+ goto done; -+ } -+ -+ DEBUG(SSSDBG_TRACE_FUNC, ("Found SID [%s].\n", ctx->master_sid)); -+ -+ ntver = sss_ldap_encode_ndr_uint32(ctx, NETLOGON_NT_VERSION_5EX | -+ NETLOGON_NT_VERSION_WITH_CLOSEST_SITE); -+ if (ntver == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, ("sss_ldap_encode_ndr_uint32 failed.\n")); -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ filter = talloc_asprintf(ctx, "(&(%s=%s)(%s=%s))", -+ AD_AT_DNS_DOMAIN, ctx->sd_ctx->domain_name, -+ AD_AT_NT_VERSION, ntver); -+ if (filter == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, ("talloc_asprintf failed.\n")); -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ req = sdap_get_generic_send(ctx, ctx->sd_ctx->be_ctx->ev, -+ ctx->sd_ctx->sdap_id_ctx->opts, -+ sdap_id_op_handle(ctx->sdap_op), -+ "", LDAP_SCOPE_BASE, filter, attrs, NULL, 0, -+ dp_opt_get_int(ctx->sd_ctx->sdap_id_ctx->opts->basic, -+ SDAP_SEARCH_TIMEOUT), -+ false); -+ if (req == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, ("sdap_get_generic_send failed.\n")); -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ tevent_req_set_callback(req, ad_subdomains_get_netlogon_done, ctx); -+ return; -+ -+done: -+ be_req_terminate(ctx->be_req, DP_ERR_FATAL, ret, NULL); -+} -+ -+static void ad_subdomains_get_netlogon_done(struct tevent_req *req) -+{ -+ int ret; -+ size_t reply_count; -+ struct sysdb_attrs **reply = NULL; -+ struct ad_subdomains_req_ctx *ctx; -+ struct ldb_message_element *el; -+ DATA_BLOB blob; -+ enum ndr_err_code ndr_err; -+ struct ndr_pull *ndr_pull = NULL; -+ struct netlogon_samlogon_response response; -+ -+ ctx = tevent_req_callback_data(req, struct ad_subdomains_req_ctx); -+ -+ ret = sdap_get_generic_recv(req, ctx, &reply_count, &reply); -+ talloc_zfree(req); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, ("sdap_get_generic_send request failed.\n")); -+ goto done; -+ } -+ -+ if (reply_count == 0) { -+ DEBUG(SSSDBG_TRACE_FUNC, ("No netlogon data available.\n")); -+ } else if (reply_count > 1) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ ("More than one netlogon info returned.\n")); -+ ret = EINVAL; -+ goto done; -+ } -+ -+ ret = sysdb_attrs_get_el(reply[0], AD_AT_NETLOGON, &el); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, ("sysdb_attrs_get_el() failed\n")); -+ goto done; -+ } -+ -+ if (el->num_values == 0) { -+ DEBUG(SSSDBG_OP_FAILURE, ("netlogon has no value\n")); -+ ret = ENOENT; -+ goto done; -+ } else if (el->num_values > 1) { -+ DEBUG(SSSDBG_OP_FAILURE, ("More than one netlogon value?\n")); -+ ret = EIO; -+ goto done; -+ } -+ -+ blob.data = el->values[0].data; -+ blob.length = el->values[0].length; -+ -+ ndr_pull = ndr_pull_init_blob(&blob, ctx); -+ if (ndr_pull == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, ("ndr_pull_init_blob() failed.\n")); -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ ndr_err = ndr_pull_netlogon_samlogon_response(ndr_pull, NDR_SCALARS, -+ &response); -+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { -+ DEBUG(SSSDBG_OP_FAILURE, ("ndr_pull_netlogon_samlogon_response() " -+ "failed [%d]\n", ndr_err)); -+ ret = EBADMSG; -+ goto done; -+ } -+ -+ if (!(response.ntver & NETLOGON_NT_VERSION_5EX)) { -+ DEBUG(SSSDBG_OP_FAILURE, ("Wrong version returned [%x]\n", -+ response.ntver)); -+ ret = EBADMSG; -+ goto done; -+ } -+ -+ if (response.data.nt5_ex.domain_name != NULL && -+ *response.data.nt5_ex.domain_name != '\0') { -+ ctx->flat_name = talloc_strdup(ctx, response.data.nt5_ex.domain_name); -+ if (ctx->flat_name == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, ("talloc_strdup failed.\n")); -+ ret = ENOMEM; -+ goto done; -+ } -+ } -+ -+ DEBUG(SSSDBG_TRACE_FUNC, ("Found flat name [%s].\n", ctx->flat_name)); -+ -+ ret = sysdb_master_domain_add_info(ctx->sd_ctx->be_ctx->domain, -+ NULL, ctx->flat_name, ctx->master_sid); -+ -+ ret = EOK; -+ -+done: -+ -+ if (ret == EOK) { -+ ctx->sd_ctx->last_refreshed = time(NULL); -+ } -+ be_req_terminate(ctx->be_req, DP_ERR_FATAL, ret, NULL); -+} -+ -+static void ad_subdom_online_cb(void *pvt); -+ -+static void ad_subdom_timer_refresh(struct tevent_context *ev, -+ struct tevent_timer *te, -+ struct timeval current_time, -+ void *pvt) -+{ -+ ad_subdom_online_cb(pvt); -+} -+ -+static void ad_subdom_be_req_callback(struct be_req *be_req, -+ int dp_err, int dp_ret, -+ const char *errstr) -+{ -+ talloc_free(be_req); -+} -+ -+static void ad_subdom_online_cb(void *pvt) -+{ -+ struct ad_subdomains_ctx *ctx; -+ struct be_req *be_req; -+ struct timeval tv; -+ -+ ctx = talloc_get_type(pvt, struct ad_subdomains_ctx); -+ if (!ctx) { -+ DEBUG(SSSDBG_CRIT_FAILURE, ("Bad private pointer\n")); -+ return; -+ } -+ -+ be_req = be_req_create(ctx, NULL, ctx->be_ctx, -+ ad_subdom_be_req_callback, NULL); -+ if (be_req == NULL) { -+ DEBUG(SSSDBG_CRIT_FAILURE, ("be_req_create() failed.\n")); -+ return; -+ } -+ -+ ad_subdomains_retrieve(ctx, be_req); -+ -+ tv = tevent_timeval_current_ofs(AD_SUBDOMAIN_REFRESH_PERIOD, 0); -+ ctx->timer_event = tevent_add_timer(ctx->be_ctx->ev, ctx, tv, -+ ad_subdom_timer_refresh, ctx); -+ if (!ctx->timer_event) { -+ DEBUG(SSSDBG_MINOR_FAILURE, ("Failed to add subdom timer event\n")); -+ } -+} -+ -+static void ad_subdom_offline_cb(void *pvt) -+{ -+ struct ad_subdomains_ctx *ctx; -+ -+ ctx = talloc_get_type(pvt, struct ad_subdomains_ctx); -+ -+ if (ctx) { -+ talloc_zfree(ctx->timer_event); -+ } -+} -+ -+void ad_subdomains_handler(struct be_req *be_req) -+{ -+ struct be_ctx *be_ctx = be_req_get_be_ctx(be_req); -+ struct ad_subdomains_ctx *ctx; -+ time_t now; -+ -+ ctx = talloc_get_type(be_ctx->bet_info[BET_SUBDOMAINS].pvt_bet_data, -+ struct ad_subdomains_ctx); -+ if (!ctx) { -+ be_req_terminate(be_req, DP_ERR_FATAL, EINVAL, NULL); -+ return; -+ } -+ -+ now = time(NULL); -+ -+ if (ctx->last_refreshed > now - AD_SUBDOMAIN_REFRESH_LIMIT) { -+ be_req_terminate(be_req, DP_ERR_OK, EOK, NULL); -+ return; -+ } -+ -+ ad_subdomains_retrieve(ctx, be_req); -+} -+ -+struct bet_ops ad_subdomains_ops = { -+ .handler = ad_subdomains_handler, -+ .finalize = NULL -+}; -+ -+static void *idmap_talloc(size_t size, void *pvt) -+{ -+ return talloc_size(pvt, size); -+} -+ -+static void idmap_free(void *ptr, void *pvt) -+{ -+ talloc_free(ptr); -+} -+ -+int ad_subdom_init(struct be_ctx *be_ctx, -+ struct ad_id_ctx *id_ctx, -+ const char *ad_domain, -+ struct bet_ops **ops, -+ void **pvt_data) -+{ -+ struct ad_subdomains_ctx *ctx; -+ int ret; -+ enum idmap_error_code err; -+ -+ ctx = talloc_zero(id_ctx, struct ad_subdomains_ctx); -+ if (ctx == NULL) { -+ DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_zero failed.\n")); -+ return ENOMEM; -+ } -+ -+ ctx->be_ctx = be_ctx; -+ ctx->sdap_id_ctx = id_ctx->sdap_id_ctx; -+ ctx->domain_name = talloc_strdup(ctx, ad_domain); -+ if (ctx->domain_name == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, ("talloc_strdup failed.\n")); -+ return ENOMEM; -+ } -+ *ops = &ad_subdomains_ops; -+ *pvt_data = ctx; -+ -+ ret = be_add_online_cb(ctx, be_ctx, ad_subdom_online_cb, ctx, NULL); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_MINOR_FAILURE, ("Failed to add subdom online callback")); -+ } -+ -+ ret = be_add_offline_cb(ctx, be_ctx, ad_subdom_offline_cb, ctx, NULL); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_MINOR_FAILURE, ("Failed to add subdom offline callback")); -+ } -+ -+ err = sss_idmap_init(idmap_talloc, ctx, idmap_free, &ctx->idmap_ctx); -+ if (err != IDMAP_SUCCESS) { -+ DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to initialize idmap context.\n")); -+ return EFAULT; -+ } -+ -+ return EOK; -+} -diff --git a/src/providers/ad/ad_subdomains.h b/src/providers/ad/ad_subdomains.h -new file mode 100644 -index 0000000000000000000000000000000000000000..b1a418f132595c10abd8448f78a5df62402314a8 ---- /dev/null -+++ b/src/providers/ad/ad_subdomains.h -@@ -0,0 +1,37 @@ -+/* -+ SSSD -+ -+ AD Subdomains Module -+ -+ Authors: -+ Sumit Bose -+ -+ Copyright (C) 2013 Red Hat -+ -+ This program is free software; you can redistribute it and/or modify -+ 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 . -+*/ -+ -+#ifndef _IPA_SUBDOMAINS_H_ -+#define _IPA_SUBDOMAINS_H_ -+ -+#include "providers/dp_backend.h" -+#include "providers/ad/ad_common.h" -+ -+int ad_subdom_init(struct be_ctx *be_ctx, -+ struct ad_id_ctx *id_ctx, -+ const char *ad_domain, -+ struct bet_ops **ops, -+ void **pvt_data); -+ -+#endif /* _IPA_SUBDOMAINS_H_ */ --- -1.8.2.1 - diff --git a/0002-Actually-use-the-index-parameter-in-resolv_get_socka.patch b/0002-Actually-use-the-index-parameter-in-resolv_get_socka.patch deleted file mode 100644 index c0d4494..0000000 --- a/0002-Actually-use-the-index-parameter-in-resolv_get_socka.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 7c091610f5b35e8ba89da839322f6591f1e7619b Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Mon, 6 May 2013 15:10:22 +0200 -Subject: [PATCH 2/6] Actually use the index parameter in - resolv_get_sockaddr_address_index - ---- - src/resolv/async_resolv.c | 11 +++++++---- - src/resolv/async_resolv.h | 5 +++-- - 2 files changed, 10 insertions(+), 6 deletions(-) - -diff --git a/src/resolv/async_resolv.c b/src/resolv/async_resolv.c -index 1eb0acf83cb5bb48d92a58b8baf872f4ca4d8278..ad9d58297d0701e2a48ef86179c93c71320654fb 100644 ---- a/src/resolv/async_resolv.c -+++ b/src/resolv/async_resolv.c -@@ -1453,8 +1453,9 @@ resolv_get_string_ptr_address(TALLOC_CTX *mem_ctx, - } - - struct sockaddr_storage * --resolv_get_sockaddr_address_index(TALLOC_CTX *mem_ctx, struct resolv_hostent *hostent, -- int port, int index) -+resolv_get_sockaddr_address_index(TALLOC_CTX *mem_ctx, -+ struct resolv_hostent *hostent, -+ int port, int addrindex) - { - struct sockaddr_storage *sockaddr; - -@@ -1470,14 +1471,16 @@ resolv_get_sockaddr_address_index(TALLOC_CTX *mem_ctx, struct resolv_hostent *ho - case AF_INET: - sockaddr->ss_family = AF_INET; - memcpy(&((struct sockaddr_in *) sockaddr)->sin_addr, -- hostent->addr_list[0]->ipaddr, sizeof(struct in_addr)); -+ hostent->addr_list[addrindex]->ipaddr, -+ sizeof(struct in_addr)); - ((struct sockaddr_in *) sockaddr)->sin_port = (in_port_t) htons(port); - - break; - case AF_INET6: - sockaddr->ss_family = AF_INET6; - memcpy(&((struct sockaddr_in6 *) sockaddr)->sin6_addr, -- hostent->addr_list[0]->ipaddr, sizeof(struct in6_addr)); -+ hostent->addr_list[addrindex]->ipaddr, -+ sizeof(struct in6_addr)); - ((struct sockaddr_in6 *) sockaddr)->sin6_port = (in_port_t) htons(port); - break; - default: -diff --git a/src/resolv/async_resolv.h b/src/resolv/async_resolv.h -index 9bf5e0c40e44c385858fa4d85adebe6e022ca006..a8207884c79d7a12af2bc1fc9da9c1304b2c252d 100644 ---- a/src/resolv/async_resolv.h -+++ b/src/resolv/async_resolv.h -@@ -129,8 +129,9 @@ resolv_get_string_ptr_address(TALLOC_CTX *mem_ctx, - resolv_get_string_address_index(mem_ctx, hostent, 0) - - struct sockaddr_storage * --resolv_get_sockaddr_address_index(TALLOC_CTX *mem_ctx, struct resolv_hostent *hostent, -- int port, int index); -+resolv_get_sockaddr_address_index(TALLOC_CTX *mem_ctx, -+ struct resolv_hostent *hostent, -+ int port, int addrindex); - - #define resolv_get_sockaddr_address(mem_ctx, rhostent, port) \ - resolv_get_sockaddr_address_index(mem_ctx, rhostent, port, 0) --- -1.8.2.1 - diff --git a/0003-UTIL-Add-function-sss_names_init_from_args.patch b/0003-UTIL-Add-function-sss_names_init_from_args.patch deleted file mode 100644 index d250c91..0000000 --- a/0003-UTIL-Add-function-sss_names_init_from_args.patch +++ /dev/null @@ -1,205 +0,0 @@ -From f54b271376b23cb968eafb9ffd5100c6dadad2a7 Mon Sep 17 00:00:00 2001 -From: Jan Cholasta -Date: Fri, 26 Apr 2013 09:40:53 +0200 -Subject: [PATCH 3/6] UTIL: Add function sss_names_init_from_args - -This function allows initializing sss_names_ctx using a regular expression and -fully qualified format string specified in its arguments. ---- - src/util/usertools.c | 107 +++++++++++++++++++++++++++++++-------------------- - src/util/util.h | 7 ++++ - 2 files changed, 73 insertions(+), 41 deletions(-) - -diff --git a/src/util/usertools.c b/src/util/usertools.c -index 7323d9f8260580f32b4ab55c8c2db5bd7eec20ed..91110f263657de9ba53ed305e7c4710eb006bec6 100644 ---- a/src/util/usertools.c -+++ b/src/util/usertools.c -@@ -135,13 +135,11 @@ done: - #endif - } - --int sss_names_init(TALLOC_CTX *mem_ctx, struct confdb_ctx *cdb, -- const char *domain, struct sss_names_ctx **out) -+int sss_names_init_from_args(TALLOC_CTX *mem_ctx, const char *re_pattern, -+ const char *fq_fmt, struct sss_names_ctx **out) - { - struct sss_names_ctx *ctx; -- TALLOC_CTX *tmpctx = NULL; - const char *errstr; -- char *conf_path; - int errval; - int errpos; - int ret; -@@ -150,6 +148,49 @@ int sss_names_init(TALLOC_CTX *mem_ctx, struct confdb_ctx *cdb, - if (!ctx) return ENOMEM; - talloc_set_destructor(ctx, sss_names_ctx_destructor); - -+ ctx->re_pattern = talloc_strdup(ctx, re_pattern); -+ if (ctx->re_pattern == NULL) { -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ DEBUG(SSSDBG_CONF_SETTINGS, ("Using re [%s].\n", ctx->re_pattern)); -+ -+ ctx->fq_fmt = talloc_strdup(ctx, fq_fmt); -+ if (ctx->fq_fmt == NULL) { -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ ctx->re = pcre_compile2(ctx->re_pattern, -+ NAME_DOMAIN_PATTERN_OPTIONS, -+ &errval, &errstr, &errpos, NULL); -+ if (!ctx->re) { -+ DEBUG(1, ("Invalid Regular Expression pattern at position %d." -+ " (Error: %d [%s])\n", errpos, errval, errstr)); -+ ret = EFAULT; -+ goto done; -+ } -+ -+ *out = ctx; -+ ret = EOK; -+ -+done: -+ if (ret != EOK) { -+ talloc_free(ctx); -+ } -+ return ret; -+} -+ -+int sss_names_init(TALLOC_CTX *mem_ctx, struct confdb_ctx *cdb, -+ const char *domain, struct sss_names_ctx **out) -+{ -+ TALLOC_CTX *tmpctx = NULL; -+ char *conf_path; -+ char *re_pattern; -+ char *fq_fmt; -+ int ret; -+ - tmpctx = talloc_new(NULL); - if (tmpctx == NULL) { - ret = ENOMEM; -@@ -162,19 +203,19 @@ int sss_names_init(TALLOC_CTX *mem_ctx, struct confdb_ctx *cdb, - goto done; - } - -- ret = confdb_get_string(cdb, ctx, conf_path, -- CONFDB_NAME_REGEX, NULL, &ctx->re_pattern); -+ ret = confdb_get_string(cdb, tmpctx, conf_path, -+ CONFDB_NAME_REGEX, NULL, &re_pattern); - if (ret != EOK) goto done; - - /* If not found in the domain, look in globals */ -- if (ctx->re_pattern == NULL) { -- ret = confdb_get_string(cdb, ctx, CONFDB_MONITOR_CONF_ENTRY, -- CONFDB_NAME_REGEX, NULL, &ctx->re_pattern); -+ if (re_pattern == NULL) { -+ ret = confdb_get_string(cdb, tmpctx, CONFDB_MONITOR_CONF_ENTRY, -+ CONFDB_NAME_REGEX, NULL, &re_pattern); - if (ret != EOK) goto done; - } - -- if (ctx->re_pattern == NULL) { -- ret = get_id_provider_default_re(ctx, cdb, conf_path, &ctx->re_pattern); -+ if (re_pattern == NULL) { -+ ret = get_id_provider_default_re(tmpctx, cdb, conf_path, &re_pattern); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, ("Failed to get provider default regular " \ - "expression for domain [%s].\n", domain)); -@@ -182,10 +223,10 @@ int sss_names_init(TALLOC_CTX *mem_ctx, struct confdb_ctx *cdb, - } - } - -- if (!ctx->re_pattern) { -- ctx->re_pattern = talloc_strdup(ctx, -- "(?P[^@]+)@?(?P[^@]*$)"); -- if (!ctx->re_pattern) { -+ if (!re_pattern) { -+ re_pattern = talloc_strdup(tmpctx, -+ "(?P[^@]+)@?(?P[^@]*$)"); -+ if (!re_pattern) { - ret = ENOMEM; - goto done; - } -@@ -195,49 +236,33 @@ int sss_names_init(TALLOC_CTX *mem_ctx, struct confdb_ctx *cdb, - "not support non-unique named subpatterns.\n")); - DEBUG(2, ("Please make sure that your pattern [%s] only contains " - "subpatterns with a unique name and uses " -- "the Python syntax (?P).\n", ctx->re_pattern)); -+ "the Python syntax (?P).\n", re_pattern)); - #endif - } - -- DEBUG(SSSDBG_CONF_SETTINGS, ("Using re [%s].\n", ctx->re_pattern)); -- -- ret = confdb_get_string(cdb, ctx, conf_path, -- CONFDB_FULL_NAME_FORMAT, NULL, &ctx->fq_fmt); -+ ret = confdb_get_string(cdb, tmpctx, conf_path, -+ CONFDB_FULL_NAME_FORMAT, NULL, &fq_fmt); - if (ret != EOK) goto done; - - /* If not found in the domain, look in globals */ -- if (ctx->fq_fmt == NULL) { -- ret = confdb_get_string(cdb, ctx, CONFDB_MONITOR_CONF_ENTRY, -- CONFDB_FULL_NAME_FORMAT, NULL, &ctx->fq_fmt); -+ if (fq_fmt == NULL) { -+ ret = confdb_get_string(cdb, tmpctx, CONFDB_MONITOR_CONF_ENTRY, -+ CONFDB_FULL_NAME_FORMAT, NULL, &fq_fmt); - if (ret != EOK) goto done; - } - -- if (!ctx->fq_fmt) { -- ctx->fq_fmt = talloc_strdup(ctx, "%1$s@%2$s"); -- if (!ctx->fq_fmt) { -+ if (!fq_fmt) { -+ fq_fmt = talloc_strdup(tmpctx, "%1$s@%2$s"); -+ if (!fq_fmt) { - ret = ENOMEM; - goto done; - } - } - -- ctx->re = pcre_compile2(ctx->re_pattern, -- NAME_DOMAIN_PATTERN_OPTIONS, -- &errval, &errstr, &errpos, NULL); -- if (!ctx->re) { -- DEBUG(1, ("Invalid Regular Expression pattern at position %d." -- " (Error: %d [%s])\n", errpos, errval, errstr)); -- ret = EFAULT; -- goto done; -- } -- -- *out = ctx; -- ret = EOK; -+ ret = sss_names_init_from_args(mem_ctx, re_pattern, fq_fmt, out); - - done: - talloc_free(tmpctx); -- if (ret != EOK) { -- talloc_free(ctx); -- } - return ret; - } - -diff --git a/src/util/util.h b/src/util/util.h -index 33725f63591a4d165a084c1fd361f9651e80e50b..49dc850c36cedd83755034367357fab41bd32ec6 100644 ---- a/src/util/util.h -+++ b/src/util/util.h -@@ -401,6 +401,13 @@ struct sss_names_ctx { - pcre *re; - }; - -+/* initialize sss_names_ctx directly from arguments */ -+int sss_names_init_from_args(TALLOC_CTX *mem_ctx, -+ const char *re_pattern, -+ const char *fq_fmt, -+ struct sss_names_ctx **out); -+ -+/* initialize sss_names_ctx from domain configuration */ - int sss_names_init(TALLOC_CTX *mem_ctx, - struct confdb_ctx *cdb, - const char *domain, --- -1.8.2.1 - diff --git a/0004-SSH-Fix-parsing-of-names-from-client-requests.patch b/0004-SSH-Fix-parsing-of-names-from-client-requests.patch deleted file mode 100644 index b063bbd..0000000 --- a/0004-SSH-Fix-parsing-of-names-from-client-requests.patch +++ /dev/null @@ -1,116 +0,0 @@ -From 728b10c81204929be5669c1e67bd086e09c47c00 Mon Sep 17 00:00:00 2001 -From: Jan Cholasta -Date: Fri, 26 Apr 2013 09:53:47 +0200 -Subject: [PATCH 4/6] SSH: Fix parsing of names from client requests - -Try to parse names in the form user@domain first, as that's what sss_ssh_* -send in requests when the --domain option is used. Do not parse host names -using domain-specific regular expression. ---- - src/responder/ssh/sshsrv.c | 8 ++++++++ - src/responder/ssh/sshsrv_cmd.c | 23 ++++++++++++++++++++--- - src/responder/ssh/sshsrv_private.h | 2 ++ - 3 files changed, 30 insertions(+), 3 deletions(-) - -diff --git a/src/responder/ssh/sshsrv.c b/src/responder/ssh/sshsrv.c -index 8a66f2239ac370218ec48d4cfc003d40dc1b7aec..410e631af43b8e8ef160334bab9a540ea913804c 100644 ---- a/src/responder/ssh/sshsrv.c -+++ b/src/responder/ssh/sshsrv.c -@@ -118,6 +118,14 @@ int ssh_process_init(TALLOC_CTX *mem_ctx, - ssh_ctx->rctx = rctx; - ssh_ctx->rctx->pvt_ctx = ssh_ctx; - -+ ret = sss_names_init_from_args(ssh_ctx, -+ "(?P[^@]+)@?(?P[^@]*$)", -+ "%1$s@%2$s", &ssh_ctx->snctx); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_FATAL_FAILURE, ("fatal error initializing regex data\n")); -+ goto fail; -+ } -+ - /* Enable automatic reconnection to the Data Provider */ - ret = confdb_get_int(ssh_ctx->rctx->cdb, - CONFDB_SSH_CONF_ENTRY, -diff --git a/src/responder/ssh/sshsrv_cmd.c b/src/responder/ssh/sshsrv_cmd.c -index 671160ea77904bc5d9a74fee1e351fec8b7cb3fb..374abe6c6ef4ffe1abeeafa2fe94602f5bff3414 100644 ---- a/src/responder/ssh/sshsrv_cmd.c -+++ b/src/responder/ssh/sshsrv_cmd.c -@@ -55,6 +55,7 @@ sss_ssh_cmd_get_user_pubkeys(struct cli_ctx *cctx) - return ENOMEM; - } - cmd_ctx->cctx = cctx; -+ cmd_ctx->is_user = true; - - ret = ssh_cmd_parse_request(cmd_ctx); - if (ret != EOK) { -@@ -101,6 +102,7 @@ sss_ssh_cmd_get_host_pubkeys(struct cli_ctx *cctx) - return ENOMEM; - } - cmd_ctx->cctx = cctx; -+ cmd_ctx->is_user = false; - - ret = ssh_cmd_parse_request(cmd_ctx); - if (ret != EOK) { -@@ -673,6 +675,8 @@ static errno_t - ssh_cmd_parse_request(struct ssh_cmd_ctx *cmd_ctx) - { - struct cli_ctx *cctx = cmd_ctx->cctx; -+ struct ssh_ctx *ssh_ctx = talloc_get_type(cctx->rctx->pvt_ctx, -+ struct ssh_ctx); - errno_t ret; - uint8_t *body; - size_t body_len; -@@ -705,14 +709,27 @@ ssh_cmd_parse_request(struct ssh_cmd_ctx *cmd_ctx) - } - c += name_len; - -- ret = sss_parse_name_for_domains(cmd_ctx, cctx->rctx->domains, -- cctx->rctx->default_domain,name, -- &cmd_ctx->domname, &cmd_ctx->name); -+ ret = sss_parse_name(cmd_ctx, ssh_ctx->snctx, name, -+ &cmd_ctx->domname, &cmd_ctx->name); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, ("Invalid name received [%s]\n", name)); - return ENOENT; - } - -+ if (cmd_ctx->is_user && cmd_ctx->domname == NULL) { -+ name = cmd_ctx->name; -+ -+ ret = sss_parse_name_for_domains(cmd_ctx, cctx->rctx->domains, -+ cctx->rctx->default_domain, name, -+ &cmd_ctx->domname, -+ &cmd_ctx->name); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ ("Invalid name received [%s]\n", name)); -+ return ENOENT; -+ } -+ } -+ - if (flags & 1) { - SAFEALIGN_COPY_UINT32_CHECK(&alias_len, body+c, body_len, &c); - if (alias_len == 0 || alias_len > body_len - c) { -diff --git a/src/responder/ssh/sshsrv_private.h b/src/responder/ssh/sshsrv_private.h -index 296bd94a2947796198a0559c06d904b389283ade..ebb30ce7cbc982bb29b73592d5873e7d3652228a 100644 ---- a/src/responder/ssh/sshsrv_private.h -+++ b/src/responder/ssh/sshsrv_private.h -@@ -28,6 +28,7 @@ - - struct ssh_ctx { - struct resp_ctx *rctx; -+ struct sss_names_ctx *snctx; - - bool hash_known_hosts; - int known_hosts_timeout; -@@ -38,6 +39,7 @@ struct ssh_cmd_ctx { - char *name; - char *alias; - char *domname; -+ bool is_user; - - struct sss_domain_info *domain; - bool check_next; --- -1.8.2.1 - diff --git a/0005-SSH-Use-separate-field-for-domain-name-in-client-req.patch b/0005-SSH-Use-separate-field-for-domain-name-in-client-req.patch deleted file mode 100644 index 2faed0f..0000000 --- a/0005-SSH-Use-separate-field-for-domain-name-in-client-req.patch +++ /dev/null @@ -1,315 +0,0 @@ -From 28e55560008f21a532b103b3f612c6fca2a54d76 Mon Sep 17 00:00:00 2001 -From: Jan Cholasta -Date: Fri, 26 Apr 2013 10:45:42 +0200 -Subject: [PATCH 5/6] SSH: Use separate field for domain name in client - requests - -Instead of appending @domain to names when the --domain option of sss_ssh_* is -used, put domain name in a separate field in client requests. ---- - src/responder/ssh/sshsrv_cmd.c | 91 +++++++++++++++++++--------- - src/sss_client/ssh/sss_ssh_authorizedkeys.c | 15 +---- - src/sss_client/ssh/sss_ssh_client.c | 38 ++++++++---- - src/sss_client/ssh/sss_ssh_client.h | 1 + - src/sss_client/ssh/sss_ssh_knownhostsproxy.c | 12 +--- - src/util/sss_ssh.h | 4 ++ - 6 files changed, 97 insertions(+), 64 deletions(-) - -diff --git a/src/responder/ssh/sshsrv_cmd.c b/src/responder/ssh/sshsrv_cmd.c -index 374abe6c6ef4ffe1abeeafa2fe94602f5bff3414..d2f889fa6ac1e414dfa9bbd943b8ef6af125ae74 100644 ---- a/src/responder/ssh/sshsrv_cmd.c -+++ b/src/responder/ssh/sshsrv_cmd.c -@@ -685,12 +685,14 @@ ssh_cmd_parse_request(struct ssh_cmd_ctx *cmd_ctx) - uint32_t name_len; - char *name; - uint32_t alias_len; -- char *alias; -+ char *alias = NULL; -+ uint32_t domain_len; -+ char *domain = cctx->rctx->default_domain; - - sss_packet_get_body(cctx->creq->in, &body, &body_len); - - SAFEALIGN_COPY_UINT32_CHECK(&flags, body+c, body_len, &c); -- if (flags > 1) { -+ if (flags & ~(uint32_t)SSS_SSH_REQ_MASK) { - DEBUG(SSSDBG_CRIT_FAILURE, ("Invalid flags received [0x%x]\n", flags)); - return EINVAL; - } -@@ -709,28 +711,7 @@ ssh_cmd_parse_request(struct ssh_cmd_ctx *cmd_ctx) - } - c += name_len; - -- ret = sss_parse_name(cmd_ctx, ssh_ctx->snctx, name, -- &cmd_ctx->domname, &cmd_ctx->name); -- if (ret != EOK) { -- DEBUG(SSSDBG_OP_FAILURE, ("Invalid name received [%s]\n", name)); -- return ENOENT; -- } -- -- if (cmd_ctx->is_user && cmd_ctx->domname == NULL) { -- name = cmd_ctx->name; -- -- ret = sss_parse_name_for_domains(cmd_ctx, cctx->rctx->domains, -- cctx->rctx->default_domain, name, -- &cmd_ctx->domname, -- &cmd_ctx->name); -- if (ret != EOK) { -- DEBUG(SSSDBG_OP_FAILURE, -- ("Invalid name received [%s]\n", name)); -- return ENOENT; -- } -- } -- -- if (flags & 1) { -+ if (flags & SSS_SSH_REQ_ALIAS) { - SAFEALIGN_COPY_UINT32_CHECK(&alias_len, body+c, body_len, &c); - if (alias_len == 0 || alias_len > body_len - c) { - DEBUG(SSSDBG_CRIT_FAILURE, ("Invalid alias length\n")); -@@ -744,11 +725,67 @@ ssh_cmd_parse_request(struct ssh_cmd_ctx *cmd_ctx) - return EINVAL; - } - c += alias_len; -+ } - -- if (strcmp(cmd_ctx->name, alias) != 0) { -- cmd_ctx->alias = talloc_strdup(cmd_ctx, alias); -- if (!cmd_ctx->alias) return ENOMEM; -+ if (flags & SSS_SSH_REQ_DOMAIN) { -+ SAFEALIGN_COPY_UINT32_CHECK(&domain_len, body+c, body_len, &c); -+ if (domain_len > 0) { -+ if (domain_len > body_len - c) { -+ DEBUG(SSSDBG_CRIT_FAILURE, ("Invalid domain length\n")); -+ return EINVAL; -+ } -+ -+ domain = (char *)(body+c); -+ if (!sss_utf8_check((const uint8_t *)domain, domain_len-1) || -+ domain[domain_len-1] != 0) { -+ DEBUG(SSSDBG_CRIT_FAILURE, -+ ("Domain is not valid UTF-8 string\n")); -+ return EINVAL; -+ } -+ c += domain_len; -+ } -+ -+ DEBUG(SSSDBG_TRACE_FUNC, -+ ("Requested domain [%s]\n", domain ? domain : "")); -+ } else { -+ DEBUG(SSSDBG_TRACE_FUNC, ("Splitting domain from name [%s]\n", name)); -+ -+ ret = sss_parse_name(cmd_ctx, ssh_ctx->snctx, name, -+ &cmd_ctx->domname, &cmd_ctx->name); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, ("Invalid name received [%s]\n", name)); -+ return ENOENT; - } -+ -+ name = cmd_ctx->name; -+ } -+ -+ if (cmd_ctx->is_user && cmd_ctx->domname == NULL) { -+ DEBUG(SSSDBG_TRACE_FUNC, -+ ("Parsing name [%s][%s]\n", name, domain ? domain : "")); -+ -+ ret = sss_parse_name_for_domains(cmd_ctx, cctx->rctx->domains, -+ domain, name, -+ &cmd_ctx->domname, -+ &cmd_ctx->name); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ ("Invalid name received [%s]\n", name)); -+ return ENOENT; -+ } -+ } else if (cmd_ctx->name == NULL && cmd_ctx->domname == NULL) { -+ cmd_ctx->name = talloc_strdup(cmd_ctx, name); -+ if (!cmd_ctx->name) return ENOMEM; -+ -+ if (domain != NULL) { -+ cmd_ctx->domname = talloc_strdup(cmd_ctx, domain); -+ if (!cmd_ctx->domname) return ENOMEM; -+ } -+ } -+ -+ if (alias != NULL && strcmp(cmd_ctx->name, alias) != 0) { -+ cmd_ctx->alias = talloc_strdup(cmd_ctx, alias); -+ if (!cmd_ctx->alias) return ENOMEM; - } - - return EOK; -diff --git a/src/sss_client/ssh/sss_ssh_authorizedkeys.c b/src/sss_client/ssh/sss_ssh_authorizedkeys.c -index 11deff9a6bb2592ce102ff314bcb2b92f90fa1da..bc991a837635186449b1fd5f1c6bdc944176c43d 100644 ---- a/src/sss_client/ssh/sss_ssh_authorizedkeys.c -+++ b/src/sss_client/ssh/sss_ssh_authorizedkeys.c -@@ -43,7 +43,6 @@ int main(int argc, const char **argv) - POPT_TABLEEND - }; - poptContext pc = NULL; -- const char *user; - struct sss_ssh_ent *ent; - size_t i; - char *repr; -@@ -84,21 +83,9 @@ int main(int argc, const char **argv) - BAD_POPT_PARAMS(pc, _("User not specified\n"), ret, fini); - } - -- /* append domain to username if domain is specified */ -- if (pc_domain) { -- user = talloc_asprintf(mem_ctx, "%s@%s", pc_user, pc_domain); -- if (!user) { -- ERROR("Not enough memory\n"); -- ret = EXIT_FAILURE; -- goto fini; -- } -- } else { -- user = pc_user; -- } -- - /* look up public keys */ - ret = sss_ssh_get_ent(mem_ctx, SSS_SSH_GET_USER_PUBKEYS, -- user, NULL, &ent); -+ pc_user, pc_domain, NULL, &ent); - if (ret != EOK) { - DEBUG(SSSDBG_CRIT_FAILURE, - ("sss_ssh_get_ent() failed (%d): %s\n", ret, strerror(ret))); -diff --git a/src/sss_client/ssh/sss_ssh_client.c b/src/sss_client/ssh/sss_ssh_client.c -index 645f2928985637f26213ab7a0d48a626b088ad58..5312dba2be32aa0cc8813dedfc4189edeff7085c 100644 ---- a/src/sss_client/ssh/sss_ssh_client.c -+++ b/src/sss_client/ssh/sss_ssh_client.c -@@ -70,29 +70,34 @@ int set_locale(void) - - /* SSH public key request: - * -- * 0..3: flags (unsigned int, must be 0 or 1) -- * 4..7: name length (unsigned int) -- * 8..(X-1): name (null-terminated UTF-8 string) -- * if (flags & 1) { -- * X..(X+3): alias length (unsigned int) -- * (X+4)..Y: alias (null-terminated UTF-8 string) -- * } -+ * header: -+ * 0..3: flags (unsigned int, must be combination of SSS_SSH_REQ_* flags) -+ * 4..7: name length (unsigned int) -+ * 8..X: name (null-terminated UTF-8 string) -+ * alias (only included if flags & SSS_SSH_REQ_ALIAS): -+ * 0..3: alias length (unsigned int) -+ * 4..X: alias (null-terminated UTF-8 string) -+ * domain (ony included if flags & SSS_SSH_REQ_DOMAIN): -+ * 0..3: domain length (unsigned int, 0 means default domain) -+ * 4..X: domain (null-terminated UTF-8 string) - * - * SSH public key reply: - * -- * 0..3: number of results (unsigned int) -- * 4..7: reserved (unsigned int, must be 0) -- * 8..$: array of results: -+ * header: -+ * 0..3: number of results (unsigned int) -+ * 4..7: reserved (unsigned int, must be 0) -+ * results (repeated for each result): - * 0..3: flags (unsigned int, must be 0) - * 4..7: name length (unsigned int) - * 8..(X-1): name (null-terminated UTF-8 string) - * X..(X+3): key length (unsigned int) -- * (X+4)..Y: key (public key blob as defined in RFC4253, section 6.6) -+ * (X+4)..Y: key (public key data) - */ - errno_t - sss_ssh_get_ent(TALLOC_CTX *mem_ctx, - enum sss_cli_command command, - const char *name, -+ const char *domain, - const char *alias, - struct sss_ssh_ent **result) - { -@@ -102,6 +107,7 @@ sss_ssh_get_ent(TALLOC_CTX *mem_ctx, - uint32_t flags; - uint32_t name_len; - uint32_t alias_len; -+ uint32_t domain_len; - size_t req_len; - uint8_t *req = NULL; - size_t c = 0; -@@ -122,11 +128,15 @@ sss_ssh_get_ent(TALLOC_CTX *mem_ctx, - req_len = 2*sizeof(uint32_t) + name_len; - - if (alias) { -- flags |= 1; -+ flags |= SSS_SSH_REQ_ALIAS; - alias_len = strlen(alias)+1; - req_len += sizeof(uint32_t) + alias_len; - } - -+ flags |= SSS_SSH_REQ_DOMAIN; -+ domain_len = domain ? (strlen(domain)+1) : 0; -+ req_len += sizeof(uint32_t) + domain_len; -+ - req = talloc_array(tmp_ctx, uint8_t, req_len); - if (!req) { - ret = ENOMEM; -@@ -140,6 +150,10 @@ sss_ssh_get_ent(TALLOC_CTX *mem_ctx, - SAFEALIGN_SET_UINT32(req+c, alias_len, &c); - safealign_memcpy(req+c, alias, alias_len, &c); - } -+ SAFEALIGN_SET_UINT32(req+c, domain_len, &c); -+ if (domain_len > 0) { -+ safealign_memcpy(req+c, domain, domain_len, &c); -+ } - - /* send request */ - rd.data = req; -diff --git a/src/sss_client/ssh/sss_ssh_client.h b/src/sss_client/ssh/sss_ssh_client.h -index 7ffc3983e11c4cfb5fcef9ff417592f63fef3b74..5ad0643f9b821d1ceec85c477ee2037c73e73d7f 100644 ---- a/src/sss_client/ssh/sss_ssh_client.h -+++ b/src/sss_client/ssh/sss_ssh_client.h -@@ -34,6 +34,7 @@ errno_t - sss_ssh_get_ent(TALLOC_CTX *mem_ctx, - enum sss_cli_command command, - const char *name, -+ const char *domain, - const char *alias, - struct sss_ssh_ent **result); - -diff --git a/src/sss_client/ssh/sss_ssh_knownhostsproxy.c b/src/sss_client/ssh/sss_ssh_knownhostsproxy.c -index 600895d1fec81be59f0a6e0092b8a6c9f17890ec..e2202b1839214a165d5a94e3c70ce6af47cb9187 100644 ---- a/src/sss_client/ssh/sss_ssh_knownhostsproxy.c -+++ b/src/sss_client/ssh/sss_ssh_knownhostsproxy.c -@@ -282,19 +282,9 @@ int main(int argc, const char **argv) - } - - if (host) { -- /* append domain to hostname if domain is specified */ -- if (pc_domain) { -- host = talloc_asprintf(mem_ctx, "%s@%s", host, pc_domain); -- if (!host) { -- DEBUG(SSSDBG_CRIT_FAILURE, ("Not enough memory\n")); -- ret = EXIT_FAILURE; -- goto fini; -- } -- } -- - /* look up public keys */ - ret = sss_ssh_get_ent(mem_ctx, SSS_SSH_GET_HOST_PUBKEYS, -- host, pc_host, &ent); -+ host, pc_domain, pc_host, &ent); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, - ("sss_ssh_get_ent() failed (%d): %s\n", ret, strerror(ret))); -diff --git a/src/util/sss_ssh.h b/src/util/sss_ssh.h -index fec7c732bdb319a906e01ec185d7ff0e7f2de0fe..1ba50a6552904096f8950b1f53563d7903eaf786 100644 ---- a/src/util/sss_ssh.h -+++ b/src/util/sss_ssh.h -@@ -21,6 +21,10 @@ - #ifndef _SSS_SSH_H_ - #define _SSS_SSH_H_ - -+#define SSS_SSH_REQ_ALIAS 0x01 -+#define SSS_SSH_REQ_DOMAIN 0x02 -+#define SSS_SSH_REQ_MASK 0x03 -+ - struct sss_ssh_pubkey { - uint8_t *data; - size_t data_len; --- -1.8.2.1 - diff --git a/0006-SSH-Do-not-skip-domains-with-use_fully_qualified_nam.patch b/0006-SSH-Do-not-skip-domains-with-use_fully_qualified_nam.patch deleted file mode 100644 index c9a81e3..0000000 --- a/0006-SSH-Do-not-skip-domains-with-use_fully_qualified_nam.patch +++ /dev/null @@ -1,30 +0,0 @@ -From d5fcc4c497eb17404812be7600fb1181a75cbfd3 Mon Sep 17 00:00:00 2001 -From: Jan Cholasta -Date: Fri, 26 Apr 2013 10:07:22 +0200 -Subject: [PATCH 6/6] SSH: Do not skip domains with use_fully_qualified_names - in host key requests - ---- - src/responder/ssh/sshsrv_cmd.c | 6 ------ - 1 file changed, 6 deletions(-) - -diff --git a/src/responder/ssh/sshsrv_cmd.c b/src/responder/ssh/sshsrv_cmd.c -index d2f889fa6ac1e414dfa9bbd943b8ef6af125ae74..bb765c62890aa326cfad87f511622167df61f0a1 100644 ---- a/src/responder/ssh/sshsrv_cmd.c -+++ b/src/responder/ssh/sshsrv_cmd.c -@@ -300,12 +300,6 @@ ssh_host_pubkeys_search(struct ssh_cmd_ctx *cmd_ctx) - struct tevent_req *req; - struct dp_callback_ctx *cb_ctx; - -- /* if it is a domainless search, skip domains that require fully -- * qualified names instead */ -- while (cmd_ctx->domain && cmd_ctx->check_next && cmd_ctx->domain->fqnames) { -- cmd_ctx->domain = get_next_domain(cmd_ctx->domain, false); -- } -- - if (!cmd_ctx->domain) { - DEBUG(SSSDBG_OP_FAILURE, - ("No matching domain found for [%s], fail!\n", cmd_ctx->name)); --- -1.8.2.1 - diff --git a/0007-Always-update-cached-upn-if-enterprise-principals-ar.patch b/0007-Always-update-cached-upn-if-enterprise-principals-ar.patch deleted file mode 100644 index 9b8ce53..0000000 --- a/0007-Always-update-cached-upn-if-enterprise-principals-ar.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 517ba52c518eb747ccb2a76d75a7ec88fc870cf4 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Mon, 13 May 2013 14:25:15 +0200 -Subject: [PATCH] Always update cached upn if enterprise principals are used - -Instead of continuing to use the initial upn if enterprise principals -are used if should always be replaced. The enterprise principal -is stored in the credential cache and without knowing it the -ccache_for_princ() calls to determine the location of the credential -cache will fail. - -Fixes https://fedorahosted.org/sssd/ticket/1921 ---- - src/providers/krb5/krb5_auth.c | 7 ++++--- - 1 files changed, 4 insertions(+), 3 deletions(-) - -diff --git a/src/providers/krb5/krb5_auth.c b/src/providers/krb5/krb5_auth.c -index 6d7494c..f65e599 100644 ---- a/src/providers/krb5/krb5_auth.c -+++ b/src/providers/krb5/krb5_auth.c -@@ -913,11 +913,12 @@ static void krb5_auth_done(struct tevent_req *subreq) - KRB5_USE_ENTERPRISE_PRINCIPAL); - - /* Check if the cases of our upn are correct and update it if needed. -- * Fail if the upn differs by more than just the case. */ -+ * Fail if the upn differs by more than just the case for non-enterprise -+ * principals. */ - if (res->correct_upn != NULL && -- use_enterprise_principal == false && - strcmp(kr->upn, res->correct_upn) != 0) { -- if (strcasecmp(kr->upn, res->correct_upn) == 0) { -+ if (strcasecmp(kr->upn, res->correct_upn) == 0 || -+ use_enterprise_principal == true) { - talloc_free(kr->upn); - kr->upn = talloc_strdup(kr, res->correct_upn); - if (kr->upn == NULL) { --- -1.7.7.6 - diff --git a/0008-Enable-the-AD-dynamic-DNS-updates-by-default.patch b/0008-Enable-the-AD-dynamic-DNS-updates-by-default.patch deleted file mode 100644 index 86ef52a..0000000 --- a/0008-Enable-the-AD-dynamic-DNS-updates-by-default.patch +++ /dev/null @@ -1,40 +0,0 @@ -From ad1be6fd04234f61f108773ff39aa7485abda47c Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Thu, 9 May 2013 16:41:47 +0200 -Subject: [PATCH] Enable the AD dynamic DNS updates by default - -https://fedorahosted.org/sssd/ticket/1915 ---- - src/man/sssd-ad.5.xml | 2 +- - src/providers/ad/ad_opts.h | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/src/man/sssd-ad.5.xml b/src/man/sssd-ad.5.xml -index 71e8a2075bc83bc814987f2ca738ddb138c14e5a..589dfd0b5f7514a8e17c9f04407476ccf7c33e88 100644 ---- a/src/man/sssd-ad.5.xml -+++ b/src/man/sssd-ad.5.xml -@@ -170,7 +170,7 @@ ldap_id_mapping = False - realm must be set properly in /etc/krb5.conf - - -- Default: false -+ Default: true - - - -diff --git a/src/providers/ad/ad_opts.h b/src/providers/ad/ad_opts.h -index 32bbe3db2f4048056c7e96619eaf53ce22bf52f8..6e9d843c1f0a619fc3da26ae82bb15fe80eb4420 100644 ---- a/src/providers/ad/ad_opts.h -+++ b/src/providers/ad/ad_opts.h -@@ -239,7 +239,7 @@ struct sdap_attr_map ad_autofs_entry_map[] = { - }; - - struct dp_option ad_dyndns_opts[] = { -- { "dyndns_update", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, -+ { "dyndns_update", DP_OPT_BOOL, BOOL_TRUE, BOOL_FALSE }, - { "dyndns_refresh_interval", DP_OPT_NUMBER, { .number = 86400 }, NULL_NUMBER }, - { "dyndns_iface", DP_OPT_STRING, NULL_STRING, NULL_STRING }, - { "dyndns_ttl", DP_OPT_NUMBER, { .number = 3600 }, NULL_NUMBER }, --- -1.8.2.1 - diff --git a/0009-Fix-segfault-in-AD-Subdomains-Module.patch b/0009-Fix-segfault-in-AD-Subdomains-Module.patch deleted file mode 100644 index 21794cd..0000000 --- a/0009-Fix-segfault-in-AD-Subdomains-Module.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 574061e65d3fb687b9cb2c757afa1fe92812245e Mon Sep 17 00:00:00 2001 -From: Lukas Slebodnik -Date: Wed, 15 May 2013 10:09:08 +0200 -Subject: [PATCH] Fix segfault in AD Subdomains Module - -In function ad_subdomains_get_netlogon_done: -If variable "reply_count" is zero then variable "reply" will not be -initialized. Therefore we should not continue. ---- - src/providers/ad/ad_subdomains.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c -index 1da343f8711b2b99a7afff6a4a398a1aa515a875..2ad318f63a89b2e8894ca07d007cde11867ed290 100644 ---- a/src/providers/ad/ad_subdomains.c -+++ b/src/providers/ad/ad_subdomains.c -@@ -307,6 +307,8 @@ static void ad_subdomains_get_netlogon_done(struct tevent_req *req) - - if (reply_count == 0) { - DEBUG(SSSDBG_TRACE_FUNC, ("No netlogon data available.\n")); -+ ret = ENOENT; -+ goto done; - } else if (reply_count > 1) { - DEBUG(SSSDBG_OP_FAILURE, - ("More than one netlogon info returned.\n")); --- -1.8.2.1 - diff --git a/0010-LDAP-Always-initialize-idmap-object.patch b/0010-LDAP-Always-initialize-idmap-object.patch deleted file mode 100644 index 1c4a743..0000000 --- a/0010-LDAP-Always-initialize-idmap-object.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 392dce02615e446b3c73dfb8b4e0a19ebb86f914 Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Mon, 13 May 2013 10:15:09 +0200 -Subject: [PATCH] LDAP: Always initialize idmap object - -https://fedorahosted.org/sssd/ticket/1922 - -Since we always store the SID now, we need to always initialize the ID -mapping object in LDAP provider as well. Some users might want to -configure the LDAP provider with ID mapping, not the AD provider itself. ---- - src/providers/ldap/ldap_init.c | 8 +++----- - 1 file changed, 3 insertions(+), 5 deletions(-) - -diff --git a/src/providers/ldap/ldap_init.c b/src/providers/ldap/ldap_init.c -index 2e30c37edb707799baada3d695776ae602c6a7eb..0884a85c7d9db2c7c777caf0baebf59217076982 100644 ---- a/src/providers/ldap/ldap_init.c -+++ b/src/providers/ldap/ldap_init.c -@@ -155,11 +155,9 @@ int sssm_ldap_id_init(struct be_ctx *bectx, - goto done; - } - -- if (dp_opt_get_bool(ctx->opts->basic, SDAP_ID_MAPPING)) { -- /* Set up the ID mapping object */ -- ret = sdap_idmap_init(ctx, ctx, &ctx->opts->idmap_ctx); -- if (ret != EOK) goto done; -- } -+ /* Set up the ID mapping object */ -+ ret = sdap_idmap_init(ctx, ctx, &ctx->opts->idmap_ctx); -+ if (ret != EOK) goto done; - - ret = sdap_id_setup_tasks(ctx); - if (ret != EOK) { --- -1.8.2.1 - diff --git a/0011-Re-add-a-useful-DEBUG-message.patch b/0011-Re-add-a-useful-DEBUG-message.patch deleted file mode 100644 index 9f8654e..0000000 --- a/0011-Re-add-a-useful-DEBUG-message.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 5aad10b49e193ee14a86e1277146a223005a2d6b Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Mon, 13 May 2013 10:23:56 +0200 -Subject: [PATCH] Re-add a useful DEBUG message - -In commit 46222e5191473f9a46aec581273eb2eef22e23be we removed a very -similar DEBUG message while moving the whole piece of code to the idmap -library. But it turned out that the DEBUG message was useful while -testing the functionality, so this patch adds it back. ---- - src/providers/ldap/sdap_idmap.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/src/providers/ldap/sdap_idmap.c b/src/providers/ldap/sdap_idmap.c -index 050b2c5a768f58acd376e68a15a579e1e56894ac..43db0c83354ed2f8f112a8853ab66ab51e1d9fd2 100644 ---- a/src/providers/ldap/sdap_idmap.c -+++ b/src/providers/ldap/sdap_idmap.c -@@ -242,6 +242,8 @@ sdap_idmap_add_domain(struct sdap_idmap_ctx *idmap_ctx, - ret = EIO; - goto done; - } -+ DEBUG(SSSDBG_TRACE_LIBS, -+ ("Adding domain [%s] as slice [%llu]\n", dom_sid, slice)); - - if (range.max > idmap_upper) { - /* This should never happen */ --- -1.8.2.1 -