root/source3/winbindd/idmap_adex/domain_util.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. dc_list_head
  2. dc_add_domain
  3. dc_server_list_destroy
  4. domain_init_list
  5. dc_do_search
  6. dc_find_domain
  7. dc_search_domains

   1 /*
   2  * idmap_adex: Domain search interface
   3  *
   4  * Copyright (C) Gerald (Jerry) Carter 2007-2008
   5  *
   6  * This program is free software; you can redistribute it and/or modify
   7  * it under the terms of the GNU General Public License as published by
   8  * the Free Software Foundation; either version 2 of the License, or
   9  * (at your option) any later version.
  10  *
  11  * This program is distributed in the hope that it will be useful,
  12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14  * GNU General Public License for more details.
  15  *
  16  * You should have received a copy of the GNU General Public License
  17  * along with this program; if not, write to the Free Software
  18  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19  */
  20 
  21 #include "includes.h"
  22 #include "idmap_adex.h"
  23 
  24 #undef DBGC_CLASS
  25 #define DBGC_CLASS DBGC_IDMAP
  26 
  27 struct dc_info {
  28         struct dc_info *prev, *next;
  29         char *dns_name;
  30         struct likewise_cell *domain_cell;
  31 };
  32 
  33 static struct dc_info *_dc_server_list = NULL;
  34 
  35 
  36 /**********************************************************************
  37  *********************************************************************/
  38 
  39 static struct dc_info *dc_list_head(void)
     /* [<][>][^][v][top][bottom][index][help] */
  40 {
  41         return _dc_server_list;
  42 }
  43 
  44 /**********************************************************************
  45  *********************************************************************/
  46 
  47 static NTSTATUS dc_add_domain(const char *domain)
     /* [<][>][^][v][top][bottom][index][help] */
  48 {
  49         NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
  50         struct dc_info *dc = NULL;
  51 
  52         if (!domain) {
  53                 return NT_STATUS_INVALID_PARAMETER;
  54         }
  55 
  56         DEBUG(10,("dc_add_domain: Attempting to add domain %s\n", domain));
  57 
  58         /* Check for duplicates */
  59 
  60         dc = dc_list_head();
  61         while (dc) {
  62                 if (strequal (dc->dns_name, domain))
  63                         break;
  64                 dc = dc->next;
  65         }
  66 
  67         if (dc) {
  68                 DEBUG(10,("dc_add_domain: %s already in list\n", domain));
  69                 return NT_STATUS_OK;
  70         }
  71 
  72         dc = TALLOC_ZERO_P(NULL, struct dc_info);
  73         BAIL_ON_PTR_ERROR(dc, nt_status);
  74 
  75         dc->dns_name = talloc_strdup(dc, domain);
  76         BAIL_ON_PTR_ERROR(dc->dns_name, nt_status);
  77 
  78         DLIST_ADD_END(_dc_server_list, dc, struct dc_info*);
  79 
  80         nt_status = NT_STATUS_OK;
  81 
  82         DEBUG(5,("dc_add_domain: Successfully added %s\n", domain));
  83 
  84 done:
  85         if (!NT_STATUS_IS_OK(nt_status)) {
  86                 talloc_destroy(dc);
  87                 DEBUG(0,("LWI: Failed to add new DC connection for %s (%s)\n",
  88                          domain, nt_errstr(nt_status)));
  89         }
  90 
  91         return nt_status;
  92 }
  93 
  94 /**********************************************************************
  95  *********************************************************************/
  96 
  97 static void dc_server_list_destroy(void)
     /* [<][>][^][v][top][bottom][index][help] */
  98 {
  99         struct dc_info *dc = dc_list_head();
 100 
 101         while (dc) {
 102                 struct dc_info *p = dc->next;
 103 
 104                 cell_destroy(dc->domain_cell);
 105                 talloc_destroy(dc);
 106 
 107                 dc = p;
 108         }
 109 
 110         return;
 111 }
 112 
 113 
 114 /**********************************************************************
 115  *********************************************************************/
 116 
 117  NTSTATUS domain_init_list(void)
     /* [<][>][^][v][top][bottom][index][help] */
 118 {
 119         NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
 120         struct winbindd_tdc_domain *domains = NULL;
 121         size_t num_domains = 0;
 122         int i;
 123 
 124         if (_dc_server_list != NULL) {
 125                 dc_server_list_destroy();
 126         }
 127 
 128         /* Add our domain */
 129 
 130         nt_status = dc_add_domain(lp_realm());
 131         BAIL_ON_NTSTATUS_ERROR(nt_status);
 132 
 133         if (!wcache_tdc_fetch_list(&domains, &num_domains)) {
 134                 nt_status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
 135                 BAIL_ON_NTSTATUS_ERROR(nt_status);
 136         }
 137 
 138         /* Add all domains with an incoming trust path */
 139 
 140         for (i=0; i<num_domains; i++) {
 141                 uint32_t flags = (NETR_TRUST_FLAG_INBOUND|NETR_TRUST_FLAG_IN_FOREST);
 142 
 143                 /* We just require one of the flags to be set here */
 144 
 145                 if (domains[i].trust_flags & flags) {
 146                         nt_status = dc_add_domain(domains[i].dns_name);
 147                         BAIL_ON_NTSTATUS_ERROR(nt_status);
 148                 }
 149         }
 150 
 151         nt_status = NT_STATUS_OK;
 152 
 153 done:
 154         if (!NT_STATUS_IS_OK(nt_status)) {
 155                 DEBUG(2,("LWI: Failed to initialize DC list (%s)\n",
 156                          nt_errstr(nt_status)));
 157         }
 158 
 159         TALLOC_FREE(domains);
 160 
 161         return nt_status;
 162 }
 163 
 164 /********************************************************************
 165  *******************************************************************/
 166 
 167 static NTSTATUS dc_do_search(struct dc_info *dc,
     /* [<][>][^][v][top][bottom][index][help] */
 168                              const char *search_base,
 169                              int scope,
 170                              const char *expr,
 171                              const char **attrs,
 172                              LDAPMessage ** msg)
 173 {
 174         ADS_STATUS status = ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL);
 175         NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
 176 
 177         status = cell_do_search(dc->domain_cell, search_base,
 178                                 scope, expr, attrs, msg);
 179         nt_status = ads_ntstatus(status);
 180 
 181         return nt_status;
 182 }
 183 
 184 /**********************************************************************
 185  *********************************************************************/
 186 
 187 static struct dc_info *dc_find_domain(const char *dns_domain)
     /* [<][>][^][v][top][bottom][index][help] */
 188 {
 189         struct dc_info *dc = dc_list_head();
 190 
 191         if (!dc)
 192                 return NULL;
 193 
 194         while (dc) {
 195                 if (strequal(dc->dns_name, dns_domain)) {
 196                         return dc;
 197                 }
 198 
 199                 dc = dc->next;
 200         }
 201 
 202         return NULL;
 203 }
 204 
 205 /**********************************************************************
 206  *********************************************************************/
 207 
 208  NTSTATUS dc_search_domains(struct likewise_cell **cell,
     /* [<][>][^][v][top][bottom][index][help] */
 209                             LDAPMessage **msg,
 210                             const char *dn,
 211                             const DOM_SID *sid)
 212 {
 213         NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
 214         TALLOC_CTX *frame = talloc_stackframe();
 215         char *dns_domain;
 216         const char *attrs[] = { "*", NULL };
 217         struct dc_info *dc = NULL;
 218         const char *base = NULL;
 219 
 220         if (!dn || !*dn) {
 221                 nt_status = NT_STATUS_INVALID_PARAMETER;
 222                 BAIL_ON_NTSTATUS_ERROR(nt_status);
 223         }
 224 
 225         dns_domain = cell_dn_to_dns(dn);
 226         BAIL_ON_PTR_ERROR(dns_domain, nt_status);
 227 
 228         if ((dc = dc_find_domain(dns_domain)) == NULL) {
 229                 nt_status = NT_STATUS_TRUSTED_DOMAIN_FAILURE;
 230                 BAIL_ON_NTSTATUS_ERROR(nt_status);
 231         }
 232 
 233         /* Reparse the cell settings for the domain if necessary */
 234 
 235         if (!dc->domain_cell) {
 236                 char *base_dn;
 237 
 238                 base_dn = ads_build_dn(dc->dns_name);
 239                 BAIL_ON_PTR_ERROR(base_dn, nt_status);
 240 
 241                 nt_status = cell_connect_dn(&dc->domain_cell, base_dn);
 242                 SAFE_FREE(base_dn);
 243                 BAIL_ON_NTSTATUS_ERROR(nt_status);
 244 
 245                 nt_status = cell_lookup_settings(dc->domain_cell);
 246                 BAIL_ON_NTSTATUS_ERROR(nt_status);
 247 
 248                 /* By definition this is already part of a larger
 249                    forest-wide search scope */
 250 
 251                 cell_set_flags(dc->domain_cell, LWCELL_FLAG_SEARCH_FOREST);
 252         }
 253 
 254         /* Check whether we are operating in non-schema or RFC2307
 255            mode */
 256 
 257         if (cell_flags(dc->domain_cell) & LWCELL_FLAG_USE_RFC2307_ATTRS) {
 258                 nt_status = dc_do_search(dc, dn, LDAP_SCOPE_BASE,
 259                                          "(objectclass=*)", attrs, msg);
 260         } else {
 261                 const char *sid_str = NULL;
 262                 char *filter = NULL;
 263 
 264                 sid_str = sid_string_talloc(frame, sid);
 265                 BAIL_ON_PTR_ERROR(sid_str, nt_status);
 266 
 267                 filter = talloc_asprintf(frame, "(keywords=backLink=%s)",
 268                                          sid_str);
 269                 BAIL_ON_PTR_ERROR(filter, nt_status);
 270 
 271                 base = cell_search_base(dc->domain_cell);
 272                 BAIL_ON_PTR_ERROR(base, nt_status);
 273 
 274                 nt_status = dc_do_search(dc, base, LDAP_SCOPE_SUBTREE,
 275                                          filter, attrs, msg);
 276         }
 277         BAIL_ON_NTSTATUS_ERROR(nt_status);
 278 
 279         *cell = dc->domain_cell;
 280 
 281 done:
 282         talloc_destroy(CONST_DISCARD(char*, base));
 283         talloc_destroy(frame);
 284 
 285         return nt_status;
 286 }

/* [<][>][^][v][top][bottom][index][help] */