diff options
author | Stefan Metzmacher <metze@samba.org> | 2006-01-13 16:58:04 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:51:02 -0500 |
commit | cd9752d61f49a07a1e943b524c56e0bb75cdeb61 (patch) | |
tree | b222f4e73663512c7fd960b7940789c3e696a1ab /source4/nbt_server | |
parent | ef1572dbc160f4e0ae7eb5b4aa02fdb8b1817ec4 (diff) | |
download | samba-cd9752d61f49a07a1e943b524c56e0bb75cdeb61.tar.gz samba-cd9752d61f49a07a1e943b524c56e0bb75cdeb61.tar.bz2 samba-cd9752d61f49a07a1e943b524c56e0bb75cdeb61.zip |
r12909: add an ldb module for the wins.ldb,
it currently doesn't do much, but it's later
prevent adding corrupted records via ldbedit,
and will take care of the versionID counter
metze
(This used to be commit a6f279bc43c74cf4dc116cb6ba99f1aed13a4de9)
Diffstat (limited to 'source4/nbt_server')
-rw-r--r-- | source4/nbt_server/config.mk | 10 | ||||
-rw-r--r-- | source4/nbt_server/wins/wins_ldb.c | 137 | ||||
-rw-r--r-- | source4/nbt_server/wins/winsdb.c | 83 | ||||
-rw-r--r-- | source4/nbt_server/wins/winsdb.h | 13 | ||||
-rw-r--r-- | source4/nbt_server/wins/winsserver.c | 2 |
5 files changed, 240 insertions, 5 deletions
diff --git a/source4/nbt_server/config.mk b/source4/nbt_server/config.mk index 330eef6e81..4d5f90e9fb 100644 --- a/source4/nbt_server/config.mk +++ b/source4/nbt_server/config.mk @@ -13,6 +13,16 @@ REQUIRED_SUBSYSTEMS = \ ####################### ####################### +# Start MODULE libldb_wins_ldb +[MODULE::libldb_wins_ldb] +SUBSYSTEM = LIBLDB +OUTPUT_TYPE = MERGEDOBJ +OBJ_FILES = \ + wins/wins_ldb.o +# End MODULE libldb_wins_ldb +####################### + +####################### # Start SUBSYSTEM NBTD_WINS [SUBSYSTEM::NBTD_WINS] OBJ_FILES = \ diff --git a/source4/nbt_server/wins/wins_ldb.c b/source4/nbt_server/wins/wins_ldb.c new file mode 100644 index 0000000000..7bf1fa9916 --- /dev/null +++ b/source4/nbt_server/wins/wins_ldb.c @@ -0,0 +1,137 @@ +/* + ldb database module + + Copyright (C) Stefan Metzmacher 2006 + + 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 + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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. +*/ + +/* + * Name: ldb + * + * Component: ldb winsdb module + * + * Description: verify winsdb records before they're written to disk + * + * Author: Stefan Metzmacher + */ + +#include "includes.h" +#include "nbt_server/nbt_server.h" +#include "nbt_server/wins/winsdb.h" +#include "lib/ldb/include/ldb.h" +#include "lib/ldb/include/ldb_errors.h" +#include "lib/ldb/include/ldb_private.h" + +/* add_record: do things with the sambaPassword attribute */ +static int wins_ldb_verify(struct ldb_module *module, struct ldb_request *req, const struct ldb_message *msg) +{ + struct winsdb_handle *h = talloc_get_type(ldb_get_opaque(module->ldb, "winsdb_handle"), + struct winsdb_handle); + char *error = NULL; + + if (!h) { + error = talloc_strdup(module, "WINS_LDB: INTERNAL ERROR: no winsdb_handle present!"); + ldb_debug(module->ldb, LDB_DEBUG_FATAL, "%s", error); + ldb_set_errstring(module, error); + return LDB_ERR_OTHER; + } + + switch (h->caller) { + case WINSDB_HANDLE_CALLER_NBTD: + case WINSDB_HANDLE_CALLER_WREPL: + /* we trust our nbt and wrepl code ... */ + return ldb_next_request(module, req); + + case WINSDB_HANDLE_CALLER_ADMIN: + error = talloc_strdup(module, "WINS_LDB: TODO verify add/modify for WINSDB_HANDLE_CALLER_ADMIN"); + ldb_debug(module->ldb, LDB_DEBUG_WARNING, "%s\n", error); + return ldb_next_request(module, req); + } + + return LDB_ERR_OTHER; +} + +static int wins_ldb_request(struct ldb_module *module, struct ldb_request *req) +{ + const struct ldb_message *msg = req->op.mod.message; + + switch (req->operation) { + case LDB_REQ_ADD: + msg = req->op.add.message; + break; + + case LDB_REQ_MODIFY: + msg = req->op.mod.message; + break; + + default: + goto call_next; + } + + if (ldb_dn_is_special(msg->dn)) goto call_next; + + return wins_ldb_verify(module, req, msg); + +call_next: + return ldb_next_request(module, req); +} + +static const struct ldb_module_ops wins_ldb_ops = { + .name = "wins_ldb", + .request = wins_ldb_request +}; + + +/* the init function */ +struct ldb_module *wins_ldb_module_init(struct ldb_context *ldb, const char *options[]) +{ + struct ldb_module *ctx; + struct winsdb_handle *h; + const char *owner; + int ret; + + ctx = talloc(ldb, struct ldb_module); + if (!ctx) return NULL; + + ctx->private_data = NULL; + ctx->ldb = ldb; + ctx->prev = ctx->next = NULL; + ctx->ops = &wins_ldb_ops; + + owner = lp_parm_string(-1, "winsdb", "local_owner"); + if (!owner) { + owner = iface_n_ip(0); + if (!owner) { + owner = "0.0.0.0"; + } + } + + h = talloc(ctx, struct winsdb_handle); + if (!h) goto failed; + h->ldb = ldb; + h->caller = WINSDB_HANDLE_CALLER_ADMIN; + h->local_owner = talloc_strdup(h, owner); + if (!h->local_owner) goto failed; + + ret = ldb_set_opaque(ldb, "winsdb_handle", h); + if (ret != LDB_SUCCESS) goto failed; + + return ctx; + +failed: + talloc_free(ctx); + return NULL; +} diff --git a/source4/nbt_server/wins/winsdb.c b/source4/nbt_server/wins/winsdb.c index d2a47e8f7c..3e73d89fdd 100644 --- a/source4/nbt_server/wins/winsdb.c +++ b/source4/nbt_server/wins/winsdb.c @@ -27,7 +27,6 @@ #include "lib/ldb/include/ldb.h" #include "lib/ldb/include/ldb_errors.h" #include "system/time.h" -#include "auth/auth.h" uint64_t winsdb_get_maxVersion(struct winsdb_handle *h) { @@ -771,11 +770,78 @@ failed: return NBT_RCODE_SVR; } -struct winsdb_handle *winsdb_connect(TALLOC_CTX *mem_ctx) +static BOOL winsdb_check_or_add_module_list(struct winsdb_handle *h) +{ + int trans; + int ret; + struct ldb_dn *dn; + struct ldb_result *res = NULL; + struct ldb_message *msg = NULL; + TALLOC_CTX *tmp_ctx = talloc_new(h); + unsigned int flags = 0; + + trans = ldb_transaction_start(h->ldb); + if (trans != LDB_SUCCESS) goto failed; + + /* check if we have a special @MODULES record already */ + dn = ldb_dn_explode(tmp_ctx, "@MODULES"); + if (!dn) goto failed; + + /* find the record in the WINS database */ + ret = ldb_search(h->ldb, dn, LDB_SCOPE_BASE, NULL, NULL, &res); + if (ret != LDB_SUCCESS) goto failed; + talloc_steal(tmp_ctx, res); + + if (res->count > 0) goto skip; + + /* if there's no record, add one */ + msg = ldb_msg_new(tmp_ctx); + if (!msg) goto failed; + msg->dn = dn; + + ret = ldb_msg_add_string(msg, "@LIST", "wins_ldb"); + if (ret != 0) goto failed; + + ret = ldb_add(h->ldb, msg); + if (ret != 0) goto failed; + + trans = ldb_transaction_commit(h->ldb); + if (trans != LDB_SUCCESS) goto failed; + + /* close and reopen the database, with the modules */ + trans = LDB_ERR_OTHER; + talloc_free(h->ldb); + h->ldb = NULL; + + if (lp_parm_bool(-1,"winsdb", "nosync", False)) { + flags |= LDB_FLG_NOSYNC; + } + + h->ldb = ldb_wrap_connect(h, lock_path(h, lp_wins_url()), + NULL, NULL, flags, NULL); + if (!h->ldb) goto failed; + + talloc_free(tmp_ctx); + return True; + +skip: + if (trans == LDB_SUCCESS) ldb_transaction_cancel(h->ldb); + talloc_free(tmp_ctx); + return True; + +failed: + if (trans == LDB_SUCCESS) ldb_transaction_cancel(h->ldb); + talloc_free(tmp_ctx); + return False; +} + +struct winsdb_handle *winsdb_connect(TALLOC_CTX *mem_ctx, enum winsdb_handle_caller caller) { struct winsdb_handle *h = NULL; const char *owner; unsigned int flags = 0; + BOOL ret; + int ldb_err; h = talloc(mem_ctx, struct winsdb_handle); if (!h) return NULL; @@ -785,8 +851,10 @@ struct winsdb_handle *winsdb_connect(TALLOC_CTX *mem_ctx) } h->ldb = ldb_wrap_connect(h, lock_path(h, lp_wins_url()), - system_session(h), NULL, flags, NULL); - if (!h->ldb) goto failed; + NULL, NULL, flags, NULL); + if (!h->ldb) goto failed; + + h->caller = caller; owner = lp_parm_string(-1, "winsdb", "local_owner"); if (!owner) { @@ -796,6 +864,13 @@ struct winsdb_handle *winsdb_connect(TALLOC_CTX *mem_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); + if (!ret) goto failed; + + ldb_err = ldb_set_opaque(h->ldb, "winsdb_handle", h); + if (ldb_err != LDB_SUCCESS) goto failed; + return h; failed: talloc_free(h); diff --git a/source4/nbt_server/wins/winsdb.h b/source4/nbt_server/wins/winsdb.h index 6310966d87..47e11b4694 100644 --- a/source4/nbt_server/wins/winsdb.h +++ b/source4/nbt_server/wins/winsdb.h @@ -47,10 +47,23 @@ struct winsdb_record { const char *registered_by; }; +enum winsdb_handle_caller { + WINSDB_HANDLE_CALLER_ADMIN = 0, + WINSDB_HANDLE_CALLER_NBTD = 1, + WINSDB_HANDLE_CALLER_WREPL = 2 +}; + struct winsdb_handle { /* wins server database handle */ struct ldb_context *ldb; + /* + * the type of the caller, as we pass this to the + * 'wins_ldb' ldb module can decide if it needs to verify the + * the records before they're written to disk + */ + enum winsdb_handle_caller caller; + /* local owner address */ const char *local_owner; }; diff --git a/source4/nbt_server/wins/winsserver.c b/source4/nbt_server/wins/winsserver.c index b5c008121b..7d3ab8294b 100644 --- a/source4/nbt_server/wins/winsserver.c +++ b/source4/nbt_server/wins/winsserver.c @@ -829,7 +829,7 @@ NTSTATUS nbtd_winsserver_init(struct nbtd_server *nbtsrv) tmp = lp_parm_int(-1,"wreplsrv","tombstone_timeout", 1*24*60*60); nbtsrv->winssrv->config.tombstone_timeout = tmp; - nbtsrv->winssrv->wins_db = winsdb_connect(nbtsrv->winssrv); + nbtsrv->winssrv->wins_db = winsdb_connect(nbtsrv->winssrv, WINSDB_HANDLE_CALLER_NBTD); if (!nbtsrv->winssrv->wins_db) { return NT_STATUS_INTERNAL_DB_ERROR; } |