ad_subdomains.c revision c56da2ccf852c403b21dd987de8bae451654e95a
/*
SSSD
AD Subdomains Module
Authors:
Sumit Bose <sbose@redhat.com>
Copyright (C) 2013 Red Hat
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "providers/ldap/sdap_async.h"
#include "providers/ad/ad_subdomains.h"
#include "providers/ad/ad_domain_info.h"
#include "providers/ldap/sdap_idmap.h"
#include "util/util_sss_idmap.h"
#include <ctype.h>
#include <ndr.h>
#define AD_AT_OBJECT_SID "objectSID"
#define AD_AT_DNS_DOMAIN "DnsDomain"
#define AD_AT_NT_VERSION "NtVer"
#define AD_AT_NETLOGON "netlogon"
/* Attributes of AD trusted domains */
#define AD_AT_FLATNAME "flatName"
#define AD_AT_SID "securityIdentifier"
#define AD_AT_TRUST_TYPE "trustType"
#define AD_AT_TRUST_PARTNER "trustPartner"
#define AD_AT_TRUST_ATTRS "trustAttributes"
#define MASTER_DOMAIN_SID_FILTER "objectclass=domain"
/* trustType=2 denotes uplevel (NT5 and later) trusted domains. See
* for example.
*
* The absence of msDS-TrustForestTrustInfo attribute denotes a domain from
* the same forest. See http://msdn.microsoft.com/en-us/library/cc223786.aspx
* for more information.
*/
#define SLAVE_DOMAIN_FILTER "(&(objectclass=trustedDomain)(trustType=2)(!(msDS-TrustForestTrustInfo=*)))"
/* do not refresh more often than every 5 seconds for now */
#define AD_SUBDOMAIN_REFRESH_LIMIT 5
struct ad_subdomains_ctx {
struct sdap_id_ctx *sdap_id_ctx;
struct sdap_domain *sdom;
struct sdap_id_conn_ctx *ldap_ctx;
struct sss_idmap_ctx *idmap_ctx;
char *domain_name;
struct tevent_timer *timer_event;
};
struct ad_subdomains_req_ctx {
struct ad_subdomains_ctx *sd_ctx;
struct sdap_id_op *sdap_op;
char *current_filter;
struct sysdb_attrs **reply;
char *master_sid;
char *flat_name;
};
static errno_t
struct sss_domain_info *parent)
{
}
static errno_t
struct sss_domain_info *domain,
struct sysdb_attrs *subdom_attrs)
{
const char *name;
char *realm;
const char *flat;
enum idmap_error_code err;
struct ldb_message_element *el;
bool mpg;
goto done;
}
&trust_type);
goto done;
}
goto done;
}
if (!realm) {
goto done;
}
if (ret) {
name));
goto done;
}
goto done;
}
&sid_str);
if (err != IDMAP_SUCCESS) {
goto done;
}
name,
sid_str);
/* AD subdomains are currently all mpg and do not enumerate */
goto done;
}
done:
return ret;
}
bool *changes)
{
struct sdap_domain *sdom;
const char *value;
int c, h;
int ret;
h = 0;
/* check existing subdomains */
for (c = 0; c < count; c++) {
if (handled[c]) {
continue;
}
goto done;
}
break;
}
}
if (c >= count) {
/* ok this subdomain does not exist anymore, let's clean up */
goto done;
}
continue;
}
/* Remove the subdomain from the list of LDAP domains */
/* terminate all requests for this subdomain so we can free it */
} else {
/* ok let's try to update it */
if (ret) {
/* Nothing we can do about the error. Let's at least try
* to reuse the existing domains
*/
"will try to use cached subdomain\n"));
}
handled[c] = true;
h++;
}
}
if (count == h) {
/* all domains were already accounted for and have been updated */
goto done;
}
/* if we get here it means we have changes to the subdomains list */
*changes = true;
for (c = 0; c < count; c++) {
if (handled[c]) {
continue;
}
/* Nothing we can do about the error. Let's at least try
* to reuse the existing domains.
*/
if (ret) {
"will try to use cached subdomain\n"));
}
}
done:
ctx->last_refreshed = 0;
} else {
}
return ret;
}
{
struct tevent_req *req;
int dp_error = DP_ERR_FATAL;
int ret;
goto done;
}
req_ctx->reply_count = 0;
goto done;
}
goto done;
}
return;
done:
}
}
{
int ret;
int dp_error = DP_ERR_FATAL;
struct ad_subdomains_req_ctx *ctx;
if (ret) {
if (dp_error == DP_ERR_OFFLINE) {
("No AD server is available, cannot get the "
"subdomain list while offline\n"));
} else {
("Failed to connect to AD server: [%d](%s)\n",
}
goto fail;
}
goto fail;
}
return;
fail:
}
{
struct ad_subdomains_req_ctx *ctx;
goto done;
}
goto done;
}
return;
goto done;
}
done:
}
{
struct tevent_req *req;
struct sdap_search_base *base;
return EOK;
}
NULL, 0,
false);
return ENOMEM;
}
return EAGAIN;
}
{
int ret;
struct ad_subdomains_req_ctx *ctx;
int dp_error = DP_ERR_FATAL;
bool refresh_has_changes = false;
goto done;
}
if (reply_count) {
goto done;
}
reply_count * sizeof(struct sysdb_attrs *));
}
return;
goto done;
}
/* Got all the subdomains, let's process them */
goto done;
}
if (refresh_has_changes) {
goto done;
}
goto done;
}
("sss_krb5_write_mappings failed.\n"));
/* Just continue */
}
}
done:
}
}
static void ad_subdom_online_cb(void *pvt);
struct tevent_timer *te,
struct timeval current_time,
void *pvt)
{
}
const char *errstr)
{
}
static void ad_subdom_online_cb(void *pvt)
{
struct ad_subdomains_ctx *ctx;
if (!ctx) {
return;
}
return;
}
if (!ctx->timer_event) {
}
}
static void ad_subdom_offline_cb(void *pvt)
{
struct ad_subdomains_ctx *ctx;
if (ctx) {
}
}
{
struct ad_subdomains_ctx *ctx;
struct ad_subdomains_ctx);
if (!ctx) {
return;
}
return;
}
}
struct bet_ops ad_subdomains_ops = {
};
const char *ad_domain,
void **pvt_data)
{
struct ad_subdomains_ctx *ctx;
int ret;
enum idmap_error_code err;
return ENOMEM;
}
return ENOMEM;
}
*ops = &ad_subdomains_ops;
}
}
if (err != IDMAP_SUCCESS) {
return EFAULT;
}
return EOK;
}