Line data Source code
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 "samba/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 :
37 0 : static int kccsrv_add_connection(struct kccsrv_service *s,
38 : struct kcc_connection *conn)
39 : {
40 0 : struct ldb_message *msg;
41 0 : TALLOC_CTX *tmp_ctx;
42 0 : struct ldb_dn *new_dn, *server_dn;
43 0 : struct GUID guid;
44 : /* struct ldb_val schedule_val; */
45 0 : int ret;
46 0 : bool ok;
47 :
48 0 : tmp_ctx = talloc_new(s);
49 0 : if (!tmp_ctx) {
50 0 : DEBUG(0, ("failed to talloc\n"));
51 0 : ret = LDB_ERR_OPERATIONS_ERROR;
52 0 : goto done;
53 : }
54 0 : new_dn = samdb_ntds_settings_dn(s->samdb, tmp_ctx);
55 0 : if (!new_dn) {
56 0 : DEBUG(0, ("failed to find NTDS settings\n"));
57 0 : ret = LDB_ERR_OPERATIONS_ERROR;
58 0 : goto done;
59 : }
60 0 : new_dn = ldb_dn_copy(tmp_ctx, new_dn);
61 0 : if (!new_dn) {
62 0 : DEBUG(0, ("failed to copy NTDS settings\n"));
63 0 : ret = LDB_ERR_OPERATIONS_ERROR;
64 0 : goto done;
65 : }
66 0 : guid = GUID_random();
67 0 : ok = ldb_dn_add_child_fmt(new_dn, "CN=%s", GUID_string(tmp_ctx, &guid));
68 0 : if (!ok) {
69 0 : DEBUG(0, ("failed to create nTDSConnection DN\n"));
70 0 : ret = LDB_ERR_INVALID_DN_SYNTAX;
71 0 : goto done;
72 : }
73 0 : ret = dsdb_find_dn_by_guid(s->samdb, tmp_ctx, &conn->dsa_guid, 0, &server_dn);
74 0 : if (ret != LDB_SUCCESS) {
75 0 : DEBUG(0, ("failed to find fromServer DN '%s'\n",
76 : GUID_string(tmp_ctx, &conn->dsa_guid)));
77 0 : goto done;
78 : }
79 : /*schedule_val = data_blob_const(r1->schedule, sizeof(r1->schedule));*/
80 :
81 0 : msg = ldb_msg_new(tmp_ctx);
82 0 : msg->dn = new_dn;
83 0 : ldb_msg_add_string(msg, "objectClass", "nTDSConnection");
84 0 : ldb_msg_add_string(msg, "showInAdvancedViewOnly", "TRUE");
85 0 : ldb_msg_add_string(msg, "enabledConnection", "TRUE");
86 0 : ldb_msg_add_linearized_dn(msg, "fromServer", server_dn);
87 : /* ldb_msg_add_value(msg, "schedule", &schedule_val, NULL); */
88 :
89 0 : samdb_msg_add_uint(s->samdb, msg, msg,
90 : "options", NTDSCONN_OPT_IS_GENERATED);
91 :
92 0 : ret = ldb_add(s->samdb, msg);
93 0 : if (ret == LDB_SUCCESS) {
94 0 : DEBUG(2, ("added nTDSConnection object '%s'\n",
95 : ldb_dn_get_linearized(new_dn)));
96 : } else {
97 0 : DEBUG(0, ("failed to add an nTDSConnection object: %s\n",
98 : ldb_strerror(ret)));
99 : }
100 :
101 0 : done:
102 0 : talloc_free(tmp_ctx);
103 0 : return ret;
104 : }
105 :
106 0 : static int kccsrv_delete_connection(struct kccsrv_service *s,
107 : struct kcc_connection *conn)
108 : {
109 0 : TALLOC_CTX *tmp_ctx;
110 0 : struct ldb_dn *dn;
111 0 : int ret;
112 :
113 0 : tmp_ctx = talloc_new(s);
114 0 : ret = dsdb_find_dn_by_guid(s->samdb, tmp_ctx, &conn->obj_guid, 0, &dn);
115 0 : if (ret != LDB_SUCCESS) {
116 0 : DEBUG(0, ("failed to find nTDSConnection's DN: %s\n",
117 : ldb_strerror(ret)));
118 0 : goto done;
119 : }
120 :
121 0 : ret = ldb_delete(s->samdb, dn);
122 0 : if (ret == LDB_SUCCESS) {
123 0 : DEBUG(2, ("deleted nTDSConnection object '%s'\n",
124 : ldb_dn_get_linearized(dn)));
125 : } else {
126 0 : DEBUG(0, ("failed to delete an nTDSConnection object: %s\n",
127 : ldb_strerror(ret)));
128 : }
129 :
130 0 : done:
131 0 : talloc_free(tmp_ctx);
132 0 : return ret;
133 : }
134 :
135 0 : void kccsrv_apply_connections(struct kccsrv_service *s,
136 : struct kcc_connection_list *ntds_list,
137 : struct kcc_connection_list *dsa_list)
138 : {
139 0 : unsigned int i, j, deleted = 0, added = 0;
140 0 : int ret;
141 :
142 : /* XXX
143 : *
144 : * This routine is not respecting connections that the
145 : * administrator can specifically create (NTDSCONN_OPT_IS_GENERATED
146 : * bit will not be set)
147 : */
148 0 : for (i = 0; ntds_list && i < ntds_list->count; i++) {
149 0 : struct kcc_connection *ntds = &ntds_list->servers[i];
150 0 : for (j = 0; j < dsa_list->count; j++) {
151 0 : struct kcc_connection *dsa = &dsa_list->servers[j];
152 0 : if (GUID_equal(&ntds->dsa_guid, &dsa->dsa_guid)) {
153 0 : break;
154 : }
155 : }
156 0 : if (j == dsa_list->count) {
157 0 : ret = kccsrv_delete_connection(s, ntds);
158 0 : if (ret == LDB_SUCCESS) {
159 0 : deleted++;
160 : }
161 : }
162 : }
163 0 : DEBUG(4, ("%d connections have been deleted\n", deleted));
164 :
165 0 : for (i = 0; i < dsa_list->count; i++) {
166 0 : struct kcc_connection *dsa = &dsa_list->servers[i];
167 0 : for (j = 0; ntds_list && j < ntds_list->count; j++) {
168 0 : struct kcc_connection *ntds = &ntds_list->servers[j];
169 0 : if (GUID_equal(&dsa->dsa_guid, &ntds->dsa_guid)) {
170 0 : break;
171 : }
172 : }
173 0 : if (ntds_list == NULL || j == ntds_list->count) {
174 0 : ret = kccsrv_add_connection(s, dsa);
175 0 : if (ret == LDB_SUCCESS) {
176 0 : added++;
177 : }
178 : }
179 : }
180 0 : DEBUG(4, ("%d connections have been added\n", added));
181 0 : }
182 :
183 0 : struct kcc_connection_list *kccsrv_find_connections(struct kccsrv_service *s,
184 : TALLOC_CTX *mem_ctx)
185 : {
186 0 : unsigned int i;
187 0 : int ret;
188 0 : struct ldb_dn *base_dn;
189 0 : struct ldb_result *res;
190 0 : const char *attrs[] = { "objectGUID", "fromServer", NULL };
191 0 : struct kcc_connection_list *list;
192 0 : TALLOC_CTX *tmp_ctx;
193 :
194 0 : tmp_ctx = talloc_new(mem_ctx);
195 0 : if (!tmp_ctx) {
196 0 : DEBUG(0, ("failed to talloc\n"));
197 0 : return NULL;
198 : }
199 :
200 0 : base_dn = samdb_ntds_settings_dn(s->samdb, tmp_ctx);
201 0 : if (!base_dn) {
202 0 : DEBUG(0, ("failed to find our own NTDS settings DN\n"));
203 0 : talloc_free(tmp_ctx);
204 0 : return NULL;
205 : }
206 :
207 0 : ret = ldb_search(s->samdb, tmp_ctx, &res, base_dn, LDB_SCOPE_ONELEVEL,
208 : attrs, "objectClass=nTDSConnection");
209 0 : if (ret != LDB_SUCCESS) {
210 0 : DEBUG(0, ("failed nTDSConnection search: %s\n",
211 : ldb_strerror(ret)));
212 0 : talloc_free(tmp_ctx);
213 0 : return NULL;
214 : }
215 :
216 0 : list = talloc(tmp_ctx, struct kcc_connection_list);
217 0 : if (!list) {
218 0 : DEBUG(0, ("out of memory\n"));
219 0 : return NULL;
220 : }
221 0 : list->servers = talloc_array(list, struct kcc_connection,
222 : res->count);
223 0 : if (!list->servers) {
224 0 : DEBUG(0, ("out of memory\n"));
225 0 : talloc_free(tmp_ctx);
226 0 : return NULL;
227 : }
228 0 : list->count = 0;
229 :
230 0 : for (i = 0; i < res->count; i++) {
231 0 : struct ldb_dn *server_dn;
232 :
233 0 : list->servers[i].obj_guid = samdb_result_guid(res->msgs[i],
234 : "objectGUID");
235 0 : server_dn = samdb_result_dn(s->samdb, mem_ctx, res->msgs[i],
236 : "fromServer", NULL);
237 0 : ret = dsdb_find_guid_by_dn(s->samdb, server_dn,
238 0 : &list->servers[i].dsa_guid);
239 0 : if (ret != LDB_SUCCESS) {
240 0 : DEBUG(0, ("Failed to find connection server's GUID by "
241 : "DN=%s: %s\n",
242 : ldb_dn_get_linearized(server_dn),
243 : ldb_strerror(ret)));
244 0 : continue;
245 : }
246 0 : list->count++;
247 : }
248 0 : DEBUG(4, ("found %d existing nTDSConnection objects\n", list->count));
249 0 : talloc_steal(mem_ctx, list);
250 0 : talloc_free(tmp_ctx);
251 0 : return list;
252 : }
|