2 * idmap_adex: Support for AD Forests
4 * Copyright (C) Gerald (Jerry) Carter 2006-2008
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.
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.
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.
22 #include "idmap_adex.h"
23 #include "../libds/common/flags.h"
26 #define DBGC_CLASS DBGC_IDMAP
28 /**********************************************************************
29 **********************************************************************/
31 char *find_attr_string(char **list, size_t num_lines, const char *substr)
34 int cmplen = strlen(substr);
36 for (i = 0; i < num_lines; i++) {
37 /* make sure to avoid substring matches like uid
39 if ((StrnCaseCmp(list[i], substr, cmplen) == 0) &&
40 (list[i][cmplen] == '=')) {
41 /* Don't return an empty string */
42 if (list[i][cmplen + 1] != '\0')
43 return &(list[i][cmplen + 1]);
52 /**********************************************************************
53 **********************************************************************/
55 bool is_object_class(char **list, size_t num_lines, const char *substr)
59 for (i = 0; i < num_lines; i++) {
60 if (strequal(list[i], substr)) {
68 /**********************************************************************
69 Find out about the cell (e.g. use2307Attrs, etc...)
70 **********************************************************************/
72 NTSTATUS cell_lookup_settings(struct likewise_cell * cell)
74 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
79 nt_status = NT_STATUS_INVALID_PARAMETER;
80 BAIL_ON_NTSTATUS_ERROR(nt_status);
83 /* Only supporting Forest-wide, schema based searches */
85 cell_set_flags(cell, LWCELL_FLAG_USE_RFC2307_ATTRS);
86 cell_set_flags(cell, LWCELL_FLAG_SEARCH_FOREST);
88 cell->provider = &ccp_unified;
90 nt_status = NT_STATUS_OK;
93 if (!NT_STATUS_IS_OK(nt_status)) {
94 DEBUG(1,("LWI: Failed to obtain cell settings (%s)\n",
95 nt_errstr(nt_status)));
102 static NTSTATUS cell_lookup_forest(struct likewise_cell *c)
104 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
105 struct gc_info *gc = NULL;
108 return NT_STATUS_INVALID_PARAMETER;
111 if ((gc = TALLOC_ZERO_P(NULL, struct gc_info)) == NULL) {
112 nt_status = NT_STATUS_NO_MEMORY;
113 BAIL_ON_NTSTATUS_ERROR(nt_status);
116 /* Query the rootDSE for the forest root naming conect first.
117 Check that the a GC server for the forest has not already
120 nt_status = gc_find_forest_root(gc, cell_dns_domain(c));
121 BAIL_ON_NTSTATUS_ERROR(nt_status);
123 c->forest_name = talloc_strdup(c, gc->forest_name);
124 BAIL_ON_PTR_ERROR(c->forest_name, nt_status);
134 /**********************************************************************
135 **********************************************************************/
137 NTSTATUS cell_locate_membership(ADS_STRUCT * ads)
140 char *domain_dn = ads_build_dn(lp_realm());
141 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
143 struct likewise_cell *cell = NULL;
145 /* In the Likewise plugin, I had to support the concept of cells
146 based on the machine's membership in an OU. However, now I'll
147 just assume our membership in the forest cell */
149 DEBUG(2, ("locate_cell_membership: Located membership "
150 "in cell \"%s\"\n", domain_dn));
152 if ((cell = cell_new()) == NULL) {
153 nt_status = NT_STATUS_NO_MEMORY;
154 BAIL_ON_NTSTATUS_ERROR(nt_status);
157 status = ads_domain_sid(ads, &sid);
158 if (!ADS_ERR_OK(status)) {
159 DEBUG(3,("locate_cell_membership: Failed to find "
160 "domain SID for %s\n", domain_dn));
163 /* save the SID and search base for our domain */
165 cell_set_dns_domain(cell, lp_realm());
166 cell_set_connection(cell, ads);
167 cell_set_dn(cell, domain_dn);
168 cell_set_domain_sid(cell, &sid);
170 /* Now save our forest root */
172 cell_lookup_forest(cell);
174 /* Add the cell to the list */
176 if (!cell_list_add(cell)) {
177 nt_status = NT_STATUS_INSUFFICIENT_RESOURCES;
178 BAIL_ON_NTSTATUS_ERROR(nt_status);
182 nt_status = NT_STATUS_OK;
185 if (!NT_STATUS_IS_OK(nt_status)) {
186 DEBUG(0,("LWI: Failed to locate cell membership (%s)\n",
187 nt_errstr(nt_status)));
190 SAFE_FREE(domain_dn);
195 /*********************************************************************
196 ********************************************************************/
198 int min_id_value(void)
202 id_val = lp_parm_int(-1, "lwidentity", "min_id_value", MIN_ID_VALUE);
204 /* Still don't let it go below 50 */
206 return MAX(50, id_val);
209 /********************************************************************
210 *******************************************************************/
212 char *cell_dn_to_dns(const char *dn)
214 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
216 char *dns_name = NULL;
219 TALLOC_CTX *frame = talloc_stackframe();
225 tmp_dn = talloc_strdup(frame, dn);
226 BAIL_ON_PTR_ERROR(tmp_dn, nt_status);
228 while (next_token_talloc(frame, &tmp_dn, &buffer, ",")) {
230 /* skip everything up the where DC=... begins */
231 if (StrnCaseCmp(buffer, "DC=", 3) != 0)
235 domain = talloc_strdup(frame, &buffer[3]);
237 domain = talloc_asprintf_append(domain, ".%s",
240 BAIL_ON_PTR_ERROR(domain, nt_status);
243 dns_name = SMB_STRDUP(domain);
244 BAIL_ON_PTR_ERROR(dns_name, nt_status);
246 nt_status = NT_STATUS_OK;
249 PRINT_NTSTATUS_ERROR(nt_status, "cell_dn_to_dns", 1);
251 talloc_destroy(frame);
256 /*********************************************************************
257 ********************************************************************/
259 NTSTATUS get_sid_type(ADS_STRUCT *ads,
261 enum lsa_SidType *type)
263 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
266 if (!ads_pull_uint32(ads, msg, "sAMAccountType", &atype)) {
267 nt_status = NT_STATUS_INVALID_USER_BUFFER;
268 BAIL_ON_NTSTATUS_ERROR(nt_status);
271 switch (atype &0xF0000000) {
272 case ATYPE_SECURITY_GLOBAL_GROUP:
273 *type = SID_NAME_DOM_GRP;
275 case ATYPE_SECURITY_LOCAL_GROUP:
276 *type = SID_NAME_ALIAS;
278 case ATYPE_NORMAL_ACCOUNT:
279 case ATYPE_WORKSTATION_TRUST:
280 case ATYPE_INTERDOMAIN_TRUST:
281 *type = SID_NAME_USER;
284 *type = SID_NAME_USE_NONE;
285 nt_status = NT_STATUS_INVALID_ACCOUNT_NAME;
286 BAIL_ON_NTSTATUS_ERROR(nt_status);
289 nt_status = NT_STATUS_OK;