+/*
+ Fill 'master_nc_list' with the master ncs hosted by this server
+*/
+static WERROR get_master_ncs(TALLOC_CTX *mem_ctx, struct ldb_context *samdb,
+ const char *ntds_guid_str, struct ncList **master_nc_list)
+{
+ const char *attrs[] = { "hasMasterNCs", NULL };
+ struct ldb_result *res;
+ struct ncList *nc_list = NULL;
+ struct ncList *nc_list_elem;
+ int ret;
+ int i;
+ char *nc_str;
+
+ ret = ldb_search(samdb, mem_ctx, &res, ldb_get_config_basedn(samdb),
+ LDB_SCOPE_DEFAULT, attrs, "(objectguid=%s)", ntds_guid_str);
+
+ if (ret != LDB_SUCCESS) {
+ DEBUG(0,(__location__ ": Failed objectguid search - %s\n", ldb_errstring(samdb)));
+ return WERR_INTERNAL_ERROR;
+ }
+
+ if (res->count == 0) {
+ DEBUG(0,(__location__ ": Failed: objectguid=%s not found\n", ntds_guid_str));
+ return WERR_INTERNAL_ERROR;
+ }
+
+ for (i = 0; i < res->count; i++) {
+ struct ldb_message_element *msg_elem = ldb_msg_find_element(res->msgs[i], "hasMasterNCs");
+ int k;
+
+ if (!msg_elem || msg_elem->num_values == 0) {
+ DEBUG(0,(__location__ ": Failed: Attribute hasMasterNCs not found - %s\n",
+ ldb_errstring(samdb)));
+ return WERR_INTERNAL_ERROR;
+ }
+
+ for (k = 0; k < msg_elem->num_values; k++) {
+ int len = msg_elem->values[k].length;
+
+ /* copy the string on msg_elem->values[k]->data to nc_str */
+ nc_str = talloc_array(mem_ctx, char, len);
+ W_ERROR_HAVE_NO_MEMORY(nc_str);
+ memcpy(nc_str, msg_elem->values[k].data, len);
+ nc_str[len] = '\0';
+
+ nc_list_elem = talloc_zero(mem_ctx, struct ncList);
+ W_ERROR_HAVE_NO_MEMORY(nc_list_elem);
+ nc_list_elem->dn = ldb_dn_new(mem_ctx, samdb, nc_str);
+ W_ERROR_HAVE_NO_MEMORY(nc_list_elem);
+ DLIST_ADD(nc_list, nc_list_elem);
+ }
+
+ }
+
+ *master_nc_list = nc_list;
+ return WERR_OK;
+}
+
+/*
+ Fill 'nc_list' with the ncs list. (MS-DRSR 4.1.13.3)
+ if the object dn is specified, fill 'nc_list' only with this dn
+ otherwise, fill 'nc_list' with all master ncs hosted by this server
+*/
+static WERROR get_ncs_list(TALLOC_CTX *mem_ctx,
+ struct ldb_context *samdb,
+ struct kccsrv_service *service,
+ const char *object_dn_str,
+ struct ncList **nc_list)
+{
+ WERROR status;
+ struct ncList *nc_list_elem;
+ struct ldb_dn *nc_dn;
+
+ if (object_dn_str != NULL) {
+ /* ncs := { object_dn } */
+ *nc_list = NULL;
+ nc_dn = ldb_dn_new(mem_ctx, samdb, object_dn_str);
+ nc_list_elem = talloc_zero(mem_ctx, struct ncList);
+ W_ERROR_HAVE_NO_MEMORY(nc_list_elem);
+ nc_list_elem->dn = nc_dn;
+ DLIST_ADD_END(*nc_list, nc_list_elem, struct ncList*);
+ } else {
+ /* ncs := getNCs() from ldb database.
+ * getNCs() must return an array containing
+ * the DSNames of all NCs hosted by this
+ * server.
+ */
+ char *ntds_guid_str = GUID_string(mem_ctx, &service->ntds_guid);
+ W_ERROR_HAVE_NO_MEMORY(ntds_guid_str);
+ status = get_master_ncs(mem_ctx, samdb, ntds_guid_str, nc_list);
+ W_ERROR_NOT_OK_RETURN(status);
+ }
+
+ return WERR_OK;
+}