This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
#include "lib/ldb/include/ldb_errors.h"
#include "librpc/gen_ndr/ndr_nbt.h"
#include "system/time.h"
-#include "db_wrap.h"
+#include "ldb_wrap.h"
#include "system/network.h"
-#include "netif/netif.h"
+#include "lib/socket/netif.h"
+#include "param/param.h"
uint64_t winsdb_get_maxVersion(struct winsdb_handle *h)
{
TALLOC_CTX *tmp_ctx = talloc_new(ldb);
uint64_t maxVersion = 0;
- dn = ldb_dn_explode(tmp_ctx, "CN=VERSION");
+ dn = ldb_dn_new(tmp_ctx, ldb, "CN=VERSION");
if (!dn) goto failed;
/* find the record in the WINS database */
- ret = ldb_search(ldb, dn, LDB_SCOPE_BASE,
- NULL, NULL, &res);
+ ret = ldb_search(ldb, tmp_ctx, &res, dn, LDB_SCOPE_BASE, NULL, NULL);
if (ret != LDB_SUCCESS) goto failed;
- talloc_steal(tmp_ctx, res);
if (res->count > 1) goto failed;
if (res->count == 1) {
trans = ldb_transaction_start(wins_db);
if (trans != LDB_SUCCESS) goto failed;
- dn = ldb_dn_explode(tmp_ctx, "CN=VERSION");
+ dn = ldb_dn_new(tmp_ctx, wins_db, "CN=VERSION");
if (!dn) goto failed;
/* find the record in the WINS database */
- ret = ldb_search(wins_db, dn, LDB_SCOPE_BASE, NULL, NULL, &res);
-
+ ret = ldb_search(wins_db, tmp_ctx, &res, dn, LDB_SCOPE_BASE, NULL, NULL);
if (ret != LDB_SUCCESS) goto failed;
if (res->count > 1) goto failed;
- talloc_steal(tmp_ctx, res);
-
if (res->count == 1) {
oldMaxVersion = ldb_msg_find_attr_as_uint64(res->msgs[0], "maxVersion", 0);
}
msg->dn = dn;
- ret = ldb_msg_add_empty(msg, "objectClass", LDB_FLAG_MOD_REPLACE);
+ ret = ldb_msg_add_empty(msg, "objectClass", LDB_FLAG_MOD_REPLACE, NULL);
if (ret != 0) goto failed;
ret = ldb_msg_add_string(msg, "objectClass", "winsMaxVersion");
if (ret != 0) goto failed;
- ret = ldb_msg_add_empty(msg, "maxVersion", LDB_FLAG_MOD_REPLACE);
+ ret = ldb_msg_add_empty(msg, "maxVersion", LDB_FLAG_MOD_REPLACE, NULL);
if (ret != 0) goto failed;
ret = ldb_msg_add_fmt(msg, "maxVersion", "%llu", (long long)newMaxVersion);
if (ret != 0) goto failed;
TALLOC_CTX *tmp_ctx = talloc_new(ldb);
uint64_t seqnumber = 0;
- dn = ldb_dn_explode(tmp_ctx, "@BASEINFO");
+ dn = ldb_dn_new(tmp_ctx, ldb, "@BASEINFO");
if (!dn) goto failed;
/* find the record in the WINS database */
- ret = ldb_search(ldb, dn, LDB_SCOPE_BASE,
- NULL, NULL, &res);
+ ret = ldb_search(ldb, tmp_ctx, &res, dn, LDB_SCOPE_BASE, NULL, NULL);
if (ret != LDB_SUCCESS) goto failed;
- talloc_steal(tmp_ctx, res);
if (res->count > 1) goto failed;
if (res->count == 1) {
/*
return a DN for a nbt_name
*/
-static struct ldb_dn *winsdb_dn(TALLOC_CTX *mem_ctx, struct nbt_name *name)
+static struct ldb_dn *winsdb_dn(TALLOC_CTX *mem_ctx, struct ldb_context *ldb,
+ const struct nbt_name *name)
{
struct ldb_dn *dn;
- dn = ldb_dn_string_compose(mem_ctx, NULL, "type=0x%02X", name->type);
- if (dn && name->name && *name->name) {
- dn = ldb_dn_string_compose(mem_ctx, dn, "name=%s", name->name);
+ dn = ldb_dn_new_fmt(mem_ctx, ldb, "type=0x%02X", name->type);
+ if (ldb_dn_is_valid(dn) && name->name && *name->name) {
+ ldb_dn_add_child_fmt(dn, "name=%s", name->name);
}
- if (dn && name->scope && *name->scope) {
- dn = ldb_dn_string_compose(mem_ctx, dn, "scope=%s", name->scope);
+ if (ldb_dn_is_valid(dn) && name->scope && *name->scope) {
+ ldb_dn_add_child_fmt(dn, "scope=%s", name->scope);
}
return dn;
}
{
NTSTATUS status;
struct nbt_name *name;
+ unsigned int comp_num;
uint32_t cur = 0;
name = talloc(mem_ctx, struct nbt_name);
goto failed;
}
- if (dn->comp_num > 3) {
+ comp_num = ldb_dn_get_comp_num(dn);
+
+ if (comp_num > 3) {
status = NT_STATUS_INTERNAL_DB_CORRUPTION;
goto failed;
}
- if (dn->comp_num > cur && strcasecmp("scope", dn->components[cur].name) == 0) {
- name->scope = (const char *)talloc_steal(name, dn->components[cur].value.data);
+ if (comp_num > cur && strcasecmp("scope", ldb_dn_get_component_name(dn, cur)) == 0) {
+ name->scope = (const char *)talloc_strdup(name, (char *)ldb_dn_get_component_val(dn, cur)->data);
cur++;
} else {
name->scope = NULL;
}
- if (dn->comp_num > cur && strcasecmp("name", dn->components[cur].name) == 0) {
- name->name = (const char *)talloc_steal(name, dn->components[cur].value.data);
+ if (comp_num > cur && strcasecmp("name", ldb_dn_get_component_name(dn, cur)) == 0) {
+ name->name = (const char *)talloc_strdup(name, (char *)ldb_dn_get_component_val(dn, cur)->data);
cur++;
} else {
name->name = talloc_strdup(name, "");
}
}
- if (dn->comp_num > cur && strcasecmp("type", dn->components[cur].name) == 0) {
- name->type = strtoul((char *)dn->components[cur].value.data, NULL, 0);
+ if (comp_num > cur && strcasecmp("type", ldb_dn_get_component_name(dn, cur)) == 0) {
+ name->type = strtoul((char *)ldb_dn_get_component_val(dn, cur)->data, NULL, 0);
cur++;
} else {
status = NT_STATUS_INTERNAL_DB_CORRUPTION;
val.data = discard_const_p(uint8_t, str);
val.length = strlen(str);
- return ldb_msg_add_value(msg, attr_name, &val);
+ return ldb_msg_add_value(msg, attr_name, &val, NULL);
}
struct winsdb_addr **winsdb_addr_list_make(TALLOC_CTX *mem_ctx)
struct winsdb_addr *a1 = talloc_get_type(*p1, struct winsdb_addr);
struct winsdb_addr *a2 = talloc_get_type(*p2, struct winsdb_addr);
struct winsdb_handle *h= talloc_get_type(opaque, struct winsdb_handle);
- BOOL a1_owned = False;
- BOOL a2_owned = False;
+ bool a1_owned = false;
+ bool a2_owned = false;
/*
* first the owned addresses with the newest to the oldest address
}
if (strcmp(a2->wins_owner, h->local_owner) == 0) {
- a2_owned = True;
+ a2_owned = true;
}
if (strcmp(a1->wins_owner, h->local_owner) == 0) {
- a1_owned = True;
+ a1_owned = true;
}
return a2_owned - a1_owned;
struct winsdb_addr **winsdb_addr_list_add(struct winsdb_handle *h, const struct winsdb_record *rec,
struct winsdb_addr **addresses, const char *address,
const char *wins_owner, time_t expire_time,
- BOOL is_name_registration)
+ bool is_name_registration)
{
struct winsdb_addr *old_addr = NULL;
size_t len = 0;
size_t i;
- BOOL found_old_replica = False;
+ bool found_old_replica = false;
/*
* count the addresses and maybe
* record at all, find the oldest owned address
*/
for (i=0; addresses[i]; i++) {
- BOOL cur_is_replica = False;
+ bool cur_is_replica = false;
/* find out if the current address is a replica */
if (strcmp(addresses[i]->wins_owner, h->local_owner) != 0) {
- cur_is_replica = True;
+ cur_is_replica = true;
}
/*
* that would be replaced
*/
if (!found_old_replica && cur_is_replica) {
- found_old_replica = True;
+ found_old_replica = true;
old_addr = addresses[i];
continue;
}
load a WINS entry from the database
*/
NTSTATUS winsdb_lookup(struct winsdb_handle *h,
- struct nbt_name *name,
+ const struct nbt_name *name,
TALLOC_CTX *mem_ctx,
struct winsdb_record **_rec)
{
time_t now = time(NULL);
/* find the record in the WINS database */
- ret = ldb_search(wins_db, winsdb_dn(tmp_ctx, name), LDB_SCOPE_BASE,
- NULL, NULL, &res);
+ ret = ldb_search(wins_db, tmp_ctx, &res,
+ winsdb_dn(tmp_ctx, wins_db, name),
+ LDB_SCOPE_BASE, NULL, NULL);
if (ret != LDB_SUCCESS || res->count > 1) {
status = NT_STATUS_INTERNAL_DB_CORRUPTION;
goto failed;
}
- talloc_steal(tmp_ctx, res);
-
status = winsdb_record(h, res->msgs[0], tmp_ctx, now, &rec);
if (!NT_STATUS_IS_OK(status)) goto failed;
goto failed;
}
- /* see if it has already expired */
- if (!rec->is_static &&
- rec->expire_time <= now &&
- rec->state == WREPL_STATE_ACTIVE) {
- DEBUG(5,("WINS: expiring name %s (expired at %s)\n",
- nbt_name_string(mem_ctx, rec->name), timestring(mem_ctx, rec->expire_time)));
- rec->state = WREPL_STATE_RELEASED;
- }
-
rec->addresses = talloc_array(rec, struct winsdb_addr *, num_values+1);
if (rec->addresses == NULL) {
status = NT_STATUS_NO_MEMORY;
}
for (i=0,j=0;i<num_values;i++) {
+ bool we_are_owner = false;
+
status = winsdb_addr_decode(h, rec, &el->values[i], rec->addresses, &rec->addresses[j]);
if (!NT_STATUS_IS_OK(status)) goto failed;
+ if (strcmp(rec->addresses[j]->wins_owner, h->local_owner) == 0) {
+ we_are_owner = true;
+ }
+
/*
* the record isn't static and is active
- * then don't add the address if it's expired
+ * then don't add the address if it's expired,
+ * but only if we're the owner of the address
+ *
+ * This is important for SGROUP records,
+ * because each server thinks he's the owner of the
+ * record and the record isn't replicated on a
+ * name_refresh. So addresses owned by another owner
+ * could expire, but we still need to return them
+ * (as windows does).
*/
if (!rec->is_static &&
rec->addresses[j]->expire_time <= now &&
- rec->state == WREPL_STATE_ACTIVE) {
+ rec->state == WREPL_STATE_ACTIVE &&
+ we_are_owner) {
DEBUG(5,("WINS: expiring name addr %s of %s (expired at %s)\n",
rec->addresses[j]->address, nbt_name_string(rec->addresses[j], rec->name),
timestring(rec->addresses[j], rec->addresses[j]->expire_time)));
return NT_STATUS_OK;
failed:
if (NT_STATUS_EQUAL(NT_STATUS_INTERNAL_DB_CORRUPTION, status)) {
- DEBUG(1,("winsdb_record: corrupted record: %s\n", ldb_dn_linearize(rec, msg->dn)));
+ DEBUG(1,("winsdb_record: corrupted record: %s\n", ldb_dn_get_linearized(msg->dn)));
}
talloc_free(rec);
return status;
/*
form a ldb_message from a winsdb_record
*/
-struct ldb_message *winsdb_message(struct ldb_context *ldb,
- struct winsdb_record *rec, TALLOC_CTX *mem_ctx)
+static struct ldb_message *winsdb_message(struct ldb_context *ldb,
+ struct winsdb_record *rec,
+ TALLOC_CTX *mem_ctx)
{
int i, ret=0;
size_t addr_count;
goto failed;
}
- msg->dn = winsdb_dn(msg, rec->name);
+ msg->dn = winsdb_dn(msg, ldb, rec->name);
if (msg->dn == NULL) goto failed;
ret |= ldb_msg_add_fmt(msg, "type", "0x%02X", rec->name->type);
if (rec->name->name && *rec->name->name) {
ret |= ldb_msg_add_fmt(msg, "recordState", "%u", rec->state);
ret |= ldb_msg_add_fmt(msg, "nodeType", "%u", rec->node);
ret |= ldb_msg_add_fmt(msg, "isStatic", "%u", rec->is_static);
- ret |= ldb_msg_add_empty(msg, "expireTime", 0);
+ ret |= ldb_msg_add_empty(msg, "expireTime", 0, NULL);
if (!(rec->is_static && rec->state == WREPL_STATE_ACTIVE)) {
ret |= ldb_msg_add_string(msg, "expireTime", expire_time);
}
ret |= ldb_msg_add_fmt(msg, "versionID", "%llu", (long long)rec->version);
ret |= ldb_msg_add_string(msg, "winsOwner", rec->wins_owner);
- ret |= ldb_msg_add_empty(msg, "address", 0);
+ ret |= ldb_msg_add_empty(msg, "address", 0, NULL);
for (i=0;rec->addresses[i];i++) {
ret |= ldb_msg_add_winsdb_addr(msg, rec, "address", rec->addresses[i]);
}
- ret |= ldb_msg_add_empty(msg, "registeredBy", 0);
if (rec->registered_by) {
+ ret |= ldb_msg_add_empty(msg, "registeredBy", 0, NULL);
ret |= ldb_msg_add_string(msg, "registeredBy", rec->registered_by);
- if (ret != 0) goto failed;
}
+ if (ret != 0) goto failed;
return msg;
failed:
trans = ldb_transaction_commit(wins_db);
if (trans != LDB_SUCCESS) goto failed;
- wins_hook(h, rec, WINS_HOOK_ADD);
+ wins_hook(h, rec, WINS_HOOK_ADD, h->hook_script);
talloc_free(tmp_ctx);
return NBT_RCODE_OK;
trans = ldb_transaction_commit(wins_db);
if (trans != LDB_SUCCESS) goto failed;
- wins_hook(h, rec, WINS_HOOK_MODIFY);
+ wins_hook(h, rec, WINS_HOOK_MODIFY, h->hook_script);
talloc_free(tmp_ctx);
return NBT_RCODE_OK;
{
struct ldb_context *wins_db = h->ldb;
TALLOC_CTX *tmp_ctx = talloc_new(wins_db);
- const struct ldb_dn *dn;
+ struct ldb_dn *dn;
int trans;
int ret;
trans = ldb_transaction_start(wins_db);
if (trans != LDB_SUCCESS) goto failed;
- dn = winsdb_dn(tmp_ctx, rec->name);
+ dn = winsdb_dn(tmp_ctx, wins_db, rec->name);
if (dn == NULL) goto failed;
ret = ldb_delete(wins_db, dn);
trans = ldb_transaction_commit(wins_db);
if (trans != LDB_SUCCESS) goto failed;
- wins_hook(h, rec, WINS_HOOK_DELETE);
+ wins_hook(h, rec, WINS_HOOK_DELETE, h->hook_script);
talloc_free(tmp_ctx);
return NBT_RCODE_OK;
return NBT_RCODE_SVR;
}
-static BOOL winsdb_check_or_add_module_list(struct winsdb_handle *h)
+static bool winsdb_check_or_add_module_list(struct tevent_context *ev_ctx,
+ struct loadparm_context *lp_ctx, struct winsdb_handle *h)
{
int trans;
int ret;
if (trans != LDB_SUCCESS) goto failed;
/* check if we have a special @MODULES record already */
- dn = ldb_dn_explode(tmp_ctx, "@MODULES");
+ dn = ldb_dn_new(tmp_ctx, h->ldb, "@MODULES");
if (!dn) goto failed;
/* find the record in the WINS database */
- ret = ldb_search(h->ldb, dn, LDB_SCOPE_BASE, NULL, NULL, &res);
+ ret = ldb_search(h->ldb, tmp_ctx, &res, dn, LDB_SCOPE_BASE, NULL, NULL);
if (ret != LDB_SUCCESS) goto failed;
- talloc_steal(tmp_ctx, res);
if (res->count > 0) goto skip;
talloc_free(h->ldb);
h->ldb = NULL;
- if (lp_parm_bool(-1,"winsdb", "nosync", False)) {
+ if (lp_parm_bool(lp_ctx, NULL,"winsdb", "nosync", false)) {
flags |= LDB_FLG_NOSYNC;
}
- h->ldb = ldb_wrap_connect(h, lock_path(h, lp_wins_url()),
+ h->ldb = ldb_wrap_connect(h, ev_ctx, lp_ctx, lock_path(h, lp_ctx, lp_wins_url(lp_ctx)),
NULL, NULL, flags, NULL);
if (!h->ldb) goto failed;
talloc_free(tmp_ctx);
- return True;
+ return true;
skip:
if (trans == LDB_SUCCESS) ldb_transaction_cancel(h->ldb);
talloc_free(tmp_ctx);
- return True;
+ return true;
failed:
if (trans == LDB_SUCCESS) ldb_transaction_cancel(h->ldb);
talloc_free(tmp_ctx);
- return False;
+ return false;
}
-struct winsdb_handle *winsdb_connect(TALLOC_CTX *mem_ctx, enum winsdb_handle_caller caller)
+struct winsdb_handle *winsdb_connect(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev_ctx,
+ struct loadparm_context *lp_ctx,
+ const char *owner,
+ enum winsdb_handle_caller caller)
{
struct winsdb_handle *h = NULL;
- const char *owner;
unsigned int flags = 0;
- BOOL ret;
+ bool ret;
int ldb_err;
- h = talloc(mem_ctx, struct winsdb_handle);
+ h = talloc_zero(mem_ctx, struct winsdb_handle);
if (!h) return NULL;
- if (lp_parm_bool(-1,"winsdb", "nosync", False)) {
+ if (lp_parm_bool(lp_ctx, NULL,"winsdb", "nosync", false)) {
flags |= LDB_FLG_NOSYNC;
}
- h->ldb = ldb_wrap_connect(h, lock_path(h, lp_wins_url()),
+ h->ldb = ldb_wrap_connect(h, ev_ctx, lp_ctx, lock_path(h, lp_ctx, lp_wins_url(lp_ctx)),
NULL, NULL, flags, NULL);
if (!h->ldb) goto failed;
h->caller = caller;
-
- owner = lp_parm_string(-1, "winsdb", "local_owner");
- if (!owner) {
- owner = iface_n_ip(0);
- }
+ h->hook_script = lp_wins_hook(lp_ctx);
h->local_owner = talloc_strdup(h, owner);
if (!h->local_owner) goto failed;
/* make sure the module list is available and used */
- ret = winsdb_check_or_add_module_list(h);
+ ret = winsdb_check_or_add_module_list(ev_ctx, lp_ctx, h);
if (!ret) goto failed;
ldb_err = ldb_set_opaque(h->ldb, "winsdb_handle", h);