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/>.
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_connection.h"
29 #include "dsdb/kcc/kcc_service.h"
30 #include "lib/ldb/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
;
42 struct ldb_dn
*new_dn
, *server_dn
;
44 /* struct ldb_val schedule_val; */
48 tmp_ctx
= talloc_new(s
);
49 new_dn
= samdb_ntds_settings_dn(s
->samdb
);
51 DEBUG(0, ("failed to find NTDS settings\n"));
52 ret
= LDB_ERR_OPERATIONS_ERROR
;
55 new_dn
= ldb_dn_copy(tmp_ctx
, new_dn
);
57 DEBUG(0, ("failed to copy NTDS settings\n"));
58 ret
= LDB_ERR_OPERATIONS_ERROR
;
62 ok
= ldb_dn_add_child_fmt(new_dn
, "CN=%s", GUID_string(tmp_ctx
, &guid
));
64 DEBUG(0, ("failed to create nTDSConnection DN\n"));
65 ret
= LDB_ERR_INVALID_DN_SYNTAX
;
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
)));
74 /*schedule_val = data_blob_const(r1->schedule, sizeof(r1->schedule));*/
76 msg
= ldb_msg_new(tmp_ctx
);
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 ldb_msg_add_string(msg
, "options", "1");
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
)));
90 DEBUG(0, ("failed to add an nTDSConnection object: %s\n",
99 static int kccsrv_delete_connection(struct kccsrv_service
*s
,
100 struct kcc_connection
*conn
)
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",
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
)));
119 DEBUG(0, ("failed to delete an nTDSConnection object: %s\n",
124 talloc_free(tmp_ctx
);
128 void kccsrv_apply_connections(struct kccsrv_service
*s
,
129 struct kcc_connection_list
*ntds_list
,
130 struct kcc_connection_list
*dsa_list
)
132 int i
, j
, deleted
= 0, added
= 0, ret
;
134 for (i
= 0; ntds_list
&& i
< ntds_list
->count
; i
++) {
135 struct kcc_connection
*ntds
= &ntds_list
->servers
[i
];
136 for (j
= 0; j
< dsa_list
->count
; j
++) {
137 struct kcc_connection
*dsa
= &dsa_list
->servers
[j
];
138 if (GUID_equal(&ntds
->dsa_guid
, &dsa
->dsa_guid
)) {
142 if (j
== dsa_list
->count
) {
143 ret
= kccsrv_delete_connection(s
, ntds
);
144 if (ret
== LDB_SUCCESS
) {
149 DEBUG(4, ("%d connections have been deleted\n", deleted
));
151 for (i
= 0; i
< dsa_list
->count
; i
++) {
152 struct kcc_connection
*dsa
= &dsa_list
->servers
[i
];
153 for (j
= 0; ntds_list
&& j
< ntds_list
->count
; j
++) {
154 struct kcc_connection
*ntds
= &ntds_list
->servers
[j
];
155 if (GUID_equal(&dsa
->dsa_guid
, &ntds
->dsa_guid
)) {
159 if (ntds_list
== NULL
|| j
== ntds_list
->count
) {
160 ret
= kccsrv_add_connection(s
, dsa
);
161 if (ret
== LDB_SUCCESS
) {
166 DEBUG(4, ("%d connections have been added\n", added
));
169 struct kcc_connection_list
*kccsrv_find_connections(struct kccsrv_service
*s
,
173 struct ldb_dn
*base_dn
;
174 struct ldb_result
*res
;
175 const char *attrs
[] = { "objectGUID", "fromServer", NULL
};
176 struct kcc_connection_list
*list
;
178 base_dn
= samdb_ntds_settings_dn(s
->samdb
);
180 DEBUG(0, ("failed to find our own NTDS settings DN\n"));
184 ret
= ldb_search(s
->samdb
, mem_ctx
, &res
, base_dn
, LDB_SCOPE_ONELEVEL
,
185 attrs
, "objectClass=nTDSConnection");
186 if (ret
!= LDB_SUCCESS
) {
187 DEBUG(0, ("failed nTDSConnection search: %s\n",
192 list
= talloc(mem_ctx
, struct kcc_connection_list
);
194 DEBUG(0, ("out of memory"));
197 list
->servers
= talloc_array(mem_ctx
, struct kcc_connection
,
199 if (!list
->servers
) {
200 DEBUG(0, ("out of memory"));
205 for (i
= 0; i
< res
->count
; i
++) {
206 struct ldb_dn
*server_dn
;
208 list
->servers
[i
].obj_guid
= samdb_result_guid(res
->msgs
[i
],
210 server_dn
= samdb_result_dn(s
->samdb
, mem_ctx
, res
->msgs
[i
],
212 ret
= dsdb_find_guid_by_dn(s
->samdb
, server_dn
,
213 &list
->servers
[i
].dsa_guid
);
214 if (ret
!= LDB_SUCCESS
) {
215 DEBUG(0, ("failed to find connection server's GUID"
217 ldb_dn_get_linearized(server_dn
),
223 DEBUG(4, ("found %d existing nTDSConnection objects\n", list
->count
));