2 Unix SMB/CIFS implementation.
4 Implements functions offered by repadmin.exe tool under Windows
6 Copyright (C) Kamen Mazdrashki <kamen.mazdrashki@postpath.com> 2010
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "utils/net/net.h"
24 #include "utils/net/drs/net_drs.h"
25 #include "lib/ldb/include/ldb.h"
28 static bool net_drs_kcc_site_info(struct net_drs_context *drs_ctx,
29 const char **site_name,
30 uint32_t *site_options)
33 const struct ldb_val *ldb_val;
36 struct ldb_result *ldb_res;
37 static const char *attrs[] = {
43 mem_ctx = talloc_new(drs_ctx);
45 /* get dsServiceName, which is NTDS Settings
46 * object for the server
47 * e.g.: CN=NTDS Settings,CN=<DC_NAME>,CN=Servers,CN=<SITE_NAME>,CN=Sites,<CONFIG> */
48 dn = ldb_msg_find_attr_as_dn(drs_ctx->ldap.ldb, mem_ctx, drs_ctx->ldap.rootdse, "dsServiceName");
50 d_printf("No dsServiceName value in RootDSE!\n");
54 /* work out site name */
55 if (!ldb_dn_remove_child_components(dn, 3)) {
56 d_printf("Failed to find Site DN.\n");
60 ldb_val = ldb_dn_get_rdn_val(dn);
62 d_printf("Failed to get site name.\n");
65 *site_name = talloc_strndup(drs_ctx, (const char*)ldb_val->data, ldb_val->length);
67 /* get 'NTDS Site Settings' */
68 if (!ldb_dn_add_child_fmt(dn, "CN=NTDS Site Settings")) {
69 d_printf("Failed to create NTDS Site Settings DN.\n");
73 ret = ldb_search(drs_ctx->ldap.ldb, mem_ctx, &ldb_res,
74 dn, LDB_SCOPE_BASE, attrs, "(objectClass=*)");
75 if (ret != LDB_SUCCESS) {
76 d_printf("Failed to get Site object\n");
79 if (ldb_res->count != 1) {
80 d_printf("Error: returned %d messages for Site object.\n", ldb_res->count);
83 *site_options = ldb_msg_find_attr_as_uint(ldb_res->msgs[0], "options", 0);
94 * 'net drs kcc' command entry point
96 int net_drs_kcc_cmd(struct net_context *ctx, int argc, const char **argv)
99 struct net_drs_context *drs_ctx;
100 struct net_drs_connection *drs_conn;
101 struct drsuapi_DsBindInfo48 *info48;
102 struct drsuapi_DsExecuteKCC req;
103 union drsuapi_DsExecuteKCCRequest kcc_req;
104 const char *site_name;
105 uint32_t site_options;
107 /* only one arg expected */
109 return net_drs_kcc_usage(ctx, argc, argv);
112 if (!net_drs_create_context(ctx, argv[0], &drs_ctx)) {
115 drs_conn = drs_ctx->drs_conn;
116 info48 = &drs_conn->info48;
118 /* check if target DC supports ExecuteKCC */
119 if (!(info48->supported_extensions & DRSUAPI_SUPPORTED_EXTENSION_KCC_EXECUTE)) {
120 d_printf("%s does not support EXECUTE_KCC extension.\n", drs_ctx->dc_name);
124 /* gather some Site info */
125 if (!net_drs_kcc_site_info(drs_ctx, &site_name, &site_options)) {
129 d_printf("%s\n", site_name);
131 /* TODO: print meaningfull site options here */
132 d_printf("Current Site Options: 0x%X\n", site_options);
134 d_printf("Current Site Options: (none)\n");
139 ZERO_STRUCT(kcc_req);
140 req.in.bind_handle = &drs_conn->bind_handle;
142 req.in.req = &kcc_req;
143 status = dcerpc_drsuapi_DsExecuteKCC_r(drs_conn->drs_handle, drs_ctx, &req);
144 if (!NT_STATUS_IS_OK(status)) {
145 const char *errstr = nt_errstr(status);
146 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
147 errstr = dcerpc_errstr(drs_ctx, drs_conn->drs_pipe->last_fault_code);
149 d_printf("dcerpc_drsuapi_DsExecuteKCC failed - %s.\n", errstr);
151 } else if (!W_ERROR_IS_OK(req.out.result)) {
152 d_printf("DsExecuteKCC failed - %s.\n", win_errstr(req.out.result));
156 d_printf("Consistency check on %s successful.\n", drs_ctx->dc_name);
158 talloc_free(drs_ctx);
162 talloc_free(drs_ctx);
167 * 'net drs kcc' usage
169 int net_drs_kcc_usage(struct net_context *ctx, int argc, const char **argv)
171 d_printf("net drs kcc <DC_NAME>\n");