2 Unix SMB/CIFS implementation.
4 endpoint server for the drsuapi pipe
7 Copyright (C) Stefan Metzmacher 2004
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include "librpc/gen_ndr/ndr_drsuapi.h"
26 #include "rpc_server/dcerpc_server.h"
27 #include "rpc_server/common/common.h"
28 #include "rpc_server/drsuapi/dcesrv_drsuapi.h"
29 #include "lib/ldb/include/ldb.h"
31 static WERROR
DsCrackNameOneName(struct drsuapi_bind_state
*b_state
, TALLOC_CTX
*mem_ctx
,
32 uint32_t format_flags
, uint32_t format_offered
, uint32_t format_desired
,
33 const char *name
, struct drsuapi_DsNameInfo1
*info1
)
36 const char *domain_filter
= NULL
;
37 const char * const *domain_attrs
;
38 struct ldb_message
**domain_res
= NULL
;
39 const char *result_basedn
= NULL
;
40 const char *result_filter
= NULL
;
41 const char * const *result_attrs
;
42 struct ldb_message
**result_res
= NULL
;
44 info1
->status
= DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR
;
45 info1
->dns_domain_name
= NULL
;
46 info1
->result_name
= NULL
;
49 return WERR_INVALID_PARAM
;
52 /* TODO: - fill the correct names in all cases!
53 * - handle format_flags
56 /* here we need to set the domain_filter and/or the result_filter */
57 switch (format_offered
) {
58 case DRSUAPI_DS_NAME_FORMAT_CANONICAL
: {
61 str
= talloc_asprintf(mem_ctx
, "%s/", lp_realm());
62 WERR_TALLOC_CHECK(str
);
64 ret
= strcasecmp(str
, name
);
67 info1
->status
= DRSUAPI_DS_NAME_STATUS_NOT_FOUND
;
71 domain_filter
= talloc_asprintf(mem_ctx
, "(&(objectClass=domainDNS)(name=%s))",
73 WERR_TALLOC_CHECK(domain_filter
);
77 case DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT
: {
80 const char *account
= NULL
;
82 domain
= talloc_strdup(mem_ctx
, name
);
83 WERR_TALLOC_CHECK(domain
);
85 p
= strchr(domain
, '\\');
87 /* invalid input format */
88 info1
->status
= DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR
;
97 domain_filter
= talloc_asprintf(mem_ctx
, "(&(objectClass=domainDNS)(name=%s))",
99 WERR_TALLOC_CHECK(domain_filter
);
101 result_filter
= talloc_asprintf(mem_ctx
, "(sAMAccountName=%s)",
103 WERR_TALLOC_CHECK(result_filter
);
110 info1
->status
= DRSUAPI_DS_NAME_STATUS_NOT_FOUND
;
115 /* here we need to set the attrs lists for domain and result lookups */
116 switch (format_desired
) {
117 case DRSUAPI_DS_NAME_FORMAT_FQDN_1779
: {
118 const char * const _domain_attrs
[] = { "dn", "dnsDomain", NULL
};
119 const char * const _result_attrs
[] = { "dn", NULL
};
121 domain_attrs
= _domain_attrs
;
122 result_attrs
= _result_attrs
;
125 case DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT
: {
126 const char * const _domain_attrs
[] = { "name", "dnsDomain", "dn", NULL
};
127 const char * const _result_attrs
[] = { "sAMAccountName", NULL
};
129 domain_attrs
= _domain_attrs
;
130 result_attrs
= _result_attrs
;
133 case DRSUAPI_DS_NAME_FORMAT_GUID
: {
134 const char * const _domain_attrs
[] = { "objectGUID", "dnsDomain", "dn", NULL
};
135 const char * const _result_attrs
[] = { "objectGUID", NULL
};
137 domain_attrs
= _domain_attrs
;
138 result_attrs
= _result_attrs
;
145 /* if we have a domain_filter look it up and set the result_basedn and the dns_domain_name */
146 ret
= gendb_search(b_state
->sam_ctx
, mem_ctx
, NULL
, &domain_res
, domain_attrs
,
147 "%s", domain_filter
);
152 info1
->status
= DRSUAPI_DS_NAME_STATUS_NOT_FOUND
;
155 info1
->status
= DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR
;
158 info1
->status
= DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE
;
162 info1
->dns_domain_name
= samdb_result_string(domain_res
[0], "dnsDomain", NULL
);
163 WERR_TALLOC_CHECK(info1
->dns_domain_name
);
164 info1
->status
= DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY
;
167 result_basedn
= samdb_result_string(domain_res
[0], "dn", NULL
);
169 ret
= gendb_search(b_state
->sam_ctx
, mem_ctx
, result_basedn
, &result_res
,
170 result_attrs
, "%s", result_filter
);
177 info1
->status
= DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR
;
180 info1
->status
= DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE
;
184 result_res
= domain_res
;
187 /* here we can use result_res[0] and domain_res[0] */
188 switch (format_desired
) {
189 case DRSUAPI_DS_NAME_FORMAT_FQDN_1779
: {
190 info1
->result_name
= samdb_result_string(result_res
[0], "dn", NULL
);
191 WERR_TALLOC_CHECK(info1
->result_name
);
193 info1
->status
= DRSUAPI_DS_NAME_STATUS_OK
;
196 case DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT
: {
198 const char *_acc
= "";
200 _dom
= samdb_result_string(domain_res
[0], "name", NULL
);
201 WERR_TALLOC_CHECK(_dom
);
204 _acc
= samdb_result_string(result_res
[0], "sAMAccountName", NULL
);
205 WERR_TALLOC_CHECK(_acc
);
208 info1
->result_name
= talloc_asprintf(mem_ctx
, "%s\\%s", _dom
, _acc
);
209 WERR_TALLOC_CHECK(info1
->result_name
);
211 info1
->status
= DRSUAPI_DS_NAME_STATUS_OK
;
214 case DRSUAPI_DS_NAME_FORMAT_GUID
: {
217 result
= samdb_result_string(result_res
[0], "objectGUID", NULL
);
218 WERR_TALLOC_CHECK(result
);
220 info1
->result_name
= talloc_asprintf(mem_ctx
, "{%s}", result
);
221 WERR_TALLOC_CHECK(info1
->result_name
);
223 info1
->status
= DRSUAPI_DS_NAME_STATUS_OK
;
230 return WERR_INVALID_PARAM
;
236 WERROR
dcesrv_drsuapi_DsCrackNames(struct dcesrv_call_state
*dce_call
, TALLOC_CTX
*mem_ctx
,
237 struct drsuapi_DsCrackNames
*r
)
240 struct drsuapi_bind_state
*b_state
;
241 struct dcesrv_handle
*h
;
243 r
->out
.level
= r
->in
.level
;
244 ZERO_STRUCT(r
->out
.ctr
);
246 DCESRV_PULL_HANDLE_WERR(h
, r
->in
.bind_handle
, DRSUAPI_BIND_HANDLE
);
249 switch (r
->in
.level
) {
251 struct drsuapi_DsNameCtr1
*ctr1
;
252 struct drsuapi_DsNameInfo1
*names
;
256 ctr1
= talloc(mem_ctx
, struct drsuapi_DsNameCtr1
);
257 WERR_TALLOC_CHECK(ctr1
);
259 count
= r
->in
.req
.req1
.count
;
260 names
= talloc_array(mem_ctx
, struct drsuapi_DsNameInfo1
, count
);
261 WERR_TALLOC_CHECK(names
);
263 for (i
=0; i
< count
; i
++) {
264 status
= DsCrackNameOneName(b_state
, mem_ctx
,
265 r
->in
.req
.req1
.format_flags
,
266 r
->in
.req
.req1
.format_offered
,
267 r
->in
.req
.req1
.format_desired
,
268 r
->in
.req
.req1
.names
[i
].str
,
270 if (!W_ERROR_IS_OK(status
)) {
277 r
->out
.ctr
.ctr1
= ctr1
;
283 return WERR_UNKNOWN_LEVEL
;