mirror of
https://github.com/samba-team/samba.git
synced 2025-03-03 12:58:35 +03:00
r11877: - give winsdb_add/modify/delete() ldb_context as first argument
and add a flags argument to add and modify,the current flags are: WINSDB_FLAG_ALLOC_VERSION to allocate a new version id for the record WINSDB_FLAG_TAKE_OWNERSHIP to take the become the wins owner of the record - fix handling of records with no addresses, this is valid for MHOMED and SGROUP records when they're not in ACTIVE state metze (This used to be commit 0ffea2a7b898b1807e4cdcfbbeba9bd0c6792231)
This commit is contained in:
parent
4725c3a83d
commit
5257693496
@ -31,25 +31,24 @@
|
||||
/*
|
||||
return the new maxVersion and save it
|
||||
*/
|
||||
static uint64_t winsdb_allocate_version(struct wins_server *winssrv)
|
||||
static uint64_t winsdb_allocate_version(struct ldb_context *wins_db)
|
||||
{
|
||||
int trans;
|
||||
int ret;
|
||||
struct ldb_context *ldb = winssrv->wins_db;
|
||||
struct ldb_dn *dn;
|
||||
struct ldb_result *res = NULL;
|
||||
struct ldb_message *msg = NULL;
|
||||
TALLOC_CTX *tmp_ctx = talloc_new(winssrv);
|
||||
TALLOC_CTX *tmp_ctx = talloc_new(wins_db);
|
||||
uint64_t maxVersion = 0;
|
||||
|
||||
trans = ldb_transaction_start(ldb);
|
||||
trans = ldb_transaction_start(wins_db);
|
||||
if (trans != LDB_SUCCESS) goto failed;
|
||||
|
||||
dn = ldb_dn_explode(tmp_ctx, "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(wins_db, dn, LDB_SCOPE_BASE, NULL, NULL, &res);
|
||||
|
||||
if (ret != LDB_SUCCESS) goto failed;
|
||||
if (res->count > 1) goto failed;
|
||||
@ -75,18 +74,18 @@ static uint64_t winsdb_allocate_version(struct wins_server *winssrv)
|
||||
ret = ldb_msg_add_fmt(msg, "maxVersion", "%llu", maxVersion);
|
||||
if (ret != 0) goto failed;
|
||||
|
||||
ret = ldb_modify(ldb, msg);
|
||||
if (ret != 0) ret = ldb_add(ldb, msg);
|
||||
ret = ldb_modify(wins_db, msg);
|
||||
if (ret != 0) ret = ldb_add(wins_db, msg);
|
||||
if (ret != 0) goto failed;
|
||||
|
||||
trans = ldb_transaction_commit(ldb);
|
||||
trans = ldb_transaction_commit(wins_db);
|
||||
if (trans != LDB_SUCCESS) goto failed;
|
||||
|
||||
talloc_free(tmp_ctx);
|
||||
return maxVersion;
|
||||
|
||||
failed:
|
||||
if (trans == LDB_SUCCESS) ldb_transaction_cancel(ldb);
|
||||
if (trans == LDB_SUCCESS) ldb_transaction_cancel(wins_db);
|
||||
talloc_free(tmp_ctx);
|
||||
return 0;
|
||||
}
|
||||
@ -422,7 +421,7 @@ NTSTATUS winsdb_record(struct ldb_message *msg, struct nbt_name *name, TALLOC_CT
|
||||
NTSTATUS status;
|
||||
struct winsdb_record *rec;
|
||||
struct ldb_message_element *el;
|
||||
uint32_t i;
|
||||
uint32_t i, num_values;
|
||||
|
||||
rec = talloc(mem_ctx, struct winsdb_record);
|
||||
if (rec == NULL) {
|
||||
@ -466,25 +465,32 @@ NTSTATUS winsdb_record(struct ldb_message *msg, struct nbt_name *name, TALLOC_CT
|
||||
}
|
||||
|
||||
el = ldb_msg_find_element(msg, "address");
|
||||
if (el == NULL) {
|
||||
status = NT_STATUS_INTERNAL_DB_CORRUPTION;
|
||||
goto failed;
|
||||
if (el) {
|
||||
num_values = el->num_values;
|
||||
} else {
|
||||
num_values = 0;
|
||||
}
|
||||
|
||||
if (rec->type == WREPL_TYPE_UNIQUE || rec->type == WREPL_TYPE_GROUP) {
|
||||
if (el->num_values != 1) {
|
||||
if (num_values != 1) {
|
||||
status = NT_STATUS_INTERNAL_DB_CORRUPTION;
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
if (rec->state == WREPL_STATE_ACTIVE) {
|
||||
if (num_values < 1) {
|
||||
status = NT_STATUS_INTERNAL_DB_CORRUPTION;
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
|
||||
rec->addresses = talloc_array(rec, struct winsdb_addr *, el->num_values+1);
|
||||
rec->addresses = talloc_array(rec, struct winsdb_addr *, num_values+1);
|
||||
if (rec->addresses == NULL) {
|
||||
status = NT_STATUS_NO_MEMORY;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
for (i=0;i<el->num_values;i++) {
|
||||
for (i=0;i<num_values;i++) {
|
||||
status = winsdb_addr_decode(rec, &el->values[i], rec->addresses, &rec->addresses[i]);
|
||||
if (!NT_STATUS_IS_OK(status)) goto failed;
|
||||
}
|
||||
@ -531,8 +537,10 @@ struct ldb_message *winsdb_message(struct ldb_context *ldb,
|
||||
for (i=0;rec->addresses[i];i++) {
|
||||
ret |= ldb_msg_add_winsdb_addr(msg, "address", rec->addresses[i]);
|
||||
}
|
||||
if (rec->registered_by) {
|
||||
ret |= ldb_msg_add_string(msg, "registeredBy", rec->registered_by);
|
||||
if (ret != 0) goto failed;
|
||||
}
|
||||
return msg;
|
||||
|
||||
failed:
|
||||
@ -543,34 +551,37 @@ failed:
|
||||
/*
|
||||
save a WINS record into the database
|
||||
*/
|
||||
uint8_t winsdb_add(struct wins_server *winssrv, struct winsdb_record *rec)
|
||||
uint8_t winsdb_add(struct ldb_context *wins_db, struct winsdb_record *rec, uint32_t flags)
|
||||
{
|
||||
struct ldb_context *ldb = winssrv->wins_db;
|
||||
struct ldb_message *msg;
|
||||
TALLOC_CTX *tmp_ctx = talloc_new(winssrv);
|
||||
TALLOC_CTX *tmp_ctx = talloc_new(wins_db);
|
||||
int trans = -1;
|
||||
int ret = 0;
|
||||
|
||||
trans = ldb_transaction_start(ldb);
|
||||
trans = ldb_transaction_start(wins_db);
|
||||
if (trans != LDB_SUCCESS) goto failed;
|
||||
|
||||
rec->version = winsdb_allocate_version(winssrv);
|
||||
if (flags & WINSDB_FLAG_ALLOC_VERSION) {
|
||||
rec->version = winsdb_allocate_version(wins_db);
|
||||
if (rec->version == 0) goto failed;
|
||||
}
|
||||
if (flags & WINSDB_FLAG_TAKE_OWNERSHIP) {
|
||||
rec->wins_owner = WINSDB_OWNER_LOCAL;
|
||||
}
|
||||
|
||||
msg = winsdb_message(winssrv->wins_db, rec, tmp_ctx);
|
||||
msg = winsdb_message(wins_db, rec, tmp_ctx);
|
||||
if (msg == NULL) goto failed;
|
||||
ret = ldb_add(ldb, msg);
|
||||
ret = ldb_add(wins_db, msg);
|
||||
if (ret != 0) goto failed;
|
||||
|
||||
trans = ldb_transaction_commit(ldb);
|
||||
trans = ldb_transaction_commit(wins_db);
|
||||
if (trans != LDB_SUCCESS) goto failed;
|
||||
|
||||
talloc_free(tmp_ctx);
|
||||
return NBT_RCODE_OK;
|
||||
|
||||
failed:
|
||||
if (trans == LDB_SUCCESS) ldb_transaction_cancel(ldb);
|
||||
if (trans == LDB_SUCCESS) ldb_transaction_cancel(wins_db);
|
||||
talloc_free(tmp_ctx);
|
||||
return NBT_RCODE_SVR;
|
||||
}
|
||||
@ -579,40 +590,43 @@ failed:
|
||||
/*
|
||||
modify a WINS record in the database
|
||||
*/
|
||||
uint8_t winsdb_modify(struct wins_server *winssrv, struct winsdb_record *rec)
|
||||
uint8_t winsdb_modify(struct ldb_context *wins_db, struct winsdb_record *rec, uint32_t flags)
|
||||
{
|
||||
struct ldb_context *ldb = winssrv->wins_db;
|
||||
struct ldb_message *msg;
|
||||
TALLOC_CTX *tmp_ctx = talloc_new(winssrv);
|
||||
TALLOC_CTX *tmp_ctx = talloc_new(wins_db);
|
||||
int trans;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
trans = ldb_transaction_start(ldb);
|
||||
trans = ldb_transaction_start(wins_db);
|
||||
if (trans != LDB_SUCCESS) goto failed;
|
||||
|
||||
rec->version = winsdb_allocate_version(winssrv);
|
||||
if (flags & WINSDB_FLAG_ALLOC_VERSION) {
|
||||
rec->version = winsdb_allocate_version(wins_db);
|
||||
if (rec->version == 0) goto failed;
|
||||
}
|
||||
if (flags & WINSDB_FLAG_TAKE_OWNERSHIP) {
|
||||
rec->wins_owner = WINSDB_OWNER_LOCAL;
|
||||
}
|
||||
|
||||
msg = winsdb_message(winssrv->wins_db, rec, tmp_ctx);
|
||||
msg = winsdb_message(wins_db, rec, tmp_ctx);
|
||||
if (msg == NULL) goto failed;
|
||||
|
||||
for (i=0;i<msg->num_elements;i++) {
|
||||
msg->elements[i].flags = LDB_FLAG_MOD_REPLACE;
|
||||
}
|
||||
|
||||
ret = ldb_modify(ldb, msg);
|
||||
ret = ldb_modify(wins_db, msg);
|
||||
if (ret != 0) goto failed;
|
||||
|
||||
trans = ldb_transaction_commit(ldb);
|
||||
trans = ldb_transaction_commit(wins_db);
|
||||
if (trans != LDB_SUCCESS) goto failed;
|
||||
|
||||
talloc_free(tmp_ctx);
|
||||
return NBT_RCODE_OK;
|
||||
|
||||
failed:
|
||||
if (trans == LDB_SUCCESS) ldb_transaction_cancel(ldb);
|
||||
if (trans == LDB_SUCCESS) ldb_transaction_cancel(wins_db);
|
||||
talloc_free(tmp_ctx);
|
||||
return NBT_RCODE_SVR;
|
||||
}
|
||||
@ -621,31 +635,30 @@ failed:
|
||||
/*
|
||||
delete a WINS record from the database
|
||||
*/
|
||||
uint8_t winsdb_delete(struct wins_server *winssrv, struct winsdb_record *rec)
|
||||
uint8_t winsdb_delete(struct ldb_context *wins_db, struct winsdb_record *rec)
|
||||
{
|
||||
struct ldb_context *ldb = winssrv->wins_db;
|
||||
TALLOC_CTX *tmp_ctx = talloc_new(winssrv);
|
||||
TALLOC_CTX *tmp_ctx = talloc_new(wins_db);
|
||||
const struct ldb_dn *dn;
|
||||
int trans;
|
||||
int ret;
|
||||
|
||||
trans = ldb_transaction_start(ldb);
|
||||
trans = ldb_transaction_start(wins_db);
|
||||
if (trans != LDB_SUCCESS) goto failed;
|
||||
|
||||
dn = winsdb_dn(tmp_ctx, rec->name);
|
||||
if (dn == NULL) goto failed;
|
||||
|
||||
ret = ldb_delete(ldb, dn);
|
||||
ret = ldb_delete(wins_db, dn);
|
||||
if (ret != 0) goto failed;
|
||||
|
||||
trans = ldb_transaction_commit(ldb);
|
||||
trans = ldb_transaction_commit(wins_db);
|
||||
if (trans != LDB_SUCCESS) goto failed;
|
||||
|
||||
talloc_free(tmp_ctx);
|
||||
return NBT_RCODE_OK;
|
||||
|
||||
failed:
|
||||
if (trans == LDB_SUCCESS) ldb_transaction_cancel(ldb);
|
||||
if (trans == LDB_SUCCESS) ldb_transaction_cancel(wins_db);
|
||||
talloc_free(tmp_ctx);
|
||||
return NBT_RCODE_SVR;
|
||||
}
|
||||
|
@ -23,6 +23,9 @@
|
||||
#define WINSDB_OWNER_LOCAL "0.0.0.0"
|
||||
#define WINSDB_GROUP_ADDRESS "255.255.255.255"
|
||||
|
||||
#define WINSDB_FLAG_ALLOC_VERSION (1<<0)
|
||||
#define WINSDB_FLAG_TAKE_OWNERSHIP (1<<1)
|
||||
|
||||
struct winsdb_addr {
|
||||
const char *address;
|
||||
const char *wins_owner;
|
||||
|
@ -83,7 +83,7 @@ static uint8_t wins_register_new(struct nbt_name_socket *nbtsock,
|
||||
rec.is_static = False;
|
||||
rec.expire_time = time(NULL) + ttl;
|
||||
rec.version = 0; /* will allocated later */
|
||||
rec.wins_owner = WINSDB_OWNER_LOCAL;
|
||||
rec.wins_owner = NULL; /* will be set later */
|
||||
rec.registered_by = src->addr;
|
||||
rec.addresses = winsdb_addr_list_make(packet);
|
||||
if (rec.addresses == NULL) return NBT_RCODE_SVR;
|
||||
@ -97,7 +97,7 @@ static uint8_t wins_register_new(struct nbt_name_socket *nbtsock,
|
||||
DEBUG(4,("WINS: accepted registration of %s with address %s\n",
|
||||
nbt_name_string(packet, name), rec.addresses[0]->address));
|
||||
|
||||
return winsdb_add(winssrv, &rec);
|
||||
return winsdb_add(winssrv->wins_db, &rec, WINSDB_FLAG_ALLOC_VERSION | WINSDB_FLAG_TAKE_OWNERSHIP);
|
||||
}
|
||||
|
||||
|
||||
@ -124,7 +124,7 @@ static uint8_t wins_update_ttl(struct nbt_name_socket *nbtsock,
|
||||
DEBUG(5,("WINS: refreshed registration of %s at %s\n",
|
||||
nbt_name_string(packet, rec->name), address));
|
||||
|
||||
return winsdb_modify(winssrv, rec);
|
||||
return winsdb_modify(winssrv->wins_db, rec, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -164,7 +164,8 @@ static void nbtd_winsserver_register(struct nbt_name_socket *nbtsock,
|
||||
rcode = NBT_RCODE_SVR;
|
||||
goto done;
|
||||
} else if (rec->state != WREPL_STATE_ACTIVE) {
|
||||
winsdb_delete(winssrv, rec);
|
||||
/* TODO: this is not always correct!!!*/
|
||||
winsdb_delete(winssrv->wins_db, rec);
|
||||
rcode = wins_register_new(nbtsock, packet, src);
|
||||
goto done;
|
||||
}
|
||||
@ -291,7 +292,7 @@ static void nbtd_winsserver_release(struct nbt_name_socket *nbtsock,
|
||||
if (rec->addresses[0] == NULL) {
|
||||
rec->state = WREPL_STATE_RELEASED;
|
||||
}
|
||||
winsdb_modify(winssrv, rec);
|
||||
winsdb_modify(winssrv->wins_db, rec, 0);
|
||||
}
|
||||
|
||||
done:
|
||||
|
@ -82,7 +82,7 @@ static void wins_wack_allow(struct wack_state *state)
|
||||
|
||||
rec->registered_by = state->src.addr;
|
||||
|
||||
winsdb_modify(state->winssrv, rec);
|
||||
winsdb_modify(state->winssrv->wins_db, rec, WINSDB_FLAG_ALLOC_VERSION | WINSDB_FLAG_TAKE_OWNERSHIP);
|
||||
|
||||
DEBUG(4,("WINS: accepted registration of %s with address %s\n",
|
||||
nbt_name_string(state, rec->name), state->reg_address));
|
||||
|
Loading…
x
Reference in New Issue
Block a user