~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source3/winbindd/idmap_adex/domain_util.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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)
 
40
{
 
41
        return _dc_server_list;
 
42
}
 
43
 
 
44
/**********************************************************************
 
45
 *********************************************************************/
 
46
 
 
47
static NTSTATUS dc_add_domain(const char *domain)
 
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)
 
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)
 
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,
 
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)
 
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,
 
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
}