source: branches/samba-3.5.x/source4/libgpo/ads_convenience.c

Last change on this file was 414, checked in by Herwig Bauernfeind, 16 years ago

Samba 3.5.0: Initial import

File size: 7.4 KB
Line 
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}
Note: See TracBrowser for help on using the repository browser.