source: trunk/server/source4/dsdb/kcc/kcc_connection.c

Last change on this file was 745, checked in by Silvan Scherrer, 13 years ago

Samba Server: updated trunk to 3.6.0

File size: 6.5 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3 KCC service periodic handling
4
5 Copyright (C) Crístian Deives
6
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.
11
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.
16
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/>.
19
20*/
21
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"
36
37static int kccsrv_add_connection(struct kccsrv_service *s,
38 struct kcc_connection *conn)
39{
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;
47
48 tmp_ctx = talloc_new(s);
49 new_dn = samdb_ntds_settings_dn(s->samdb);
50 if (!new_dn) {
51 DEBUG(0, ("failed to find NTDS settings\n"));
52 ret = LDB_ERR_OPERATIONS_ERROR;
53 goto done;
54 }
55 new_dn = ldb_dn_copy(tmp_ctx, new_dn);
56 if (!new_dn) {
57 DEBUG(0, ("failed to copy NTDS settings\n"));
58 ret = LDB_ERR_OPERATIONS_ERROR;
59 goto done;
60 }
61 guid = GUID_random();
62 ok = ldb_dn_add_child_fmt(new_dn, "CN=%s", GUID_string(tmp_ctx, &guid));
63 if (!ok) {
64 DEBUG(0, ("failed to create nTDSConnection DN\n"));
65 ret = LDB_ERR_INVALID_DN_SYNTAX;
66 goto done;
67 }
68 ret = dsdb_find_dn_by_guid(s->samdb, tmp_ctx, &conn->dsa_guid, &server_dn);
69 if (ret != LDB_SUCCESS) {
70 DEBUG(0, ("failed to find fromServer DN '%s'\n",
71 GUID_string(tmp_ctx, &conn->dsa_guid)));
72 goto done;
73 }
74 /*schedule_val = data_blob_const(r1->schedule, sizeof(r1->schedule));*/
75
76 msg = ldb_msg_new(tmp_ctx);
77 msg->dn = new_dn;
78 ldb_msg_add_string(msg, "objectClass", "nTDSConnection");
79 ldb_msg_add_string(msg, "showInAdvancedViewOnly", "TRUE");
80 ldb_msg_add_string(msg, "enabledConnection", "TRUE");
81 ldb_msg_add_linearized_dn(msg, "fromServer", server_dn);
82 /* ldb_msg_add_value(msg, "schedule", &schedule_val, NULL); */
83 samdb_msg_add_uint(s->samdb, msg, msg, "options", 1);
84
85 ret = ldb_add(s->samdb, msg);
86 if (ret == LDB_SUCCESS) {
87 DEBUG(2, ("added nTDSConnection object '%s'\n",
88 ldb_dn_get_linearized(new_dn)));
89 } else {
90 DEBUG(0, ("failed to add an nTDSConnection object: %s\n",
91 ldb_strerror(ret)));
92 }
93
94done:
95 talloc_free(tmp_ctx);
96 return ret;
97}
98
99static int kccsrv_delete_connection(struct kccsrv_service *s,
100 struct kcc_connection *conn)
101{
102 TALLOC_CTX *tmp_ctx;
103 struct ldb_dn *dn;
104 int ret;
105
106 tmp_ctx = talloc_new(s);
107 ret = dsdb_find_dn_by_guid(s->samdb, tmp_ctx, &conn->obj_guid, &dn);
108 if (ret != LDB_SUCCESS) {
109 DEBUG(0, ("failed to find nTDSConnection's DN: %s\n",
110 ldb_strerror(ret)));
111 goto done;
112 }
113
114 ret = ldb_delete(s->samdb, dn);
115 if (ret == LDB_SUCCESS) {
116 DEBUG(2, ("deleted nTDSConnection object '%s'\n",
117 ldb_dn_get_linearized(dn)));
118 } else {
119 DEBUG(0, ("failed to delete an nTDSConnection object: %s\n",
120 ldb_strerror(ret)));
121 }
122
123done:
124 talloc_free(tmp_ctx);
125 return ret;
126}
127
128void kccsrv_apply_connections(struct kccsrv_service *s,
129 struct kcc_connection_list *ntds_list,
130 struct kcc_connection_list *dsa_list)
131{
132 unsigned int i, j, deleted = 0, added = 0;
133 int ret;
134
135 for (i = 0; ntds_list && i < ntds_list->count; i++) {
136 struct kcc_connection *ntds = &ntds_list->servers[i];
137 for (j = 0; j < dsa_list->count; j++) {
138 struct kcc_connection *dsa = &dsa_list->servers[j];
139 if (GUID_equal(&ntds->dsa_guid, &dsa->dsa_guid)) {
140 break;
141 }
142 }
143 if (j == dsa_list->count) {
144 ret = kccsrv_delete_connection(s, ntds);
145 if (ret == LDB_SUCCESS) {
146 deleted++;
147 }
148 }
149 }
150 DEBUG(4, ("%d connections have been deleted\n", deleted));
151
152 for (i = 0; i < dsa_list->count; i++) {
153 struct kcc_connection *dsa = &dsa_list->servers[i];
154 for (j = 0; ntds_list && j < ntds_list->count; j++) {
155 struct kcc_connection *ntds = &ntds_list->servers[j];
156 if (GUID_equal(&dsa->dsa_guid, &ntds->dsa_guid)) {
157 break;
158 }
159 }
160 if (ntds_list == NULL || j == ntds_list->count) {
161 ret = kccsrv_add_connection(s, dsa);
162 if (ret == LDB_SUCCESS) {
163 added++;
164 }
165 }
166 }
167 DEBUG(4, ("%d connections have been added\n", added));
168}
169
170struct kcc_connection_list *kccsrv_find_connections(struct kccsrv_service *s,
171 TALLOC_CTX *mem_ctx)
172{
173 unsigned int i;
174 int ret;
175 struct ldb_dn *base_dn;
176 struct ldb_result *res;
177 const char *attrs[] = { "objectGUID", "fromServer", NULL };
178 struct kcc_connection_list *list;
179
180 kcctpl_test(s);
181
182 base_dn = samdb_ntds_settings_dn(s->samdb);
183 if (!base_dn) {
184 DEBUG(0, ("failed to find our own NTDS settings DN\n"));
185 return NULL;
186 }
187
188 ret = ldb_search(s->samdb, mem_ctx, &res, base_dn, LDB_SCOPE_ONELEVEL,
189 attrs, "objectClass=nTDSConnection");
190 if (ret != LDB_SUCCESS) {
191 DEBUG(0, ("failed nTDSConnection search: %s\n",
192 ldb_strerror(ret)));
193 return NULL;
194 }
195
196 list = talloc(mem_ctx, struct kcc_connection_list);
197 if (!list) {
198 DEBUG(0, ("out of memory"));
199 return NULL;
200 }
201 list->servers = talloc_array(mem_ctx, struct kcc_connection,
202 res->count);
203 if (!list->servers) {
204 DEBUG(0, ("out of memory"));
205 return NULL;
206 }
207 list->count = 0;
208
209 for (i = 0; i < res->count; i++) {
210 struct ldb_dn *server_dn;
211
212 list->servers[i].obj_guid = samdb_result_guid(res->msgs[i],
213 "objectGUID");
214 server_dn = samdb_result_dn(s->samdb, mem_ctx, res->msgs[i],
215 "fromServer", NULL);
216 ret = dsdb_find_guid_by_dn(s->samdb, server_dn,
217 &list->servers[i].dsa_guid);
218 if (ret != LDB_SUCCESS) {
219 DEBUG(0, ("Failed to find connection server's GUID by "
220 "DN=%s: %s\n",
221 ldb_dn_get_linearized(server_dn),
222 ldb_strerror(ret)));
223 continue;
224 }
225 list->count++;
226 }
227 DEBUG(4, ("found %d existing nTDSConnection objects\n", list->count));
228 return list;
229}
Note: See TracBrowser for help on using the repository browser.