dsdb: Allow dsdb_find_dn_by_guid to show deleted DNs
[Samba/id10ts.git] / source4 / dsdb / kcc / kcc_connection.c
blobf85ed13f5532df079d41bfb3f9bb5541d9ca1d16
1 /*
2 Unix SMB/CIFS implementation.
3 KCC service periodic handling
5 Copyright (C) Crístian Deives
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "includes.h"
23 #include "lib/events/events.h"
24 #include "dsdb/samdb/samdb.h"
25 #include "auth/auth.h"
26 #include "smbd/service.h"
27 #include "lib/messaging/irpc.h"
28 #include "dsdb/kcc/kcc_service.h"
29 #include "dsdb/kcc/kcc_connection.h"
30 #include <ldb_errors.h>
31 #include "../lib/util/dlinklist.h"
32 #include "librpc/gen_ndr/ndr_misc.h"
33 #include "librpc/gen_ndr/ndr_drsuapi.h"
34 #include "librpc/gen_ndr/ndr_drsblobs.h"
35 #include "param/param.h"
37 static int kccsrv_add_connection(struct kccsrv_service *s,
38 struct kcc_connection *conn)
40 struct ldb_message *msg;
41 TALLOC_CTX *tmp_ctx;
42 struct ldb_dn *new_dn, *server_dn;
43 struct GUID guid;
44 /* struct ldb_val schedule_val; */
45 int ret;
46 bool ok;
48 tmp_ctx = talloc_new(s);
49 if (!tmp_ctx) {
50 DEBUG(0, ("failed to talloc\n"));
51 ret = LDB_ERR_OPERATIONS_ERROR;
52 goto done;
54 new_dn = samdb_ntds_settings_dn(s->samdb, tmp_ctx);
55 if (!new_dn) {
56 DEBUG(0, ("failed to find NTDS settings\n"));
57 ret = LDB_ERR_OPERATIONS_ERROR;
58 goto done;
60 new_dn = ldb_dn_copy(tmp_ctx, new_dn);
61 if (!new_dn) {
62 DEBUG(0, ("failed to copy NTDS settings\n"));
63 ret = LDB_ERR_OPERATIONS_ERROR;
64 goto done;
66 guid = GUID_random();
67 ok = ldb_dn_add_child_fmt(new_dn, "CN=%s", GUID_string(tmp_ctx, &guid));
68 if (!ok) {
69 DEBUG(0, ("failed to create nTDSConnection DN\n"));
70 ret = LDB_ERR_INVALID_DN_SYNTAX;
71 goto done;
73 ret = dsdb_find_dn_by_guid(s->samdb, tmp_ctx, &conn->dsa_guid, 0, &server_dn);
74 if (ret != LDB_SUCCESS) {
75 DEBUG(0, ("failed to find fromServer DN '%s'\n",
76 GUID_string(tmp_ctx, &conn->dsa_guid)));
77 goto done;
79 /*schedule_val = data_blob_const(r1->schedule, sizeof(r1->schedule));*/
81 msg = ldb_msg_new(tmp_ctx);
82 msg->dn = new_dn;
83 ldb_msg_add_string(msg, "objectClass", "nTDSConnection");
84 ldb_msg_add_string(msg, "showInAdvancedViewOnly", "TRUE");
85 ldb_msg_add_string(msg, "enabledConnection", "TRUE");
86 ldb_msg_add_linearized_dn(msg, "fromServer", server_dn);
87 /* ldb_msg_add_value(msg, "schedule", &schedule_val, NULL); */
89 samdb_msg_add_uint(s->samdb, msg, msg,
90 "options", NTDSCONN_OPT_IS_GENERATED);
92 ret = ldb_add(s->samdb, msg);
93 if (ret == LDB_SUCCESS) {
94 DEBUG(2, ("added nTDSConnection object '%s'\n",
95 ldb_dn_get_linearized(new_dn)));
96 } else {
97 DEBUG(0, ("failed to add an nTDSConnection object: %s\n",
98 ldb_strerror(ret)));
101 done:
102 talloc_free(tmp_ctx);
103 return ret;
106 static int kccsrv_delete_connection(struct kccsrv_service *s,
107 struct kcc_connection *conn)
109 TALLOC_CTX *tmp_ctx;
110 struct ldb_dn *dn;
111 int ret;
113 tmp_ctx = talloc_new(s);
114 ret = dsdb_find_dn_by_guid(s->samdb, tmp_ctx, &conn->obj_guid, 0, &dn);
115 if (ret != LDB_SUCCESS) {
116 DEBUG(0, ("failed to find nTDSConnection's DN: %s\n",
117 ldb_strerror(ret)));
118 goto done;
121 ret = ldb_delete(s->samdb, dn);
122 if (ret == LDB_SUCCESS) {
123 DEBUG(2, ("deleted nTDSConnection object '%s'\n",
124 ldb_dn_get_linearized(dn)));
125 } else {
126 DEBUG(0, ("failed to delete an nTDSConnection object: %s\n",
127 ldb_strerror(ret)));
130 done:
131 talloc_free(tmp_ctx);
132 return ret;
135 void kccsrv_apply_connections(struct kccsrv_service *s,
136 struct kcc_connection_list *ntds_list,
137 struct kcc_connection_list *dsa_list)
139 unsigned int i, j, deleted = 0, added = 0;
140 int ret;
142 /* XXX
144 * This routine is not respecting connections that the
145 * administrator can specifically create (NTDSCONN_OPT_IS_GENERATED
146 * bit will not be set)
148 for (i = 0; ntds_list && i < ntds_list->count; i++) {
149 struct kcc_connection *ntds = &ntds_list->servers[i];
150 for (j = 0; j < dsa_list->count; j++) {
151 struct kcc_connection *dsa = &dsa_list->servers[j];
152 if (GUID_equal(&ntds->dsa_guid, &dsa->dsa_guid)) {
153 break;
156 if (j == dsa_list->count) {
157 ret = kccsrv_delete_connection(s, ntds);
158 if (ret == LDB_SUCCESS) {
159 deleted++;
163 DEBUG(4, ("%d connections have been deleted\n", deleted));
165 for (i = 0; i < dsa_list->count; i++) {
166 struct kcc_connection *dsa = &dsa_list->servers[i];
167 for (j = 0; ntds_list && j < ntds_list->count; j++) {
168 struct kcc_connection *ntds = &ntds_list->servers[j];
169 if (GUID_equal(&dsa->dsa_guid, &ntds->dsa_guid)) {
170 break;
173 if (ntds_list == NULL || j == ntds_list->count) {
174 ret = kccsrv_add_connection(s, dsa);
175 if (ret == LDB_SUCCESS) {
176 added++;
180 DEBUG(4, ("%d connections have been added\n", added));
183 struct kcc_connection_list *kccsrv_find_connections(struct kccsrv_service *s,
184 TALLOC_CTX *mem_ctx)
186 unsigned int i;
187 int ret;
188 struct ldb_dn *base_dn;
189 struct ldb_result *res;
190 const char *attrs[] = { "objectGUID", "fromServer", NULL };
191 struct kcc_connection_list *list;
192 TALLOC_CTX *tmp_ctx;
193 kcctpl_test(s);
195 tmp_ctx = talloc_new(mem_ctx);
196 if (!tmp_ctx) {
197 DEBUG(0, ("failed to talloc\n"));
198 return NULL;
201 base_dn = samdb_ntds_settings_dn(s->samdb, tmp_ctx);
202 if (!base_dn) {
203 DEBUG(0, ("failed to find our own NTDS settings DN\n"));
204 talloc_free(tmp_ctx);
205 return NULL;
208 ret = ldb_search(s->samdb, tmp_ctx, &res, base_dn, LDB_SCOPE_ONELEVEL,
209 attrs, "objectClass=nTDSConnection");
210 if (ret != LDB_SUCCESS) {
211 DEBUG(0, ("failed nTDSConnection search: %s\n",
212 ldb_strerror(ret)));
213 talloc_free(tmp_ctx);
214 return NULL;
217 list = talloc(tmp_ctx, struct kcc_connection_list);
218 if (!list) {
219 DEBUG(0, ("out of memory"));
220 return NULL;
222 list->servers = talloc_array(list, struct kcc_connection,
223 res->count);
224 if (!list->servers) {
225 DEBUG(0, ("out of memory"));
226 talloc_free(tmp_ctx);
227 return NULL;
229 list->count = 0;
231 for (i = 0; i < res->count; i++) {
232 struct ldb_dn *server_dn;
234 list->servers[i].obj_guid = samdb_result_guid(res->msgs[i],
235 "objectGUID");
236 server_dn = samdb_result_dn(s->samdb, mem_ctx, res->msgs[i],
237 "fromServer", NULL);
238 ret = dsdb_find_guid_by_dn(s->samdb, server_dn,
239 &list->servers[i].dsa_guid);
240 if (ret != LDB_SUCCESS) {
241 DEBUG(0, ("Failed to find connection server's GUID by "
242 "DN=%s: %s\n",
243 ldb_dn_get_linearized(server_dn),
244 ldb_strerror(ret)));
245 continue;
247 list->count++;
249 DEBUG(4, ("found %d existing nTDSConnection objects\n", list->count));
250 talloc_steal(mem_ctx, list);
251 talloc_free(tmp_ctx);
252 return list;