s3:docs: Document "aio write behind".
[Samba/gebeck_regimport.git] / source4 / libgpo / ads_convenience.c
blob09ceecc752e3ed14383e0cfd2b1ec88c72a3a43f
1 /*
2 Samba CIFS implementation
3 ADS convenience functions for GPO
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
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.
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.
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/>.
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"
33 static ADS_STATUS ads_connect(ADS_STRUCT *ads);
35 WERROR ads_startup (struct libnet_context *netctx, ADS_STRUCT **ads)
37 *ads = talloc(netctx, ADS_STRUCT);
38 (*ads)->netctx = netctx;
40 ads_connect(*ads);
42 return WERR_OK;
45 static ADS_STATUS ads_connect(ADS_STRUCT *ads)
47 struct libnet_LookupDCs *io;
48 char *url;
50 io = talloc_zero(ads, struct libnet_LookupDCs);
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);
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);
60 if (ads->ldbctx == NULL) {
61 return ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL);
64 return ADS_ERROR_NT(NT_STATUS_OK);
67 ADS_STATUS ads_search_dn(ADS_STRUCT *ads, LDAPMessage **res,
68 const char *dn, const char **attrs)
70 ADS_STATUS status;
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=*)");
78 status.error_type = ENUM_ADS_ERROR_LDAP;
79 return status;
82 const char * ads_get_dn(ADS_STRUCT *ads, LDAPMessage *res)
84 return ldb_dn_get_linearized(res->msgs[0]->dn);
87 bool ads_pull_sd(ADS_STRUCT *ads, TALLOC_CTX *ctx, LDAPMessage *res, const char *field, struct security_descriptor **sd)
89 const struct ldb_val *val;
90 enum ndr_err_code ndr_err;
92 val = ldb_msg_find_ldb_val(res->msgs[0], field);
94 *sd = talloc(ctx, struct security_descriptor);
95 if (*sd == NULL) {
96 return -1;
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;
105 return 0;
108 ADS_STATUS ads_search_retry_dn_sd_flags(ADS_STRUCT *ads, LDAPMessage **res, uint32_t sd_flags,
109 const char *dn, const char **attrs)
111 return ads_do_search_all_sd_flags(ads, dn, LDB_SCOPE_BASE, "(objectclass=*)", attrs, sd_flags, res);
114 ADS_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)
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;
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;
130 tree = ldb_parse_tree(ads, filter);
132 ldb_dn = ldb_dn_new(ads, ads->ldbctx, dn);
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);
142 rv = ldb_request(ads->ldbctx, req);
143 if (rv == LDB_SUCCESS) {
144 rv = ldb_wait(req->handle, LDB_WAIT_ALL);
147 talloc_free(req);
148 talloc_free(tree);
149 return ADS_ERROR(rv);
153 const char * ads_pull_string(ADS_STRUCT *ads, TALLOC_CTX *ctx, LDAPMessage *res, const char *field)
155 return ldb_msg_find_attr_as_string(res->msgs[0], field, NULL);
158 bool ads_pull_uint32(ADS_STRUCT *ads, LDAPMessage *res, const char *field, uint32_t *ret)
160 if (ldb_msg_find_element(res->msgs[0], field) == NULL) {
161 return false;
163 *ret = ldb_msg_find_attr_as_uint(res->msgs[0], field, 0);
164 return true;
168 int ads_count_replies(ADS_STRUCT *ads, LDAPMessage *res)
170 return res->count;
173 ADS_STATUS ads_msgfree(ADS_STRUCT *ads, LDAPMessage *res)
175 talloc_free(res);
176 return ADS_ERROR_NT(NT_STATUS_OK);
180 do a rough conversion between ads error codes and NT status codes
181 we'll need to fill this in more
183 NTSTATUS ads_ntstatus(ADS_STATUS status)
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;
194 return NT_STATUS_UNSUCCESSFUL;
195 default:
196 break;
199 if (ADS_ERR_OK(status)) {
200 return NT_STATUS_OK;
202 return NT_STATUS_UNSUCCESSFUL;
206 return a string for an error from an ads routine
208 const char *ads_errstr(ADS_STATUS status)
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?)";
222 ADS_STATUS ads_build_ldap_error(int ldb_error)
224 ADS_STATUS ret;
225 ret.err.rc = ldb_error;
226 ret.error_type = ENUM_ADS_ERROR_LDAP;
227 return ret;
230 ADS_STATUS ads_build_nt_error(NTSTATUS nt_status)
232 ADS_STATUS ret;
233 ret.err.nt_status = nt_status;
234 ret.error_type = ENUM_ADS_ERROR_NT;
235 return ret;
239 bool nt_token_check_sid( const struct dom_sid *sid, const NT_USER_TOKEN *token)
241 int i;
243 if (!sid || !token) {
244 return false;
247 if (dom_sid_equal(sid, token->user_sid)) {
248 return true;
250 if (dom_sid_equal(sid, token->group_sid)) {
251 return true;
253 for (i = 0; i < token->num_sids; i++) {
254 if (dom_sid_equal(sid, token->sids[i])) {
255 return true;
259 return false;
261 const char *ads_get_ldap_server_name(ADS_STRUCT *ads) {
262 return ads->ldap_server_name;
267 FIXME
268 Stub write functions, these do not do anything, though they should. -- Wilco
271 ADS_MODLIST ads_init_mods(TALLOC_CTX *ctx)
273 return NULL;
276 ADS_STATUS ads_mod_str(TALLOC_CTX *ctx, ADS_MODLIST *mods, const char *name, const char *val)
278 return ADS_ERROR_NT(NT_STATUS_NOT_IMPLEMENTED);
281 ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, ADS_MODLIST mods)
283 return ADS_ERROR_NT(NT_STATUS_NOT_IMPLEMENTED);