Update SSSD for the F19 test day
- Explicitly Require libini_config >= 1.0.0.1 to work around a SONAME bug in ding-libs - Fix SSH integration with fully-qualified domains - Add the ability to dynamically discover the NetBIOS name
This commit is contained in:
		
							parent
							
								
									3726d5f5e7
								
							
						
					
					
						commit
						14fef6c6d9
					
				
							
								
								
									
										702
									
								
								0001-AD-read-flat-name-and-SID-of-the-AD-domain.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										702
									
								
								0001-AD-read-flat-name-and-SID-of-the-AD-domain.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,702 @@ | ||||
| From 4cdaf239d4504966bed8ecd5e3fa07def74c7302 Mon Sep 17 00:00:00 2001 | ||||
| From: Sumit Bose <sbose@redhat.com> | ||||
| 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. | ||||
|                          </para> | ||||
| +                        <para>
 | ||||
| +                            The short domain name (also known as the NetBIOS
 | ||||
| +                            or the flat name) is autodetected by the SSSD.
 | ||||
| +                        </para>
 | ||||
|                      </listitem> | ||||
|                  </varlistentry> | ||||
|   | ||||
| 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.
 | ||||
|                          </para> | ||||
|                          <para> | ||||
|                              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 <sbose@redhat.com>
 | ||||
| +
 | ||||
| +    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 <http://www.gnu.org/licenses/>.
 | ||||
| +*/
 | ||||
| +
 | ||||
| +#include "providers/ldap/sdap_async.h"
 | ||||
| +#include "providers/ad/ad_subdomains.h"
 | ||||
| +#include <ctype.h>
 | ||||
| +#include <ndr.h>
 | ||||
| +#include <ndr/ndr_nbt.h>
 | ||||
| +
 | ||||
| +#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 <sbose@redhat.com>
 | ||||
| +
 | ||||
| +    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 <http://www.gnu.org/licenses/>.
 | ||||
| +*/
 | ||||
| +
 | ||||
| +#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 | ||||
| 
 | ||||
| @ -0,0 +1,65 @@ | ||||
| From 7c091610f5b35e8ba89da839322f6591f1e7619b Mon Sep 17 00:00:00 2001 | ||||
| From: Jakub Hrozek <jhrozek@redhat.com> | ||||
| 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 | ||||
| 
 | ||||
							
								
								
									
										205
									
								
								0003-UTIL-Add-function-sss_names_init_from_args.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										205
									
								
								0003-UTIL-Add-function-sss_names_init_from_args.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,205 @@ | ||||
| From f54b271376b23cb968eafb9ffd5100c6dadad2a7 Mon Sep 17 00:00:00 2001 | ||||
| From: Jan Cholasta <jcholast@redhat.com> | ||||
| 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<name>[^@]+)@?(?P<domain>[^@]*$)");
 | ||||
| -        if (!ctx->re_pattern) {
 | ||||
| +    if (!re_pattern) {
 | ||||
| +        re_pattern = talloc_strdup(tmpctx,
 | ||||
| +                                   "(?P<name>[^@]+)@?(?P<domain>[^@]*$)");
 | ||||
| +        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<name>).\n", ctx->re_pattern));
 | ||||
| +                  "the Python syntax (?P<name>).\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 | ||||
| 
 | ||||
							
								
								
									
										116
									
								
								0004-SSH-Fix-parsing-of-names-from-client-requests.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								0004-SSH-Fix-parsing-of-names-from-client-requests.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,116 @@ | ||||
| From 728b10c81204929be5669c1e67bd086e09c47c00 Mon Sep 17 00:00:00 2001 | ||||
| From: Jan Cholasta <jcholast@redhat.com> | ||||
| 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<name>[^@]+)@?(?P<domain>[^@]*$)",
 | ||||
| +                                   "%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 | ||||
| 
 | ||||
							
								
								
									
										315
									
								
								0005-SSH-Use-separate-field-for-domain-name-in-client-req.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										315
									
								
								0005-SSH-Use-separate-field-for-domain-name-in-client-req.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,315 @@ | ||||
| From 28e55560008f21a532b103b3f612c6fca2a54d76 Mon Sep 17 00:00:00 2001 | ||||
| From: Jan Cholasta <jcholast@redhat.com> | ||||
| 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 : "<ALL>"));
 | ||||
| +    } 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 : "<ALL>"));
 | ||||
| +
 | ||||
| +        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 | ||||
| 
 | ||||
| @ -0,0 +1,30 @@ | ||||
| From d5fcc4c497eb17404812be7600fb1181a75cbfd3 Mon Sep 17 00:00:00 2001 | ||||
| From: Jan Cholasta <jcholast@redhat.com> | ||||
| 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 | ||||
| 
 | ||||
							
								
								
									
										16
									
								
								sssd.spec
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								sssd.spec
									
									
									
									
									
								
							| @ -16,7 +16,7 @@ | ||||
| 
 | ||||
| Name: sssd | ||||
| Version: 1.10.0 | ||||
| Release: 3%{?dist}.beta1 | ||||
| Release: 4%{?dist}.beta1 | ||||
| Group: Applications/System | ||||
| Summary: System Security Services Daemon | ||||
| License: GPLv3+ | ||||
| @ -25,6 +25,13 @@ Source0: https://fedorahosted.org/released/sssd/%{name}-%{version}beta1.tar.gz | ||||
| BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) | ||||
| 
 | ||||
| ### Patches ### | ||||
| Patch0001: 0001-AD-read-flat-name-and-SID-of-the-AD-domain.patch | ||||
| Patch0002: 0002-Actually-use-the-index-parameter-in-resolv_get_socka.patch | ||||
| Patch0003: 0003-UTIL-Add-function-sss_names_init_from_args.patch | ||||
| Patch0004: 0004-SSH-Fix-parsing-of-names-from-client-requests.patch | ||||
| Patch0005: 0005-SSH-Use-separate-field-for-domain-name-in-client-req.patch | ||||
| Patch0006: 0006-SSH-Do-not-skip-domains-with-use_fully_qualified_nam.patch | ||||
| 
 | ||||
| Patch0501:  0501-FEDORA-Switch-the-default-ccache-location.patch | ||||
| 
 | ||||
| ### Dependencies ### | ||||
| @ -38,6 +45,7 @@ Requires: libipa_hbac%{?_isa} = %{version}-%{release} | ||||
| Requires: libsss_idmap%{?_isa} = %{version}-%{release} | ||||
| Requires: python-sssdconfig = %{version}-%{release} | ||||
| Requires: krb5-libs%{?_isa} >= 1.10 | ||||
| Requires: libini_config >= 1.0.0.1 | ||||
| Requires(post): systemd-units initscripts chkconfig | ||||
| Requires(preun): systemd-units initscripts chkconfig | ||||
| Requires(postun): systemd-units initscripts chkconfig | ||||
| @ -595,6 +603,12 @@ fi | ||||
| %postun -n libsss_sudo -p /sbin/ldconfig | ||||
| 
 | ||||
| %changelog | ||||
| * Tue May  7 2013 Jakub Hrozek <jhrozek@redhat.com> - 1.10.0-4.beta1 | ||||
| - Explicitly Require libini_config >= 1.0.0.1 to work around a SONAME bug | ||||
|   in ding-libs | ||||
| - Fix SSH integration with fully-qualified domains | ||||
| - Add the ability to dynamically discover the NetBIOS name | ||||
| 
 | ||||
| * Fri May  3 2013 Jakub Hrozek <jhrozek@redhat.com> - 1.10.0-3.beta1 | ||||
| - New upstream release 1.10 beta1 | ||||
| - https://fedorahosted.org/sssd/wiki/Releases/Notes-1.10.0beta1 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user