• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/router/samba-3.5.8/source4/libgpo/
1/*
2   Samba CIFS implementation
3   ADS convenience functions for GPO
4
5   Copyright (C) 2001 Andrew Tridgell (from samba3 ads.c)
6   Copyright (C) 2001 Remus Koos (from samba3 ads.c)
7   Copyright (C) 2001 Andrew Bartlett (from samba3 ads.c)
8   Copyright (C) 2008 Jelmer Vernooij, jelmer@samba.org
9   Copyright (C) 2008 Wilco Baan Hofman, wilco@baanhofman.nl
10
11   This program is free software; you can redistribute it and/or modify
12   it under the terms of the GNU General Public License as published by
13   the Free Software Foundation; either version 3 of the License, or
14   (at your option) any later version.
15
16   This program is distributed in the hope that it will be useful,
17   but WITHOUT ANY WARRANTY; without even the implied warranty of
18   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19   GNU General Public License for more details.
20
21   You should have received a copy of the GNU General Public License
22   along with this program.  If not, see <http://www.gnu.org/licenses/>.
23*/
24
25#include "includes.h"
26#include "libnet/libnet.h"
27#include "librpc/gen_ndr/ndr_security.h"
28#include "libgpo/ads_convenience.h"
29#include "param/param.h"
30#include "libcli/libcli.h"
31#include "ldb_wrap.h"
32
33static ADS_STATUS ads_connect(ADS_STRUCT *ads);
34
35WERROR ads_startup (struct libnet_context *netctx, ADS_STRUCT **ads)
36{
37	*ads = talloc(netctx, ADS_STRUCT);
38	(*ads)->netctx = netctx;
39
40	ads_connect(*ads);
41
42	return WERR_OK;
43}
44
45static ADS_STATUS ads_connect(ADS_STRUCT *ads)
46{
47	struct libnet_LookupDCs *io;
48	char *url;
49
50	io = talloc_zero(ads, struct libnet_LookupDCs);
51
52	/* We are looking for the PDC of the active domain. */
53	io->in.name_type = NBT_NAME_PDC;
54	io->in.domain_name = lp_workgroup(ads->netctx->lp_ctx);
55	libnet_LookupDCs(ads->netctx, ads, io);
56
57	url = talloc_asprintf(ads, "ldap://%s", io->out.dcs[0].name);
58	ads->ldbctx = ldb_wrap_connect(ads, ads->netctx->event_ctx, ads->netctx->lp_ctx,
59	                 url, NULL, ads->netctx->cred, 0, NULL);
60	if (ads->ldbctx == NULL) {
61		return ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL);
62	}
63
64	return ADS_ERROR_NT(NT_STATUS_OK);
65}
66
67ADS_STATUS ads_search_dn(ADS_STRUCT *ads, LDAPMessage **res,
68                         const char *dn, const char **attrs)
69{
70	ADS_STATUS status;
71
72	status.err.rc = ldb_search(ads->ldbctx, ads, res,
73	                              ldb_dn_new(ads, ads->ldbctx, dn),
74	                              LDB_SCOPE_BASE,
75                                      attrs,
76	                              "(objectclass=*)");
77
78	status.error_type = ENUM_ADS_ERROR_LDAP;
79	return status;
80}
81
82const char * ads_get_dn(ADS_STRUCT *ads, LDAPMessage *res)
83{
84	return ldb_dn_get_linearized(res->msgs[0]->dn);
85}
86
87bool ads_pull_sd(ADS_STRUCT *ads, TALLOC_CTX *ctx, LDAPMessage *res, const char *field, struct security_descriptor **sd)
88{
89	const struct ldb_val *val;
90	enum ndr_err_code ndr_err;
91
92	val = ldb_msg_find_ldb_val(res->msgs[0], field);
93
94        *sd = talloc(ctx, struct security_descriptor);
95        if (*sd == NULL) {
96                return -1;
97        }
98        /* We can't use ndr_pull_struct_blob_all because this contains relative pointers */
99        ndr_err = ndr_pull_struct_blob(val, *sd, NULL, *sd,
100                                           (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
101        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
102                talloc_free(*sd);
103                return -1;
104        }
105	return 0;
106}
107
108ADS_STATUS ads_search_retry_dn_sd_flags(ADS_STRUCT *ads, LDAPMessage **res, uint32_t sd_flags,
109                                        const char *dn, const char **attrs)
110{
111	return ads_do_search_all_sd_flags(ads, dn, LDB_SCOPE_BASE, "(objectclass=*)", attrs, sd_flags, res);
112}
113
114ADS_STATUS ads_do_search_all_sd_flags (ADS_STRUCT *ads, const char *dn, int scope,
115                                              const char *filter, const char **attrs,
116                                              uint32_t sd_flags, LDAPMessage **res)
117{
118	int rv;
119	struct ldb_request *req;
120	struct ldb_control **controls;
121	struct ldb_parse_tree *tree;
122	struct ldb_dn *ldb_dn;
123
124	controls = talloc_zero_array(ads, struct ldb_control *, 2);
125	controls[0] = talloc(ads, struct ldb_control);
126	controls[0]->oid = LDB_CONTROL_SD_FLAGS_OID;
127	controls[0]->data = &sd_flags;
128	controls[0]->critical = 1;
129
130	tree = ldb_parse_tree(ads, filter);
131
132	ldb_dn = ldb_dn_new(ads, ads->ldbctx, dn);
133
134	rv = ldb_build_search_req_ex(&req, ads->ldbctx, (TALLOC_CTX *)res, ldb_dn, scope, tree, attrs, controls,
135	                             res, ldb_search_default_callback, NULL);
136	if (rv != LDB_SUCCESS) {
137		talloc_free(*res);
138		talloc_free(req);
139		talloc_free(tree);
140		return ADS_ERROR(rv);
141	}
142	rv = ldb_request(ads->ldbctx, req);
143	if (rv == LDB_SUCCESS) {
144		rv = ldb_wait(req->handle, LDB_WAIT_ALL);
145	}
146
147	talloc_free(req);
148	talloc_free(tree);
149	return ADS_ERROR(rv);
150
151}
152
153const char * ads_pull_string(ADS_STRUCT *ads, TALLOC_CTX *ctx, LDAPMessage *res, const char *field)
154{
155	return ldb_msg_find_attr_as_string(res->msgs[0], field, NULL);
156}
157
158bool ads_pull_uint32(ADS_STRUCT *ads, LDAPMessage *res, const char *field, uint32_t *ret)
159{
160	if (ldb_msg_find_element(res->msgs[0], field) == NULL) {
161		return false;
162	}
163	*ret = ldb_msg_find_attr_as_uint(res->msgs[0], field, 0);
164	return true;
165}
166
167
168int ads_count_replies(ADS_STRUCT *ads, LDAPMessage *res)
169{
170	return res->count;
171}
172
173ADS_STATUS ads_msgfree(ADS_STRUCT *ads, LDAPMessage *res)
174{
175	talloc_free(res);
176	return ADS_ERROR_NT(NT_STATUS_OK);
177}
178
179/*
180  do a rough conversion between ads error codes and NT status codes
181  we'll need to fill this in more
182*/
183NTSTATUS ads_ntstatus(ADS_STATUS status)
184{
185	switch (status.error_type) {
186	case ENUM_ADS_ERROR_NT:
187		return status.err.nt_status;
188	case ENUM_ADS_ERROR_SYSTEM:
189		return map_nt_error_from_unix(status.err.rc);
190	case ENUM_ADS_ERROR_LDAP:
191		if (status.err.rc == LDB_SUCCESS) {
192			return NT_STATUS_OK;
193		}
194		return NT_STATUS_UNSUCCESSFUL;
195	default:
196		break;
197	}
198
199	if (ADS_ERR_OK(status)) {
200		return NT_STATUS_OK;
201	}
202	return NT_STATUS_UNSUCCESSFUL;
203}
204
205/*
206  return a string for an error from an ads routine
207*/
208const char *ads_errstr(ADS_STATUS status)
209{
210	switch (status.error_type) {
211	case ENUM_ADS_ERROR_SYSTEM:
212		return strerror(status.err.rc);
213	case ENUM_ADS_ERROR_LDAP:
214		return ldb_strerror(status.err.rc);
215	case ENUM_ADS_ERROR_NT:
216		return get_friendly_nt_error_msg(ads_ntstatus(status));
217	default:
218		return "Unknown ADS error type!? (not compiled in?)";
219	}
220}
221
222ADS_STATUS ads_build_ldap_error(int ldb_error)
223{
224	ADS_STATUS ret;
225	ret.err.rc = ldb_error;
226	ret.error_type = ENUM_ADS_ERROR_LDAP;
227	return ret;
228}
229
230ADS_STATUS ads_build_nt_error(NTSTATUS nt_status)
231{
232	ADS_STATUS ret;
233	ret.err.nt_status = nt_status;
234	ret.error_type = ENUM_ADS_ERROR_NT;
235	return ret;
236}
237
238
239bool nt_token_check_sid( const struct dom_sid *sid, const NT_USER_TOKEN *token)
240{
241	int i;
242
243	if (!sid || !token) {
244		return false;
245	}
246
247	if (dom_sid_equal(sid, token->user_sid)) {
248		return true;
249	}
250	if (dom_sid_equal(sid, token->group_sid)) {
251		return true;
252	}
253	for (i = 0; i < token->num_sids; i++) {
254		if (dom_sid_equal(sid, token->sids[i])) {
255			return true;
256		}
257	}
258
259	return false;
260}
261const char *ads_get_ldap_server_name(ADS_STRUCT *ads) {
262	return ads->ldap_server_name;
263}
264
265
266/*
267  FIXME
268  Stub write functions, these do not do anything, though they should. -- Wilco
269*/
270
271ADS_MODLIST ads_init_mods(TALLOC_CTX *ctx)
272{
273	return NULL;
274}
275
276ADS_STATUS ads_mod_str(TALLOC_CTX *ctx, ADS_MODLIST *mods, const char *name, const char *val)
277{
278	return ADS_ERROR_NT(NT_STATUS_NOT_IMPLEMENTED);
279}
280
281ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, ADS_MODLIST mods)
282{
283	return ADS_ERROR_NT(NT_STATUS_NOT_IMPLEMENTED);
284}
285