diff options
Diffstat (limited to 'source/lib')
243 files changed, 2054 insertions, 55453 deletions
diff --git a/source/lib/charcnv.c b/source/lib/charcnv.c index 5ca7f201c24..8d5fbc8118d 100644 --- a/source/lib/charcnv.c +++ b/source/lib/charcnv.c @@ -168,7 +168,7 @@ void init_iconv(void) conv_handles[c1][c2] = smb_iconv_open(n2,n1); if (!conv_handles[c1][c2]) { DEBUG(0,("init_iconv: Conversion from %s to %s failed", n1, n2)); - smb_panic("init_iconv: conv_handle initialization failed"); + smb_panic("init_iconv: conv_handle initialization failed."); } } } @@ -1376,24 +1376,16 @@ size_t push_string_fn(const char *function, unsigned int line, const void *base_ The resulting string in "dest" is always null terminated. **/ -size_t pull_string_fn(const char *function, unsigned int line, - const void *base_ptr, uint16 smb_flags2, char *dest, - const void *src, size_t dest_len, size_t src_len, - int flags) +size_t pull_string_fn(const char *function, unsigned int line, const void *base_ptr, char *dest, const void *src, size_t dest_len, size_t src_len, int flags) { #ifdef DEVELOPER if (dest_len != (size_t)-1) clobber_region(function, line, dest, dest_len); #endif - if ((base_ptr == NULL) && ((flags & (STR_ASCII|STR_UNICODE)) == 0)) { - smb_panic("No base ptr to get flg2 and neither ASCII nor " - "UNICODE defined"); - } - if (!(flags & STR_ASCII) && \ ((flags & STR_UNICODE || \ - (smb_flags2 & FLAGS2_UNICODE_STRINGS)))) { + (SVAL(base_ptr, smb_flg2) & FLAGS2_UNICODE_STRINGS)))) { return pull_ucs2(base_ptr, dest, src, dest_len, src_len, flags); } return pull_ascii(dest, src, dest_len, src_len, flags); diff --git a/source/lib/conn_tdb.c b/source/lib/conn_tdb.c deleted file mode 100644 index 979f202df7f..00000000000 --- a/source/lib/conn_tdb.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Low-level connections.tdb access functions - Copyright (C) Volker Lendecke 2007 - - 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. -*/ - -#include "includes.h" - -static struct db_context *connections_db_ctx(BOOL rw) -{ - static struct db_context *db_ctx; - - if (db_ctx != NULL) { - return db_ctx; - } - - if (rw) { - db_ctx = db_open(NULL, lock_path("connections.tdb"), 0, - TDB_CLEAR_IF_FIRST|TDB_DEFAULT, - O_RDWR | O_CREAT, 0644); - } - else { - db_ctx = db_open(NULL, lock_path("connections.tdb"), 0, - TDB_DEFAULT, O_RDONLY, 0); - } - - return db_ctx; -} - -struct db_record *connections_fetch_record(TALLOC_CTX *mem_ctx, - TDB_DATA key) -{ - struct db_context *ctx = connections_db_ctx(True); - - if (ctx == NULL) { - return NULL; - } - - return ctx->fetch_locked(ctx, mem_ctx, key); -} - -struct db_record *connections_fetch_entry(TALLOC_CTX *mem_ctx, - connection_struct *conn, - const char *name) -{ - struct connections_key ckey; - TDB_DATA key; - - ZERO_STRUCT(ckey); - ckey.pid = procid_self(); - ckey.cnum = conn ? conn->cnum : -1; - strlcpy(ckey.name, name, sizeof(ckey.name)); - - key.dsize = sizeof(ckey); - key.dptr = (uint8 *)&ckey; - - return connections_fetch_record(mem_ctx, key); -} - -struct conn_traverse_state { - int (*fn)(struct db_record *rec, - const struct connections_key *key, - const struct connections_data *data, - void *private_data); - void *private_data; -}; - -static int conn_traverse_fn(struct db_record *rec, void *private_data) -{ - struct conn_traverse_state *state = - (struct conn_traverse_state *)private_data; - - if ((rec->key.dsize != sizeof(struct connections_key)) - || (rec->value.dsize != sizeof(struct connections_data))) { - return 0; - } - - return state->fn(rec, (const struct connections_key *)rec->key.dptr, - (const struct connections_data *)rec->value.dptr, - state->private_data); -} - -int connections_traverse(int (*fn)(struct db_record *rec, - void *private_data), - void *private_data) -{ - struct db_context *ctx = connections_db_ctx(False); - - if (ctx == NULL) { - return -1; - } - - return ctx->traverse(ctx, fn, private_data); -} - -int connections_forall(int (*fn)(struct db_record *rec, - const struct connections_key *key, - const struct connections_data *data, - void *private_data), - void *private_data) -{ - struct conn_traverse_state state; - - state.fn = fn; - state.private_data = private_data; - - return connections_traverse(conn_traverse_fn, (void *)&state); -} - -BOOL connections_init(BOOL rw) -{ - return (connections_db_ctx(rw) != NULL); -} diff --git a/source/lib/ctdbd_conn.c b/source/lib/ctdbd_conn.c deleted file mode 100644 index 8c1aab8f371..00000000000 --- a/source/lib/ctdbd_conn.c +++ /dev/null @@ -1,1167 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Samba internal messaging functions - Copyright (C) 2007 by Volker Lendecke - Copyright (C) 2007 by Andrew Tridgell - - 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. -*/ - -#include "includes.h" - -#ifdef CLUSTER_SUPPORT - -#include "librpc/gen_ndr/messaging.h" -#include "librpc/gen_ndr/ndr_messaging.h" - -/* paths to these include files come from --with-ctdb= in configure */ -#include "ctdb.h" -#include "ctdb_private.h" - -struct ctdbd_connection { - struct messaging_context *msg_ctx; - uint32 reqid; - uint32 our_vnn; - uint64 rand_srvid; - struct packet_context *pkt; - struct fd_event *fde; - - void (*release_ip_handler)(const char *ip_addr, void *private_data); - void *release_ip_priv; -}; - -static NTSTATUS ctdbd_control(struct ctdbd_connection *conn, - uint32_t vnn, uint32 opcode, - uint64_t srvid, TDB_DATA data, - TALLOC_CTX *mem_ctx, TDB_DATA *outdata, - int *cstatus); - -/* - * exit on fatal communications errors with the ctdbd daemon - */ -static void cluster_fatal(const char *why) -{ - DEBUG(0,("cluster fatal event: %s - exiting immediately\n", why)); - /* we don't use smb_panic() as we don't want to delay to write - a core file. We need to release this process id immediately - so that someone else can take over without getting sharing - violations */ - _exit(0); -} - -/* - * Register a srvid with ctdbd - */ -static NTSTATUS register_with_ctdbd(struct ctdbd_connection *conn, - uint64_t srvid) -{ - - int cstatus; - return ctdbd_control(conn, CTDB_CURRENT_NODE, - CTDB_CONTROL_REGISTER_SRVID, srvid, - tdb_null, NULL, NULL, &cstatus); -} - -/* - * get our vnn from the cluster - */ -static NTSTATUS get_cluster_vnn(struct ctdbd_connection *conn, uint32 *vnn) -{ - int32_t cstatus=-1; - NTSTATUS status; - status = ctdbd_control(conn, - CTDB_CURRENT_NODE, CTDB_CONTROL_GET_VNN, 0, - tdb_null, NULL, NULL, &cstatus); - if (!NT_STATUS_IS_OK(status)) { - cluster_fatal("ctdbd_control failed\n"); - } - *vnn = (uint32_t)cstatus; - return status; -} - -uint32 ctdbd_vnn(const struct ctdbd_connection *conn) -{ - return conn->our_vnn; -} - -/* - * Get us a ctdb connection - */ - -static NTSTATUS ctdbd_connect(TALLOC_CTX *mem_ctx, - struct packet_context **presult) -{ - struct packet_context *result; - const char *sockname = lp_ctdbd_socket(); - struct sockaddr_un addr; - int fd; - - if (!sockname || !*sockname) { - sockname = CTDB_PATH; - } - - fd = socket(AF_UNIX, SOCK_STREAM, 0); - if (fd == -1) { - DEBUG(3, ("Could not create socket: %s\n", strerror(errno))); - return map_nt_error_from_unix(errno); - } - - ZERO_STRUCT(addr); - addr.sun_family = AF_UNIX; - strncpy(addr.sun_path, sockname, sizeof(addr.sun_path)); - - if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) { - DEBUG(0, ("connect(%s) failed: %s\n", sockname, - strerror(errno))); - close(fd); - return map_nt_error_from_unix(errno); - } - - if (!(result = packet_init(mem_ctx, fd))) { - close(fd); - return NT_STATUS_NO_MEMORY; - } - - *presult = result; - return NT_STATUS_OK; -} - -/* - * Do we have a complete ctdb packet in the queue? - */ - -static BOOL ctdb_req_complete(const struct data_blob *data, - size_t *length, - void *private_data) -{ - uint32 msglen; - - if (data->length < sizeof(msglen)) { - return False; - } - - msglen = *((uint32 *)data->data); - - DEBUG(10, ("msglen = %d\n", msglen)); - - if (msglen < sizeof(struct ctdb_req_header)) { - DEBUG(0, ("Got invalid msglen: %d, expected at least %d for " - "the req_header\n", msglen, - sizeof(struct ctdb_req_header))); - cluster_fatal("ctdbd protocol error\n"); - } - - if (data->length >= msglen) { - *length = msglen; - return True; - } - - return False; -} - -/* - * State necessary to defer an incoming message while we are waiting for a - * ctdb reply. - */ - -struct deferred_msg_state { - struct messaging_context *msg_ctx; - struct messaging_rec *rec; -}; - -/* - * Timed event handler for the deferred message - */ - -static void deferred_message_dispatch(struct event_context *event_ctx, - struct timed_event *te, - const struct timeval *now, - void *private_data) -{ - struct deferred_msg_state *state = talloc_get_type_abort( - private_data, struct deferred_msg_state); - - messaging_dispatch_rec(state->msg_ctx, state->rec); - TALLOC_FREE(state); - TALLOC_FREE(te); -} - -struct req_pull_state { - TALLOC_CTX *mem_ctx; - DATA_BLOB req; -}; - -/* - * Pull a ctdb request out of the incoming packet queue - */ - -static NTSTATUS ctdb_req_pull(const struct data_blob *data, - void *private_data) -{ - struct req_pull_state *state = (struct req_pull_state *)private_data; - - state->req = data_blob_talloc(state->mem_ctx, data->data, - data->length); - if (state->req.data == NULL) { - return NT_STATUS_NO_MEMORY; - } - return NT_STATUS_OK; -} - -/* - * Fetch a messaging_rec from an incoming ctdb style message - */ - -static struct messaging_rec *ctdb_pull_messaging_rec(TALLOC_CTX *mem_ctx, - size_t overall_length, - struct ctdb_req_message *msg) -{ - struct messaging_rec *result; - DATA_BLOB blob; - NTSTATUS status; - - if ((overall_length < offsetof(struct ctdb_req_message, data)) - || (overall_length - < offsetof(struct ctdb_req_message, data) + msg->datalen)) { - - cluster_fatal("got invalid msg length"); - } - - if (!(result = TALLOC_P(mem_ctx, struct messaging_rec))) { - DEBUG(0, ("talloc failed\n")); - return NULL; - } - - blob = data_blob_const(msg->data, msg->datalen); - - status = ndr_pull_struct_blob( - &blob, result, result, - (ndr_pull_flags_fn_t)ndr_pull_messaging_rec); - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("ndr_pull_struct_blob failed: %s\n", - nt_errstr(status))); - TALLOC_FREE(result); - return NULL; - } - - return result; -} - -/* - * Read a full ctdbd request. If we have a messaging context, defer incoming - * messages that might come in between. - */ - -static NTSTATUS ctdb_read_req(struct ctdbd_connection *conn, uint32 reqid, - TALLOC_CTX *mem_ctx, void *result) -{ - struct ctdb_req_header *hdr; - struct req_pull_state state; - NTSTATUS status; - - again: - - status = packet_fd_read_sync(conn->pkt); - - if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_BUSY)) { - /* EAGAIN */ - goto again; - } - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(3, ("packet_fd_read failed: %s\n", nt_errstr(status))); - cluster_fatal("ctdbd died\n"); - } - - ZERO_STRUCT(state); - state.mem_ctx = mem_ctx; - - if (!packet_handler(conn->pkt, ctdb_req_complete, ctdb_req_pull, - &state, &status)) { - /* - * Not enough data - */ - goto again; - } - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(3, ("Could not read packet: %s\n", nt_errstr(status))); - cluster_fatal("ctdbd died\n"); - } - - hdr = (struct ctdb_req_header *)state.req.data; - - if (hdr->operation == CTDB_REQ_MESSAGE) { - struct timed_event *evt; - struct deferred_msg_state *msg_state; - struct ctdb_req_message *msg = (struct ctdb_req_message *)hdr; - - if (conn->msg_ctx == NULL) { - DEBUG(1, ("Got a message without having a msg ctx, " - "dropping msg %llu\n", msg->srvid)); - goto again; - } - - if ((conn->release_ip_handler != NULL) - && (msg->srvid == CTDB_SRVID_RELEASE_IP)) { - /* must be dispatched immediately */ - DEBUG(10, ("received CTDB_SRVID_RELEASE_IP\n")); - conn->release_ip_handler((const char *)msg->data, - conn->release_ip_priv); - TALLOC_FREE(hdr); - goto again; - } - - if (!(msg_state = TALLOC_P(NULL, struct deferred_msg_state))) { - DEBUG(0, ("talloc failed\n")); - TALLOC_FREE(hdr); - goto again; - } - - if (!(msg_state->rec = ctdb_pull_messaging_rec( - msg_state, state.req.length, msg))) { - DEBUG(0, ("ctdbd_pull_messaging_rec failed\n")); - TALLOC_FREE(msg_state); - TALLOC_FREE(hdr); - goto again; - } - - TALLOC_FREE(hdr); - - msg_state->msg_ctx = conn->msg_ctx; - - /* - * We're waiting for a call reply, but an async message has - * crossed. Defer dispatching to the toplevel event loop. - */ - evt = event_add_timed(conn->msg_ctx->event_ctx, - conn->msg_ctx->event_ctx, - timeval_zero(), - "deferred_message_dispatch", - deferred_message_dispatch, - msg_state); - if (evt == NULL) { - DEBUG(0, ("event_add_timed failed\n")); - TALLOC_FREE(msg_state); - TALLOC_FREE(hdr); - goto again; - } - - goto again; - } - - if (hdr->reqid != reqid) { - /* we got the wrong reply */ - DEBUG(0,("Discarding mismatched ctdb reqid %u should have " - "been %u\n", hdr->reqid, reqid)); - TALLOC_FREE(hdr); - goto again; - } - - *((void **)result) = talloc_move(mem_ctx, &hdr); - - return NT_STATUS_OK; -} - -/* - * Get us a ctdbd connection - */ - -NTSTATUS ctdbd_init_connection(TALLOC_CTX *mem_ctx, - struct ctdbd_connection **pconn) -{ - struct ctdbd_connection *conn; - NTSTATUS status; - - if (!(conn = TALLOC_ZERO_P(mem_ctx, struct ctdbd_connection))) { - DEBUG(0, ("talloc failed\n")); - return NT_STATUS_NO_MEMORY; - } - - status = ctdbd_connect(conn, &conn->pkt); - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(10, ("ctdbd_connect failed: %s\n", nt_errstr(status))); - goto fail; - } - - status = get_cluster_vnn(conn, &conn->our_vnn); - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(10, ("get_cluster_vnn failed: %s\n", nt_errstr(status))); - goto fail; - } - - generate_random_buffer((unsigned char *)&conn->rand_srvid, - sizeof(conn->rand_srvid)); - - status = register_with_ctdbd(conn, conn->rand_srvid); - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(5, ("Could not register random srvid: %s\n", - nt_errstr(status))); - goto fail; - } - - *pconn = conn; - return NT_STATUS_OK; - - fail: - TALLOC_FREE(conn); - return status; -} - -/* - * Get us a ctdbd connection and register us as a process - */ - -NTSTATUS ctdbd_messaging_connection(TALLOC_CTX *mem_ctx, - struct ctdbd_connection **pconn) -{ - struct ctdbd_connection *conn; - NTSTATUS status; - - status = ctdbd_init_connection(mem_ctx, &conn); - - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - status = register_with_ctdbd(conn, (uint64_t)sys_getpid()); - if (!NT_STATUS_IS_OK(status)) { - goto fail; - } - - status = register_with_ctdbd(conn, MSG_SRVID_SAMBA); - if (!NT_STATUS_IS_OK(status)) { - goto fail; - } - - *pconn = conn; - return NT_STATUS_OK; - - fail: - TALLOC_FREE(conn); - return status; -} - -/* - * Packet handler to receive and handle a ctdb message - */ -static NTSTATUS ctdb_handle_message(const struct data_blob *data, - void *private_data) -{ - struct ctdbd_connection *conn = talloc_get_type_abort( - private_data, struct ctdbd_connection); - struct ctdb_req_message *msg; - struct messaging_rec *msg_rec; - - msg = (struct ctdb_req_message *)data->data; - - if (msg->hdr.operation != CTDB_REQ_MESSAGE) { - DEBUG(0, ("Received async msg of type %u, discarding\n", - msg->hdr.operation)); - return NT_STATUS_INVALID_PARAMETER; - } - - if ((conn->release_ip_handler != NULL) - && (msg->srvid == CTDB_SRVID_RELEASE_IP)) { - /* must be dispatched immediately */ - DEBUG(10, ("received CTDB_SRVID_RELEASE_IP\n")); - conn->release_ip_handler((const char *)msg->data, - conn->release_ip_priv); - return NT_STATUS_OK; - } - - SMB_ASSERT(conn->msg_ctx != NULL); - - if (msg->srvid == CTDB_SRVID_RECONFIGURE) { - DEBUG(0,("Got cluster reconfigure message\n")); - /* - * when the cluster is reconfigured, we need to clean the brl - * database - */ - messaging_send(conn->msg_ctx, procid_self(), - MSG_SMB_BRL_VALIDATE, &data_blob_null); - - /* - * it's possible that we have just rejoined the cluster after - * an outage. In that case our pending locks could have been - * removed from the lockdb, so retry them once more - */ - message_send_all(conn->msg_ctx, MSG_SMB_UNLOCK, NULL, 0, NULL); - - return NT_STATUS_OK; - - } - - /* only messages to our pid or the broadcast are valid here */ - if (msg->srvid != sys_getpid() && msg->srvid != MSG_SRVID_SAMBA) { - DEBUG(0,("Got unexpected message with srvid=%llu\n", - (unsigned long long)msg->srvid)); - return NT_STATUS_OK; - } - - if (!(msg_rec = ctdb_pull_messaging_rec(NULL, data->length, msg))) { - DEBUG(10, ("ctdb_pull_messaging_rec failed\n")); - return NT_STATUS_NO_MEMORY; - } - - messaging_dispatch_rec(conn->msg_ctx, msg_rec); - - TALLOC_FREE(msg_rec); - return NT_STATUS_OK; -} - -/* - * The ctdbd socket is readable asynchronuously - */ - -static void ctdbd_socket_handler(struct event_context *event_ctx, - struct fd_event *event, - uint16 flags, - void *private_data) -{ - struct ctdbd_connection *conn = talloc_get_type_abort( - private_data, struct ctdbd_connection); - - NTSTATUS status; - - status = packet_fd_read(conn->pkt); - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("packet_fd_read failed: %s\n", nt_errstr(status))); - cluster_fatal("ctdbd died\n"); - } - - while (packet_handler(conn->pkt, ctdb_req_complete, - ctdb_handle_message, conn, &status)) { - if (!NT_STATUS_IS_OK(status)) { - DEBUG(10, ("could not handle incoming message: %s\n", - nt_errstr(status))); - } - } -} - -/* - * Prepare a ctdbd connection to receive messages - */ - -NTSTATUS ctdbd_register_msg_ctx(struct ctdbd_connection *conn, - struct messaging_context *msg_ctx) -{ - SMB_ASSERT(conn->msg_ctx == NULL); - SMB_ASSERT(conn->fde == NULL); - - if (!(conn->fde = event_add_fd(msg_ctx->event_ctx, conn, - packet_get_fd(conn->pkt), - EVENT_FD_READ, - ctdbd_socket_handler, - conn))) { - DEBUG(0, ("event_add_fd failed\n")); - return NT_STATUS_NO_MEMORY; - } - - conn->msg_ctx = msg_ctx; - - return NT_STATUS_OK; -} - -/* - * Send a messaging message across a ctdbd - */ - -NTSTATUS ctdbd_messaging_send(struct ctdbd_connection *conn, - uint32 dst_vnn, uint64 dst_srvid, - struct messaging_rec *msg) -{ - struct ctdb_req_message r; - TALLOC_CTX *mem_ctx; - DATA_BLOB blob; - NTSTATUS status; - - if (!(mem_ctx = talloc_init("ctdbd_messaging_send"))) { - DEBUG(0, ("talloc failed\n")); - return NT_STATUS_NO_MEMORY; - } - - status = ndr_push_struct_blob( - &blob, mem_ctx, msg, - (ndr_push_flags_fn_t)ndr_push_messaging_rec); - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("ndr_push_struct_blob failed: %s\n", - nt_errstr(status))); - goto fail; - } - - r.hdr.length = offsetof(struct ctdb_req_message, data) + blob.length; - r.hdr.ctdb_magic = CTDB_MAGIC; - r.hdr.ctdb_version = CTDB_VERSION; - r.hdr.generation = 1; - r.hdr.operation = CTDB_REQ_MESSAGE; - r.hdr.destnode = dst_vnn; - r.hdr.srcnode = conn->our_vnn; - r.hdr.reqid = 0; - r.srvid = dst_srvid; - r.datalen = blob.length; - - status = packet_send( - conn->pkt, 2, - data_blob_const(&r, offsetof(struct ctdb_req_message, data)), - blob); - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("packet_send failed: %s\n", nt_errstr(status))); - goto fail; - } - - status = packet_flush(conn->pkt); - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(3, ("write to ctdbd failed: %s\n", nt_errstr(status))); - cluster_fatal("cluster dispatch daemon msg write error\n"); - } - - status = NT_STATUS_OK; - fail: - TALLOC_FREE(mem_ctx); - return status; -} - -/* - * send/recv a generic ctdb control message - */ -static NTSTATUS ctdbd_control(struct ctdbd_connection *conn, - uint32_t vnn, uint32 opcode, - uint64_t srvid, TDB_DATA data, - TALLOC_CTX *mem_ctx, TDB_DATA *outdata, - int *cstatus) -{ - struct ctdb_req_control req; - struct ctdb_reply_control *reply = NULL; - struct ctdbd_connection *new_conn = NULL; - NTSTATUS status; - - if (conn == NULL) { - status = ctdbd_init_connection(NULL, &new_conn); - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(10, ("Could not init temp connection: %s\n", - nt_errstr(status))); - goto fail; - } - - conn = new_conn; - } - - ZERO_STRUCT(req); - req.hdr.length = offsetof(struct ctdb_req_control, data) + data.dsize; - req.hdr.ctdb_magic = CTDB_MAGIC; - req.hdr.ctdb_version = CTDB_VERSION; - req.hdr.operation = CTDB_REQ_CONTROL; - req.hdr.reqid = ++conn->reqid; - req.hdr.destnode = vnn; - req.opcode = opcode; - req.srvid = srvid; - req.datalen = data.dsize; - - status = packet_send( - conn->pkt, 2, - data_blob_const(&req, offsetof(struct ctdb_req_control, data)), - data); - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(3, ("packet_send failed: %s\n", nt_errstr(status))); - goto fail; - } - - status = packet_flush(conn->pkt); - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(3, ("write to ctdbd failed: %s\n", nt_errstr(status))); - cluster_fatal("cluster dispatch daemon control write error\n"); - } - - status = ctdb_read_req(conn, req.hdr.reqid, NULL, (void *)&reply); - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(10, ("ctdb_read_req failed: %s\n", nt_errstr(status))); - goto fail; - } - - if (reply->hdr.operation != CTDB_REPLY_CONTROL) { - DEBUG(0, ("received invalid reply\n")); - goto fail; - } - - if (outdata) { - if (!(outdata->dptr = (uint8 *)talloc_memdup( - mem_ctx, reply->data, reply->datalen))) { - TALLOC_FREE(reply); - return NT_STATUS_NO_MEMORY; - } - outdata->dsize = reply->datalen; - } - if (cstatus) { - (*cstatus) = reply->status; - } - - status = NT_STATUS_OK; - - fail: - TALLOC_FREE(new_conn); - TALLOC_FREE(reply); - return status; -} - -/* - * see if a remote process exists - */ -BOOL ctdbd_process_exists(struct ctdbd_connection *conn, uint32 vnn, pid_t pid) -{ - NTSTATUS status; - TDB_DATA data; - int32_t cstatus; - - data.dptr = (uint8_t*)&pid; - data.dsize = sizeof(pid); - - status = ctdbd_control(conn, vnn, CTDB_CONTROL_PROCESS_EXISTS, 0, - data, NULL, NULL, &cstatus); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, (__location__ " ctdb_control for process_exists " - "failed\n")); - return False; - } - - return cstatus == 0; -} - -/* - * Get a db path - */ -char *ctdbd_dbpath(struct ctdbd_connection *conn, - TALLOC_CTX *mem_ctx, uint32_t db_id) -{ - NTSTATUS status; - TDB_DATA data; - int32_t cstatus; - - data.dptr = (uint8_t*)&db_id; - data.dsize = sizeof(db_id); - - status = ctdbd_control(conn, CTDB_CURRENT_NODE, - CTDB_CONTROL_GETDBPATH, 0, data, - mem_ctx, &data, &cstatus); - if (!NT_STATUS_IS_OK(status) || cstatus != 0) { - DEBUG(0,(__location__ " ctdb_control for getdbpath failed\n")); - return NULL; - } - - return (char *)data.dptr; -} - -/* - * attach to a ctdb database - */ -NTSTATUS ctdbd_db_attach(struct ctdbd_connection *conn, - const char *name, uint32_t *db_id, int tdb_flags) -{ - NTSTATUS status; - TDB_DATA data; - int32_t cstatus; - - data.dptr = (uint8_t*)name; - data.dsize = strlen(name)+1; - - status = ctdbd_control(conn, CTDB_CURRENT_NODE, - CTDB_CONTROL_DB_ATTACH, 0, data, - NULL, &data, &cstatus); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, (__location__ " ctdb_control for db_attach " - "failed: %s\n", nt_errstr(status))); - return status; - } - - if (cstatus != 0 || data.dsize != sizeof(uint32_t)) { - DEBUG(0,(__location__ " ctdb_control for db_attach failed\n")); - return NT_STATUS_INTERNAL_ERROR; - } - - *db_id = *(uint32_t *)data.dptr; - talloc_free(data.dptr); - - if (!(tdb_flags & TDB_SEQNUM)) { - return NT_STATUS_OK; - } - - data.dptr = (uint8_t *)db_id; - data.dsize = sizeof(*db_id); - - status = ctdbd_control(conn, CTDB_CURRENT_NODE, - CTDB_CONTROL_ENABLE_SEQNUM, 0, data, - NULL, NULL, &cstatus); - if (!NT_STATUS_IS_OK(status) || cstatus != 0) { - DEBUG(0,(__location__ " ctdb_control for enable seqnum " - "failed\n")); - return NT_STATUS_IS_OK(status) ? NT_STATUS_INTERNAL_ERROR : - status; - } - - return NT_STATUS_OK; -} - -/* - * force the migration of a record to this node - */ -NTSTATUS ctdbd_migrate(struct ctdbd_connection *conn, uint32 db_id, - TDB_DATA key) -{ - struct ctdb_req_call req; - struct ctdb_reply_call *reply; - NTSTATUS status; - - ZERO_STRUCT(req); - - req.hdr.length = offsetof(struct ctdb_req_call, data) + key.dsize; - req.hdr.ctdb_magic = CTDB_MAGIC; - req.hdr.ctdb_version = CTDB_VERSION; - req.hdr.operation = CTDB_REQ_CALL; - req.hdr.reqid = ++conn->reqid; - req.flags = CTDB_IMMEDIATE_MIGRATION; - req.callid = CTDB_NULL_FUNC; - req.db_id = db_id; - req.keylen = key.dsize; - - status = packet_send( - conn->pkt, 2, - data_blob_const(&req, offsetof(struct ctdb_req_call, data)), - key); - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(3, ("packet_send failed: %s\n", nt_errstr(status))); - return status; - } - - status = packet_flush(conn->pkt); - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(3, ("write to ctdbd failed: %s\n", nt_errstr(status))); - cluster_fatal("cluster dispatch daemon control write error\n"); - } - - status = ctdb_read_req(conn, req.hdr.reqid, NULL, (void *)&reply); - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("ctdb_read_req failed: %s\n", nt_errstr(status))); - goto fail; - } - - if (reply->hdr.operation != CTDB_REPLY_CALL) { - DEBUG(0, ("received invalid reply\n")); - status = NT_STATUS_INTERNAL_ERROR; - goto fail; - } - - status = NT_STATUS_OK; - fail: - - TALLOC_FREE(reply); - return status; -} - -/* - * remotely fetch a record without locking it or forcing a migration - */ -NTSTATUS ctdbd_fetch(struct ctdbd_connection *conn, uint32 db_id, - TDB_DATA key, TALLOC_CTX *mem_ctx, TDB_DATA *data) -{ - struct ctdb_req_call req; - struct ctdb_reply_call *reply; - NTSTATUS status; - - ZERO_STRUCT(req); - - req.hdr.length = offsetof(struct ctdb_req_call, data) + key.dsize; - req.hdr.ctdb_magic = CTDB_MAGIC; - req.hdr.ctdb_version = CTDB_VERSION; - req.hdr.operation = CTDB_REQ_CALL; - req.hdr.reqid = ++conn->reqid; - req.flags = 0; - req.callid = CTDB_FETCH_FUNC; - req.db_id = db_id; - req.keylen = key.dsize; - - status = packet_send( - conn->pkt, 2, - data_blob_const(&req, offsetof(struct ctdb_req_call, data)), - key); - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(3, ("packet_send failed: %s\n", nt_errstr(status))); - return status; - } - - status = packet_flush(conn->pkt); - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(3, ("write to ctdbd failed: %s\n", nt_errstr(status))); - cluster_fatal("cluster dispatch daemon control write error\n"); - } - - status = ctdb_read_req(conn, req.hdr.reqid, NULL, (void *)&reply); - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("ctdb_read_req failed: %s\n", nt_errstr(status))); - goto fail; - } - - if (reply->hdr.operation != CTDB_REPLY_CALL) { - DEBUG(0, ("received invalid reply\n")); - status = NT_STATUS_INTERNAL_ERROR; - goto fail; - } - - data->dsize = reply->datalen; - if (data->dsize == 0) { - data->dptr = NULL; - goto done; - } - - data->dptr = (uint8 *)talloc_memdup(mem_ctx, &reply->data[0], - reply->datalen); - if (data->dptr == NULL) { - DEBUG(0, ("talloc failed\n")); - status = NT_STATUS_NO_MEMORY; - goto fail; - } - - done: - status = NT_STATUS_OK; - fail: - TALLOC_FREE(reply); - return status; -} - -struct ctdbd_traverse_state { - void (*fn)(TDB_DATA key, TDB_DATA data, void *private_data); - void *private_data; -}; - -/* - * Handle a traverse record coming in on the ctdbd connection - */ - -static NTSTATUS ctdb_traverse_handler(const struct data_blob *blob, - void *private_data) -{ - struct ctdbd_traverse_state *state = - (struct ctdbd_traverse_state *)private_data; - - struct ctdb_req_message *m; - struct ctdb_rec_data *d; - TDB_DATA key, data; - - m = (struct ctdb_req_message *)blob->data; - - if (blob->length < sizeof(*m) || m->hdr.length != blob->length) { - DEBUG(0, ("Got invalid message of length %d\n", - (int)blob->length)); - return NT_STATUS_UNEXPECTED_IO_ERROR; - } - - d = (struct ctdb_rec_data *)&m->data[0]; - if (m->datalen < sizeof(uint32_t) || m->datalen != d->length) { - DEBUG(0, ("Got invalid traverse data of length %d\n", - (int)m->datalen)); - return NT_STATUS_UNEXPECTED_IO_ERROR; - } - - key.dsize = d->keylen; - key.dptr = &d->data[0]; - data.dsize = d->datalen; - data.dptr = &d->data[d->keylen]; - - if (key.dsize == 0 && data.dsize == 0) { - /* end of traverse */ - return NT_STATUS_END_OF_FILE; - } - - if (data.dsize < sizeof(struct ctdb_ltdb_header)) { - DEBUG(0, ("Got invalid ltdb header length %d\n", - (int)data.dsize)); - return NT_STATUS_UNEXPECTED_IO_ERROR; - } - data.dsize -= sizeof(struct ctdb_ltdb_header); - data.dptr += sizeof(struct ctdb_ltdb_header); - - if (state->fn) { - state->fn(key, data, state->private_data); - } - - return NT_STATUS_OK; -} - -/* - Traverse a ctdb database. This uses a kind-of hackish way to open a second - connection to ctdbd to avoid the hairy recursive and async problems with - everything in-line. -*/ - -NTSTATUS ctdbd_traverse(uint32 db_id, - void (*fn)(TDB_DATA key, TDB_DATA data, - void *private_data), - void *private_data) -{ - struct ctdbd_connection *conn; - NTSTATUS status; - - TDB_DATA data; - struct ctdb_traverse_start t; - int cstatus; - struct ctdbd_traverse_state state; - - status = ctdbd_init_connection(NULL, &conn); - - t.db_id = db_id; - t.srvid = conn->rand_srvid; - t.reqid = ++conn->reqid; - - data.dptr = (uint8_t *)&t; - data.dsize = sizeof(t); - - status = ctdbd_control(conn, CTDB_CURRENT_NODE, - CTDB_CONTROL_TRAVERSE_START, conn->rand_srvid, - data, NULL, NULL, &cstatus); - - if (!NT_STATUS_IS_OK(status) || (cstatus != 0)) { - - DEBUG(0,("ctdbd_control failed: %s, %d\n", nt_errstr(status), - cstatus)); - - if (NT_STATUS_IS_OK(status)) { - /* - * We need a mapping here - */ - status = NT_STATUS_UNSUCCESSFUL; - } - goto done; - } - - state.fn = fn; - state.private_data = private_data; - - while (True) { - - status = NT_STATUS_OK; - - if (packet_handler(conn->pkt, ctdb_req_complete, - ctdb_traverse_handler, &state, &status)) { - - if (NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)) { - status = NT_STATUS_OK; - break; - } - - /* - * There might be more in the queue - */ - continue; - } - - if (!NT_STATUS_IS_OK(status)) { - break; - } - - status = packet_fd_read_sync(conn->pkt); - - if (NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)) { - status = NT_STATUS_OK; - } - - if (!NT_STATUS_IS_OK(status)) { - cluster_fatal("ctdbd died\n"); - } - } - - done: - TALLOC_FREE(conn); - return status; -} - -/* - * Register us as a server for a particular tcp connection - */ - -NTSTATUS ctdbd_register_ips(struct ctdbd_connection *conn, - const struct sockaddr_in *server, - const struct sockaddr_in *client, - void (*release_ip_handler)(const char *ip_addr, - void *private_data), - void *private_data) -{ - struct ctdb_control_tcp p; - TDB_DATA data; - NTSTATUS status; - - /* - * Only one connection so far - */ - SMB_ASSERT(conn->release_ip_handler == NULL); - - /* - * We want to be told about IP releases - */ - - status = register_with_ctdbd(conn, CTDB_SRVID_RELEASE_IP); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - p.dest = *server; - p.src = *client; - - /* - * inform ctdb of our tcp connection, so if IP takeover happens ctdb - * can send an extra ack to trigger a reset for our client, so it - * immediately reconnects - */ - data.dptr = (uint8_t *)&p; - data.dsize = sizeof(p); - - return ctdbd_control(conn, CTDB_CURRENT_NODE, - CTDB_CONTROL_TCP_CLIENT, - CTDB_CTRL_FLAG_NOREPLY, data, NULL, NULL, NULL); -} - -/* - * We want to handle reconfigure events - */ -NTSTATUS ctdbd_register_reconfigure(struct ctdbd_connection *conn) -{ - return register_with_ctdbd(conn, CTDB_SRVID_RECONFIGURE); -} - -#else - -NTSTATUS ctdbd_init_connection(TALLOC_CTX *mem_ctx, - struct ctdbd_connection **pconn) -{ - return NT_STATUS_NOT_IMPLEMENTED; -} - -#endif diff --git a/source/lib/data_blob.c b/source/lib/data_blob.c index ebe97230e40..e07247bc49e 100644 --- a/source/lib/data_blob.c +++ b/source/lib/data_blob.c @@ -21,8 +21,6 @@ #include "includes.h" -const DATA_BLOB data_blob_null = { NULL, 0, NULL }; - /******************************************************************* Free() a data blob. *******************************************************************/ @@ -74,11 +72,11 @@ DATA_BLOB data_blob_talloc(TALLOC_CTX *mem_ctx, const void *p, size_t length) if (p) { ret.data = (uint8 *)TALLOC_MEMDUP(mem_ctx, p, length); if (ret.data == NULL) - smb_panic("data_blob_talloc: TALLOC_MEMDUP failed"); + smb_panic("data_blob_talloc: TALLOC_MEMDUP failed.\n"); } else { ret.data = (uint8 *)TALLOC(mem_ctx, length); if (ret.data == NULL) - smb_panic("data_blob_talloc: TALLOC failed"); + smb_panic("data_blob_talloc: talloc failed.\n"); } ret.length = length; diff --git a/source/lib/dbwrap.c b/source/lib/dbwrap.c deleted file mode 100644 index c06cd4bb164..00000000000 --- a/source/lib/dbwrap.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Database interface wrapper - Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2006 - - Major code contributions from Aleksey Fedoseev (fedoseev@ru.ibm.com) - - 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. -*/ - -#include "includes.h" - -/* - * Fall back using fetch_locked if no genuine fetch operation is provided - */ - -static int dbwrap_fallback_fetch(struct db_context *db, TALLOC_CTX *mem_ctx, - TDB_DATA key, TDB_DATA *data) -{ - struct db_record *rec; - - if (!(rec = db->fetch_locked(db, mem_ctx, key))) { - return -1; - } - - data->dsize = rec->value.dsize; - data->dptr = talloc_move(mem_ctx, &rec->value.dptr); - TALLOC_FREE(rec); - return 0; -} - -struct db_context *db_open(TALLOC_CTX *mem_ctx, - const char *name, - int hash_size, int tdb_flags, - int open_flags, mode_t mode) -{ - struct db_context *result = NULL; - -#ifdef CLUSTER_SUPPORT - - if (lp_clustering()) { - const char *partname; - /* ctdb only wants the file part of the name */ - partname = strrchr(name, '/'); - if (partname) { - partname++; - } else { - partname = name; - } - /* allow ctdb for individual databases to be disabled */ - if (lp_parm_bool(-1, "ctdb", partname, True)) { - result = db_open_ctdb(mem_ctx, partname, hash_size, - tdb_flags, open_flags, mode); - if (result == NULL) { - DEBUG(0,("failed to attach to ctdb %s\n", - partname)); - smb_panic("failed to attach to a ctdb " - "database"); - } - } - } - -#endif - - if (result == NULL) { - result = db_open_tdb(mem_ctx, name, hash_size, - tdb_flags, open_flags, mode); - } - - if ((result != NULL) && (result->fetch == NULL)) { - result->fetch = dbwrap_fallback_fetch; - } - - return result; -} diff --git a/source/lib/dbwrap_ctdb.c b/source/lib/dbwrap_ctdb.c deleted file mode 100644 index 124485e539c..00000000000 --- a/source/lib/dbwrap_ctdb.c +++ /dev/null @@ -1,451 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Database interface wrapper around ctdbd - Copyright (C) Volker Lendecke 2007 - - 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. -*/ - -#include "includes.h" - -#ifdef CLUSTER_SUPPORT - -#include "ctdb.h" -#include "ctdb_private.h" - -struct db_ctdb_ctx { - struct tdb_wrap *wtdb; - uint32 db_id; - struct ctdbd_connection *conn; -}; - -struct db_ctdb_rec { - struct db_ctdb_ctx *ctdb_ctx; - struct ctdb_ltdb_header header; -}; - -static struct ctdbd_connection *db_ctdbd_conn(struct db_ctdb_ctx *ctx); - -static NTSTATUS db_ctdb_store(struct db_record *rec, TDB_DATA data, int flag) -{ - struct db_ctdb_rec *crec = talloc_get_type_abort( - rec->private_data, struct db_ctdb_rec); - TDB_DATA cdata; - int ret; - - cdata.dsize = sizeof(crec->header) + data.dsize; - - if (!(cdata.dptr = SMB_MALLOC_ARRAY(uint8, cdata.dsize))) { - return NT_STATUS_NO_MEMORY; - } - - memcpy(cdata.dptr, &crec->header, sizeof(crec->header)); - memcpy(cdata.dptr + sizeof(crec->header), data.dptr, data.dsize); - - ret = tdb_store(crec->ctdb_ctx->wtdb->tdb, rec->key, cdata, TDB_REPLACE); - - SAFE_FREE(cdata.dptr); - - return (ret == 0) ? NT_STATUS_OK : NT_STATUS_INTERNAL_DB_CORRUPTION; -} - -static NTSTATUS db_ctdb_delete(struct db_record *rec) -{ - struct db_ctdb_rec *crec = talloc_get_type_abort( - rec->private_data, struct db_ctdb_rec); - TDB_DATA data; - int ret; - - /* - * We have to store the header with empty data. TODO: Fix the - * tdb-level cleanup - */ - - data.dptr = (uint8 *)&crec->header; - data.dsize = sizeof(crec->header); - - ret = tdb_store(crec->ctdb_ctx->wtdb->tdb, rec->key, data, TDB_REPLACE); - - return (ret == 0) ? NT_STATUS_OK : NT_STATUS_INTERNAL_DB_CORRUPTION; -} - -static int db_ctdb_record_destr(struct db_record* data) -{ - struct db_ctdb_rec *crec = talloc_get_type_abort( - data->private_data, struct db_ctdb_rec); - - DEBUG(10, ("Unlocking key %s\n", - hex_encode(data, (unsigned char *)data->key.dptr, - data->key.dsize))); - - if (tdb_chainunlock(crec->ctdb_ctx->wtdb->tdb, data->key) != 0) { - DEBUG(0, ("tdb_chainunlock failed\n")); - return -1; - } - - return 0; -} - -static struct db_record *db_ctdb_fetch_locked(struct db_context *db, - TALLOC_CTX *mem_ctx, - TDB_DATA key) -{ - struct db_ctdb_ctx *ctx = talloc_get_type_abort(db->private_data, - struct db_ctdb_ctx); - struct db_record *result; - struct db_ctdb_rec *crec; - NTSTATUS status; - TDB_DATA ctdb_data; - - if (!(result = talloc(mem_ctx, struct db_record))) { - DEBUG(0, ("talloc failed\n")); - return NULL; - } - - if (!(crec = TALLOC_ZERO_P(result, struct db_ctdb_rec))) { - DEBUG(0, ("talloc failed\n")); - TALLOC_FREE(result); - return NULL; - } - - result->private_data = (void *)crec; - crec->ctdb_ctx = ctx; - - result->key.dsize = key.dsize; - result->key.dptr = (uint8 *)talloc_memdup(result, key.dptr, key.dsize); - if (result->key.dptr == NULL) { - DEBUG(0, ("talloc failed\n")); - TALLOC_FREE(result); - return NULL; - } - - /* - * Do a blocking lock on the record - */ -again: - - DEBUG(10, ("Locking key %s\n", - hex_encode(result, (unsigned char *)key.dptr, - key.dsize))); - - if (tdb_chainlock(ctx->wtdb->tdb, key) != 0) { - DEBUG(3, ("tdb_chainlock failed\n")); - TALLOC_FREE(result); - return NULL; - } - - result->store = db_ctdb_store; - result->delete_rec = db_ctdb_delete; - talloc_set_destructor(result, db_ctdb_record_destr); - - ctdb_data = tdb_fetch(ctx->wtdb->tdb, key); - - /* - * See if we have a valid record and we are the dmaster. If so, we can - * take the shortcut and just return it. - */ - - if ((ctdb_data.dptr == NULL) || - (ctdb_data.dsize < sizeof(struct ctdb_ltdb_header)) || - ((struct ctdb_ltdb_header *)ctdb_data.dptr)->dmaster != get_my_vnn() -#if 0 - || (random() % 2 != 0) -#endif -) { - SAFE_FREE(ctdb_data.dptr); - tdb_chainunlock(ctx->wtdb->tdb, key); - talloc_set_destructor(result, NULL); - - DEBUG(10, ("ctdb_data.dptr = %p, dmaster = %u (%u)\n", - ctdb_data.dptr, ctdb_data.dptr ? - ((struct ctdb_ltdb_header *)ctdb_data.dptr)->dmaster : -1, - get_my_vnn())); - - status = ctdbd_migrate(db_ctdbd_conn(ctx), ctx->db_id, key); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(5, ("ctdb_migrate failed: %s\n", - nt_errstr(status))); - TALLOC_FREE(result); - return NULL; - } - /* now its migrated, try again */ - goto again; - } - - memcpy(&crec->header, ctdb_data.dptr, sizeof(crec->header)); - - result->value.dsize = ctdb_data.dsize - sizeof(crec->header); - result->value.dptr = NULL; - - if ((result->value.dsize != 0) - && !(result->value.dptr = (uint8 *)talloc_memdup( - result, ctdb_data.dptr + sizeof(crec->header), - result->value.dsize))) { - DEBUG(0, ("talloc failed\n")); - TALLOC_FREE(result); - } - - SAFE_FREE(ctdb_data.dptr); - - return result; -} - -/* - fetch (unlocked, no migration) operation on ctdb - */ -static int db_ctdb_fetch(struct db_context *db, TALLOC_CTX *mem_ctx, - TDB_DATA key, TDB_DATA *data) -{ - struct db_ctdb_ctx *ctx = talloc_get_type_abort(db->private_data, - struct db_ctdb_ctx); - NTSTATUS status; - TDB_DATA ctdb_data; - - /* try a direct fetch */ - ctdb_data = tdb_fetch(ctx->wtdb->tdb, key); - - /* - * See if we have a valid record and we are the dmaster. If so, we can - * take the shortcut and just return it. - */ - if ((ctdb_data.dptr != NULL) && - (ctdb_data.dsize >= sizeof(struct ctdb_ltdb_header)) && - ((struct ctdb_ltdb_header *)ctdb_data.dptr)->dmaster == get_my_vnn()) { - /* we are the dmaster - avoid the ctdb protocol op */ - - data->dsize = ctdb_data.dsize - sizeof(struct ctdb_ltdb_header); - if (data->dsize == 0) { - SAFE_FREE(ctdb_data.dptr); - data->dptr = NULL; - return 0; - } - - data->dptr = (uint8 *)talloc_memdup( - mem_ctx, ctdb_data.dptr+sizeof(struct ctdb_ltdb_header), - data->dsize); - - SAFE_FREE(ctdb_data.dptr); - - if (data->dptr == NULL) { - return -1; - } - return 0; - } - - SAFE_FREE(ctdb_data.dptr); - - /* we weren't able to get it locally - ask ctdb to fetch it for us */ - status = ctdbd_fetch(db_ctdbd_conn(ctx), ctx->db_id, key, mem_ctx, - data); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(5, ("ctdbd_fetch failed: %s\n", nt_errstr(status))); - return -1; - } - - return 0; -} - -struct traverse_state { - struct db_context *db; - int (*fn)(struct db_record *rec, void *private_data); - void *private_data; -}; - -static void traverse_callback(TDB_DATA key, TDB_DATA data, void *private_data) -{ - struct traverse_state *state = (struct traverse_state *)private_data; - struct db_record *rec; - TALLOC_CTX *tmp_ctx = talloc_new(state->db); - /* we have to give them a locked record to prevent races */ - rec = db_ctdb_fetch_locked(state->db, tmp_ctx, key); - if (rec && rec->value.dsize > 0) { - state->fn(rec, state->private_data); - } - talloc_free(tmp_ctx); -} - -static int db_ctdb_traverse(struct db_context *db, - int (*fn)(struct db_record *rec, - void *private_data), - void *private_data) -{ - struct db_ctdb_ctx *ctx = talloc_get_type_abort(db->private_data, - struct db_ctdb_ctx); - struct traverse_state state; - - state.db = db; - state.fn = fn; - state.private_data = private_data; - - ctdbd_traverse(ctx->db_id, traverse_callback, &state); - return 0; -} - -static NTSTATUS db_ctdb_store_deny(struct db_record *rec, TDB_DATA data, int flag) -{ - return NT_STATUS_MEDIA_WRITE_PROTECTED; -} - -static NTSTATUS db_ctdb_delete_deny(struct db_record *rec) -{ - return NT_STATUS_MEDIA_WRITE_PROTECTED; -} - -static void traverse_read_callback(TDB_DATA key, TDB_DATA data, void *private_data) -{ - struct traverse_state *state = (struct traverse_state *)private_data; - struct db_record rec; - rec.key = key; - rec.value = data; - rec.store = db_ctdb_store_deny; - rec.delete_rec = db_ctdb_delete_deny; - rec.private_data = state->db; - state->fn(&rec, state->private_data); -} - -static int db_ctdb_traverse_read(struct db_context *db, - int (*fn)(struct db_record *rec, - void *private_data), - void *private_data) -{ - struct db_ctdb_ctx *ctx = talloc_get_type_abort(db->private_data, - struct db_ctdb_ctx); - struct traverse_state state; - - state.db = db; - state.fn = fn; - state.private_data = private_data; - - ctdbd_traverse(ctx->db_id, traverse_read_callback, &state); - return 0; -} - -static int db_ctdb_get_seqnum(struct db_context *db) -{ - struct db_ctdb_ctx *ctx = talloc_get_type_abort(db->private_data, - struct db_ctdb_ctx); - return tdb_get_seqnum(ctx->wtdb->tdb); -} - -/* - * Get the ctdbd connection for a database. If possible, re-use the messaging - * ctdbd connection - */ -static struct ctdbd_connection *db_ctdbd_conn(struct db_ctdb_ctx *ctx) -{ - struct ctdbd_connection *result; - - result = messaging_ctdbd_connection(); - - if (result != NULL) { - - if (ctx->conn == NULL) { - /* - * Someone has initialized messaging since we - * initialized our own connection, we don't need it - * anymore. - */ - TALLOC_FREE(ctx->conn); - } - - return result; - } - - if (ctx->conn == NULL) { - ctdbd_init_connection(ctx, &ctx->conn); - set_my_vnn(ctdbd_vnn(ctx->conn)); - } - - return ctx->conn; -} - -struct db_context *db_open_ctdb(TALLOC_CTX *mem_ctx, - const char *name, - int hash_size, int tdb_flags, - int open_flags, mode_t mode) -{ - struct db_context *result; - struct db_ctdb_ctx *db_ctdb; - char *db_path; - NTSTATUS status; - - if (!lp_clustering()) { - DEBUG(10, ("Clustering disabled -- no ctdb\n")); - return NULL; - } - - if (!(result = TALLOC_ZERO_P(mem_ctx, struct db_context))) { - DEBUG(0, ("talloc failed\n")); - TALLOC_FREE(result); - return NULL; - } - - if (!(db_ctdb = TALLOC_P(result, struct db_ctdb_ctx))) { - DEBUG(0, ("talloc failed\n")); - TALLOC_FREE(result); - return NULL; - } - - db_ctdb->conn = NULL; - - status = ctdbd_db_attach(db_ctdbd_conn(db_ctdb), name, - &db_ctdb->db_id, tdb_flags); - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("ctdbd_db_attach failed for %s: %s\n", name, - nt_errstr(status))); - TALLOC_FREE(result); - return NULL; - } - - db_path = ctdbd_dbpath(db_ctdbd_conn(db_ctdb), db_ctdb, - db_ctdb->db_id); - - /* only pass through specific flags */ - tdb_flags &= TDB_SEQNUM; - - db_ctdb->wtdb = tdb_wrap_open(db_ctdb, db_path, hash_size, tdb_flags, O_RDWR, 0); - if (db_ctdb->wtdb == NULL) { - DEBUG(0, ("Could not open tdb %s: %s\n", db_path, strerror(errno))); - TALLOC_FREE(result); - return NULL; - } - talloc_free(db_path); - - result->private_data = (void *)db_ctdb; - result->fetch_locked = db_ctdb_fetch_locked; - result->fetch = db_ctdb_fetch; - result->traverse = db_ctdb_traverse; - result->traverse_read = db_ctdb_traverse_read; - result->get_seqnum = db_ctdb_get_seqnum; - - DEBUG(3,("db_open_ctdb: opened database '%s' with dbid 0x%x\n", - name, db_ctdb->db_id)); - - return result; -} - -#else - -struct db_context *db_open_ctdb(TALLOC_CTX *mem_ctx, - const char *name, - int hash_size, int tdb_flags, - int open_flags, mode_t mode) -{ - DEBUG(0, ("no clustering compiled in\n")); - return NULL; -} - -#endif diff --git a/source/lib/dbwrap_file.c b/source/lib/dbwrap_file.c deleted file mode 100644 index 0ac7586e48b..00000000000 --- a/source/lib/dbwrap_file.c +++ /dev/null @@ -1,414 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Database interface using a file per record - Copyright (C) Volker Lendecke 2005 - - 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. -*/ - -/* - * Be aware that this is just sample code that has not seen too much testing - */ - -#include "includes.h" - -struct db_file_ctx { - const char *dirname; - - /* We only support one locked record at a time -- everything else - * would lead to a potential deadlock anyway! */ - struct db_record *locked_record; -}; - -struct db_locked_file { - int fd; - uint8 hash; - const char *name; - const char *path; - struct db_file_ctx *parent; -}; - -/* Copy from statcache.c... */ - -static uint32 fsh(const uint8 *p, int len) -{ - uint32 n = 0; - int i; - for (i=0; i<len; i++) { - n = ((n << 5) + n) ^ (uint32)(p[i]); - } - return n; -} - -static int db_locked_file_destr(struct db_locked_file *data) -{ - if (data->parent != NULL) { - data->parent->locked_record = NULL; - } - - if (close(data->fd) != 0) { - DEBUG(3, ("close failed: %s\n", strerror(errno))); - return -1; - } - - return 0; -} - -static NTSTATUS db_file_store(struct db_record *rec, TDB_DATA data, int flag); -static NTSTATUS db_file_delete(struct db_record *rec); - -static struct db_record *db_file_fetch_locked(struct db_context *db, - TALLOC_CTX *mem_ctx, - TDB_DATA key) -{ - struct db_file_ctx *ctx = talloc_get_type_abort(db->private_data, - struct db_file_ctx); - struct db_record *result; - struct db_locked_file *file; - struct flock fl; - SMB_STRUCT_STAT statbuf; - ssize_t nread; - int ret; - - SMB_ASSERT(ctx->locked_record == NULL); - - again: - if (!(result = TALLOC_P(mem_ctx, struct db_record))) { - DEBUG(0, ("talloc failed\n")); - return NULL; - } - - if (!(file = TALLOC_P(result, struct db_locked_file))) { - DEBUG(0, ("talloc failed\n")); - TALLOC_FREE(result); - return NULL; - } - - result->private_data = file; - result->store = db_file_store; - result->delete_rec = db_file_delete; - - result->key.dsize = key.dsize; - result->key.dptr = (uint8 *)talloc_memdup(result, key.dptr, key.dsize); - if (result->key.dptr == NULL) { - DEBUG(0, ("talloc failed\n")); - TALLOC_FREE(result); - return NULL; - } - - /* Cut to 8 bits */ - file->hash = fsh(key.dptr, key.dsize); - file->name = hex_encode(file, (unsigned char *)key.dptr, key.dsize); - if (file->name == NULL) { - DEBUG(0, ("hex_encode failed\n")); - TALLOC_FREE(result); - return NULL; - } - - file->path = talloc_asprintf(file, "%s/%2.2X/%s", ctx->dirname, - file->hash, file->name); - if (file->path == NULL) { - DEBUG(0, ("talloc_asprintf failed\n")); - TALLOC_FREE(result); - return NULL; - } - - become_root(); - file->fd = open(file->path, O_RDWR|O_CREAT, 0644); - unbecome_root(); - - if (file->fd < 0) { - DEBUG(3, ("Could not open/create %s: %s\n", - file->path, strerror(errno))); - TALLOC_FREE(result); - return NULL; - } - - talloc_set_destructor(file, db_locked_file_destr); - - fl.l_type = F_WRLCK; - fl.l_whence = SEEK_SET; - fl.l_start = 0; - fl.l_len = 1; - fl.l_pid = 0; - - do { - ret = fcntl(file->fd, F_SETLKW, &fl); - } while ((ret == -1) && (errno == EINTR)); - - if (ret == -1) { - DEBUG(3, ("Could not get lock on %s: %s\n", - file->path, strerror(errno))); - TALLOC_FREE(result); - return NULL; - } - - if (sys_fstat(file->fd, &statbuf) != 0) { - DEBUG(3, ("Could not fstat %s: %s\n", - file->path, strerror(errno))); - TALLOC_FREE(result); - return NULL; - } - - if (statbuf.st_nlink == 0) { - /* Someone has deleted it under the lock, retry */ - TALLOC_FREE(result); - goto again; - } - - result->value.dsize = 0; - result->value.dptr = NULL; - - if (statbuf.st_size != 0) { - result->value.dsize = statbuf.st_size; - result->value.dptr = TALLOC_ARRAY(result, uint8, - statbuf.st_size); - if (result->value.dptr == NULL) { - DEBUG(1, ("talloc failed\n")); - TALLOC_FREE(result); - return NULL; - } - - nread = read_data(file->fd, (char *)result->value.dptr, - result->value.dsize); - if (nread != result->value.dsize) { - DEBUG(3, ("read_data failed: %s\n", strerror(errno))); - TALLOC_FREE(result); - return NULL; - } - } - - ctx->locked_record = result; - file->parent = (struct db_file_ctx *)talloc_reference(file, ctx); - - return result; -} - -static NTSTATUS db_file_store_root(int fd, TDB_DATA data) -{ - if (sys_lseek(fd, 0, SEEK_SET) != 0) { - DEBUG(0, ("sys_lseek failed: %s\n", strerror(errno))); - return map_nt_error_from_unix(errno); - } - - if (write_data(fd, (char *)data.dptr, data.dsize) != data.dsize) { - DEBUG(3, ("write_data failed: %s\n", strerror(errno))); - return map_nt_error_from_unix(errno); - } - - if (sys_ftruncate(fd, data.dsize) != 0) { - DEBUG(3, ("sys_ftruncate failed: %s\n", strerror(errno))); - return map_nt_error_from_unix(errno); - } - - return NT_STATUS_OK; -} - -static NTSTATUS db_file_store(struct db_record *rec, TDB_DATA data, int flag) -{ - struct db_locked_file *file = - talloc_get_type_abort(rec->private_data, - struct db_locked_file); - NTSTATUS status; - - become_root(); - status = db_file_store_root(file->fd, data); - unbecome_root(); - - return status; -} - -static NTSTATUS db_file_delete(struct db_record *rec) -{ - struct db_locked_file *file = - talloc_get_type_abort(rec->private_data, - struct db_locked_file); - int res; - - become_root(); - res = unlink(file->path); - unbecome_root(); - - if (res == -1) { - DEBUG(3, ("unlink(%s) failed: %s\n", file->path, - strerror(errno))); - return map_nt_error_from_unix(errno); - } - - return NT_STATUS_OK; -} - -static int db_file_traverse(struct db_context *db, - int (*fn)(struct db_record *rec, - void *private_data), - void *private_data) -{ - struct db_file_ctx *ctx = talloc_get_type_abort(db->private_data, - struct db_file_ctx); - TALLOC_CTX *mem_ctx = talloc_init("traversal %s\n", ctx->dirname); - - int i; - int count = 0; - - for (i=0; i<256; i++) { - const char *dirname = talloc_asprintf(mem_ctx, "%s/%2.2X", - ctx->dirname, i); - DIR *dir; - struct dirent *dirent; - - if (dirname == NULL) { - DEBUG(0, ("talloc failed\n")); - TALLOC_FREE(mem_ctx); - return -1; - } - - dir = opendir(dirname); - if (dir == NULL) { - DEBUG(3, ("Could not open dir %s: %s\n", dirname, - strerror(errno))); - TALLOC_FREE(mem_ctx); - return -1; - } - - while ((dirent = readdir(dir)) != NULL) { - DATA_BLOB keyblob; - TDB_DATA key; - struct db_record *rec; - - if ((dirent->d_name[0] == '.') && - ((dirent->d_name[1] == '\0') || - ((dirent->d_name[1] == '.') && - (dirent->d_name[2] == '\0')))) { - continue; - } - - keyblob = strhex_to_data_blob(mem_ctx, dirent->d_name); - if (keyblob.data == NULL) { - DEBUG(5, ("strhex_to_data_blob failed\n")); - continue; - } - - key.dptr = keyblob.data; - key.dsize = keyblob.length; - - if ((ctx->locked_record != NULL) && - (key.dsize == ctx->locked_record->key.dsize) && - (memcmp(key.dptr, ctx->locked_record->key.dptr, - key.dsize) == 0)) { - count += 1; - if (fn(ctx->locked_record, - private_data) != 0) { - TALLOC_FREE(mem_ctx); - closedir(dir); - return count; - } - } - - rec = db_file_fetch_locked(db, mem_ctx, key); - if (rec == NULL) { - /* Someone might have deleted it */ - continue; - } - - if (rec->value.dptr == NULL) { - TALLOC_FREE(rec); - continue; - } - - count += 1; - - if (fn(rec, private_data) != 0) { - TALLOC_FREE(mem_ctx); - closedir(dir); - return count; - } - TALLOC_FREE(rec); - } - - closedir(dir); - } - - TALLOC_FREE(mem_ctx); - return count; -} - -struct db_context *db_open_file(TALLOC_CTX *mem_ctx, - struct messaging_context *msg_ctx, - const char *name, - int hash_size, int tdb_flags, - int open_flags, mode_t mode) -{ - struct db_context *result = NULL; - struct db_file_ctx *ctx; - - if (!(result = TALLOC_ZERO_P(mem_ctx, struct db_context))) { - DEBUG(0, ("talloc failed\n")); - return NULL; - } - - if (!(ctx = TALLOC_P(result, struct db_file_ctx))) { - DEBUG(0, ("talloc failed\n")); - TALLOC_FREE(result); - return NULL; - } - - result->private_data = ctx; - result->fetch_locked = db_file_fetch_locked; - result->traverse = db_file_traverse; - result->traverse_read = db_file_traverse; - - ctx->locked_record = NULL; - if (!(ctx->dirname = talloc_strdup(ctx, name))) { - DEBUG(0, ("talloc failed\n")); - TALLOC_FREE(result); - return NULL; - } - - if (open_flags & O_CREAT) { - int ret, i; - - mode |= (mode & S_IRUSR) ? S_IXUSR : 0; - mode |= (mode & S_IRGRP) ? S_IXGRP : 0; - mode |= (mode & S_IROTH) ? S_IXOTH : 0; - - ret = mkdir(name, mode); - if ((ret != 0) && (errno != EEXIST)) { - DEBUG(5, ("mkdir(%s,%o) failed: %s\n", name, mode, - strerror(errno))); - TALLOC_FREE(result); - return NULL; - } - - for (i=0; i<256; i++) { - char *path; - path = talloc_asprintf(result, "%s/%2.2X", name, i); - if (path == NULL) { - DEBUG(0, ("asprintf failed\n")); - TALLOC_FREE(result); - return NULL; - } - ret = mkdir(path, mode); - if ((ret != 0) && (errno != EEXIST)) { - DEBUG(5, ("mkdir(%s,%o) failed: %s\n", path, - mode, strerror(errno))); - TALLOC_FREE(result); - return NULL; - } - TALLOC_FREE(path); - } - } - - return result; -} diff --git a/source/lib/dbwrap_tdb.c b/source/lib/dbwrap_tdb.c deleted file mode 100644 index 8997f9f040c..00000000000 --- a/source/lib/dbwrap_tdb.c +++ /dev/null @@ -1,263 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Database interface wrapper around tdb - Copyright (C) Volker Lendecke 2005-2007 - - 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. -*/ - -#include "includes.h" - -struct db_tdb_ctx { - struct tdb_wrap *wtdb; -}; - -static NTSTATUS db_tdb_store(struct db_record *rec, TDB_DATA data, int flag); -static NTSTATUS db_tdb_delete(struct db_record *rec); - -static int db_tdb_record_destr(struct db_record* data) -{ - struct db_tdb_ctx *ctx = - talloc_get_type_abort(data->private_data, struct db_tdb_ctx); - - DEBUG(10, ("Unlocking key %s\n", - hex_encode(data, (unsigned char *)data->key.dptr, - data->key.dsize))); - - if (tdb_chainunlock(ctx->wtdb->tdb, data->key) != 0) { - DEBUG(0, ("tdb_chainunlock failed\n")); - return -1; - } - return 0; -} - -static struct db_record *db_tdb_fetch_locked(struct db_context *db, - TALLOC_CTX *mem_ctx, TDB_DATA key) -{ - struct db_tdb_ctx *ctx = talloc_get_type_abort(db->private_data, - struct db_tdb_ctx); - struct db_record *result; - TDB_DATA value; - - result = TALLOC_P(mem_ctx, struct db_record); - if (result == NULL) { - DEBUG(0, ("talloc failed\n")); - return NULL; - } - - result->key.dsize = key.dsize; - result->key.dptr = (uint8 *)talloc_memdup(result, key.dptr, key.dsize); - if (result->key.dptr == NULL) { - DEBUG(0, ("talloc failed\n")); - TALLOC_FREE(result); - return NULL; - } - - result->value.dptr = NULL; - result->value.dsize = 0; - result->private_data = talloc_reference(result, ctx); - result->store = db_tdb_store; - result->delete_rec = db_tdb_delete; - - { - char *keystr = hex_encode(NULL, (unsigned char *)key.dptr, - key.dsize); - DEBUG(10, ("Locking key %s\n", keystr)); - TALLOC_FREE(keystr); - } - - if (tdb_chainlock(ctx->wtdb->tdb, key) != 0) { - DEBUG(3, ("tdb_chainlock failed\n")); - TALLOC_FREE(result); - return NULL; - } - - talloc_set_destructor(result, db_tdb_record_destr); - - value = tdb_fetch(ctx->wtdb->tdb, key); - - if (value.dptr == NULL) { - return result; - } - - result->value.dsize = value.dsize; - result->value.dptr = (uint8 *)talloc_memdup(result, value.dptr, - value.dsize); - if (result->value.dptr == NULL) { - DEBUG(3, ("talloc failed\n")); - TALLOC_FREE(result); - return NULL; - } - - SAFE_FREE(value.dptr); - - DEBUG(10, ("Allocated locked data 0x%p\n", result)); - - return result; -} - -static NTSTATUS db_tdb_store(struct db_record *rec, TDB_DATA data, int flag) -{ - struct db_tdb_ctx *ctx = talloc_get_type_abort(rec->private_data, - struct db_tdb_ctx); - - /* - * This has a bug: We need to replace rec->value for correct - * operation, but right now brlock and locking don't use the value - * anymore after it was stored. - */ - - return (tdb_store(ctx->wtdb->tdb, rec->key, data, flag) == 0) ? - NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; -} - -static NTSTATUS db_tdb_delete(struct db_record *rec) -{ - struct db_tdb_ctx *ctx = talloc_get_type_abort(rec->private_data, - struct db_tdb_ctx); - int res; - - res = tdb_delete(ctx->wtdb->tdb, rec->key); - - if (res == 0) { - return NT_STATUS_OK; - } - - return map_nt_error_from_tdb(tdb_error(ctx->wtdb->tdb)); -} - -struct db_tdb_traverse_ctx { - struct db_context *db; - int (*f)(struct db_record *rec, void *private_data); - void *private_data; -}; - -static int db_tdb_traverse_func(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, - void *private_data) -{ - struct db_tdb_traverse_ctx *ctx = - (struct db_tdb_traverse_ctx *)private_data; - struct db_record rec; - - rec.key = kbuf; - rec.value = dbuf; - rec.store = db_tdb_store; - rec.delete_rec = db_tdb_delete; - rec.private_data = ctx->db->private_data; - - return ctx->f(&rec, ctx->private_data); -} - -static int db_tdb_traverse(struct db_context *db, - int (*f)(struct db_record *rec, void *private_data), - void *private_data) -{ - struct db_tdb_ctx *db_ctx = - talloc_get_type_abort(db->private_data, struct db_tdb_ctx); - struct db_tdb_traverse_ctx ctx; - - ctx.db = db; - ctx.f = f; - ctx.private_data = private_data; - return tdb_traverse(db_ctx->wtdb->tdb, db_tdb_traverse_func, &ctx); -} - -static NTSTATUS db_tdb_store_deny(struct db_record *rec, TDB_DATA data, int flag) -{ - return NT_STATUS_MEDIA_WRITE_PROTECTED; -} - -static NTSTATUS db_tdb_delete_deny(struct db_record *rec) -{ - return NT_STATUS_MEDIA_WRITE_PROTECTED; -} - -static int db_tdb_traverse_read_func(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, - void *private_data) -{ - struct db_tdb_traverse_ctx *ctx = - (struct db_tdb_traverse_ctx *)private_data; - struct db_record rec; - - rec.key = kbuf; - rec.value = dbuf; - rec.store = db_tdb_store_deny; - rec.delete_rec = db_tdb_delete_deny; - rec.private_data = ctx->db->private_data; - - return ctx->f(&rec, ctx->private_data); -} - -static int db_tdb_traverse_read(struct db_context *db, - int (*f)(struct db_record *rec, void *private_data), - void *private_data) -{ - struct db_tdb_ctx *db_ctx = - talloc_get_type_abort(db->private_data, struct db_tdb_ctx); - struct db_tdb_traverse_ctx ctx; - - ctx.db = db; - ctx.f = f; - ctx.private_data = private_data; - return tdb_traverse_read(db_ctx->wtdb->tdb, db_tdb_traverse_read_func, &ctx); -} - -static int db_tdb_get_seqnum(struct db_context *db) - -{ - struct db_tdb_ctx *db_ctx = - talloc_get_type_abort(db->private_data, struct db_tdb_ctx); - return tdb_get_seqnum(db_ctx->wtdb->tdb); -} - -struct db_context *db_open_tdb(TALLOC_CTX *mem_ctx, - const char *name, - int hash_size, int tdb_flags, - int open_flags, mode_t mode) -{ - struct db_context *result = NULL; - struct db_tdb_ctx *db_tdb; - - result = TALLOC_ZERO_P(mem_ctx, struct db_context); - if (result == NULL) { - DEBUG(0, ("talloc failed\n")); - goto fail; - } - - result->private_data = db_tdb = TALLOC_P(result, struct db_tdb_ctx); - if (db_tdb == NULL) { - DEBUG(0, ("talloc failed\n")); - goto fail; - } - - db_tdb->wtdb = tdb_wrap_open(db_tdb, name, hash_size, tdb_flags, - open_flags, mode); - if (db_tdb->wtdb == NULL) { - DEBUG(3, ("Could not open tdb: %s\n", strerror(errno))); - goto fail; - } - - result->fetch_locked = db_tdb_fetch_locked; - result->traverse = db_tdb_traverse; - result->traverse_read = db_tdb_traverse_read; - result->get_seqnum = db_tdb_get_seqnum; - return result; - - fail: - if (result != NULL) { - TALLOC_FREE(result); - } - return NULL; -} diff --git a/source/lib/debug.c b/source/lib/debug.c index 4bbbf88d0d2..62fda5741c9 100644 --- a/source/lib/debug.c +++ b/source/lib/debug.c @@ -471,16 +471,13 @@ BOOL debug_parse_levels(const char *params_str) Receive a "set debug level" message. ****************************************************************************/ -static void debug_message(struct messaging_context *msg_ctx, - void *private_data, - uint32_t msg_type, - struct server_id src, - DATA_BLOB *data) +static void debug_message(int msg_type, struct process_id src, + void *buf, size_t len, void *private_data) { - const char *params_str = (const char *)data->data; + const char *params_str = (const char *)buf; /* Check, it's a proper string! */ - if (params_str[(data->length)-1] != '\0') { + if (params_str[len-1] != '\0') { DEBUG(1, ("Invalid debug message from pid %u to pid %u\n", (unsigned int)procid_to_pid(&src), (unsigned int)getpid())); @@ -495,14 +492,24 @@ static void debug_message(struct messaging_context *msg_ctx, } /**************************************************************************** + Send a "set debug level" message. +****************************************************************************/ + +void debug_message_send(pid_t pid, const char *params_str) +{ + if (!params_str) + return; + message_send_pid(pid_to_procid(pid), MSG_DEBUG, + params_str, strlen(params_str) + 1, + False); +} + +/**************************************************************************** Return current debug level. ****************************************************************************/ -static void debuglevel_message(struct messaging_context *msg_ctx, - void *private_data, - uint32_t msg_type, - struct server_id src, - DATA_BLOB *data) +static void debuglevel_message(int msg_type, struct process_id src, + void *buf, size_t len, void *private_data) { char *message = debug_list_class_names_and_levels(); @@ -511,10 +518,9 @@ static void debuglevel_message(struct messaging_context *msg_ctx, return; } - DEBUG(1,("INFO: Received REQ_DEBUGLEVEL message from PID %s\n", - procid_str_static(&src))); - messaging_send_buf(msg_ctx, src, MSG_DEBUGLEVEL, - (uint8 *)message, strlen(message) + 1); + DEBUG(1,("INFO: Received REQ_DEBUGLEVEL message from PID %u\n", + (unsigned int)procid_to_pid(&src))); + message_send_pid(src, MSG_DEBUGLEVEL, message, strlen(message) + 1, True); SAFE_FREE(message); } @@ -533,18 +539,14 @@ void debug_init(void) initialised = True; + message_register(MSG_DEBUG, debug_message, NULL); + message_register(MSG_REQ_DEBUGLEVEL, debuglevel_message, NULL); + for(p = default_classname_table; *p; p++) { debug_add_class(*p); } } -void debug_register_msgs(struct messaging_context *msg_ctx) -{ - messaging_register(msg_ctx, NULL, MSG_DEBUG, debug_message); - messaging_register(msg_ctx, NULL, MSG_REQ_DEBUGLEVEL, - debuglevel_message); -} - /*************************************************************************** Get ready for syslog stuff **************************************************************************/ @@ -979,7 +981,7 @@ BOOL dbghdr( int level, const char *file, const char *func, int line ) /* Print it all out at once to prevent split syslog output. */ if( lp_debug_prefix_timestamp() ) { - (void)Debug1( "[%s, %2d%s] ", + (void)Debug1( "[%s, %d%s] ", current_timestring(lp_debug_hires_timestamp()), level, header_str); } else { diff --git a/source/lib/dmallocmsg.c b/source/lib/dmallocmsg.c index 7e52e93a103..fed7bf59c52 100644 --- a/source/lib/dmallocmsg.c +++ b/source/lib/dmallocmsg.c @@ -35,11 +35,10 @@ static unsigned long our_dm_mark = 0; * Respond to a POOL_USAGE message by sending back string form of memory * usage stats. **/ -static void msg_req_dmalloc_mark(struct messaging_context *msg, - void *private_data, - uint32_t msg_type, - struct server_id server_id, - DATA_BLOB *data) +static void msg_req_dmalloc_mark(int UNUSED(msg_type), + struct process_id UNUSED(src_pid), + void *UNUSED(buf), size_t UNUSED(len), + void *private_data) { #ifdef ENABLE_DMALLOC our_dm_mark = dmalloc_mark(); @@ -51,11 +50,10 @@ static void msg_req_dmalloc_mark(struct messaging_context *msg, -static void msg_req_dmalloc_log_changed(struct messaging_context *msg, - void *private_data, - uint32_t msg_type, - struct server_id server_id, - DATA_BLOB *data) +static void msg_req_dmalloc_log_changed(int UNUSED(msg_type), + struct process_id UNUSED(src_pid), + void *UNUSED(buf), size_t UNUSED(len), + void *private_data) { #ifdef ENABLE_DMALLOC dmalloc_log_changed(our_dm_mark, True, True, True); @@ -69,11 +67,10 @@ static void msg_req_dmalloc_log_changed(struct messaging_context *msg, /** * Register handler for MSG_REQ_POOL_USAGE **/ -void register_dmalloc_msgs(struct messaging_context *msg_ctx) +void register_dmalloc_msgs(void) { - messaging_register(msg_ctx, NULL, MSG_REQ_DMALLOC_MARK, - msg_req_dmalloc_mark); - messaging_register(msg_ctx, NULL, MSG_REQ_DMALLOC_LOG_CHANGED, - msg_req_dmalloc_log_changed); + message_register(MSG_REQ_DMALLOC_MARK, msg_req_dmalloc_mark, NULL); + message_register(MSG_REQ_DMALLOC_LOG_CHANGED, + msg_req_dmalloc_log_changed, NULL); DEBUG(2, ("Registered MSG_REQ_DMALLOC_MARK and LOG_CHANGED\n")); } diff --git a/source/lib/dummysmbd.c b/source/lib/dummysmbd.c index ed64d9b7834..a291a5884d9 100644 --- a/source/lib/dummysmbd.c +++ b/source/lib/dummysmbd.c @@ -48,23 +48,3 @@ NTSTATUS can_delete_directory(struct connection_struct *conn, return NT_STATUS_OK; } -NTSTATUS srv_decrypt_buffer(char *buf) -{ - return NT_STATUS_OK; -} - -NTSTATUS srv_encrypt_buffer(char *buffer, char **buf_out) -{ - *buf_out = buffer; - return NT_STATUS_OK; -} - -void srv_free_enc_buffer(char *buf) -{ - ; -} - -BOOL srv_encryption_on(void) -{ - return False; -} diff --git a/source/lib/errmap_unix.c b/source/lib/errmap_unix.c deleted file mode 100644 index 8ec0e5facac..00000000000 --- a/source/lib/errmap_unix.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * map unix to NT errors, an excerpt of libsmb/errormap.c - * Copyright (C) Andrew Tridgell 2001 - * Copyright (C) Andrew Bartlett 2001 - * Copyright (C) Tim Potter 2000 - * Copyright (C) Jeremy Allison 2007 - * - * 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. - */ - -#include "includes.h" - -/* Mapping from Unix, to NT error numbers */ - -const struct unix_error_map unix_dos_nt_errmap[] = { - { EPERM, ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED }, - { EACCES, ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED }, - { ENOENT, ERRDOS, ERRbadfile, NT_STATUS_OBJECT_NAME_NOT_FOUND }, - { ENOTDIR, ERRDOS, ERRbadpath, NT_STATUS_NOT_A_DIRECTORY }, - { EIO, ERRHRD, ERRgeneral, NT_STATUS_IO_DEVICE_ERROR }, - { EBADF, ERRSRV, ERRsrverror, NT_STATUS_INVALID_HANDLE }, - { EINVAL, ERRSRV, ERRsrverror, NT_STATUS_INVALID_HANDLE }, - { EEXIST, ERRDOS, ERRfilexists, NT_STATUS_OBJECT_NAME_COLLISION}, - { ENFILE, ERRDOS, ERRnofids, NT_STATUS_TOO_MANY_OPENED_FILES }, - { EMFILE, ERRDOS, ERRnofids, NT_STATUS_TOO_MANY_OPENED_FILES }, - { ENOSPC, ERRHRD, ERRdiskfull, NT_STATUS_DISK_FULL }, - { ENOMEM, ERRDOS, ERRnomem, NT_STATUS_NO_MEMORY }, - { EISDIR, ERRDOS, ERRnoaccess, NT_STATUS_FILE_IS_A_DIRECTORY}, - { EMLINK, ERRDOS, ERRgeneral, NT_STATUS_TOO_MANY_LINKS }, - { EINTR, ERRHRD, ERRgeneral, NT_STATUS_RETRY }, -#ifdef EDQUOT - { EDQUOT, ERRHRD, ERRdiskfull, NT_STATUS_DISK_FULL }, /* Windows apps need this, not NT_STATUS_QUOTA_EXCEEDED */ -#endif -#ifdef ENOTEMPTY - { ENOTEMPTY, ERRDOS, ERRnoaccess, NT_STATUS_DIRECTORY_NOT_EMPTY }, -#endif -#ifdef EXDEV - { EXDEV, ERRDOS, ERRdiffdevice, NT_STATUS_NOT_SAME_DEVICE }, -#endif -#ifdef EROFS - { EROFS, ERRHRD, ERRnowrite, NT_STATUS_ACCESS_DENIED }, -#endif -#ifdef ENAMETOOLONG - { ENAMETOOLONG, ERRDOS, 206, NT_STATUS_OBJECT_NAME_INVALID }, -#endif -#ifdef EFBIG - { EFBIG, ERRHRD, ERRdiskfull, NT_STATUS_DISK_FULL }, -#endif -#ifdef ENOBUFS - { ENOBUFS, ERRDOS, ERRnomem, NT_STATUS_INSUFFICIENT_RESOURCES }, -#endif - { EAGAIN, ERRDOS, 111, NT_STATUS_NETWORK_BUSY }, -#ifdef EADDRINUSE - { EADDRINUSE, ERRDOS, 52, NT_STATUS_ADDRESS_ALREADY_ASSOCIATED}, -#endif -#ifdef ENETUNREACH - { ENETUNREACH, ERRHRD, ERRgeneral, NT_STATUS_NETWORK_UNREACHABLE}, -#endif -#ifdef EHOSTUNREACH - { EHOSTUNREACH, ERRHRD, ERRgeneral, NT_STATUS_HOST_UNREACHABLE}, -#endif -#ifdef ECONNREFUSED - { ECONNREFUSED, ERRHRD, ERRgeneral, NT_STATUS_CONNECTION_REFUSED}, -#endif -#ifdef ETIMEDOUT - { ETIMEDOUT, ERRHRD, 121, NT_STATUS_IO_TIMEOUT}, -#endif -#ifdef ECONNABORTED - { ECONNABORTED, ERRHRD, ERRgeneral, NT_STATUS_CONNECTION_ABORTED}, -#endif -#ifdef ENODEV - { ENODEV, ERRDOS, 55, NT_STATUS_DEVICE_DOES_NOT_EXIST}, -#endif -#ifdef EPIPE - { EPIPE, ERRDOS, 109, NT_STATUS_PIPE_BROKEN}, -#endif -#ifdef EWOULDBLOCK - { EWOULDBLOCK, ERRDOS, 111, NT_STATUS_NETWORK_BUSY }, -#endif - - { 0, 0, 0, NT_STATUS_OK } -}; - -/********************************************************************* - Map an NT error code from a Unix error code. -*********************************************************************/ - -NTSTATUS map_nt_error_from_unix(int unix_error) -{ - int i = 0; - - if (unix_error == 0) - return NT_STATUS_OK; - - /* Look through list */ - while(unix_dos_nt_errmap[i].unix_error != 0) { - if (unix_dos_nt_errmap[i].unix_error == unix_error) - return unix_dos_nt_errmap[i].nt_error; - i++; - } - - /* Default return */ - return NT_STATUS_ACCESS_DENIED; -} diff --git a/source/lib/events.c b/source/lib/events.c index 314fa2d5386..a00db77b6be 100644 --- a/source/lib/events.c +++ b/source/lib/events.c @@ -185,27 +185,20 @@ void event_fd_set_not_readable(struct fd_event *fde) fde->flags &= ~EVENT_FD_READ; } -/* - * Return if there's something in the queue - */ - -BOOL event_add_to_select_args(struct event_context *event_ctx, +void event_add_to_select_args(struct event_context *event_ctx, const struct timeval *now, fd_set *read_fds, fd_set *write_fds, struct timeval *timeout, int *maxfd) { struct fd_event *fde; struct timeval diff; - BOOL ret = False; for (fde = event_ctx->fd_events; fde; fde = fde->next) { if (fde->flags & EVENT_FD_READ) { FD_SET(fde->fd, read_fds); - ret = True; } if (fde->flags & EVENT_FD_WRITE) { FD_SET(fde->fd, write_fds); - ret = True; } if ((fde->flags & (EVENT_FD_READ|EVENT_FD_WRITE)) @@ -215,28 +208,11 @@ BOOL event_add_to_select_args(struct event_context *event_ctx, } if (event_ctx->timed_events == NULL) { - return ret; + return; } diff = timeval_until(now, &event_ctx->timed_events->when); *timeout = timeval_min(timeout, &diff); - - return True; -} - -BOOL events_pending(struct event_context *event_ctx) -{ - struct fd_event *fde; - - if (event_ctx->timed_events != NULL) { - return True; - } - for (fde = event_ctx->fd_events; fde; fde = fde->next) { - if (fde->flags & (EVENT_FD_READ|EVENT_FD_WRITE)) { - return True; - } - } - return False; } BOOL run_events(struct event_context *event_ctx, @@ -321,40 +297,6 @@ struct timeval *get_timed_events_timeout(struct event_context *event_ctx, return to_ret; } -int event_loop_once(struct event_context *ev) -{ - struct timeval now, to; - fd_set r_fds, w_fds; - int maxfd = 0; - int ret; - - FD_ZERO(&r_fds); - FD_ZERO(&w_fds); - - to.tv_sec = 9999; /* Max timeout */ - to.tv_usec = 0; - - GetTimeOfDay(&now); - - if (!event_add_to_select_args(ev, &now, &r_fds, &w_fds, &to, &maxfd)) { - return -1; - } - - if (timeval_is_zero(&to)) { - run_events(ev, 0, NULL, NULL); - return 0; - } - - ret = sys_select(maxfd, &r_fds, &w_fds, NULL, &to); - - if (ret == -1 && errno != EINTR) { - return -1; - } - - run_events(ev, ret, &r_fds, &w_fds); - return 0; -} - struct event_context *event_context_init(TALLOC_CTX *mem_ctx) { return TALLOC_ZERO_P(NULL, struct event_context); @@ -391,36 +333,3 @@ int cancel_named_event(struct event_context *event_ctx, } return 0; } - -void dump_event_list(struct event_context *event_ctx) -{ - struct timed_event *te; - struct fd_event *fe; - struct timeval evt, now; - - if (!event_ctx) { - return; - } - - now = timeval_current(); - - DEBUG(10,("dump_event_list:\n")); - - for (te = event_ctx->timed_events; te; te = te->next) { - - evt = timeval_until(&now, &te->when); - - DEBUGADD(10,("Timed Event \"%s\" %lx handled in %d seconds\n", - te->event_name, - (unsigned long)te, - (int)evt.tv_sec)); - } - - for (fe = event_ctx->fd_events; fe; fe = fe->next) { - - DEBUGADD(10,("FD Event %d %lx, flags: 0x%04x\n", - fe->fd, - (unsigned long)fe, - fe->flags)); - } -} diff --git a/source/lib/file_id.c b/source/lib/file_id.c deleted file mode 100644 index 18d3397bedc..00000000000 --- a/source/lib/file_id.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - file_id structure handling - - Copyright (C) Andrew Tridgell 2007 - - 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. -*/ - -#include "includes.h" - -/* - return a file_id which gives a unique ID for a file given the device and - inode numbers - */ -struct file_id file_id_create(SMB_DEV_T dev, SMB_INO_T inode) -{ - struct file_id key; - /* the ZERO_STRUCT ensures padding doesn't break using the key as a - * blob */ - ZERO_STRUCT(key); - key.devid = dev; - key.inode = inode; - return key; -} - -/* - generate a file_id from a stat structure - */ -struct file_id file_id_sbuf(const SMB_STRUCT_STAT *sbuf) -{ - return file_id_create(sbuf->st_dev, sbuf->st_ino); -} - - -/* - return True if two file_id structures are equal - */ -BOOL file_id_equal(const struct file_id *id1, const struct file_id *id2) -{ - return id1->inode == id2->inode && id1->devid == id2->devid; -} - -/* - a static string for a file_id structure - */ -const char *file_id_static_string(const struct file_id *id) -{ - static char buf[32]; - snprintf(buf, sizeof(buf), "%llx:%llx", - (unsigned long long)id->devid, - (unsigned long long)id->inode); - return buf; -} - -/* - a 2nd static string for a file_id structure so we can print 2 at once - */ -const char *file_id_static_string2(const struct file_id *id) -{ - static char buf[32]; - snprintf(buf, sizeof(buf), "%llx:%llx", - (unsigned long long)id->devid, - (unsigned long long)id->inode); - return buf; -} - -/* - push a 16 byte version of a file id into a buffer - */ -void push_file_id_16(char *buf, const struct file_id *id) -{ - SIVAL(buf, 0, id->devid&0xFFFFFFFF); - SIVAL(buf, 4, id->devid>>32); - SIVAL(buf, 8, id->inode&0xFFFFFFFF); - SIVAL(buf, 12, id->inode>>32); -} - -/* - pul a 16 byte version of a file id from a buffer - */ -void pull_file_id_16(char *buf, struct file_id *id) -{ - ZERO_STRUCTP(id); - id->devid = IVAL(buf, 0); - id->devid |= ((uint64_t)IVAL(buf,4))<<32; - id->inode = IVAL(buf, 8); - id->inode |= ((uint64_t)IVAL(buf,12))<<32; -} diff --git a/source/lib/gencache.c b/source/lib/gencache.c index af60ee1ff47..c58642553c0 100644 --- a/source/lib/gencache.c +++ b/source/lib/gencache.c @@ -114,7 +114,7 @@ BOOL gencache_shutdown(void) BOOL gencache_set(const char *keystr, const char *value, time_t timeout) { int ret; - TDB_DATA databuf; + TDB_DATA keybuf, databuf; char* valstr = NULL; /* fail completely if get null pointers passed */ @@ -130,13 +130,16 @@ BOOL gencache_set(const char *keystr, const char *value, time_t timeout) if (!valstr) return False; - databuf = string_term_tdb_data(valstr); + keybuf.dptr = CONST_DISCARD(char *, keystr); + keybuf.dsize = strlen(keystr)+1; + databuf.dptr = valstr; + databuf.dsize = strlen(valstr)+1; DEBUG(10, ("Adding cache entry with key = %s; value = %s and timeout =" - " %s (%d seconds %s)\n", keystr, value,ctime(&timeout), + " %s (%d seconds %s)\n", keybuf.dptr, value,ctime(&timeout), (int)(timeout - time(NULL)), timeout > time(NULL) ? "ahead" : "in the past")); - ret = tdb_store_bystring(cache, keystr, databuf, 0); + ret = tdb_store(cache, keybuf, databuf, 0); SAFE_FREE(valstr); return ret == 0; @@ -154,6 +157,7 @@ BOOL gencache_set(const char *keystr, const char *value, time_t timeout) BOOL gencache_del(const char *keystr) { int ret; + TDB_DATA keybuf; /* fail completely if get null pointers passed */ SMB_ASSERT(keystr); @@ -164,8 +168,10 @@ BOOL gencache_del(const char *keystr) return False; } + keybuf.dptr = CONST_DISCARD(char *, keystr); + keybuf.dsize = strlen(keystr)+1; DEBUG(10, ("Deleting cache entry (key = %s)\n", keystr)); - ret = tdb_delete_bystring(cache, keystr); + ret = tdb_delete(cache, keybuf); return ret == 0; } @@ -186,7 +192,7 @@ BOOL gencache_del(const char *keystr) BOOL gencache_get(const char *keystr, char **valstr, time_t *timeout) { - TDB_DATA databuf; + TDB_DATA keybuf, databuf; time_t t; char *endptr; @@ -196,8 +202,10 @@ BOOL gencache_get(const char *keystr, char **valstr, time_t *timeout) if (!gencache_init()) { return False; } - - databuf = tdb_fetch_bystring(cache, keystr); + + keybuf.dptr = CONST_DISCARD(char *, keystr); + keybuf.dsize = strlen(keystr)+1; + databuf = tdb_fetch(cache, keybuf); if (databuf.dptr == NULL) { DEBUG(10, ("Cache entry with key = %s couldn't be found\n", @@ -205,7 +213,7 @@ BOOL gencache_get(const char *keystr, char **valstr, time_t *timeout) return False; } - t = strtol((const char *)databuf.dptr, &endptr, 10); + t = strtol(databuf.dptr, &endptr, 10); if ((endptr == NULL) || (*endptr != '/')) { DEBUG(2, ("Invalid gencache data format: %s\n", databuf.dptr)); @@ -220,7 +228,7 @@ BOOL gencache_get(const char *keystr, char **valstr, time_t *timeout) if (t <= time(NULL)) { /* We're expired, delete the entry */ - tdb_delete_bystring(cache, keystr); + tdb_delete(cache, keybuf); SAFE_FREE(databuf.dptr); return False; @@ -279,7 +287,7 @@ void gencache_iterate(void (*fn)(const char* key, const char *value, time_t time char *fmt; /* ensure null termination of the key string */ - keystr = SMB_STRNDUP((const char *)node->node_key.dptr, node->node_key.dsize); + keystr = SMB_STRNDUP(node->node_key.dptr, node->node_key.dsize); if (!keystr) { break; } @@ -295,7 +303,7 @@ void gencache_iterate(void (*fn)(const char* key, const char *value, time_t time node = node->next; continue; } - entry = SMB_STRNDUP((const char *)databuf.dptr, databuf.dsize); + entry = SMB_STRNDUP(databuf.dptr, databuf.dsize); if (!entry) { SAFE_FREE(databuf.dptr); SAFE_FREE(keystr); diff --git a/source/lib/launchd.c b/source/lib/launchd.c deleted file mode 100644 index 2c3f7cac89f..00000000000 --- a/source/lib/launchd.c +++ /dev/null @@ -1,242 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Launchd integration wrapper API - - Copyright (C) 2007 James Peach - - 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. -*/ - -#include "includes.h" -#include "smb_launchd.h" - -/* launchd source code and documentation is available here: - * http://launchd.macosforge.org/ - */ - -#if defined(WITH_LAUNCHD_SUPPORT) - -#include <launch.h> -#include <stdarg.h> - -typedef void (*launchd_iterator)(launch_data_t, const char*, void*); - -#define LAUNCHD_TRACE_LEVEL 10 - - void smb_launchd_checkout(struct smb_launch_info *linfo) -{ - talloc_free(linfo->socket_list); -} - -static void pull_launch_sockets(launch_data_t key, - const char *name, - struct smb_launch_info *linfo) -{ - launch_data_type_t type; - - type = launch_data_get_type(key); - DEBUG(LAUNCHD_TRACE_LEVEL, - ("Searching item name='%s' type=%d for sockets\n", - name ? name : "", (int)type)); - - switch (type) { - case LAUNCH_DATA_FD: - if (!linfo->socket_list) { - /* We are counting the number of sockets. */ - linfo->num_sockets++; - } else { - /* We are collecting the socket fds. */ - int fd = launch_data_get_fd(key); - - linfo->socket_list[linfo->num_sockets] = fd; - linfo->num_sockets++; - DEBUG(LAUNCHD_TRACE_LEVEL, - ("Added fd=%d to launchd set\n", fd)); - } - return; - case LAUNCH_DATA_ARRAY: - { - int i; - launch_data_t item; - - for (i = 0; i < launch_data_array_get_count(key); ++i) { - item = launch_data_array_get_index(key, i); - pull_launch_sockets(item, name, linfo); - } - return; - } - case LAUNCH_DATA_DICTIONARY: - launch_data_dict_iterate(key, - (launchd_iterator)pull_launch_sockets, linfo); - return; - default: - return; - } -} - - BOOL smb_launchd_checkin_names(struct smb_launch_info *linfo, ...) -{ - launch_data_t msg; - launch_data_t resp; - launch_data_t item; - BOOL is_launchd = False; - - ZERO_STRUCTP(linfo); - - msg = launch_data_new_string(LAUNCH_KEY_CHECKIN); - resp = launch_msg(msg); - if (resp == NULL) { - /* IPC to launchd failed. */ - launch_data_free(msg); - return is_launchd; - } - - if (launch_data_get_type(resp) == LAUNCH_DATA_ERRNO) { - errno = launch_data_get_errno(resp); - goto done; - } - - /* At this point, we know we are running under launchd. */ - linfo->idle_timeout_secs = 600; - is_launchd = True; - - if ((item = launch_data_dict_lookup(resp, LAUNCH_JOBKEY_TIMEOUT))) { - linfo->idle_timeout_secs = launch_data_get_integer(item); - } - - if ((item = launch_data_dict_lookup(resp, LAUNCH_JOBKEY_SOCKETS))) { - int count = 0; - const char * sockname = NULL; - launch_data_t sockdata; - va_list args; - - /* Figure out the maximum number of sockets. */ - va_start(args, linfo); - while ((sockname = va_arg(args, const char *))) { - ++count; - } - va_end(args); - - DEBUG(LAUNCHD_TRACE_LEVEL, ("Found %d launchd sockets\n", - linfo->num_sockets)); - - if (launch_data_dict_get_count(item) < count) { - DEBUG(0, ("%d launchd sockets requested, " - "but only %d are available\n", - count, launch_data_dict_get_count(item))); - } - - linfo->socket_list = TALLOC_ARRAY(NULL, int, count); - if (linfo->socket_list == NULL) { - goto done; - } - - linfo->num_sockets = 0; - va_start(args, linfo); - while ((sockname = va_arg(args, const char *))) { - sockdata = launch_data_dict_lookup(item, sockname); - - pull_launch_sockets(sockdata, sockname, linfo); - DEBUG(LAUNCHD_TRACE_LEVEL, - ("Added launchd socket \"%s\"\n", sockname)); - } - - SMB_ASSERT(count >= linfo->num_sockets); - } - -done: - launch_data_free(msg); - launch_data_free(resp); - return is_launchd; -} - - BOOL smb_launchd_checkin(struct smb_launch_info *linfo) -{ - launch_data_t msg; - launch_data_t resp; - launch_data_t item; - BOOL is_launchd = False; - - ZERO_STRUCTP(linfo); - - msg = launch_data_new_string(LAUNCH_KEY_CHECKIN); - resp = launch_msg(msg); - if (resp == NULL) { - /* IPC to launchd failed. */ - launch_data_free(msg); - return is_launchd; - } - - if (launch_data_get_type(resp) == LAUNCH_DATA_ERRNO) { - errno = launch_data_get_errno(resp); - goto done; - } - - /* At this point, we know we are running under launchd. */ - linfo->idle_timeout_secs = 600; - is_launchd = True; - - if ((item = launch_data_dict_lookup(resp, LAUNCH_JOBKEY_TIMEOUT))) { - linfo->idle_timeout_secs = launch_data_get_integer(item); - } - - if ((item = launch_data_dict_lookup(resp, LAUNCH_JOBKEY_SOCKETS))) { - int count; - - pull_launch_sockets(item, NULL, linfo); - DEBUG(LAUNCHD_TRACE_LEVEL, ("Found %d launchd sockets\n", - linfo->num_sockets)); - - count = linfo->num_sockets; - linfo->socket_list = TALLOC_ARRAY(NULL, int, count); - if (linfo->socket_list == NULL) { - goto done; - } - - linfo->num_sockets = 0; - pull_launch_sockets(item, NULL, linfo); - - DEBUG(LAUNCHD_TRACE_LEVEL, ("Added %d launchd sockets\n", - linfo->num_sockets)); - - SMB_ASSERT(count == linfo->num_sockets); - } - -done: - launch_data_free(msg); - launch_data_free(resp); - return is_launchd; -} - -#else /* defined(WITH_LAUNCHD_SUPPORT) */ - - BOOL smb_launchd_checkin(struct smb_launch_info * UNUSED(linfo)) -{ - ZERO_STRUCTP(linfo); - return False; -} - - BOOL smb_launchd_checkin_names(struct smb_launch_info * UNUSED(linfo), ...) -{ - ZERO_STRUCTP(linfo); - return False; -} - - void smb_launchd_checkout(struct smb_launch_info * UNUSED(linfo)) -{ -} - -#endif /* defined(WITH_LAUNCHD_SUPPORT) */ - diff --git a/source/lib/ldb/Doxyfile b/source/lib/ldb/Doxyfile deleted file mode 100644 index 07b12b516a8..00000000000 --- a/source/lib/ldb/Doxyfile +++ /dev/null @@ -1,26 +0,0 @@ -PROJECT_NAME = LDB -OUTPUT_DIRECTORY = apidocs -REPEAT_BRIEF = YES -OPTIMIZE_OUTPUT_FOR_C = YES -SORT_MEMBER_DOCS = YES -SORT_BRIEF_DOCS = NO -GENERATE_TODOLIST = YES -GENERATE_BUGLIST = YES -GENERATE_DEPRECATEDLIST= YES -SHOW_USED_FILES = NO -SHOW_DIRECTORIES = NO -WARNINGS = YES -WARN_IF_UNDOCUMENTED = YES -WARN_IF_DOC_ERROR = YES -WARN_NO_PARAMDOC = NO -WARN_FORMAT = "$file:$line: $text" -INPUT = include . -FILE_PATTERNS = *.h *.dox -EXCLUDE = include/config.h include/dlinklist.h \ - include/includes.h -EXAMPLE_PATH = examples -GENERATE_HTML = YES -HTML_OUTPUT = html -GENERATE_MAN = YES -ALWAYS_DETAILED_SEC = YES -JAVADOC_AUTOBRIEF = YES diff --git a/source/lib/ldb/Makefile.in b/source/lib/ldb/Makefile.in deleted file mode 100644 index a091b4832eb..00000000000 --- a/source/lib/ldb/Makefile.in +++ /dev/null @@ -1,173 +0,0 @@ -#!gmake -# -CC = @CC@ -GCOV = @GCOV@ -XSLTPROC = @XSLTPROC@ -DOXYGEN = @DOXYGEN@ -prefix = @prefix@ -exec_prefix = @exec_prefix@ -datarootdir = @datarootdir@ -includedir = @includedir@ -libdir = @libdir@ -bindir = @bindir@ -mandir = @mandir@ -VPATH = @srcdir@:@tdbdir@:@tallocdir@:@libreplacedir@:@poptdir@ -srcdir = @srcdir@ -builddir = @builddir@ -SLAPD = @SLAPD@ -EXTRA_OBJ=@EXTRA_OBJ@ -TESTS=test-tdb.sh @TESTS@ - -CFLAGS=-g -I$(srcdir)/include -Iinclude -I$(srcdir) -I$(srcdir)/.. \ - @POPT_CFLAGS@ -I@tallocdir@ -I@tdbdir@/include -I@libreplacedir@ \ - -DLIBDIR=\"$(libdir)\" -DSHLIBEXT=\"@SHLIBEXT@\" -DUSE_MMAP=1 @CFLAGS@ - -LIB_FLAGS=@LDFLAGS@ -Llib -lldb @LIBS@ @POPT_LIBS@ - -LDB_TDB_DIR=ldb_tdb -LDB_TDB_OBJ=$(LDB_TDB_DIR)/ldb_tdb.o \ - $(LDB_TDB_DIR)/ldb_pack.o $(LDB_TDB_DIR)/ldb_search.o $(LDB_TDB_DIR)/ldb_index.o \ - $(LDB_TDB_DIR)/ldb_cache.o $(LDB_TDB_DIR)/ldb_tdb_wrap.o - -COMDIR=common -COMMON_OBJ=$(COMDIR)/ldb.o $(COMDIR)/ldb_ldif.o \ - $(COMDIR)/ldb_parse.o $(COMDIR)/ldb_msg.o $(COMDIR)/ldb_utf8.o \ - $(COMDIR)/ldb_debug.o $(COMDIR)/ldb_modules.o \ - $(COMDIR)/ldb_dn.o $(COMDIR)/ldb_match.o $(COMDIR)/ldb_attributes.o \ - $(COMDIR)/attrib_handlers.o $(COMDIR)/ldb_controls.o $(COMDIR)/qsort.o - -MODDIR=modules -MODULES_OBJ=$(MODDIR)/operational.o $(MODDIR)/rdn_name.o \ - $(MODDIR)/objectclass.o \ - $(MODDIR)/paged_results.o $(MODDIR)/sort.o $(MODDIR)/asq.o - -NSSDIR=nssldb -NSS_OBJ= $(NSSDIR)/ldb-nss.o $(NSSDIR)/ldb-pwd.o $(NSSDIR)/ldb-grp.o -NSS_LIB = lib/libnss_ldb.so.2 - -OBJS = $(MODULES_OBJ) $(COMMON_OBJ) $(LDB_TDB_OBJ) @TDBOBJ@ @TALLOCOBJ@ @POPTOBJ@ @LIBREPLACEOBJ@ $(EXTRA_OBJ) - -LDB_LIB = lib/libldb.a - -BINS = bin/ldbadd bin/ldbsearch bin/ldbdel bin/ldbmodify bin/ldbedit bin/ldbrename bin/ldbtest bin/oLschema2ldif - -LIBS = $(LDB_LIB) - -EXAMPLES = examples/ldbreader examples/ldifreader - -DIRS = lib bin common ldb_tdb ldb_ldap ldb_sqlite3 modules tools examples - -default: all - -nss: nssdir all $(NSS_LIB) - -nssdir: - @mkdir -p $(NSSDIR) - -all: showflags dirs $(OBJS) $(LDB_LIB) $(BINS) $(EXAMPLES) manpages - -showflags: - @echo 'ldb will be compiled with flags:' - @echo ' CFLAGS = $(CFLAGS)' - @echo ' LIBS = $(LIBS)' - -.c.o: - @echo Compiling $*.c - @mkdir -p `dirname $@` - @$(CC) $(CFLAGS) -c $< -o $@ - -dirs: - @mkdir -p $(DIRS) - -lib/libldb.a: $(OBJS) - ar -rv $@ $(OBJS) - @-ranlib $@ - -lib/libnss_ldb.so.2: $(NSS_OBJ) $(LIBS) - $(CC) -shared -Wl,-soname,libnss_ldb.so.2 -o lib/libnss_ldb.so.2 $(NSS_OBJ) $(OBJS) $(LIB_FLAGS) - -bin/ldbadd: tools/ldbadd.o tools/cmdline.o $(LIBS) - $(CC) -o bin/ldbadd tools/ldbadd.o tools/cmdline.o $(LIB_FLAGS) - -bin/ldbsearch: tools/ldbsearch.o tools/cmdline.o $(LIBS) - $(CC) -o bin/ldbsearch tools/ldbsearch.o tools/cmdline.o $(LIB_FLAGS) - -bin/ldbdel: tools/ldbdel.o tools/cmdline.o $(LIBS) - $(CC) -o bin/ldbdel tools/ldbdel.o tools/cmdline.o $(LIB_FLAGS) - -bin/ldbmodify: tools/ldbmodify.o tools/cmdline.o $(LIBS) - $(CC) -o bin/ldbmodify tools/ldbmodify.o tools/cmdline.o $(LIB_FLAGS) - -bin/ldbedit: tools/ldbedit.o tools/cmdline.o $(LIBS) - $(CC) -o bin/ldbedit tools/ldbedit.o tools/cmdline.o $(LIB_FLAGS) - -bin/ldbrename: tools/ldbrename.o tools/cmdline.o $(LIBS) - $(CC) -o bin/ldbrename tools/ldbrename.o tools/cmdline.o $(LIB_FLAGS) - -bin/ldbtest: tools/ldbtest.o tools/cmdline.o $(LIBS) - $(CC) -o bin/ldbtest tools/ldbtest.o tools/cmdline.o $(LIB_FLAGS) - -bin/oLschema2ldif: tools/oLschema2ldif.o tools/cmdline.o tools/convert.o $(LIBS) - $(CC) -o bin/oLschema2ldif tools/oLschema2ldif.o tools/cmdline.o tools/convert.o $(LIB_FLAGS) - -examples/ldbreader: examples/ldbreader.o $(LIBS) - $(CC) -o examples/ldbreader examples/ldbreader.o $(LIB_FLAGS) - -examples/ldifreader: examples/ldifreader.o $(LIBS) - $(CC) -o examples/ldifreader examples/ldifreader.o $(LIB_FLAGS) - -.SUFFIXES: .1 .1.xml .3 .3.xml .xml .html - -manpages: - @$(srcdir)/docs/builddocs.sh "$(XSLTPROC)" "$(srcdir)" - -doxygen: - test -z "$(DOXYGEN)" || (cd $(srcdir) && "$(DOXYGEN)") - -clean: - rm -f *.o */*.o *.gcov */*.gc?? tdbtest.ldb* - rm -f $(BINS) $(TDB_OBJ) $(TALLOC_OBJ) $(LDB_LIB) $(NSS_LIB) - rm -f man/*.1 man/*.3 man/*.html - rm -f $(EXAMPLES) - rm -rf apidocs/ - rm -rf tests/schema/ - -distclean: clean - rm -f *~ */*~ - rm -rf bin lib - rm -f config.log config.status config.cache include/config.h - rm -f ldb.pc - rm -f Makefile - -realdistclean: distclean - rm -f configure.in include/config.h.in - -test: all - for t in $(TESTS); do echo STARTING $${t}; $(srcdir)/tests/$${t} || exit 1; done - -valgrindtest: all - for t in $(TESTS); do echo STARTING $${t}; VALGRIND="valgrind -q --db-attach=yes --num-callers=30" $(srcdir)/tests/$${t} || exit 1; done - -installcheck: install test - -install: all - mkdir -p $(includedir) $(libdir)/pkgconfig $(libdir) $(bindir) - cp $(srcdir)/include/ldb.h $(srcdir)/include/ldb_errors.h $(includedir) - cp $(LDB_LIB) $(libdir) - cp $(BINS) $(bindir) - cp ldb.pc $(libdir)/pkgconfig - $(srcdir)/docs/installdocs.sh $(mandir) - -gcov: - $(GCOV) -po ldb_sqlite3 $(srcdir)/ldb_sqlite3/*.c 2| tee ldb_sqlite3.report.gcov - $(GCOV) -po ldb_ldap $(srcdir)/ldb_ldap/*.c 2| tee ldb_ldap.report.gcov - $(GCOV) -po ldb_tdb $(srcdir)/ldb_tdb/*.c 2| tee ldb_tdb.report.gcov - $(GCOV) -po common $(srcdir)/common/*.c 2| tee common.report.gcov - $(GCOV) -po modules $(srcdir)/modules/*.c 2| tee modules.report.gcov - $(GCOV) -po tools $(srcdir)/tools/*.c 2| tee tools.report.gcov - -etags: - etags `find $(srcdir) -name "*.[ch]"` - -ctags: - ctags `find $(srcdir) -name "*.[ch]"` diff --git a/source/lib/ldb/README_gcov.txt b/source/lib/ldb/README_gcov.txt deleted file mode 100644 index 2abd9378f43..00000000000 --- a/source/lib/ldb/README_gcov.txt +++ /dev/null @@ -1,29 +0,0 @@ -Here is how to use gcov to test code coverage in ldb. - -Step 1: build ldb with gcov enabled - - make clean all WITH_GCOV=1 - -Step 3: run the test suite - make test-tdb - -Step 4: produce the gcov report - make gcov - -Step 5: read the summary reports - less *.report.gcov - -Step 6: examine the per-file reports - less ldb_tdb\#ldb_tdb.c.gcov - -You can also combine steps 2 to 4 like this: - - make clean all test-tdb gcov WITH_GCOV=1 - -Note that you should not expect 100% coverage, as some error paths -(such as memory allocation failures) are very hard to trigger. There -are ways of working around this, but they are quite tricky (they -involve allocation wrappers that "fork and fail on malloc"). - -The lines to look for in the per-file reports are the ones starting -with "#####". Those are lines that are never executed. diff --git a/source/lib/ldb/aclocal.m4 b/source/lib/ldb/aclocal.m4 deleted file mode 100644 index 5605e476bab..00000000000 --- a/source/lib/ldb/aclocal.m4 +++ /dev/null @@ -1 +0,0 @@ -m4_include(libreplace.m4) diff --git a/source/lib/ldb/autogen.sh b/source/lib/ldb/autogen.sh deleted file mode 100755 index 500cab87d50..00000000000 --- a/source/lib/ldb/autogen.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh - -rm -rf autom4te.cache -rm -f configure config.h.in - -IPATHS="-I libreplace -I lib/replace -I ../libreplace -I ../replace" -IPATHS="$IPATHS -I lib/talloc -I talloc -I ../talloc" -IPATHS="$IPATHS -I lib/tdb -I tdb -I ../tdb" -IPATHS="$IPATHS -I lib/popt -I popt -I ../popt" -autoheader $IPATHS || exit 1 -autoconf $IPATHS || exit 1 - -rm -rf autom4te.cache - -echo "Now run ./configure and then make." -exit 0 - diff --git a/source/lib/ldb/common/attrib_handlers.c b/source/lib/ldb/common/attrib_handlers.c deleted file mode 100644 index 2b699aeaa81..00000000000 --- a/source/lib/ldb/common/attrib_handlers.c +++ /dev/null @@ -1,406 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2005 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -/* - attribute handlers for well known attribute types, selected by syntax OID - see rfc2252 -*/ - -#include "includes.h" -#include "ldb/include/includes.h" -#include "system/locale.h" - -/* - default handler that just copies a ldb_val. -*/ -int ldb_handler_copy(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - *out = ldb_val_dup(mem_ctx, in); - if (in->length > 0 && out->data == NULL) { - ldb_oom(ldb); - return -1; - } - return 0; -} - -/* - a case folding copy handler, removing leading and trailing spaces and - multiple internal spaces - - We exploit the fact that utf8 never uses the space octet except for - the space itself -*/ -static int ldb_handler_fold(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - char *s, *t; - int l; - if (!in || !out || !(in->data)) { - return -1; - } - - out->data = (uint8_t *)ldb_casefold(ldb, mem_ctx, (const char *)(in->data)); - if (out->data == NULL) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_handler_fold: unable to casefold string [%s]", in->data); - return -1; - } - - s = (char *)(out->data); - - /* remove trailing spaces if any */ - l = strlen(s); - while (l > 0 && s[l - 1] == ' ') l--; - s[l] = '\0'; - - /* remove leading spaces if any */ - if (*s == ' ') { - for (t = s; *s == ' '; s++) ; - - /* remove leading spaces by moving down the string */ - memmove(t, s, l); - - s = t; - } - - /* check middle spaces */ - while ((t = strchr(s, ' ')) != NULL) { - for (s = t; *s == ' '; s++) ; - - if ((s - t) > 1) { - l = strlen(s); - - /* remove all spaces but one by moving down the string */ - memmove(t + 1, s, l); - } - } - - out->length = strlen((char *)out->data); - return 0; -} - - - -/* - canonicalise a ldap Integer - rfc2252 specifies it should be in decimal form -*/ -static int ldb_canonicalise_Integer(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - char *end; - long long i = strtoll((char *)in->data, &end, 0); - if (*end != 0) { - return -1; - } - out->data = (uint8_t *)talloc_asprintf(mem_ctx, "%lld", i); - if (out->data == NULL) { - return -1; - } - out->length = strlen((char *)out->data); - return 0; -} - -/* - compare two Integers -*/ -static int ldb_comparison_Integer(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *v1, const struct ldb_val *v2) -{ - return strtoll((char *)v1->data, NULL, 0) - strtoll((char *)v2->data, NULL, 0); -} - -/* - compare two binary blobs -*/ -int ldb_comparison_binary(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *v1, const struct ldb_val *v2) -{ - if (v1->length != v2->length) { - return v1->length - v2->length; - } - return memcmp(v1->data, v2->data, v1->length); -} - -/* - compare two case insensitive strings, ignoring multiple whitespaces - and leading and trailing whitespaces - see rfc2252 section 8.1 - - try to optimize for the ascii case, - but if we find out an utf8 codepoint revert to slower but correct function -*/ -static int ldb_comparison_fold(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *v1, const struct ldb_val *v2) -{ - const char *s1=(const char *)v1->data, *s2=(const char *)v2->data; - const char *u1, *u2; - char *b1, *b2; - int ret; - while (*s1 == ' ') s1++; - while (*s2 == ' ') s2++; - /* TODO: make utf8 safe, possibly with helper function from application */ - while (*s1 && *s2) { - /* the first 127 (0x7F) chars are ascii and utf8 guarantes they - * never appear in multibyte sequences */ - if (((unsigned char)s1[0]) & 0x80) goto utf8str; - if (((unsigned char)s2[0]) & 0x80) goto utf8str; - if (toupper((unsigned char)*s1) != toupper((unsigned char)*s2)) - break; - if (*s1 == ' ') { - while (s1[0] == s1[1]) s1++; - while (s2[0] == s2[1]) s2++; - } - s1++; s2++; - } - if (! (*s1 && *s2)) { - /* check for trailing spaces only if one of the pointers - * has reached the end of the strings otherwise we - * can mistakenly match. - * ex. "domain users" <-> "domainUpdates" - */ - while (*s1 == ' ') s1++; - while (*s2 == ' ') s2++; - } - return (int)(toupper(*s1)) - (int)(toupper(*s2)); - -utf8str: - /* no need to recheck from the start, just from the first utf8 char found */ - b1 = ldb_casefold(ldb, mem_ctx, s1); - b2 = ldb_casefold(ldb, mem_ctx, s2); - - if (b1 && b2) { - /* Both strings converted correctly */ - - u1 = b1; - u2 = b2; - } else { - /* One of the strings was not UTF8, so we have no options but to do a binary compare */ - - u1 = s1; - u2 = s2; - } - - while (*u1 & *u2) { - if (*u1 != *u2) - break; - if (*u1 == ' ') { - while (u1[0] == u1[1]) u1++; - while (u2[0] == u2[1]) u2++; - } - u1++; u2++; - } - if (! (*u1 && *u2)) { - while (*u1 == ' ') u1++; - while (*u2 == ' ') u2++; - } - ret = (int)(*u1 - *u2); - - talloc_free(b1); - talloc_free(b2); - - return ret; -} - -/* - canonicalise a attribute in DN format -*/ -static int ldb_canonicalise_dn(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - struct ldb_dn *dn; - int ret = -1; - - out->length = 0; - out->data = NULL; - - dn = ldb_dn_explode_casefold(ldb, mem_ctx, (char *)in->data); - if (dn == NULL) { - return -1; - } - - out->data = (uint8_t *)ldb_dn_linearize(mem_ctx, dn); - if (out->data == NULL) { - goto done; - } - out->length = strlen((char *)out->data); - - ret = 0; - -done: - talloc_free(dn); - - return ret; -} - -/* - compare two dns -*/ -static int ldb_comparison_dn(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *v1, const struct ldb_val *v2) -{ - struct ldb_dn *dn1 = NULL, *dn2 = NULL; - int ret; - - dn1 = ldb_dn_explode_casefold(ldb, mem_ctx, (char *)v1->data); - if (dn1 == NULL) return -1; - - dn2 = ldb_dn_explode_casefold(ldb, mem_ctx, (char *)v2->data); - if (dn2 == NULL) { - talloc_free(dn1); - return -1; - } - - ret = ldb_dn_compare(ldb, dn1, dn2); - - talloc_free(dn1); - talloc_free(dn2); - return ret; -} - -/* - compare two objectclasses, looking at subclasses -*/ -static int ldb_comparison_objectclass(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *v1, const struct ldb_val *v2) -{ - int ret, i; - const char **subclasses; - ret = ldb_comparison_fold(ldb, mem_ctx, v1, v2); - if (ret == 0) { - return 0; - } - subclasses = ldb_subclass_list(ldb, (char *)v1->data); - if (subclasses == NULL) { - return ret; - } - for (i=0;subclasses[i];i++) { - struct ldb_val vs; - vs.data = discard_const_p(uint8_t, subclasses[i]); - vs.length = strlen(subclasses[i]); - if (ldb_comparison_objectclass(ldb, mem_ctx, &vs, v2) == 0) { - return 0; - } - } - return ret; -} - -/* - compare two utc time values. 1 second resolution -*/ -static int ldb_comparison_utctime(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *v1, const struct ldb_val *v2) -{ - time_t t1, t2; - t1 = ldb_string_to_time((char *)v1->data); - t2 = ldb_string_to_time((char *)v2->data); - return (int)t2 - (int)t1; -} - -/* - canonicalise a utc time -*/ -static int ldb_canonicalise_utctime(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - time_t t = ldb_string_to_time((char *)in->data); - out->data = (uint8_t *)ldb_timestring(mem_ctx, t); - if (out->data == NULL) { - return -1; - } - out->length = strlen((char *)out->data); - return 0; -} - -/* - table of standard attribute handlers -*/ -static const struct ldb_attrib_handler ldb_standard_attribs[] = { - { - .attr = LDB_SYNTAX_INTEGER, - .flags = 0, - .ldif_read_fn = ldb_handler_copy, - .ldif_write_fn = ldb_handler_copy, - .canonicalise_fn = ldb_canonicalise_Integer, - .comparison_fn = ldb_comparison_Integer - }, - { - .attr = LDB_SYNTAX_OCTET_STRING, - .flags = 0, - .ldif_read_fn = ldb_handler_copy, - .ldif_write_fn = ldb_handler_copy, - .canonicalise_fn = ldb_handler_copy, - .comparison_fn = ldb_comparison_binary - }, - { - .attr = LDB_SYNTAX_DIRECTORY_STRING, - .flags = 0, - .ldif_read_fn = ldb_handler_copy, - .ldif_write_fn = ldb_handler_copy, - .canonicalise_fn = ldb_handler_fold, - .comparison_fn = ldb_comparison_fold - }, - { - .attr = LDB_SYNTAX_DN, - .flags = 0, - .ldif_read_fn = ldb_handler_copy, - .ldif_write_fn = ldb_handler_copy, - .canonicalise_fn = ldb_canonicalise_dn, - .comparison_fn = ldb_comparison_dn - }, - { - .attr = LDB_SYNTAX_OBJECTCLASS, - .flags = 0, - .ldif_read_fn = ldb_handler_copy, - .ldif_write_fn = ldb_handler_copy, - .canonicalise_fn = ldb_handler_fold, - .comparison_fn = ldb_comparison_objectclass - }, - { - .attr = LDB_SYNTAX_UTC_TIME, - .flags = 0, - .ldif_read_fn = ldb_handler_copy, - .ldif_write_fn = ldb_handler_copy, - .canonicalise_fn = ldb_canonicalise_utctime, - .comparison_fn = ldb_comparison_utctime - } -}; - - -/* - return the attribute handlers for a given syntax name -*/ -const struct ldb_attrib_handler *ldb_attrib_handler_syntax(struct ldb_context *ldb, - const char *syntax) -{ - int i; - unsigned num_handlers = sizeof(ldb_standard_attribs)/sizeof(ldb_standard_attribs[0]); - /* TODO: should be replaced with a binary search */ - for (i=0;i<num_handlers;i++) { - if (strcmp(ldb_standard_attribs[i].attr, syntax) == 0) { - return &ldb_standard_attribs[i]; - } - } - return NULL; -} - diff --git a/source/lib/ldb/common/ldb.c b/source/lib/ldb/common/ldb.c deleted file mode 100644 index 512ad84efa0..00000000000 --- a/source/lib/ldb/common/ldb.c +++ /dev/null @@ -1,1133 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - Copyright (C) Simo Sorce 2005-2006 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - * Name: ldb - * - * Component: ldb core API - * - * Description: core API routines interfacing to ldb backends - * - * Author: Andrew Tridgell - */ - -#include "includes.h" -#include "ldb/include/includes.h" - -/* - initialise a ldb context - The mem_ctx is optional -*/ -struct ldb_context *ldb_init(void *mem_ctx) -{ - struct ldb_context *ldb = talloc_zero(mem_ctx, struct ldb_context); - int ret; - - ret = ldb_setup_wellknown_attributes(ldb); - if (ret != 0) { - talloc_free(ldb); - return NULL; - } - - ldb_set_utf8_default(ldb); - ldb_set_create_perms(ldb, 0666); - - return ldb; -} - -static struct ldb_backend { - const char *name; - ldb_connect_fn connect_fn; - struct ldb_backend *prev, *next; -} *ldb_backends = NULL; - - -static ldb_connect_fn ldb_find_backend(const char *url) -{ - struct ldb_backend *backend; - - for (backend = ldb_backends; backend; backend = backend->next) { - if (strncmp(backend->name, url, strlen(backend->name)) == 0) { - return backend->connect_fn; - } - } - - return NULL; -} - -/* - register a new ldb backend -*/ -int ldb_register_backend(const char *url_prefix, ldb_connect_fn connectfn) -{ - struct ldb_backend *backend = talloc(talloc_autofree_context(), struct ldb_backend); - - if (ldb_find_backend(url_prefix)) { - return LDB_SUCCESS; - } - - /* Maybe check for duplicity here later on? */ - - backend->name = talloc_strdup(backend, url_prefix); - backend->connect_fn = connectfn; - DLIST_ADD(ldb_backends, backend); - - return LDB_SUCCESS; -} - -/* - Return the ldb module form of a database. The URL can either be one of the following forms - ldb://path - ldapi://path - - flags is made up of LDB_FLG_* - - the options are passed uninterpreted to the backend, and are - backend specific. - - This allows modules to get at only the backend module, for example where a module - may wish to direct certain requests at a particular backend. -*/ -int ldb_connect_backend(struct ldb_context *ldb, const char *url, const char *options[], - struct ldb_module **backend_module) -{ - int ret; - char *backend; - ldb_connect_fn fn; - - if (strchr(url, ':') != NULL) { - backend = talloc_strndup(ldb, url, strchr(url, ':')-url); - } else { - /* Default to tdb */ - backend = talloc_strdup(ldb, "tdb"); - } - - fn = ldb_find_backend(backend); - - if (fn == NULL) { - if (ldb_try_load_dso(ldb, backend) == 0) { - fn = ldb_find_backend(backend); - } - } - - talloc_free(backend); - - if (fn == NULL) { - ldb_debug(ldb, LDB_DEBUG_FATAL, "Unable to find backend for '%s'\n", url); - return LDB_ERR_OTHER; - } - - ret = fn(ldb, url, ldb->flags, options, backend_module); - - if (ret != LDB_SUCCESS) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to connect to '%s'\n", url); - return ret; - } - return ret; -} - -/* - try to autodetect a basedn if none specified. This fixes one of my - pet hates about ldapsearch, which is that you have to get a long, - complex basedn right to make any use of it. -*/ -static const struct ldb_dn *ldb_set_default_basedn(struct ldb_context *ldb) -{ - TALLOC_CTX *tmp_ctx; - int ret; - static const char *attrs[] = { "defaultNamingContext", NULL }; - struct ldb_result *res; - struct ldb_dn *basedn=NULL; - - basedn = (struct ldb_dn *)ldb_get_opaque(ldb, "default_baseDN"); - if (basedn) { - return basedn; - } - - tmp_ctx = talloc_new(ldb); - ret = ldb_search(ldb, ldb_dn_new(tmp_ctx), LDB_SCOPE_BASE, - "(objectClass=*)", attrs, &res); - if (ret == LDB_SUCCESS) { - if (res->count == 1) { - basedn = ldb_msg_find_attr_as_dn(ldb, res->msgs[0], "defaultNamingContext"); - ldb_set_opaque(ldb, "default_baseDN", basedn); - } - talloc_free(res); - } - - talloc_free(tmp_ctx); - return basedn; -} - -const struct ldb_dn *ldb_get_default_basedn(struct ldb_context *ldb) -{ - return (const struct ldb_dn *)ldb_get_opaque(ldb, "default_baseDN"); -} - -/* - connect to a database. The URL can either be one of the following forms - ldb://path - ldapi://path - - flags is made up of LDB_FLG_* - - the options are passed uninterpreted to the backend, and are - backend specific -*/ -int ldb_connect(struct ldb_context *ldb, const char *url, unsigned int flags, const char *options[]) -{ - int ret; - - ldb->flags = flags; - - ret = ldb_connect_backend(ldb, url, options, &ldb->modules); - if (ret != LDB_SUCCESS) { - return ret; - } - - if (ldb_load_modules(ldb, options) != LDB_SUCCESS) { - ldb_debug(ldb, LDB_DEBUG_FATAL, "Unable to load modules for %s: %s\n", - url, ldb_errstring(ldb)); - return LDB_ERR_OTHER; - } - - /* TODO: get timeout from options if available there */ - ldb->default_timeout = 300; /* set default to 5 minutes */ - - /* set the default base dn */ - ldb_set_default_basedn(ldb); - - return LDB_SUCCESS; -} - -void ldb_set_errstring(struct ldb_context *ldb, const char *err_string) -{ - if (ldb->err_string) { - talloc_free(ldb->err_string); - } - ldb->err_string = talloc_strdup(ldb, err_string); -} - -void ldb_asprintf_errstring(struct ldb_context *ldb, const char *format, ...) -{ - va_list ap; - - if (ldb->err_string) { - talloc_free(ldb->err_string); - } - - va_start(ap, format); - ldb->err_string = talloc_vasprintf(ldb, format, ap); - va_end(ap); -} - -void ldb_reset_err_string(struct ldb_context *ldb) -{ - if (ldb->err_string) { - talloc_free(ldb->err_string); - ldb->err_string = NULL; - } -} - -#define FIRST_OP(ldb, op) do { \ - module = ldb->modules; \ - while (module && module->ops->op == NULL) module = module->next; \ - if (module == NULL) { \ - ldb_asprintf_errstring(ldb, "unable to find module or backend to handle operation: " #op); \ - return LDB_ERR_OPERATIONS_ERROR; \ - } \ -} while (0) - -/* - start a transaction -*/ -static int ldb_transaction_start_internal(struct ldb_context *ldb) -{ - struct ldb_module *module; - int status; - FIRST_OP(ldb, start_transaction); - - ldb_reset_err_string(ldb); - - status = module->ops->start_transaction(module); - if (status != LDB_SUCCESS) { - if (ldb->err_string == NULL) { - /* no error string was setup by the backend */ - ldb_asprintf_errstring(ldb, - "ldb transaction start: %s (%d)", - ldb_strerror(status), - status); - } - } - return status; -} - -/* - commit a transaction -*/ -static int ldb_transaction_commit_internal(struct ldb_context *ldb) -{ - struct ldb_module *module; - int status; - FIRST_OP(ldb, end_transaction); - - ldb_reset_err_string(ldb); - - status = module->ops->end_transaction(module); - if (status != LDB_SUCCESS) { - if (ldb->err_string == NULL) { - /* no error string was setup by the backend */ - ldb_asprintf_errstring(ldb, - "ldb transaction commit: %s (%d)", - ldb_strerror(status), - status); - } - } - return status; -} - -/* - cancel a transaction -*/ -static int ldb_transaction_cancel_internal(struct ldb_context *ldb) -{ - struct ldb_module *module; - int status; - FIRST_OP(ldb, del_transaction); - - status = module->ops->del_transaction(module); - if (status != LDB_SUCCESS) { - if (ldb->err_string == NULL) { - /* no error string was setup by the backend */ - ldb_asprintf_errstring(ldb, - "ldb transaction cancel: %s (%d)", - ldb_strerror(status), - status); - } - } - return status; -} - -int ldb_transaction_start(struct ldb_context *ldb) -{ - /* disable autotransactions */ - ldb->transaction_active++; - - return ldb_transaction_start_internal(ldb); -} - -int ldb_transaction_commit(struct ldb_context *ldb) -{ - /* renable autotransactions (when we reach 0) */ - if (ldb->transaction_active > 0) - ldb->transaction_active--; - - return ldb_transaction_commit_internal(ldb); -} - -int ldb_transaction_cancel(struct ldb_context *ldb) -{ - /* renable autotransactions (when we reach 0) */ - if (ldb->transaction_active > 0) - ldb->transaction_active--; - - return ldb_transaction_cancel_internal(ldb); -} - -static int ldb_autotransaction_start(struct ldb_context *ldb) -{ - /* explicit transaction active, ignore autotransaction request */ - if (ldb->transaction_active) - return LDB_SUCCESS; - - return ldb_transaction_start_internal(ldb); -} - -static int ldb_autotransaction_commit(struct ldb_context *ldb) -{ - /* explicit transaction active, ignore autotransaction request */ - if (ldb->transaction_active) - return LDB_SUCCESS; - - return ldb_transaction_commit_internal(ldb); -} - -static int ldb_autotransaction_cancel(struct ldb_context *ldb) -{ - /* explicit transaction active, ignore autotransaction request */ - if (ldb->transaction_active) - return LDB_SUCCESS; - - return ldb_transaction_cancel_internal(ldb); -} - -/* autostarts a transacion if none active */ -static int ldb_autotransaction_request(struct ldb_context *ldb, struct ldb_request *req) -{ - int ret; - - ret = ldb_autotransaction_start(ldb); - if (ret != LDB_SUCCESS) { - return ret; - } - - ret = ldb_request(ldb, req); - if (ret == LDB_SUCCESS) { - ret = ldb_wait(req->handle, LDB_WAIT_ALL); - } - - if (ret == LDB_SUCCESS) { - return ldb_autotransaction_commit(ldb); - } - ldb_autotransaction_cancel(ldb); - - if (ldb->err_string == NULL) { - /* no error string was setup by the backend */ - ldb_asprintf_errstring(ldb, "%s (%d)", ldb_strerror(ret), ret); - } - - return ret; -} - -int ldb_wait(struct ldb_handle *handle, enum ldb_wait_type type) -{ - if (!handle) { - return LDB_SUCCESS; - } - - return handle->module->ops->wait(handle, type); -} - -/* set the specified timeout or, if timeout is 0 set the default timeout */ -/* timeout == -1 means no timeout */ -int ldb_set_timeout(struct ldb_context *ldb, struct ldb_request *req, int timeout) -{ - if (req == NULL) return LDB_ERR_OPERATIONS_ERROR; - - if (timeout != 0) { - req->timeout = timeout; - } else { - req->timeout = ldb->default_timeout; - } - req->starttime = time(NULL); - - return LDB_SUCCESS; -} - -/* calculates the new timeout based on the previous starttime and timeout */ -int ldb_set_timeout_from_prev_req(struct ldb_context *ldb, struct ldb_request *oldreq, struct ldb_request *newreq) -{ - time_t now; - - if (newreq == NULL) return LDB_ERR_OPERATIONS_ERROR; - - now = time(NULL); - - if (oldreq == NULL) - return ldb_set_timeout(ldb, newreq, 0); - - if ((now - oldreq->starttime) > oldreq->timeout) { - return LDB_ERR_TIME_LIMIT_EXCEEDED; - } - newreq->starttime = oldreq->starttime; - newreq->timeout = oldreq->timeout - (now - oldreq->starttime); - - return LDB_SUCCESS; -} - - -/* - set the permissions for new files to be passed to open() in - backends that use local files - */ -void ldb_set_create_perms(struct ldb_context *ldb, unsigned int perms) -{ - ldb->create_perms = perms; -} - -/* - start an ldb request - NOTE: the request must be a talloc context. - returns LDB_ERR_* on errors. -*/ -int ldb_request(struct ldb_context *ldb, struct ldb_request *req) -{ - struct ldb_module *module; - int ret; - - ldb_reset_err_string(ldb); - - /* call the first module in the chain */ - switch (req->operation) { - case LDB_SEARCH: - FIRST_OP(ldb, search); - ret = module->ops->search(module, req); - break; - case LDB_ADD: - FIRST_OP(ldb, add); - ret = module->ops->add(module, req); - break; - case LDB_MODIFY: - FIRST_OP(ldb, modify); - ret = module->ops->modify(module, req); - break; - case LDB_DELETE: - FIRST_OP(ldb, del); - ret = module->ops->del(module, req); - break; - case LDB_RENAME: - FIRST_OP(ldb, rename); - ret = module->ops->rename(module, req); - break; - case LDB_SEQUENCE_NUMBER: - FIRST_OP(ldb, sequence_number); - ret = module->ops->sequence_number(module, req); - break; - default: - FIRST_OP(ldb, request); - ret = module->ops->request(module, req); - break; - } - - return ret; -} - -/* - search the database given a LDAP-like search expression - - returns an LDB error code - - Use talloc_free to free the ldb_message returned in 'res', if successful - -*/ -int ldb_search_default_callback(struct ldb_context *ldb, void *context, struct ldb_reply *ares) -{ - struct ldb_result *res; - int n; - - if (!context) { - ldb_set_errstring(ldb, "NULL Context in callback"); - return LDB_ERR_OPERATIONS_ERROR; - } - - res = talloc_get_type(context, struct ldb_result); - - if (!res || !ares) { - ldb_set_errstring(ldb, "NULL res or ares in callback"); - goto error; - } - - switch (ares->type) { - case LDB_REPLY_ENTRY: - res->msgs = talloc_realloc(res, res->msgs, struct ldb_message *, res->count + 2); - if (! res->msgs) { - goto error; - } - - res->msgs[res->count + 1] = NULL; - - res->msgs[res->count] = talloc_move(res->msgs, &ares->message); - res->count++; - break; - case LDB_REPLY_REFERRAL: - if (res->refs) { - for (n = 0; res->refs[n]; n++) /*noop*/ ; - } else { - n = 0; - } - - res->refs = talloc_realloc(res, res->refs, char *, n + 2); - if (! res->refs) { - goto error; - } - - res->refs[n] = talloc_move(res->refs, &ares->referral); - res->refs[n + 1] = NULL; - case LDB_REPLY_EXTENDED: - case LDB_REPLY_DONE: - /* TODO: we should really support controls on entries and referrals too! */ - res->controls = talloc_move(res, &ares->controls); - break; - } - talloc_free(ares); - return LDB_SUCCESS; - -error: - talloc_free(ares); - return LDB_ERR_OPERATIONS_ERROR; -} - -int ldb_build_search_req(struct ldb_request **ret_req, - struct ldb_context *ldb, - void *mem_ctx, - const struct ldb_dn *base, - enum ldb_scope scope, - const char *expression, - const char * const *attrs, - struct ldb_control **controls, - void *context, - ldb_request_callback_t callback) -{ - struct ldb_request *req; - - *ret_req = NULL; - - req = talloc(mem_ctx, struct ldb_request); - if (req == NULL) { - ldb_set_errstring(ldb, "Out of Memory"); - return LDB_ERR_OPERATIONS_ERROR; - } - - req->operation = LDB_SEARCH; - if (base == NULL) { - req->op.search.base = ldb_dn_new(req); - } else { - req->op.search.base = base; - } - req->op.search.scope = scope; - - req->op.search.tree = ldb_parse_tree(req, expression); - if (req->op.search.tree == NULL) { - ldb_set_errstring(ldb, "Unable to parse search expression"); - talloc_free(req); - return LDB_ERR_OPERATIONS_ERROR; - } - - req->op.search.attrs = attrs; - req->controls = controls; - req->context = context; - req->callback = callback; - - *ret_req = req; - return LDB_SUCCESS; -} - -int ldb_build_add_req(struct ldb_request **ret_req, - struct ldb_context *ldb, - void *mem_ctx, - const struct ldb_message *message, - struct ldb_control **controls, - void *context, - ldb_request_callback_t callback) -{ - struct ldb_request *req; - - *ret_req = NULL; - - req = talloc(mem_ctx, struct ldb_request); - if (req == NULL) { - ldb_set_errstring(ldb, "Out of Memory"); - return LDB_ERR_OPERATIONS_ERROR; - } - - req->operation = LDB_ADD; - req->op.add.message = message; - req->controls = controls; - req->context = context; - req->callback = callback; - - *ret_req = req; - - return LDB_SUCCESS; -} - -int ldb_build_mod_req(struct ldb_request **ret_req, - struct ldb_context *ldb, - void *mem_ctx, - const struct ldb_message *message, - struct ldb_control **controls, - void *context, - ldb_request_callback_t callback) -{ - struct ldb_request *req; - - *ret_req = NULL; - - req = talloc(mem_ctx, struct ldb_request); - if (req == NULL) { - ldb_set_errstring(ldb, "Out of Memory"); - return LDB_ERR_OPERATIONS_ERROR; - } - - req->operation = LDB_MODIFY; - req->op.mod.message = message; - req->controls = controls; - req->context = context; - req->callback = callback; - - *ret_req = req; - - return LDB_SUCCESS; -} - -int ldb_build_del_req(struct ldb_request **ret_req, - struct ldb_context *ldb, - void *mem_ctx, - const struct ldb_dn *dn, - struct ldb_control **controls, - void *context, - ldb_request_callback_t callback) -{ - struct ldb_request *req; - - *ret_req = NULL; - - req = talloc(mem_ctx, struct ldb_request); - if (req == NULL) { - ldb_set_errstring(ldb, "Out of Memory"); - return LDB_ERR_OPERATIONS_ERROR; - } - - req->operation = LDB_DELETE; - req->op.del.dn = dn; - req->controls = controls; - req->context = context; - req->callback = callback; - - *ret_req = req; - - return LDB_SUCCESS; -} - -int ldb_build_rename_req(struct ldb_request **ret_req, - struct ldb_context *ldb, - void *mem_ctx, - const struct ldb_dn *olddn, - const struct ldb_dn *newdn, - struct ldb_control **controls, - void *context, - ldb_request_callback_t callback) -{ - struct ldb_request *req; - - *ret_req = NULL; - - req = talloc(mem_ctx, struct ldb_request); - if (req == NULL) { - ldb_set_errstring(ldb, "Out of Memory"); - return LDB_ERR_OPERATIONS_ERROR; - } - - req->operation = LDB_RENAME; - req->op.rename.olddn = olddn; - req->op.rename.newdn = newdn; - req->controls = controls; - req->context = context; - req->callback = callback; - - *ret_req = req; - - return LDB_SUCCESS; -} - -/* - note that ldb_search() will automatically replace a NULL 'base' value with the - defaultNamingContext from the rootDSE if available. -*/ -int ldb_search(struct ldb_context *ldb, - const struct ldb_dn *base, - enum ldb_scope scope, - const char *expression, - const char * const *attrs, - struct ldb_result **_res) -{ - struct ldb_request *req; - int ret; - struct ldb_result *res; - - *_res = NULL; - - res = talloc_zero(ldb, struct ldb_result); - if (!res) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldb_build_search_req(&req, ldb, ldb, - base?base:ldb_get_default_basedn(ldb), - scope, - expression, - attrs, - NULL, - res, - ldb_search_default_callback); - - if (ret != LDB_SUCCESS) goto done; - - ldb_set_timeout(ldb, req, 0); /* use default timeout */ - - ret = ldb_request(ldb, req); - - if (ret == LDB_SUCCESS) { - ret = ldb_wait(req->handle, LDB_WAIT_ALL); - } - - talloc_free(req); - -done: - if (ret != LDB_SUCCESS) { - talloc_free(res); - } - - *_res = res; - return ret; -} - -/* - a useful search function where you can easily define the expression and that - takes a memory context where results are allocated -*/ - -int ldb_search_exp_fmt(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, struct ldb_result **result, - struct ldb_dn *base, enum ldb_scope scope, const char * const *attrs, - const char *exp_fmt, ...) -{ - struct ldb_result *res; - char *expression; - va_list ap; - int ret; - - res = NULL; - *result = NULL; - - va_start(ap, exp_fmt); - expression = talloc_vasprintf(mem_ctx, exp_fmt, ap); - va_end(ap); - - if ( ! expression) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldb_search(ldb, base, scope, expression, attrs, &res); - - if (ret == LDB_SUCCESS) { - talloc_steal(mem_ctx, res); - *result = res; - } else { - talloc_free(res); - } - - talloc_free(expression); - - return ret; -} - -/* - add a record to the database. Will fail if a record with the given class and key - already exists -*/ -int ldb_add(struct ldb_context *ldb, - const struct ldb_message *message) -{ - struct ldb_request *req; - int ret; - - ret = ldb_msg_sanity_check(ldb, message); - if (ret != LDB_SUCCESS) { - return ret; - } - - ret = ldb_build_add_req(&req, ldb, ldb, - message, - NULL, - NULL, - NULL); - - if (ret != LDB_SUCCESS) return ret; - - ldb_set_timeout(ldb, req, 0); /* use default timeout */ - - /* do request and autostart a transaction */ - ret = ldb_autotransaction_request(ldb, req); - - talloc_free(req); - return ret; -} - -/* - modify the specified attributes of a record -*/ -int ldb_modify(struct ldb_context *ldb, - const struct ldb_message *message) -{ - struct ldb_request *req; - int ret; - - ret = ldb_msg_sanity_check(ldb, message); - if (ret != LDB_SUCCESS) { - return ret; - } - - ret = ldb_build_mod_req(&req, ldb, ldb, - message, - NULL, - NULL, - NULL); - - if (ret != LDB_SUCCESS) return ret; - - ldb_set_timeout(ldb, req, 0); /* use default timeout */ - - /* do request and autostart a transaction */ - ret = ldb_autotransaction_request(ldb, req); - - talloc_free(req); - return ret; -} - - -/* - delete a record from the database -*/ -int ldb_delete(struct ldb_context *ldb, const struct ldb_dn *dn) -{ - struct ldb_request *req; - int ret; - - ret = ldb_build_del_req(&req, ldb, ldb, - dn, - NULL, - NULL, - NULL); - - if (ret != LDB_SUCCESS) return ret; - - ldb_set_timeout(ldb, req, 0); /* use default timeout */ - - /* do request and autostart a transaction */ - ret = ldb_autotransaction_request(ldb, req); - - talloc_free(req); - return ret; -} - -/* - rename a record in the database -*/ -int ldb_rename(struct ldb_context *ldb, const struct ldb_dn *olddn, const struct ldb_dn *newdn) -{ - struct ldb_request *req; - int ret; - - ret = ldb_build_rename_req(&req, ldb, ldb, - olddn, - newdn, - NULL, - NULL, - NULL); - - if (ret != LDB_SUCCESS) return ret; - - ldb_set_timeout(ldb, req, 0); /* use default timeout */ - - /* do request and autostart a transaction */ - ret = ldb_autotransaction_request(ldb, req); - - talloc_free(req); - return ret; -} - - -/* - return the global sequence number -*/ -int ldb_sequence_number(struct ldb_context *ldb, enum ldb_sequence_type type, uint64_t *seq_num) -{ - struct ldb_request *req; - int ret; - - req = talloc(ldb, struct ldb_request); - if (req == NULL) { - ldb_set_errstring(ldb, "Out of Memory"); - return LDB_ERR_OPERATIONS_ERROR; - } - - req->operation = LDB_SEQUENCE_NUMBER; - req->controls = NULL; - req->context = NULL; - req->callback = NULL; - ldb_set_timeout(ldb, req, 0); /* use default timeout */ - - req->op.seq_num.type = type; - /* do request and autostart a transaction */ - ret = ldb_request(ldb, req); - - if (ret == LDB_SUCCESS) { - *seq_num = req->op.seq_num.seq_num; - } - - talloc_free(req); - return ret; -} - - - -/* - return extended error information -*/ -const char *ldb_errstring(struct ldb_context *ldb) -{ - if (ldb->err_string) { - return ldb->err_string; - } - - return NULL; -} - -/* - return a string explaining what a ldb error constant meancs -*/ -const char *ldb_strerror(int ldb_err) -{ - switch (ldb_err) { - case LDB_SUCCESS: - return "Success"; - case LDB_ERR_OPERATIONS_ERROR: - return "Operations error"; - case LDB_ERR_PROTOCOL_ERROR: - return "Protocol error"; - case LDB_ERR_TIME_LIMIT_EXCEEDED: - return "Time limit exceeded"; - case LDB_ERR_SIZE_LIMIT_EXCEEDED: - return "Size limit exceeded"; - case LDB_ERR_COMPARE_FALSE: - return "Compare false"; - case LDB_ERR_COMPARE_TRUE: - return "Compare true"; - case LDB_ERR_AUTH_METHOD_NOT_SUPPORTED: - return "Auth method not supported"; - case LDB_ERR_STRONG_AUTH_REQUIRED: - return "Strong auth required"; -/* 9 RESERVED */ - case LDB_ERR_REFERRAL: - return "Referral error"; - case LDB_ERR_ADMIN_LIMIT_EXCEEDED: - return "Admin limit exceeded"; - case LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION: - return "Unsupported critical extension"; - case LDB_ERR_CONFIDENTIALITY_REQUIRED: - return "Confidentiality required"; - case LDB_ERR_SASL_BIND_IN_PROGRESS: - return "SASL bind in progress"; - case LDB_ERR_NO_SUCH_ATTRIBUTE: - return "No such attribute"; - case LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE: - return "Undefined attribute type"; - case LDB_ERR_INAPPROPRIATE_MATCHING: - return "Inappropriate matching"; - case LDB_ERR_CONSTRAINT_VIOLATION: - return "Constraint violation"; - case LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS: - return "Attribute or value exists"; - case LDB_ERR_INVALID_ATTRIBUTE_SYNTAX: - return "Invalid attribute syntax"; -/* 22-31 unused */ - case LDB_ERR_NO_SUCH_OBJECT: - return "No such object"; - case LDB_ERR_ALIAS_PROBLEM: - return "Alias problem"; - case LDB_ERR_INVALID_DN_SYNTAX: - return "Invalid DN syntax"; -/* 35 RESERVED */ - case LDB_ERR_ALIAS_DEREFERENCING_PROBLEM: - return "Alias dereferencing problem"; -/* 37-47 unused */ - case LDB_ERR_INAPPROPRIATE_AUTHENTICATION: - return "Inappropriate authentication"; - case LDB_ERR_INVALID_CREDENTIALS: - return "Invalid credentials"; - case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS: - return "insufficient access rights"; - case LDB_ERR_BUSY: - return "Busy"; - case LDB_ERR_UNAVAILABLE: - return "Unavailable"; - case LDB_ERR_UNWILLING_TO_PERFORM: - return "Unwilling to perform"; - case LDB_ERR_LOOP_DETECT: - return "Loop detect"; -/* 55-63 unused */ - case LDB_ERR_NAMING_VIOLATION: - return "Naming violation"; - case LDB_ERR_OBJECT_CLASS_VIOLATION: - return "Object class violation"; - case LDB_ERR_NOT_ALLOWED_ON_NON_LEAF: - return "Not allowed on non-leaf"; - case LDB_ERR_NOT_ALLOWED_ON_RDN: - return "Not allowed on RDN"; - case LDB_ERR_ENTRY_ALREADY_EXISTS: - return "Entry already exists"; - case LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED: - return "Object class mods prohibited"; -/* 70 RESERVED FOR CLDAP */ - case LDB_ERR_AFFECTS_MULTIPLE_DSAS: - return "Affects multiple DSAs"; -/* 72-79 unused */ - case LDB_ERR_OTHER: - return "Other"; - } - - return "Unknown error"; -} - -/* - set backend specific opaque parameters -*/ -int ldb_set_opaque(struct ldb_context *ldb, const char *name, void *value) -{ - struct ldb_opaque *o; - - /* allow updating an existing value */ - for (o=ldb->opaque;o;o=o->next) { - if (strcmp(o->name, name) == 0) { - o->value = value; - return LDB_SUCCESS; - } - } - - o = talloc(ldb, struct ldb_opaque); - if (o == NULL) { - ldb_oom(ldb); - return LDB_ERR_OTHER; - } - o->next = ldb->opaque; - o->name = name; - o->value = value; - ldb->opaque = o; - return LDB_SUCCESS; -} - -/* - get a previously set opaque value -*/ -void *ldb_get_opaque(struct ldb_context *ldb, const char *name) -{ - struct ldb_opaque *o; - for (o=ldb->opaque;o;o=o->next) { - if (strcmp(o->name, name) == 0) { - return o->value; - } - } - return NULL; -} diff --git a/source/lib/ldb/common/ldb_attributes.c b/source/lib/ldb/common/ldb_attributes.c deleted file mode 100644 index 26c1aac5a58..00000000000 --- a/source/lib/ldb/common/ldb_attributes.c +++ /dev/null @@ -1,309 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2005 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -/* - register handlers for specific attributes and objectclass relationships - - this allows a backend to store its schema information in any format - it likes (or to not have any schema information at all) while keeping the - message matching logic generic -*/ - -#include "includes.h" -#include "ldb/include/includes.h" - -/* - add to the list of ldif handlers for this ldb context -*/ -int ldb_set_attrib_handlers(struct ldb_context *ldb, - const struct ldb_attrib_handler *handlers, - unsigned num_handlers) -{ - int i; - struct ldb_attrib_handler *h; - h = talloc_realloc(ldb, ldb->schema.attrib_handlers, - struct ldb_attrib_handler, - ldb->schema.num_attrib_handlers + num_handlers); - if (h == NULL) { - ldb_oom(ldb); - return -1; - } - ldb->schema.attrib_handlers = h; - memcpy(h + ldb->schema.num_attrib_handlers, - handlers, sizeof(*h) * num_handlers); - for (i=0;i<num_handlers;i++) { - if (h[ldb->schema.num_attrib_handlers+i].flags & LDB_ATTR_FLAG_ALLOCATED) { - h[ldb->schema.num_attrib_handlers+i].attr = talloc_strdup(ldb->schema.attrib_handlers, - h[ldb->schema.num_attrib_handlers+i].attr); - if (h[ldb->schema.num_attrib_handlers+i].attr == NULL) { - ldb_oom(ldb); - return -1; - } - } - } - ldb->schema.num_attrib_handlers += num_handlers; - return 0; -} - - -/* - default function for read/write/canonicalise -*/ -static int ldb_default_copy(struct ldb_context *ldb, - void *mem_ctx, - const struct ldb_val *in, - struct ldb_val *out) -{ - *out = ldb_val_dup(mem_ctx, in); - - if (out->data == NULL && in->data != NULL) { - return -1; - } - - return 0; -} - -/* - default function for comparison -*/ -static int ldb_default_cmp(struct ldb_context *ldb, - void *mem_ctx, - const struct ldb_val *v1, - const struct ldb_val *v2) -{ - if (v1->length != v2->length) { - return v1->length - v2->length; - } - return memcmp(v1->data, v2->data, v1->length); -} - -/* - default handler function pointers -*/ -static const struct ldb_attrib_handler ldb_default_attrib_handler = { - .attr = NULL, - .ldif_read_fn = ldb_default_copy, - .ldif_write_fn = ldb_default_copy, - .canonicalise_fn = ldb_default_copy, - .comparison_fn = ldb_default_cmp, -}; - -/* - return the attribute handlers for a given attribute -*/ -const struct ldb_attrib_handler *ldb_attrib_handler(struct ldb_context *ldb, - const char *attrib) -{ - int i; - const struct ldb_attrib_handler *def = &ldb_default_attrib_handler; - /* TODO: should be replaced with a binary search, with a sort on add */ - for (i=0;i<ldb->schema.num_attrib_handlers;i++) { - if (strcmp(ldb->schema.attrib_handlers[i].attr, "*") == 0) { - def = &ldb->schema.attrib_handlers[i]; - } - if (ldb_attr_cmp(attrib, ldb->schema.attrib_handlers[i].attr) == 0) { - return &ldb->schema.attrib_handlers[i]; - } - } - return def; -} - - -/* - add to the list of ldif handlers for this ldb context -*/ -void ldb_remove_attrib_handler(struct ldb_context *ldb, const char *attrib) -{ - const struct ldb_attrib_handler *h; - int i; - h = ldb_attrib_handler(ldb, attrib); - if (h == &ldb_default_attrib_handler) { - return; - } - if (h->flags & LDB_ATTR_FLAG_ALLOCATED) { - talloc_free(discard_const_p(char, h->attr)); - } - i = h - ldb->schema.attrib_handlers; - if (i < ldb->schema.num_attrib_handlers - 1) { - memmove(&ldb->schema.attrib_handlers[i], - h+1, sizeof(*h) * (ldb->schema.num_attrib_handlers-(i+1))); - } - ldb->schema.num_attrib_handlers--; -} - -/* - setup a attribute handler using a standard syntax -*/ -int ldb_set_attrib_handler_syntax(struct ldb_context *ldb, - const char *attr, const char *syntax) -{ - const struct ldb_attrib_handler *h = ldb_attrib_handler_syntax(ldb, syntax); - struct ldb_attrib_handler h2; - if (h == NULL) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "Unknown syntax '%s'\n", syntax); - return -1; - } - h2 = *h; - h2.attr = attr; - return ldb_set_attrib_handlers(ldb, &h2, 1); -} - -/* - setup the attribute handles for well known attributes -*/ -int ldb_setup_wellknown_attributes(struct ldb_context *ldb) -{ - const struct { - const char *attr; - const char *syntax; - } wellknown[] = { - { "dn", LDB_SYNTAX_DN }, - { "ncName", LDB_SYNTAX_DN }, - { "distinguishedName", LDB_SYNTAX_DN }, - { "cn", LDB_SYNTAX_DIRECTORY_STRING }, - { "dc", LDB_SYNTAX_DIRECTORY_STRING }, - { "ou", LDB_SYNTAX_DIRECTORY_STRING }, - { "objectClass", LDB_SYNTAX_OBJECTCLASS } - }; - int i; - for (i=0;i<ARRAY_SIZE(wellknown);i++) { - if (ldb_set_attrib_handler_syntax(ldb, wellknown[i].attr, - wellknown[i].syntax) != 0) { - return -1; - } - } - return 0; -} - - -/* - return the list of subclasses for a class -*/ -const char **ldb_subclass_list(struct ldb_context *ldb, const char *classname) -{ - int i; - for (i=0;i<ldb->schema.num_classes;i++) { - if (ldb_attr_cmp(classname, ldb->schema.classes[i].name) == 0) { - return (const char **)ldb->schema.classes[i].subclasses; - } - } - return NULL; -} - - -/* - add a new subclass -*/ -static int ldb_subclass_new(struct ldb_context *ldb, const char *classname, const char *subclass) -{ - struct ldb_subclass *s, *c; - s = talloc_realloc(ldb, ldb->schema.classes, struct ldb_subclass, ldb->schema.num_classes+1); - if (s == NULL) goto failed; - - ldb->schema.classes = s; - c = &s[ldb->schema.num_classes]; - c->name = talloc_strdup(s, classname); - if (c->name == NULL) goto failed; - - c->subclasses = talloc_array(s, char *, 2); - if (c->subclasses == NULL) goto failed; - - c->subclasses[0] = talloc_strdup(c->subclasses, subclass); - if (c->subclasses[0] == NULL) goto failed; - c->subclasses[1] = NULL; - - ldb->schema.num_classes++; - - return 0; -failed: - ldb_oom(ldb); - return -1; -} - -/* - add a subclass -*/ -int ldb_subclass_add(struct ldb_context *ldb, const char *classname, const char *subclass) -{ - int i, n; - struct ldb_subclass *c; - char **s; - - for (i=0;i<ldb->schema.num_classes;i++) { - if (ldb_attr_cmp(classname, ldb->schema.classes[i].name) == 0) { - break; - } - } - if (i == ldb->schema.num_classes) { - return ldb_subclass_new(ldb, classname, subclass); - } - c = &ldb->schema.classes[i]; - - for (n=0;c->subclasses[n];n++) /* noop */; - - s = talloc_realloc(ldb->schema.classes, c->subclasses, char *, n+2); - if (s == NULL) { - ldb_oom(ldb); - return -1; - } - - c->subclasses = s; - s[n] = talloc_strdup(s, subclass); - if (s[n] == NULL) { - ldb_oom(ldb); - return -1; - } - s[n+1] = NULL; - - return 0; -} - -/* - remove a set of subclasses for a class -*/ -void ldb_subclass_remove(struct ldb_context *ldb, const char *classname) -{ - int i; - struct ldb_subclass *c; - - for (i=0;i<ldb->schema.num_classes;i++) { - if (ldb_attr_cmp(classname, ldb->schema.classes[i].name) == 0) { - break; - } - } - if (i == ldb->schema.num_classes) { - return; - } - - c = &ldb->schema.classes[i]; - talloc_free(c->name); - talloc_free(c->subclasses); - if (ldb->schema.num_classes-(i+1) > 0) { - memmove(c, c+1, sizeof(*c) * (ldb->schema.num_classes-(i+1))); - } - ldb->schema.num_classes--; - if (ldb->schema.num_classes == 0) { - talloc_free(ldb->schema.classes); - ldb->schema.classes = NULL; - } -} diff --git a/source/lib/ldb/common/ldb_controls.c b/source/lib/ldb/common/ldb_controls.c deleted file mode 100644 index d2729c82ab8..00000000000 --- a/source/lib/ldb/common/ldb_controls.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - ldb database library - - Copyright (C) Simo Sorce 2005 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - * Name: ldb_controls.c - * - * Component: ldb controls utility functions - * - * Description: helper functions for control modules - * - * Author: Simo Sorce - */ - -#include "includes.h" -#include "ldb/include/includes.h" - -/* check if a control with the specified "oid" exist and return it */ -/* returns NULL if not found */ -struct ldb_control *get_control_from_list(struct ldb_control **controls, const char *oid) -{ - int i; - - /* check if there's a paged request control */ - if (controls != NULL) { - for (i = 0; controls[i]; i++) { - if (strcmp(oid, controls[i]->oid) == 0) { - break; - } - } - - return controls[i]; - } - - return NULL; -} - -/* saves the current controls list into the "saver" and replace the one in req with a new one excluding -the "exclude" control */ -/* returns False on error */ -int save_controls(struct ldb_control *exclude, struct ldb_request *req, struct ldb_control ***saver) -{ - struct ldb_control **lcs; - int i, j; - - *saver = req->controls; - for (i = 0; req->controls[i]; i++); - if (i == 1) { - req->controls = NULL; - return 1; - } - - lcs = talloc_array(req, struct ldb_control *, i); - if (!lcs) { - return 0; - } - - for (i = 0, j = 0; (*saver)[i]; i++) { - if (exclude == (*saver)[i]) continue; - lcs[j] = (*saver)[i]; - j++; - } - lcs[j] = NULL; - - req->controls = lcs; - return 1; -} - -/* check if there's any control marked as critical in the list */ -/* return True if any, False if none */ -int check_critical_controls(struct ldb_control **controls) -{ - int i; - - if (controls == NULL) { - return 0; - } - - for (i = 0; controls[i]; i++) { - if (controls[i]->critical) { - return 1; - } - } - - return 0; -} diff --git a/source/lib/ldb/common/ldb_debug.c b/source/lib/ldb/common/ldb_debug.c deleted file mode 100644 index 2548a5495aa..00000000000 --- a/source/lib/ldb/common/ldb_debug.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - * Name: ldb - * - * Component: ldb debug - * - * Description: functions for printing debug messages - * - * Author: Andrew Tridgell - */ - -#include "includes.h" -#include "ldb/include/includes.h" - -/* - this allows the user to choose their own debug function -*/ -int ldb_set_debug(struct ldb_context *ldb, - void (*debug)(void *context, enum ldb_debug_level level, - const char *fmt, va_list ap), - void *context) -{ - ldb->debug_ops.debug = debug; - ldb->debug_ops.context = context; - return 0; -} - -/* - debug function for ldb_set_debug_stderr -*/ -static void ldb_debug_stderr(void *context, enum ldb_debug_level level, - const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0); -static void ldb_debug_stderr(void *context, enum ldb_debug_level level, - const char *fmt, va_list ap) -{ - if (level <= LDB_DEBUG_WARNING) { - vfprintf(stderr, fmt, ap); - } -} - -/* - convenience function to setup debug messages on stderr - messages of level LDB_DEBUG_WARNING and higher are printed -*/ -int ldb_set_debug_stderr(struct ldb_context *ldb) -{ - return ldb_set_debug(ldb, ldb_debug_stderr, ldb); -} - -/* - log a message -*/ -void ldb_debug(struct ldb_context *ldb, enum ldb_debug_level level, const char *fmt, ...) -{ - va_list ap; - if (ldb->debug_ops.debug == NULL) { - ldb_set_debug_stderr(ldb); - } - va_start(ap, fmt); - ldb->debug_ops.debug(ldb->debug_ops.context, level, fmt, ap); - va_end(ap); -} - - -/* - log a message, and set the ldb error string to the same message -*/ -void ldb_debug_set(struct ldb_context *ldb, enum ldb_debug_level level, - const char *fmt, ...) -{ - va_list ap; - char *msg; - va_start(ap, fmt); - msg = talloc_vasprintf(ldb, fmt, ap); - va_end(ap); - if (msg != NULL) { - ldb_set_errstring(ldb, msg); - ldb_debug(ldb, level, "%s", msg); - } - talloc_free(msg); -} - diff --git a/source/lib/ldb/common/ldb_dn.c b/source/lib/ldb/common/ldb_dn.c deleted file mode 100644 index 7a1d8a910b2..00000000000 --- a/source/lib/ldb/common/ldb_dn.c +++ /dev/null @@ -1,1028 +0,0 @@ -/* - ldb database library - - Copyright (C) Simo Sorce 2005 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - * Name: ldb - * - * Component: ldb dn explode and utility functions - * - * Description: - explode a dn into it's own basic elements - * and put them in a structure - * - manipulate ldb_dn structures - * - * Author: Simo Sorce - */ - -#include "includes.h" -#include "ldb/include/includes.h" - -#define LDB_DN_NULL_FAILED(x) if (!(x)) goto failed - -#define LDB_SPECIAL "@SPECIAL" - -/** - internal ldb exploded dn structures -*/ -struct ldb_dn_component { - char *name; - struct ldb_val value; -}; - -struct ldb_dn { - int comp_num; - struct ldb_dn_component *components; -}; - -int ldb_dn_is_special(const struct ldb_dn *dn) -{ - if (dn == NULL || dn->comp_num != 1) return 0; - - return ! strcmp(dn->components[0].name, LDB_SPECIAL); -} - -int ldb_dn_check_special(const struct ldb_dn *dn, const char *check) -{ - if (dn == NULL || dn->comp_num != 1) return 0; - - return ! strcmp((char *)dn->components[0].value.data, check); -} - -char *ldb_dn_escape_value(void *mem_ctx, struct ldb_val value) -{ - const char *p, *s, *src; - char *d, *dst; - int len; - - if (!value.length) - return NULL; - - p = s = src = (const char *)value.data; - len = value.length; - - /* allocate destination string, it will be at most 3 times the source */ - dst = d = talloc_array(mem_ctx, char, len * 3 + 1); - LDB_DN_NULL_FAILED(dst); - - while (p - src < len) { - - p += strcspn(p, ",=\n+<>#;\\\""); - - if (p - src == len) /* found no escapable chars */ - break; - - memcpy(d, s, p - s); /* copy the part of the string before the stop */ - d += (p - s); /* move to current position */ - - if (*p) { /* it is a normal escapable character */ - *d++ = '\\'; - *d++ = *p++; - } else { /* we have a zero byte in the string */ - strncpy(d, "\00", 3); /* escape the zero */ - d = d + 3; - p++; /* skip the zero */ - } - s = p; /* move forward */ - } - - /* copy the last part (with zero) and return */ - memcpy(d, s, &src[len] - s + 1); - - return dst; - -failed: - talloc_free(dst); - return NULL; -} - -static struct ldb_val ldb_dn_unescape_value(void *mem_ctx, const char *src) -{ - struct ldb_val value; - unsigned x; - char *p, *dst = NULL, *end; - - memset(&value, 0, sizeof(value)); - - LDB_DN_NULL_FAILED(src); - - dst = p = (char *)talloc_memdup(mem_ctx, src, strlen(src) + 1); - LDB_DN_NULL_FAILED(dst); - - end = &dst[strlen(dst)]; - - while (*p) { - p += strcspn(p, ",=\n+<>#;\\\""); - - if (*p == '\\') { - if (strchr(",=\n+<>#;\\\"", p[1])) { - memmove(p, p + 1, end - (p + 1) + 1); - end--; - p++; - continue; - } - - if (sscanf(p + 1, "%02x", &x) == 1) { - *p = (unsigned char)x; - memmove(p + 1, p + 3, end - (p + 3) + 1); - end -= 2; - p++; - continue; - } - } - - /* a string with not escaped specials is invalid (tested) */ - if (*p != '\0') { - goto failed; - } - } - - value.length = end - dst; - value.data = (uint8_t *)dst; - return value; - -failed: - talloc_free(dst); - return value; -} - -/* check if the string contains quotes - * skips leading and trailing spaces - * - returns 0 if no quotes found - * - returns 1 if quotes are found and put their position - * in *quote_start and *quote_end parameters - * - return -1 if there are open quotes - */ - -static int get_quotes_position(const char *source, int *quote_start, int *quote_end) -{ - const char *p; - - if (source == NULL || quote_start == NULL || quote_end == NULL) return -1; - - p = source; - - /* check if there are quotes surrounding the value */ - p += strspn(p, " \n"); /* skip white spaces */ - - if (*p == '\"') { - *quote_start = p - source; - - p++; - while (*p != '\"') { - p = strchr(p, '\"'); - LDB_DN_NULL_FAILED(p); - - if (*(p - 1) == '\\') - p++; - } - - *quote_end = p - source; - return 1; - } - - return 0; - -failed: - return -1; -} - -static char *seek_to_separator(char *string, const char *separators) -{ - char *p, *q; - int ret, qs, qe, escaped; - - if (string == NULL || separators == NULL) return NULL; - - p = strchr(string, '='); - LDB_DN_NULL_FAILED(p); - - p++; - - /* check if there are quotes surrounding the value */ - - ret = get_quotes_position(p, &qs, &qe); - if (ret == -1) - return NULL; - - if (ret == 1) { /* quotes found */ - - p += qe; /* positioning after quotes */ - p += strspn(p, " \n"); /* skip white spaces after the quote */ - - if (strcspn(p, separators) != 0) /* if there are characters between quotes */ - return NULL; /* and separators, the dn is invalid */ - - return p; /* return on the separator */ - } - - /* no quotes found seek to separators */ - q = p; - do { - escaped = 0; - ret = strcspn(q, separators); - - if (q[ret - 1] == '\\') { - escaped = 1; - q = q + ret + 1; - } - } while (escaped); - - if (ret == 0 && p == q) /* no separators ?! bail out */ - return NULL; - - return q + ret; - -failed: - return NULL; -} - -static char *ldb_dn_trim_string(char *string, const char *edge) -{ - char *s, *p; - - /* seek out edge from start of string */ - s = string + strspn(string, edge); - - /* backwards skip from end of string */ - p = &s[strlen(s) - 1]; - while (p > s && strchr(edge, *p)) { - *p = '\0'; - p--; - } - - return s; -} - -/* we choosed to not support multpile valued components */ -static struct ldb_dn_component ldb_dn_explode_component(void *mem_ctx, char *raw_component) -{ - struct ldb_dn_component dc; - char *p; - int ret, qs, qe; - - memset(&dc, 0, sizeof(dc)); - - if (raw_component == NULL) { - return dc; - } - - /* find attribute type/value separator */ - p = strchr(raw_component, '='); - LDB_DN_NULL_FAILED(p); - - *p++ = '\0'; /* terminate name and point to value */ - - /* copy and trim name in the component */ - dc.name = talloc_strdup(mem_ctx, ldb_dn_trim_string(raw_component, " \n")); - if (!dc.name) - return dc; - - if (! ldb_valid_attr_name(dc.name)) { - goto failed; - } - - ret = get_quotes_position(p, &qs, &qe); - - switch (ret) { - case 0: /* no quotes trim the string */ - p = ldb_dn_trim_string(p, " \n"); - dc.value = ldb_dn_unescape_value(mem_ctx, p); - break; - - case 1: /* quotes found get the unquoted string */ - p[qe] = '\0'; - p = p + qs + 1; - dc.value.length = strlen(p); - dc.value.data = (uint8_t *)talloc_memdup(mem_ctx, p, - dc.value.length + 1); - break; - - default: /* mismatched quotes ot other error, bail out */ - goto failed; - } - - if (dc.value.length == 0) { - goto failed; - } - - return dc; - -failed: - talloc_free(dc.name); - dc.name = NULL; - return dc; -} - -struct ldb_dn *ldb_dn_new(void *mem_ctx) -{ - struct ldb_dn *edn; - - edn = talloc(mem_ctx, struct ldb_dn); - LDB_DN_NULL_FAILED(edn); - - /* Initially there are no components */ - edn->comp_num = 0; - edn->components = NULL; - - return edn; - -failed: - return NULL; -} - -/* - explode a DN string into a ldb_dn structure -*/ -struct ldb_dn *ldb_dn_explode(void *mem_ctx, const char *dn) -{ - struct ldb_dn *edn; /* the exploded dn */ - char *pdn, *p; - - if (dn == NULL) return NULL; - - /* Allocate a structure to hold the exploded DN */ - edn = ldb_dn_new(mem_ctx); - if (edn == NULL) { - return NULL; - } - - pdn = NULL; - - /* Empty DNs */ - if (dn[0] == '\0') { - return edn; - } - - /* Special DNs case */ - if (dn[0] == '@') { - edn->comp_num = 1; - edn->components = talloc(edn, struct ldb_dn_component); - if (edn->components == NULL) goto failed; - edn->components[0].name = talloc_strdup(edn->components, LDB_SPECIAL); - if (edn->components[0].name == NULL) goto failed; - edn->components[0].value.data = (uint8_t *)talloc_strdup(edn->components, dn); - if (edn->components[0].value.data== NULL) goto failed; - edn->components[0].value.length = strlen(dn); - return edn; - } - - pdn = p = talloc_strdup(edn, dn); - LDB_DN_NULL_FAILED(pdn); - - /* get the components */ - do { - char *t; - - /* terminate the current component and return pointer to the next one */ - t = seek_to_separator(p, ",;"); - LDB_DN_NULL_FAILED(t); - - if (*t) { /* here there is a separator */ - *t = '\0'; /*terminate */ - t++; /* a separtor means another component follows */ - } - - /* allocate space to hold the dn component */ - edn->components = talloc_realloc(edn, edn->components, - struct ldb_dn_component, - edn->comp_num + 1); - if (edn->components == NULL) - goto failed; - - /* store the exploded component in the main structure */ - edn->components[edn->comp_num] = ldb_dn_explode_component(edn, p); - LDB_DN_NULL_FAILED(edn->components[edn->comp_num].name); - - edn->comp_num++; - - /* jump to the next component if any */ - p = t; - - } while(*p); - - talloc_free(pdn); - return edn; - -failed: - talloc_free(pdn); - talloc_free(edn); - return NULL; -} - -struct ldb_dn *ldb_dn_explode_or_special(void *mem_ctx, const char *dn) -{ - struct ldb_dn *edn; /* the exploded dn */ - - if (dn == NULL) return NULL; - - if (strncasecmp(dn, "<GUID=", 6) == 0) { - /* this is special DN returned when the - * exploded_dn control is used - */ - - /* Allocate a structure to hold the exploded DN */ - if (!(edn = ldb_dn_new(mem_ctx))) { - return NULL; - } - - edn->comp_num = 1; - edn->components = talloc(edn, struct ldb_dn_component); - if (edn->components == NULL) goto failed; - edn->components[0].name = talloc_strdup(edn->components, LDB_SPECIAL); - if (edn->components[0].name == NULL) goto failed; - edn->components[0].value.data = (uint8_t *)talloc_strdup(edn->components, dn); - if (edn->components[0].value.data== NULL) goto failed; - edn->components[0].value.length = strlen(dn); - return edn; - - } - - return ldb_dn_explode(mem_ctx, dn); - -failed: - talloc_free(edn); - return NULL; -} - -char *ldb_dn_linearize(void *mem_ctx, const struct ldb_dn *edn) -{ - char *dn, *value; - int i; - - if (edn == NULL) return NULL; - - /* Special DNs */ - if (ldb_dn_is_special(edn)) { - dn = talloc_strdup(mem_ctx, (char *)edn->components[0].value.data); - return dn; - } - - dn = talloc_strdup(mem_ctx, ""); - LDB_DN_NULL_FAILED(dn); - - for (i = 0; i < edn->comp_num; i++) { - value = ldb_dn_escape_value(dn, edn->components[i].value); - LDB_DN_NULL_FAILED(value); - - if (i == 0) { - dn = talloc_asprintf_append(dn, "%s=%s", edn->components[i].name, value); - } else { - dn = talloc_asprintf_append(dn, ",%s=%s", edn->components[i].name, value); - } - LDB_DN_NULL_FAILED(dn); - - talloc_free(value); - } - - return dn; - -failed: - talloc_free(dn); - return NULL; -} - -/* Determine if dn is below base, in the ldap tree. Used for - * evaluating a subtree search. - * 0 if they match, otherwise non-zero - */ - -int ldb_dn_compare_base(struct ldb_context *ldb, - const struct ldb_dn *base, - const struct ldb_dn *dn) -{ - int ret; - int n0, n1; - - if (base == NULL || base->comp_num == 0) return 0; - if (dn == NULL || dn->comp_num == 0) return -1; - - /* if the base has more componts than the dn, then they differ */ - if (base->comp_num > dn->comp_num) { - return (dn->comp_num - base->comp_num); - } - - n0 = base->comp_num - 1; - n1 = dn->comp_num - 1; - while (n0 >= 0 && n1 >= 0) { - const struct ldb_attrib_handler *h; - - /* compare names (attribute names are guaranteed to be ASCII only) */ - ret = ldb_attr_cmp(base->components[n0].name, - dn->components[n1].name); - if (ret) { - return ret; - } - - /* names match, compare values */ - h = ldb_attrib_handler(ldb, base->components[n0].name); - ret = h->comparison_fn(ldb, ldb, &(base->components[n0].value), - &(dn->components[n1].value)); - if (ret) { - return ret; - } - n1--; - n0--; - } - - return 0; -} - -/* compare DNs using casefolding compare functions. - - If they match, then return 0 - */ - -int ldb_dn_compare(struct ldb_context *ldb, - const struct ldb_dn *edn0, - const struct ldb_dn *edn1) -{ - if (edn0 == NULL || edn1 == NULL) return edn1 - edn0; - - if (edn0->comp_num != edn1->comp_num) - return (edn1->comp_num - edn0->comp_num); - - return ldb_dn_compare_base(ldb, edn0, edn1); -} - -int ldb_dn_cmp(struct ldb_context *ldb, const char *dn0, const char *dn1) -{ - struct ldb_dn *edn0; - struct ldb_dn *edn1; - int ret; - - if (dn0 == NULL || dn1 == NULL) return dn1 - dn0; - - edn0 = ldb_dn_explode_casefold(ldb, ldb, dn0); - if (edn0 == NULL) return 1; - - edn1 = ldb_dn_explode_casefold(ldb, ldb, dn1); - if (edn1 == NULL) { - talloc_free(edn0); - return -1; - } - - ret = ldb_dn_compare(ldb, edn0, edn1); - - talloc_free(edn0); - talloc_free(edn1); - - return ret; -} - -/* - casefold a dn. We need to casefold the attribute names, and canonicalize - attribute values of case insensitive attributes. -*/ -struct ldb_dn *ldb_dn_casefold(struct ldb_context *ldb, void *mem_ctx, const struct ldb_dn *edn) -{ - struct ldb_dn *cedn; - int i, ret; - - if (edn == NULL) return NULL; - - cedn = ldb_dn_new(mem_ctx); - if (!cedn) { - return NULL; - } - - cedn->comp_num = edn->comp_num; - cedn->components = talloc_array(cedn, struct ldb_dn_component, edn->comp_num); - if (!cedn->components) { - talloc_free(cedn); - return NULL; - } - - for (i = 0; i < edn->comp_num; i++) { - struct ldb_dn_component dc; - const struct ldb_attrib_handler *h; - - memset(&dc, 0, sizeof(dc)); - dc.name = ldb_attr_casefold(cedn->components, edn->components[i].name); - if (!dc.name) { - talloc_free(cedn); - return NULL; - } - - h = ldb_attrib_handler(ldb, dc.name); - ret = h->canonicalise_fn(ldb, cedn->components, - &(edn->components[i].value), - &(dc.value)); - if (ret != 0) { - talloc_free(cedn); - return NULL; - } - - cedn->components[i] = dc; - } - - return cedn; -} - -struct ldb_dn *ldb_dn_explode_casefold(struct ldb_context *ldb, void *mem_ctx, const char *dn) -{ - struct ldb_dn *edn, *cdn; - - if (dn == NULL) return NULL; - - edn = ldb_dn_explode(ldb, dn); - if (edn == NULL) return NULL; - - cdn = ldb_dn_casefold(ldb, mem_ctx, edn); - - talloc_free(edn); - return cdn; -} - -char *ldb_dn_linearize_casefold(struct ldb_context *ldb, void *mem_ctx, const struct ldb_dn *edn) -{ - struct ldb_dn *cdn; - char *dn; - - if (edn == NULL) return NULL; - - /* Special DNs */ - if (ldb_dn_is_special(edn)) { - dn = talloc_strdup(mem_ctx, (char *)edn->components[0].value.data); - return dn; - } - - cdn = ldb_dn_casefold(ldb, mem_ctx, edn); - if (cdn == NULL) return NULL; - - dn = ldb_dn_linearize(ldb, cdn); - if (dn == NULL) { - talloc_free(cdn); - return NULL; - } - - talloc_free(cdn); - return dn; -} - -static struct ldb_dn_component ldb_dn_copy_component(void *mem_ctx, struct ldb_dn_component *src) -{ - struct ldb_dn_component dst; - - memset(&dst, 0, sizeof(dst)); - - if (src == NULL) { - return dst; - } - - dst.value = ldb_val_dup(mem_ctx, &(src->value)); - if (dst.value.data == NULL) { - return dst; - } - - dst.name = talloc_strdup(mem_ctx, src->name); - if (dst.name == NULL) { - talloc_free(dst.value.data); - dst.value.data = NULL; - } - - return dst; -} - -/* Copy a DN but replace the old with the new base DN. */ -struct ldb_dn *ldb_dn_copy_rebase(void *mem_ctx, const struct ldb_dn *old, const struct ldb_dn *old_base, const struct ldb_dn *new_base) -{ - struct ldb_dn *new_dn; - int i, offset; - - /* Perhaps we don't need to rebase at all? */ - if (!old_base || !new_base) { - return ldb_dn_copy(mem_ctx, old); - } - - offset = old->comp_num - old_base->comp_num; - if (!(new_dn = ldb_dn_copy_partial(mem_ctx, new_base, - offset + new_base->comp_num))) { - return NULL; - } - for (i = 0; i < offset; i++) { - new_dn->components[i] = ldb_dn_copy_component(new_dn->components, &(old->components[i])); - } - - return new_dn; -} - -/* copy specified number of elements of a dn into a new one - element are copied from top level up to the unique rdn - num_el may be greater than dn->comp_num (see ldb_dn_make_child) -*/ -struct ldb_dn *ldb_dn_copy_partial(void *mem_ctx, const struct ldb_dn *dn, int num_el) -{ - struct ldb_dn *newdn; - int i, n, e; - - if (dn == NULL) return NULL; - if (num_el <= 0) return NULL; - - newdn = ldb_dn_new(mem_ctx); - LDB_DN_NULL_FAILED(newdn); - - newdn->comp_num = num_el; - n = newdn->comp_num - 1; - newdn->components = talloc_array(newdn, struct ldb_dn_component, newdn->comp_num); - if (newdn->components == NULL) goto failed; - - if (dn->comp_num == 0) return newdn; - e = dn->comp_num - 1; - - for (i = 0; i < newdn->comp_num; i++) { - newdn->components[n - i] = ldb_dn_copy_component(newdn->components, - &(dn->components[e - i])); - if ((e - i) == 0) { - return newdn; - } - } - - return newdn; - -failed: - talloc_free(newdn); - return NULL; -} - -struct ldb_dn *ldb_dn_copy(void *mem_ctx, const struct ldb_dn *dn) -{ - if (dn == NULL) return NULL; - return ldb_dn_copy_partial(mem_ctx, dn, dn->comp_num); -} - -struct ldb_dn *ldb_dn_get_parent(void *mem_ctx, const struct ldb_dn *dn) -{ - if (dn == NULL) return NULL; - return ldb_dn_copy_partial(mem_ctx, dn, dn->comp_num - 1); -} - -struct ldb_dn_component *ldb_dn_build_component(void *mem_ctx, const char *attr, - const char *val) -{ - struct ldb_dn_component *dc; - - if (attr == NULL || val == NULL) return NULL; - - dc = talloc(mem_ctx, struct ldb_dn_component); - if (dc == NULL) return NULL; - - dc->name = talloc_strdup(dc, attr); - if (dc->name == NULL) { - talloc_free(dc); - return NULL; - } - - dc->value.data = (uint8_t *)talloc_strdup(dc, val); - if (dc->value.data == NULL) { - talloc_free(dc); - return NULL; - } - - dc->value.length = strlen(val); - - return dc; -} - -struct ldb_dn *ldb_dn_build_child(void *mem_ctx, const char *attr, - const char * value, - const struct ldb_dn *base) -{ - struct ldb_dn *newdn; - if (! ldb_valid_attr_name(attr)) return NULL; - if (value == NULL || value == '\0') return NULL; - - if (base != NULL) { - newdn = ldb_dn_copy_partial(mem_ctx, base, base->comp_num + 1); - LDB_DN_NULL_FAILED(newdn); - } else { - newdn = ldb_dn_new(mem_ctx); - LDB_DN_NULL_FAILED(newdn); - - newdn->comp_num = 1; - newdn->components = talloc_array(newdn, struct ldb_dn_component, newdn->comp_num); - LDB_DN_NULL_FAILED(newdn->components); - } - - newdn->components[0].name = talloc_strdup(newdn->components, attr); - LDB_DN_NULL_FAILED(newdn->components[0].name); - - newdn->components[0].value.data = (uint8_t *)talloc_strdup(newdn->components, value); - LDB_DN_NULL_FAILED(newdn->components[0].value.data); - newdn->components[0].value.length = strlen((char *)newdn->components[0].value.data); - - return newdn; - -failed: - talloc_free(newdn); - return NULL; - -} - -struct ldb_dn *ldb_dn_compose(void *mem_ctx, const struct ldb_dn *dn1, const struct ldb_dn *dn2) -{ - int i; - struct ldb_dn *newdn; - - if (dn2 == NULL && dn1 == NULL) { - return NULL; - } - - if (dn2 == NULL) { - newdn = ldb_dn_new(mem_ctx); - LDB_DN_NULL_FAILED(newdn); - - newdn->comp_num = dn1->comp_num; - newdn->components = talloc_array(newdn, struct ldb_dn_component, newdn->comp_num); - LDB_DN_NULL_FAILED(newdn->components); - } else { - int comp_num = dn2->comp_num; - if (dn1 != NULL) comp_num += dn1->comp_num; - newdn = ldb_dn_copy_partial(mem_ctx, dn2, comp_num); - LDB_DN_NULL_FAILED(newdn); - } - - if (dn1 == NULL) { - return newdn; - } - - for (i = 0; i < dn1->comp_num; i++) { - newdn->components[i] = ldb_dn_copy_component(newdn->components, - &(dn1->components[i])); - if (newdn->components[i].value.data == NULL) { - goto failed; - } - } - - return newdn; - -failed: - talloc_free(newdn); - return NULL; -} - -struct ldb_dn *ldb_dn_string_compose(void *mem_ctx, const struct ldb_dn *base, const char *child_fmt, ...) -{ - struct ldb_dn *dn, *dn1; - char *child_str; - va_list ap; - - if (child_fmt == NULL) return NULL; - - va_start(ap, child_fmt); - child_str = talloc_vasprintf(mem_ctx, child_fmt, ap); - va_end(ap); - - if (child_str == NULL) return NULL; - - dn1 = ldb_dn_explode(mem_ctx, child_str); - dn = ldb_dn_compose(mem_ctx, dn1, base); - - talloc_free(child_str); - talloc_free(dn1); - - return dn; -} - -/* Create a 'canonical name' string from a DN: - - ie dc=samba,dc=org -> samba.org/ - uid=administrator,ou=users,dc=samba,dc=org = samba.org/users/administrator - - There are two formats, the EX format has the last / replaced with a newline (\n). - -*/ -static char *ldb_dn_canonical(void *mem_ctx, const struct ldb_dn *dn, int ex_format) { - int i; - char *cracked = NULL; - - /* Walk backwards down the DN, grabbing 'dc' components at first */ - for (i = dn->comp_num - 1 ; i >= 0; i--) { - if (ldb_attr_cmp(dn->components[i].name, "dc") != 0) { - break; - } - if (cracked) { - cracked = talloc_asprintf(mem_ctx, "%s.%s", - ldb_dn_escape_value(mem_ctx, dn->components[i].value), - cracked); - } else { - cracked = ldb_dn_escape_value(mem_ctx, dn->components[i].value); - } - if (!cracked) { - return NULL; - } - } - - /* Only domain components? Finish here */ - if (i < 0) { - if (ex_format) { - cracked = talloc_asprintf(mem_ctx, "%s\n", cracked); - } else { - cracked = talloc_asprintf(mem_ctx, "%s/", cracked); - } - return cracked; - } - - /* Now walk backwards appending remaining components */ - for (; i > 0; i--) { - cracked = talloc_asprintf(mem_ctx, "%s/%s", cracked, - ldb_dn_escape_value(mem_ctx, dn->components[i].value)); - if (!cracked) { - return NULL; - } - } - - /* Last one, possibly a newline for the 'ex' format */ - if (ex_format) { - cracked = talloc_asprintf(mem_ctx, "%s\n%s", cracked, - ldb_dn_escape_value(mem_ctx, dn->components[i].value)); - } else { - cracked = talloc_asprintf(mem_ctx, "%s/%s", cracked, - ldb_dn_escape_value(mem_ctx, dn->components[i].value)); - } - return cracked; -} - -/* Wrapper functions for the above, for the two different string formats */ -char *ldb_dn_canonical_string(void *mem_ctx, const struct ldb_dn *dn) { - return ldb_dn_canonical(mem_ctx, dn, 0); - -} - -char *ldb_dn_canonical_ex_string(void *mem_ctx, const struct ldb_dn *dn) { - return ldb_dn_canonical(mem_ctx, dn, 1); -} - -int ldb_dn_get_comp_num(const struct ldb_dn *dn) -{ - return dn->comp_num; -} - -const char *ldb_dn_get_component_name(const struct ldb_dn *dn, unsigned int num) -{ - if (num >= dn->comp_num) return NULL; - return dn->components[num].name; -} - -const struct ldb_val *ldb_dn_get_component_val(const struct ldb_dn *dn, unsigned int num) -{ - if (num >= dn->comp_num) return NULL; - return &dn->components[num].value; -} - -const char *ldb_dn_get_rdn_name(const struct ldb_dn *dn) { - if (dn->comp_num == 0) return NULL; - return dn->components[0].name; -} - -const struct ldb_val *ldb_dn_get_rdn_val(const struct ldb_dn *dn) { - if (dn->comp_num == 0) return NULL; - return &dn->components[0].value; -} - -int ldb_dn_set_component(struct ldb_dn *dn, int num, const char *name, const struct ldb_val val) -{ - char *n; - struct ldb_val v; - - if (num >= dn->comp_num) { - return LDB_ERR_OTHER; - } - - n = talloc_strdup(dn, name); - if ( ! n) { - return LDB_ERR_OTHER; - } - - v.length = val.length; - v.data = (uint8_t *)talloc_memdup(dn, val.data, v.length+1); - if ( ! v.data) { - return LDB_ERR_OTHER; - } - - talloc_free(dn->components[num].name); - talloc_free(dn->components[num].value.data); - dn->components[num].name = n; - dn->components[num].value = v; - - return LDB_SUCCESS; -} diff --git a/source/lib/ldb/common/ldb_ldif.c b/source/lib/ldb/common/ldb_ldif.c deleted file mode 100644 index 135ce9eecd9..00000000000 --- a/source/lib/ldb/common/ldb_ldif.c +++ /dev/null @@ -1,761 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - * Name: ldb - * - * Component: ldif routines - * - * Description: ldif pack/unpack routines - * - * Author: Andrew Tridgell - */ - -/* - see RFC2849 for the LDIF format definition -*/ - -#include "includes.h" -#include "ldb/include/includes.h" -#include "system/locale.h" - -/* - -*/ -static int ldb_read_data_file(void *mem_ctx, struct ldb_val *value) -{ - struct stat statbuf; - char *buf; - int count, size, bytes; - int ret; - int f; - const char *fname = (const char *)value->data; - - if (strncmp(fname, "file://", 7) != 0) { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - fname += 7; - - f = open(fname, O_RDONLY); - if (f == -1) { - return -1; - } - - if (fstat(f, &statbuf) != 0) { - ret = -1; - goto done; - } - - if (statbuf.st_size == 0) { - ret = -1; - goto done; - } - - value->data = (uint8_t *)talloc_size(mem_ctx, statbuf.st_size + 1); - if (value->data == NULL) { - ret = -1; - goto done; - } - value->data[statbuf.st_size] = 0; - - count = 0; - size = statbuf.st_size; - buf = (char *)value->data; - while (count < statbuf.st_size) { - bytes = read(f, buf, size); - if (bytes == -1) { - talloc_free(value->data); - ret = -1; - goto done; - } - count += bytes; - buf += bytes; - size -= bytes; - } - - value->length = statbuf.st_size; - ret = statbuf.st_size; - -done: - close(f); - return ret; -} - -/* - this base64 decoder was taken from jitterbug (written by tridge). - we might need to replace it with a new version -*/ -int ldb_base64_decode(char *s) -{ - const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - int bit_offset=0, byte_offset, idx, i, n; - uint8_t *d = (uint8_t *)s; - char *p=NULL; - - n=i=0; - - while (*s && (p=strchr(b64,*s))) { - idx = (int)(p - b64); - byte_offset = (i*6)/8; - bit_offset = (i*6)%8; - d[byte_offset] &= ~((1<<(8-bit_offset))-1); - if (bit_offset < 3) { - d[byte_offset] |= (idx << (2-bit_offset)); - n = byte_offset+1; - } else { - d[byte_offset] |= (idx >> (bit_offset-2)); - d[byte_offset+1] = 0; - d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF; - n = byte_offset+2; - } - s++; i++; - } - if (bit_offset >= 3) { - n--; - } - - if (*s && !p) { - /* the only termination allowed */ - if (*s != '=') { - return -1; - } - } - - /* null terminate */ - d[n] = 0; - return n; -} - - -/* - encode as base64 - caller frees -*/ -char *ldb_base64_encode(void *mem_ctx, const char *buf, int len) -{ - const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - int bit_offset, byte_offset, idx, i; - const uint8_t *d = (const uint8_t *)buf; - int bytes = (len*8 + 5)/6, pad_bytes = (bytes % 4) ? 4 - (bytes % 4) : 0; - char *out; - - out = talloc_array(mem_ctx, char, bytes+pad_bytes+1); - if (!out) return NULL; - - for (i=0;i<bytes;i++) { - byte_offset = (i*6)/8; - bit_offset = (i*6)%8; - if (bit_offset < 3) { - idx = (d[byte_offset] >> (2-bit_offset)) & 0x3F; - } else { - idx = (d[byte_offset] << (bit_offset-2)) & 0x3F; - if (byte_offset+1 < len) { - idx |= (d[byte_offset+1] >> (8-(bit_offset-2))); - } - } - out[i] = b64[idx]; - } - - for (;i<bytes+pad_bytes;i++) - out[i] = '='; - out[i] = 0; - - return out; -} - -/* - see if a buffer should be base64 encoded -*/ -int ldb_should_b64_encode(const struct ldb_val *val) -{ - unsigned int i; - uint8_t *p = val->data; - - if (val->length == 0) { - return 0; - } - - if (p[0] == ' ' || p[0] == ':') { - return 1; - } - - for (i=0; i<val->length; i++) { - if (!isprint(p[i]) || p[i] == '\n') { - return 1; - } - } - return 0; -} - -/* this macro is used to handle the return checking on fprintf_fn() */ -#define CHECK_RET do { if (ret < 0) return ret; total += ret; } while (0) - -/* - write a line folded string onto a file -*/ -static int fold_string(int (*fprintf_fn)(void *, const char *, ...), void *private_data, - const char *buf, size_t length, int start_pos) -{ - unsigned int i; - int total=0, ret; - - for (i=0;i<length;i++) { - ret = fprintf_fn(private_data, "%c", buf[i]); - CHECK_RET; - if (i != (length-1) && (i + start_pos) % 77 == 0) { - ret = fprintf_fn(private_data, "\n "); - CHECK_RET; - } - } - - return total; -} - -#undef CHECK_RET - -/* - encode as base64 to a file -*/ -static int base64_encode_f(struct ldb_context *ldb, - int (*fprintf_fn)(void *, const char *, ...), - void *private_data, - const char *buf, int len, int start_pos) -{ - char *b = ldb_base64_encode(ldb, buf, len); - int ret; - - if (!b) { - return -1; - } - - ret = fold_string(fprintf_fn, private_data, b, strlen(b), start_pos); - - talloc_free(b); - return ret; -} - - -static const struct { - const char *name; - enum ldb_changetype changetype; -} ldb_changetypes[] = { - {"add", LDB_CHANGETYPE_ADD}, - {"delete", LDB_CHANGETYPE_DELETE}, - {"modify", LDB_CHANGETYPE_MODIFY}, - {NULL, 0} -}; - -/* this macro is used to handle the return checking on fprintf_fn() */ -#define CHECK_RET do { if (ret < 0) { talloc_free(mem_ctx); return ret; } total += ret; } while (0) - -/* - write to ldif, using a caller supplied write method -*/ -int ldb_ldif_write(struct ldb_context *ldb, - int (*fprintf_fn)(void *, const char *, ...), - void *private_data, - const struct ldb_ldif *ldif) -{ - TALLOC_CTX *mem_ctx; - unsigned int i, j; - int total=0, ret; - const struct ldb_message *msg; - - mem_ctx = talloc_named_const(NULL, 0, "ldb_ldif_write"); - - msg = ldif->msg; - - ret = fprintf_fn(private_data, "dn: %s\n", ldb_dn_linearize(msg->dn, msg->dn)); - CHECK_RET; - - if (ldif->changetype != LDB_CHANGETYPE_NONE) { - for (i=0;ldb_changetypes[i].name;i++) { - if (ldb_changetypes[i].changetype == ldif->changetype) { - break; - } - } - if (!ldb_changetypes[i].name) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: Invalid ldif changetype %d\n", - ldif->changetype); - talloc_free(mem_ctx); - return -1; - } - ret = fprintf_fn(private_data, "changetype: %s\n", ldb_changetypes[i].name); - CHECK_RET; - } - - for (i=0;i<msg->num_elements;i++) { - const struct ldb_attrib_handler *h; - - h = ldb_attrib_handler(ldb, msg->elements[i].name); - - if (ldif->changetype == LDB_CHANGETYPE_MODIFY) { - switch (msg->elements[i].flags & LDB_FLAG_MOD_MASK) { - case LDB_FLAG_MOD_ADD: - fprintf_fn(private_data, "add: %s\n", - msg->elements[i].name); - break; - case LDB_FLAG_MOD_DELETE: - fprintf_fn(private_data, "delete: %s\n", - msg->elements[i].name); - break; - case LDB_FLAG_MOD_REPLACE: - fprintf_fn(private_data, "replace: %s\n", - msg->elements[i].name); - break; - } - } - - for (j=0;j<msg->elements[i].num_values;j++) { - struct ldb_val v; - ret = h->ldif_write_fn(ldb, mem_ctx, &msg->elements[i].values[j], &v); - CHECK_RET; - if (ldb_should_b64_encode(&v)) { - ret = fprintf_fn(private_data, "%s:: ", - msg->elements[i].name); - CHECK_RET; - ret = base64_encode_f(ldb, fprintf_fn, private_data, - (char *)v.data, v.length, - strlen(msg->elements[i].name)+3); - CHECK_RET; - ret = fprintf_fn(private_data, "\n"); - CHECK_RET; - } else { - ret = fprintf_fn(private_data, "%s: ", msg->elements[i].name); - CHECK_RET; - ret = fold_string(fprintf_fn, private_data, - (char *)v.data, v.length, - strlen(msg->elements[i].name)+2); - CHECK_RET; - ret = fprintf_fn(private_data, "\n"); - CHECK_RET; - } - if (v.data != msg->elements[i].values[j].data) { - talloc_free(v.data); - } - } - if (ldif->changetype == LDB_CHANGETYPE_MODIFY) { - fprintf_fn(private_data, "-\n"); - } - } - ret = fprintf_fn(private_data,"\n"); - CHECK_RET; - - return total; -} - -#undef CHECK_RET - - -/* - pull a ldif chunk, which is defined as a piece of data ending in \n\n or EOF - this routine removes any RFC2849 continuations and comments - - caller frees -*/ -static char *next_chunk(struct ldb_context *ldb, - int (*fgetc_fn)(void *), void *private_data) -{ - size_t alloc_size=0, chunk_size = 0; - char *chunk = NULL; - int c; - int in_comment = 0; - - while ((c = fgetc_fn(private_data)) != EOF) { - if (chunk_size+1 >= alloc_size) { - char *c2; - alloc_size += 1024; - c2 = talloc_realloc(ldb, chunk, char, alloc_size); - if (!c2) { - talloc_free(chunk); - errno = ENOMEM; - return NULL; - } - chunk = c2; - } - - if (in_comment) { - if (c == '\n') { - in_comment = 0; - } - continue; - } - - /* handle continuation lines - see RFC2849 */ - if (c == ' ' && chunk_size > 1 && chunk[chunk_size-1] == '\n') { - chunk_size--; - continue; - } - - /* chunks are terminated by a double line-feed */ - if (c == '\n' && chunk_size > 0 && chunk[chunk_size-1] == '\n') { - chunk[chunk_size-1] = 0; - return chunk; - } - - if (c == '#' && (chunk_size == 0 || chunk[chunk_size-1] == '\n')) { - in_comment = 1; - continue; - } - - /* ignore leading blank lines */ - if (chunk_size == 0 && c == '\n') { - continue; - } - - chunk[chunk_size++] = c; - } - - if (chunk) { - chunk[chunk_size] = 0; - } - - return chunk; -} - - -/* simple ldif attribute parser */ -static int next_attr(void *mem_ctx, char **s, const char **attr, struct ldb_val *value) -{ - char *p; - int base64_encoded = 0; - int binary_file = 0; - - if (strncmp(*s, "-\n", 2) == 0) { - value->length = 0; - *attr = "-"; - *s += 2; - return 0; - } - - p = strchr(*s, ':'); - if (!p) { - return -1; - } - - *p++ = 0; - - if (*p == ':') { - base64_encoded = 1; - p++; - } - - if (*p == '<') { - binary_file = 1; - p++; - } - - *attr = *s; - - while (*p == ' ' || *p == '\t') { - p++; - } - - value->data = (uint8_t *)p; - - p = strchr(p, '\n'); - - if (!p) { - value->length = strlen((char *)value->data); - *s = ((char *)value->data) + value->length; - } else { - value->length = p - (char *)value->data; - *s = p+1; - *p = 0; - } - - if (base64_encoded) { - int len = ldb_base64_decode((char *)value->data); - if (len == -1) { - /* it wasn't valid base64 data */ - return -1; - } - value->length = len; - } - - if (binary_file) { - int len = ldb_read_data_file(mem_ctx, value); - if (len == -1) { - /* an error occured hile trying to retrieve the file */ - return -1; - } - } - - return 0; -} - - -/* - free a message from a ldif_read -*/ -void ldb_ldif_read_free(struct ldb_context *ldb, struct ldb_ldif *ldif) -{ - talloc_free(ldif); -} - -/* - read from a LDIF source, creating a ldb_message -*/ -struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb, - int (*fgetc_fn)(void *), void *private_data) -{ - struct ldb_ldif *ldif; - struct ldb_message *msg; - const char *attr=NULL; - char *chunk=NULL, *s; - struct ldb_val value; - unsigned flags = 0; - - value.data = NULL; - - ldif = talloc(ldb, struct ldb_ldif); - if (!ldif) return NULL; - - ldif->msg = talloc(ldif, struct ldb_message); - if (ldif->msg == NULL) { - talloc_free(ldif); - return NULL; - } - - ldif->changetype = LDB_CHANGETYPE_NONE; - msg = ldif->msg; - - msg->dn = NULL; - msg->elements = NULL; - msg->num_elements = 0; - msg->private_data = NULL; - - chunk = next_chunk(ldb, fgetc_fn, private_data); - if (!chunk) { - goto failed; - } - talloc_steal(ldif, chunk); - - msg->private_data = chunk; - s = chunk; - - if (next_attr(ldif, &s, &attr, &value) != 0) { - goto failed; - } - - /* first line must be a dn */ - if (ldb_attr_cmp(attr, "dn") != 0) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: First line of ldif must be a dn not '%s'\n", - attr); - goto failed; - } - - msg->dn = ldb_dn_explode(msg, (char *)value.data); - - if (msg->dn == NULL) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: Unable to parse dn '%s'\n", - value.data); - goto failed; - } - - while (next_attr(ldif, &s, &attr, &value) == 0) { - const struct ldb_attrib_handler *h; - struct ldb_message_element *el; - int ret, empty = 0; - - if (ldb_attr_cmp(attr, "changetype") == 0) { - int i; - for (i=0;ldb_changetypes[i].name;i++) { - if (ldb_attr_cmp((char *)value.data, ldb_changetypes[i].name) == 0) { - ldif->changetype = ldb_changetypes[i].changetype; - break; - } - } - if (!ldb_changetypes[i].name) { - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Error: Bad ldif changetype '%s'\n",(char *)value.data); - } - flags = 0; - continue; - } - - if (ldb_attr_cmp(attr, "add") == 0) { - flags = LDB_FLAG_MOD_ADD; - empty = 1; - } - if (ldb_attr_cmp(attr, "delete") == 0) { - flags = LDB_FLAG_MOD_DELETE; - empty = 1; - } - if (ldb_attr_cmp(attr, "replace") == 0) { - flags = LDB_FLAG_MOD_REPLACE; - empty = 1; - } - if (ldb_attr_cmp(attr, "-") == 0) { - flags = 0; - continue; - } - - if (empty) { - if (ldb_msg_add_empty(msg, (char *)value.data, flags, NULL) != 0) { - goto failed; - } - continue; - } - - el = &msg->elements[msg->num_elements-1]; - - h = ldb_attrib_handler(ldb, attr); - - if (msg->num_elements > 0 && ldb_attr_cmp(attr, el->name) == 0 && - flags == el->flags) { - /* its a continuation */ - el->values = - talloc_realloc(msg->elements, el->values, - struct ldb_val, el->num_values+1); - if (!el->values) { - goto failed; - } - ret = h->ldif_read_fn(ldb, ldif, &value, &el->values[el->num_values]); - if (ret != 0) { - goto failed; - } - if (value.length == 0) { - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Error: Attribute value cannot be empty for attribute '%s'\n", el->name); - goto failed; - } - if (value.data != el->values[el->num_values].data) { - talloc_steal(el->values, el->values[el->num_values].data); - } - el->num_values++; - } else { - /* its a new attribute */ - msg->elements = talloc_realloc(ldif, msg->elements, - struct ldb_message_element, - msg->num_elements+1); - if (!msg->elements) { - goto failed; - } - el = &msg->elements[msg->num_elements]; - el->flags = flags; - el->name = talloc_strdup(msg->elements, attr); - el->values = talloc(msg->elements, struct ldb_val); - if (!el->values || !el->name) { - goto failed; - } - el->num_values = 1; - ret = h->ldif_read_fn(ldb, ldif, &value, &el->values[0]); - if (ret != 0) { - goto failed; - } - if (value.data != el->values[0].data) { - talloc_steal(el->values, el->values[0].data); - } - msg->num_elements++; - } - } - - return ldif; - -failed: - talloc_free(ldif); - return NULL; -} - - - -/* - a wrapper around ldif_read() for reading from FILE* -*/ -struct ldif_read_file_state { - FILE *f; -}; - -static int fgetc_file(void *private_data) -{ - struct ldif_read_file_state *state = - (struct ldif_read_file_state *)private_data; - return fgetc(state->f); -} - -struct ldb_ldif *ldb_ldif_read_file(struct ldb_context *ldb, FILE *f) -{ - struct ldif_read_file_state state; - state.f = f; - return ldb_ldif_read(ldb, fgetc_file, &state); -} - - -/* - a wrapper around ldif_read() for reading from const char* -*/ -struct ldif_read_string_state { - const char *s; -}; - -static int fgetc_string(void *private_data) -{ - struct ldif_read_string_state *state = - (struct ldif_read_string_state *)private_data; - if (state->s[0] != 0) { - return *state->s++; - } - return EOF; -} - -struct ldb_ldif *ldb_ldif_read_string(struct ldb_context *ldb, const char **s) -{ - struct ldif_read_string_state state; - struct ldb_ldif *ldif; - state.s = *s; - ldif = ldb_ldif_read(ldb, fgetc_string, &state); - *s = state.s; - return ldif; -} - - -/* - wrapper around ldif_write() for a file -*/ -struct ldif_write_file_state { - FILE *f; -}; - -static int fprintf_file(void *private_data, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3); - -static int fprintf_file(void *private_data, const char *fmt, ...) -{ - struct ldif_write_file_state *state = - (struct ldif_write_file_state *)private_data; - int ret; - va_list ap; - - va_start(ap, fmt); - ret = vfprintf(state->f, fmt, ap); - va_end(ap); - return ret; -} - -int ldb_ldif_write_file(struct ldb_context *ldb, FILE *f, const struct ldb_ldif *ldif) -{ - struct ldif_write_file_state state; - state.f = f; - return ldb_ldif_write(ldb, fprintf_file, &state, ldif); -} diff --git a/source/lib/ldb/common/ldb_match.c b/source/lib/ldb/common/ldb_match.c deleted file mode 100644 index 0cd220ad607..00000000000 --- a/source/lib/ldb/common/ldb_match.c +++ /dev/null @@ -1,431 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004-2005 - Copyright (C) Simo Sorce 2005 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - * Name: ldb - * - * Component: ldb expression matching - * - * Description: ldb expression matching - * - * Author: Andrew Tridgell - */ - -#include "includes.h" -#include "ldb/include/includes.h" - -/* - check if the scope matches in a search result -*/ -static int ldb_match_scope(struct ldb_context *ldb, - const struct ldb_dn *base, - const struct ldb_dn *dn, - enum ldb_scope scope) -{ - int ret = 0; - - if (base == NULL || dn == NULL) { - return 1; - } - - switch (scope) { - case LDB_SCOPE_BASE: - if (ldb_dn_compare(ldb, base, dn) == 0) { - ret = 1; - } - break; - - case LDB_SCOPE_ONELEVEL: - if (ldb_dn_get_comp_num(dn) == (ldb_dn_get_comp_num(base) + 1)) { - if (ldb_dn_compare_base(ldb, base, dn) == 0) { - ret = 1; - } - } - break; - - case LDB_SCOPE_SUBTREE: - default: - if (ldb_dn_compare_base(ldb, base, dn) == 0) { - ret = 1; - } - break; - } - - return ret; -} - - -/* - match if node is present -*/ -static int ldb_match_present(struct ldb_context *ldb, - const struct ldb_message *msg, - const struct ldb_parse_tree *tree, - enum ldb_scope scope) -{ - if (ldb_attr_dn(tree->u.present.attr) == 0) { - return 1; - } - - if (ldb_msg_find_element(msg, tree->u.present.attr)) { - return 1; - } - - return 0; -} - -static int ldb_match_comparison(struct ldb_context *ldb, - const struct ldb_message *msg, - const struct ldb_parse_tree *tree, - enum ldb_scope scope, - enum ldb_parse_op comp_op) -{ - unsigned int i; - struct ldb_message_element *el; - const struct ldb_attrib_handler *h; - int ret; - - /* FIXME: APPROX comparison not handled yet */ - if (comp_op == LDB_OP_APPROX) return 0; - - el = ldb_msg_find_element(msg, tree->u.comparison.attr); - if (el == NULL) { - return 0; - } - - h = ldb_attrib_handler(ldb, el->name); - - for (i = 0; i < el->num_values; i++) { - ret = h->comparison_fn(ldb, ldb, &el->values[i], &tree->u.comparison.value); - - if (ret == 0) { - return 1; - } - if (ret > 0 && comp_op == LDB_OP_GREATER) { - return 1; - } - if (ret < 0 && comp_op == LDB_OP_LESS) { - return 1; - } - } - - return 0; -} - -/* - match a simple leaf node -*/ -static int ldb_match_equality(struct ldb_context *ldb, - const struct ldb_message *msg, - const struct ldb_parse_tree *tree, - enum ldb_scope scope) -{ - unsigned int i; - struct ldb_message_element *el; - const struct ldb_attrib_handler *h; - struct ldb_dn *valuedn; - int ret; - - if (ldb_attr_dn(tree->u.equality.attr) == 0) { - valuedn = ldb_dn_explode_casefold(ldb, ldb, - (char *)tree->u.equality.value.data); - if (valuedn == NULL) { - return 0; - } - - ret = ldb_dn_compare(ldb, msg->dn, valuedn); - - talloc_free(valuedn); - - if (ret == 0) return 1; - return 0; - } - - /* TODO: handle the "*" case derived from an extended search - operation without the attibute type defined */ - el = ldb_msg_find_element(msg, tree->u.equality.attr); - if (el == NULL) { - return 0; - } - - h = ldb_attrib_handler(ldb, el->name); - - for (i=0;i<el->num_values;i++) { - if (h->comparison_fn(ldb, ldb, &tree->u.equality.value, - &el->values[i]) == 0) { - return 1; - } - } - - return 0; -} - -static int ldb_wildcard_compare(struct ldb_context *ldb, - const struct ldb_parse_tree *tree, - const struct ldb_val value) -{ - const struct ldb_attrib_handler *h; - struct ldb_val val; - struct ldb_val cnk; - struct ldb_val *chunk; - char *p, *g; - uint8_t *save_p = NULL; - int c = 0; - - h = ldb_attrib_handler(ldb, tree->u.substring.attr); - - if(h->canonicalise_fn(ldb, ldb, &value, &val) != 0) - return -1; - - save_p = val.data; - cnk.data = NULL; - - if ( ! tree->u.substring.start_with_wildcard ) { - - chunk = tree->u.substring.chunks[c]; - if(h->canonicalise_fn(ldb, ldb, chunk, &cnk) != 0) goto failed; - - /* This deals with wildcard prefix searches on binary attributes (eg objectGUID) */ - if (cnk.length > val.length) { - goto failed; - } - if (memcmp((char *)val.data, (char *)cnk.data, cnk.length) != 0) goto failed; - val.length -= cnk.length; - val.data += cnk.length; - c++; - talloc_free(cnk.data); - cnk.data = NULL; - } - - while (tree->u.substring.chunks[c]) { - - chunk = tree->u.substring.chunks[c]; - if(h->canonicalise_fn(ldb, ldb, chunk, &cnk) != 0) goto failed; - - /* FIXME: case of embedded nulls */ - p = strstr((char *)val.data, (char *)cnk.data); - if (p == NULL) goto failed; - if ( (! tree->u.substring.chunks[c + 1]) && (! tree->u.substring.end_with_wildcard) ) { - do { /* greedy */ - g = strstr((char *)p + cnk.length, (char *)cnk.data); - if (g) p = g; - } while(g); - } - val.length = val.length - (p - (char *)(val.data)) - cnk.length; - val.data = (uint8_t *)(p + cnk.length); - c++; - talloc_free(cnk.data); - cnk.data = NULL; - } - - if ( (! tree->u.substring.end_with_wildcard) && (*(val.data) != 0) ) goto failed; /* last chunk have not reached end of string */ - talloc_free(save_p); - return 1; - -failed: - talloc_free(save_p); - talloc_free(cnk.data); - return 0; -} - -/* - match a simple leaf node -*/ -static int ldb_match_substring(struct ldb_context *ldb, - const struct ldb_message *msg, - const struct ldb_parse_tree *tree, - enum ldb_scope scope) -{ - unsigned int i; - struct ldb_message_element *el; - - el = ldb_msg_find_element(msg, tree->u.substring.attr); - if (el == NULL) { - return 0; - } - - for (i = 0; i < el->num_values; i++) { - if (ldb_wildcard_compare(ldb, tree, el->values[i]) == 1) { - return 1; - } - } - - return 0; -} - - -/* - bitwise-and comparator -*/ -static int ldb_comparator_and(const struct ldb_val *v1, const struct ldb_val *v2) -{ - uint64_t i1, i2; - i1 = strtoull((char *)v1->data, NULL, 0); - i2 = strtoull((char *)v2->data, NULL, 0); - return ((i1 & i2) == i2); -} - -/* - bitwise-or comparator -*/ -static int ldb_comparator_or(const struct ldb_val *v1, const struct ldb_val *v2) -{ - uint64_t i1, i2; - i1 = strtoull((char *)v1->data, NULL, 0); - i2 = strtoull((char *)v2->data, NULL, 0); - return ((i1 & i2) != 0); -} - - -/* - extended match, handles things like bitops -*/ -static int ldb_match_extended(struct ldb_context *ldb, - const struct ldb_message *msg, - const struct ldb_parse_tree *tree, - enum ldb_scope scope) -{ - int i; - const struct { - const char *oid; - int (*comparator)(const struct ldb_val *, const struct ldb_val *); - } rules[] = { - { LDB_OID_COMPARATOR_AND, ldb_comparator_and}, - { LDB_OID_COMPARATOR_OR, ldb_comparator_or} - }; - int (*comp)(const struct ldb_val *, const struct ldb_val *) = NULL; - struct ldb_message_element *el; - - if (tree->u.extended.dnAttributes) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb: dnAttributes extended match not supported yet"); - return -1; - } - if (tree->u.extended.rule_id == NULL) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb: no-rule extended matches not supported yet"); - return -1; - } - if (tree->u.extended.attr == NULL) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb: no-attribute extended matches not supported yet"); - return -1; - } - - for (i=0;i<ARRAY_SIZE(rules);i++) { - if (strcmp(rules[i].oid, tree->u.extended.rule_id) == 0) { - comp = rules[i].comparator; - break; - } - } - if (comp == NULL) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb: unknown extended rule_id %s\n", - tree->u.extended.rule_id); - return -1; - } - - /* find the message element */ - el = ldb_msg_find_element(msg, tree->u.extended.attr); - if (el == NULL) { - return 0; - } - - for (i=0;i<el->num_values;i++) { - int ret = comp(&el->values[i], &tree->u.extended.value); - if (ret == -1 || ret == 1) return ret; - } - - return 0; -} - -/* - return 0 if the given parse tree matches the given message. Assumes - the message is in sorted order - - return 1 if it matches, and 0 if it doesn't match - - this is a recursive function, and does short-circuit evaluation - */ -static int ldb_match_message(struct ldb_context *ldb, - const struct ldb_message *msg, - const struct ldb_parse_tree *tree, - enum ldb_scope scope) -{ - unsigned int i; - int v; - - switch (tree->operation) { - case LDB_OP_AND: - for (i=0;i<tree->u.list.num_elements;i++) { - v = ldb_match_message(ldb, msg, tree->u.list.elements[i], scope); - if (!v) return 0; - } - return 1; - - case LDB_OP_OR: - for (i=0;i<tree->u.list.num_elements;i++) { - v = ldb_match_message(ldb, msg, tree->u.list.elements[i], scope); - if (v) return 1; - } - return 0; - - case LDB_OP_NOT: - return ! ldb_match_message(ldb, msg, tree->u.isnot.child, scope); - - case LDB_OP_EQUALITY: - return ldb_match_equality(ldb, msg, tree, scope); - - case LDB_OP_SUBSTRING: - return ldb_match_substring(ldb, msg, tree, scope); - - case LDB_OP_GREATER: - return ldb_match_comparison(ldb, msg, tree, scope, LDB_OP_GREATER); - - case LDB_OP_LESS: - return ldb_match_comparison(ldb, msg, tree, scope, LDB_OP_LESS); - - case LDB_OP_PRESENT: - return ldb_match_present(ldb, msg, tree, scope); - - case LDB_OP_APPROX: - return ldb_match_comparison(ldb, msg, tree, scope, LDB_OP_APPROX); - - case LDB_OP_EXTENDED: - return ldb_match_extended(ldb, msg, tree, scope); - - } - - return 0; -} - -int ldb_match_msg(struct ldb_context *ldb, - const struct ldb_message *msg, - const struct ldb_parse_tree *tree, - const struct ldb_dn *base, - enum ldb_scope scope) -{ - if ( ! ldb_match_scope(ldb, base, msg->dn, scope) ) { - return 0; - } - - return ldb_match_message(ldb, msg, tree, scope); -} diff --git a/source/lib/ldb/common/ldb_modules.c b/source/lib/ldb/common/ldb_modules.c deleted file mode 100644 index a6997b324a1..00000000000 --- a/source/lib/ldb/common/ldb_modules.c +++ /dev/null @@ -1,452 +0,0 @@ - -/* - ldb database library - - Copyright (C) Simo Sorce 2004 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - * Name: ldb - * - * Component: ldb modules core - * - * Description: core modules routines - * - * Author: Simo Sorce - */ - -#include "includes.h" -#include "ldb/include/includes.h" - -#if (_SAMBA_BUILD_ >= 4) -#include "build.h" -#include "dynconfig.h" -#endif - -#define LDB_MODULE_PREFIX "modules:" -#define LDB_MODULE_PREFIX_LEN 8 - -static char *ldb_modules_strdup_no_spaces(TALLOC_CTX *mem_ctx, const char *string) -{ - int i, len; - char *trimmed; - - trimmed = talloc_strdup(mem_ctx, string); - if (!trimmed) { - return NULL; - } - - len = strlen(trimmed); - for (i = 0; trimmed[i] != '\0'; i++) { - switch (trimmed[i]) { - case ' ': - case '\t': - case '\n': - memmove(&trimmed[i], &trimmed[i + 1], len -i -1); - break; - } - } - - return trimmed; -} - - -/* modules are called in inverse order on the stack. - Lets place them as an admin would think the right order is. - Modules order is important */ -const char **ldb_modules_list_from_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *string) -{ - char **modules = NULL; - const char **m; - char *modstr, *p; - int i; - - /* spaces not admitted */ - modstr = ldb_modules_strdup_no_spaces(mem_ctx, string); - if ( ! modstr) { - ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_strdup_no_spaces()\n"); - return NULL; - } - - modules = talloc_realloc(mem_ctx, modules, char *, 2); - if ( ! modules ) { - ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_list_from_string()\n"); - talloc_free(modstr); - return NULL; - } - talloc_steal(modules, modstr); - - i = 0; - /* The str*r*chr walks backwards: This is how we get the inverse order mentioned above */ - while ((p = strrchr(modstr, ',')) != NULL) { - *p = '\0'; - p++; - modules[i] = p; - - i++; - modules = talloc_realloc(mem_ctx, modules, char *, i + 2); - if ( ! modules ) { - ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_list_from_string()\n"); - return NULL; - } - - } - modules[i] = modstr; - - modules[i + 1] = NULL; - - m = (const char **)modules; - - return m; -} - -static struct ops_list_entry { - const struct ldb_module_ops *ops; - struct ops_list_entry *next; -} *registered_modules = NULL; - -static const struct ldb_module_ops *ldb_find_module_ops(const char *name) -{ - struct ops_list_entry *e; - - for (e = registered_modules; e; e = e->next) { - if (strcmp(e->ops->name, name) == 0) - return e->ops; - } - - return NULL; -} - -#ifndef STATIC_ldb_MODULES - -#ifdef HAVE_LDB_LDAP -#define LDAP_INIT ldb_ldap_init, -#else -#define LDAP_INIT -#endif - -#ifdef HAVE_LDB_SQLITE3 -#define SQLITE3_INIT ldb_sqlite3_init, -#else -#define SQLITE3_INIT -#endif - -#define STATIC_ldb_MODULES \ - { \ - LDAP_INIT \ - SQLITE3_INIT \ - ldb_tdb_init, \ - ldb_operational_init, \ - ldb_rdn_name_init, \ - ldb_objectclass_init, \ - ldb_paged_results_init, \ - ldb_sort_init, \ - ldb_asq_init, \ - NULL \ - } -#endif - -int ldb_global_init(void) -{ - static int (*static_init_fns[])(void) = STATIC_ldb_MODULES; - - static int initialized = 0; - int ret = 0, i; - - if (initialized) - return 0; - - initialized = 1; - - for (i = 0; static_init_fns[i]; i++) { - if (static_init_fns[i]() == -1) - ret = -1; - } - - return ret; -} - -int ldb_register_module(const struct ldb_module_ops *ops) -{ - struct ops_list_entry *entry = talloc(talloc_autofree_context(), struct ops_list_entry); - - if (ldb_find_module_ops(ops->name) != NULL) - return -1; - - if (entry == NULL) - return -1; - - entry->ops = ops; - entry->next = registered_modules; - registered_modules = entry; - - return 0; -} - -int ldb_try_load_dso(struct ldb_context *ldb, const char *name) -{ - char *path; - void *handle; - int (*init_fn) (void); - char *modulesdir; - -#ifdef HAVE_DLOPEN - if (getenv("LD_LDB_MODULE_PATH") != NULL) { - modulesdir = talloc_strdup(ldb, getenv("LD_LDB_MODULE_PATH")); - } else { -#ifdef _SAMBA_BUILD_ - modulesdir = talloc_asprintf(ldb, "%s/ldb", dyn_MODULESDIR); -#else - modulesdir = talloc_strdup(ldb, MODULESDIR); -#endif - } - - path = talloc_asprintf(ldb, "%s/%s.%s", modulesdir, name, SHLIBEXT); - - talloc_free(modulesdir); - - ldb_debug(ldb, LDB_DEBUG_TRACE, "trying to load %s from %s\n", name, path); - - handle = dlopen(path, RTLD_NOW); - if (handle == NULL) { - ldb_debug(ldb, LDB_DEBUG_WARNING, "unable to load %s from %s: %s\n", name, path, dlerror()); - return -1; - } - - init_fn = (int (*)(void))dlsym(handle, "init_module"); - - if (init_fn == NULL) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "no symbol `init_module' found in %s: %s\n", path, dlerror()); - return -1; - } - - talloc_free(path); - - return init_fn(); -#else - ldb_debug(ldb, LDB_DEBUG_TRACE, "no dlopen() - not trying to load %s module\n", name); - return -1; -#endif -} - -int ldb_load_modules_list(struct ldb_context *ldb, const char **module_list, struct ldb_module *backend, struct ldb_module **out) -{ - struct ldb_module *module; - int i; - - module = backend; - - for (i = 0; module_list[i] != NULL; i++) { - struct ldb_module *current; - const struct ldb_module_ops *ops; - - ops = ldb_find_module_ops(module_list[i]); - if (ops == NULL) { - if (ldb_try_load_dso(ldb, module_list[i]) == 0) { - ops = ldb_find_module_ops(module_list[i]); - } - } - - if (ops == NULL) { - ldb_debug(ldb, LDB_DEBUG_WARNING, "WARNING: Module [%s] not found\n", - module_list[i]); - continue; - } - - current = talloc_zero(ldb, struct ldb_module); - if (current == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - talloc_set_name(current, "ldb_module: %s", module_list[i]); - - current->ldb = ldb; - current->ops = ops; - - DLIST_ADD(module, current); - } - *out = module; - return LDB_SUCCESS; -} - -int ldb_init_module_chain(struct ldb_context *ldb, struct ldb_module *module) -{ - while (module && module->ops->init_context == NULL) - module = module->next; - - if (module && module->ops->init_context && - module->ops->init_context(module) != LDB_SUCCESS) { - ldb_debug(ldb, LDB_DEBUG_FATAL, "module initialization failed\n"); - return LDB_ERR_OPERATIONS_ERROR; - } - - return LDB_SUCCESS; -} - -int ldb_load_modules(struct ldb_context *ldb, const char *options[]) -{ - const char **modules = NULL; - int i; - int ret; - TALLOC_CTX *mem_ctx = talloc_new(ldb); - if (!mem_ctx) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* find out which modules we are requested to activate */ - - /* check if we have a custom module list passd as ldb option */ - if (options) { - for (i = 0; options[i] != NULL; i++) { - if (strncmp(options[i], LDB_MODULE_PREFIX, LDB_MODULE_PREFIX_LEN) == 0) { - modules = ldb_modules_list_from_string(ldb, mem_ctx, &options[i][LDB_MODULE_PREFIX_LEN]); - } - } - } - - /* if not overloaded by options and the backend is not ldap try to load the modules list from ldb */ - if ((modules == NULL) && (strcmp("ldap", ldb->modules->ops->name) != 0)) { - const char * const attrs[] = { "@LIST" , NULL}; - struct ldb_result *res = NULL; - struct ldb_dn *mods_dn; - - mods_dn = ldb_dn_explode(mem_ctx, "@MODULES"); - if (mods_dn == NULL) { - talloc_free(mem_ctx); - return -1; - } - - ret = ldb_search(ldb, mods_dn, LDB_SCOPE_BASE, "", attrs, &res); - talloc_steal(mods_dn, res); - if (ret == LDB_SUCCESS && (res->count == 0 || res->msgs[0]->num_elements == 0)) { - ldb_debug(ldb, LDB_DEBUG_TRACE, "no modules required by the db\n"); - } else { - if (ret != LDB_SUCCESS) { - ldb_debug(ldb, LDB_DEBUG_FATAL, "ldb error (%s) occurred searching for modules, bailing out\n", ldb_errstring(ldb)); - talloc_free(mem_ctx); - return -1; - } - if (res->count > 1) { - ldb_debug(ldb, LDB_DEBUG_FATAL, "Too many records found (%d), bailing out\n", res->count); - talloc_free(mem_ctx); - return -1; - } - - modules = ldb_modules_list_from_string(ldb, mem_ctx, - (const char *)res->msgs[0]->elements[0].values[0].data); - - } - - talloc_free(mods_dn); - } - - if (modules != NULL) { - ret = ldb_load_modules_list(ldb, modules, ldb->modules, &ldb->modules); - talloc_free(modules); - if (ret != LDB_SUCCESS) { - return ret; - } - } else { - ldb_debug(ldb, LDB_DEBUG_TRACE, "No modules specified for this database\n"); - } - - return ldb_init_module_chain(ldb, ldb->modules); -} - -/* - by using this we allow ldb modules to only implement the functions they care about, - which makes writing a module simpler, and makes it more likely to keep working - when ldb is extended -*/ -#define FIND_OP(module, op) do { \ - struct ldb_context *ldb = module->ldb; \ - module = module->next; \ - while (module && module->ops->op == NULL) module = module->next; \ - if (module == NULL) { \ - ldb_asprintf_errstring(ldb, "Unable to find backend operation for " #op ); \ - return LDB_ERR_OPERATIONS_ERROR; \ - } \ -} while (0) - - -/* - helper functions to call the next module in chain -*/ - -int ldb_next_request(struct ldb_module *module, struct ldb_request *request) -{ - switch (request->operation) { - case LDB_SEARCH: - FIND_OP(module, search); - return module->ops->search(module, request); - case LDB_ADD: - FIND_OP(module, add); - return module->ops->add(module, request); - case LDB_MODIFY: - FIND_OP(module, modify); - return module->ops->modify(module, request); - case LDB_DELETE: - FIND_OP(module, del); - return module->ops->del(module, request); - case LDB_RENAME: - FIND_OP(module, rename); - return module->ops->rename(module, request); - case LDB_SEQUENCE_NUMBER: - FIND_OP(module, sequence_number); - return module->ops->sequence_number(module, request); - default: - FIND_OP(module, request); - return module->ops->request(module, request); - } -} - -int ldb_next_init(struct ldb_module *module) -{ - /* init is different in that it is not an error if modules - * do not require initialization */ - - module = module->next; - - while (module && module->ops->init_context == NULL) - module = module->next; - - if (module == NULL) - return LDB_SUCCESS; - - return module->ops->init_context(module); -} - -int ldb_next_start_trans(struct ldb_module *module) -{ - FIND_OP(module, start_transaction); - return module->ops->start_transaction(module); -} - -int ldb_next_end_trans(struct ldb_module *module) -{ - FIND_OP(module, end_transaction); - return module->ops->end_transaction(module); -} - -int ldb_next_del_trans(struct ldb_module *module) -{ - FIND_OP(module, del_transaction); - return module->ops->del_transaction(module); -} diff --git a/source/lib/ldb/common/ldb_msg.c b/source/lib/ldb/common/ldb_msg.c deleted file mode 100644 index bf217d2787f..00000000000 --- a/source/lib/ldb/common/ldb_msg.c +++ /dev/null @@ -1,830 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - * Name: ldb - * - * Component: ldb message component utility functions - * - * Description: functions for manipulating ldb_message structures - * - * Author: Andrew Tridgell - */ - -#include "includes.h" -#include "ldb/include/includes.h" - -void ldb_dump_results(struct ldb_context *ldb, struct ldb_result *result, FILE *f); -int ldb_msg_element_compare_name(struct ldb_message_element *el1, - struct ldb_message_element *el2); - -/* - create a new ldb_message in a given memory context (NULL for top level) -*/ -struct ldb_message *ldb_msg_new(void *mem_ctx) -{ - return talloc_zero(mem_ctx, struct ldb_message); -} - -/* - find an element in a message by attribute name -*/ -struct ldb_message_element *ldb_msg_find_element(const struct ldb_message *msg, - const char *attr_name) -{ - unsigned int i; - for (i=0;i<msg->num_elements;i++) { - if (ldb_attr_cmp(msg->elements[i].name, attr_name) == 0) { - return &msg->elements[i]; - } - } - return NULL; -} - -/* - see if two ldb_val structures contain exactly the same data - return 1 for a match, 0 for a mis-match -*/ -int ldb_val_equal_exact(const struct ldb_val *v1, const struct ldb_val *v2) -{ - if (v1->length != v2->length) return 0; - - if (v1->length == 0) return 1; - - if (memcmp(v1->data, v2->data, v1->length) == 0) { - return 1; - } - - return 0; -} - -/* - find a value in an element - assumes case sensitive comparison -*/ -struct ldb_val *ldb_msg_find_val(const struct ldb_message_element *el, - struct ldb_val *val) -{ - unsigned int i; - for (i=0;i<el->num_values;i++) { - if (ldb_val_equal_exact(val, &el->values[i])) { - return &el->values[i]; - } - } - return NULL; -} - -/* - duplicate a ldb_val structure -*/ -struct ldb_val ldb_val_dup(void *mem_ctx, const struct ldb_val *v) -{ - struct ldb_val v2; - v2.length = v->length; - if (v->data == NULL) { - v2.data = NULL; - return v2; - } - - /* the +1 is to cope with buggy C library routines like strndup - that look one byte beyond */ - v2.data = talloc_array(mem_ctx, uint8_t, v->length+1); - if (!v2.data) { - v2.length = 0; - return v2; - } - - memcpy(v2.data, v->data, v->length); - ((char *)v2.data)[v->length] = 0; - return v2; -} - -/* - add an empty element to a message -*/ -int ldb_msg_add_empty( struct ldb_message *msg, - const char *attr_name, - int flags, - struct ldb_message_element **return_el) -{ - struct ldb_message_element *els; - - if (! ldb_valid_attr_name(attr_name)) { - return LDB_ERR_OPERATIONS_ERROR; - } - - els = talloc_realloc(msg, msg->elements, - struct ldb_message_element, msg->num_elements+1); - if (!els) { - errno = ENOMEM; - return LDB_ERR_OPERATIONS_ERROR; - } - - els[msg->num_elements].values = NULL; - els[msg->num_elements].num_values = 0; - els[msg->num_elements].flags = flags; - els[msg->num_elements].name = talloc_strdup(els, attr_name); - if (!els[msg->num_elements].name) { - errno = ENOMEM; - return LDB_ERR_OPERATIONS_ERROR; - } - - msg->elements = els; - msg->num_elements++; - - if (return_el) { - *return_el = &els[msg->num_elements-1]; - } - - return LDB_SUCCESS; -} - -/* - add an empty element to a message -*/ -int ldb_msg_add(struct ldb_message *msg, - const struct ldb_message_element *el, - int flags) -{ - if (ldb_msg_add_empty(msg, el->name, flags, NULL) != 0) { - return LDB_ERR_OPERATIONS_ERROR; - } - - msg->elements[msg->num_elements-1] = *el; - msg->elements[msg->num_elements-1].flags = flags; - - return LDB_SUCCESS; -} - -/* - add a value to a message -*/ -int ldb_msg_add_value(struct ldb_message *msg, - const char *attr_name, - const struct ldb_val *val, - struct ldb_message_element **return_el) -{ - struct ldb_message_element *el; - struct ldb_val *vals; - int ret; - - el = ldb_msg_find_element(msg, attr_name); - if (!el) { - ret = ldb_msg_add_empty(msg, attr_name, 0, &el); - if (ret != LDB_SUCCESS) { - return ret; - } - } - - vals = talloc_realloc(msg, el->values, struct ldb_val, el->num_values+1); - if (!vals) { - errno = ENOMEM; - return LDB_ERR_OPERATIONS_ERROR; - } - el->values = vals; - el->values[el->num_values] = *val; - el->num_values++; - - if (return_el) { - *return_el = el; - } - - return LDB_SUCCESS; -} - - -/* - add a value to a message, stealing it into the 'right' place -*/ -int ldb_msg_add_steal_value(struct ldb_message *msg, - const char *attr_name, - struct ldb_val *val) -{ - int ret; - struct ldb_message_element *el; - - ret = ldb_msg_add_value(msg, attr_name, val, &el); - if (ret == LDB_SUCCESS) { - talloc_steal(el->values, val->data); - } - return ret; -} - - -/* - add a string element to a message -*/ -int ldb_msg_add_string(struct ldb_message *msg, - const char *attr_name, const char *str) -{ - struct ldb_val val; - - val.data = discard_const_p(uint8_t, str); - val.length = strlen(str); - - if (val.length == 0) { - /* allow empty strings as non-existant attributes */ - return LDB_SUCCESS; - } - - return ldb_msg_add_value(msg, attr_name, &val, NULL); -} - -/* - add a string element to a message, stealing it into the 'right' place -*/ -int ldb_msg_add_steal_string(struct ldb_message *msg, - const char *attr_name, char *str) -{ - struct ldb_val val; - - val.data = (uint8_t *)str; - val.length = strlen(str); - - return ldb_msg_add_steal_value(msg, attr_name, &val); -} - -/* - add a printf formatted element to a message -*/ -int ldb_msg_add_fmt(struct ldb_message *msg, - const char *attr_name, const char *fmt, ...) -{ - struct ldb_val val; - va_list ap; - char *str; - - va_start(ap, fmt); - str = talloc_vasprintf(msg, fmt, ap); - va_end(ap); - - if (str == NULL) return LDB_ERR_OPERATIONS_ERROR; - - val.data = (uint8_t *)str; - val.length = strlen(str); - - return ldb_msg_add_steal_value(msg, attr_name, &val); -} - -/* - compare two ldb_message_element structures - assumes case senistive comparison -*/ -int ldb_msg_element_compare(struct ldb_message_element *el1, - struct ldb_message_element *el2) -{ - unsigned int i; - - if (el1->num_values != el2->num_values) { - return el1->num_values - el2->num_values; - } - - for (i=0;i<el1->num_values;i++) { - if (!ldb_msg_find_val(el2, &el1->values[i])) { - return -1; - } - } - - return 0; -} - -/* - compare two ldb_message_element structures - comparing by element name -*/ -int ldb_msg_element_compare_name(struct ldb_message_element *el1, - struct ldb_message_element *el2) -{ - return ldb_attr_cmp(el1->name, el2->name); -} - -/* - convenience functions to return common types from a message - these return the first value if the attribute is multi-valued -*/ -const struct ldb_val *ldb_msg_find_ldb_val(const struct ldb_message *msg, const char *attr_name) -{ - struct ldb_message_element *el = ldb_msg_find_element(msg, attr_name); - if (!el || el->num_values == 0) { - return NULL; - } - return &el->values[0]; -} - -int ldb_msg_find_attr_as_int(const struct ldb_message *msg, - const char *attr_name, - int default_value) -{ - const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); - if (!v || !v->data) { - return default_value; - } - return strtol((const char *)v->data, NULL, 0); -} - -unsigned int ldb_msg_find_attr_as_uint(const struct ldb_message *msg, - const char *attr_name, - unsigned int default_value) -{ - const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); - if (!v || !v->data) { - return default_value; - } - return strtoul((const char *)v->data, NULL, 0); -} - -int64_t ldb_msg_find_attr_as_int64(const struct ldb_message *msg, - const char *attr_name, - int64_t default_value) -{ - const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); - if (!v || !v->data) { - return default_value; - } - return strtoll((const char *)v->data, NULL, 0); -} - -uint64_t ldb_msg_find_attr_as_uint64(const struct ldb_message *msg, - const char *attr_name, - uint64_t default_value) -{ - const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); - if (!v || !v->data) { - return default_value; - } - return strtoull((const char *)v->data, NULL, 0); -} - -double ldb_msg_find_attr_as_double(const struct ldb_message *msg, - const char *attr_name, - double default_value) -{ - const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); - if (!v || !v->data) { - return default_value; - } - return strtod((const char *)v->data, NULL); -} - -int ldb_msg_find_attr_as_bool(const struct ldb_message *msg, - const char *attr_name, - int default_value) -{ - const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); - if (!v || !v->data) { - return default_value; - } - if (strcasecmp((const char *)v->data, "FALSE") == 0) { - return 0; - } - if (strcasecmp((const char *)v->data, "TRUE") == 0) { - return 1; - } - return default_value; -} - -const char *ldb_msg_find_attr_as_string(const struct ldb_message *msg, - const char *attr_name, - const char *default_value) -{ - const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); - if (!v || !v->data) { - return default_value; - } - return (const char *)v->data; -} - -struct ldb_dn *ldb_msg_find_attr_as_dn(void *mem_ctx, - const struct ldb_message *msg, - const char *attr_name) -{ - const struct ldb_val *v; - - v = ldb_msg_find_ldb_val(msg, attr_name); - if (!v || !v->data) { - return NULL; - } - return ldb_dn_explode(mem_ctx, (const char *)v->data); -} - -/* - sort the elements of a message by name -*/ -void ldb_msg_sort_elements(struct ldb_message *msg) -{ - qsort(msg->elements, msg->num_elements, sizeof(struct ldb_message_element), - (comparison_fn_t)ldb_msg_element_compare_name); -} - -/* - shallow copy a message - copying only the elements array so that the caller - can safely add new elements without changing the message -*/ -struct ldb_message *ldb_msg_copy_shallow(TALLOC_CTX *mem_ctx, - const struct ldb_message *msg) -{ - struct ldb_message *msg2; - int i; - - msg2 = talloc(mem_ctx, struct ldb_message); - if (msg2 == NULL) return NULL; - - *msg2 = *msg; - msg2->private_data = NULL; - - msg2->elements = talloc_array(msg2, struct ldb_message_element, - msg2->num_elements); - if (msg2->elements == NULL) goto failed; - - for (i=0;i<msg2->num_elements;i++) { - msg2->elements[i] = msg->elements[i]; - } - - return msg2; - -failed: - talloc_free(msg2); - return NULL; -} - - -/* - copy a message, allocating new memory for all parts -*/ -struct ldb_message *ldb_msg_copy(TALLOC_CTX *mem_ctx, - const struct ldb_message *msg) -{ - struct ldb_message *msg2; - int i, j; - - msg2 = ldb_msg_copy_shallow(mem_ctx, msg); - if (msg2 == NULL) return NULL; - - msg2->dn = ldb_dn_copy(msg2, msg2->dn); - if (msg2->dn == NULL) goto failed; - - for (i=0;i<msg2->num_elements;i++) { - struct ldb_message_element *el = &msg2->elements[i]; - struct ldb_val *values = el->values; - el->name = talloc_strdup(msg2->elements, el->name); - if (el->name == NULL) goto failed; - el->values = talloc_array(msg2->elements, struct ldb_val, el->num_values); - for (j=0;j<el->num_values;j++) { - el->values[j] = ldb_val_dup(el->values, &values[j]); - if (el->values[j].data == NULL && values[j].length != 0) { - goto failed; - } - } - } - - return msg2; - -failed: - talloc_free(msg2); - return NULL; -} - - -/* - canonicalise a message, merging elements of the same name -*/ -struct ldb_message *ldb_msg_canonicalize(struct ldb_context *ldb, - const struct ldb_message *msg) -{ - int i; - struct ldb_message *msg2; - - msg2 = ldb_msg_copy(ldb, msg); - if (msg2 == NULL) return NULL; - - ldb_msg_sort_elements(msg2); - - for (i=1;i<msg2->num_elements;i++) { - struct ldb_message_element *el1 = &msg2->elements[i-1]; - struct ldb_message_element *el2 = &msg2->elements[i]; - if (ldb_msg_element_compare_name(el1, el2) == 0) { - el1->values = talloc_realloc(msg2->elements, el1->values, struct ldb_val, - el1->num_values + el2->num_values); - if (el1->values == NULL) { - return NULL; - } - memcpy(el1->values + el1->num_values, - el2->values, - sizeof(struct ldb_val) * el2->num_values); - el1->num_values += el2->num_values; - talloc_free(discard_const_p(char, el2->name)); - if (i+1<msg2->num_elements) { - memmove(el2, el2+1, sizeof(struct ldb_message_element) * - (msg2->num_elements - (i+1))); - } - msg2->num_elements--; - i--; - } - } - - return msg2; -} - - -/* - return a ldb_message representing the differences between msg1 and msg2. If you - then use this in a ldb_modify() call it can be used to save edits to a message -*/ -struct ldb_message *ldb_msg_diff(struct ldb_context *ldb, - struct ldb_message *msg1, - struct ldb_message *msg2) -{ - struct ldb_message *mod; - struct ldb_message_element *el; - unsigned int i; - - mod = ldb_msg_new(ldb); - - mod->dn = msg1->dn; - mod->num_elements = 0; - mod->elements = NULL; - - msg2 = ldb_msg_canonicalize(ldb, msg2); - if (msg2 == NULL) { - return NULL; - } - - /* look in msg2 to find elements that need to be added - or modified */ - for (i=0;i<msg2->num_elements;i++) { - el = ldb_msg_find_element(msg1, msg2->elements[i].name); - - if (el && ldb_msg_element_compare(el, &msg2->elements[i]) == 0) { - continue; - } - - if (ldb_msg_add(mod, - &msg2->elements[i], - el?LDB_FLAG_MOD_REPLACE:LDB_FLAG_MOD_ADD) != 0) { - return NULL; - } - } - - /* look in msg1 to find elements that need to be deleted */ - for (i=0;i<msg1->num_elements;i++) { - el = ldb_msg_find_element(msg2, msg1->elements[i].name); - if (!el) { - if (ldb_msg_add_empty(mod, - msg1->elements[i].name, - LDB_FLAG_MOD_DELETE, NULL) != 0) { - return NULL; - } - } - } - - return mod; -} - -int ldb_msg_sanity_check(struct ldb_context *ldb, - const struct ldb_message *msg) -{ - int i, j; - - /* basic check on DN */ - if (msg->dn == NULL) { - /* TODO: return also an error string */ - ldb_set_errstring(ldb, "ldb message lacks a DN!"); - return LDB_ERR_INVALID_DN_SYNTAX; - } - - /* basic syntax checks */ - for (i = 0; i < msg->num_elements; i++) { - for (j = 0; j < msg->elements[i].num_values; j++) { - if (msg->elements[i].values[j].length == 0) { - TALLOC_CTX *mem_ctx = talloc_new(ldb); - /* an attribute cannot be empty */ - /* TODO: return also an error string */ - ldb_asprintf_errstring(ldb, "Element %s has empty attribute in ldb message (%s)!", - msg->elements[i].name, - ldb_dn_linearize(mem_ctx, msg->dn)); - talloc_free(mem_ctx); - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - } - } - - return LDB_SUCCESS; -} - - - - -/* - copy an attribute list. This only copies the array, not the elements - (ie. the elements are left as the same pointers) -*/ -const char **ldb_attr_list_copy(TALLOC_CTX *mem_ctx, const char * const *attrs) -{ - const char **ret; - int i; - for (i=0;attrs[i];i++) /* noop */ ; - ret = talloc_array(mem_ctx, const char *, i+1); - if (ret == NULL) { - return NULL; - } - for (i=0;attrs[i];i++) { - ret[i] = attrs[i]; - } - ret[i] = attrs[i]; - return ret; -} - - -/* - copy an attribute list. This only copies the array, not the elements - (ie. the elements are left as the same pointers). The new attribute is added to the list. -*/ -const char **ldb_attr_list_copy_add(TALLOC_CTX *mem_ctx, const char * const *attrs, const char *new_attr) -{ - const char **ret; - int i; - for (i=0;attrs[i];i++) /* noop */ ; - ret = talloc_array(mem_ctx, const char *, i+2); - if (ret == NULL) { - return NULL; - } - for (i=0;attrs[i];i++) { - ret[i] = attrs[i]; - } - ret[i] = new_attr; - ret[i+1] = NULL; - return ret; -} - - -/* - return 1 if an attribute is in a list of attributes, or 0 otherwise -*/ -int ldb_attr_in_list(const char * const *attrs, const char *attr) -{ - int i; - for (i=0;attrs[i];i++) { - if (ldb_attr_cmp(attrs[i], attr) == 0) { - return 1; - } - } - return 0; -} - - -/* - rename the specified attribute in a search result -*/ -int ldb_msg_rename_attr(struct ldb_message *msg, const char *attr, const char *replace) -{ - struct ldb_message_element *el = ldb_msg_find_element(msg, attr); - if (el == NULL) { - return LDB_SUCCESS; - } - el->name = talloc_strdup(msg->elements, replace); - if (el->name == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - return LDB_SUCCESS; -} - - -/* - copy the specified attribute in a search result to a new attribute -*/ -int ldb_msg_copy_attr(struct ldb_message *msg, const char *attr, const char *replace) -{ - struct ldb_message_element *el = ldb_msg_find_element(msg, attr); - if (el == NULL) { - return LDB_SUCCESS; - } - if (ldb_msg_add(msg, el, 0) != 0) { - return LDB_ERR_OPERATIONS_ERROR; - } - return ldb_msg_rename_attr(msg, attr, replace); -} - - -/* - remove the specified attribute in a search result -*/ -void ldb_msg_remove_attr(struct ldb_message *msg, const char *attr) -{ - struct ldb_message_element *el = ldb_msg_find_element(msg, attr); - if (el) { - int n = (el - msg->elements); - if (n != msg->num_elements-1) { - memmove(el, el+1, ((msg->num_elements-1) - n)*sizeof(*el)); - } - msg->num_elements--; - } -} - -/* - remove the specified element in a search result -*/ -void ldb_msg_remove_element(struct ldb_message *msg, struct ldb_message_element *el) -{ - int n = (el - msg->elements); - if (n != msg->num_elements-1) { - memmove(el, el+1, ((msg->num_elements-1) - n)*sizeof(*el)); - } - msg->num_elements--; -} - -/* - return a LDAP formatted time string -*/ -char *ldb_timestring(TALLOC_CTX *mem_ctx, time_t t) -{ - struct tm *tm = gmtime(&t); - - if (!tm) { - return NULL; - } - - /* formatted like: 20040408072012.0Z */ - return talloc_asprintf(mem_ctx, - "%04u%02u%02u%02u%02u%02u.0Z", - tm->tm_year+1900, tm->tm_mon+1, - tm->tm_mday, tm->tm_hour, tm->tm_min, - tm->tm_sec); -} - - -/* - convert a LDAP time string to a time_t. Return 0 if unable to convert -*/ -time_t ldb_string_to_time(const char *s) -{ - struct tm tm; - - if (s == NULL) return 0; - - memset(&tm, 0, sizeof(tm)); - if (sscanf(s, "%04u%02u%02u%02u%02u%02u", - &tm.tm_year, &tm.tm_mon, &tm.tm_mday, - &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) { - return 0; - } - tm.tm_year -= 1900; - tm.tm_mon -= 1; - - return timegm(&tm); -} - - -/* - dump a set of results to a file. Useful from within gdb -*/ -void ldb_dump_results(struct ldb_context *ldb, struct ldb_result *result, FILE *f) -{ - int i; - - for (i = 0; i < result->count; i++) { - struct ldb_ldif ldif; - fprintf(f, "# record %d\n", i+1); - ldif.changetype = LDB_CHANGETYPE_NONE; - ldif.msg = result->msgs[i]; - ldb_ldif_write_file(ldb, f, &ldif); - } -} - -int ldb_msg_check_string_attribute(const struct ldb_message *msg, const char *name, const char *value) -{ - struct ldb_message_element *el; - struct ldb_val val; - - el = ldb_msg_find_element(msg, name); - if (el == NULL) - return 0; - - val.data = discard_const_p(uint8_t, value); - val.length = strlen(value); - - if (ldb_msg_find_val(el, &val)) - return 1; - - return 0; -} diff --git a/source/lib/ldb/common/ldb_parse.c b/source/lib/ldb/common/ldb_parse.c deleted file mode 100644 index 5c5709f929e..00000000000 --- a/source/lib/ldb/common/ldb_parse.c +++ /dev/null @@ -1,819 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - * Name: ldb - * - * Component: ldb expression parsing - * - * Description: parse LDAP-like search expressions - * - * Author: Andrew Tridgell - */ - -/* - TODO: - - add RFC2254 binary string handling - - possibly add ~=, <= and >= handling - - expand the test suite - - add better parse error handling - -*/ - -#include "includes.h" -#include "ldb/include/includes.h" -#include "system/locale.h" - -struct ldb_val ldb_binary_decode(void *mem_ctx, const char *str); - -/* -a filter is defined by: - <filter> ::= '(' <filtercomp> ')' - <filtercomp> ::= <and> | <or> | <not> | <simple> - <and> ::= '&' <filterlist> - <or> ::= '|' <filterlist> - <not> ::= '!' <filter> - <filterlist> ::= <filter> | <filter> <filterlist> - <simple> ::= <attributetype> <filtertype> <attributevalue> - <filtertype> ::= '=' | '~=' | '<=' | '>=' -*/ - -/* - decode a RFC2254 binary string representation of a buffer. - Used in LDAP filters. -*/ -struct ldb_val ldb_binary_decode(void *mem_ctx, const char *str) -{ - int i, j; - struct ldb_val ret; - int slen = str?strlen(str):0; - - ret.data = (uint8_t *)talloc_size(mem_ctx, slen+1); - ret.length = 0; - if (ret.data == NULL) return ret; - - for (i=j=0;i<slen;i++) { - if (str[i] == '\\') { - unsigned c; - if (sscanf(&str[i+1], "%02X", &c) != 1) { - talloc_free(ret.data); - memset(&ret, 0, sizeof(ret)); - return ret; - } - ((uint8_t *)ret.data)[j++] = c; - i += 2; - } else { - ((uint8_t *)ret.data)[j++] = str[i]; - } - } - ret.length = j; - ((uint8_t *)ret.data)[j] = 0; - - return ret; -} - - -/* - encode a blob as a RFC2254 binary string, escaping any - non-printable or '\' characters -*/ -char *ldb_binary_encode(void *mem_ctx, struct ldb_val val) -{ - int i; - char *ret; - int len = val.length; - unsigned char *buf = val.data; - - for (i=0;i<val.length;i++) { - if (!isprint(buf[i]) || strchr(" *()\\&|!\"", buf[i])) { - len += 2; - } - } - ret = talloc_array(mem_ctx, char, len+1); - if (ret == NULL) return NULL; - - len = 0; - for (i=0;i<val.length;i++) { - if (!isprint(buf[i]) || strchr(" *()\\&|!\"", buf[i])) { - snprintf(ret+len, 4, "\\%02X", buf[i]); - len += 3; - } else { - ret[len++] = buf[i]; - } - } - - ret[len] = 0; - - return ret; -} - -/* - encode a string as a RFC2254 binary string, escaping any - non-printable or '\' characters. This routine is suitable for use - in escaping user data in ldap filters. -*/ -char *ldb_binary_encode_string(void *mem_ctx, const char *string) -{ - struct ldb_val val; - val.data = discard_const_p(uint8_t, string); - val.length = strlen(string); - return ldb_binary_encode(mem_ctx, val); -} - -/* find the first matching wildcard */ -static char *ldb_parse_find_wildcard(char *value) -{ - while (*value) { - value = strpbrk(value, "\\*"); - if (value == NULL) return NULL; - - if (value[0] == '\\') { - if (value[1] == '\0') return NULL; - value += 2; - continue; - } - - if (value[0] == '*') return value; - } - - return NULL; -} - -/* return a NULL terminated list of binary strings representing the value - chunks separated by wildcards that makes the value portion of the filter -*/ -static struct ldb_val **ldb_wildcard_decode(void *mem_ctx, const char *string) -{ - struct ldb_val **ret = NULL; - int val = 0; - char *wc, *str; - - wc = talloc_strdup(mem_ctx, string); - if (wc == NULL) return NULL; - - while (wc && *wc) { - str = wc; - wc = ldb_parse_find_wildcard(str); - if (wc && *wc) { - if (wc == str) { - wc++; - continue; - } - *wc = 0; - wc++; - } - - ret = talloc_realloc(mem_ctx, ret, struct ldb_val *, val + 2); - if (ret == NULL) return NULL; - - ret[val] = talloc(mem_ctx, struct ldb_val); - if (ret[val] == NULL) return NULL; - - *(ret[val]) = ldb_binary_decode(mem_ctx, str); - if ((ret[val])->data == NULL) return NULL; - - val++; - } - - if (ret != NULL) { - ret[val] = NULL; - } - - return ret; -} - -static struct ldb_parse_tree *ldb_parse_filter(void *mem_ctx, const char **s); - - -/* - parse an extended match - - possible forms: - (attr:oid:=value) - (attr:dn:oid:=value) - (attr:dn:=value) - (:dn:oid:=value) - - the ':dn' part sets the dnAttributes boolean if present - the oid sets the rule_id string - -*/ -static struct ldb_parse_tree *ldb_parse_extended(struct ldb_parse_tree *ret, - char *attr, char *value) -{ - char *p1, *p2; - - ret->operation = LDB_OP_EXTENDED; - ret->u.extended.value = ldb_binary_decode(ret, value); - if (ret->u.extended.value.data == NULL) goto failed; - - p1 = strchr(attr, ':'); - if (p1 == NULL) goto failed; - p2 = strchr(p1+1, ':'); - - *p1 = 0; - if (p2) *p2 = 0; - - ret->u.extended.attr = attr; - if (strcmp(p1+1, "dn") == 0) { - ret->u.extended.dnAttributes = 1; - if (p2) { - ret->u.extended.rule_id = talloc_strdup(ret, p2+1); - if (ret->u.extended.rule_id == NULL) goto failed; - } else { - ret->u.extended.rule_id = NULL; - } - } else { - ret->u.extended.dnAttributes = 0; - ret->u.extended.rule_id = talloc_strdup(ret, p1+1); - if (ret->u.extended.rule_id == NULL) goto failed; - } - - return ret; - -failed: - talloc_free(ret); - return NULL; -} - -static enum ldb_parse_op ldb_parse_filtertype(void *mem_ctx, char **type, char **value, const char **s) -{ - enum ldb_parse_op filter = 0; - char *name, *val, *k; - const char *p = *s; - const char *t, *t1; - - /* retrieve attributetype name */ - t = p; - - while ((isascii(*p) && isalnum((unsigned char)*p)) || (*p == '-')) { /* attribute names can only be alphanums */ - p++; - } - - if (*p == ':') { /* but extended searches have : and . chars too */ - p = strstr(p, ":="); - if (p == NULL) { /* malformed attribute name */ - return 0; - } - } - - t1 = p; - - while (isspace((unsigned char)*p)) p++; - - if (!strchr("=<>~:", *p)) { - return 0; - } - - /* save name */ - name = (char *)talloc_memdup(mem_ctx, t, t1 - t + 1); - if (name == NULL) return 0; - name[t1 - t] = '\0'; - - /* retrieve filtertype */ - - if (*p == '=') { - filter = LDB_OP_EQUALITY; - } else if (*(p + 1) == '=') { - switch (*p) { - case '<': - filter = LDB_OP_LESS; - p++; - break; - case '>': - filter = LDB_OP_GREATER; - p++; - break; - case '~': - filter = LDB_OP_APPROX; - p++; - break; - case ':': - filter = LDB_OP_EXTENDED; - p++; - break; - } - } - if (!filter) { - talloc_free(name); - return filter; - } - p++; - - while (isspace((unsigned char)*p)) p++; - - /* retieve value */ - t = p; - - while (*p && ((*p != ')') || ((*p == ')') && (*(p - 1) == '\\')))) p++; - - val = (char *)talloc_memdup(mem_ctx, t, p - t + 1); - if (val == NULL) { - talloc_free(name); - return 0; - } - val[p - t] = '\0'; - - k = &(val[p - t]); - - /* remove trailing spaces from value */ - while ((k > val) && (isspace((unsigned char)*(k - 1)))) k--; - *k = '\0'; - - *type = name; - *value = val; - *s = p; - return filter; -} - -/* - <simple> ::= <attributetype> <filtertype> <attributevalue> -*/ -static struct ldb_parse_tree *ldb_parse_simple(void *mem_ctx, const char **s) -{ - char *attr, *value; - struct ldb_parse_tree *ret; - enum ldb_parse_op filtertype; - - ret = talloc(mem_ctx, struct ldb_parse_tree); - if (!ret) { - errno = ENOMEM; - return NULL; - } - - filtertype = ldb_parse_filtertype(ret, &attr, &value, s); - if (!filtertype) { - talloc_free(ret); - return NULL; - } - - switch (filtertype) { - - case LDB_OP_PRESENT: - ret->operation = LDB_OP_PRESENT; - ret->u.present.attr = attr; - break; - - case LDB_OP_EQUALITY: - - if (strcmp(value, "*") == 0) { - ret->operation = LDB_OP_PRESENT; - ret->u.present.attr = attr; - break; - } - - if (ldb_parse_find_wildcard(value) != NULL) { - ret->operation = LDB_OP_SUBSTRING; - ret->u.substring.attr = attr; - ret->u.substring.start_with_wildcard = 0; - ret->u.substring.end_with_wildcard = 0; - ret->u.substring.chunks = ldb_wildcard_decode(ret, value); - if (ret->u.substring.chunks == NULL){ - talloc_free(ret); - return NULL; - } - if (value[0] == '*') - ret->u.substring.start_with_wildcard = 1; - if (value[strlen(value) - 1] == '*') - ret->u.substring.end_with_wildcard = 1; - talloc_free(value); - - break; - } - - ret->operation = LDB_OP_EQUALITY; - ret->u.equality.attr = attr; - ret->u.equality.value = ldb_binary_decode(ret, value); - if (ret->u.equality.value.data == NULL) { - talloc_free(ret); - return NULL; - } - talloc_free(value); - break; - - case LDB_OP_GREATER: - ret->operation = LDB_OP_GREATER; - ret->u.comparison.attr = attr; - ret->u.comparison.value = ldb_binary_decode(ret, value); - if (ret->u.comparison.value.data == NULL) { - talloc_free(ret); - return NULL; - } - talloc_free(value); - break; - - case LDB_OP_LESS: - ret->operation = LDB_OP_LESS; - ret->u.comparison.attr = attr; - ret->u.comparison.value = ldb_binary_decode(ret, value); - if (ret->u.comparison.value.data == NULL) { - talloc_free(ret); - return NULL; - } - talloc_free(value); - break; - - case LDB_OP_APPROX: - ret->operation = LDB_OP_APPROX; - ret->u.comparison.attr = attr; - ret->u.comparison.value = ldb_binary_decode(ret, value); - if (ret->u.comparison.value.data == NULL) { - talloc_free(ret); - return NULL; - } - talloc_free(value); - break; - - case LDB_OP_EXTENDED: - - ret = ldb_parse_extended(ret, attr, value); - break; - - default: - talloc_free(ret); - return NULL; - } - - return ret; -} - - -/* - parse a filterlist - <and> ::= '&' <filterlist> - <or> ::= '|' <filterlist> - <filterlist> ::= <filter> | <filter> <filterlist> -*/ -static struct ldb_parse_tree *ldb_parse_filterlist(void *mem_ctx, const char **s) -{ - struct ldb_parse_tree *ret, *next; - enum ldb_parse_op op; - const char *p = *s; - - switch (*p) { - case '&': - op = LDB_OP_AND; - break; - case '|': - op = LDB_OP_OR; - break; - default: - return NULL; - } - p++; - - while (isspace((unsigned char)*p)) p++; - - ret = talloc(mem_ctx, struct ldb_parse_tree); - if (!ret) { - errno = ENOMEM; - return NULL; - } - - ret->operation = op; - ret->u.list.num_elements = 1; - ret->u.list.elements = talloc(ret, struct ldb_parse_tree *); - if (!ret->u.list.elements) { - errno = ENOMEM; - talloc_free(ret); - return NULL; - } - - ret->u.list.elements[0] = ldb_parse_filter(ret->u.list.elements, &p); - if (!ret->u.list.elements[0]) { - talloc_free(ret); - return NULL; - } - - while (isspace((unsigned char)*p)) p++; - - while (*p && (next = ldb_parse_filter(ret->u.list.elements, &p))) { - struct ldb_parse_tree **e; - e = talloc_realloc(ret, ret->u.list.elements, - struct ldb_parse_tree *, - ret->u.list.num_elements + 1); - if (!e) { - errno = ENOMEM; - talloc_free(ret); - return NULL; - } - ret->u.list.elements = e; - ret->u.list.elements[ret->u.list.num_elements] = next; - ret->u.list.num_elements++; - while (isspace((unsigned char)*p)) p++; - } - - *s = p; - - return ret; -} - - -/* - <not> ::= '!' <filter> -*/ -static struct ldb_parse_tree *ldb_parse_not(void *mem_ctx, const char **s) -{ - struct ldb_parse_tree *ret; - const char *p = *s; - - if (*p != '!') { - return NULL; - } - p++; - - ret = talloc(mem_ctx, struct ldb_parse_tree); - if (!ret) { - errno = ENOMEM; - return NULL; - } - - ret->operation = LDB_OP_NOT; - ret->u.isnot.child = ldb_parse_filter(ret, &p); - if (!ret->u.isnot.child) { - talloc_free(ret); - return NULL; - } - - *s = p; - - return ret; -} - -/* - parse a filtercomp - <filtercomp> ::= <and> | <or> | <not> | <simple> -*/ -static struct ldb_parse_tree *ldb_parse_filtercomp(void *mem_ctx, const char **s) -{ - struct ldb_parse_tree *ret; - const char *p = *s; - - while (isspace((unsigned char)*p)) p++; - - switch (*p) { - case '&': - ret = ldb_parse_filterlist(mem_ctx, &p); - break; - - case '|': - ret = ldb_parse_filterlist(mem_ctx, &p); - break; - - case '!': - ret = ldb_parse_not(mem_ctx, &p); - break; - - case '(': - case ')': - return NULL; - - default: - ret = ldb_parse_simple(mem_ctx, &p); - - } - - *s = p; - return ret; -} - - -/* - <filter> ::= '(' <filtercomp> ')' -*/ -static struct ldb_parse_tree *ldb_parse_filter(void *mem_ctx, const char **s) -{ - struct ldb_parse_tree *ret; - const char *p = *s; - - if (*p != '(') { - return NULL; - } - p++; - - ret = ldb_parse_filtercomp(mem_ctx, &p); - - if (*p != ')') { - return NULL; - } - p++; - - while (isspace((unsigned char)*p)) { - p++; - } - - *s = p; - - return ret; -} - - -/* - main parser entry point. Takes a search string and returns a parse tree - - expression ::= <simple> | <filter> -*/ -struct ldb_parse_tree *ldb_parse_tree(void *mem_ctx, const char *s) -{ - if (s == NULL || *s == 0) { - s = "(|(objectClass=*)(distinguishedName=*))"; - } - - while (isspace((unsigned char)*s)) s++; - - if (*s == '(') { - return ldb_parse_filter(mem_ctx, &s); - } - - return ldb_parse_simple(mem_ctx, &s); -} - - -/* - construct a ldap parse filter given a parse tree -*/ -char *ldb_filter_from_tree(void *mem_ctx, struct ldb_parse_tree *tree) -{ - char *s, *s2, *ret; - int i; - - if (tree == NULL) { - return NULL; - } - - switch (tree->operation) { - case LDB_OP_AND: - case LDB_OP_OR: - ret = talloc_asprintf(mem_ctx, "(%c", tree->operation==LDB_OP_AND?'&':'|'); - if (ret == NULL) return NULL; - for (i=0;i<tree->u.list.num_elements;i++) { - s = ldb_filter_from_tree(mem_ctx, tree->u.list.elements[i]); - if (s == NULL) { - talloc_free(ret); - return NULL; - } - s2 = talloc_asprintf_append(ret, "%s", s); - talloc_free(s); - if (s2 == NULL) { - talloc_free(ret); - return NULL; - } - ret = s2; - } - s = talloc_asprintf_append(ret, ")"); - if (s == NULL) { - talloc_free(ret); - return NULL; - } - return s; - case LDB_OP_NOT: - s = ldb_filter_from_tree(mem_ctx, tree->u.isnot.child); - if (s == NULL) return NULL; - - ret = talloc_asprintf(mem_ctx, "(!%s)", s); - talloc_free(s); - return ret; - case LDB_OP_EQUALITY: - s = ldb_binary_encode(mem_ctx, tree->u.equality.value); - if (s == NULL) return NULL; - ret = talloc_asprintf(mem_ctx, "(%s=%s)", - tree->u.equality.attr, s); - talloc_free(s); - return ret; - case LDB_OP_SUBSTRING: - ret = talloc_asprintf(mem_ctx, "(%s=%s", tree->u.substring.attr, - tree->u.substring.start_with_wildcard?"*":""); - if (ret == NULL) return NULL; - for (i = 0; tree->u.substring.chunks[i]; i++) { - s2 = ldb_binary_encode(mem_ctx, *(tree->u.substring.chunks[i])); - if (s2 == NULL) { - talloc_free(ret); - return NULL; - } - if (tree->u.substring.chunks[i+1] || - tree->u.substring.end_with_wildcard) { - s = talloc_asprintf_append(ret, "%s*", s2); - } else { - s = talloc_asprintf_append(ret, "%s", s2); - } - if (s == NULL) { - talloc_free(ret); - return NULL; - } - ret = s; - } - s = talloc_asprintf_append(ret, ")"); - if (s == NULL) { - talloc_free(ret); - return NULL; - } - ret = s; - return ret; - case LDB_OP_GREATER: - s = ldb_binary_encode(mem_ctx, tree->u.equality.value); - if (s == NULL) return NULL; - ret = talloc_asprintf(mem_ctx, "(%s>=%s)", - tree->u.equality.attr, s); - talloc_free(s); - return ret; - case LDB_OP_LESS: - s = ldb_binary_encode(mem_ctx, tree->u.equality.value); - if (s == NULL) return NULL; - ret = talloc_asprintf(mem_ctx, "(%s<=%s)", - tree->u.equality.attr, s); - talloc_free(s); - return ret; - case LDB_OP_PRESENT: - ret = talloc_asprintf(mem_ctx, "(%s=*)", tree->u.present.attr); - return ret; - case LDB_OP_APPROX: - s = ldb_binary_encode(mem_ctx, tree->u.equality.value); - if (s == NULL) return NULL; - ret = talloc_asprintf(mem_ctx, "(%s~=%s)", - tree->u.equality.attr, s); - talloc_free(s); - return ret; - case LDB_OP_EXTENDED: - s = ldb_binary_encode(mem_ctx, tree->u.extended.value); - if (s == NULL) return NULL; - ret = talloc_asprintf(mem_ctx, "(%s%s%s%s:=%s)", - tree->u.extended.attr?tree->u.extended.attr:"", - tree->u.extended.dnAttributes?":dn":"", - tree->u.extended.rule_id?":":"", - tree->u.extended.rule_id?tree->u.extended.rule_id:"", - s); - talloc_free(s); - return ret; - } - - return NULL; -} - - -/* - replace any occurances of an attribute name in the parse tree with a - new name -*/ -void ldb_parse_tree_attr_replace(struct ldb_parse_tree *tree, - const char *attr, - const char *replace) -{ - int i; - switch (tree->operation) { - case LDB_OP_AND: - case LDB_OP_OR: - for (i=0;i<tree->u.list.num_elements;i++) { - ldb_parse_tree_attr_replace(tree->u.list.elements[i], - attr, replace); - } - break; - case LDB_OP_NOT: - ldb_parse_tree_attr_replace(tree->u.isnot.child, attr, replace); - break; - case LDB_OP_EQUALITY: - case LDB_OP_GREATER: - case LDB_OP_LESS: - case LDB_OP_APPROX: - if (ldb_attr_cmp(tree->u.equality.attr, attr) == 0) { - tree->u.equality.attr = replace; - } - break; - case LDB_OP_SUBSTRING: - if (ldb_attr_cmp(tree->u.substring.attr, attr) == 0) { - tree->u.substring.attr = replace; - } - break; - case LDB_OP_PRESENT: - if (ldb_attr_cmp(tree->u.present.attr, attr) == 0) { - tree->u.present.attr = replace; - } - break; - case LDB_OP_EXTENDED: - if (tree->u.extended.attr && - ldb_attr_cmp(tree->u.extended.attr, attr) == 0) { - tree->u.extended.attr = replace; - } - break; - } -} diff --git a/source/lib/ldb/common/ldb_utf8.c b/source/lib/ldb/common/ldb_utf8.c deleted file mode 100644 index 86ed40535a9..00000000000 --- a/source/lib/ldb/common/ldb_utf8.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - * Name: ldb - * - * Component: ldb utf8 handling - * - * Description: case folding and case comparison for UTF8 strings - * - * Author: Andrew Tridgell - */ - -#include "includes.h" -#include "ldb/include/includes.h" -#include "system/locale.h" - - -/* - this allow the user to pass in a caseless comparison - function to handle utf8 caseless comparisons - */ -void ldb_set_utf8_fns(struct ldb_context *ldb, - void *context, - char *(*casefold)(void *, void *, const char *)) -{ - if (context) - ldb->utf8_fns.context = context; - if (casefold) - ldb->utf8_fns.casefold = casefold; -} - -/* - a simple case folding function - NOTE: does not handle UTF8 -*/ -char *ldb_casefold_default(void *context, void *mem_ctx, const char *s) -{ - int i; - char *ret = talloc_strdup(mem_ctx, s); - if (!s) { - errno = ENOMEM; - return NULL; - } - for (i=0;ret[i];i++) { - ret[i] = toupper((unsigned char)ret[i]); - } - return ret; -} - -void ldb_set_utf8_default(struct ldb_context *ldb) -{ - ldb_set_utf8_fns(ldb, NULL, ldb_casefold_default); -} - -char *ldb_casefold(struct ldb_context *ldb, void *mem_ctx, const char *s) -{ - return ldb->utf8_fns.casefold(ldb->utf8_fns.context, mem_ctx, s); -} - -/* - check the attribute name is valid according to rfc2251 - returns 1 if the name is ok - */ - -int ldb_valid_attr_name(const char *s) -{ - int i; - - if (!s || !s[0]) - return 0; - - /* handle special ldb_tdb wildcard */ - if (strcmp(s, "*") == 0) return 1; - - for (i = 0; s[i]; i++) { - if (! isascii(s[i])) { - return 0; - } - if (i == 0) { /* first char must be an alpha (or our special '@' identifier) */ - if (! (isalpha(s[i]) || (s[i] == '@'))) { - return 0; - } - } else { - if (! (isalnum(s[i]) || (s[i] == '-'))) { - return 0; - } - } - } - return 1; -} - -/* - compare two attribute names - attribute names are restricted by rfc2251 so using - strcasecmp and toupper here is ok. - return 0 for match -*/ -int ldb_attr_cmp(const char *attr1, const char *attr2) -{ - return strcasecmp(attr1, attr2); -} - -char *ldb_attr_casefold(void *mem_ctx, const char *s) -{ - int i; - char *ret = talloc_strdup(mem_ctx, s); - if (!ret) { - errno = ENOMEM; - return NULL; - } - for (i = 0; ret[i]; i++) { - ret[i] = toupper((unsigned char)ret[i]); - } - return ret; -} - -/* - we accept either 'dn' or 'distinguishedName' for a distinguishedName -*/ -int ldb_attr_dn(const char *attr) -{ - if (ldb_attr_cmp(attr, "dn") == 0 || - ldb_attr_cmp(attr, "distinguishedName") == 0) { - return 0; - } - return -1; -} diff --git a/source/lib/ldb/common/qsort.c b/source/lib/ldb/common/qsort.c deleted file mode 100644 index ef7be2c14ec..00000000000 --- a/source/lib/ldb/common/qsort.c +++ /dev/null @@ -1,254 +0,0 @@ -/* Copyright (C) 1991,1992,1996,1997,1999,2004 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Written by Douglas C. Schmidt (schmidt@ics.uci.edu). - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -/* If you consider tuning this algorithm, you should consult first: - Engineering a sort function; Jon Bentley and M. Douglas McIlroy; - Software - Practice and Experience; Vol. 23 (11), 1249-1265, 1993. */ - -/* Modified to be used in samba4 by - * Simo Sorce <idra@samba.org> 2005 - */ - -#include "includes.h" -#include "ldb/include/includes.h" - -/* Byte-wise swap two items of size SIZE. */ -#define SWAP(a, b, size) \ - do \ - { \ - register size_t __size = (size); \ - register char *__a = (a), *__b = (b); \ - do \ - { \ - char __tmp = *__a; \ - *__a++ = *__b; \ - *__b++ = __tmp; \ - } while (--__size > 0); \ - } while (0) - -/* Discontinue quicksort algorithm when partition gets below this size. - This particular magic number was chosen to work best on a Sun 4/260. */ -#define MAX_THRESH 4 - -/* Stack node declarations used to store unfulfilled partition obligations. */ -typedef struct - { - char *lo; - char *hi; - } stack_node; - -/* The next 4 #defines implement a very fast in-line stack abstraction. */ -/* The stack needs log (total_elements) entries (we could even subtract - log(MAX_THRESH)). Since total_elements has type size_t, we get as - upper bound for log (total_elements): - bits per byte (CHAR_BIT) * sizeof(size_t). */ -#ifndef CHAR_BIT -#define CHAR_BIT 8 -#endif -#define STACK_SIZE (CHAR_BIT * sizeof(size_t)) -#define PUSH(low, high) ((void) ((top->lo = (low)), (top->hi = (high)), ++top)) -#define POP(low, high) ((void) (--top, (low = top->lo), (high = top->hi))) -#define STACK_NOT_EMPTY (stack < top) - - -/* Order size using quicksort. This implementation incorporates - four optimizations discussed in Sedgewick: - - 1. Non-recursive, using an explicit stack of pointer that store the - next array partition to sort. To save time, this maximum amount - of space required to store an array of SIZE_MAX is allocated on the - stack. Assuming a 32-bit (64 bit) integer for size_t, this needs - only 32 * sizeof(stack_node) == 256 bytes (for 64 bit: 1024 bytes). - Pretty cheap, actually. - - 2. Chose the pivot element using a median-of-three decision tree. - This reduces the probability of selecting a bad pivot value and - eliminates certain extraneous comparisons. - - 3. Only quicksorts TOTAL_ELEMS / MAX_THRESH partitions, leaving - insertion sort to order the MAX_THRESH items within each partition. - This is a big win, since insertion sort is faster for small, mostly - sorted array segments. - - 4. The larger of the two sub-partitions is always pushed onto the - stack first, with the algorithm then concentrating on the - smaller partition. This *guarantees* no more than log (total_elems) - stack size is needed (actually O(1) in this case)! */ - -void ldb_qsort (void *const pbase, size_t total_elems, size_t size, - void *opaque, ldb_qsort_cmp_fn_t cmp) -{ - register char *base_ptr = (char *) pbase; - - const size_t max_thresh = MAX_THRESH * size; - - if (total_elems == 0) - /* Avoid lossage with unsigned arithmetic below. */ - return; - - if (total_elems > MAX_THRESH) - { - char *lo = base_ptr; - char *hi = &lo[size * (total_elems - 1)]; - stack_node stack[STACK_SIZE]; - stack_node *top = stack; - - PUSH (NULL, NULL); - - while (STACK_NOT_EMPTY) - { - char *left_ptr; - char *right_ptr; - - /* Select median value from among LO, MID, and HI. Rearrange - LO and HI so the three values are sorted. This lowers the - probability of picking a pathological pivot value and - skips a comparison for both the LEFT_PTR and RIGHT_PTR in - the while loops. */ - - char *mid = lo + size * ((hi - lo) / size >> 1); - - if ((*cmp) ((void *) mid, (void *) lo, opaque) < 0) - SWAP (mid, lo, size); - if ((*cmp) ((void *) hi, (void *) mid, opaque) < 0) - SWAP (mid, hi, size); - else - goto jump_over; - if ((*cmp) ((void *) mid, (void *) lo, opaque) < 0) - SWAP (mid, lo, size); - jump_over:; - - left_ptr = lo + size; - right_ptr = hi - size; - - /* Here's the famous ``collapse the walls'' section of quicksort. - Gotta like those tight inner loops! They are the main reason - that this algorithm runs much faster than others. */ - do - { - while ((*cmp) ((void *) left_ptr, (void *) mid, opaque) < 0) - left_ptr += size; - - while ((*cmp) ((void *) mid, (void *) right_ptr, opaque) < 0) - right_ptr -= size; - - if (left_ptr < right_ptr) - { - SWAP (left_ptr, right_ptr, size); - if (mid == left_ptr) - mid = right_ptr; - else if (mid == right_ptr) - mid = left_ptr; - left_ptr += size; - right_ptr -= size; - } - else if (left_ptr == right_ptr) - { - left_ptr += size; - right_ptr -= size; - break; - } - } - while (left_ptr <= right_ptr); - - /* Set up pointers for next iteration. First determine whether - left and right partitions are below the threshold size. If so, - ignore one or both. Otherwise, push the larger partition's - bounds on the stack and continue sorting the smaller one. */ - - if ((size_t) (right_ptr - lo) <= max_thresh) - { - if ((size_t) (hi - left_ptr) <= max_thresh) - /* Ignore both small partitions. */ - POP (lo, hi); - else - /* Ignore small left partition. */ - lo = left_ptr; - } - else if ((size_t) (hi - left_ptr) <= max_thresh) - /* Ignore small right partition. */ - hi = right_ptr; - else if ((right_ptr - lo) > (hi - left_ptr)) - { - /* Push larger left partition indices. */ - PUSH (lo, right_ptr); - lo = left_ptr; - } - else - { - /* Push larger right partition indices. */ - PUSH (left_ptr, hi); - hi = right_ptr; - } - } - } - - /* Once the BASE_PTR array is partially sorted by quicksort the rest - is completely sorted using insertion sort, since this is efficient - for partitions below MAX_THRESH size. BASE_PTR points to the beginning - of the array to sort, and END_PTR points at the very last element in - the array (*not* one beyond it!). */ - -#define min(x, y) ((x) < (y) ? (x) : (y)) - - { - char *const end_ptr = &base_ptr[size * (total_elems - 1)]; - char *tmp_ptr = base_ptr; - char *thresh = min(end_ptr, base_ptr + max_thresh); - register char *run_ptr; - - /* Find smallest element in first threshold and place it at the - array's beginning. This is the smallest array element, - and the operation speeds up insertion sort's inner loop. */ - - for (run_ptr = tmp_ptr + size; run_ptr <= thresh; run_ptr += size) - if ((*cmp) ((void *) run_ptr, (void *) tmp_ptr, opaque) < 0) - tmp_ptr = run_ptr; - - if (tmp_ptr != base_ptr) - SWAP (tmp_ptr, base_ptr, size); - - /* Insertion sort, running from left-hand-side up to right-hand-side. */ - - run_ptr = base_ptr + size; - while ((run_ptr += size) <= end_ptr) - { - tmp_ptr = run_ptr - size; - while ((*cmp) ((void *) run_ptr, (void *) tmp_ptr, opaque) < 0) - tmp_ptr -= size; - - tmp_ptr += size; - if (tmp_ptr != run_ptr) - { - char *trav; - - trav = run_ptr + size; - while (--trav >= run_ptr) - { - char c = *trav; - char *hi, *lo; - - for (hi = lo = trav; (lo -= size) >= tmp_ptr; hi = lo) - *hi = *lo; - *hi = c; - } - } - } - } -} diff --git a/source/lib/ldb/config.guess b/source/lib/ldb/config.guess deleted file mode 100755 index ad5281e66e9..00000000000 --- a/source/lib/ldb/config.guess +++ /dev/null @@ -1,1466 +0,0 @@ -#! /bin/sh -# Attempt to guess a canonical system name. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. - -timestamp='2005-08-03' - -# This file 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., 51 Franklin Street - Fifth Floor, Boston, MA -# 02110-1301, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - - -# Originally written by Per Bothner <per@bothner.com>. -# Please send patches to <config-patches@gnu.org>. Submit a context -# diff and a properly formatted ChangeLog entry. -# -# This script attempts to guess a canonical system name similar to -# config.sub. If it succeeds, it prints the system name on stdout, and -# exits with 0. Otherwise, it exits with 1. -# -# The plan is that this can be called by configure scripts if you -# don't specify an explicit build system type. - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] - -Output the configuration name of the system \`$me' is run on. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to <config-patches@gnu.org>." - -version="\ -GNU config.guess ($timestamp) - -Originally written by Per Bothner. -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 -Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit ;; - --version | -v ) - echo "$version" ; exit ;; - --help | --h* | -h ) - echo "$usage"; exit ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" >&2 - exit 1 ;; - * ) - break ;; - esac -done - -if test $# != 0; then - echo "$me: too many arguments$help" >&2 - exit 1 -fi - -trap 'exit 1' 1 2 15 - -# CC_FOR_BUILD -- compiler used by this script. Note that the use of a -# compiler to aid in system detection is discouraged as it requires -# temporary files to be created and, as you can see below, it is a -# headache to deal with in a portable fashion. - -# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still -# use `HOST_CC' if defined, but it is deprecated. - -# Portable tmp directory creation inspired by the Autoconf team. - -set_cc_for_build=' -trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; -trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; -: ${TMPDIR=/tmp} ; - { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || - { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || - { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || - { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; -dummy=$tmp/dummy ; -tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; -case $CC_FOR_BUILD,$HOST_CC,$CC in - ,,) echo "int x;" > $dummy.c ; - for c in cc gcc c89 c99 ; do - if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then - CC_FOR_BUILD="$c"; break ; - fi ; - done ; - if test x"$CC_FOR_BUILD" = x ; then - CC_FOR_BUILD=no_compiler_found ; - fi - ;; - ,,*) CC_FOR_BUILD=$CC ;; - ,*,*) CC_FOR_BUILD=$HOST_CC ;; -esac ; set_cc_for_build= ;' - -# This is needed to find uname on a Pyramid OSx when run in the BSD universe. -# (ghazi@noc.rutgers.edu 1994-08-24) -if (test -f /.attbin/uname) >/dev/null 2>&1 ; then - PATH=$PATH:/.attbin ; export PATH -fi - -UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown -UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown -UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown -UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown - -# Note: order is significant - the case branches are not exclusive. - -case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in - *:NetBSD:*:*) - # NetBSD (nbsd) targets should (where applicable) match one or - # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, - # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently - # switched to ELF, *-*-netbsd* would select the old - # object file format. This provides both forward - # compatibility and a consistent mechanism for selecting the - # object file format. - # - # Note: NetBSD doesn't particularly care about the vendor - # portion of the name. We always set it to "unknown". - sysctl="sysctl -n hw.machine_arch" - UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ - /usr/sbin/$sysctl 2>/dev/null || echo unknown)` - case "${UNAME_MACHINE_ARCH}" in - armeb) machine=armeb-unknown ;; - arm*) machine=arm-unknown ;; - sh3el) machine=shl-unknown ;; - sh3eb) machine=sh-unknown ;; - *) machine=${UNAME_MACHINE_ARCH}-unknown ;; - esac - # The Operating System including object format, if it has switched - # to ELF recently, or will in the future. - case "${UNAME_MACHINE_ARCH}" in - arm*|i386|m68k|ns32k|sh3*|sparc|vax) - eval $set_cc_for_build - if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep __ELF__ >/dev/null - then - # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). - # Return netbsd for either. FIX? - os=netbsd - else - os=netbsdelf - fi - ;; - *) - os=netbsd - ;; - esac - # The OS release - # Debian GNU/NetBSD machines have a different userland, and - # thus, need a distinct triplet. However, they do not need - # kernel version information, so it can be replaced with a - # suitable tag, in the style of linux-gnu. - case "${UNAME_VERSION}" in - Debian*) - release='-gnu' - ;; - *) - release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` - ;; - esac - # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: - # contains redundant information, the shorter form: - # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}" - exit ;; - *:OpenBSD:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} - exit ;; - *:ekkoBSD:*:*) - echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} - exit ;; - macppc:MirBSD:*:*) - echo powerppc-unknown-mirbsd${UNAME_RELEASE} - exit ;; - *:MirBSD:*:*) - echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} - exit ;; - alpha:OSF1:*:*) - case $UNAME_RELEASE in - *4.0) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` - ;; - *5.*) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` - ;; - esac - # According to Compaq, /usr/sbin/psrinfo has been available on - # OSF/1 and Tru64 systems produced since 1995. I hope that - # covers most systems running today. This code pipes the CPU - # types through head -n 1, so we only detect the type of CPU 0. - ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` - case "$ALPHA_CPU_TYPE" in - "EV4 (21064)") - UNAME_MACHINE="alpha" ;; - "EV4.5 (21064)") - UNAME_MACHINE="alpha" ;; - "LCA4 (21066/21068)") - UNAME_MACHINE="alpha" ;; - "EV5 (21164)") - UNAME_MACHINE="alphaev5" ;; - "EV5.6 (21164A)") - UNAME_MACHINE="alphaev56" ;; - "EV5.6 (21164PC)") - UNAME_MACHINE="alphapca56" ;; - "EV5.7 (21164PC)") - UNAME_MACHINE="alphapca57" ;; - "EV6 (21264)") - UNAME_MACHINE="alphaev6" ;; - "EV6.7 (21264A)") - UNAME_MACHINE="alphaev67" ;; - "EV6.8CB (21264C)") - UNAME_MACHINE="alphaev68" ;; - "EV6.8AL (21264B)") - UNAME_MACHINE="alphaev68" ;; - "EV6.8CX (21264D)") - UNAME_MACHINE="alphaev68" ;; - "EV6.9A (21264/EV69A)") - UNAME_MACHINE="alphaev69" ;; - "EV7 (21364)") - UNAME_MACHINE="alphaev7" ;; - "EV7.9 (21364A)") - UNAME_MACHINE="alphaev79" ;; - esac - # A Pn.n version is a patched version. - # A Vn.n version is a released version. - # A Tn.n version is a released field test version. - # A Xn.n version is an unreleased experimental baselevel. - # 1.2 uses "1.2" for uname -r. - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - exit ;; - Alpha\ *:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # Should we change UNAME_MACHINE based on the output of uname instead - # of the specific Alpha model? - echo alpha-pc-interix - exit ;; - 21064:Windows_NT:50:3) - echo alpha-dec-winnt3.5 - exit ;; - Amiga*:UNIX_System_V:4.0:*) - echo m68k-unknown-sysv4 - exit ;; - *:[Aa]miga[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-amigaos - exit ;; - *:[Mm]orph[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-morphos - exit ;; - *:OS/390:*:*) - echo i370-ibm-openedition - exit ;; - *:z/VM:*:*) - echo s390-ibm-zvmoe - exit ;; - *:OS400:*:*) - echo powerpc-ibm-os400 - exit ;; - arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) - echo arm-acorn-riscix${UNAME_RELEASE} - exit ;; - arm:riscos:*:*|arm:RISCOS:*:*) - echo arm-unknown-riscos - exit ;; - SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) - echo hppa1.1-hitachi-hiuxmpp - exit ;; - Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) - # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. - if test "`(/bin/universe) 2>/dev/null`" = att ; then - echo pyramid-pyramid-sysv3 - else - echo pyramid-pyramid-bsd - fi - exit ;; - NILE*:*:*:dcosx) - echo pyramid-pyramid-svr4 - exit ;; - DRS?6000:unix:4.0:6*) - echo sparc-icl-nx6 - exit ;; - DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) - case `/usr/bin/uname -p` in - sparc) echo sparc-icl-nx7; exit ;; - esac ;; - sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - i86pc:SunOS:5.*:*) - echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:6*:*) - # According to config.sub, this is the proper way to canonicalize - # SunOS6. Hard to guess exactly what SunOS6 will be like, but - # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:*:*) - case "`/usr/bin/arch -k`" in - Series*|S4*) - UNAME_RELEASE=`uname -v` - ;; - esac - # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` - exit ;; - sun3*:SunOS:*:*) - echo m68k-sun-sunos${UNAME_RELEASE} - exit ;; - sun*:*:4.2BSD:*) - UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 - case "`/bin/arch`" in - sun3) - echo m68k-sun-sunos${UNAME_RELEASE} - ;; - sun4) - echo sparc-sun-sunos${UNAME_RELEASE} - ;; - esac - exit ;; - aushp:SunOS:*:*) - echo sparc-auspex-sunos${UNAME_RELEASE} - exit ;; - # The situation for MiNT is a little confusing. The machine name - # can be virtually everything (everything which is not - # "atarist" or "atariste" at least should have a processor - # > m68000). The system name ranges from "MiNT" over "FreeMiNT" - # to the lowercase version "mint" (or "freemint"). Finally - # the system name "TOS" denotes a system which is actually not - # MiNT. But MiNT is downward compatible to TOS, so this should - # be no problem. - atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} - exit ;; - hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} - exit ;; - *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} - exit ;; - m68k:machten:*:*) - echo m68k-apple-machten${UNAME_RELEASE} - exit ;; - powerpc:machten:*:*) - echo powerpc-apple-machten${UNAME_RELEASE} - exit ;; - RISC*:Mach:*:*) - echo mips-dec-mach_bsd4.3 - exit ;; - RISC*:ULTRIX:*:*) - echo mips-dec-ultrix${UNAME_RELEASE} - exit ;; - VAX*:ULTRIX*:*:*) - echo vax-dec-ultrix${UNAME_RELEASE} - exit ;; - 2020:CLIX:*:* | 2430:CLIX:*:*) - echo clipper-intergraph-clix${UNAME_RELEASE} - exit ;; - mips:*:*:UMIPS | mips:*:*:RISCos) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c -#ifdef __cplusplus -#include <stdio.h> /* for printf() prototype */ - int main (int argc, char *argv[]) { -#else - int main (argc, argv) int argc; char *argv[]; { -#endif - #if defined (host_mips) && defined (MIPSEB) - #if defined (SYSTYPE_SYSV) - printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_SVR4) - printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) - printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); - #endif - #endif - exit (-1); - } -EOF - $CC_FOR_BUILD -o $dummy $dummy.c && - dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && - SYSTEM_NAME=`$dummy $dummyarg` && - { echo "$SYSTEM_NAME"; exit; } - echo mips-mips-riscos${UNAME_RELEASE} - exit ;; - Motorola:PowerMAX_OS:*:*) - echo powerpc-motorola-powermax - exit ;; - Motorola:*:4.3:PL8-*) - echo powerpc-harris-powermax - exit ;; - Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) - echo powerpc-harris-powermax - exit ;; - Night_Hawk:Power_UNIX:*:*) - echo powerpc-harris-powerunix - exit ;; - m88k:CX/UX:7*:*) - echo m88k-harris-cxux7 - exit ;; - m88k:*:4*:R4*) - echo m88k-motorola-sysv4 - exit ;; - m88k:*:3*:R3*) - echo m88k-motorola-sysv3 - exit ;; - AViiON:dgux:*:*) - # DG/UX returns AViiON for all architectures - UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] - then - if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ - [ ${TARGET_BINARY_INTERFACE}x = x ] - then - echo m88k-dg-dgux${UNAME_RELEASE} - else - echo m88k-dg-dguxbcs${UNAME_RELEASE} - fi - else - echo i586-dg-dgux${UNAME_RELEASE} - fi - exit ;; - M88*:DolphinOS:*:*) # DolphinOS (SVR3) - echo m88k-dolphin-sysv3 - exit ;; - M88*:*:R3*:*) - # Delta 88k system running SVR3 - echo m88k-motorola-sysv3 - exit ;; - XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) - echo m88k-tektronix-sysv3 - exit ;; - Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) - echo m68k-tektronix-bsd - exit ;; - *:IRIX*:*:*) - echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` - exit ;; - ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. - echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id - exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' - i*86:AIX:*:*) - echo i386-ibm-aix - exit ;; - ia64:AIX:*:*) - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} - exit ;; - *:AIX:2:3) - if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include <sys/systemcfg.h> - - main() - { - if (!__power_pc()) - exit(1); - puts("powerpc-ibm-aix3.2.5"); - exit(0); - } -EOF - if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` - then - echo "$SYSTEM_NAME" - else - echo rs6000-ibm-aix3.2.5 - fi - elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then - echo rs6000-ibm-aix3.2.4 - else - echo rs6000-ibm-aix3.2 - fi - exit ;; - *:AIX:*:[45]) - IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` - if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then - IBM_ARCH=rs6000 - else - IBM_ARCH=powerpc - fi - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${IBM_ARCH}-ibm-aix${IBM_REV} - exit ;; - *:AIX:*:*) - echo rs6000-ibm-aix - exit ;; - ibmrt:4.4BSD:*|romp-ibm:BSD:*) - echo romp-ibm-bsd4.4 - exit ;; - ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and - echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to - exit ;; # report: romp-ibm BSD 4.3 - *:BOSX:*:*) - echo rs6000-bull-bosx - exit ;; - DPX/2?00:B.O.S.:*:*) - echo m68k-bull-sysv3 - exit ;; - 9000/[34]??:4.3bsd:1.*:*) - echo m68k-hp-bsd - exit ;; - hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) - echo m68k-hp-bsd4.4 - exit ;; - 9000/[34678]??:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - case "${UNAME_MACHINE}" in - 9000/31? ) HP_ARCH=m68000 ;; - 9000/[34]?? ) HP_ARCH=m68k ;; - 9000/[678][0-9][0-9]) - if [ -x /usr/bin/getconf ]; then - sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` - sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "${sc_cpu_version}" in - 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 - 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 - 532) # CPU_PA_RISC2_0 - case "${sc_kernel_bits}" in - 32) HP_ARCH="hppa2.0n" ;; - 64) HP_ARCH="hppa2.0w" ;; - '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 - esac ;; - esac - fi - if [ "${HP_ARCH}" = "" ]; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - - #define _HPUX_SOURCE - #include <stdlib.h> - #include <unistd.h> - - int main () - { - #if defined(_SC_KERNEL_BITS) - long bits = sysconf(_SC_KERNEL_BITS); - #endif - long cpu = sysconf (_SC_CPU_VERSION); - - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1"); break; - case CPU_PA_RISC2_0: - #if defined(_SC_KERNEL_BITS) - switch (bits) - { - case 64: puts ("hppa2.0w"); break; - case 32: puts ("hppa2.0n"); break; - default: puts ("hppa2.0"); break; - } break; - #else /* !defined(_SC_KERNEL_BITS) */ - puts ("hppa2.0"); break; - #endif - default: puts ("hppa1.0"); break; - } - exit (0); - } -EOF - (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` - test -z "$HP_ARCH" && HP_ARCH=hppa - fi ;; - esac - if [ ${HP_ARCH} = "hppa2.0w" ] - then - eval $set_cc_for_build - - # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating - # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler - # generating 64-bit code. GNU and HP use different nomenclature: - # - # $ CC_FOR_BUILD=cc ./config.guess - # => hppa2.0w-hp-hpux11.23 - # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess - # => hppa64-hp-hpux11.23 - - if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | - grep __LP64__ >/dev/null - then - HP_ARCH="hppa2.0w" - else - HP_ARCH="hppa64" - fi - fi - echo ${HP_ARCH}-hp-hpux${HPUX_REV} - exit ;; - ia64:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - echo ia64-hp-hpux${HPUX_REV} - exit ;; - 3050*:HI-UX:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include <unistd.h> - int - main () - { - long cpu = sysconf (_SC_CPU_VERSION); - /* The order matters, because CPU_IS_HP_MC68K erroneously returns - true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct - results, however. */ - if (CPU_IS_PA_RISC (cpu)) - { - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; - case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; - default: puts ("hppa-hitachi-hiuxwe2"); break; - } - } - else if (CPU_IS_HP_MC68K (cpu)) - puts ("m68k-hitachi-hiuxwe2"); - else puts ("unknown-hitachi-hiuxwe2"); - exit (0); - } -EOF - $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && - { echo "$SYSTEM_NAME"; exit; } - echo unknown-hitachi-hiuxwe2 - exit ;; - 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) - echo hppa1.1-hp-bsd - exit ;; - 9000/8??:4.3bsd:*:*) - echo hppa1.0-hp-bsd - exit ;; - *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) - echo hppa1.0-hp-mpeix - exit ;; - hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) - echo hppa1.1-hp-osf - exit ;; - hp8??:OSF1:*:*) - echo hppa1.0-hp-osf - exit ;; - i*86:OSF1:*:*) - if [ -x /usr/sbin/sysversion ] ; then - echo ${UNAME_MACHINE}-unknown-osf1mk - else - echo ${UNAME_MACHINE}-unknown-osf1 - fi - exit ;; - parisc*:Lites*:*:*) - echo hppa1.1-hp-lites - exit ;; - C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) - echo c1-convex-bsd - exit ;; - C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit ;; - C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) - echo c34-convex-bsd - exit ;; - C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) - echo c38-convex-bsd - exit ;; - C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) - echo c4-convex-bsd - exit ;; - CRAY*Y-MP:*:*:*) - echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*[A-Z]90:*:*:*) - echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ - | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ - -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ - -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*TS:*:*:*) - echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*T3E:*:*:*) - echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*SV1:*:*:*) - echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - *:UNICOS/mp:*:*) - echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) - FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` - echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; - 5000:UNIX_System_V:4.*:*) - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` - echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; - i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) - echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} - exit ;; - sparc*:BSD/OS:*:*) - echo sparc-unknown-bsdi${UNAME_RELEASE} - exit ;; - *:BSD/OS:*:*) - echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} - exit ;; - *:FreeBSD:*:*) - echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` - exit ;; - i*:CYGWIN*:*) - echo ${UNAME_MACHINE}-pc-cygwin - exit ;; - i*:MINGW*:*) - echo ${UNAME_MACHINE}-pc-mingw32 - exit ;; - i*:windows32*:*) - # uname -m includes "-pc" on this system. - echo ${UNAME_MACHINE}-mingw32 - exit ;; - i*:PW*:*) - echo ${UNAME_MACHINE}-pc-pw32 - exit ;; - x86:Interix*:[34]*) - echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//' - exit ;; - [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) - echo i${UNAME_MACHINE}-pc-mks - exit ;; - i*:Windows_NT*:* | Pentium*:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we - # UNAME_MACHINE based on the output of uname instead of i386? - echo i586-pc-interix - exit ;; - i*:UWIN*:*) - echo ${UNAME_MACHINE}-pc-uwin - exit ;; - amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) - echo x86_64-unknown-cygwin - exit ;; - p*:CYGWIN*:*) - echo powerpcle-unknown-cygwin - exit ;; - prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - *:GNU:*:*) - # the GNU system - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` - exit ;; - *:GNU/*:*:*) - # other systems with GNU libc and userland - echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu - exit ;; - i*86:Minix:*:*) - echo ${UNAME_MACHINE}-pc-minix - exit ;; - arm*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - cris:Linux:*:*) - echo cris-axis-linux-gnu - exit ;; - crisv32:Linux:*:*) - echo crisv32-axis-linux-gnu - exit ;; - frv:Linux:*:*) - echo frv-unknown-linux-gnu - exit ;; - ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - m32r*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - mips:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef mips - #undef mipsel - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=mipsel - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=mips - #else - CPU= - #endif - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } - ;; - mips64:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef mips64 - #undef mips64el - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=mips64el - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=mips64 - #else - CPU= - #endif - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } - ;; - or32:Linux:*:*) - echo or32-unknown-linux-gnu - exit ;; - ppc:Linux:*:*) - echo powerpc-unknown-linux-gnu - exit ;; - ppc64:Linux:*:*) - echo powerpc64-unknown-linux-gnu - exit ;; - alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in - EV5) UNAME_MACHINE=alphaev5 ;; - EV56) UNAME_MACHINE=alphaev56 ;; - PCA56) UNAME_MACHINE=alphapca56 ;; - PCA57) UNAME_MACHINE=alphapca56 ;; - EV6) UNAME_MACHINE=alphaev6 ;; - EV67) UNAME_MACHINE=alphaev67 ;; - EV68*) UNAME_MACHINE=alphaev68 ;; - esac - objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null - if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi - echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} - exit ;; - parisc:Linux:*:* | hppa:Linux:*:*) - # Look for CPU level - case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-gnu ;; - PA8*) echo hppa2.0-unknown-linux-gnu ;; - *) echo hppa-unknown-linux-gnu ;; - esac - exit ;; - parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-gnu - exit ;; - s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux - exit ;; - sh64*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - sh*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - sparc:Linux:*:* | sparc64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - x86_64:Linux:*:*) - echo x86_64-unknown-linux-gnu - exit ;; - i*86:Linux:*:*) - # The BFD linker knows what the default object file format is, so - # first see if it will tell us. cd to the root directory to prevent - # problems with other programs or directories called `ld' in the path. - # Set LC_ALL=C to ensure ld outputs messages in English. - ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ - | sed -ne '/supported targets:/!d - s/[ ][ ]*/ /g - s/.*supported targets: *// - s/ .*// - p'` - case "$ld_supported_targets" in - elf32-i386) - TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" - ;; - a.out-i386-linux) - echo "${UNAME_MACHINE}-pc-linux-gnuaout" - exit ;; - coff-i386) - echo "${UNAME_MACHINE}-pc-linux-gnucoff" - exit ;; - "") - # Either a pre-BFD a.out linker (linux-gnuoldld) or - # one that does not give us useful --help. - echo "${UNAME_MACHINE}-pc-linux-gnuoldld" - exit ;; - esac - # Determine whether the default compiler is a.out or elf - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include <features.h> - #ifdef __ELF__ - # ifdef __GLIBC__ - # if __GLIBC__ >= 2 - LIBC=gnu - # else - LIBC=gnulibc1 - # endif - # else - LIBC=gnulibc1 - # endif - #else - #ifdef __INTEL_COMPILER - LIBC=gnu - #else - LIBC=gnuaout - #endif - #endif - #ifdef __dietlibc__ - LIBC=dietlibc - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` - test x"${LIBC}" != x && { - echo "${UNAME_MACHINE}-pc-linux-${LIBC}" - exit - } - test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } - ;; - i*86:DYNIX/ptx:4*:*) - # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. - # earlier versions are messed up and put the nodename in both - # sysname and nodename. - echo i386-sequent-sysv4 - exit ;; - i*86:UNIX_SV:4.2MP:2.*) - # Unixware is an offshoot of SVR4, but it has its own version - # number series starting with 2... - # I am not positive that other SVR4 systems won't match this, - # I just have to hope. -- rms. - # Use sysv4.2uw... so that sysv4* matches it. - echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} - exit ;; - i*86:OS/2:*:*) - # If we were able to find `uname', then EMX Unix compatibility - # is probably installed. - echo ${UNAME_MACHINE}-pc-os2-emx - exit ;; - i*86:XTS-300:*:STOP) - echo ${UNAME_MACHINE}-unknown-stop - exit ;; - i*86:atheos:*:*) - echo ${UNAME_MACHINE}-unknown-atheos - exit ;; - i*86:syllable:*:*) - echo ${UNAME_MACHINE}-pc-syllable - exit ;; - i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) - echo i386-unknown-lynxos${UNAME_RELEASE} - exit ;; - i*86:*DOS:*:*) - echo ${UNAME_MACHINE}-pc-msdosdjgpp - exit ;; - i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) - UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` - if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} - else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} - fi - exit ;; - i*86:*:5:[678]*) - # UnixWare 7.x, OpenUNIX and OpenServer 6. - case `/bin/uname -X | grep "^Machine"` in - *486*) UNAME_MACHINE=i486 ;; - *Pentium) UNAME_MACHINE=i586 ;; - *Pent*|*Celeron) UNAME_MACHINE=i686 ;; - esac - echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} - exit ;; - i*86:*:3.2:*) - if test -f /usr/options/cb.name; then - UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name` - echo ${UNAME_MACHINE}-pc-isc$UNAME_REL - elif /bin/uname -X 2>/dev/null >/dev/null ; then - UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` - (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 - (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ - && UNAME_MACHINE=i586 - (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ - && UNAME_MACHINE=i686 - (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ - && UNAME_MACHINE=i686 - echo ${UNAME_MACHINE}-pc-sco$UNAME_REL - else - echo ${UNAME_MACHINE}-pc-sysv32 - fi - exit ;; - pc:*:*:*) - # Left here for compatibility: - # uname -m prints for DJGPP always 'pc', but it prints nothing about - # the processor, so we play safe by assuming i386. - echo i386-pc-msdosdjgpp - exit ;; - Intel:Mach:3*:*) - echo i386-pc-mach3 - exit ;; - paragon:*:*:*) - echo i860-intel-osf1 - exit ;; - i860:*:4.*:*) # i860-SVR4 - if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then - echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 - else # Add other i860-SVR4 vendors below as they are discovered. - echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 - fi - exit ;; - mini*:CTIX:SYS*5:*) - # "miniframe" - echo m68010-convergent-sysv - exit ;; - mc68k:UNIX:SYSTEM5:3.51m) - echo m68k-convergent-sysv - exit ;; - M680?0:D-NIX:5.3:*) - echo m68k-diab-dnix - exit ;; - M68*:*:R3V[5678]*:*) - test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; - 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) - OS_REL='' - test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; - 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4; exit; } ;; - m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - echo m68k-unknown-lynxos${UNAME_RELEASE} - exit ;; - mc68030:UNIX_System_V:4.*:*) - echo m68k-atari-sysv4 - exit ;; - TSUNAMI:LynxOS:2.*:*) - echo sparc-unknown-lynxos${UNAME_RELEASE} - exit ;; - rs6000:LynxOS:2.*:*) - echo rs6000-unknown-lynxos${UNAME_RELEASE} - exit ;; - PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) - echo powerpc-unknown-lynxos${UNAME_RELEASE} - exit ;; - SM[BE]S:UNIX_SV:*:*) - echo mips-dde-sysv${UNAME_RELEASE} - exit ;; - RM*:ReliantUNIX-*:*:*) - echo mips-sni-sysv4 - exit ;; - RM*:SINIX-*:*:*) - echo mips-sni-sysv4 - exit ;; - *:SINIX-*:*:*) - if uname -p 2>/dev/null >/dev/null ; then - UNAME_MACHINE=`(uname -p) 2>/dev/null` - echo ${UNAME_MACHINE}-sni-sysv4 - else - echo ns32k-sni-sysv - fi - exit ;; - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort - # says <Richard.M.Bartel@ccMail.Census.GOV> - echo i586-unisys-sysv4 - exit ;; - *:UNIX_System_V:4*:FTX*) - # From Gerald Hewes <hewes@openmarket.com>. - # How about differentiating between stratus architectures? -djm - echo hppa1.1-stratus-sysv4 - exit ;; - *:*:*:FTX*) - # From seanf@swdc.stratus.com. - echo i860-stratus-sysv4 - exit ;; - i*86:VOS:*:*) - # From Paul.Green@stratus.com. - echo ${UNAME_MACHINE}-stratus-vos - exit ;; - *:VOS:*:*) - # From Paul.Green@stratus.com. - echo hppa1.1-stratus-vos - exit ;; - mc68*:A/UX:*:*) - echo m68k-apple-aux${UNAME_RELEASE} - exit ;; - news*:NEWS-OS:6*:*) - echo mips-sony-newsos6 - exit ;; - R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) - if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} - else - echo mips-unknown-sysv${UNAME_RELEASE} - fi - exit ;; - BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. - echo powerpc-be-beos - exit ;; - BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. - echo powerpc-apple-beos - exit ;; - BePC:BeOS:*:*) # BeOS running on Intel PC compatible. - echo i586-pc-beos - exit ;; - SX-4:SUPER-UX:*:*) - echo sx4-nec-superux${UNAME_RELEASE} - exit ;; - SX-5:SUPER-UX:*:*) - echo sx5-nec-superux${UNAME_RELEASE} - exit ;; - SX-6:SUPER-UX:*:*) - echo sx6-nec-superux${UNAME_RELEASE} - exit ;; - Power*:Rhapsody:*:*) - echo powerpc-apple-rhapsody${UNAME_RELEASE} - exit ;; - *:Rhapsody:*:*) - echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} - exit ;; - *:Darwin:*:*) - UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - case $UNAME_PROCESSOR in - *86) UNAME_PROCESSOR=i686 ;; - unknown) UNAME_PROCESSOR=powerpc ;; - esac - echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} - exit ;; - *:procnto*:*:* | *:QNX:[0123456789]*:*) - UNAME_PROCESSOR=`uname -p` - if test "$UNAME_PROCESSOR" = "x86"; then - UNAME_PROCESSOR=i386 - UNAME_MACHINE=pc - fi - echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} - exit ;; - *:QNX:*:4*) - echo i386-pc-qnx - exit ;; - NSE-?:NONSTOP_KERNEL:*:*) - echo nse-tandem-nsk${UNAME_RELEASE} - exit ;; - NSR-?:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk${UNAME_RELEASE} - exit ;; - *:NonStop-UX:*:*) - echo mips-compaq-nonstopux - exit ;; - BS2000:POSIX*:*:*) - echo bs2000-siemens-sysv - exit ;; - DS/*:UNIX_System_V:*:*) - echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} - exit ;; - *:Plan9:*:*) - # "uname -m" is not consistent, so use $cputype instead. 386 - # is converted to i386 for consistency with other x86 - # operating systems. - if test "$cputype" = "386"; then - UNAME_MACHINE=i386 - else - UNAME_MACHINE="$cputype" - fi - echo ${UNAME_MACHINE}-unknown-plan9 - exit ;; - *:TOPS-10:*:*) - echo pdp10-unknown-tops10 - exit ;; - *:TENEX:*:*) - echo pdp10-unknown-tenex - exit ;; - KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) - echo pdp10-dec-tops20 - exit ;; - XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) - echo pdp10-xkl-tops20 - exit ;; - *:TOPS-20:*:*) - echo pdp10-unknown-tops20 - exit ;; - *:ITS:*:*) - echo pdp10-unknown-its - exit ;; - SEI:*:*:SEIUX) - echo mips-sei-seiux${UNAME_RELEASE} - exit ;; - *:DragonFly:*:*) - echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` - exit ;; - *:*VMS:*:*) - UNAME_MACHINE=`(uname -p) 2>/dev/null` - case "${UNAME_MACHINE}" in - A*) echo alpha-dec-vms ; exit ;; - I*) echo ia64-dec-vms ; exit ;; - V*) echo vax-dec-vms ; exit ;; - esac ;; - *:XENIX:*:SysV) - echo i386-pc-xenix - exit ;; - i*86:skyos:*:*) - echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' - exit ;; -esac - -#echo '(No uname command or uname output not recognized.)' 1>&2 -#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 - -eval $set_cc_for_build -cat >$dummy.c <<EOF -#ifdef _SEQUENT_ -# include <sys/types.h> -# include <sys/utsname.h> -#endif -main () -{ -#if defined (sony) -#if defined (MIPSEB) - /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, - I don't know.... */ - printf ("mips-sony-bsd\n"); exit (0); -#else -#include <sys/param.h> - printf ("m68k-sony-newsos%s\n", -#ifdef NEWSOS4 - "4" -#else - "" -#endif - ); exit (0); -#endif -#endif - -#if defined (__arm) && defined (__acorn) && defined (__unix) - printf ("arm-acorn-riscix\n"); exit (0); -#endif - -#if defined (hp300) && !defined (hpux) - printf ("m68k-hp-bsd\n"); exit (0); -#endif - -#if defined (NeXT) -#if !defined (__ARCHITECTURE__) -#define __ARCHITECTURE__ "m68k" -#endif - int version; - version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; - if (version < 4) - printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); - else - printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); - exit (0); -#endif - -#if defined (MULTIMAX) || defined (n16) -#if defined (UMAXV) - printf ("ns32k-encore-sysv\n"); exit (0); -#else -#if defined (CMU) - printf ("ns32k-encore-mach\n"); exit (0); -#else - printf ("ns32k-encore-bsd\n"); exit (0); -#endif -#endif -#endif - -#if defined (__386BSD__) - printf ("i386-pc-bsd\n"); exit (0); -#endif - -#if defined (sequent) -#if defined (i386) - printf ("i386-sequent-dynix\n"); exit (0); -#endif -#if defined (ns32000) - printf ("ns32k-sequent-dynix\n"); exit (0); -#endif -#endif - -#if defined (_SEQUENT_) - struct utsname un; - - uname(&un); - - if (strncmp(un.version, "V2", 2) == 0) { - printf ("i386-sequent-ptx2\n"); exit (0); - } - if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ - printf ("i386-sequent-ptx1\n"); exit (0); - } - printf ("i386-sequent-ptx\n"); exit (0); - -#endif - -#if defined (vax) -# if !defined (ultrix) -# include <sys/param.h> -# if defined (BSD) -# if BSD == 43 - printf ("vax-dec-bsd4.3\n"); exit (0); -# else -# if BSD == 199006 - printf ("vax-dec-bsd4.3reno\n"); exit (0); -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# endif -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# else - printf ("vax-dec-ultrix\n"); exit (0); -# endif -#endif - -#if defined (alliant) && defined (i860) - printf ("i860-alliant-bsd\n"); exit (0); -#endif - - exit (1); -} -EOF - -$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && - { echo "$SYSTEM_NAME"; exit; } - -# Apollos put the system type in the environment. - -test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } - -# Convex versions that predate uname can use getsysinfo(1) - -if [ -x /usr/convex/getsysinfo ] -then - case `getsysinfo -f cpu_type` in - c1*) - echo c1-convex-bsd - exit ;; - c2*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit ;; - c34*) - echo c34-convex-bsd - exit ;; - c38*) - echo c38-convex-bsd - exit ;; - c4*) - echo c4-convex-bsd - exit ;; - esac -fi - -cat >&2 <<EOF -$0: unable to guess system type - -This script, last modified $timestamp, has failed to recognize -the operating system you are using. It is advised that you -download the most up to date version of the config scripts from - - http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess -and - http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub - -If the version you run ($0) is already up to date, please -send the following data and any information you think might be -pertinent to <config-patches@gnu.org> in order to provide the needed -information to handle your system. - -config.guess timestamp = $timestamp - -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null` - -hostinfo = `(hostinfo) 2>/dev/null` -/bin/universe = `(/bin/universe) 2>/dev/null` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` -/bin/arch = `(/bin/arch) 2>/dev/null` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` - -UNAME_MACHINE = ${UNAME_MACHINE} -UNAME_RELEASE = ${UNAME_RELEASE} -UNAME_SYSTEM = ${UNAME_SYSTEM} -UNAME_VERSION = ${UNAME_VERSION} -EOF - -exit 1 - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/source/lib/ldb/config.mk b/source/lib/ldb/config.mk deleted file mode 100644 index cd80adf7213..00000000000 --- a/source/lib/ldb/config.mk +++ /dev/null @@ -1,315 +0,0 @@ -################################################ -# Start MODULE ldb_asq -[MODULE::ldb_asq] -PRIVATE_DEPENDENCIES = LIBTALLOC -INIT_FUNCTION = ldb_asq_init -SUBSYSTEM = ldb -OBJ_FILES = \ - modules/asq.o -# End MODULE ldb_asq -################################################ - -################################################ -# Start MODULE ldb_server_sort -[MODULE::ldb_server_sort] -PRIVATE_DEPENDENCIES = LIBTALLOC -INIT_FUNCTION = ldb_sort_init -SUBSYSTEM = ldb -OBJ_FILES = \ - modules/sort.o -# End MODULE ldb_sort -################################################ - -################################################ -# Start MODULE ldb_paged_results -[MODULE::ldb_paged_results] -INIT_FUNCTION = ldb_paged_results_init -PRIVATE_DEPENDENCIES = LIBTALLOC -SUBSYSTEM = ldb -OBJ_FILES = \ - modules/paged_results.o -# End MODULE ldb_paged_results -################################################ - -################################################ -# Start MODULE ldb_paged_results -[MODULE::ldb_paged_searches] -INIT_FUNCTION = ldb_paged_searches_init -PRIVATE_DEPENDENCIES = LIBTALLOC -SUBSYSTEM = ldb -OBJ_FILES = \ - modules/paged_searches.o -# End MODULE ldb_paged_results -################################################ - -################################################ -# Start MODULE ldb_operational -[MODULE::ldb_operational] -SUBSYSTEM = ldb -PRIVATE_DEPENDENCIES = LIBTALLOC -INIT_FUNCTION = ldb_operational_init -OBJ_FILES = \ - modules/operational.o -# End MODULE ldb_operational -################################################ - -################################################ -# Start MODULE ldb_objectclass -[MODULE::ldb_objectclass] -INIT_FUNCTION = ldb_objectclass_init -PRIVATE_DEPENDENCIES = LIBTALLOC -SUBSYSTEM = ldb -OBJ_FILES = \ - modules/objectclass.o -# End MODULE ldb_objectclass -################################################ - -################################################ -# Start MODULE ldb_rdn_name -[MODULE::ldb_rdn_name] -SUBSYSTEM = ldb -PRIVATE_DEPENDENCIES = LIBTALLOC -INIT_FUNCTION = ldb_rdn_name_init -OBJ_FILES = \ - modules/rdn_name.o -# End MODULE ldb_rdn_name -################################################ - -################################################ -# Start MODULE ldb_ildap -[MODULE::ldb_ildap] -SUBSYSTEM = ldb -PRIVATE_DEPENDENCIES = LIBTALLOC -INIT_FUNCTION = ldb_ildap_init -ALIASES = ldapi ldaps ldap -OBJ_FILES = \ - ldb_ildap/ldb_ildap.o -PUBLIC_DEPENDENCIES = \ - LIBCLI_LDAP -# End MODULE ldb_ildap -################################################ - -################################################ -# Start MODULE ldb_map -[MODULE::ldb_map] -PRIVATE_DEPENDENCIES = LIBTALLOC -SUBSYSTEM = ldb -OBJ_FILES = \ - modules/ldb_map_inbound.o \ - modules/ldb_map_outbound.o \ - modules/ldb_map.o -# End MODULE ldb_map -################################################ - -################################################ -# Start MODULE ldb_skel -[MODULE::ldb_skel] -SUBSYSTEM = ldb -PRIVATE_DEPENDENCIES = LIBTALLOC -INIT_FUNCTION = ldb_skel_init -OBJ_FILES = modules/skel.o -# End MODULE ldb_skel -################################################ - -################################################ -# Start MODULE ldb_sqlite3 -[MODULE::ldb_sqlite3] -SUBSYSTEM = ldb -PRIVATE_DEPENDENCIES = LIBTALLOC -INIT_FUNCTION = ldb_sqlite3_init -OBJ_FILES = \ - ldb_sqlite3/ldb_sqlite3.o -PUBLIC_DEPENDENCIES = \ - SQLITE3 LIBTALLOC -# End MODULE ldb_sqlite3 -################################################ - -################################################ -# Start MODULE ldb_tdb -[MODULE::ldb_tdb] -SUBSYSTEM = ldb -INIT_FUNCTION = ldb_tdb_init -OBJ_FILES = \ - ldb_tdb/ldb_tdb.o \ - ldb_tdb/ldb_search.o \ - ldb_tdb/ldb_pack.o \ - ldb_tdb/ldb_index.o \ - ldb_tdb/ldb_cache.o \ - ldb_tdb/ldb_tdb_wrap.o -PUBLIC_DEPENDENCIES = \ - LIBTDB LIBTALLOC -# End MODULE ldb_tdb -################################################ - -./lib/ldb/common/ldb_modules.o: lib/ldb/common/ldb_modules.c Makefile - @echo Compiling $< - @$(CC) -Iinclude $(CFLAGS) -Ilib/replace -Ilib/talloc -Ilib/ldb $(PICFLAG) -DLDBMODULESDIR=\"$(MODULESDIR)/ldb\" -DSHLIBEXT=\"$(SHLIBEXT)\" -c $< -o $@ - -################################################ -# Start SUBSYSTEM ldb -[LIBRARY::ldb] -VERSION = 0.0.1 -SO_VERSION = 0 -DESCRIPTION = LDAP-like embedded database library -INIT_FUNCTION_TYPE = int (*) (void) -OBJ_FILES = \ - common/ldb.o \ - common/ldb_ldif.o \ - common/ldb_parse.o \ - common/ldb_msg.o \ - common/ldb_utf8.o \ - common/ldb_debug.o \ - common/ldb_modules.o \ - common/ldb_match.o \ - common/ldb_attributes.o \ - common/attrib_handlers.o \ - common/ldb_dn.o \ - common/ldb_controls.o \ - common/qsort.o -PUBLIC_DEPENDENCIES = \ - LIBTALLOC \ - DYNCONFIG \ - SOCKET_WRAPPER -MANPAGE = man/ldb.3 -PUBLIC_HEADERS = include/ldb.h include/ldb_errors.h -# -# End SUBSYSTEM ldb -################################################ - -################################################ -# Start SUBSYSTEM LDBSAMBA -[SUBSYSTEM::LDBSAMBA] -PRIVATE_DEPENDENCIES = ldb -PRIVATE_PROTO_HEADER = samba/ldif_handlers.h -PUBLIC_DEPENDENCIES = LIBSECURITY SAMDB -OBJ_FILES = \ - samba/ldif_handlers.o -# End SUBSYSTEM LDBSAMBA -################################################ - -################################################ -# Start SUBSYSTEM LIBLDB_CMDLINE -[SUBSYSTEM::LIBLDB_CMDLINE] -OBJ_FILES= \ - tools/cmdline.o -PUBLIC_DEPENDENCIES = ldb LIBSAMBA-UTIL LIBPOPT POPT_SAMBA POPT_CREDENTIALS -PRIVATE_DEPENDENCIES = gensec -# End SUBSYSTEM LIBLDB_CMDLINE -################################################ - -################################################ -# Start BINARY ldbadd -[BINARY::ldbadd] -INSTALLDIR = BINDIR -OBJ_FILES = \ - tools/ldbadd.o -PRIVATE_DEPENDENCIES = \ - LIBLDB_CMDLINE LIBCLI_RESOLVE -MANPAGE = man/ldbadd.1 -# End BINARY ldbadd -################################################ - -################################################ -# Start BINARY ldbdel -[BINARY::ldbdel] -INSTALLDIR = BINDIR -OBJ_FILES= \ - tools/ldbdel.o -PRIVATE_DEPENDENCIES = \ - LIBLDB_CMDLINE -MANPAGE = man/ldbdel.1 -# End BINARY ldbdel -################################################ - -################################################ -# Start BINARY ldbmodify -[BINARY::ldbmodify] -INSTALLDIR = BINDIR -OBJ_FILES= \ - tools/ldbmodify.o -PRIVATE_DEPENDENCIES = \ - LIBLDB_CMDLINE -MANPAGE = man/ldbmodify.1 -# End BINARY ldbmodify -################################################ - -################################################ -# Start BINARY ldbsearch -[BINARY::ldbsearch] -INSTALLDIR = BINDIR -OBJ_FILES= \ - tools/ldbsearch.o -PRIVATE_DEPENDENCIES = \ - LIBLDB_CMDLINE -MANPAGE = man/ldbsearch.1 -# End BINARY ldbsearch -################################################ - -################################################ -# Start BINARY ldbedit -[BINARY::ldbedit] -INSTALLDIR = BINDIR -OBJ_FILES= \ - tools/ldbedit.o -PRIVATE_DEPENDENCIES = \ - LIBLDB_CMDLINE -MANPAGE = man/ldbedit.1 -# End BINARY ldbedit -################################################ - -################################################ -# Start BINARY ldbrename -[BINARY::ldbrename] -INSTALLDIR = BINDIR -OBJ_FILES= \ - tools/ldbrename.o -PRIVATE_DEPENDENCIES = \ - LIBLDB_CMDLINE -MANPAGE = man/ldbrename.1 -# End BINARY ldbrename -################################################ - -################################################ -# Start BINARY ldbtest -[BINARY::ldbtest] -OBJ_FILES= \ - tools/ldbtest.o -PRIVATE_DEPENDENCIES = \ - LIBLDB_CMDLINE -# End BINARY ldbtest -################################################ - -################################################ -# Start BINARY oLschema2ldif -[BINARY::oLschema2ldif] -INSTALLDIR = BINDIR -MANPAGE = man/oLschema2ldif.1 -OBJ_FILES= \ - tools/convert.o \ - tools/oLschema2ldif.o -PRIVATE_DEPENDENCIES = \ - LIBLDB_CMDLINE -# End BINARY oLschema2ldif -################################################ - -################################################ -# Start BINARY ad2oLschema -[BINARY::ad2oLschema] -INSTALLDIR = BINDIR -MANPAGE = man/ad2oLschema.1 -OBJ_FILES= \ - tools/convert.o \ - tools/ad2oLschema.o -PRIVATE_DEPENDENCIES = \ - LIBLDB_CMDLINE -# End BINARY ad2oLschema -################################################ - -####################### -# Start LIBRARY swig_ldb -[LIBRARY::swig_ldb] -PUBLIC_DEPENDENCIES = ldb DYNCONFIG -LIBRARY_REALNAME = swig/_ldb.$(SHLIBEXT) -OBJ_FILES = swig/ldb_wrap.o -# End LIBRARY swig_ldb -####################### diff --git a/source/lib/ldb/config.sub b/source/lib/ldb/config.sub deleted file mode 100755 index 1c366dfde9a..00000000000 --- a/source/lib/ldb/config.sub +++ /dev/null @@ -1,1579 +0,0 @@ -#! /bin/sh -# Configuration validation subroutine script. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. - -timestamp='2005-07-08' - -# This file is (in principle) common to ALL GNU software. -# The presence of a machine in this file suggests that SOME GNU software -# can handle that machine. It does not imply ALL GNU software can. -# -# This file 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., 51 Franklin Street - Fifth Floor, Boston, MA -# 02110-1301, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - - -# Please send patches to <config-patches@gnu.org>. Submit a context -# diff and a properly formatted ChangeLog entry. -# -# Configuration subroutine to validate and canonicalize a configuration type. -# Supply the specified configuration type as an argument. -# If it is invalid, we print an error message on stderr and exit with code 1. -# Otherwise, we print the canonical config type on stdout and succeed. - -# This file is supposed to be the same for all GNU packages -# and recognize all the CPU types, system types and aliases -# that are meaningful with *any* GNU software. -# Each package is responsible for reporting which valid configurations -# it does not support. The user should be able to distinguish -# a failure to support a valid configuration from a meaningless -# configuration. - -# The goal of this file is to map all the various variations of a given -# machine specification into a single specification in the form: -# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM -# or in some cases, the newer four-part form: -# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM -# It is wrong to echo any other type of specification. - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] CPU-MFR-OPSYS - $0 [OPTION] ALIAS - -Canonicalize a configuration name. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to <config-patches@gnu.org>." - -version="\ -GNU config.sub ($timestamp) - -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 -Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit ;; - --version | -v ) - echo "$version" ; exit ;; - --help | --h* | -h ) - echo "$usage"; exit ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" - exit 1 ;; - - *local*) - # First pass through any local machine types. - echo $1 - exit ;; - - * ) - break ;; - esac -done - -case $# in - 0) echo "$me: missing argument$help" >&2 - exit 1;; - 1) ;; - *) echo "$me: too many arguments$help" >&2 - exit 1;; -esac - -# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). -# Here we must recognize all the valid KERNEL-OS combinations. -maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` -case $maybe_os in - nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \ - kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*) - os=-$maybe_os - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` - ;; - *) - basic_machine=`echo $1 | sed 's/-[^-]*$//'` - if [ $basic_machine != $1 ] - then os=`echo $1 | sed 's/.*-/-/'` - else os=; fi - ;; -esac - -### Let's recognize common machines as not being operating systems so -### that things like config.sub decstation-3100 work. We also -### recognize some manufacturers as not being operating systems, so we -### can provide default operating systems below. -case $os in - -sun*os*) - # Prevent following clause from handling this invalid input. - ;; - -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ - -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ - -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ - -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ - -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ - -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ - -apple | -axis | -knuth | -cray) - os= - basic_machine=$1 - ;; - -sim | -cisco | -oki | -wec | -winbond) - os= - basic_machine=$1 - ;; - -scout) - ;; - -wrs) - os=-vxworks - basic_machine=$1 - ;; - -chorusos*) - os=-chorusos - basic_machine=$1 - ;; - -chorusrdb) - os=-chorusrdb - basic_machine=$1 - ;; - -hiux*) - os=-hiuxwe2 - ;; - -sco5) - os=-sco3.2v5 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco4) - os=-sco3.2v4 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2.[4-9]*) - os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2v[4-9]*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco*) - os=-sco3.2v2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -udk*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -isc) - os=-isc2.2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -clix*) - basic_machine=clipper-intergraph - ;; - -isc*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -lynx*) - os=-lynxos - ;; - -ptx*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` - ;; - -windowsnt*) - os=`echo $os | sed -e 's/windowsnt/winnt/'` - ;; - -psos*) - os=-psos - ;; - -mint | -mint[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; -esac - -# Decode aliases for certain CPU-COMPANY combinations. -case $basic_machine in - # Recognize the basic CPU types without company name. - # Some are omitted here because they have special meanings below. - 1750a | 580 \ - | a29k \ - | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ - | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ - | am33_2.0 \ - | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ - | bfin \ - | c4x | clipper \ - | d10v | d30v | dlx | dsp16xx \ - | fr30 | frv \ - | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ - | i370 | i860 | i960 | ia64 \ - | ip2k | iq2000 \ - | m32r | m32rle | m68000 | m68k | m88k | maxq | mcore \ - | mips | mipsbe | mipseb | mipsel | mipsle \ - | mips16 \ - | mips64 | mips64el \ - | mips64vr | mips64vrel \ - | mips64orion | mips64orionel \ - | mips64vr4100 | mips64vr4100el \ - | mips64vr4300 | mips64vr4300el \ - | mips64vr5000 | mips64vr5000el \ - | mips64vr5900 | mips64vr5900el \ - | mipsisa32 | mipsisa32el \ - | mipsisa32r2 | mipsisa32r2el \ - | mipsisa64 | mipsisa64el \ - | mipsisa64r2 | mipsisa64r2el \ - | mipsisa64sb1 | mipsisa64sb1el \ - | mipsisa64sr71k | mipsisa64sr71kel \ - | mipstx39 | mipstx39el \ - | mn10200 | mn10300 \ - | ms1 \ - | msp430 \ - | ns16k | ns32k \ - | or32 \ - | pdp10 | pdp11 | pj | pjl \ - | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ - | pyramid \ - | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ - | sh64 | sh64le \ - | sparc | sparc64 | sparc64b | sparc86x | sparclet | sparclite \ - | sparcv8 | sparcv9 | sparcv9b \ - | strongarm \ - | tahoe | thumb | tic4x | tic80 | tron \ - | v850 | v850e \ - | we32k \ - | x86 | xscale | xscalee[bl] | xstormy16 | xtensa \ - | z8k) - basic_machine=$basic_machine-unknown - ;; - m32c) - basic_machine=$basic_machine-unknown - ;; - m6811 | m68hc11 | m6812 | m68hc12) - # Motorola 68HC11/12. - basic_machine=$basic_machine-unknown - os=-none - ;; - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) - ;; - - # We use `pc' rather than `unknown' - # because (1) that's what they normally are, and - # (2) the word "unknown" tends to confuse beginning users. - i*86 | x86_64) - basic_machine=$basic_machine-pc - ;; - # Object if more than one company name word. - *-*-*) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; - # Recognize the basic CPU types with company name. - 580-* \ - | a29k-* \ - | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ - | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ - | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ - | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ - | avr-* \ - | bfin-* | bs2000-* \ - | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ - | clipper-* | craynv-* | cydra-* \ - | d10v-* | d30v-* | dlx-* \ - | elxsi-* \ - | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ - | h8300-* | h8500-* \ - | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ - | i*86-* | i860-* | i960-* | ia64-* \ - | ip2k-* | iq2000-* \ - | m32r-* | m32rle-* \ - | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | maxq-* | mcore-* \ - | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ - | mips16-* \ - | mips64-* | mips64el-* \ - | mips64vr-* | mips64vrel-* \ - | mips64orion-* | mips64orionel-* \ - | mips64vr4100-* | mips64vr4100el-* \ - | mips64vr4300-* | mips64vr4300el-* \ - | mips64vr5000-* | mips64vr5000el-* \ - | mips64vr5900-* | mips64vr5900el-* \ - | mipsisa32-* | mipsisa32el-* \ - | mipsisa32r2-* | mipsisa32r2el-* \ - | mipsisa64-* | mipsisa64el-* \ - | mipsisa64r2-* | mipsisa64r2el-* \ - | mipsisa64sb1-* | mipsisa64sb1el-* \ - | mipsisa64sr71k-* | mipsisa64sr71kel-* \ - | mipstx39-* | mipstx39el-* \ - | mmix-* \ - | ms1-* \ - | msp430-* \ - | none-* | np1-* | ns16k-* | ns32k-* \ - | orion-* \ - | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ - | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ - | pyramid-* \ - | romp-* | rs6000-* \ - | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | shbe-* \ - | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ - | sparc-* | sparc64-* | sparc64b-* | sparc86x-* | sparclet-* \ - | sparclite-* \ - | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ - | tahoe-* | thumb-* \ - | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ - | tron-* \ - | v850-* | v850e-* | vax-* \ - | we32k-* \ - | x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \ - | xstormy16-* | xtensa-* \ - | ymp-* \ - | z8k-*) - ;; - m32c-*) - ;; - # Recognize the various machine names and aliases which stand - # for a CPU type and a company and sometimes even an OS. - 386bsd) - basic_machine=i386-unknown - os=-bsd - ;; - 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) - basic_machine=m68000-att - ;; - 3b*) - basic_machine=we32k-att - ;; - a29khif) - basic_machine=a29k-amd - os=-udi - ;; - abacus) - basic_machine=abacus-unknown - ;; - adobe68k) - basic_machine=m68010-adobe - os=-scout - ;; - alliant | fx80) - basic_machine=fx80-alliant - ;; - altos | altos3068) - basic_machine=m68k-altos - ;; - am29k) - basic_machine=a29k-none - os=-bsd - ;; - amd64) - basic_machine=x86_64-pc - ;; - amd64-*) - basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - amdahl) - basic_machine=580-amdahl - os=-sysv - ;; - amiga | amiga-*) - basic_machine=m68k-unknown - ;; - amigaos | amigados) - basic_machine=m68k-unknown - os=-amigaos - ;; - amigaunix | amix) - basic_machine=m68k-unknown - os=-sysv4 - ;; - apollo68) - basic_machine=m68k-apollo - os=-sysv - ;; - apollo68bsd) - basic_machine=m68k-apollo - os=-bsd - ;; - aux) - basic_machine=m68k-apple - os=-aux - ;; - balance) - basic_machine=ns32k-sequent - os=-dynix - ;; - c90) - basic_machine=c90-cray - os=-unicos - ;; - convex-c1) - basic_machine=c1-convex - os=-bsd - ;; - convex-c2) - basic_machine=c2-convex - os=-bsd - ;; - convex-c32) - basic_machine=c32-convex - os=-bsd - ;; - convex-c34) - basic_machine=c34-convex - os=-bsd - ;; - convex-c38) - basic_machine=c38-convex - os=-bsd - ;; - cray | j90) - basic_machine=j90-cray - os=-unicos - ;; - craynv) - basic_machine=craynv-cray - os=-unicosmp - ;; - cr16c) - basic_machine=cr16c-unknown - os=-elf - ;; - crds | unos) - basic_machine=m68k-crds - ;; - crisv32 | crisv32-* | etraxfs*) - basic_machine=crisv32-axis - ;; - cris | cris-* | etrax*) - basic_machine=cris-axis - ;; - crx) - basic_machine=crx-unknown - os=-elf - ;; - da30 | da30-*) - basic_machine=m68k-da30 - ;; - decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) - basic_machine=mips-dec - ;; - decsystem10* | dec10*) - basic_machine=pdp10-dec - os=-tops10 - ;; - decsystem20* | dec20*) - basic_machine=pdp10-dec - os=-tops20 - ;; - delta | 3300 | motorola-3300 | motorola-delta \ - | 3300-motorola | delta-motorola) - basic_machine=m68k-motorola - ;; - delta88) - basic_machine=m88k-motorola - os=-sysv3 - ;; - djgpp) - basic_machine=i586-pc - os=-msdosdjgpp - ;; - dpx20 | dpx20-*) - basic_machine=rs6000-bull - os=-bosx - ;; - dpx2* | dpx2*-bull) - basic_machine=m68k-bull - os=-sysv3 - ;; - ebmon29k) - basic_machine=a29k-amd - os=-ebmon - ;; - elxsi) - basic_machine=elxsi-elxsi - os=-bsd - ;; - encore | umax | mmax) - basic_machine=ns32k-encore - ;; - es1800 | OSE68k | ose68k | ose | OSE) - basic_machine=m68k-ericsson - os=-ose - ;; - fx2800) - basic_machine=i860-alliant - ;; - genix) - basic_machine=ns32k-ns - ;; - gmicro) - basic_machine=tron-gmicro - os=-sysv - ;; - go32) - basic_machine=i386-pc - os=-go32 - ;; - h3050r* | hiux*) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - h8300hms) - basic_machine=h8300-hitachi - os=-hms - ;; - h8300xray) - basic_machine=h8300-hitachi - os=-xray - ;; - h8500hms) - basic_machine=h8500-hitachi - os=-hms - ;; - harris) - basic_machine=m88k-harris - os=-sysv3 - ;; - hp300-*) - basic_machine=m68k-hp - ;; - hp300bsd) - basic_machine=m68k-hp - os=-bsd - ;; - hp300hpux) - basic_machine=m68k-hp - os=-hpux - ;; - hp3k9[0-9][0-9] | hp9[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k2[0-9][0-9] | hp9k31[0-9]) - basic_machine=m68000-hp - ;; - hp9k3[2-9][0-9]) - basic_machine=m68k-hp - ;; - hp9k6[0-9][0-9] | hp6[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k7[0-79][0-9] | hp7[0-79][0-9]) - basic_machine=hppa1.1-hp - ;; - hp9k78[0-9] | hp78[0-9]) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][13679] | hp8[0-9][13679]) - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][0-9] | hp8[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hppa-next) - os=-nextstep3 - ;; - hppaosf) - basic_machine=hppa1.1-hp - os=-osf - ;; - hppro) - basic_machine=hppa1.1-hp - os=-proelf - ;; - i370-ibm* | ibm*) - basic_machine=i370-ibm - ;; -# I'm not sure what "Sysv32" means. Should this be sysv3.2? - i*86v32) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv32 - ;; - i*86v4*) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv4 - ;; - i*86v) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv - ;; - i*86sol2) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-solaris2 - ;; - i386mach) - basic_machine=i386-mach - os=-mach - ;; - i386-vsta | vsta) - basic_machine=i386-unknown - os=-vsta - ;; - iris | iris4d) - basic_machine=mips-sgi - case $os in - -irix*) - ;; - *) - os=-irix4 - ;; - esac - ;; - isi68 | isi) - basic_machine=m68k-isi - os=-sysv - ;; - m88k-omron*) - basic_machine=m88k-omron - ;; - magnum | m3230) - basic_machine=mips-mips - os=-sysv - ;; - merlin) - basic_machine=ns32k-utek - os=-sysv - ;; - mingw32) - basic_machine=i386-pc - os=-mingw32 - ;; - miniframe) - basic_machine=m68000-convergent - ;; - *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; - mips3*-*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` - ;; - mips3*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown - ;; - monitor) - basic_machine=m68k-rom68k - os=-coff - ;; - morphos) - basic_machine=powerpc-unknown - os=-morphos - ;; - msdos) - basic_machine=i386-pc - os=-msdos - ;; - mvs) - basic_machine=i370-ibm - os=-mvs - ;; - ncr3000) - basic_machine=i486-ncr - os=-sysv4 - ;; - netbsd386) - basic_machine=i386-unknown - os=-netbsd - ;; - netwinder) - basic_machine=armv4l-rebel - os=-linux - ;; - news | news700 | news800 | news900) - basic_machine=m68k-sony - os=-newsos - ;; - news1000) - basic_machine=m68030-sony - os=-newsos - ;; - news-3600 | risc-news) - basic_machine=mips-sony - os=-newsos - ;; - necv70) - basic_machine=v70-nec - os=-sysv - ;; - next | m*-next ) - basic_machine=m68k-next - case $os in - -nextstep* ) - ;; - -ns2*) - os=-nextstep2 - ;; - *) - os=-nextstep3 - ;; - esac - ;; - nh3000) - basic_machine=m68k-harris - os=-cxux - ;; - nh[45]000) - basic_machine=m88k-harris - os=-cxux - ;; - nindy960) - basic_machine=i960-intel - os=-nindy - ;; - mon960) - basic_machine=i960-intel - os=-mon960 - ;; - nonstopux) - basic_machine=mips-compaq - os=-nonstopux - ;; - np1) - basic_machine=np1-gould - ;; - nsr-tandem) - basic_machine=nsr-tandem - ;; - op50n-* | op60c-*) - basic_machine=hppa1.1-oki - os=-proelf - ;; - openrisc | openrisc-*) - basic_machine=or32-unknown - ;; - os400) - basic_machine=powerpc-ibm - os=-os400 - ;; - OSE68000 | ose68000) - basic_machine=m68000-ericsson - os=-ose - ;; - os68k) - basic_machine=m68k-none - os=-os68k - ;; - pa-hitachi) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - paragon) - basic_machine=i860-intel - os=-osf - ;; - pbd) - basic_machine=sparc-tti - ;; - pbb) - basic_machine=m68k-tti - ;; - pc532 | pc532-*) - basic_machine=ns32k-pc532 - ;; - pentium | p5 | k5 | k6 | nexgen | viac3) - basic_machine=i586-pc - ;; - pentiumpro | p6 | 6x86 | athlon | athlon_*) - basic_machine=i686-pc - ;; - pentiumii | pentium2 | pentiumiii | pentium3) - basic_machine=i686-pc - ;; - pentium4) - basic_machine=i786-pc - ;; - pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) - basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumpro-* | p6-* | 6x86-* | athlon-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentium4-*) - basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pn) - basic_machine=pn-gould - ;; - power) basic_machine=power-ibm - ;; - ppc) basic_machine=powerpc-unknown - ;; - ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppcle | powerpclittle | ppc-le | powerpc-little) - basic_machine=powerpcle-unknown - ;; - ppcle-* | powerpclittle-*) - basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64) basic_machine=powerpc64-unknown - ;; - ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64le | powerpc64little | ppc64-le | powerpc64-little) - basic_machine=powerpc64le-unknown - ;; - ppc64le-* | powerpc64little-*) - basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ps2) - basic_machine=i386-ibm - ;; - pw32) - basic_machine=i586-unknown - os=-pw32 - ;; - rom68k) - basic_machine=m68k-rom68k - os=-coff - ;; - rm[46]00) - basic_machine=mips-siemens - ;; - rtpc | rtpc-*) - basic_machine=romp-ibm - ;; - s390 | s390-*) - basic_machine=s390-ibm - ;; - s390x | s390x-*) - basic_machine=s390x-ibm - ;; - sa29200) - basic_machine=a29k-amd - os=-udi - ;; - sb1) - basic_machine=mipsisa64sb1-unknown - ;; - sb1el) - basic_machine=mipsisa64sb1el-unknown - ;; - sei) - basic_machine=mips-sei - os=-seiux - ;; - sequent) - basic_machine=i386-sequent - ;; - sh) - basic_machine=sh-hitachi - os=-hms - ;; - sh64) - basic_machine=sh64-unknown - ;; - sparclite-wrs | simso-wrs) - basic_machine=sparclite-wrs - os=-vxworks - ;; - sps7) - basic_machine=m68k-bull - os=-sysv2 - ;; - spur) - basic_machine=spur-unknown - ;; - st2000) - basic_machine=m68k-tandem - ;; - stratus) - basic_machine=i860-stratus - os=-sysv4 - ;; - sun2) - basic_machine=m68000-sun - ;; - sun2os3) - basic_machine=m68000-sun - os=-sunos3 - ;; - sun2os4) - basic_machine=m68000-sun - os=-sunos4 - ;; - sun3os3) - basic_machine=m68k-sun - os=-sunos3 - ;; - sun3os4) - basic_machine=m68k-sun - os=-sunos4 - ;; - sun4os3) - basic_machine=sparc-sun - os=-sunos3 - ;; - sun4os4) - basic_machine=sparc-sun - os=-sunos4 - ;; - sun4sol2) - basic_machine=sparc-sun - os=-solaris2 - ;; - sun3 | sun3-*) - basic_machine=m68k-sun - ;; - sun4) - basic_machine=sparc-sun - ;; - sun386 | sun386i | roadrunner) - basic_machine=i386-sun - ;; - sv1) - basic_machine=sv1-cray - os=-unicos - ;; - symmetry) - basic_machine=i386-sequent - os=-dynix - ;; - t3e) - basic_machine=alphaev5-cray - os=-unicos - ;; - t90) - basic_machine=t90-cray - os=-unicos - ;; - tic54x | c54x*) - basic_machine=tic54x-unknown - os=-coff - ;; - tic55x | c55x*) - basic_machine=tic55x-unknown - os=-coff - ;; - tic6x | c6x*) - basic_machine=tic6x-unknown - os=-coff - ;; - tx39) - basic_machine=mipstx39-unknown - ;; - tx39el) - basic_machine=mipstx39el-unknown - ;; - toad1) - basic_machine=pdp10-xkl - os=-tops20 - ;; - tower | tower-32) - basic_machine=m68k-ncr - ;; - tpf) - basic_machine=s390x-ibm - os=-tpf - ;; - udi29k) - basic_machine=a29k-amd - os=-udi - ;; - ultra3) - basic_machine=a29k-nyu - os=-sym1 - ;; - v810 | necv810) - basic_machine=v810-nec - os=-none - ;; - vaxv) - basic_machine=vax-dec - os=-sysv - ;; - vms) - basic_machine=vax-dec - os=-vms - ;; - vpp*|vx|vx-*) - basic_machine=f301-fujitsu - ;; - vxworks960) - basic_machine=i960-wrs - os=-vxworks - ;; - vxworks68) - basic_machine=m68k-wrs - os=-vxworks - ;; - vxworks29k) - basic_machine=a29k-wrs - os=-vxworks - ;; - w65*) - basic_machine=w65-wdc - os=-none - ;; - w89k-*) - basic_machine=hppa1.1-winbond - os=-proelf - ;; - xbox) - basic_machine=i686-pc - os=-mingw32 - ;; - xps | xps100) - basic_machine=xps100-honeywell - ;; - ymp) - basic_machine=ymp-cray - os=-unicos - ;; - z8k-*-coff) - basic_machine=z8k-unknown - os=-sim - ;; - none) - basic_machine=none-none - os=-none - ;; - -# Here we handle the default manufacturer of certain CPU types. It is in -# some cases the only manufacturer, in others, it is the most popular. - w89k) - basic_machine=hppa1.1-winbond - ;; - op50n) - basic_machine=hppa1.1-oki - ;; - op60c) - basic_machine=hppa1.1-oki - ;; - romp) - basic_machine=romp-ibm - ;; - mmix) - basic_machine=mmix-knuth - ;; - rs6000) - basic_machine=rs6000-ibm - ;; - vax) - basic_machine=vax-dec - ;; - pdp10) - # there are many clones, so DEC is not a safe bet - basic_machine=pdp10-unknown - ;; - pdp11) - basic_machine=pdp11-dec - ;; - we32k) - basic_machine=we32k-att - ;; - sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele) - basic_machine=sh-unknown - ;; - sparc | sparcv8 | sparcv9 | sparcv9b) - basic_machine=sparc-sun - ;; - cydra) - basic_machine=cydra-cydrome - ;; - orion) - basic_machine=orion-highlevel - ;; - orion105) - basic_machine=clipper-highlevel - ;; - mac | mpw | mac-mpw) - basic_machine=m68k-apple - ;; - pmac | pmac-mpw) - basic_machine=powerpc-apple - ;; - *-unknown) - # Make sure to match an already-canonicalized machine name. - ;; - *) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; -esac - -# Here we canonicalize certain aliases for manufacturers. -case $basic_machine in - *-digital*) - basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` - ;; - *-commodore*) - basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` - ;; - *) - ;; -esac - -# Decode manufacturer-specific aliases for certain operating systems. - -if [ x"$os" != x"" ] -then -case $os in - # First match some system type aliases - # that might get confused with valid system types. - # -solaris* is a basic system type, with this one exception. - -solaris1 | -solaris1.*) - os=`echo $os | sed -e 's|solaris1|sunos4|'` - ;; - -solaris) - os=-solaris2 - ;; - -svr4*) - os=-sysv4 - ;; - -unixware*) - os=-sysv4.2uw - ;; - -gnu/linux*) - os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` - ;; - # First accept the basic system types. - # The portable systems comes first. - # Each alternative MUST END IN A *, to match a version number. - # -sysv* is not here because it comes later, after sysvr4. - -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ - | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ - | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ - | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ - | -aos* \ - | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ - | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ - | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \ - | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ - | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ - | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ - | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ - | -chorusos* | -chorusrdb* \ - | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \ - | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ - | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ - | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ - | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ - | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ - | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ - | -skyos* | -haiku*) - # Remember, each alternative MUST END IN *, to match a version number. - ;; - -qnx*) - case $basic_machine in - x86-* | i*86-*) - ;; - *) - os=-nto$os - ;; - esac - ;; - -nto-qnx*) - ;; - -nto*) - os=`echo $os | sed -e 's|nto|nto-qnx|'` - ;; - -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ - | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ - | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) - ;; - -mac*) - os=`echo $os | sed -e 's|mac|macos|'` - ;; - -linux-dietlibc) - os=-linux-dietlibc - ;; - -linux*) - os=`echo $os | sed -e 's|linux|linux-gnu|'` - ;; - -sunos5*) - os=`echo $os | sed -e 's|sunos5|solaris2|'` - ;; - -sunos6*) - os=`echo $os | sed -e 's|sunos6|solaris3|'` - ;; - -opened*) - os=-openedition - ;; - -os400*) - os=-os400 - ;; - -wince*) - os=-wince - ;; - -osfrose*) - os=-osfrose - ;; - -osf*) - os=-osf - ;; - -utek*) - os=-bsd - ;; - -dynix*) - os=-bsd - ;; - -acis*) - os=-aos - ;; - -atheos*) - os=-atheos - ;; - -syllable*) - os=-syllable - ;; - -386bsd) - os=-bsd - ;; - -ctix* | -uts*) - os=-sysv - ;; - -nova*) - os=-rtmk-nova - ;; - -ns2 ) - os=-nextstep2 - ;; - -nsk*) - os=-nsk - ;; - # Preserve the version number of sinix5. - -sinix5.*) - os=`echo $os | sed -e 's|sinix|sysv|'` - ;; - -sinix*) - os=-sysv4 - ;; - -tpf*) - os=-tpf - ;; - -triton*) - os=-sysv3 - ;; - -oss*) - os=-sysv3 - ;; - -svr4) - os=-sysv4 - ;; - -svr3) - os=-sysv3 - ;; - -sysvr4) - os=-sysv4 - ;; - # This must come after -sysvr4. - -sysv*) - ;; - -ose*) - os=-ose - ;; - -es1800*) - os=-ose - ;; - -xenix) - os=-xenix - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - os=-mint - ;; - -aros*) - os=-aros - ;; - -kaos*) - os=-kaos - ;; - -zvmoe) - os=-zvmoe - ;; - -none) - ;; - *) - # Get rid of the `-' at the beginning of $os. - os=`echo $os | sed 's/[^-]*-//'` - echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 - exit 1 - ;; -esac -else - -# Here we handle the default operating systems that come with various machines. -# The value should be what the vendor currently ships out the door with their -# machine or put another way, the most popular os provided with the machine. - -# Note that if you're going to try to match "-MANUFACTURER" here (say, -# "-sun"), then you have to tell the case statement up towards the top -# that MANUFACTURER isn't an operating system. Otherwise, code above -# will signal an error saying that MANUFACTURER isn't an operating -# system, and we'll never get to this point. - -case $basic_machine in - *-acorn) - os=-riscix1.2 - ;; - arm*-rebel) - os=-linux - ;; - arm*-semi) - os=-aout - ;; - c4x-* | tic4x-*) - os=-coff - ;; - # This must come before the *-dec entry. - pdp10-*) - os=-tops20 - ;; - pdp11-*) - os=-none - ;; - *-dec | vax-*) - os=-ultrix4.2 - ;; - m68*-apollo) - os=-domain - ;; - i386-sun) - os=-sunos4.0.2 - ;; - m68000-sun) - os=-sunos3 - # This also exists in the configure program, but was not the - # default. - # os=-sunos4 - ;; - m68*-cisco) - os=-aout - ;; - mips*-cisco) - os=-elf - ;; - mips*-*) - os=-elf - ;; - or32-*) - os=-coff - ;; - *-tti) # must be before sparc entry or we get the wrong os. - os=-sysv3 - ;; - sparc-* | *-sun) - os=-sunos4.1.1 - ;; - *-be) - os=-beos - ;; - *-haiku) - os=-haiku - ;; - *-ibm) - os=-aix - ;; - *-knuth) - os=-mmixware - ;; - *-wec) - os=-proelf - ;; - *-winbond) - os=-proelf - ;; - *-oki) - os=-proelf - ;; - *-hp) - os=-hpux - ;; - *-hitachi) - os=-hiux - ;; - i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) - os=-sysv - ;; - *-cbm) - os=-amigaos - ;; - *-dg) - os=-dgux - ;; - *-dolphin) - os=-sysv3 - ;; - m68k-ccur) - os=-rtu - ;; - m88k-omron*) - os=-luna - ;; - *-next ) - os=-nextstep - ;; - *-sequent) - os=-ptx - ;; - *-crds) - os=-unos - ;; - *-ns) - os=-genix - ;; - i370-*) - os=-mvs - ;; - *-next) - os=-nextstep3 - ;; - *-gould) - os=-sysv - ;; - *-highlevel) - os=-bsd - ;; - *-encore) - os=-bsd - ;; - *-sgi) - os=-irix - ;; - *-siemens) - os=-sysv4 - ;; - *-masscomp) - os=-rtu - ;; - f30[01]-fujitsu | f700-fujitsu) - os=-uxpv - ;; - *-rom68k) - os=-coff - ;; - *-*bug) - os=-coff - ;; - *-apple) - os=-macos - ;; - *-atari*) - os=-mint - ;; - *) - os=-none - ;; -esac -fi - -# Here we handle the case where we know the os, and the CPU type, but not the -# manufacturer. We pick the logical manufacturer. -vendor=unknown -case $basic_machine in - *-unknown) - case $os in - -riscix*) - vendor=acorn - ;; - -sunos*) - vendor=sun - ;; - -aix*) - vendor=ibm - ;; - -beos*) - vendor=be - ;; - -hpux*) - vendor=hp - ;; - -mpeix*) - vendor=hp - ;; - -hiux*) - vendor=hitachi - ;; - -unos*) - vendor=crds - ;; - -dgux*) - vendor=dg - ;; - -luna*) - vendor=omron - ;; - -genix*) - vendor=ns - ;; - -mvs* | -opened*) - vendor=ibm - ;; - -os400*) - vendor=ibm - ;; - -ptx*) - vendor=sequent - ;; - -tpf*) - vendor=ibm - ;; - -vxsim* | -vxworks* | -windiss*) - vendor=wrs - ;; - -aux*) - vendor=apple - ;; - -hms*) - vendor=hitachi - ;; - -mpw* | -macos*) - vendor=apple - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - vendor=atari - ;; - -vos*) - vendor=stratus - ;; - esac - basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` - ;; -esac - -echo $basic_machine$os -exit - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/source/lib/ldb/configure.ac b/source/lib/ldb/configure.ac deleted file mode 100644 index e1e9d49ceeb..00000000000 --- a/source/lib/ldb/configure.ac +++ /dev/null @@ -1,74 +0,0 @@ -AC_PREREQ(2.50) -AC_DEFUN([AC_CHECK_LIB_EXT], [ - AC_CHECK_LIB([$1],[$3],[$4],[$5],[$7]) - ac_cv_lib_ext_$1_$3=$ac_cv_lib_$1_$3 -]) -AC_DEFUN([AC_CHECK_FUNC_EXT], [ - AC_CHECK_FUNC([$1],[$3],[$4]) - ac_cv_func_ext_$1=$ac_cv_func_$1 -]) -AC_DEFUN([SMB_MODULE_DEFAULT], [echo -n ""]) -AC_DEFUN([SMB_LIBRARY_ENABLE], [echo -n ""]) -AC_DEFUN([SMB_EXT_LIB], [echo -n ""]) -AC_DEFUN([SMB_ENABLE], [echo -n ""]) -AC_INIT(include/ldb.h) -AC_CONFIG_SRCDIR([common/ldb.c]) - -AC_LIBREPLACE_ALL_CHECKS - -if test "$ac_cv_prog_gcc" = yes; then - CFLAGS="$CFLAGS -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings" -fi - -WITH_GCOV=0 -AC_ARG_ENABLE(gcov, - AS_HELP_STRING([--enable-gcov],[enable GCOV code coverage tests]), - [ WITH_GCOV=1]) -AC_SUBST(WITH_GCOV) -if test x"$with_gcov_support" = x"yes"; then - CFLAGS="$CFLAGS -ftest-coverage -fprofile-arcs" - LIBS="$LIBS -lgcov" -fi - -AC_PATH_PROG(XSLTPROC,xsltproc) -AC_PATH_PROG(DOXYGEN,doxygen) -AC_PATH_PROG(GCOV,gcov) -AC_PATH_PROG(SLAPD,slapd) -AC_CHECK_HEADERS(stdint.h dlfcn.h) -AC_CONFIG_HEADER(include/config.h) -AC_SEARCH_LIBS(dlopen, dl, AC_DEFINE(HAVE_DLOPEN, [1], [have dlopen])) - -SHLIBEXT="so" # Should be set based on OS later on -AC_SUBST(SHLIBEXT) - -AC_DEFINE_UNQUOTED(MODULESDIR, LIBDIR "/ldb" , [Modules directory] ) -AC_SUBST(MODULESDIR) - -TESTS="" -EXTRA_OBJ="" - -m4_include(libpopt.m4) -m4_include(libtalloc.m4) -m4_include(libtdb.m4) - -m4_include(ldap.m4) -if test x"$with_ldap_support" = x"yes"; then - LIBS="$LIBS -llber -lldap" - CFLAGS="$CFLAGS -DHAVE_LDB_LDAP=1" - EXTRA_OBJ="$EXTRA_OBJ ldb_ldap/ldb_ldap.o" - TESTS="$TESTS test-ldap.sh" -fi - -m4_include(sqlite3.m4) -if test x"$with_sqlite3_support" = x"yes"; then - LIBS="$LIBS -lsqlite3" - CFLAGS="$CFLAGS -DHAVE_LDB_SQLITE3=1" - EXTRA_OBJ="$EXTRA_OBJ ldb_sqlite3/ldb_sqlite3.o" - TESTS="$TESTS test-sqlite3.sh" -fi - -AC_SUBST(TESTS) -AC_SUBST(EXTRA_OBJ) - -m4_include(libldb.m4) -AC_OUTPUT(Makefile ldb.pc) diff --git a/source/lib/ldb/docs/builddocs.sh b/source/lib/ldb/docs/builddocs.sh deleted file mode 100755 index 449dcb26815..00000000000 --- a/source/lib/ldb/docs/builddocs.sh +++ /dev/null @@ -1,52 +0,0 @@ -#!/bin/sh -# build ldb docs -# tridge@samba.org August 2006 - -XSLTPROC="$1" -SRCDIR="$2" - -if [ -z "$XSLTPROC" ] || [ ! -x "$XSLTPROC" ]; then - echo "xsltproc not installed" - exit 0 -fi - -MANXSL="http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl" -HTMLXSL="http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl" - -mkdir -p man - -for f in $SRCDIR/man/*.xml; do - base=`basename $f .xml` - out=man/"`basename $base`" - if [ ! -f "$out" ] || [ "$f" -nt "$out" ]; then - echo Processing manpage $f - $XSLTPROC --nonet -o "$out" "$MANXSL" $f - ret=$? - if [ "$ret" = "4" ]; then - echo "ignoring stylesheet error 4 for $MANXSL" - exit 0 - fi - if [ "$ret" != "0" ]; then - echo "xsltproc failed with error $ret" - exit $ret - fi - fi -done - -for f in $SRCDIR/man/*.xml; do - base=`basename $f .xml` - out=man/"`basename $base`".html - if [ ! -f "$out" ] || [ "$f" -nt "$out" ]; then - echo Processing html $f - $XSLTPROC --nonet -o "$out" "$HTMLXSL" $f - ret=$? - if [ "$ret" = "4" ]; then - echo "ignoring stylesheet error 4 for $HTMLXSL" - exit 0 - fi - if [ "$ret" != "0" ]; then - echo "xsltproc failed with error $ret" - exit $ret - fi - fi -done diff --git a/source/lib/ldb/docs/design.txt b/source/lib/ldb/docs/design.txt deleted file mode 100644 index 0bb278b5b42..00000000000 --- a/source/lib/ldb/docs/design.txt +++ /dev/null @@ -1,41 +0,0 @@ -The list of indexed fields --------------------------- - -dn=@INDEXLIST - list of field names that are indexed - - contains fields of type @IDXATTR which contain attriute names - of indexed fields - - -Data records ------------- - -for each user record in the db there is: - main record - key: DN=dn - data: packed attribute/value list - - a index record for each indexed field in the record - - -Index Records -------------- - -The index records contain the list of dn's that contain records -matching the index key - -All index records are of the form: - dn=@INDEX:field:value - -and contain fields of type @IDX which are the dns of the records -that have that value for some attribute - - -Search Expressions ------------------- - -Very similar to LDAP search expressions, but does not allow ~=, <= or >= - - attrib0 := (field=value) - attrib := attrib0 | (attrib&&attrib) | (attrib||attrib) | !attrib diff --git a/source/lib/ldb/docs/installdocs.sh b/source/lib/ldb/docs/installdocs.sh deleted file mode 100755 index 6cc7b74ad51..00000000000 --- a/source/lib/ldb/docs/installdocs.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh -# install ldb docs -# tridge@samba.org August 2006 - -MANDIR="$1" - -MAN1="`/bin/ls man/*.1`" -MAN3="`/bin/ls man/*.3`" - -if [ -z "$MAN1" ] && [ -z "$MAN3" ]; then - echo "No manpages have been built" - exit 0 -fi - -mkdir -p "$MANDIR/man1" "$MANDIR/man3" -cp $MAN1 "$MANDIR/man1/" || exit 1 -cp $MAN3 "$MANDIR/man3/" || exit 1 diff --git a/source/lib/ldb/examples.dox b/source/lib/ldb/examples.dox deleted file mode 100644 index ef4b4f0a400..00000000000 --- a/source/lib/ldb/examples.dox +++ /dev/null @@ -1,16 +0,0 @@ -/** \example ldbreader.c - -The code below shows a simple LDB application. - -It lists / dumps the records in a LDB database to standard output. - -*/ - - -/** \example ldifreader.c - -The code below shows a simple LDB application. - -It lists / dumps the entries in an LDIF file to standard output. - -*/ diff --git a/source/lib/ldb/examples/ldbreader.c b/source/lib/ldb/examples/ldbreader.c deleted file mode 100644 index 207c6c3d424..00000000000 --- a/source/lib/ldb/examples/ldbreader.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - example code for the ldb database library - - Copyright (C) Brad Hards (bradh@frogmouth.net) 2005-2006 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301 USA -*/ - -/** \example ldbreader.c - -The code below shows a simple LDB application. - -It lists / dumps the records in a LDB database to standard output. - -*/ - -#include "includes.h" -#include "ldb/include/ldb.h" -#include "ldb/include/ldb_errors.h" - -/* - ldb_ldif_write takes a function pointer to a custom output - function. This version is about as simple as the output function can - be. In a more complex example, you'd likely be doing something with - the private data function (e.g. holding a file handle). -*/ -static int vprintf_fn(void *private_data, const char *fmt, ...) -{ - int retval; - va_list ap; - - va_start(ap, fmt); - /* We just write to standard output */ - retval = vprintf(fmt, ap); - va_end(ap); - /* Note that the function should return the number of - bytes written, or a negative error code */ - return retval; -} - -int main(int argc, const char **argv) -{ - struct ldb_context *ldb; - const char *expression = "(dn=*)"; - struct ldb_result *resultMsg; - int i; - - /* - This is the always the first thing you want to do in an LDB - application - initialise up the context structure. - - Note that you can use the context structure as a parent - for talloc allocations as well - */ - ldb = ldb_init(NULL); - - /* - We now open the database. In this example we just hard code the connection path. - - Also note that the database is being opened read-only. This means that the - call will fail unless the database already exists. - */ - if (LDB_SUCCESS != ldb_connect(ldb, "tdb://tdbtest.ldb", LDB_FLG_RDONLY, NULL) ){ - printf("Problem on connection\n"); - exit(-1); - } - - /* - At this stage we have an open database, and can start using it. It is opened - read-only, so a query is possible. - - We construct a search that just returns all the (sensible) contents. You can do - quite fine grained results with the LDAP search syntax, however it is a bit - confusing to start with. See RFC2254. - */ - if (LDB_SUCCESS != ldb_search(ldb, NULL, LDB_SCOPE_DEFAULT, - expression, NULL, &resultMsg) ) { - printf("Problem in search\n"); - exit(-1); - } - - printf("%i records returned\n", resultMsg->count); - - /* - We can now iterate through the results, writing them out - (to standard output) with our custom output routine as defined - at the top of this file - */ - for (i = 0; i < resultMsg->count; ++i) { - struct ldb_ldif ldifMsg; - - printf("Message: %i\n", i+1); - - ldifMsg.changetype = LDB_CHANGETYPE_NONE; - ldifMsg.msg = resultMsg->msgs[i]; - ldb_ldif_write(ldb, vprintf_fn, NULL, &ldifMsg); - } - - /* - There are two objects to clean up - the result from the - ldb_search() query, and the original ldb context. - */ - talloc_free(resultMsg); - - talloc_free(ldb); - - return 0; -} diff --git a/source/lib/ldb/examples/ldifreader.c b/source/lib/ldb/examples/ldifreader.c deleted file mode 100644 index 3b8591e73fe..00000000000 --- a/source/lib/ldb/examples/ldifreader.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - example code for the ldb database library - - Copyright (C) Brad Hards (bradh@frogmouth.net) 2005-2006 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301 USA -*/ - -/** \example ldifreader.c - -The code below shows a simple LDB application. - -It lists / dumps the entries in an LDIF file to standard output. - -*/ - -#include "includes.h" -#include "ldb/include/ldb.h" -#include "ldb/include/ldb_errors.h" - -/* - ldb_ldif_write takes a function pointer to a custom output - function. This version is about as simple as the output function can - be. In a more complex example, you'd likely be doing something with - the private data function (e.g. holding a file handle). -*/ -static int vprintf_fn(void *private_data, const char *fmt, ...) -{ - int retval; - va_list ap; - - va_start(ap, fmt); - /* We just write to standard output */ - retval = vprintf(fmt, ap); - va_end(ap); - /* Note that the function should return the number of - bytes written, or a negative error code */ - return retval; -} - -int main(int argc, const char **argv) -{ - struct ldb_context *ldb; - FILE *fileStream; - struct ldb_ldif *ldifMsg; - - if (argc != 2) { - printf("Usage %s filename.ldif\n", argv[0]); - exit(1); - } - - /* - This is the always the first thing you want to do in an LDB - application - initialise up the context structure. - - Note that you can use the context structure as a parent - for talloc allocations as well - */ - ldb = ldb_init(NULL); - - fileStream = fopen(argv[1], "r"); - if (0 == fileStream) { - perror(argv[1]); - exit(1); - } - - /* - We now work through the filestream to get each entry. - */ - while ( (ldifMsg = ldb_ldif_read_file(ldb, fileStream)) ) { - /* - Each message has a particular change type. For Add, - Modify and Delete, this will also appear in the - output listing (as changetype: add, changetype: - modify or changetype:delete, respectively). - */ - switch (ldifMsg->changetype) { - case LDB_CHANGETYPE_NONE: - printf("ChangeType: None\n"); - break; - case LDB_CHANGETYPE_ADD: - printf("ChangeType: Add\n"); - break; - case LDB_CHANGETYPE_MODIFY: - printf("ChangeType: Modify\n"); - break; - case LDB_CHANGETYPE_DELETE: - printf("ChangeType: Delete\n"); - break; - default: - printf("ChangeType: Unknown\n"); - } - - /* - We can now write out the results, using our custom - output routine as defined at the top of this file. - */ - ldb_ldif_write(ldb, vprintf_fn, NULL, ldifMsg); - - /* - Clean up the message - */ - ldb_ldif_read_free(ldb, ldifMsg); - } - - /* - Clean up the context - */ - talloc_free(ldb); - - return 0; -} diff --git a/source/lib/ldb/include/dlinklist.h b/source/lib/ldb/include/dlinklist.h deleted file mode 100644 index 3779a4cc61c..00000000000 --- a/source/lib/ldb/include/dlinklist.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - Unix SMB/CIFS implementation. - some simple double linked list macros - Copyright (C) Andrew Tridgell 1998 - - 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. -*/ - -/* To use these macros you must have a structure containing a next and - prev pointer */ - - -/* hook into the front of the list */ -#define DLIST_ADD(list, p) \ -do { \ - if (!(list)) { \ - (list) = (p); \ - (p)->next = (p)->prev = NULL; \ - } else { \ - (list)->prev = (p); \ - (p)->next = (list); \ - (p)->prev = NULL; \ - (list) = (p); \ - }\ -} while (0) - -/* remove an element from a list - element doesn't have to be in list. */ -#ifndef DLIST_REMOVE -#define DLIST_REMOVE(list, p) \ -do { \ - if ((p) == (list)) { \ - (list) = (p)->next; \ - if (list) (list)->prev = NULL; \ - } else { \ - if ((p)->prev) (p)->prev->next = (p)->next; \ - if ((p)->next) (p)->next->prev = (p)->prev; \ - } \ - if ((p) && ((p) != (list))) (p)->next = (p)->prev = NULL; \ -} while (0) -#endif - -/* promote an element to the top of the list */ -#define DLIST_PROMOTE(list, p) \ -do { \ - DLIST_REMOVE(list, p); \ - DLIST_ADD(list, p); \ -} while (0) - -/* hook into the end of the list - needs a tmp pointer */ -#define DLIST_ADD_END(list, p, type) \ -do { \ - if (!(list)) { \ - (list) = (p); \ - (p)->next = (p)->prev = NULL; \ - } else { \ - type tmp; \ - for (tmp = (list); tmp->next; tmp = tmp->next) ; \ - tmp->next = (p); \ - (p)->next = NULL; \ - (p)->prev = tmp; \ - } \ -} while (0) - -/* insert 'p' after the given element 'el' in a list. If el is NULL then - this is the same as a DLIST_ADD() */ -#define DLIST_ADD_AFTER(list, p, el) \ -do { \ - if (!(list) || !(el)) { \ - DLIST_ADD(list, p); \ - } else { \ - p->prev = el; \ - p->next = el->next; \ - el->next = p; \ - if (p->next) p->next->prev = p; \ - }\ -} while (0) - -/* demote an element to the end of the list, needs a tmp pointer */ -#define DLIST_DEMOTE(list, p, tmp) \ -do { \ - DLIST_REMOVE(list, p); \ - DLIST_ADD_END(list, p, tmp); \ -} while (0) - -/* concatenate two lists - putting all elements of the 2nd list at the - end of the first list */ -#define DLIST_CONCATENATE(list1, list2, type) \ -do { \ - if (!(list1)) { \ - (list1) = (list2); \ - } else { \ - type tmp; \ - for (tmp = (list1); tmp->next; tmp = tmp->next) ; \ - tmp->next = (list2); \ - if (list2) { \ - (list2)->prev = tmp; \ - } \ - } \ -} while (0) diff --git a/source/lib/ldb/include/includes.h b/source/lib/ldb/include/includes.h deleted file mode 100644 index e2bcca2b04b..00000000000 --- a/source/lib/ldb/include/includes.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef _LDB_PRIVATE_INCLUDES_H_ -#define _LDB_PRIVATE_INCLUDES_H_ -/* - a temporary includes file until I work on the ldb build system -*/ - -#if (_SAMBA_BUILD_ >= 4) -/* tell ldb we have the internal ldap code */ -#define HAVE_ILDAP 1 -#endif - -#if (_SAMBA_BUILD_ <= 3) -/* allow forbidden string functions - should be replaced with _m functions */ -#undef strcasecmp -#undef strncasecmp -#define dyn_MODULESDIR dyn_LIBDIR -#endif - -#include "replace.h" -#include "system/filesys.h" -#include "system/network.h" -#include "system/time.h" -#include "talloc.h" -#include "ldb.h" -#include "ldb_errors.h" -#include "ldb_private.h" -#include "dlinklist.h" - -#endif /*_LDB_PRIVATE_INCLUDES_H_*/ diff --git a/source/lib/ldb/include/ldb.h b/source/lib/ldb/include/ldb.h deleted file mode 100644 index f96b90a1b2d..00000000000 --- a/source/lib/ldb/include/ldb.h +++ /dev/null @@ -1,1561 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - Copyright (C) Stefan Metzmacher 2004 - Copyright (C) Simo Sorce 2005-2006 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - * Name: ldb - * - * Component: ldb header - * - * Description: defines for base ldb API - * - * Author: Andrew Tridgell - * Author: Stefan Metzmacher - */ - -/** - \file ldb.h Samba's ldb database - - This header file provides the main API for ldb. -*/ - -#ifndef _LDB_H_ - -/*! \cond DOXYGEN_IGNORE */ -#define _LDB_H_ 1 -/*! \endcond */ - -/* - major restrictions as compared to normal LDAP: - - - no async calls. - - each record must have a unique key field - - the key must be representable as a NULL terminated C string and may not - contain a comma or braces - - major restrictions as compared to tdb: - - - no explicit locking calls - UPDATE: we have transactions now, better than locking --SSS. - -*/ - -#ifndef ldb_val -/** - Result value - - An individual lump of data in a result comes in this format. The - pointer will usually be to a UTF-8 string if the application is - sensible, but it can be to anything you like, including binary data - blobs of arbitrary size. - - \note the data is null (0x00) terminated, but the length does not - include the terminator. -*/ -struct ldb_val { - uint8_t *data; /*!< result data */ - size_t length; /*!< length of data */ -}; -#endif - -/*! \cond DOXYGEN_IGNORE */ -#ifndef PRINTF_ATTRIBUTE -#define PRINTF_ATTRIBUTE(a,b) -#endif -/*! \endcond */ - -/* opaque ldb_dn structures, see ldb_dn.c for internals */ -struct ldb_dn_component; -struct ldb_dn; - -/** - There are a number of flags that are used with ldap_modify() in - ldb_message_element.flags fields. The LDA_FLAGS_MOD_ADD, - LDA_FLAGS_MOD_DELETE and LDA_FLAGS_MOD_REPLACE flags are used in - ldap_modify() calls to specify whether attributes are being added, - deleted or modified respectively. -*/ -#define LDB_FLAG_MOD_MASK 0x3 - -/** - Flag value used in ldap_modify() to indicate that attributes are - being added. - - \sa LDB_FLAG_MOD_MASK -*/ -#define LDB_FLAG_MOD_ADD 1 - -/** - Flag value used in ldap_modify() to indicate that attributes are - being replaced. - - \sa LDB_FLAG_MOD_MASK -*/ -#define LDB_FLAG_MOD_REPLACE 2 - -/** - Flag value used in ldap_modify() to indicate that attributes are - being deleted. - - \sa LDB_FLAG_MOD_MASK -*/ -#define LDB_FLAG_MOD_DELETE 3 - -/** - OID for logic AND comaprison. - - This is the well known object ID for a logical AND comparitor. -*/ -#define LDB_OID_COMPARATOR_AND "1.2.840.113556.1.4.803" - -/** - OID for logic OR comparison. - - This is the well known object ID for a logical OR comparitor. -*/ -#define LDB_OID_COMPARATOR_OR "1.2.840.113556.1.4.804" - -/** - results are given back as arrays of ldb_message_element -*/ -struct ldb_message_element { - unsigned int flags; - const char *name; - unsigned int num_values; - struct ldb_val *values; -}; - - -/** - a ldb_message represents all or part of a record. It can contain an arbitrary - number of elements. -*/ -struct ldb_message { - struct ldb_dn *dn; - unsigned int num_elements; - struct ldb_message_element *elements; - void *private_data; /* private to the backend */ -}; - -enum ldb_changetype { - LDB_CHANGETYPE_NONE=0, - LDB_CHANGETYPE_ADD, - LDB_CHANGETYPE_DELETE, - LDB_CHANGETYPE_MODIFY -}; - -/** - LDIF record - - This structure contains a LDIF record, as returned from ldif_read() - and equivalent functions. -*/ -struct ldb_ldif { - enum ldb_changetype changetype; /*!< The type of change */ - struct ldb_message *msg; /*!< The changes */ -}; - -enum ldb_scope {LDB_SCOPE_DEFAULT=-1, - LDB_SCOPE_BASE=0, - LDB_SCOPE_ONELEVEL=1, - LDB_SCOPE_SUBTREE=2}; - -struct ldb_context; - -/* debugging uses one of the following levels */ -enum ldb_debug_level {LDB_DEBUG_FATAL, LDB_DEBUG_ERROR, - LDB_DEBUG_WARNING, LDB_DEBUG_TRACE}; - -/** - the user can optionally supply a debug function. The function - is based on the vfprintf() style of interface, but with the addition - of a severity level -*/ -struct ldb_debug_ops { - void (*debug)(void *context, enum ldb_debug_level level, - const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0); - void *context; -}; - -/** - The user can optionally supply a custom utf8 functions, - to handle comparisons and casefolding. -*/ -struct ldb_utf8_fns { - void *context; - char *(*casefold)(void *context, void *mem_ctx, const char *s); -}; - -/** - Flag value for database connection mode. - - If LDB_FLG_RDONLY is used in ldb_connect, then the database will be - opened read-only, if possible. -*/ -#define LDB_FLG_RDONLY 1 - -/** - Flag value for database connection mode. - - If LDB_FLG_NOSYNC is used in ldb_connect, then the database will be - opened without synchronous operations, if possible. -*/ -#define LDB_FLG_NOSYNC 2 - -/** - Flag value to specify autoreconnect mode. - - If LDB_FLG_RECONNECT is used in ldb_connect, then the backend will - be opened in a way that makes it try to auto reconnect if the - connection is dropped (actually make sense only with ldap). -*/ -#define LDB_FLG_RECONNECT 4 - -/** - Flag to tell backends not to use mmap -*/ -#define LDB_FLG_NOMMAP 8 - -/* - structures for ldb_parse_tree handling code -*/ -enum ldb_parse_op { LDB_OP_AND=1, LDB_OP_OR=2, LDB_OP_NOT=3, - LDB_OP_EQUALITY=4, LDB_OP_SUBSTRING=5, - LDB_OP_GREATER=6, LDB_OP_LESS=7, LDB_OP_PRESENT=8, - LDB_OP_APPROX=9, LDB_OP_EXTENDED=10 }; - -struct ldb_parse_tree { - enum ldb_parse_op operation; - union { - struct { - struct ldb_parse_tree *child; - } isnot; - struct { - const char *attr; - struct ldb_val value; - } equality; - struct { - const char *attr; - int start_with_wildcard; - int end_with_wildcard; - struct ldb_val **chunks; - } substring; - struct { - const char *attr; - } present; - struct { - const char *attr; - struct ldb_val value; - } comparison; - struct { - const char *attr; - int dnAttributes; - char *rule_id; - struct ldb_val value; - } extended; - struct { - unsigned int num_elements; - struct ldb_parse_tree **elements; - } list; - } u; -}; - -struct ldb_parse_tree *ldb_parse_tree(void *mem_ctx, const char *s); -char *ldb_filter_from_tree(void *mem_ctx, struct ldb_parse_tree *tree); - -/** - Encode a binary blob - - This function encodes a binary blob using the encoding rules in RFC - 2254 (Section 4). This function also escapes any non-printable - characters. - - \param ctx the memory context to allocate the return string in. - \param val the (potentially) binary data to be encoded - - \return the encoded data as a null terminated string - - \sa <a href="http://www.ietf.org/rfc/rfc2252.txt">RFC 2252</a>. -*/ -char *ldb_binary_encode(void *ctx, struct ldb_val val); - -/** - Encode a string - - This function encodes a string using the encoding rules in RFC 2254 - (Section 4). This function also escapes any non-printable - characters. - - \param mem_ctx the memory context to allocate the return string in. - \param string the string to be encoded - - \return the encoded data as a null terminated string - - \sa <a href="http://www.ietf.org/rfc/rfc2252.txt">RFC 2252</a>. -*/ -char *ldb_binary_encode_string(void *mem_ctx, const char *string); - -/* - functions for controlling attribute handling -*/ -typedef int (*ldb_attr_handler_t)(struct ldb_context *, void *mem_ctx, const struct ldb_val *, struct ldb_val *); -typedef int (*ldb_attr_comparison_t)(struct ldb_context *, void *mem_ctx, const struct ldb_val *, const struct ldb_val *); - -/* - attribute handler structure - - attr -> The attribute name - flags -> LDB_ATTR_FLAG_* - ldif_read_fn -> convert from ldif to binary format - ldif_write_fn -> convert from binary to ldif format - canonicalise_fn -> canonicalise a value, for use by indexing and dn construction - comparison_fn -> compare two values -*/ - -struct ldb_attrib_handler { - - const char *attr; - unsigned flags; - - ldb_attr_handler_t ldif_read_fn; - ldb_attr_handler_t ldif_write_fn; - ldb_attr_handler_t canonicalise_fn; - ldb_attr_comparison_t comparison_fn; -}; - -/** - The attribute is not returned by default -*/ -#define LDB_ATTR_FLAG_HIDDEN (1<<0) - -/* the attribute handler name should be freed when released */ -#define LDB_ATTR_FLAG_ALLOCATED (1<<1) - -/** - The attribute is constructed from other attributes -*/ -#define LDB_ATTR_FLAG_CONSTRUCTED (1<<1) - -/** - LDAP attribute syntax for a DN - - This is the well-known LDAP attribute syntax for a DN. - - See <a href="http://www.ietf.org/rfc/rfc2252.txt">RFC 2252</a>, Section 4.3.2 -*/ -#define LDB_SYNTAX_DN "1.3.6.1.4.1.1466.115.121.1.12" - -/** - LDAP attribute syntax for a Directory String - - This is the well-known LDAP attribute syntax for a Directory String. - - \sa <a href="http://www.ietf.org/rfc/rfc2252.txt">RFC 2252</a>, Section 4.3.2 -*/ -#define LDB_SYNTAX_DIRECTORY_STRING "1.3.6.1.4.1.1466.115.121.1.15" - -/** - LDAP attribute syntax for an integer - - This is the well-known LDAP attribute syntax for an integer. - - See <a href="http://www.ietf.org/rfc/rfc2252.txt">RFC 2252</a>, Section 4.3.2 -*/ -#define LDB_SYNTAX_INTEGER "1.3.6.1.4.1.1466.115.121.1.27" - -/** - LDAP attribute syntax for an octet string - - This is the well-known LDAP attribute syntax for an octet string. - - See <a href="http://www.ietf.org/rfc/rfc2252.txt">RFC 2252</a>, Section 4.3.2 -*/ -#define LDB_SYNTAX_OCTET_STRING "1.3.6.1.4.1.1466.115.121.1.40" - -/** - LDAP attribute syntax for UTC time. - - This is the well-known LDAP attribute syntax for a UTC time. - - See <a href="http://www.ietf.org/rfc/rfc2252.txt">RFC 2252</a>, Section 4.3.2 -*/ -#define LDB_SYNTAX_UTC_TIME "1.3.6.1.4.1.1466.115.121.1.53" - -#define LDB_SYNTAX_OBJECTCLASS "LDB_SYNTAX_OBJECTCLASS" - -/* sorting helpers */ -typedef int (*ldb_qsort_cmp_fn_t) (void *v1, void *v2, void *opaque); - -/** - OID for the paged results control. This control is included in the - searchRequest and searchResultDone messages as part of the controls - field of the LDAPMessage, as defined in Section 4.1.12 of - LDAP v3. - - \sa <a href="http://www.ietf.org/rfc/rfc2696.txt">RFC 2696</a>. -*/ -#define LDB_CONTROL_PAGED_RESULTS_OID "1.2.840.113556.1.4.319" - -/** - OID for specifying the returned elements of the ntSecurityDescriptor - - \sa <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ldap/ldap/ldap_server_sd_flags_oid.asp">Microsoft documentation of this OID</a> -*/ -#define LDB_CONTROL_SD_FLAGS_OID "1.2.840.113556.1.4.801" - -/** - OID for specifying an advanced scope for the search (one partition) - - \sa <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ldap/ldap/ldap_server_domain_scope_oid.asp">Microsoft documentation of this OID</a> -*/ -#define LDB_CONTROL_DOMAIN_SCOPE_OID "1.2.840.113556.1.4.1339" - -/** - OID for specifying an advanced scope for a search - - \sa <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ldap/ldap/ldap_server_search_options_oid.asp">Microsoft documentation of this OID</a> -*/ -#define LDB_CONTROL_SEARCH_OPTIONS_OID "1.2.840.113556.1.4.1340" - -/** - OID for notification - - \sa <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ldap/ldap/ldap_server_notification_oid.asp">Microsoft documentation of this OID</a> -*/ -#define LDB_CONTROL_NOTIFICATION_OID "1.2.840.113556.1.4.528" - -/** - OID for getting deleted objects - - \sa <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ldap/ldap/ldap_server_show_deleted_oid.asp">Microsoft documentation of this OID</a> -*/ -#define LDB_CONTROL_SHOW_DELETED_OID "1.2.840.113556.1.4.417" - -/** - OID for extended DN - - \sa <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ldap/ldap/ldap_server_extended_dn_oid.asp">Microsoft documentation of this OID</a> -*/ -#define LDB_CONTROL_EXTENDED_DN_OID "1.2.840.113556.1.4.529" - -/** - OID for LDAP server sort result extension. - - This control is included in the searchRequest message as part of - the controls field of the LDAPMessage, as defined in Section 4.1.12 - of LDAP v3. The controlType is set to - "1.2.840.113556.1.4.473". The criticality MAY be either TRUE or - FALSE (where absent is also equivalent to FALSE) at the client's - option. - - \sa <a href="http://www.ietf.org/rfc/rfc2891.txt">RFC 2891</a>. -*/ -#define LDB_CONTROL_SERVER_SORT_OID "1.2.840.113556.1.4.473" - -/** - OID for LDAP server sort result response extension. - - This control is included in the searchResultDone message as part of - the controls field of the LDAPMessage, as defined in Section 4.1.12 of - LDAP v3. - - \sa <a href="http://www.ietf.org/rfc/rfc2891.txt">RFC 2891</a>. -*/ -#define LDB_CONTROL_SORT_RESP_OID "1.2.840.113556.1.4.474" - -/** - OID for LDAP Attribute Scoped Query extension. - - This control is included in SearchRequest or SearchResponse - messages as part of the controls field of the LDAPMessage. -*/ -#define LDB_CONTROL_ASQ_OID "1.2.840.113556.1.4.1504" - -/** - OID for LDAP Directory Sync extension. - - This control is included in SearchRequest or SearchResponse - messages as part of the controls field of the LDAPMessage. -*/ -#define LDB_CONTROL_DIRSYNC_OID "1.2.840.113556.1.4.841" - - -/** - OID for LDAP Virtual List View Request extension. - - This control is included in SearchRequest messages - as part of the controls field of the LDAPMessage. -*/ -#define LDB_CONTROL_VLV_REQ_OID "2.16.840.1.113730.3.4.9" - -/** - OID for LDAP Virtual List View Response extension. - - This control is included in SearchResponse messages - as part of the controls field of the LDAPMessage. -*/ -#define LDB_CONTROL_VLV_RESP_OID "2.16.840.1.113730.3.4.10" - -/** - OID to let modifies don't give an error when adding an existing - attribute with the same value or deleting an nonexisting one attribute - - \sa <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ldap/ldap/ldap_server_permissive_modify_oid.asp">Microsoft documentation of this OID</a> -*/ -#define LDB_CONTROL_PERMISSIVE_MODIFY_OID "1.2.840.113556.1.4.1413" - -/** - OID for LDAP Extended Operation START_TLS. - - This Extended operation is used to start a new TLS - channel on top of a clear text channel. -*/ -#define LDB_EXTENDED_START_TLS_OID "1.3.6.1.4.1.1466.20037" - -/** - OID for LDAP Extended Operation START_TLS. - - This Extended operation is used to start a new TLS - channel on top of a clear text channel. -*/ -#define LDB_EXTENDED_DYNAMIC_OID "1.3.6.1.4.1.1466.101.119.1" - -/** - OID for LDAP Extended Operation START_TLS. - - This Extended operation is used to start a new TLS - channel on top of a clear text channel. -*/ -#define LDB_EXTENDED_FAST_BIND_OID "1.2.840.113556.1.4.1781" - -struct ldb_sd_flags_control { - /* - * request the owner 0x00000001 - * request the group 0x00000002 - * request the DACL 0x00000004 - * request the SACL 0x00000008 - */ - unsigned secinfo_flags; -}; - -struct ldb_search_options_control { - /* - * DOMAIN_SCOPE 0x00000001 - * this limits the search to one partition, - * and no referrals will be returned. - * (Note this doesn't limit the entries by there - * objectSid belonging to a domain! Builtin and Foreign Sids - * are still returned) - * - * PHANTOM_ROOT 0x00000002 - * this search on the whole tree on a domain controller - * over multiple partitions without referrals. - * (This is the default behavior on the Global Catalog Port) - */ - unsigned search_options; -}; - -struct ldb_paged_control { - int size; - int cookie_len; - char *cookie; -}; - -struct ldb_extended_dn_control { - int type; -}; - -struct ldb_server_sort_control { - char *attributeName; - char *orderingRule; - int reverse; -}; - -struct ldb_sort_resp_control { - int result; - char *attr_desc; -}; - -struct ldb_asq_control { - int request; - char *source_attribute; - int src_attr_len; - int result; -}; - -struct ldb_dirsync_control { - int flags; - int max_attributes; - int cookie_len; - char *cookie; -}; - -struct ldb_vlv_req_control { - int beforeCount; - int afterCount; - int type; - union { - struct { - int offset; - int contentCount; - } byOffset; - struct { - int value_len; - char *value; - } gtOrEq; - } match; - int ctxid_len; - char *contextId; -}; - -struct ldb_vlv_resp_control { - int targetPosition; - int contentCount; - int vlv_result; - int ctxid_len; - char *contextId; -}; - -struct ldb_control { - const char *oid; - int critical; - void *data; -}; - -enum ldb_request_type { - LDB_SEARCH, - LDB_ADD, - LDB_MODIFY, - LDB_DELETE, - LDB_RENAME, - LDB_EXTENDED, - LDB_REQ_REGISTER_CONTROL, - LDB_REQ_REGISTER_PARTITION, - LDB_SEQUENCE_NUMBER -}; - -enum ldb_reply_type { - LDB_REPLY_ENTRY, - LDB_REPLY_REFERRAL, - LDB_REPLY_EXTENDED, - LDB_REPLY_DONE -}; - -enum ldb_wait_type { - LDB_WAIT_ALL, - LDB_WAIT_NONE -}; - -enum ldb_state { - LDB_ASYNC_INIT, - LDB_ASYNC_PENDING, - LDB_ASYNC_DONE -}; - -struct ldb_result { - unsigned int count; - struct ldb_message **msgs; - char **refs; - struct ldb_control **controls; -}; - -struct ldb_extended { - const char *oid; - const char *value; - int value_len; -}; - -struct ldb_reply { - enum ldb_reply_type type; - struct ldb_message *message; - struct ldb_extended *response; - char *referral; - struct ldb_control **controls; -}; - -struct ldb_handle { - int status; - enum ldb_state state; - void *private_data; - struct ldb_module *module; -}; - -struct ldb_search { - const struct ldb_dn *base; - enum ldb_scope scope; - const struct ldb_parse_tree *tree; - const char * const *attrs; - struct ldb_result *res; -}; - -struct ldb_add { - const struct ldb_message *message; -}; - -struct ldb_modify { - const struct ldb_message *message; -}; - -struct ldb_delete { - const struct ldb_dn *dn; -}; - -struct ldb_rename { - const struct ldb_dn *olddn; - const struct ldb_dn *newdn; -}; - -struct ldb_register_control { - const char *oid; -}; - -struct ldb_register_partition { - const struct ldb_dn *dn; -}; - -struct ldb_sequence_number { - enum ldb_sequence_type { - LDB_SEQ_HIGHEST_SEQ, - LDB_SEQ_HIGHEST_TIMESTAMP, - LDB_SEQ_NEXT - } type; - uint64_t seq_num; - uint32_t flags; -}; - -typedef int (*ldb_request_callback_t)(struct ldb_context *, void *, struct ldb_reply *); -struct ldb_request { - - enum ldb_request_type operation; - - union { - struct ldb_search search; - struct ldb_add add; - struct ldb_modify mod; - struct ldb_delete del; - struct ldb_rename rename; - struct ldb_register_control reg_control; - struct ldb_register_partition reg_partition; - struct ldb_sequence_number seq_num; - } op; - - struct ldb_control **controls; - - void *context; - ldb_request_callback_t callback; - - int timeout; - time_t starttime; - struct ldb_handle *handle; -}; - -int ldb_request(struct ldb_context *ldb, struct ldb_request *request); - -int ldb_wait(struct ldb_handle *handle, enum ldb_wait_type type); - -int ldb_set_timeout(struct ldb_context *ldb, struct ldb_request *req, int timeout); -int ldb_set_timeout_from_prev_req(struct ldb_context *ldb, struct ldb_request *oldreq, struct ldb_request *newreq); -void ldb_set_create_perms(struct ldb_context *ldb, unsigned int perms); - -/** - Initialise ldbs' global information - - This is required before any other LDB call - - \return 0 if initialisation succeeded, -1 otherwise -*/ -int ldb_global_init(void); - -/** - Initialise an ldb context - - This is required before any other LDB call. - - \param mem_ctx pointer to a talloc memory context. Pass NULL if there is - no suitable context available. - - \return pointer to ldb_context that should be free'd (using talloc_free()) - at the end of the program. -*/ -struct ldb_context *ldb_init(void *mem_ctx); - -/** - Connect to a database. - - This is typically called soon after ldb_init(), and is required prior to - any search or database modification operations. - - The URL can be one of the following forms: - - tdb://path - - ldapi://path - - ldap://host - - sqlite://path - - \param ldb the context associated with the database (from ldb_init()) - \param url the URL of the database to connect to, as noted above - \param flags a combination of LDB_FLG_* to modify the connection behaviour - \param options backend specific options - passed uninterpreted to the backend - - \return result code (LDB_SUCCESS on success, or a failure code) - - \note It is an error to connect to a database that does not exist in readonly mode - (that is, with LDB_FLG_RDONLY). However in read-write mode, the database will be - created if it does not exist. -*/ -int ldb_connect(struct ldb_context *ldb, const char *url, unsigned int flags, const char *options[]); - -/* - return an automatic baseDN from the defaultNamingContext of the rootDSE - This value have been set in an opaque pointer at connection time -*/ -const struct ldb_dn *ldb_get_default_basedn(struct ldb_context *ldb); - - -/** - The Default iasync search callback function - - \param ldb the context associated with the database (from ldb_init()) - \param context the callback context - \param ares a single reply from the async core - - \return result code (LDB_SUCCESS on success, or a failure code) - - \note this function expects the context to always be an struct ldb_result pointer - AND a talloc context, this function will steal on the context each message - from the ares reply passed on by the async core so that in the end all the - messages will be in the context (ldb_result) memory tree. - Freeing the passed context (ldb_result tree) will free all the resources - (the request need to be freed separately and the result doe not depend on the - request that can be freed as sson as the search request is finished) -*/ - -int ldb_search_default_callback(struct ldb_context *ldb, void *context, struct ldb_reply *ares); - -/** - Helper function to build a search request - - \param ret_req the request structure is returned here (talloced on mem_ctx) - \param ldb the context associated with the database (from ldb_init()) - \param mem_ctx a talloc emmory context (used as parent of ret_req) - \param base the Base Distinguished Name for the query (use ldb_dn_new() for an empty one) - \param scope the search scope for the query - \param expression the search expression to use for this query - \param attrs the search attributes for the query (pass NULL if none required) - \param controls an array of controls - \param context the callback function context - \param the callback function to handle the async replies - - \return result code (LDB_SUCCESS on success, or a failure code) -*/ - -int ldb_build_search_req(struct ldb_request **ret_req, - struct ldb_context *ldb, - void *mem_ctx, - const struct ldb_dn *base, - enum ldb_scope scope, - const char *expression, - const char * const *attrs, - struct ldb_control **controls, - void *context, - ldb_request_callback_t callback); - -/** - Helper function to build an add request - - \param ret_req the request structure is returned here (talloced on mem_ctx) - \param ldb the context associated with the database (from ldb_init()) - \param mem_ctx a talloc emmory context (used as parent of ret_req) - \param message contains the entry to be added - \param controls an array of controls - \param context the callback function context - \param the callback function to handle the async replies - - \return result code (LDB_SUCCESS on success, or a failure code) -*/ - -int ldb_build_add_req(struct ldb_request **ret_req, - struct ldb_context *ldb, - void *mem_ctx, - const struct ldb_message *message, - struct ldb_control **controls, - void *context, - ldb_request_callback_t callback); - -/** - Helper function to build a modify request - - \param ret_req the request structure is returned here (talloced on mem_ctx) - \param ldb the context associated with the database (from ldb_init()) - \param mem_ctx a talloc emmory context (used as parent of ret_req) - \param message contains the entry to be modified - \param controls an array of controls - \param context the callback function context - \param the callback function to handle the async replies - - \return result code (LDB_SUCCESS on success, or a failure code) -*/ - -int ldb_build_mod_req(struct ldb_request **ret_req, - struct ldb_context *ldb, - void *mem_ctx, - const struct ldb_message *message, - struct ldb_control **controls, - void *context, - ldb_request_callback_t callback); - -/** - Helper function to build a delete request - - \param ret_req the request structure is returned here (talloced on mem_ctx) - \param ldb the context associated with the database (from ldb_init()) - \param mem_ctx a talloc emmory context (used as parent of ret_req) - \param dn the DN to be deleted - \param controls an array of controls - \param context the callback function context - \param the callback function to handle the async replies - - \return result code (LDB_SUCCESS on success, or a failure code) -*/ - -int ldb_build_del_req(struct ldb_request **ret_req, - struct ldb_context *ldb, - void *mem_ctx, - const struct ldb_dn *dn, - struct ldb_control **controls, - void *context, - ldb_request_callback_t callback); - -/** - Helper function to build a rename request - - \param ret_req the request structure is returned here (talloced on mem_ctx) - \param ldb the context associated with the database (from ldb_init()) - \param mem_ctx a talloc emmory context (used as parent of ret_req) - \param olddn the old DN - \param newdn the new DN - \param controls an array of controls - \param context the callback function context - \param the callback function to handle the async replies - - \return result code (LDB_SUCCESS on success, or a failure code) -*/ - -int ldb_build_rename_req(struct ldb_request **ret_req, - struct ldb_context *ldb, - void *mem_ctx, - const struct ldb_dn *olddn, - const struct ldb_dn *newdn, - struct ldb_control **controls, - void *context, - ldb_request_callback_t callback); - -/** - Search the database - - This function searches the database, and returns - records that match an LDAP-like search expression - - \param ldb the context associated with the database (from ldb_init()) - \param base the Base Distinguished Name for the query (use ldb_dn_new() for an empty one) - \param scope the search scope for the query - \param expression the search expression to use for this query - \param attrs the search attributes for the query (pass NULL if none required) - \param res the return result - - \return result code (LDB_SUCCESS on success, or a failure code) - - \note use talloc_free() to free the ldb_result returned -*/ -int ldb_search(struct ldb_context *ldb, - const struct ldb_dn *base, - enum ldb_scope scope, - const char *expression, - const char * const *attrs, struct ldb_result **res); - -/* - * a useful search function where you can easily define the expression and - * that takes a memory context where results are allocated -*/ - -int ldb_search_exp_fmt(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, - struct ldb_result **result, struct ldb_dn *base, - enum ldb_scope scope, const char * const *attrs, - const char *exp_fmt, ...); - -/* - like ldb_search() but takes a parse tree -*/ -int ldb_search_bytree(struct ldb_context *ldb, - const struct ldb_dn *base, - enum ldb_scope scope, - struct ldb_parse_tree *tree, - const char * const *attrs, struct ldb_result **res); - -/** - Add a record to the database. - - This function adds a record to the database. This function will fail - if a record with the specified class and key already exists in the - database. - - \param ldb the context associated with the database (from - ldb_init()) - \param message the message containing the record to add. - - \return result code (LDB_SUCCESS if the record was added, otherwise - a failure code) -*/ -int ldb_add(struct ldb_context *ldb, - const struct ldb_message *message); - -/** - Modify the specified attributes of a record - - This function modifies a record that is in the database. - - \param ldb the context associated with the database (from - ldb_init()) - \param message the message containing the changes required. - - \return result code (LDB_SUCCESS if the record was modified as - requested, otherwise a failure code) -*/ -int ldb_modify(struct ldb_context *ldb, - const struct ldb_message *message); - -/** - Rename a record in the database - - This function renames a record in the database. - - \param ldb the context associated with the database (from - ldb_init()) - \param olddn the DN for the record to be renamed. - \param newdn the new DN - - \return result code (LDB_SUCCESS if the record was renamed as - requested, otherwise a failure code) -*/ -int ldb_rename(struct ldb_context *ldb, const struct ldb_dn *olddn, const struct ldb_dn *newdn); - -/** - Delete a record from the database - - This function deletes a record from the database. - - \param ldb the context associated with the database (from - ldb_init()) - \param dn the DN for the record to be deleted. - - \return result code (LDB_SUCCESS if the record was deleted, - otherwise a failure code) -*/ -int ldb_delete(struct ldb_context *ldb, const struct ldb_dn *dn); - -/** - start a transaction -*/ -int ldb_transaction_start(struct ldb_context *ldb); - -/** - commit a transaction -*/ -int ldb_transaction_commit(struct ldb_context *ldb); - -/** - cancel a transaction -*/ -int ldb_transaction_cancel(struct ldb_context *ldb); - - -/** - return extended error information from the last call -*/ -const char *ldb_errstring(struct ldb_context *ldb); - -/** - return a string explaining what a ldb error constant meancs -*/ -const char *ldb_strerror(int ldb_err); - -/** - setup the default utf8 functions - FIXME: these functions do not yet handle utf8 -*/ -void ldb_set_utf8_default(struct ldb_context *ldb); - -/** - Casefold a string - - \param ldb the ldb context - \param mem_ctx the memory context to allocate the result string - memory from. - \param s the string that is to be folded - \return a copy of the string, converted to upper case - - \note The default function is not yet UTF8 aware. Provide your own - set of functions through ldb_set_utf8_fns() -*/ -char *ldb_casefold(struct ldb_context *ldb, void *mem_ctx, const char *s); - -/** - Check the attribute name is valid according to rfc2251 - \param s tthe string to check - - \return 1 if the name is ok -*/ -int ldb_valid_attr_name(const char *s); - -/* - ldif manipulation functions -*/ -/** - Write an LDIF message - - This function writes an LDIF message using a caller supplied write - function. - - \param ldb the ldb context (from ldb_init()) - \param fprintf_fn a function pointer for the write function. This must take - a private data pointer, followed by a format string, and then a variable argument - list. - \param private_data pointer that will be provided back to the write - function. This is useful for maintaining state or context. - \param ldif the message to write out - - \return the total number of bytes written, or an error code as returned - from the write function. - - \sa ldb_ldif_write_file for a more convenient way to write to a - file stream. - - \sa ldb_ldif_read for the reader equivalent to this function. -*/ -int ldb_ldif_write(struct ldb_context *ldb, - int (*fprintf_fn)(void *, const char *, ...) PRINTF_ATTRIBUTE(2,3), - void *private_data, - const struct ldb_ldif *ldif); - -/** - Clean up an LDIF message - - This function cleans up a LDIF message read using ldb_ldif_read() - or related functions (such as ldb_ldif_read_string() and - ldb_ldif_read_file(). - - \param ldb the ldb context (from ldb_init()) - \param msg the message to clean up and free - -*/ -void ldb_ldif_read_free(struct ldb_context *ldb, struct ldb_ldif *msg); - -/** - Read an LDIF message - - This function creates an LDIF message using a caller supplied read - function. - - \param ldb the ldb context (from ldb_init()) - \param fgetc_fn a function pointer for the read function. This must - take a private data pointer, and must return a pointer to an - integer corresponding to the next byte read (or EOF if there is no - more data to be read). - \param private_data pointer that will be provided back to the read - function. This is udeful for maintaining state or context. - - \return the LDIF message that has been read in - - \note You must free the LDIF message when no longer required, using - ldb_ldif_read_free(). - - \sa ldb_ldif_read_file for a more convenient way to read from a - file stream. - - \sa ldb_ldif_read_string for a more convenient way to read from a - string (char array). - - \sa ldb_ldif_write for the writer equivalent to this function. -*/ -struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb, - int (*fgetc_fn)(void *), void *private_data); - -/** - Read an LDIF message from a file - - This function reads the next LDIF message from the contents of a - file stream. If you want to get all of the LDIF messages, you will - need to repeatedly call this function, until it returns NULL. - - \param ldb the ldb context (from ldb_init()) - \param f the file stream to read from (typically from fdopen()) - - \sa ldb_ldif_read_string for an equivalent function that will read - from a string (char array). - - \sa ldb_ldif_write_file for the writer equivalent to this function. - -*/ -struct ldb_ldif *ldb_ldif_read_file(struct ldb_context *ldb, FILE *f); - -/** - Read an LDIF message from a string - - This function reads the next LDIF message from the contents of a char - array. If you want to get all of the LDIF messages, you will need - to repeatedly call this function, until it returns NULL. - - \param ldb the ldb context (from ldb_init()) - \param s pointer to the char array to read from - - \sa ldb_ldif_read_file for an equivalent function that will read - from a file stream. - - \sa ldb_ldif_write for a more general (arbitrary read function) - version of this function. -*/ -struct ldb_ldif *ldb_ldif_read_string(struct ldb_context *ldb, const char **s); - -/** - Write an LDIF message to a file - - \param ldb the ldb context (from ldb_init()) - \param f the file stream to write to (typically from fdopen()) - \param msg the message to write out - - \return the total number of bytes written, or a negative error code - - \sa ldb_ldif_read_file for the reader equivalent to this function. -*/ -int ldb_ldif_write_file(struct ldb_context *ldb, FILE *f, const struct ldb_ldif *msg); - -/** - Base64 encode a buffer - - \param mem_ctx the memory context that the result is allocated - from. - \param buf pointer to the array that is to be encoded - \param len the number of elements in the array to be encoded - - \return pointer to an array containing the encoded data - - \note The caller is responsible for freeing the result -*/ -char *ldb_base64_encode(void *mem_ctx, const char *buf, int len); - -/** - Base64 decode a buffer - - This function decodes a base64 encoded string in place. - - \param s the string to decode. - - \return the length of the returned (decoded) string. - - \note the string is null terminated, but the null terminator is not - included in the length. -*/ -int ldb_base64_decode(char *s); - -int ldb_attrib_add_handlers(struct ldb_context *ldb, - const struct ldb_attrib_handler *handlers, - unsigned num_handlers); - -/* The following definitions come from lib/ldb/common/ldb_dn.c */ - -int ldb_dn_is_special(const struct ldb_dn *dn); -int ldb_dn_check_special(const struct ldb_dn *dn, const char *check); -char *ldb_dn_escape_value(void *mem_ctx, struct ldb_val value); -struct ldb_dn *ldb_dn_new(void *mem_ctx); -struct ldb_dn *ldb_dn_explode(void *mem_ctx, const char *dn); -struct ldb_dn *ldb_dn_explode_or_special(void *mem_ctx, const char *dn); -char *ldb_dn_linearize(void *mem_ctx, const struct ldb_dn *edn); -char *ldb_dn_linearize_casefold(struct ldb_context *ldb, void *mem_ctx, const struct ldb_dn *edn); -int ldb_dn_compare_base(struct ldb_context *ldb, const struct ldb_dn *base, const struct ldb_dn *dn); -int ldb_dn_compare(struct ldb_context *ldb, const struct ldb_dn *edn0, const struct ldb_dn *edn1); -struct ldb_dn *ldb_dn_casefold(struct ldb_context *ldb, void *mem_ctx, const struct ldb_dn *edn); -struct ldb_dn *ldb_dn_explode_casefold(struct ldb_context *ldb, void *mem_ctx, const char *dn); -struct ldb_dn *ldb_dn_copy_partial(void *mem_ctx, const struct ldb_dn *dn, int num_el); -struct ldb_dn *ldb_dn_copy(void *mem_ctx, const struct ldb_dn *dn); -struct ldb_dn *ldb_dn_copy_rebase(void *mem_ctx, const struct ldb_dn *old, const struct ldb_dn *old_base, const struct ldb_dn *new_base); -struct ldb_dn *ldb_dn_get_parent(void *mem_ctx, const struct ldb_dn *dn); -struct ldb_dn_component *ldb_dn_build_component(void *mem_ctx, const char *attr, - const char *val); -struct ldb_dn *ldb_dn_build_child(void *mem_ctx, const char *attr, - const char * value, - const struct ldb_dn *base); -struct ldb_dn *ldb_dn_compose(void *mem_ctx, const struct ldb_dn *dn1, const struct ldb_dn *dn2); -struct ldb_dn *ldb_dn_string_compose(void *mem_ctx, const struct ldb_dn *base, const char *child_fmt, ...) PRINTF_ATTRIBUTE(3,4); -char *ldb_dn_canonical_string(void *mem_ctx, const struct ldb_dn *dn); -char *ldb_dn_canonical_ex_string(void *mem_ctx, const struct ldb_dn *dn); -int ldb_dn_get_comp_num(const struct ldb_dn *dn); -const char *ldb_dn_get_component_name(const struct ldb_dn *dn, unsigned int num); -const struct ldb_val *ldb_dn_get_component_val(const struct ldb_dn *dn, unsigned int num); -const char *ldb_dn_get_rdn_name(const struct ldb_dn *dn); -const struct ldb_val *ldb_dn_get_rdn_val(const struct ldb_dn *dn); -int ldb_dn_set_component(struct ldb_dn *dn, int num, const char *name, const struct ldb_val val); - - - -/* useful functions for ldb_message structure manipulation */ -int ldb_dn_cmp(struct ldb_context *ldb, const char *dn1, const char *dn2); - -/** - Compare two attributes - - This function compares to attribute names. Note that this is a - case-insensitive comparison. - - \param attr1 the first attribute name to compare - \param attr2 the second attribute name to compare - - \return 0 if the attribute names are the same, or only differ in - case; non-zero if there are any differences -*/ -int ldb_attr_cmp(const char *attr1, const char *attr2); -char *ldb_attr_casefold(void *mem_ctx, const char *s); -int ldb_attr_dn(const char *attr); - -/** - Create an empty message - - \param mem_ctx the memory context to create in. You can pass NULL - to get the top level context, however the ldb context (from - ldb_init()) may be a better choice -*/ -struct ldb_message *ldb_msg_new(void *mem_ctx); - -/** - Find an element within an message -*/ -struct ldb_message_element *ldb_msg_find_element(const struct ldb_message *msg, - const char *attr_name); - -/** - Compare two ldb_val values - - \param v1 first ldb_val structure to be tested - \param v2 second ldb_val structure to be tested - - \return 1 for a match, 0 if there is any difference -*/ -int ldb_val_equal_exact(const struct ldb_val *v1, const struct ldb_val *v2); - -/** - find a value within an ldb_message_element - - \param el the element to search - \param val the value to search for - - \note This search is case sensitive -*/ -struct ldb_val *ldb_msg_find_val(const struct ldb_message_element *el, - struct ldb_val *val); - -/** - add a new empty element to a ldb_message -*/ -int ldb_msg_add_empty(struct ldb_message *msg, - const char *attr_name, - int flags, - struct ldb_message_element **return_el); - -/** - add a element to a ldb_message -*/ -int ldb_msg_add(struct ldb_message *msg, - const struct ldb_message_element *el, - int flags); -int ldb_msg_add_value(struct ldb_message *msg, - const char *attr_name, - const struct ldb_val *val, - struct ldb_message_element **return_el); -int ldb_msg_add_steal_value(struct ldb_message *msg, - const char *attr_name, - struct ldb_val *val); -int ldb_msg_add_steal_string(struct ldb_message *msg, - const char *attr_name, char *str); -int ldb_msg_add_string(struct ldb_message *msg, - const char *attr_name, const char *str); -int ldb_msg_add_fmt(struct ldb_message *msg, - const char *attr_name, const char *fmt, ...) PRINTF_ATTRIBUTE(3,4); - -/** - compare two message elements - return 0 on match -*/ -int ldb_msg_element_compare(struct ldb_message_element *el1, - struct ldb_message_element *el2); - -/** - Find elements in a message. - - This function finds elements and converts to a specific type, with - a give default value if not found. Assumes that elements are - single valued. -*/ -const struct ldb_val *ldb_msg_find_ldb_val(const struct ldb_message *msg, const char *attr_name); -int ldb_msg_find_attr_as_int(const struct ldb_message *msg, - const char *attr_name, - int default_value); -unsigned int ldb_msg_find_attr_as_uint(const struct ldb_message *msg, - const char *attr_name, - unsigned int default_value); -int64_t ldb_msg_find_attr_as_int64(const struct ldb_message *msg, - const char *attr_name, - int64_t default_value); -uint64_t ldb_msg_find_attr_as_uint64(const struct ldb_message *msg, - const char *attr_name, - uint64_t default_value); -double ldb_msg_find_attr_as_double(const struct ldb_message *msg, - const char *attr_name, - double default_value); -int ldb_msg_find_attr_as_bool(const struct ldb_message *msg, - const char *attr_name, - int default_value); -const char *ldb_msg_find_attr_as_string(const struct ldb_message *msg, - const char *attr_name, - const char *default_value); - -struct ldb_dn *ldb_msg_find_attr_as_dn(void *mem_ctx, - const struct ldb_message *msg, - const char *attr_name); - -void ldb_msg_sort_elements(struct ldb_message *msg); - -struct ldb_message *ldb_msg_copy_shallow(void *mem_ctx, - const struct ldb_message *msg); -struct ldb_message *ldb_msg_copy(void *mem_ctx, - const struct ldb_message *msg); - -struct ldb_message *ldb_msg_canonicalize(struct ldb_context *ldb, - const struct ldb_message *msg); - - -struct ldb_message *ldb_msg_diff(struct ldb_context *ldb, - struct ldb_message *msg1, - struct ldb_message *msg2); - -int ldb_msg_check_string_attribute(const struct ldb_message *msg, - const char *name, - const char *value); - -/** - Integrity check an ldb_message - - This function performs basic sanity / integrity checks on an - ldb_message. - - \param msg the message to check - - \return LDB_SUCCESS if the message is OK, or a non-zero error code - (one of LDB_ERR_INVALID_DN_SYNTAX, LDB_ERR_ENTRY_ALREADY_EXISTS or - LDB_ERR_INVALID_ATTRIBUTE_SYNTAX) if there is a problem with a - message. -*/ -int ldb_msg_sanity_check(struct ldb_context *ldb, - const struct ldb_message *msg); - -/** - Duplicate an ldb_val structure - - This function copies an ldb value structure. - - \param mem_ctx the memory context that the duplicated value will be - allocated from - \param v the ldb_val to be duplicated. - - \return the duplicated ldb_val structure. -*/ -struct ldb_val ldb_val_dup(void *mem_ctx, const struct ldb_val *v); - -/** - this allows the user to set a debug function for error reporting -*/ -int ldb_set_debug(struct ldb_context *ldb, - void (*debug)(void *context, enum ldb_debug_level level, - const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0), - void *context); - -/** - this allows the user to set custom utf8 function for error reporting -*/ -void ldb_set_utf8_fns(struct ldb_context *ldb, - void *context, - char *(*casefold)(void *, void *, const char *)); - -/** - this sets up debug to print messages on stderr -*/ -int ldb_set_debug_stderr(struct ldb_context *ldb); - -/* control backend specific opaque values */ -int ldb_set_opaque(struct ldb_context *ldb, const char *name, void *value); -void *ldb_get_opaque(struct ldb_context *ldb, const char *name); - -const struct ldb_attrib_handler *ldb_attrib_handler(struct ldb_context *ldb, - const char *attrib); - - -const char **ldb_attr_list_copy(void *mem_ctx, const char * const *attrs); -const char **ldb_attr_list_copy_add(void *mem_ctx, const char * const *attrs, const char *new_attr); -int ldb_attr_in_list(const char * const *attrs, const char *attr); - - -void ldb_parse_tree_attr_replace(struct ldb_parse_tree *tree, - const char *attr, - const char *replace); - -int ldb_msg_rename_attr(struct ldb_message *msg, const char *attr, const char *replace); -int ldb_msg_copy_attr(struct ldb_message *msg, const char *attr, const char *replace); -void ldb_msg_remove_attr(struct ldb_message *msg, const char *attr); - -/** - Convert a time structure to a string - - This function converts a time_t structure to an LDAP formatted time - string. - - \param mem_ctx the memory context to allocate the return string in - \param t the time structure to convert - - \return the formatted string, or NULL if the time structure could - not be converted -*/ -char *ldb_timestring(void *mem_ctx, time_t t); - -/** - Convert a string to a time structure - - This function converts an LDAP formatted time string to a time_t - structure. - - \param s the string to convert - - \return the time structure, or 0 if the string cannot be converted -*/ -time_t ldb_string_to_time(const char *s); - - -void ldb_qsort (void *const pbase, size_t total_elems, size_t size, void *opaque, ldb_qsort_cmp_fn_t cmp); -#endif diff --git a/source/lib/ldb/include/ldb_errors.h b/source/lib/ldb/include/ldb_errors.h deleted file mode 100644 index 3b04c7c17f2..00000000000 --- a/source/lib/ldb/include/ldb_errors.h +++ /dev/null @@ -1,311 +0,0 @@ -/* - ldb database library - - Copyright (C) Simo Sorce 2005 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - * Name: ldb - * - * Component: ldb header - * - * Description: defines error codes following RFC 2251 ldap error codes - * - * Author: Simo Sorce - */ - -#ifndef _LDB_ERRORS_H_ - -/*! \cond DOXYGEN_IGNORE */ -#define _LDB_ERRORS_H_ 1 -/*! \endcond */ - -/** - \file ldb_errors.h - - This header provides a set of result codes for LDB function calls. - - Many LDB function calls return an integer value (int). As shown in - the function documentation, those return values may indicate - whether the function call worked correctly (in which case it - returns LDB_SUCCESS) or some problem occurred (in which case some - other value will be returned). As a special case, - LDB_ERR_COMPARE_FALSE or LDB_ERR_COMPARE_TRUE may be returned, - which does not indicate an error. - - \note Not all error codes make sense for LDB, however they are - based on the LDAP error codes, and are kept for reference and to - avoid overlap. - - \note Some of this documentation is based on information in - the OpenLDAP documentation, as developed and maintained by the - <a href="http://www.openldap.org/">The OpenLDAP Project</a>. - */ - -/** - The function call succeeded. - - If a function returns LDB_SUCCESS, then that function, and the - underlying transactions that may have been required, completed - successfully. -*/ -#define LDB_SUCCESS 0 - -/** - The function call failed for some non-specific reason. -*/ -#define LDB_ERR_OPERATIONS_ERROR 1 - -/** - The function call failed because of a protocol violation. -*/ -#define LDB_ERR_PROTOCOL_ERROR 2 - -/** - The function call failed because a time limit was exceeded. -*/ -#define LDB_ERR_TIME_LIMIT_EXCEEDED 3 - -/** - The function call failed because a size limit was exceeded. -*/ -#define LDB_ERR_SIZE_LIMIT_EXCEEDED 4 - -/** - The function was for value comparison, and the comparison operation - returned false. - - \note This is a status value, and doesn't normally indicate an - error. -*/ -#define LDB_ERR_COMPARE_FALSE 5 - -/** - The function was for value comparison, and the comparison operation - returned true. - - \note This is a status value, and doesn't normally indicate an - error. -*/ -#define LDB_ERR_COMPARE_TRUE 6 - -/** - The function used an authentication method that is not supported by - the database. -*/ -#define LDB_ERR_AUTH_METHOD_NOT_SUPPORTED 7 - -/** - The function call required a underlying operation that required - strong authentication. - - This will normally only occur if you are using LDB with a LDAP - backend. -*/ -#define LDB_ERR_STRONG_AUTH_REQUIRED 8 -/* 9 RESERVED */ - -/** - The function resulted in a referral to another server. -*/ -#define LDB_ERR_REFERRAL 10 - -/** - The function failed because an administrative / policy limit was - exceeded. -*/ -#define LDB_ERR_ADMIN_LIMIT_EXCEEDED 11 - -/** - The function required an extension or capability that the - database cannot provide. -*/ -#define LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION 12 - -/** - The function involved a transaction or database operation that - could not be performed without a secure link. -*/ -#define LDB_ERR_CONFIDENTIALITY_REQUIRED 13 - -/** - This is an intermediate result code for SASL bind operations that - have more than one step. - - \note This is a result code that does not normally indicate an - error has occurred. -*/ -#define LDB_ERR_SASL_BIND_IN_PROGRESS 14 - -/** - The function referred to an attribute type that is not present in - the entry. -*/ -#define LDB_ERR_NO_SUCH_ATTRIBUTE 16 - -/** - The function referred to an attribute type that is invalid -*/ -#define LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE 17 - -/** - The function required a filter type that is not available for the - specified attribute. -*/ -#define LDB_ERR_INAPPROPRIATE_MATCHING 18 - -/** - The function would have violated an attribute constraint. -*/ -#define LDB_ERR_CONSTRAINT_VIOLATION 19 - -/** - The function involved an attribute type or attribute value that - already exists in the entry. -*/ -#define LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS 20 -/** - The function used an invalid (incorrect syntax) attribute value. -*/ -#define LDB_ERR_INVALID_ATTRIBUTE_SYNTAX 21 - -/* 22-31 unused */ - -/** - The function referred to an object that does not exist in the - database. -*/ -#define LDB_ERR_NO_SUCH_OBJECT 32 - -/** - The function referred to an alias which points to a non-existant - object in the database. -*/ -#define LDB_ERR_ALIAS_PROBLEM 33 - -/** - The function used a DN which was invalid (incorrect syntax). -*/ -#define LDB_ERR_INVALID_DN_SYNTAX 34 - -/* 35 RESERVED */ - -/** - The function required dereferencing of an alias, and something went - wrong during the dereferencing process. -*/ -#define LDB_ERR_ALIAS_DEREFERENCING_PROBLEM 36 - -/* 37-47 unused */ - -/** - The function passed in the wrong authentication method. -*/ -#define LDB_ERR_INAPPROPRIATE_AUTHENTICATION 48 - -/** - The function passed in or referenced incorrect credentials during - authentication. -*/ -#define LDB_ERR_INVALID_CREDENTIALS 49 - -/** - The function required access permissions that the user does not - possess. -*/ -#define LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS 50 - -/** - The function required a transaction or call that the database could - not perform because it is busy. -*/ -#define LDB_ERR_BUSY 51 - -/** - The function required a transaction or call to a database that is - not available. -*/ -#define LDB_ERR_UNAVAILABLE 52 - -/** - The function required a transaction or call to a database that the - database declined to perform. -*/ -#define LDB_ERR_UNWILLING_TO_PERFORM 53 - -/** - The function failed because it resulted in a loop being detected. -*/ -#define LDB_ERR_LOOP_DETECT 54 - -/* 55-63 unused */ - -/** - The function failed because it would have violated a naming rule. -*/ -#define LDB_ERR_NAMING_VIOLATION 64 - -/** - The function failed because it would have violated the schema. -*/ -#define LDB_ERR_OBJECT_CLASS_VIOLATION 65 - -/** - The function required an operation that is only allowed on leaf - objects, but the object is not a leaf. -*/ -#define LDB_ERR_NOT_ALLOWED_ON_NON_LEAF 66 - -/** - The function required an operation that cannot be performed on a - Relative DN, but the object is a Relative DN. -*/ -#define LDB_ERR_NOT_ALLOWED_ON_RDN 67 - -/** - The function failed because the entry already exists. -*/ -#define LDB_ERR_ENTRY_ALREADY_EXISTS 68 - -/** - The function failed because modifications to an object class are - not allowable. -*/ -#define LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED 69 - -/* 70 RESERVED FOR CLDAP */ - -/** - The function failed because it needed to be applied to multiple - databases. -*/ -#define LDB_ERR_AFFECTS_MULTIPLE_DSAS 71 - -/* 72-79 unused */ - -/** - The function failed for unknown reasons. -*/ -#define LDB_ERR_OTHER 80 - -/* 81-90 RESERVED for APIs */ - -#endif /* _LDB_ERRORS_H_ */ diff --git a/source/lib/ldb/include/ldb_private.h b/source/lib/ldb/include/ldb_private.h deleted file mode 100644 index f4049188ad3..00000000000 --- a/source/lib/ldb/include/ldb_private.h +++ /dev/null @@ -1,225 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - Copyright (C) Stefan Metzmacher 2004 - Copyright (C) Simo Sorce 2004-2005 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - * Name: ldb - * - * Component: ldb private header - * - * Description: defines internal ldb structures used by the subsystem and modules - * - * Author: Andrew Tridgell - * Author: Stefan Metzmacher - */ - -#ifndef _LDB_PRIVATE_H_ -#define _LDB_PRIVATE_H_ 1 - -struct ldb_context; - -struct ldb_module_ops; - -/* basic module structure */ -struct ldb_module { - struct ldb_module *prev, *next; - struct ldb_context *ldb; - void *private_data; - const struct ldb_module_ops *ops; -}; - -/* - these function pointers define the operations that a ldb module must perform - they correspond exactly to the ldb_*() interface -*/ -struct ldb_module_ops { - const char *name; - int (*init_context) (struct ldb_module *); - int (*search)(struct ldb_module *, struct ldb_request *); /* search */ - int (*add)(struct ldb_module *, struct ldb_request *); /* add */ - int (*modify)(struct ldb_module *, struct ldb_request *); /* modify */ - int (*del)(struct ldb_module *, struct ldb_request *); /* delete */ - int (*rename)(struct ldb_module *, struct ldb_request *); /* rename */ - int (*request)(struct ldb_module *, struct ldb_request *); /* match any other operation */ - int (*extended)(struct ldb_module *, struct ldb_request *); /* extended operations */ - int (*start_transaction)(struct ldb_module *); - int (*end_transaction)(struct ldb_module *); - int (*del_transaction)(struct ldb_module *); - int (*wait)(struct ldb_handle *, enum ldb_wait_type); - int (*sequence_number)(struct ldb_module *, struct ldb_request *); -}; - -typedef int (*ldb_connect_fn) (struct ldb_context *ldb, const char *url, unsigned int flags, const char *options[], - struct ldb_module **module); - -/* - schema related information needed for matching rules -*/ -struct ldb_schema { - /* attribute handling table */ - unsigned num_attrib_handlers; - struct ldb_attrib_handler *attrib_handlers; - - /* objectclass information */ - unsigned num_classes; - struct ldb_subclass { - char *name; - char **subclasses; - } *classes; -}; - -/* - every ldb connection is started by establishing a ldb_context -*/ -struct ldb_context { - /* the operations provided by the backend */ - struct ldb_module *modules; - - /* debugging operations */ - struct ldb_debug_ops debug_ops; - - /* custom utf8 functions */ - struct ldb_utf8_fns utf8_fns; - - /* backend specific opaque parameters */ - struct ldb_opaque { - struct ldb_opaque *next; - const char *name; - void *value; - } *opaque; - - struct ldb_schema schema; - - char *err_string; - - int transaction_active; - - int default_timeout; - - unsigned int flags; - - unsigned int create_perms; -}; - -#ifndef ARRAY_SIZE -#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) -#endif - -/* - simplify out of memory handling -*/ -#define ldb_oom(ldb) ldb_debug_set(ldb, LDB_DEBUG_FATAL, "ldb out of memory at %s:%d\n", __FILE__, __LINE__) - -/* The following definitions come from lib/ldb/common/ldb.c */ - -int ldb_connect_backend(struct ldb_context *ldb, const char *url, const char *options[], - struct ldb_module **backend_module); - -/* The following definitions come from lib/ldb/common/ldb_modules.c */ - -const char **ldb_modules_list_from_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *string); -int ldb_load_modules_list(struct ldb_context *ldb, const char **module_list, struct ldb_module *backend, struct ldb_module **out); -int ldb_load_modules(struct ldb_context *ldb, const char *options[]); -int ldb_init_module_chain(struct ldb_context *ldb, struct ldb_module *module); -int ldb_next_request(struct ldb_module *module, struct ldb_request *request); -int ldb_next_start_trans(struct ldb_module *module); -int ldb_next_end_trans(struct ldb_module *module); -int ldb_next_del_trans(struct ldb_module *module); -int ldb_next_init(struct ldb_module *module); - -void ldb_set_errstring(struct ldb_context *ldb, const char *err_string); -void ldb_asprintf_errstring(struct ldb_context *ldb, const char *format, ...) PRINTF_ATTRIBUTE(2,3); -void ldb_reset_err_string(struct ldb_context *ldb); - -int ldb_register_module(const struct ldb_module_ops *); -int ldb_register_backend(const char *url_prefix, ldb_connect_fn); -int ldb_try_load_dso(struct ldb_context *ldb, const char *name); - -/* The following definitions come from lib/ldb/common/ldb_debug.c */ -void ldb_debug(struct ldb_context *ldb, enum ldb_debug_level level, const char *fmt, ...) PRINTF_ATTRIBUTE(3, 4); -void ldb_debug_set(struct ldb_context *ldb, enum ldb_debug_level level, - const char *fmt, ...) PRINTF_ATTRIBUTE(3, 4); - -/* The following definitions come from lib/ldb/common/ldb_ldif.c */ -int ldb_should_b64_encode(const struct ldb_val *val); - -int ldb_objectclass_init(void); -int ldb_operational_init(void); -int ldb_paged_results_init(void); -int ldb_rdn_name_init(void); -int ldb_schema_init(void); -int ldb_asq_init(void); -int ldb_sort_init(void); -int ldb_ldap_init(void); -int ldb_ildap_init(void); -int ldb_tdb_init(void); -int ldb_sqlite3_init(void); - -int ldb_match_msg(struct ldb_context *ldb, - const struct ldb_message *msg, - const struct ldb_parse_tree *tree, - const struct ldb_dn *base, - enum ldb_scope scope); - -void ldb_remove_attrib_handler(struct ldb_context *ldb, const char *attrib); -const struct ldb_attrib_handler *ldb_attrib_handler_syntax(struct ldb_context *ldb, - const char *syntax); -int ldb_set_attrib_handlers(struct ldb_context *ldb, - const struct ldb_attrib_handler *handlers, - unsigned num_handlers); -int ldb_setup_wellknown_attributes(struct ldb_context *ldb); -int ldb_set_attrib_handler_syntax(struct ldb_context *ldb, - const char *attr, const char *syntax); - -/* The following definitions come from lib/ldb/common/ldb_attributes.c */ -const char **ldb_subclass_list(struct ldb_context *ldb, const char *classname); -void ldb_subclass_remove(struct ldb_context *ldb, const char *classname); -int ldb_subclass_add(struct ldb_context *ldb, const char *classname, const char *subclass); - -int ldb_handler_copy(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out); -int ldb_comparison_binary(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *v1, const struct ldb_val *v2); - -/* The following definitions come from lib/ldb/common/ldb_controls.c */ -struct ldb_control *get_control_from_list(struct ldb_control **controls, const char *oid); -int save_controls(struct ldb_control *exclude, struct ldb_request *req, struct ldb_control ***saver); -int check_critical_controls(struct ldb_control **controls); - -/* The following definitions come from lib/ldb/common/ldb_utf8.c */ -char *ldb_casefold_default(void *context, void *mem_ctx, const char *s); - -void ldb_msg_remove_element(struct ldb_message *msg, struct ldb_message_element *el); - -/** - Obtain current/next database sequence number -*/ -int ldb_sequence_number(struct ldb_context *ldb, enum ldb_sequence_type type, uint64_t *seq_num); - -#define LDB_SEQ_GLOBAL_SEQUENCE 0x01 -#define LDB_SEQ_TIMESTAMP_SEQUENCE 0x02 - - -#endif diff --git a/source/lib/ldb/install-sh b/source/lib/ldb/install-sh deleted file mode 100755 index 58719246f04..00000000000 --- a/source/lib/ldb/install-sh +++ /dev/null @@ -1,238 +0,0 @@ -#! /bin/sh -# -# install - install a program, script, or datafile -# This comes from X11R5. -# -# Calling this script install-sh is preferred over install.sh, to prevent -# `make' implicit rules from creating a file called install from it -# when there is no Makefile. -# -# This script is compatible with the BSD install script, but was written -# from scratch. -# - - -# set DOITPROG to echo to test this script - -# Don't use :- since 4.3BSD and earlier shells don't like it. -doit="${DOITPROG-}" - - -# put in absolute paths if you don't have them in your path; or use env. vars. - -mvprog="${MVPROG-mv}" -cpprog="${CPPROG-cp}" -chmodprog="${CHMODPROG-chmod}" -chownprog="${CHOWNPROG-chown}" -chgrpprog="${CHGRPPROG-chgrp}" -stripprog="${STRIPPROG-strip}" -rmprog="${RMPROG-rm}" -mkdirprog="${MKDIRPROG-mkdir}" - -transformbasename="" -transform_arg="" -instcmd="$mvprog" -chmodcmd="$chmodprog 0755" -chowncmd="" -chgrpcmd="" -stripcmd="" -rmcmd="$rmprog -f" -mvcmd="$mvprog" -src="" -dst="" -dir_arg="" - -while [ x"$1" != x ]; do - case $1 in - -c) instcmd="$cpprog" - shift - continue;; - - -d) dir_arg=true - shift - continue;; - - -m) chmodcmd="$chmodprog $2" - shift - shift - continue;; - - -o) chowncmd="$chownprog $2" - shift - shift - continue;; - - -g) chgrpcmd="$chgrpprog $2" - shift - shift - continue;; - - -s) stripcmd="$stripprog" - shift - continue;; - - -t=*) transformarg=`echo $1 | sed 's/-t=//'` - shift - continue;; - - -b=*) transformbasename=`echo $1 | sed 's/-b=//'` - shift - continue;; - - *) if [ x"$src" = x ] - then - src=$1 - else - # this colon is to work around a 386BSD /bin/sh bug - : - dst=$1 - fi - shift - continue;; - esac -done - -if [ x"$src" = x ] -then - echo "install: no input file specified" - exit 1 -else - true -fi - -if [ x"$dir_arg" != x ]; then - dst=$src - src="" - - if [ -d $dst ]; then - instcmd=: - else - instcmd=mkdir - fi -else - -# Waiting for this to be detected by the "$instcmd $src $dsttmp" command -# might cause directories to be created, which would be especially bad -# if $src (and thus $dsttmp) contains '*'. - - if [ -f $src -o -d $src ] - then - true - else - echo "install: $src does not exist" - exit 1 - fi - - if [ x"$dst" = x ] - then - echo "install: no destination specified" - exit 1 - else - true - fi - -# If destination is a directory, append the input filename; if your system -# does not like double slashes in filenames, you may need to add some logic - - if [ -d $dst ] - then - dst="$dst"/`basename $src` - else - true - fi -fi - -## this sed command emulates the dirname command -dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` - -# Make sure that the destination directory exists. -# this part is taken from Noah Friedman's mkinstalldirs script - -# Skip lots of stat calls in the usual case. -if [ ! -d "$dstdir" ]; then -defaultIFS=' -' -IFS="${IFS-${defaultIFS}}" - -oIFS="${IFS}" -# Some sh's can't handle IFS=/ for some reason. -IFS='%' -set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` -IFS="${oIFS}" - -pathcomp='' - -while [ $# -ne 0 ] ; do - pathcomp="${pathcomp}${1}" - shift - - if [ ! -d "${pathcomp}" ] ; - then - $mkdirprog "${pathcomp}" - else - true - fi - - pathcomp="${pathcomp}/" -done -fi - -if [ x"$dir_arg" != x ] -then - $doit $instcmd $dst && - - if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi -else - -# If we're going to rename the final executable, determine the name now. - - if [ x"$transformarg" = x ] - then - dstfile=`basename $dst` - else - dstfile=`basename $dst $transformbasename | - sed $transformarg`$transformbasename - fi - -# don't allow the sed command to completely eliminate the filename - - if [ x"$dstfile" = x ] - then - dstfile=`basename $dst` - else - true - fi - -# Make a temp file name in the proper directory. - - dsttmp=$dstdir/#inst.$$# - -# Move or copy the file name to the temp name - - $doit $instcmd $src $dsttmp && - - trap "rm -f ${dsttmp}" 0 && - -# and set any options; do chmod last to preserve setuid bits - -# If any of these fail, we abort the whole thing. If we want to -# ignore errors from any of these, just make sure not to ignore -# errors from the above "$doit $instcmd $src $dsttmp" command. - - if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && - -# Now rename the file to the real destination. - - $doit $rmcmd -f $dstdir/$dstfile && - $doit $mvcmd $dsttmp $dstdir/$dstfile - -fi && - - -exit 0 diff --git a/source/lib/ldb/ldap.m4 b/source/lib/ldb/ldap.m4 deleted file mode 100644 index 417083ed61c..00000000000 --- a/source/lib/ldb/ldap.m4 +++ /dev/null @@ -1,90 +0,0 @@ -######################################################## -# Compile with LDAP support? - -LDAP_LIBS="" -with_ldap_support=auto -AC_MSG_CHECKING([for LDAP support]) - -AC_ARG_WITH(ldap, -AS_HELP_STRING([--with-ldap],[LDAP backend support (default=yes)]), -[ case "$withval" in - yes|no) - with_ldap_support=$withval - ;; - esac ]) - -AC_MSG_RESULT($with_ldap_support) - -if test x"$with_ldap_support" != x"no"; then - - ################################################################## - # first test for ldap.h and lber.h - # (ldap.h is required for this test) - AC_CHECK_HEADERS(ldap.h lber.h) - - if test x"$ac_cv_header_ldap_h" != x"yes"; then - if test x"$with_ldap_support" = x"yes"; then - AC_MSG_ERROR(ldap.h is needed for LDAP support) - else - AC_MSG_WARN(ldap.h is needed for LDAP support) - fi - - with_ldap_support=no - fi -fi - -if test x"$with_ldap_support" != x"no"; then - ac_save_LIBS=$LIBS - - ################################################################## - # we might need the lber lib on some systems. To avoid link errors - # this test must be before the libldap test - AC_CHECK_LIB_EXT(lber, LDAP_LIBS, ber_scanf) - - ######################################################## - # now see if we can find the ldap libs in standard paths - AC_CHECK_LIB_EXT(ldap, LDAP_LIBS, ldap_init) - - AC_CHECK_FUNC_EXT(ldap_domain2hostlist,$LDAP_LIBS) - - ######################################################## - # If we have LDAP, does it's rebind procedure take 2 or 3 arguments? - # Check found in pam_ldap 145. - AC_CHECK_FUNC_EXT(ldap_set_rebind_proc,$LDAP_LIBS) - - LIBS="$LIBS $LDAP_LIBS" - AC_CACHE_CHECK(whether ldap_set_rebind_proc takes 3 arguments, smb_ldap_cv_ldap_set_rebind_proc, [ - AC_TRY_COMPILE([ - #include <lber.h> - #include <ldap.h>], - [ldap_set_rebind_proc(0, 0, 0);], - [smb_ldap_cv_ldap_set_rebind_proc=3], - [smb_ldap_cv_ldap_set_rebind_proc=2] - ) - ]) - - AC_DEFINE_UNQUOTED(LDAP_SET_REBIND_PROC_ARGS, $smb_ldap_cv_ldap_set_rebind_proc, [Number of arguments to ldap_set_rebind_proc]) - - AC_CHECK_FUNC_EXT(ldap_initialize,$LDAP_LIBS) - - if test x"$ac_cv_lib_ext_ldap_ldap_init" = x"yes" -a x"$ac_cv_func_ext_ldap_domain2hostlist" = x"yes"; then - AC_DEFINE(HAVE_LDAP,1,[Whether ldap is available]) - AC_DEFINE(HAVE_LDB_LDAP,1,[Whether ldb_ldap is available]) - with_ldap_support=yes - AC_MSG_CHECKING(whether LDAP support is used) - AC_MSG_RESULT(yes) - SMB_ENABLE(LDAP,YES) - else - if test x"$with_ldap_support" = x"yes"; then - AC_MSG_ERROR(libldap is needed for LDAP support) - else - AC_MSG_WARN(libldap is needed for LDAP support) - fi - - LDAP_LIBS="" - with_ldap_support=no - fi - LIBS=$ac_save_LIBS -fi - -SMB_EXT_LIB(LDAP,[${LDAP_LIBS}],[${LDAP_CFLAGS}],[${LDAP_CPPFLAGS}],[${LDAP_LDFLAGS}]) diff --git a/source/lib/ldb/ldb.pc.in b/source/lib/ldb/ldb.pc.in deleted file mode 100644 index 815d663a7c8..00000000000 --- a/source/lib/ldb/ldb.pc.in +++ /dev/null @@ -1,15 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ -modulesdir=@modulesdir@ - -Name: ldb -Description: An LDAP-like embedded database -Version: 4.0 -Requires.private: tdb -Requires: talloc -Libs: -L${libdir} -lldb -Cflags: -I${includedir} @CFLAGS@ -Modulesdir: ${modulesdir} -URL: http://ldb.samba.org/ diff --git a/source/lib/ldb/ldb_ildap/ldb_ildap.c b/source/lib/ldb/ldb_ildap/ldb_ildap.c deleted file mode 100644 index 87f38b5fc78..00000000000 --- a/source/lib/ldb/ldb_ildap/ldb_ildap.c +++ /dev/null @@ -1,828 +0,0 @@ -/* - ldb database library - ildap backend - - Copyright (C) Andrew Tridgell 2005 - Copyright (C) Simo Sorce 2006 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - * Name: ldb_ildap - * - * Component: ldb ildap backend - * - * Description: This is a ldb backend for the internal ldap - * client library in Samba4. By using this backend we are - * independent of a system ldap library - * - * Author: Andrew Tridgell - * - * Modifications: - * - * - description: make the module use asyncronous calls - * date: Feb 2006 - * author: Simo Sorce - */ - - -#include "includes.h" -#include "ldb/include/includes.h" - -#include "lib/events/events.h" -#include "libcli/ldap/ldap.h" -#include "libcli/ldap/ldap_client.h" -#include "auth/auth.h" -#include "auth/credentials/credentials.h" - -struct ildb_private { - struct ldap_connection *ldap; - struct ldb_context *ldb; -}; - -struct ildb_context { - struct ldb_module *module; - struct ldap_request *req; - void *context; - int (*callback)(struct ldb_context *, void *, struct ldb_reply *); -}; - -/* - convert a ldb_message structure to a list of ldap_mod structures - ready for ildap_add() or ildap_modify() -*/ -static struct ldap_mod **ildb_msg_to_mods(void *mem_ctx, int *num_mods, - const struct ldb_message *msg, int use_flags) -{ - struct ldap_mod **mods; - unsigned int i; - int n = 0; - - /* allocate maximum number of elements needed */ - mods = talloc_array(mem_ctx, struct ldap_mod *, msg->num_elements+1); - if (!mods) { - errno = ENOMEM; - return NULL; - } - mods[0] = NULL; - - for (i = 0; i < msg->num_elements; i++) { - const struct ldb_message_element *el = &msg->elements[i]; - - mods[n] = talloc(mods, struct ldap_mod); - if (!mods[n]) { - goto failed; - } - mods[n + 1] = NULL; - mods[n]->type = 0; - mods[n]->attrib = *el; - if (use_flags) { - switch (el->flags & LDB_FLAG_MOD_MASK) { - case LDB_FLAG_MOD_ADD: - mods[n]->type = LDAP_MODIFY_ADD; - break; - case LDB_FLAG_MOD_DELETE: - mods[n]->type = LDAP_MODIFY_DELETE; - break; - case LDB_FLAG_MOD_REPLACE: - mods[n]->type = LDAP_MODIFY_REPLACE; - break; - } - } - n++; - } - - *num_mods = n; - return mods; - -failed: - talloc_free(mods); - return NULL; -} - - -/* - map an ildap NTSTATUS to a ldb error code -*/ -static int ildb_map_error(struct ildb_private *ildb, NTSTATUS status) -{ - if (NT_STATUS_IS_OK(status)) { - return LDB_SUCCESS; - } - ldb_set_errstring(ildb->ldb, ldap_errstr(ildb->ldap, status)); - if (NT_STATUS_IS_LDAP(status)) { - return NT_STATUS_LDAP_CODE(status); - } - return LDB_ERR_OPERATIONS_ERROR; -} - -static void ildb_request_timeout(struct event_context *ev, struct timed_event *te, - struct timeval t, void *private_data) -{ - struct ldb_handle *handle = talloc_get_type(private_data, struct ldb_handle); - struct ildb_context *ac = talloc_get_type(handle->private_data, struct ildb_context); - - if (ac->req->state == LDAP_REQUEST_PENDING) { - DLIST_REMOVE(ac->req->conn->pending, ac->req); - } - - handle->status = LDB_ERR_TIME_LIMIT_EXCEEDED; - - return; -} - -static void ildb_callback(struct ldap_request *req) -{ - struct ldb_handle *handle = talloc_get_type(req->async.private_data, struct ldb_handle); - struct ildb_context *ac = talloc_get_type(handle->private_data, struct ildb_context); - struct ildb_private *ildb = talloc_get_type(ac->module->private_data, struct ildb_private); - NTSTATUS status; - int i; - - handle->status = LDB_SUCCESS; - - if (!NT_STATUS_IS_OK(req->status)) { - handle->status = ildb_map_error(ildb, req->status); - return; - } - - if (req->num_replies < 1) { - handle->status = LDB_ERR_OPERATIONS_ERROR; - return; - } - - switch (req->type) { - - case LDAP_TAG_ModifyRequest: - if (req->replies[0]->type != LDAP_TAG_ModifyResponse) { - handle->status = LDB_ERR_PROTOCOL_ERROR; - return; - } - status = ldap_check_response(req->conn, &req->replies[0]->r.GeneralResult); - handle->status = ildb_map_error(ildb, status); - if (ac->callback && handle->status == LDB_SUCCESS) { - /* FIXME: build a corresponding ares to pass on */ - handle->status = ac->callback(ac->module->ldb, ac->context, NULL); - } - handle->state = LDB_ASYNC_DONE; - break; - - case LDAP_TAG_AddRequest: - if (req->replies[0]->type != LDAP_TAG_AddResponse) { - handle->status = LDB_ERR_PROTOCOL_ERROR; - return; - } - status = ldap_check_response(req->conn, &req->replies[0]->r.GeneralResult); - handle->status = ildb_map_error(ildb, status); - if (ac->callback && handle->status == LDB_SUCCESS) { - /* FIXME: build a corresponding ares to pass on */ - handle->status = ac->callback(ac->module->ldb, ac->context, NULL); - } - handle->state = LDB_ASYNC_DONE; - break; - - case LDAP_TAG_DelRequest: - if (req->replies[0]->type != LDAP_TAG_DelResponse) { - handle->status = LDB_ERR_PROTOCOL_ERROR; - return; - } - status = ldap_check_response(req->conn, &req->replies[0]->r.GeneralResult); - handle->status = ildb_map_error(ildb, status); - if (ac->callback && handle->status == LDB_SUCCESS) { - /* FIXME: build a corresponding ares to pass on */ - handle->status = ac->callback(ac->module->ldb, ac->context, NULL); - } - handle->state = LDB_ASYNC_DONE; - break; - - case LDAP_TAG_ModifyDNRequest: - if (req->replies[0]->type != LDAP_TAG_ModifyDNResponse) { - handle->status = LDB_ERR_PROTOCOL_ERROR; - return; - } - status = ldap_check_response(req->conn, &req->replies[0]->r.GeneralResult); - handle->status = ildb_map_error(ildb, status); - if (ac->callback && handle->status == LDB_SUCCESS) { - /* FIXME: build a corresponding ares to pass on */ - handle->status = ac->callback(ac->module->ldb, ac->context, NULL); - } - handle->state = LDB_ASYNC_DONE; - break; - - case LDAP_TAG_SearchRequest: - /* loop over all messages */ - for (i = 0; i < req->num_replies; i++) { - struct ldap_SearchResEntry *search; - struct ldb_reply *ares = NULL; - struct ldap_message *msg; - int ret; - - ares = talloc_zero(ac, struct ldb_reply); - if (!ares) { - handle->status = LDB_ERR_OPERATIONS_ERROR; - return; - } - - msg = req->replies[i]; - switch (msg->type) { - - case LDAP_TAG_SearchResultDone: - - status = ldap_check_response(req->conn, &msg->r.GeneralResult); - if (!NT_STATUS_IS_OK(status)) { - handle->status = ildb_map_error(ildb, status); - return; - } - - ares->controls = talloc_move(ares, &msg->controls); - if (msg->r.SearchResultDone.resultcode) { - if (msg->r.SearchResultDone.errormessage) { - ldb_set_errstring(ac->module->ldb, msg->r.SearchResultDone.errormessage); - } - } - - handle->status = msg->r.SearchResultDone.resultcode; - handle->state = LDB_ASYNC_DONE; - ares->type = LDB_REPLY_DONE; - break; - - case LDAP_TAG_SearchResultEntry: - - - ares->message = ldb_msg_new(ares); - if (!ares->message) { - handle->status = LDB_ERR_OPERATIONS_ERROR; - return; - } - - search = &(msg->r.SearchResultEntry); - - ares->message->dn = ldb_dn_explode_or_special(ares->message, search->dn); - if (ares->message->dn == NULL) { - handle->status = LDB_ERR_OPERATIONS_ERROR; - return; - } - ares->message->num_elements = search->num_attributes; - ares->message->elements = talloc_move(ares->message, - &search->attributes); - - handle->status = LDB_SUCCESS; - handle->state = LDB_ASYNC_PENDING; - ares->type = LDB_REPLY_ENTRY; - break; - - case LDAP_TAG_SearchResultReference: - - ares->referral = talloc_strdup(ares, msg->r.SearchResultReference.referral); - - handle->status = LDB_SUCCESS; - handle->state = LDB_ASYNC_PENDING; - ares->type = LDB_REPLY_REFERRAL; - break; - - default: - /* TAG not handled, fail ! */ - handle->status = LDB_ERR_PROTOCOL_ERROR; - return; - } - - ret = ac->callback(ac->module->ldb, ac->context, ares); - if (ret) { - handle->status = ret; - } - } - - talloc_free(req->replies); - req->replies = NULL; - req->num_replies = 0; - - break; - - default: - handle->status = LDB_ERR_PROTOCOL_ERROR; - return; - } -} - -static struct ldb_handle *init_ildb_handle(struct ldb_module *module, - void *context, - int (*callback)(struct ldb_context *, void *, struct ldb_reply *)) -{ - struct ildb_private *ildb = talloc_get_type(module->private_data, struct ildb_private); - struct ildb_context *ildb_ac; - struct ldb_handle *h; - - h = talloc_zero(ildb->ldap, struct ldb_handle); - if (h == NULL) { - ldb_set_errstring(module->ldb, "Out of Memory"); - return NULL; - } - - h->module = module; - - ildb_ac = talloc(h, struct ildb_context); - if (ildb_ac == NULL) { - ldb_set_errstring(module->ldb, "Out of Memory"); - talloc_free(h); - return NULL; - } - - h->private_data = (void *)ildb_ac; - - h->state = LDB_ASYNC_INIT; - h->status = LDB_SUCCESS; - - ildb_ac->module = module; - ildb_ac->context = context; - ildb_ac->callback = callback; - - return h; -} - -static int ildb_request_send(struct ldb_module *module, struct ldap_message *msg, - void *context, - int (*callback)(struct ldb_context *, void *, struct ldb_reply *), - int timeout, - struct ldb_handle **handle) -{ - struct ildb_private *ildb = talloc_get_type(module->private_data, struct ildb_private); - struct ldb_handle *h = init_ildb_handle(module, context, callback); - struct ildb_context *ildb_ac; - struct ldap_request *req; - - if (!h) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ildb_ac = talloc_get_type(h->private_data, struct ildb_context); - - req = ldap_request_send(ildb->ldap, msg); - if (req == NULL) { - ldb_set_errstring(module->ldb, "async send request failed"); - return LDB_ERR_OPERATIONS_ERROR; - } - - if (!req->conn) { - ldb_set_errstring(module->ldb, "connection to remote LDAP server dropped?"); - return LDB_ERR_OPERATIONS_ERROR; - } - - talloc_free(req->time_event); - req->time_event = NULL; - if (timeout) { - req->time_event = event_add_timed(req->conn->event.event_ctx, h, - timeval_current_ofs(timeout, 0), - ildb_request_timeout, h); - } - - req->async.fn = ildb_callback; - req->async.private_data = (void *)h; - ildb_ac->req = talloc_move(ildb_ac, &req); - - *handle = h; - return LDB_SUCCESS; -} - -static int ildb_request_noop(struct ldb_module *module, struct ldb_request *req) -{ - struct ldb_handle *h = init_ildb_handle(module, req->context, req->callback); - struct ildb_context *ildb_ac; - int ret = LDB_SUCCESS; - - if (!h) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ildb_ac = talloc_get_type(h->private_data, struct ildb_context); - - req->handle = h; - - if (ildb_ac->callback) { - ret = ildb_ac->callback(module->ldb, ildb_ac->context, NULL); - } - req->handle->state = LDB_ASYNC_DONE; - return ret; -} - -/* - search for matching records using an asynchronous function - */ -static int ildb_search(struct ldb_module *module, struct ldb_request *req) -{ - struct ildb_private *ildb = talloc_get_type(module->private_data, struct ildb_private); - struct ldap_message *msg; - int n; - - req->handle = NULL; - - if (!req->callback || !req->context) { - ldb_set_errstring(module->ldb, "Async interface called with NULL callback function or NULL context"); - return LDB_ERR_OPERATIONS_ERROR; - } - - if (req->op.search.tree == NULL) { - ldb_set_errstring(module->ldb, "Invalid expression parse tree"); - return LDB_ERR_OPERATIONS_ERROR; - } - - msg = new_ldap_message(ildb); - if (msg == NULL) { - ldb_set_errstring(module->ldb, "Out of Memory"); - return LDB_ERR_OPERATIONS_ERROR; - } - - msg->type = LDAP_TAG_SearchRequest; - - if (req->op.search.base == NULL) { - msg->r.SearchRequest.basedn = talloc_strdup(msg, ""); - } else { - msg->r.SearchRequest.basedn = ldb_dn_linearize(msg, req->op.search.base); - } - if (msg->r.SearchRequest.basedn == NULL) { - ldb_set_errstring(module->ldb, "Unable to determine baseDN"); - talloc_free(msg); - return LDB_ERR_OPERATIONS_ERROR; - } - - if (req->op.search.scope == LDB_SCOPE_DEFAULT) { - msg->r.SearchRequest.scope = LDB_SCOPE_SUBTREE; - } else { - msg->r.SearchRequest.scope = req->op.search.scope; - } - - msg->r.SearchRequest.deref = LDAP_DEREFERENCE_NEVER; - msg->r.SearchRequest.timelimit = 0; - msg->r.SearchRequest.sizelimit = 0; - msg->r.SearchRequest.attributesonly = 0; - msg->r.SearchRequest.tree = discard_const_p(struct ldb_parse_tree, req->op.search.tree); - - for (n = 0; req->op.search.attrs && req->op.search.attrs[n]; n++) /* noop */ ; - msg->r.SearchRequest.num_attributes = n; - msg->r.SearchRequest.attributes = discard_const_p(char *, req->op.search.attrs), - - msg->controls = req->controls; - - return ildb_request_send(module, msg, req->context, req->callback, req->timeout, &(req->handle)); -} - -/* - add a record -*/ -static int ildb_add(struct ldb_module *module, struct ldb_request *req) -{ - struct ildb_private *ildb = talloc_get_type(module->private_data, struct ildb_private); - struct ldap_message *msg; - struct ldap_mod **mods; - int i,n; - - req->handle = NULL; - - /* ignore ltdb specials */ - if (ldb_dn_is_special(req->op.add.message->dn)) { - return ildb_request_noop(module, req); - } - - msg = new_ldap_message(ildb->ldap); - if (msg == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - msg->type = LDAP_TAG_AddRequest; - - msg->r.AddRequest.dn = ldb_dn_linearize(msg, req->op.add.message->dn); - if (msg->r.AddRequest.dn == NULL) { - talloc_free(msg); - return LDB_ERR_INVALID_DN_SYNTAX; - } - - mods = ildb_msg_to_mods(msg, &n, req->op.add.message, 0); - if (mods == NULL) { - talloc_free(msg); - return LDB_ERR_OPERATIONS_ERROR; - } - - msg->r.AddRequest.num_attributes = n; - msg->r.AddRequest.attributes = talloc_array(msg, struct ldb_message_element, n); - if (msg->r.AddRequest.attributes == NULL) { - talloc_free(msg); - return LDB_ERR_OPERATIONS_ERROR; - } - - for (i = 0; i < n; i++) { - msg->r.AddRequest.attributes[i] = mods[i]->attrib; - } - - return ildb_request_send(module, msg, req->context, req->callback, req->timeout, &(req->handle)); -} - -/* - modify a record -*/ -static int ildb_modify(struct ldb_module *module, struct ldb_request *req) -{ - struct ildb_private *ildb = talloc_get_type(module->private_data, struct ildb_private); - struct ldap_message *msg; - struct ldap_mod **mods; - int i,n; - - req->handle = NULL; - - /* ignore ltdb specials */ - if (ldb_dn_is_special(req->op.mod.message->dn)) { - return ildb_request_noop(module, req); - } - - msg = new_ldap_message(ildb->ldap); - if (msg == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - msg->type = LDAP_TAG_ModifyRequest; - - msg->r.ModifyRequest.dn = ldb_dn_linearize(msg, req->op.mod.message->dn); - if (msg->r.ModifyRequest.dn == NULL) { - talloc_free(msg); - return LDB_ERR_INVALID_DN_SYNTAX; - } - - mods = ildb_msg_to_mods(msg, &n, req->op.mod.message, 1); - if (mods == NULL) { - talloc_free(msg); - return LDB_ERR_OPERATIONS_ERROR; - } - - msg->r.ModifyRequest.num_mods = n; - msg->r.ModifyRequest.mods = talloc_array(msg, struct ldap_mod, n); - if (msg->r.ModifyRequest.mods == NULL) { - talloc_free(msg); - return LDB_ERR_OPERATIONS_ERROR; - } - - for (i = 0; i < n; i++) { - msg->r.ModifyRequest.mods[i] = *mods[i]; - } - - return ildb_request_send(module, msg, req->context, req->callback, req->timeout, &(req->handle)); -} - -/* - delete a record -*/ -static int ildb_delete(struct ldb_module *module, struct ldb_request *req) -{ - struct ildb_private *ildb = talloc_get_type(module->private_data, struct ildb_private); - struct ldap_message *msg; - - req->handle = NULL; - - /* ignore ltdb specials */ - if (ldb_dn_is_special(req->op.del.dn)) { - return ildb_request_noop(module, req); - } - - msg = new_ldap_message(ildb->ldap); - if (msg == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - msg->type = LDAP_TAG_DelRequest; - - msg->r.DelRequest.dn = ldb_dn_linearize(msg, req->op.del.dn); - if (msg->r.DelRequest.dn == NULL) { - talloc_free(msg); - return LDB_ERR_INVALID_DN_SYNTAX; - } - - return ildb_request_send(module, msg, req->context, req->callback, req->timeout, &(req->handle)); -} - -/* - rename a record -*/ -static int ildb_rename(struct ldb_module *module, struct ldb_request *req) -{ - struct ildb_private *ildb = talloc_get_type(module->private_data, struct ildb_private); - struct ldap_message *msg; - - req->handle = NULL; - - /* ignore ltdb specials */ - if (ldb_dn_is_special(req->op.rename.olddn) || ldb_dn_is_special(req->op.rename.newdn)) { - return ildb_request_noop(module, req); - } - - msg = new_ldap_message(ildb->ldap); - if (msg == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - msg->type = LDAP_TAG_ModifyDNRequest; - msg->r.ModifyDNRequest.dn = ldb_dn_linearize(msg, req->op.rename.olddn); - if (msg->r.ModifyDNRequest.dn == NULL) { - talloc_free(msg); - return LDB_ERR_INVALID_DN_SYNTAX; - } - - msg->r.ModifyDNRequest.newrdn = - talloc_asprintf(msg, "%s=%s", - ldb_dn_get_rdn_name(req->op.rename.newdn), - ldb_dn_escape_value(msg, *ldb_dn_get_rdn_val(req->op.rename.newdn))); - if (msg->r.ModifyDNRequest.newrdn == NULL) { - talloc_free(msg); - return LDB_ERR_OPERATIONS_ERROR; - } - - msg->r.ModifyDNRequest.newsuperior = - ldb_dn_linearize(msg, - ldb_dn_get_parent(msg, req->op.rename.newdn)); - if (msg->r.ModifyDNRequest.newsuperior == NULL) { - talloc_free(msg); - return LDB_ERR_INVALID_DN_SYNTAX; - } - - msg->r.ModifyDNRequest.deleteolddn = True; - - return ildb_request_send(module, msg, req->context, req->callback, req->timeout, &(req->handle)); -} - -static int ildb_start_trans(struct ldb_module *module) -{ - /* TODO implement a local locking mechanism here */ - - return LDB_SUCCESS; -} - -static int ildb_end_trans(struct ldb_module *module) -{ - /* TODO implement a local transaction mechanism here */ - - return LDB_SUCCESS; -} - -static int ildb_del_trans(struct ldb_module *module) -{ - /* TODO implement a local locking mechanism here */ - - return LDB_SUCCESS; -} - -static int ildb_request(struct ldb_module *module, struct ldb_request *req) -{ - return LDB_ERR_OPERATIONS_ERROR; -} - -static int ildb_wait(struct ldb_handle *handle, enum ldb_wait_type type) -{ - struct ildb_context *ac = talloc_get_type(handle->private_data, struct ildb_context); - - if (handle->state == LDB_ASYNC_DONE) { - return handle->status; - } - - if (!ac) { - return LDB_ERR_OPERATIONS_ERROR; - } - - handle->state = LDB_ASYNC_INIT; - - switch(type) { - case LDB_WAIT_NONE: - if (event_loop_once(ac->req->conn->event.event_ctx) != 0) { - return LDB_ERR_OTHER; - } - break; - case LDB_WAIT_ALL: - while (handle->status == LDB_SUCCESS && handle->state != LDB_ASYNC_DONE) { - if (event_loop_once(ac->req->conn->event.event_ctx) != 0) { - return LDB_ERR_OTHER; - } - } - break; - default: - return LDB_ERR_OPERATIONS_ERROR; - } - - return handle->status; -} - -static const struct ldb_module_ops ildb_ops = { - .name = "ldap", - .search = ildb_search, - .add = ildb_add, - .modify = ildb_modify, - .del = ildb_delete, - .rename = ildb_rename, - .request = ildb_request, - .start_transaction = ildb_start_trans, - .end_transaction = ildb_end_trans, - .del_transaction = ildb_del_trans, - .wait = ildb_wait -}; - -/* - connect to the database -*/ -static int ildb_connect(struct ldb_context *ldb, const char *url, - unsigned int flags, const char *options[], - struct ldb_module **module) -{ - struct ildb_private *ildb = NULL; - NTSTATUS status; - struct cli_credentials *creds; - - ildb = talloc(ldb, struct ildb_private); - if (!ildb) { - ldb_oom(ldb); - goto failed; - } - - ildb->ldb = ldb; - - ildb->ldap = ldap4_new_connection(ildb, ldb_get_opaque(ldb, "EventContext")); - if (!ildb->ldap) { - ldb_oom(ldb); - goto failed; - } - - if (flags & LDB_FLG_RECONNECT) { - ldap_set_reconn_params(ildb->ldap, 10); - } - - status = ldap_connect(ildb->ldap, url); - if (!NT_STATUS_IS_OK(status)) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to connect to ldap URL '%s' - %s\n", - url, ldap_errstr(ildb->ldap, status)); - goto failed; - } - - - *module = talloc(ldb, struct ldb_module); - if (!module) { - ldb_oom(ldb); - talloc_free(ildb); - return -1; - } - talloc_set_name_const(*module, "ldb_ildap backend"); - (*module)->ldb = ldb; - (*module)->prev = (*module)->next = NULL; - (*module)->private_data = ildb; - (*module)->ops = &ildb_ops; - - /* caller can optionally setup credentials using the opaque token 'credentials' */ - creds = talloc_get_type(ldb_get_opaque(ldb, "credentials"), struct cli_credentials); - if (creds == NULL) { - struct auth_session_info *session_info = talloc_get_type(ldb_get_opaque(ldb, "sessionInfo"), struct auth_session_info); - if (session_info) { - creds = session_info->credentials; - } - } - - if (creds != NULL && cli_credentials_authentication_requested(creds)) { - const char *bind_dn = cli_credentials_get_bind_dn(creds); - if (bind_dn) { - const char *password = cli_credentials_get_password(creds); - status = ldap_bind_simple(ildb->ldap, bind_dn, password); - if (!NT_STATUS_IS_OK(status)) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to bind - %s\n", - ldap_errstr(ildb->ldap, status)); - goto failed; - } - } else { - status = ldap_bind_sasl(ildb->ldap, creds); - if (!NT_STATUS_IS_OK(status)) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to bind - %s\n", - ldap_errstr(ildb->ldap, status)); - goto failed; - } - } - } - - return 0; - -failed: - talloc_free(ildb); - return -1; -} - -int ldb_ildap_init(void) -{ - return ldb_register_backend("ldap", ildb_connect) + - ldb_register_backend("ldapi", ildb_connect) + - ldb_register_backend("ldaps", ildb_connect); -} diff --git a/source/lib/ldb/ldb_ldap/ldb_ldap.c b/source/lib/ldb/ldb_ldap/ldb_ldap.c deleted file mode 100644 index c45fa108f2e..00000000000 --- a/source/lib/ldb/ldb_ldap/ldb_ldap.c +++ /dev/null @@ -1,847 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - Copyright (C) Simo Sorce 2006 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - * Name: ldb_ldap - * - * Component: ldb ldap backend - * - * Description: core files for LDAP backend - * - * Author: Andrew Tridgell - * - * Modifications: - * - * - description: make the module use asyncronous calls - * date: Feb 2006 - * author: Simo Sorce - */ - -#include "includes.h" -#include "ldb/include/includes.h" - -#define LDAP_DEPRECATED 1 -#include <ldap.h> - -struct lldb_private { - LDAP *ldap; -}; - -struct lldb_context { - struct ldb_module *module; - int msgid; - int timeout; - time_t starttime; - void *context; - int (*callback)(struct ldb_context *, void *, struct ldb_reply *); -}; - -static int lldb_ldap_to_ldb(int err) { - /* Ldap errors and ldb errors are defined to the same values */ - return err; -} - -static struct ldb_handle *init_handle(struct lldb_private *lldb, struct ldb_module *module, - void *context, - int (*callback)(struct ldb_context *, void *, struct ldb_reply *), - int timeout, time_t starttime) -{ - struct lldb_context *ac; - struct ldb_handle *h; - - h = talloc_zero(lldb, struct ldb_handle); - if (h == NULL) { - ldb_set_errstring(module->ldb, "Out of Memory"); - return NULL; - } - - h->module = module; - - ac = talloc(h, struct lldb_context); - if (ac == NULL) { - ldb_set_errstring(module->ldb, "Out of Memory"); - talloc_free(h); - return NULL; - } - - h->private_data = (void *)ac; - - h->state = LDB_ASYNC_INIT; - h->status = LDB_SUCCESS; - - ac->module = module; - ac->context = context; - ac->callback = callback; - ac->timeout = timeout; - ac->starttime = starttime; - ac->msgid = 0; - - return h; -} -/* - convert a ldb_message structure to a list of LDAPMod structures - ready for ldap_add() or ldap_modify() -*/ -static LDAPMod **lldb_msg_to_mods(void *mem_ctx, const struct ldb_message *msg, int use_flags) -{ - LDAPMod **mods; - unsigned int i, j; - int num_mods = 0; - - /* allocate maximum number of elements needed */ - mods = talloc_array(mem_ctx, LDAPMod *, msg->num_elements+1); - if (!mods) { - errno = ENOMEM; - return NULL; - } - mods[0] = NULL; - - for (i=0;i<msg->num_elements;i++) { - const struct ldb_message_element *el = &msg->elements[i]; - - mods[num_mods] = talloc(mods, LDAPMod); - if (!mods[num_mods]) { - goto failed; - } - mods[num_mods+1] = NULL; - mods[num_mods]->mod_op = LDAP_MOD_BVALUES; - if (use_flags) { - switch (el->flags & LDB_FLAG_MOD_MASK) { - case LDB_FLAG_MOD_ADD: - mods[num_mods]->mod_op |= LDAP_MOD_ADD; - break; - case LDB_FLAG_MOD_DELETE: - mods[num_mods]->mod_op |= LDAP_MOD_DELETE; - break; - case LDB_FLAG_MOD_REPLACE: - mods[num_mods]->mod_op |= LDAP_MOD_REPLACE; - break; - } - } - mods[num_mods]->mod_type = discard_const_p(char, el->name); - mods[num_mods]->mod_vals.modv_bvals = talloc_array(mods[num_mods], - struct berval *, - 1+el->num_values); - if (!mods[num_mods]->mod_vals.modv_bvals) { - goto failed; - } - - for (j=0;j<el->num_values;j++) { - mods[num_mods]->mod_vals.modv_bvals[j] = talloc(mods[num_mods]->mod_vals.modv_bvals, - struct berval); - if (!mods[num_mods]->mod_vals.modv_bvals[j]) { - goto failed; - } - mods[num_mods]->mod_vals.modv_bvals[j]->bv_val = - (char *)el->values[j].data; - mods[num_mods]->mod_vals.modv_bvals[j]->bv_len = el->values[j].length; - } - mods[num_mods]->mod_vals.modv_bvals[j] = NULL; - num_mods++; - } - - return mods; - -failed: - talloc_free(mods); - return NULL; -} - -/* - add a single set of ldap message values to a ldb_message -*/ -static int lldb_add_msg_attr(struct ldb_context *ldb, - struct ldb_message *msg, - const char *attr, struct berval **bval) -{ - int count, i; - struct ldb_message_element *el; - - count = ldap_count_values_len(bval); - - if (count <= 0) { - return -1; - } - - el = talloc_realloc(msg, msg->elements, struct ldb_message_element, - msg->num_elements + 1); - if (!el) { - errno = ENOMEM; - return -1; - } - - msg->elements = el; - - el = &msg->elements[msg->num_elements]; - - el->name = talloc_strdup(msg->elements, attr); - if (!el->name) { - errno = ENOMEM; - return -1; - } - el->flags = 0; - - el->num_values = 0; - el->values = talloc_array(msg->elements, struct ldb_val, count); - if (!el->values) { - errno = ENOMEM; - return -1; - } - - for (i=0;i<count;i++) { - /* we have to ensure this is null terminated so that - ldb_msg_find_attr_as_string() can work */ - el->values[i].data = - (uint8_t *)talloc_size(el->values, bval[i]->bv_len+1); - if (!el->values[i].data) { - errno = ENOMEM; - return -1; - } - memcpy(el->values[i].data, bval[i]->bv_val, bval[i]->bv_len); - el->values[i].data[bval[i]->bv_len] = 0; - el->values[i].length = bval[i]->bv_len; - el->num_values++; - } - - msg->num_elements++; - - return 0; -} - -/* - search for matching records -*/ -static int lldb_search(struct ldb_module *module, struct ldb_request *req) -{ - struct lldb_private *lldb = talloc_get_type(module->private_data, struct lldb_private); - struct lldb_context *lldb_ac; - struct timeval tv; - int ldap_scope; - char *search_base; - char *expression; - int ret; - - if (!req->callback || !req->context) { - ldb_set_errstring(module->ldb, "Async interface called with NULL callback function or NULL context"); - return LDB_ERR_OPERATIONS_ERROR; - } - - if (req->op.search.tree == NULL) { - ldb_set_errstring(module->ldb, "Invalid expression parse tree"); - return LDB_ERR_OPERATIONS_ERROR; - } - - if (req->controls != NULL) { - ldb_debug(module->ldb, LDB_DEBUG_WARNING, "Controls are not yet supported by ldb_ldap backend!\n"); - } - - req->handle = init_handle(lldb, module, req->context, req->callback, req->timeout, req->starttime); - if (req->handle == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - lldb_ac = talloc_get_type(req->handle->private_data, struct lldb_context); - - search_base = ldb_dn_linearize(lldb_ac, req->op.search.base); - if (req->op.search.base == NULL) { - search_base = talloc_strdup(lldb_ac, ""); - } - if (search_base == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - expression = ldb_filter_from_tree( - lldb_ac, - discard_const_p(struct ldb_parse_tree, req->op.search.tree)); - if (expression == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - switch (req->op.search.scope) { - case LDB_SCOPE_BASE: - ldap_scope = LDAP_SCOPE_BASE; - break; - case LDB_SCOPE_ONELEVEL: - ldap_scope = LDAP_SCOPE_ONELEVEL; - break; - default: - ldap_scope = LDAP_SCOPE_SUBTREE; - break; - } - - tv.tv_sec = req->timeout; - tv.tv_usec = 0; - - ret = ldap_search_ext(lldb->ldap, search_base, ldap_scope, - expression, - discard_const_p(char *, req->op.search.attrs), - 0, - NULL, - NULL, - &tv, - LDAP_NO_LIMIT, - &lldb_ac->msgid); - - if (ret != LDAP_SUCCESS) { - ldb_set_errstring(module->ldb, ldap_err2string(ret)); - } - - return lldb_ldap_to_ldb(ret); -} - -/* - add a record -*/ -static int lldb_add(struct ldb_module *module, struct ldb_request *req) -{ - struct lldb_private *lldb = talloc_get_type(module->private_data, struct lldb_private); - struct lldb_context *lldb_ac; - LDAPMod **mods; - char *dn; - int ret; - - /* ltdb specials should not reach this point */ - if (ldb_dn_is_special(req->op.add.message->dn)) { - return LDB_ERR_INVALID_DN_SYNTAX; - } - - req->handle = init_handle(lldb, module, req->context, req->callback, req->timeout, req->starttime); - if (req->handle == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - lldb_ac = talloc_get_type(req->handle->private_data, struct lldb_context); - - mods = lldb_msg_to_mods(lldb_ac, req->op.add.message, 0); - if (mods == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - dn = ldb_dn_linearize(lldb_ac, req->op.add.message->dn); - if (dn == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldap_add_ext(lldb->ldap, dn, mods, - NULL, - NULL, - &lldb_ac->msgid); - - if (ret != LDAP_SUCCESS) { - ldb_set_errstring(module->ldb, ldap_err2string(ret)); - } - - return lldb_ldap_to_ldb(ret); -} - -/* - modify a record -*/ -static int lldb_modify(struct ldb_module *module, struct ldb_request *req) -{ - struct lldb_private *lldb = talloc_get_type(module->private_data, struct lldb_private); - struct lldb_context *lldb_ac; - LDAPMod **mods; - char *dn; - int ret; - - /* ltdb specials should not reach this point */ - if (ldb_dn_is_special(req->op.mod.message->dn)) { - return LDB_ERR_INVALID_DN_SYNTAX; - } - - req->handle = init_handle(lldb, module, req->context, req->callback, req->timeout, req->starttime); - if (req->handle == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - lldb_ac = talloc_get_type(req->handle->private_data, struct lldb_context); - - mods = lldb_msg_to_mods(lldb_ac, req->op.mod.message, 1); - if (mods == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - dn = ldb_dn_linearize(lldb_ac, req->op.mod.message->dn); - if (dn == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldap_modify_ext(lldb->ldap, dn, mods, - NULL, - NULL, - &lldb_ac->msgid); - - if (ret != LDAP_SUCCESS) { - ldb_set_errstring(module->ldb, ldap_err2string(ret)); - } - - return lldb_ldap_to_ldb(ret); -} - -/* - delete a record -*/ -static int lldb_delete(struct ldb_module *module, struct ldb_request *req) -{ - struct lldb_private *lldb = talloc_get_type(module->private_data, struct lldb_private); - struct lldb_context *lldb_ac; - char *dnstr; - int ret; - - /* ltdb specials should not reach this point */ - if (ldb_dn_is_special(req->op.del.dn)) { - return LDB_ERR_INVALID_DN_SYNTAX; - } - - req->handle = init_handle(lldb, module, req->context, req->callback, req->timeout, req->starttime); - if (req->handle == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - lldb_ac = talloc_get_type(req->handle->private_data, struct lldb_context); - - dnstr = ldb_dn_linearize(lldb_ac, req->op.del.dn); - - ret = ldap_delete_ext(lldb->ldap, dnstr, - NULL, - NULL, - &lldb_ac->msgid); - - if (ret != LDAP_SUCCESS) { - ldb_set_errstring(module->ldb, ldap_err2string(ret)); - } - - return lldb_ldap_to_ldb(ret); -} - -/* - rename a record -*/ -static int lldb_rename(struct ldb_module *module, struct ldb_request *req) -{ - struct lldb_private *lldb = talloc_get_type(module->private_data, struct lldb_private); - struct lldb_context *lldb_ac; - char *old_dn; - char *newrdn; - char *parentdn; - int ret; - - /* ltdb specials should not reach this point */ - if (ldb_dn_is_special(req->op.rename.olddn) || ldb_dn_is_special(req->op.rename.newdn)) { - return LDB_ERR_INVALID_DN_SYNTAX; - } - - req->handle = init_handle(lldb, module, req->context, req->callback, req->timeout, req->starttime); - if (req->handle == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - lldb_ac = talloc_get_type(req->handle->private_data, struct lldb_context); - - old_dn = ldb_dn_linearize(lldb_ac, req->op.rename.olddn); - if (old_dn == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - newrdn = talloc_asprintf(lldb_ac, "%s=%s", - ldb_dn_get_rdn_name(req->op.rename.newdn), - ldb_dn_escape_value(lldb, *(ldb_dn_get_rdn_val(req->op.rename.newdn)))); - if (!newrdn) { - return LDB_ERR_OPERATIONS_ERROR; - } - - parentdn = ldb_dn_linearize(lldb_ac, ldb_dn_get_parent(lldb_ac, req->op.rename.newdn)); - if (!parentdn) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldap_rename(lldb->ldap, old_dn, newrdn, parentdn, - 1, NULL, NULL, - &lldb_ac->msgid); - - if (ret != LDAP_SUCCESS) { - ldb_set_errstring(module->ldb, ldap_err2string(ret)); - } - - return lldb_ldap_to_ldb(ret); -} - -static int lldb_parse_result(struct ldb_handle *handle, LDAPMessage *result) -{ - struct lldb_context *ac = talloc_get_type(handle->private_data, struct lldb_context); - struct lldb_private *lldb = talloc_get_type(ac->module->private_data, struct lldb_private); - struct ldb_reply *ares = NULL; - LDAPMessage *msg; - int type; - char *matcheddnp = NULL; - char *errmsgp = NULL; - char **referralsp = NULL; - LDAPControl **serverctrlsp = NULL; - int ret = LDB_SUCCESS; - - type = ldap_msgtype(result); - - handle->status = 0; - - switch (type) { - - case LDAP_RES_SEARCH_ENTRY: - msg = ldap_first_entry(lldb->ldap, result); - if (msg != NULL) { - BerElement *berptr = NULL; - char *attr, *dn; - - ares = talloc_zero(ac, struct ldb_reply); - if (!ares) { - ret = LDB_ERR_OPERATIONS_ERROR; - goto error; - } - - ares->message = ldb_msg_new(ares); - if (!ares->message) { - ret = LDB_ERR_OPERATIONS_ERROR; - goto error; - } - - dn = ldap_get_dn(lldb->ldap, msg); - if (!dn) { - ret = LDB_ERR_OPERATIONS_ERROR; - goto error; - } - ares->message->dn = ldb_dn_explode_or_special(ares->message, dn); - if (ares->message->dn == NULL) { - ret = LDB_ERR_OPERATIONS_ERROR; - goto error; - } - ldap_memfree(dn); - - ares->message->num_elements = 0; - ares->message->elements = NULL; - ares->message->private_data = NULL; - - /* loop over all attributes */ - for (attr=ldap_first_attribute(lldb->ldap, msg, &berptr); - attr; - attr=ldap_next_attribute(lldb->ldap, msg, berptr)) { - struct berval **bval; - bval = ldap_get_values_len(lldb->ldap, msg, attr); - - if (bval) { - lldb_add_msg_attr(ac->module->ldb, ares->message, attr, bval); - ldap_value_free_len(bval); - } - } - if (berptr) ber_free(berptr, 0); - - - ares->type = LDB_REPLY_ENTRY; - ret = ac->callback(ac->module->ldb, ac->context, ares); - } else { - handle->status = LDB_ERR_PROTOCOL_ERROR; - handle->state = LDB_ASYNC_DONE; - } - break; - - case LDAP_RES_SEARCH_REFERENCE: - if (ldap_parse_result(lldb->ldap, result, &handle->status, - &matcheddnp, &errmsgp, - &referralsp, &serverctrlsp, 0) != LDAP_SUCCESS) { - ret = LDB_ERR_OPERATIONS_ERROR; - goto error; - } - if (referralsp == NULL) { - handle->status = LDB_ERR_PROTOCOL_ERROR; - goto error; - } - - ares = talloc_zero(ac, struct ldb_reply); - if (!ares) { - ret = LDB_ERR_OPERATIONS_ERROR; - goto error; - } - - ares->referral = talloc_strdup(ares, *referralsp); - ares->type = LDB_REPLY_REFERRAL; - ret = ac->callback(ac->module->ldb, ac->context, ares); - - break; - - case LDAP_RES_SEARCH_RESULT: - if (ldap_parse_result(lldb->ldap, result, &handle->status, - &matcheddnp, &errmsgp, - &referralsp, &serverctrlsp, 0) != LDAP_SUCCESS) { - handle->status = LDB_ERR_OPERATIONS_ERROR; - goto error; - } - - ares = talloc_zero(ac, struct ldb_reply); - if (!ares) { - ret = LDB_ERR_OPERATIONS_ERROR; - goto error; - } - - if (serverctrlsp != NULL) { - /* FIXME: transform the LDAPControl list into an ldb_control one */ - ares->controls = NULL; - } - - ares->type = LDB_REPLY_DONE; - handle->state = LDB_ASYNC_DONE; - ret = ac->callback(ac->module->ldb, ac->context, ares); - - break; - - case LDAP_RES_MODIFY: - case LDAP_RES_ADD: - case LDAP_RES_DELETE: - case LDAP_RES_MODDN: - if (ldap_parse_result(lldb->ldap, result, &handle->status, - &matcheddnp, &errmsgp, - &referralsp, &serverctrlsp, 0) != LDAP_SUCCESS) { - handle->status = LDB_ERR_OPERATIONS_ERROR; - goto error; - } - if (ac->callback && handle->status == LDB_SUCCESS) { - ares = NULL; /* FIXME: build a corresponding ares to pass on */ - ret = ac->callback(ac->module->ldb, ac->context, ares); - } - handle->state = LDB_ASYNC_DONE; - break; - - default: - ret = LDB_ERR_PROTOCOL_ERROR; - goto error; - } - - if (matcheddnp) ldap_memfree(matcheddnp); - if (errmsgp && *errmsgp) { - ldb_set_errstring(ac->module->ldb, errmsgp); - } else if (handle->status) { - ldb_set_errstring(ac->module->ldb, ldap_err2string(handle->status)); - } - if (errmsgp) { - ldap_memfree(errmsgp); - } - if (referralsp) ldap_value_free(referralsp); - if (serverctrlsp) ldap_controls_free(serverctrlsp); - - ldap_msgfree(result); - return lldb_ldap_to_ldb(handle->status); - -error: - handle->state = LDB_ASYNC_DONE; - ldap_msgfree(result); - return ret; -} - -static int lldb_wait(struct ldb_handle *handle, enum ldb_wait_type type) -{ - struct lldb_context *ac = talloc_get_type(handle->private_data, struct lldb_context); - struct lldb_private *lldb = talloc_get_type(handle->module->private_data, struct lldb_private); - struct timeval timeout; - LDAPMessage *result; - int ret, lret; - - if (handle->state == LDB_ASYNC_DONE) { - return handle->status; - } - - if (!ac || !ac->msgid) { - return LDB_ERR_OPERATIONS_ERROR; - } - - handle->state = LDB_ASYNC_PENDING; - handle->status = LDB_SUCCESS; - - switch(type) { - case LDB_WAIT_NONE: - - if ((ac->timeout != -1) && - ((ac->starttime + ac->timeout) > time(NULL))) { - return LDB_ERR_TIME_LIMIT_EXCEEDED; - } - - timeout.tv_sec = 0; - timeout.tv_usec = 0; - - lret = ldap_result(lldb->ldap, ac->msgid, 0, &timeout, &result); - if (lret == -1) { - return LDB_ERR_OPERATIONS_ERROR; - } - if (lret == 0) { - ret = LDB_SUCCESS; - goto done; - } - - return lldb_parse_result(handle, result); - - case LDB_WAIT_ALL: - timeout.tv_usec = 0; - ret = LDB_ERR_OPERATIONS_ERROR; - - while (handle->status == LDB_SUCCESS && handle->state != LDB_ASYNC_DONE) { - - if (ac->timeout == -1) { - lret = ldap_result(lldb->ldap, ac->msgid, 0, NULL, &result); - } else { - timeout.tv_sec = ac->timeout - (time(NULL) - ac->starttime); - if (timeout.tv_sec <= 0) - return LDB_ERR_TIME_LIMIT_EXCEEDED; - lret = ldap_result(lldb->ldap, ac->msgid, 0, &timeout, &result); - } - if (lret == -1) { - return LDB_ERR_OPERATIONS_ERROR; - } - if (lret == 0) { - return LDB_ERR_TIME_LIMIT_EXCEEDED; - } - - ret = lldb_parse_result(handle, result); - if (ret != LDB_SUCCESS) { - return ret; - } - } - - break; - - default: - handle->state = LDB_ASYNC_DONE; - ret = LDB_ERR_OPERATIONS_ERROR; - } - -done: - return ret; -} - -static int lldb_start_trans(struct ldb_module *module) -{ - /* TODO implement a local transaction mechanism here */ - - return LDB_SUCCESS; -} - -static int lldb_end_trans(struct ldb_module *module) -{ - /* TODO implement a local transaction mechanism here */ - - return LDB_SUCCESS; -} - -static int lldb_del_trans(struct ldb_module *module) -{ - /* TODO implement a local transaction mechanism here */ - - return LDB_SUCCESS; -} - -static int lldb_request(struct ldb_module *module, struct ldb_request *req) -{ - return LDB_ERR_OPERATIONS_ERROR; -} - -static const struct ldb_module_ops lldb_ops = { - .name = "ldap", - .search = lldb_search, - .add = lldb_add, - .modify = lldb_modify, - .del = lldb_delete, - .rename = lldb_rename, - .request = lldb_request, - .start_transaction = lldb_start_trans, - .end_transaction = lldb_end_trans, - .del_transaction = lldb_del_trans, - .wait = lldb_wait -}; - - -static int lldb_destructor(struct lldb_private *lldb) -{ - ldap_unbind(lldb->ldap); - return 0; -} - -/* - connect to the database -*/ -static int lldb_connect(struct ldb_context *ldb, - const char *url, - unsigned int flags, - const char *options[], - struct ldb_module **module) -{ - struct lldb_private *lldb = NULL; - int version = 3; - int ret; - - lldb = talloc(ldb, struct lldb_private); - if (!lldb) { - ldb_oom(ldb); - goto failed; - } - - lldb->ldap = NULL; - - ret = ldap_initialize(&lldb->ldap, url); - if (ret != LDAP_SUCCESS) { - ldb_debug(ldb, LDB_DEBUG_FATAL, "ldap_initialize failed for URL '%s' - %s\n", - url, ldap_err2string(ret)); - goto failed; - } - - talloc_set_destructor(lldb, lldb_destructor); - - ret = ldap_set_option(lldb->ldap, LDAP_OPT_PROTOCOL_VERSION, &version); - if (ret != LDAP_SUCCESS) { - ldb_debug(ldb, LDB_DEBUG_FATAL, "ldap_set_option failed - %s\n", - ldap_err2string(ret)); - goto failed; - } - - *module = talloc(ldb, struct ldb_module); - if (*module == NULL) { - ldb_oom(ldb); - talloc_free(lldb); - return -1; - } - talloc_set_name_const(*module, "ldb_ldap backend"); - (*module)->ldb = ldb; - (*module)->prev = (*module)->next = NULL; - (*module)->private_data = lldb; - (*module)->ops = &lldb_ops; - - return 0; - -failed: - talloc_free(lldb); - return -1; -} - -int ldb_ldap_init(void) -{ - return ldb_register_backend("ldap", lldb_connect) + - ldb_register_backend("ldapi", lldb_connect) + - ldb_register_backend("ldaps", lldb_connect); -} diff --git a/source/lib/ldb/ldb_sqlite3/README b/source/lib/ldb/ldb_sqlite3/README deleted file mode 100644 index 6cda0a77595..00000000000 --- a/source/lib/ldb/ldb_sqlite3/README +++ /dev/null @@ -1,7 +0,0 @@ -trees.ps contains an explanation of the Genealogical Representation of Trees -in Databases which is being used in ldb_sqlite3. Note that we use fgID -representation with 4 bytes per level, so we can represent 6.5E+08 subclasses -of any object class. This should be adequate for our purposes. :-) - -The following document is the primary basis for the schema currently being -used here: http://www.research.ibm.com/journal/sj/392/shi.html diff --git a/source/lib/ldb/ldb_sqlite3/base160.c b/source/lib/ldb/ldb_sqlite3/base160.c deleted file mode 100644 index 4286979123b..00000000000 --- a/source/lib/ldb/ldb_sqlite3/base160.c +++ /dev/null @@ -1,155 +0,0 @@ -/* - base160 code used by ldb_sqlite3 - - Copyright (C) 2004 Derrell Lipman - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - - -/* - * ldb_sqlite3_base160() - * - * Convert an integer value to a string containing the base 160 representation - * of the integer. We always convert to a string representation that is 4 - * bytes in length, and we always null terminate. - * - * Parameters: - * val -- - * The value to be converted - * - * result -- - * Buffer in which the result is to be placed - * - * Returns: - * nothing - */ -static unsigned char base160tab[161] = -{ - 48 , 49 , 50 , 51 , 52 , 53 , 54 , 55 , 56 , 57 , /* 0-9 */ - 58 , 59 , 65 , 66 , 67 , 68 , 69 , 70 , 71 , 72 , /* : ; A-H */ - 73 , 74 , 75 , 76 , 77 , 78 , 79 , 80 , 81 , 82 , /* I-R */ - 83 , 84 , 85 , 86 , 87 , 88 , 89 , 90 , 97 , 98 , /* S-Z , a-b */ - 99 , 100, 101, 102, 103, 104, 105, 106, 107, 108, /* c-l */ - 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, /* m-v */ - 119, 120, 121, 122, 160, 161, 162, 163, 164, 165, /* w-z, latin1 */ - 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, /* latin1 */ - 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, /* latin1 */ - 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, /* latin1 */ - 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, /* latin1 */ - 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, /* latin1 */ - 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, /* latin1 */ - 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, /* latin1 */ - 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, /* latin1 */ - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, /* latin1 */ - '\0' -}; - - -/* - * lsqlite3_base160() - * - * Convert an unsigned long integer into a base160 representation of the - * number. - * - * Parameters: - * val -- - * value to be converted - * - * result -- - * character array, 5 bytes long, into which the base160 representation - * will be placed. The result will be a four-digit representation of the - * number (with leading zeros prepended as necessary), and null - * terminated. - * - * Returns: - * Nothing - */ -void -lsqlite3_base160(unsigned long val, - unsigned char result[5]) -{ - int i; - - for (i = 3; i >= 0; i--) { - - result[i] = base160tab[val % 160]; - val /= 160; - } - - result[4] = '\0'; -} - - -/* - * lsqlite3_base160Next() - * - * Retrieve the next-greater number in the base160 sequence for the terminal - * tree node (the last four digits). Only one tree level (four digits) are - * operated on. - * - * Parameters: - * base160 -- a character array containing either an empty string (in which - * case no operation is performed), or a string of base160 digits - * with a length of a multiple of four digits. - * - * Upon return, the trailing four digits (one tree level) will - * have been incremented by 1. - * - * Returns: - * base160 -- the modified array - */ -char * -lsqlite3_base160Next(char base160[]) -{ - int i; - int len; - unsigned char * pTab; - char * pBase160 = base160; - - /* - * We need a minimum of four digits, and we will always get a multiple of - * four digits. - */ - if (len = strlen(pBase160)) >= 4) - { - pBase160 += strlen(pBase160) - 1; - - /* We only carry through four digits: one level in the tree */ - for (i = 0; i < 4; i++) { - - /* What base160 value does this digit have? */ - pTab = strchr(base160tab, *pBase160); - - /* Is there a carry? */ - if (pTab < base160tab + sizeof(base160tab) - 1) { - - /* Nope. Just increment this value and we're done. */ - *pBase160 = *++pTab; - break; - } else { - - /* - * There's a carry. This value gets base160tab[0], we - * decrement the buffer pointer to get the next higher-order - * digit, and continue in the loop. - */ - *pBase160-- = base160tab[0]; - } - } - } - - return base160; -} diff --git a/source/lib/ldb/ldb_sqlite3/ldb_sqlite3.c b/source/lib/ldb/ldb_sqlite3/ldb_sqlite3.c deleted file mode 100644 index 4f9b0f6370f..00000000000 --- a/source/lib/ldb/ldb_sqlite3/ldb_sqlite3.c +++ /dev/null @@ -1,1912 +0,0 @@ -/* - ldb database library - - Copyright (C) Derrell Lipman 2005 - Copyright (C) Simo Sorce 2005-2006 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - * Name: ldb - * - * Component: ldb sqlite3 backend - * - * Description: core files for SQLITE3 backend - * - * Author: Derrell Lipman (based on Andrew Tridgell's LDAP backend) - */ - -#include "includes.h" -#include "ldb/include/includes.h" - -#include <sqlite3.h> - -struct lsqlite3_private { - int trans_count; - char **options; - sqlite3 *sqlite; -}; - -struct lsql_context { - struct ldb_module *module; - - /* search stuff */ - long long current_eid; - const char * const * attrs; - struct ldb_reply *ares; - - /* async stuff */ - void *context; - int (*callback)(struct ldb_context *, void *, struct ldb_reply *); -}; - -static struct ldb_handle *init_handle(struct lsqlite3_private *lsqlite3, - struct ldb_module *module, - struct ldb_request *req) -{ - struct lsql_context *ac; - struct ldb_handle *h; - - h = talloc_zero(lsqlite3, struct ldb_handle); - if (h == NULL) { - ldb_set_errstring(module->ldb, "Out of Memory"); - return NULL; - } - - h->module = module; - - ac = talloc(h, struct lsql_context); - if (ac == NULL) { - ldb_set_errstring(module->ldb, "Out of Memory"); - talloc_free(h); - return NULL; - } - - h->private_data = (void *)ac; - - h->state = LDB_ASYNC_INIT; - h->status = LDB_SUCCESS; - - ac->module = module; - ac->context = req->context; - ac->callback = req->callback; - - return h; -} - -/* - * Macros used throughout - */ - -#ifndef FALSE -# define FALSE (0) -# define TRUE (! FALSE) -#endif - -#define RESULT_ATTR_TABLE "temp_result_attrs" - -//#define TEMPTAB /* for testing, create non-temporary table */ -#define TEMPTAB "TEMPORARY" - -/* - * Static variables - */ -sqlite3_stmt * stmtGetEID = NULL; - -static char *lsqlite3_tprintf(TALLOC_CTX *mem_ctx, const char *fmt, ...) -{ - char *str, *ret; - va_list ap; - - va_start(ap, fmt); - str = sqlite3_vmprintf(fmt, ap); - va_end(ap); - - if (str == NULL) return NULL; - - ret = talloc_strdup(mem_ctx, str); - if (ret == NULL) { - sqlite3_free(str); - return NULL; - } - - sqlite3_free(str); - return ret; -} - -static char base160tab[161] = { - 48 ,49 ,50 ,51 ,52 ,53 ,54 ,55 ,56 ,57 , /* 0-9 */ - 58 ,59 ,65 ,66 ,67 ,68 ,69 ,70 ,71 ,72 , /* : ; A-H */ - 73 ,74 ,75 ,76 ,77 ,78 ,79 ,80 ,81 ,82 , /* I-R */ - 83 ,84 ,85 ,86 ,87 ,88 ,89 ,90 ,97 ,98 , /* S-Z , a-b */ - 99 ,100,101,102,103,104,105,106,107,108, /* c-l */ - 109,110,111,112,113,114,115,116,117,118, /* m-v */ - 119,120,121,122,160,161,162,163,164,165, /* w-z, latin1 */ - 166,167,168,169,170,171,172,173,174,175, /* latin1 */ - 176,177,178,179,180,181,182,183,184,185, /* latin1 */ - 186,187,188,189,190,191,192,193,194,195, /* latin1 */ - 196,197,198,199,200,201,202,203,204,205, /* latin1 */ - 206,207,208,209,210,211,212,213,214,215, /* latin1 */ - 216,217,218,219,220,221,222,223,224,225, /* latin1 */ - 226,227,228,229,230,231,232,233,234,235, /* latin1 */ - 236,237,238,239,240,241,242,243,244,245, /* latin1 */ - 246,247,248,249,250,251,252,253,254,255, /* latin1 */ - '\0' -}; - - -/* - * base160() - * - * Convert an unsigned long integer into a base160 representation of the - * number. - * - * Parameters: - * val -- - * value to be converted - * - * result -- - * character array, 5 bytes long, into which the base160 representation - * will be placed. The result will be a four-digit representation of the - * number (with leading zeros prepended as necessary), and null - * terminated. - * - * Returns: - * Nothing - */ -static void -base160_sql(sqlite3_context * hContext, - int argc, - sqlite3_value ** argv) -{ - int i; - long long val; - char result[5]; - - val = sqlite3_value_int64(argv[0]); - - for (i = 3; i >= 0; i--) { - - result[i] = base160tab[val % 160]; - val /= 160; - } - - result[4] = '\0'; - - sqlite3_result_text(hContext, result, -1, SQLITE_TRANSIENT); -} - - -/* - * base160next_sql() - * - * This function enhances sqlite by adding a "base160_next()" function which is - * accessible via queries. - * - * Retrieve the next-greater number in the base160 sequence for the terminal - * tree node (the last four digits). Only one tree level (four digits) is - * operated on. - * - * Input: - * A character string: either an empty string (in which case no operation is - * performed), or a string of base160 digits with a length of a multiple of - * four digits. - * - * Output: - * Upon return, the trailing four digits (one tree level) will have been - * incremented by 1. - */ -static void -base160next_sql(sqlite3_context * hContext, - int argc, - sqlite3_value ** argv) -{ - int i; - int len; - char * pTab; - char * pBase160 = strdup((const char *)sqlite3_value_text(argv[0])); - char * pStart = pBase160; - - /* - * We need a minimum of four digits, and we will always get a multiple - * of four digits. - */ - if (pBase160 != NULL && - (len = strlen(pBase160)) >= 4 && - len % 4 == 0) { - - if (pBase160 == NULL) { - - sqlite3_result_null(hContext); - return; - } - - pBase160 += strlen(pBase160) - 1; - - /* We only carry through four digits: one level in the tree */ - for (i = 0; i < 4; i++) { - - /* What base160 value does this digit have? */ - pTab = strchr(base160tab, *pBase160); - - /* Is there a carry? */ - if (pTab < base160tab + sizeof(base160tab) - 1) { - - /* - * Nope. Just increment this value and we're - * done. - */ - *pBase160 = *++pTab; - break; - } else { - - /* - * There's a carry. This value gets - * base160tab[0], we decrement the buffer - * pointer to get the next higher-order digit, - * and continue in the loop. - */ - *pBase160-- = base160tab[0]; - } - } - - sqlite3_result_text(hContext, - pStart, - strlen(pStart), - free); - } else { - sqlite3_result_value(hContext, argv[0]); - if (pBase160 != NULL) { - free(pBase160); - } - } -} - -static char *parsetree_to_sql(struct ldb_module *module, - void *mem_ctx, - const struct ldb_parse_tree *t) -{ - const struct ldb_attrib_handler *h; - struct ldb_val value, subval; - char *wild_card_string; - char *child, *tmp; - char *ret = NULL; - char *attr; - int i; - - - switch(t->operation) { - case LDB_OP_AND: - - tmp = parsetree_to_sql(module, mem_ctx, t->u.list.elements[0]); - if (tmp == NULL) return NULL; - - for (i = 1; i < t->u.list.num_elements; i++) { - - child = parsetree_to_sql(module, mem_ctx, t->u.list.elements[i]); - if (child == NULL) return NULL; - - tmp = talloc_asprintf_append(tmp, " INTERSECT %s ", child); - if (tmp == NULL) return NULL; - } - - ret = talloc_asprintf(mem_ctx, "SELECT * FROM ( %s )\n", tmp); - - return ret; - - case LDB_OP_OR: - - tmp = parsetree_to_sql(module, mem_ctx, t->u.list.elements[0]); - if (tmp == NULL) return NULL; - - for (i = 1; i < t->u.list.num_elements; i++) { - - child = parsetree_to_sql(module, mem_ctx, t->u.list.elements[i]); - if (child == NULL) return NULL; - - tmp = talloc_asprintf_append(tmp, " UNION %s ", child); - if (tmp == NULL) return NULL; - } - - return talloc_asprintf(mem_ctx, "SELECT * FROM ( %s ) ", tmp); - - case LDB_OP_NOT: - - child = parsetree_to_sql(module, mem_ctx, t->u.isnot.child); - if (child == NULL) return NULL; - - return talloc_asprintf(mem_ctx, - "SELECT eid FROM ldb_entry " - "WHERE eid NOT IN ( %s ) ", child); - - case LDB_OP_EQUALITY: - /* - * For simple searches, we want to retrieve the list of EIDs that - * match the criteria. - */ - attr = ldb_attr_casefold(mem_ctx, t->u.equality.attr); - if (attr == NULL) return NULL; - h = ldb_attrib_handler(module->ldb, attr); - - /* Get a canonicalised copy of the data */ - h->canonicalise_fn(module->ldb, mem_ctx, &(t->u.equality.value), &value); - if (value.data == NULL) { - return NULL; - } - - if (strcasecmp(t->u.equality.attr, "objectclass") == 0) { - /* - * For object classes, we want to search for all objectclasses - * that are subclasses as well. - */ - return lsqlite3_tprintf(mem_ctx, - "SELECT eid FROM ldb_attribute_values\n" - "WHERE norm_attr_name = 'OBJECTCLASS' " - "AND norm_attr_value IN\n" - " (SELECT class_name FROM ldb_object_classes\n" - " WHERE tree_key GLOB\n" - " (SELECT tree_key FROM ldb_object_classes\n" - " WHERE class_name = '%q'\n" - " ) || '*'\n" - " )\n", value.data); - - } else if (strcasecmp(t->u.equality.attr, "dn") == 0) { - /* DN query is a special ldb case */ - char *cdn = ldb_dn_linearize_casefold(module->ldb, - mem_ctx, - ldb_dn_explode(module->ldb, - (const char *)value.data)); - - return lsqlite3_tprintf(mem_ctx, - "SELECT eid FROM ldb_entry " - "WHERE norm_dn = '%q'", cdn); - - } else { - /* A normal query. */ - return lsqlite3_tprintf(mem_ctx, - "SELECT eid FROM ldb_attribute_values " - "WHERE norm_attr_name = '%q' " - "AND norm_attr_value = '%q'", - attr, - value.data); - - } - - case LDB_OP_SUBSTRING: - - wild_card_string = talloc_strdup(mem_ctx, - (t->u.substring.start_with_wildcard)?"*":""); - if (wild_card_string == NULL) return NULL; - - for (i = 0; t->u.substring.chunks[i]; i++) { - wild_card_string = talloc_asprintf_append(wild_card_string, "%s*", - t->u.substring.chunks[i]->data); - if (wild_card_string == NULL) return NULL; - } - - if ( ! t->u.substring.end_with_wildcard ) { - /* remove last wildcard */ - wild_card_string[strlen(wild_card_string) - 1] = '\0'; - } - - attr = ldb_attr_casefold(mem_ctx, t->u.substring.attr); - if (attr == NULL) return NULL; - h = ldb_attrib_handler(module->ldb, attr); - - subval.data = (void *)wild_card_string; - subval.length = strlen(wild_card_string) + 1; - - /* Get a canonicalised copy of the data */ - h->canonicalise_fn(module->ldb, mem_ctx, &(subval), &value); - if (value.data == NULL) { - return NULL; - } - - return lsqlite3_tprintf(mem_ctx, - "SELECT eid FROM ldb_attribute_values " - "WHERE norm_attr_name = '%q' " - "AND norm_attr_value GLOB '%q'", - attr, - value.data); - - case LDB_OP_GREATER: - attr = ldb_attr_casefold(mem_ctx, t->u.equality.attr); - if (attr == NULL) return NULL; - h = ldb_attrib_handler(module->ldb, attr); - - /* Get a canonicalised copy of the data */ - h->canonicalise_fn(module->ldb, mem_ctx, &(t->u.equality.value), &value); - if (value.data == NULL) { - return NULL; - } - - return lsqlite3_tprintf(mem_ctx, - "SELECT eid FROM ldb_attribute_values " - "WHERE norm_attr_name = '%q' " - "AND ldap_compare(norm_attr_value, '>=', '%q', '%q') ", - attr, - value.data, - attr); - - case LDB_OP_LESS: - attr = ldb_attr_casefold(mem_ctx, t->u.equality.attr); - if (attr == NULL) return NULL; - h = ldb_attrib_handler(module->ldb, attr); - - /* Get a canonicalised copy of the data */ - h->canonicalise_fn(module->ldb, mem_ctx, &(t->u.equality.value), &value); - if (value.data == NULL) { - return NULL; - } - - return lsqlite3_tprintf(mem_ctx, - "SELECT eid FROM ldb_attribute_values " - "WHERE norm_attr_name = '%q' " - "AND ldap_compare(norm_attr_value, '<=', '%q', '%q') ", - attr, - value.data, - attr); - - case LDB_OP_PRESENT: - if (strcasecmp(t->u.present.attr, "dn") == 0) { - return talloc_strdup(mem_ctx, "SELECT eid FROM ldb_entry"); - } - - attr = ldb_attr_casefold(mem_ctx, t->u.present.attr); - if (attr == NULL) return NULL; - - return lsqlite3_tprintf(mem_ctx, - "SELECT eid FROM ldb_attribute_values " - "WHERE norm_attr_name = '%q' ", - attr); - - case LDB_OP_APPROX: - attr = ldb_attr_casefold(mem_ctx, t->u.equality.attr); - if (attr == NULL) return NULL; - h = ldb_attrib_handler(module->ldb, attr); - - /* Get a canonicalised copy of the data */ - h->canonicalise_fn(module->ldb, mem_ctx, &(t->u.equality.value), &value); - if (value.data == NULL) { - return NULL; - } - - return lsqlite3_tprintf(mem_ctx, - "SELECT eid FROM ldb_attribute_values " - "WHERE norm_attr_name = '%q' " - "AND ldap_compare(norm_attr_value, '~%', 'q', '%q') ", - attr, - value.data, - attr); - - case LDB_OP_EXTENDED: -#warning "work out how to handle bitops" - return NULL; - - default: - break; - }; - - /* should never occur */ - abort(); - return NULL; -} - -/* - * query_int() - * - * This function is used for the common case of queries that return a single - * integer value. - * - * NOTE: If more than one value is returned by the query, all but the first - * one will be ignored. - */ -static int -query_int(const struct lsqlite3_private * lsqlite3, - long long * pRet, - const char * pSql, - ...) -{ - int ret; - int bLoop; - char * p; - sqlite3_stmt * pStmt; - va_list args; - - /* Begin access to variable argument list */ - va_start(args, pSql); - - /* Format the query */ - if ((p = sqlite3_vmprintf(pSql, args)) == NULL) { - return SQLITE_NOMEM; - } - - /* - * Prepare and execute the SQL statement. Loop allows retrying on - * certain errors, e.g. SQLITE_SCHEMA occurs if the schema changes, - * requiring retrying the operation. - */ - for (bLoop = TRUE; bLoop; ) { - - /* Compile the SQL statement into sqlite virtual machine */ - if ((ret = sqlite3_prepare(lsqlite3->sqlite, - p, - -1, - &pStmt, - NULL)) == SQLITE_SCHEMA) { - if (stmtGetEID != NULL) { - sqlite3_finalize(stmtGetEID); - stmtGetEID = NULL; - } - continue; - } else if (ret != SQLITE_OK) { - break; - } - - /* One row expected */ - if ((ret = sqlite3_step(pStmt)) == SQLITE_SCHEMA) { - if (stmtGetEID != NULL) { - sqlite3_finalize(stmtGetEID); - stmtGetEID = NULL; - } - (void) sqlite3_finalize(pStmt); - continue; - } else if (ret != SQLITE_ROW) { - (void) sqlite3_finalize(pStmt); - break; - } - - /* Get the value to be returned */ - *pRet = sqlite3_column_int64(pStmt, 0); - - /* Free the virtual machine */ - if ((ret = sqlite3_finalize(pStmt)) == SQLITE_SCHEMA) { - if (stmtGetEID != NULL) { - sqlite3_finalize(stmtGetEID); - stmtGetEID = NULL; - } - continue; - } else if (ret != SQLITE_OK) { - (void) sqlite3_finalize(pStmt); - break; - } - - /* - * Normal condition is only one time through loop. Loop is - * rerun in error conditions, via "continue", above. - */ - bLoop = FALSE; - } - - /* All done with variable argument list */ - va_end(args); - - - /* Free the memory we allocated for our query string */ - sqlite3_free(p); - - return ret; -} - -/* - * This is a bad hack to support ldap style comparisons whithin sqlite. - * val is the attribute in the row currently under test - * func is the desired test "<=" ">=" "~" ":" - * cmp is the value to compare against (eg: "test") - * attr is the attribute name the value of which we want to test - */ - -static void lsqlite3_compare(sqlite3_context *ctx, int argc, - sqlite3_value **argv) -{ - struct ldb_context *ldb = (struct ldb_context *)sqlite3_user_data(ctx); - const char *val = (const char *)sqlite3_value_text(argv[0]); - const char *func = (const char *)sqlite3_value_text(argv[1]); - const char *cmp = (const char *)sqlite3_value_text(argv[2]); - const char *attr = (const char *)sqlite3_value_text(argv[3]); - const struct ldb_attrib_handler *h; - struct ldb_val valX; - struct ldb_val valY; - int ret; - - switch (func[0]) { - /* greater */ - case '>': /* >= */ - h = ldb_attrib_handler(ldb, attr); - valX.data = (void *)cmp; - valX.length = strlen(cmp); - valY.data = (void *)val; - valY.length = strlen(val); - ret = h->comparison_fn(ldb, ldb, &valY, &valX); - if (ret >= 0) - sqlite3_result_int(ctx, 1); - else - sqlite3_result_int(ctx, 0); - return; - - /* lesser */ - case '<': /* <= */ - h = ldb_attrib_handler(ldb, attr); - valX.data = (void *)cmp; - valX.length = strlen(cmp); - valY.data = (void *)val; - valY.length = strlen(val); - ret = h->comparison_fn(ldb, ldb, &valY, &valX); - if (ret <= 0) - sqlite3_result_int(ctx, 1); - else - sqlite3_result_int(ctx, 0); - return; - - /* approx */ - case '~': - /* TODO */ - sqlite3_result_int(ctx, 0); - return; - - /* bitops */ - case ':': - /* TODO */ - sqlite3_result_int(ctx, 0); - return; - - default: - break; - } - - sqlite3_result_error(ctx, "Value must start with a special operation char (<>~:)!", -1); - return; -} - - -/* rename a record */ -static int lsqlite3_safe_rollback(sqlite3 *sqlite) -{ - char *errmsg; - int ret; - - /* execute */ - ret = sqlite3_exec(sqlite, "ROLLBACK;", NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - printf("lsqlite3_safe_rollback: Error: %s\n", errmsg); - free(errmsg); - } - return -1; - } - - return 0; -} - -/* return an eid as result */ -static int lsqlite3_eid_callback(void *result, int col_num, char **cols, char **names) -{ - long long *eid = (long long *)result; - - if (col_num != 1) return SQLITE_ABORT; - if (strcasecmp(names[0], "eid") != 0) return SQLITE_ABORT; - - *eid = atoll(cols[0]); - return SQLITE_OK; -} - -/* - * add a single set of ldap message values to a ldb_message - */ -static int lsqlite3_search_callback(void *result, int col_num, char **cols, char **names) -{ - struct ldb_handle *handle = talloc_get_type(result, struct ldb_handle); - struct lsql_context *ac = talloc_get_type(handle->private_data, struct lsql_context); - struct ldb_message *msg; - long long eid; - int i; - - /* eid, dn, attr_name, attr_value */ - if (col_num != 4) - return SQLITE_ABORT; - - eid = atoll(cols[0]); - - if (eid != ac->current_eid) { /* here begin a new entry */ - - /* call the async callback for the last entry - * except the first time */ - if (ac->current_eid != 0) { - ac->ares->message = ldb_msg_canonicalize(ac->module->ldb, ac->ares->message); - if (ac->ares->message == NULL) - return SQLITE_ABORT; - - handle->status = ac->callback(ac->module->ldb, ac->context, ac->ares); - if (handle->status != LDB_SUCCESS) - return SQLITE_ABORT; - } - - /* start over */ - ac->ares = talloc_zero(ac, struct ldb_reply); - if (!ac->ares) - return SQLITE_ABORT; - - ac->ares->message = ldb_msg_new(ac->ares); - if (!ac->ares->message) - return SQLITE_ABORT; - - ac->ares->type = LDB_REPLY_ENTRY; - ac->current_eid = eid; - } - - msg = ac->ares->message; - - if (msg->dn == NULL) { - msg->dn = ldb_dn_explode(msg, cols[1]); - if (msg->dn == NULL) - return SQLITE_ABORT; - } - - if (ac->attrs) { - int found = 0; - for (i = 0; ac->attrs[i]; i++) { - if (strcasecmp(cols[2], ac->attrs[i]) == 0) { - found = 1; - break; - } - } - if (!found) return SQLITE_OK; - } - - if (ldb_msg_add_string(msg, cols[2], cols[3]) != 0) { - return SQLITE_ABORT; - } - - return SQLITE_OK; -} - - -/* - * lsqlite3_get_eid() - * lsqlite3_get_eid_ndn() - * - * These functions are used for the very common case of retrieving an EID value - * given a (normalized) DN. - */ - -static long long lsqlite3_get_eid_ndn(sqlite3 *sqlite, void *mem_ctx, const char *norm_dn) -{ - char *errmsg; - char *query; - long long eid = -1; - long long ret; - - /* get object eid */ - query = lsqlite3_tprintf(mem_ctx, "SELECT eid " - "FROM ldb_entry " - "WHERE norm_dn = '%q';", norm_dn); - if (query == NULL) return -1; - - ret = sqlite3_exec(sqlite, query, lsqlite3_eid_callback, &eid, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - printf("lsqlite3_get_eid: Fatal Error: %s\n", errmsg); - free(errmsg); - } - return -1; - } - - return eid; -} - -static long long lsqlite3_get_eid(struct ldb_module *module, const struct ldb_dn *dn) -{ - TALLOC_CTX *local_ctx; - struct lsqlite3_private *lsqlite3 = module->private_data; - long long eid = -1; - char *cdn; - - /* ignore ltdb specials */ - if (ldb_dn_is_special(dn)) { - return -1; - } - - /* create a local ctx */ - local_ctx = talloc_named(lsqlite3, 0, "lsqlite3_get_eid local context"); - if (local_ctx == NULL) { - return -1; - } - - cdn = ldb_dn_linearize(local_ctx, ldb_dn_casefold(module->ldb, local_ctx, dn)); - if (!cdn) goto done; - - eid = lsqlite3_get_eid_ndn(lsqlite3->sqlite, local_ctx, cdn); - -done: - talloc_free(local_ctx); - return eid; -} - -/* - * Interface functions referenced by lsqlite3_ops - */ - -/* search for matching records, by tree */ -int lsql_search(struct ldb_module *module, struct ldb_request *req) -{ - struct lsqlite3_private *lsqlite3 = talloc_get_type(module->private_data, struct lsqlite3_private); - struct lsql_context *lsql_ac; - char *norm_basedn; - char *sqlfilter; - char *errmsg; - char *query = NULL; - int ret; - - req->handle = init_handle(lsqlite3, module, req); - if (req->handle == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - lsql_ac = talloc_get_type(req->handle->private_data, struct lsql_context); - - if ((req->op.search.base == NULL || req->op.search.base->comp_num == 0) && - (req->op.search.scope == LDB_SCOPE_BASE || req->op.search.scope == LDB_SCOPE_ONELEVEL)) - return LDB_ERR_OPERATIONS_ERROR; - - if (req->op.search.base) { - norm_basedn = ldb_dn_linearize(lsql_ac, ldb_dn_casefold(module->ldb, lsql_ac, req->op.search.base)); - if (norm_basedn == NULL) { - ret = LDB_ERR_INVALID_DN_SYNTAX; - goto failed; - } - } else norm_basedn = talloc_strdup(lsql_ac, ""); - - /* Convert filter into a series of SQL conditions (constraints) */ - sqlfilter = parsetree_to_sql(module, lsql_ac, req->op.search.tree); - - switch(req->op.search.scope) { - case LDB_SCOPE_DEFAULT: - case LDB_SCOPE_SUBTREE: - if (*norm_basedn != '\0') { - query = lsqlite3_tprintf(lsql_ac, - "SELECT entry.eid,\n" - " entry.dn,\n" - " av.attr_name,\n" - " av.attr_value\n" - " FROM ldb_entry AS entry\n" - - " LEFT OUTER JOIN ldb_attribute_values AS av\n" - " ON av.eid = entry.eid\n" - - " WHERE entry.eid IN\n" - " (SELECT DISTINCT ldb_entry.eid\n" - " FROM ldb_entry\n" - " WHERE (ldb_entry.norm_dn GLOB('*,%q')\n" - " OR ldb_entry.norm_dn = '%q')\n" - " AND ldb_entry.eid IN\n" - " (%s)\n" - " )\n" - - " ORDER BY entry.eid ASC;", - norm_basedn, - norm_basedn, - sqlfilter); - } else { - query = lsqlite3_tprintf(lsql_ac, - "SELECT entry.eid,\n" - " entry.dn,\n" - " av.attr_name,\n" - " av.attr_value\n" - " FROM ldb_entry AS entry\n" - - " LEFT OUTER JOIN ldb_attribute_values AS av\n" - " ON av.eid = entry.eid\n" - - " WHERE entry.eid IN\n" - " (SELECT DISTINCT ldb_entry.eid\n" - " FROM ldb_entry\n" - " WHERE ldb_entry.eid IN\n" - " (%s)\n" - " )\n" - - " ORDER BY entry.eid ASC;", - sqlfilter); - } - - break; - - case LDB_SCOPE_BASE: - query = lsqlite3_tprintf(lsql_ac, - "SELECT entry.eid,\n" - " entry.dn,\n" - " av.attr_name,\n" - " av.attr_value\n" - " FROM ldb_entry AS entry\n" - - " LEFT OUTER JOIN ldb_attribute_values AS av\n" - " ON av.eid = entry.eid\n" - - " WHERE entry.eid IN\n" - " (SELECT DISTINCT ldb_entry.eid\n" - " FROM ldb_entry\n" - " WHERE ldb_entry.norm_dn = '%q'\n" - " AND ldb_entry.eid IN\n" - " (%s)\n" - " )\n" - - " ORDER BY entry.eid ASC;", - norm_basedn, - sqlfilter); - break; - - case LDB_SCOPE_ONELEVEL: - query = lsqlite3_tprintf(lsql_ac, - "SELECT entry.eid,\n" - " entry.dn,\n" - " av.attr_name,\n" - " av.attr_value\n" - " FROM ldb_entry AS entry\n" - - " LEFT OUTER JOIN ldb_attribute_values AS av\n" - " ON av.eid = entry.eid\n" - - " WHERE entry.eid IN\n" - " (SELECT DISTINCT ldb_entry.eid\n" - " FROM ldb_entry\n" - " WHERE norm_dn GLOB('*,%q')\n" - " AND NOT norm_dn GLOB('*,*,%q')\n" - " AND ldb_entry.eid IN\n(%s)\n" - " )\n" - - " ORDER BY entry.eid ASC;", - norm_basedn, - norm_basedn, - sqlfilter); - break; - } - - if (query == NULL) { - goto failed; - } - - /* * / - printf ("%s\n", query); - / * */ - - lsql_ac->current_eid = 0; - lsql_ac->attrs = req->op.search.attrs; - lsql_ac->ares = NULL; - - req->handle->state = LDB_ASYNC_PENDING; - - ret = sqlite3_exec(lsqlite3->sqlite, query, lsqlite3_search_callback, req->handle, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - ldb_set_errstring(module->ldb, errmsg); - free(errmsg); - } - goto failed; - } - - /* complete the last message if any */ - if (lsql_ac->ares) { - lsql_ac->ares->message = ldb_msg_canonicalize(module->ldb, lsql_ac->ares->message); - if (lsql_ac->ares->message == NULL) - goto failed; - - req->handle->status = lsql_ac->callback(module->ldb, lsql_ac->context, lsql_ac->ares); - if (req->handle->status != LDB_SUCCESS) - goto failed; - } - - req->handle->state = LDB_ASYNC_DONE; - - return LDB_SUCCESS; - -failed: - return LDB_ERR_OPERATIONS_ERROR; -} - -/* add a record */ -static int lsql_add(struct ldb_module *module, struct ldb_request *req) -{ - struct lsqlite3_private *lsqlite3 = talloc_get_type(module->private_data, struct lsqlite3_private); - struct lsql_context *lsql_ac; - struct ldb_message *msg = req->op.add.message; - long long eid; - char *dn, *ndn; - char *errmsg; - char *query; - int i; - int ret = LDB_SUCCESS; - - req->handle = init_handle(lsqlite3, module, req); - if (req->handle == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - lsql_ac = talloc_get_type(req->handle->private_data, struct lsql_context); - req->handle->state = LDB_ASYNC_DONE; - req->handle->status = LDB_SUCCESS; - - /* See if this is an ltdb special */ - if (ldb_dn_is_special(msg->dn)) { - struct ldb_dn *c; - - c = ldb_dn_explode(lsql_ac, "@SUBCLASSES"); - if (ldb_dn_compare(module->ldb, msg->dn, c) == 0) { -#warning "insert subclasses into object class tree" - ret = LDB_ERR_UNWILLING_TO_PERFORM; - goto done; - } - -/* - c = ldb_dn_explode(local_ctx, "@INDEXLIST"); - if (ldb_dn_compare(module->ldb, msg->dn, c) == 0) { -#warning "should we handle indexes somehow ?" - ret = LDB_ERR_UNWILLING_TO_PERFORM; - goto done; - } -*/ - /* Others return an error */ - ret = LDB_ERR_UNWILLING_TO_PERFORM; - goto done; - } - - /* create linearized and normalized dns */ - dn = ldb_dn_linearize(lsql_ac, msg->dn); - ndn = ldb_dn_linearize(lsql_ac, ldb_dn_casefold(module->ldb, lsql_ac, msg->dn)); - if (dn == NULL || ndn == NULL) { - ret = LDB_ERR_OTHER; - goto done; - } - - query = lsqlite3_tprintf(lsql_ac, - /* Add new entry */ - "INSERT OR ABORT INTO ldb_entry " - "('dn', 'norm_dn') " - "VALUES ('%q', '%q');", - dn, ndn); - if (query == NULL) { - ret = LDB_ERR_OTHER; - goto done; - } - - ret = sqlite3_exec(lsqlite3->sqlite, query, NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - ldb_set_errstring(module->ldb, errmsg); - free(errmsg); - } - ret = LDB_ERR_OTHER; - goto done; - } - - eid = lsqlite3_get_eid_ndn(lsqlite3->sqlite, lsql_ac, ndn); - if (eid == -1) { - ret = LDB_ERR_OTHER; - goto done; - } - - for (i = 0; i < msg->num_elements; i++) { - const struct ldb_message_element *el = &msg->elements[i]; - const struct ldb_attrib_handler *h; - char *attr; - int j; - - /* Get a case-folded copy of the attribute name */ - attr = ldb_attr_casefold(lsql_ac, el->name); - if (attr == NULL) { - ret = LDB_ERR_OTHER; - goto done; - } - - h = ldb_attrib_handler(module->ldb, el->name); - - /* For each value of the specified attribute name... */ - for (j = 0; j < el->num_values; j++) { - struct ldb_val value; - char *insert; - - /* Get a canonicalised copy of the data */ - h->canonicalise_fn(module->ldb, lsql_ac, &(el->values[j]), &value); - if (value.data == NULL) { - ret = LDB_ERR_OTHER; - goto done; - } - - insert = lsqlite3_tprintf(lsql_ac, - "INSERT OR ROLLBACK INTO ldb_attribute_values " - "('eid', 'attr_name', 'norm_attr_name'," - " 'attr_value', 'norm_attr_value') " - "VALUES ('%lld', '%q', '%q', '%q', '%q');", - eid, el->name, attr, - el->values[j].data, value.data); - if (insert == NULL) { - ret = LDB_ERR_OTHER; - goto done; - } - - ret = sqlite3_exec(lsqlite3->sqlite, insert, NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - ldb_set_errstring(module->ldb, errmsg); - free(errmsg); - } - ret = LDB_ERR_OTHER; - goto done; - } - } - } - - if (lsql_ac->callback) { - req->handle->status = lsql_ac->callback(module->ldb, lsql_ac->context, NULL); - } - -done: - req->handle->state = LDB_ASYNC_DONE; - return ret; -} - -/* modify a record */ -static int lsql_modify(struct ldb_module *module, struct ldb_request *req) -{ - struct lsqlite3_private *lsqlite3 = talloc_get_type(module->private_data, struct lsqlite3_private); - struct lsql_context *lsql_ac; - struct ldb_message *msg = req->op.mod.message; - long long eid; - char *errmsg; - int i; - int ret = LDB_SUCCESS; - - req->handle = init_handle(lsqlite3, module, req); - if (req->handle == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - lsql_ac = talloc_get_type(req->handle->private_data, struct lsql_context); - req->handle->state = LDB_ASYNC_DONE; - req->handle->status = LDB_SUCCESS; - - /* See if this is an ltdb special */ - if (ldb_dn_is_special(msg->dn)) { - struct ldb_dn *c; - - c = ldb_dn_explode(lsql_ac, "@SUBCLASSES"); - if (ldb_dn_compare(module->ldb, msg->dn, c) == 0) { -#warning "modify subclasses into object class tree" - ret = LDB_ERR_UNWILLING_TO_PERFORM; - goto done; - } - - /* Others return an error */ - ret = LDB_ERR_UNWILLING_TO_PERFORM; - goto done; - } - - eid = lsqlite3_get_eid(module, msg->dn); - if (eid == -1) { - ret = LDB_ERR_OTHER; - goto done; - } - - for (i = 0; i < msg->num_elements; i++) { - const struct ldb_message_element *el = &msg->elements[i]; - const struct ldb_attrib_handler *h; - int flags = el->flags & LDB_FLAG_MOD_MASK; - char *attr; - char *mod; - int j; - - /* Get a case-folded copy of the attribute name */ - attr = ldb_attr_casefold(lsql_ac, el->name); - if (attr == NULL) { - ret = LDB_ERR_OTHER; - goto done; - } - - h = ldb_attrib_handler(module->ldb, el->name); - - switch (flags) { - - case LDB_FLAG_MOD_REPLACE: - - /* remove all attributes before adding the replacements */ - mod = lsqlite3_tprintf(lsql_ac, - "DELETE FROM ldb_attribute_values " - "WHERE eid = '%lld' " - "AND norm_attr_name = '%q';", - eid, attr); - if (mod == NULL) { - ret = LDB_ERR_OTHER; - goto done; - } - - ret = sqlite3_exec(lsqlite3->sqlite, mod, NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - ldb_set_errstring(module->ldb, errmsg); - free(errmsg); - } - ret = LDB_ERR_OTHER; - goto done; - } - - /* MISSING break is INTENTIONAL */ - - case LDB_FLAG_MOD_ADD: -#warning "We should throw an error if no value is provided!" - /* For each value of the specified attribute name... */ - for (j = 0; j < el->num_values; j++) { - struct ldb_val value; - - /* Get a canonicalised copy of the data */ - h->canonicalise_fn(module->ldb, lsql_ac, &(el->values[j]), &value); - if (value.data == NULL) { - ret = LDB_ERR_OTHER; - goto done; - } - - mod = lsqlite3_tprintf(lsql_ac, - "INSERT OR ROLLBACK INTO ldb_attribute_values " - "('eid', 'attr_name', 'norm_attr_name'," - " 'attr_value', 'norm_attr_value') " - "VALUES ('%lld', '%q', '%q', '%q', '%q');", - eid, el->name, attr, - el->values[j].data, value.data); - - if (mod == NULL) { - ret = LDB_ERR_OTHER; - goto done; - } - - ret = sqlite3_exec(lsqlite3->sqlite, mod, NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - ldb_set_errstring(module->ldb, errmsg); - free(errmsg); - } - ret = LDB_ERR_OTHER; - goto done; - } - } - - break; - - case LDB_FLAG_MOD_DELETE: -#warning "We should throw an error if the attribute we are trying to delete does not exist!" - if (el->num_values == 0) { - mod = lsqlite3_tprintf(lsql_ac, - "DELETE FROM ldb_attribute_values " - "WHERE eid = '%lld' " - "AND norm_attr_name = '%q';", - eid, attr); - if (mod == NULL) { - ret = LDB_ERR_OTHER; - goto done; - } - - ret = sqlite3_exec(lsqlite3->sqlite, mod, NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - ldb_set_errstring(module->ldb, errmsg); - free(errmsg); - } - ret = LDB_ERR_OTHER; - goto done; - } - } - - /* For each value of the specified attribute name... */ - for (j = 0; j < el->num_values; j++) { - struct ldb_val value; - - /* Get a canonicalised copy of the data */ - h->canonicalise_fn(module->ldb, lsql_ac, &(el->values[j]), &value); - if (value.data == NULL) { - ret = LDB_ERR_OTHER; - goto done; - } - - mod = lsqlite3_tprintf(lsql_ac, - "DELETE FROM ldb_attribute_values " - "WHERE eid = '%lld' " - "AND norm_attr_name = '%q' " - "AND norm_attr_value = '%q';", - eid, attr, value.data); - - if (mod == NULL) { - ret = LDB_ERR_OTHER; - goto done; - } - - ret = sqlite3_exec(lsqlite3->sqlite, mod, NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - ldb_set_errstring(module->ldb, errmsg); - free(errmsg); - } - ret = LDB_ERR_OTHER; - goto done; - } - } - - break; - } - } - - if (lsql_ac->callback) { - req->handle->status = lsql_ac->callback(module->ldb, lsql_ac->context, NULL); - } - -done: - req->handle->state = LDB_ASYNC_DONE; - return ret; -} - -/* delete a record */ -static int lsql_delete(struct ldb_module *module, struct ldb_request *req) -{ - struct lsqlite3_private *lsqlite3 = talloc_get_type(module->private_data, struct lsqlite3_private); - struct lsql_context *lsql_ac; - long long eid; - char *errmsg; - char *query; - int ret = LDB_SUCCESS; - - - req->handle = init_handle(lsqlite3, module, req); - if (req->handle == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - lsql_ac = talloc_get_type(req->handle->private_data, struct lsql_context); - req->handle->state = LDB_ASYNC_DONE; - req->handle->status = LDB_SUCCESS; - - eid = lsqlite3_get_eid(module, req->op.del.dn); - if (eid == -1) { - goto done; - } - - query = lsqlite3_tprintf(lsql_ac, - /* Delete entry */ - "DELETE FROM ldb_entry WHERE eid = %lld; " - /* Delete attributes */ - "DELETE FROM ldb_attribute_values WHERE eid = %lld; ", - eid, eid); - if (query == NULL) { - ret = LDB_ERR_OTHER; - goto done; - } - - ret = sqlite3_exec(lsqlite3->sqlite, query, NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - ldb_set_errstring(module->ldb, errmsg); - free(errmsg); - } - req->handle->status = LDB_ERR_OPERATIONS_ERROR; - goto done; - } - - if (lsql_ac->callback) { - ret = lsql_ac->callback(module->ldb, lsql_ac->context, NULL); - } - -done: - req->handle->state = LDB_ASYNC_DONE; - return ret; -} - -/* rename a record */ -static int lsql_rename(struct ldb_module *module, struct ldb_request *req) -{ - struct lsqlite3_private *lsqlite3 = talloc_get_type(module->private_data, struct lsqlite3_private); - struct lsql_context *lsql_ac; - char *new_dn, *new_cdn, *old_cdn; - char *errmsg; - char *query; - int ret = LDB_SUCCESS; - - req->handle = init_handle(lsqlite3, module, req); - if (req->handle == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - lsql_ac = talloc_get_type(req->handle->private_data, struct lsql_context); - req->handle->state = LDB_ASYNC_DONE; - req->handle->status = LDB_SUCCESS; - - /* create linearized and normalized dns */ - old_cdn = ldb_dn_linearize(lsql_ac, ldb_dn_casefold(module->ldb, lsql_ac, req->op.rename.olddn)); - new_cdn = ldb_dn_linearize(lsql_ac, ldb_dn_casefold(module->ldb, lsql_ac, req->op.rename.newdn)); - new_dn = ldb_dn_linearize(lsql_ac, req->op.rename.newdn); - if (old_cdn == NULL || new_cdn == NULL || new_dn == NULL) { - goto done; - } - - /* build the SQL query */ - query = lsqlite3_tprintf(lsql_ac, - "UPDATE ldb_entry SET dn = '%q', norm_dn = '%q' " - "WHERE norm_dn = '%q';", - new_dn, new_cdn, old_cdn); - if (query == NULL) { - goto done; - } - - /* execute */ - ret = sqlite3_exec(lsqlite3->sqlite, query, NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - ldb_set_errstring(module->ldb, errmsg); - free(errmsg); - } - ret = LDB_ERR_OPERATIONS_ERROR; - goto done; - } - - if (lsql_ac->callback) { - ret = lsql_ac->callback(module->ldb, lsql_ac->context, NULL); - } - -done: - req->handle->state = LDB_ASYNC_DONE; - return ret; -} - -static int lsql_start_trans(struct ldb_module * module) -{ - int ret; - char *errmsg; - struct lsqlite3_private * lsqlite3 = module->private_data; - - if (lsqlite3->trans_count == 0) { - ret = sqlite3_exec(lsqlite3->sqlite, "BEGIN IMMEDIATE;", NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - printf("lsqlite3_start_trans: error: %s\n", errmsg); - free(errmsg); - } - return -1; - } - }; - - lsqlite3->trans_count++; - - return 0; -} - -static int lsql_end_trans(struct ldb_module *module) -{ - int ret; - char *errmsg; - struct lsqlite3_private *lsqlite3 = module->private_data; - - if (lsqlite3->trans_count > 0) { - lsqlite3->trans_count--; - } else return -1; - - if (lsqlite3->trans_count == 0) { - ret = sqlite3_exec(lsqlite3->sqlite, "COMMIT;", NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - printf("lsqlite3_end_trans: error: %s\n", errmsg); - free(errmsg); - } - return -1; - } - } - - return 0; -} - -static int lsql_del_trans(struct ldb_module *module) -{ - struct lsqlite3_private *lsqlite3 = module->private_data; - - if (lsqlite3->trans_count > 0) { - lsqlite3->trans_count--; - } else return -1; - - if (lsqlite3->trans_count == 0) { - return lsqlite3_safe_rollback(lsqlite3->sqlite); - } - - return -1; -} - -static int destructor(struct lsqlite3_private *lsqlite3) -{ - if (lsqlite3->sqlite) { - sqlite3_close(lsqlite3->sqlite); - } - return 0; -} - -static int lsql_request(struct ldb_module *module, struct ldb_request *req) -{ - return LDB_ERR_OPERATIONS_ERROR; -} - -static int lsql_wait(struct ldb_handle *handle, enum ldb_wait_type type) -{ - return handle->status; -} - -/* - * Table of operations for the sqlite3 backend - */ -static const struct ldb_module_ops lsqlite3_ops = { - .name = "sqlite", - .search = lsql_search, - .add = lsql_add, - .modify = lsql_modify, - .del = lsql_delete, - .rename = lsql_rename, - .request = lsql_request, - .start_transaction = lsql_start_trans, - .end_transaction = lsql_end_trans, - .del_transaction = lsql_del_trans, - .wait = lsql_wait, -}; - -/* - * Static functions - */ - -static int initialize(struct lsqlite3_private *lsqlite3, - struct ldb_context *ldb, const char *url, int flags) -{ - TALLOC_CTX *local_ctx; - long long queryInt; - int rollback = 0; - char *errmsg; - char *schema; - int ret; - - /* create a local ctx */ - local_ctx = talloc_named(lsqlite3, 0, "lsqlite3_rename local context"); - if (local_ctx == NULL) { - return -1; - } - - schema = lsqlite3_tprintf(local_ctx, - - - "CREATE TABLE ldb_info AS " - " SELECT 'LDB' AS database_type," - " '1.0' AS version;" - - /* - * The entry table holds the information about an entry. - * This table is used to obtain the EID of the entry and to - * support scope=one and scope=base. The parent and child - * table is included in the entry table since all the other - * attributes are dependent on EID. - */ - "CREATE TABLE ldb_entry " - "(" - " eid INTEGER PRIMARY KEY AUTOINCREMENT," - " dn TEXT UNIQUE NOT NULL," - " norm_dn TEXT UNIQUE NOT NULL" - ");" - - - "CREATE TABLE ldb_object_classes" - "(" - " class_name TEXT PRIMARY KEY," - " parent_class_name TEXT," - " tree_key TEXT UNIQUE," - " max_child_num INTEGER DEFAULT 0" - ");" - - /* - * We keep a full listing of attribute/value pairs here - */ - "CREATE TABLE ldb_attribute_values" - "(" - " eid INTEGER REFERENCES ldb_entry," - " attr_name TEXT," - " norm_attr_name TEXT," - " attr_value TEXT," - " norm_attr_value TEXT " - ");" - - - /* - * Indexes - */ - "CREATE INDEX ldb_attribute_values_eid_idx " - " ON ldb_attribute_values (eid);" - - "CREATE INDEX ldb_attribute_values_name_value_idx " - " ON ldb_attribute_values (attr_name, norm_attr_value);" - - - - /* - * Triggers - */ - - "CREATE TRIGGER ldb_object_classes_insert_tr" - " AFTER INSERT" - " ON ldb_object_classes" - " FOR EACH ROW" - " BEGIN" - " UPDATE ldb_object_classes" - " SET tree_key = COALESCE(tree_key, " - " (" - " SELECT tree_key || " - " (SELECT base160(max_child_num + 1)" - " FROM ldb_object_classes" - " WHERE class_name = " - " new.parent_class_name)" - " FROM ldb_object_classes " - " WHERE class_name = new.parent_class_name " - " ));" - " UPDATE ldb_object_classes " - " SET max_child_num = max_child_num + 1" - " WHERE class_name = new.parent_class_name;" - " END;" - - /* - * Table initialization - */ - - "INSERT INTO ldb_object_classes " - " (class_name, tree_key) " - " VALUES " - " ('TOP', '0001');"); - - /* Skip protocol indicator of url */ - if (strncmp(url, "sqlite3://", 10) != 0) { - return SQLITE_MISUSE; - } - - /* Update pointer to just after the protocol indicator */ - url += 10; - - /* Try to open the (possibly empty/non-existent) database */ - if ((ret = sqlite3_open(url, &lsqlite3->sqlite)) != SQLITE_OK) { - return ret; - } - - /* In case this is a new database, enable auto_vacuum */ - ret = sqlite3_exec(lsqlite3->sqlite, "PRAGMA auto_vacuum = 1;", NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - printf("lsqlite3 initializaion error: %s\n", errmsg); - free(errmsg); - } - goto failed; - } - - if (flags & LDB_FLG_NOSYNC) { - /* DANGEROUS */ - ret = sqlite3_exec(lsqlite3->sqlite, "PRAGMA synchronous = OFF;", NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - printf("lsqlite3 initializaion error: %s\n", errmsg); - free(errmsg); - } - goto failed; - } - } - - /* */ - - /* Establish a busy timeout of 30 seconds */ - if ((ret = sqlite3_busy_timeout(lsqlite3->sqlite, - 30000)) != SQLITE_OK) { - return ret; - } - - /* Create a function, callable from sql, to increment a tree_key */ - if ((ret = - sqlite3_create_function(lsqlite3->sqlite,/* handle */ - "base160_next", /* function name */ - 1, /* number of args */ - SQLITE_ANY, /* preferred text type */ - NULL, /* user data */ - base160next_sql, /* called func */ - NULL, /* step func */ - NULL /* final func */ - )) != SQLITE_OK) { - return ret; - } - - /* Create a function, callable from sql, to convert int to base160 */ - if ((ret = - sqlite3_create_function(lsqlite3->sqlite,/* handle */ - "base160", /* function name */ - 1, /* number of args */ - SQLITE_ANY, /* preferred text type */ - NULL, /* user data */ - base160_sql, /* called func */ - NULL, /* step func */ - NULL /* final func */ - )) != SQLITE_OK) { - return ret; - } - - /* Create a function, callable from sql, to perform various comparisons */ - if ((ret = - sqlite3_create_function(lsqlite3->sqlite, /* handle */ - "ldap_compare", /* function name */ - 4, /* number of args */ - SQLITE_ANY, /* preferred text type */ - ldb , /* user data */ - lsqlite3_compare, /* called func */ - NULL, /* step func */ - NULL /* final func */ - )) != SQLITE_OK) { - return ret; - } - - /* Begin a transaction */ - ret = sqlite3_exec(lsqlite3->sqlite, "BEGIN EXCLUSIVE;", NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - printf("lsqlite3: initialization error: %s\n", errmsg); - free(errmsg); - } - goto failed; - } - rollback = 1; - - /* Determine if this is a new database. No tables means it is. */ - if (query_int(lsqlite3, - &queryInt, - "SELECT COUNT(*)\n" - " FROM sqlite_master\n" - " WHERE type = 'table';") != 0) { - goto failed; - } - - if (queryInt == 0) { - /* - * Create the database schema - */ - ret = sqlite3_exec(lsqlite3->sqlite, schema, NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - printf("lsqlite3 initializaion error: %s\n", errmsg); - free(errmsg); - } - goto failed; - } - } else { - /* - * Ensure that the database we opened is one of ours - */ - if (query_int(lsqlite3, - &queryInt, - "SELECT " - " (SELECT COUNT(*) = 2" - " FROM sqlite_master " - " WHERE type = 'table' " - " AND name IN " - " (" - " 'ldb_entry', " - " 'ldb_object_classes' " - " ) " - " ) " - " AND " - " (SELECT 1 " - " FROM ldb_info " - " WHERE database_type = 'LDB' " - " AND version = '1.0'" - " );") != 0 || - queryInt != 1) { - - /* It's not one that we created. See ya! */ - goto failed; - } - } - - /* Commit the transaction */ - ret = sqlite3_exec(lsqlite3->sqlite, "COMMIT;", NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - printf("lsqlite3: iniialization error: %s\n", errmsg); - free(errmsg); - } - goto failed; - } - - return SQLITE_OK; - -failed: - if (rollback) lsqlite3_safe_rollback(lsqlite3->sqlite); - sqlite3_close(lsqlite3->sqlite); - return -1; -} - -/* - * connect to the database - */ -static int lsqlite3_connect(struct ldb_context *ldb, - const char *url, - unsigned int flags, - const char *options[], - struct ldb_module **module) -{ - int i; - int ret; - struct lsqlite3_private * lsqlite3 = NULL; - - lsqlite3 = talloc(ldb, struct lsqlite3_private); - if (!lsqlite3) { - goto failed; - } - - lsqlite3->sqlite = NULL; - lsqlite3->options = NULL; - lsqlite3->trans_count = 0; - - ret = initialize(lsqlite3, ldb, url, flags); - if (ret != SQLITE_OK) { - goto failed; - } - - talloc_set_destructor(lsqlite3, destructor); - - - - *module = talloc(ldb, struct ldb_module); - if (!module) { - ldb_oom(ldb); - goto failed; - } - talloc_set_name_const(*module, "ldb_sqlite3 backend"); - (*module)->ldb = ldb; - (*module)->prev = (*module)->next = NULL; - (*module)->private_data = lsqlite3; - (*module)->ops = &lsqlite3_ops; - - if (options) { - /* - * take a copy of the options array, so we don't have to rely - * on the caller keeping it around (it might be dynamic) - */ - for (i=0;options[i];i++) ; - - lsqlite3->options = talloc_array(lsqlite3, char *, i+1); - if (!lsqlite3->options) { - goto failed; - } - - for (i=0;options[i];i++) { - - lsqlite3->options[i+1] = NULL; - lsqlite3->options[i] = - talloc_strdup(lsqlite3->options, options[i]); - if (!lsqlite3->options[i]) { - goto failed; - } - } - } - - return 0; - -failed: - if (lsqlite3->sqlite != NULL) { - (void) sqlite3_close(lsqlite3->sqlite); - } - talloc_free(lsqlite3); - return -1; -} - -int ldb_sqlite3_init(void) -{ - return ldb_register_backend("sqlite3", lsqlite3_connect); -} diff --git a/source/lib/ldb/ldb_sqlite3/schema b/source/lib/ldb/ldb_sqlite3/schema deleted file mode 100644 index 08dc50de089..00000000000 --- a/source/lib/ldb/ldb_sqlite3/schema +++ /dev/null @@ -1,363 +0,0 @@ - -- ------------------------------------------------------ - - PRAGMA auto_vacuum=1; - - -- ------------------------------------------------------ - - BEGIN EXCLUSIVE; - - -- ------------------------------------------------------ - - CREATE TABLE ldb_info AS - SELECT 'LDB' AS database_type, - '1.0' AS version; - - /* - * Get the next USN value with: - * BEGIN EXCLUSIVE; - * UPDATE usn SET value = value + 1; - * SELECT value FROM usn; - * COMMIT; - */ - CREATE TABLE usn - ( - value INTEGER - ); - - CREATE TABLE ldb_object - ( - /* tree_key is auto-generated by the insert trigger */ - tree_key TEXT PRIMARY KEY, - - parent_tree_key TEXT, - dn TEXT, - - attr_name TEXT REFERENCES ldb_attributes, - attr_value TEXT, - - /* - * object_type can take on these values (to date): - * 1: object is a node of a DN - * 2: object is an attribute/value pair of its parent DN - */ - object_type INTEGER, - - /* - * if object_type is 1, the node can have children. - * this tracks the maximum previously assigned child - * number so we can generate a new unique tree key for - * a new child object. note that this is always incremented, - * so if children are deleted, this will not represent - * the _number_ of children. - */ - max_child_num INTEGER, - - /* - * Automatically maintained meta-data (a gift for metze) - */ - object_guid TEXT UNIQUE, - timestamp INTEGER, -- originating_time - invoke_id TEXT, -- GUID: originating_invocation_id - usn INTEGER, -- hyper: originating_usn - - /* do not allow duplicate name/value pairs */ - UNIQUE (parent_tree_key, attr_name, attr_value, object_type) - ); - - CREATE TABLE ldb_attributes - ( - attr_name TEXT PRIMARY KEY, - parent_tree_key TEXT, - - objectclass_p BOOLEAN DEFAULT 0, - - case_insensitive_p BOOLEAN DEFAULT 0, - wildcard_p BOOLEAN DEFAULT 0, - hidden_p BOOLEAN DEFAULT 0, - integer_p BOOLEAN DEFAULT 0, - - /* tree_key is auto-generated by the insert trigger */ - tree_key TEXT, -- null if not a object/sub class - -- level 1 if an objectclass - -- level 1-n if a subclass - max_child_num INTEGER - ); - - -- ------------------------------------------------------ - - CREATE INDEX ldb_object_dn_idx - ON ldb_object (dn); - - CREATE INDEX ldb_attributes_tree_key_ids - ON ldb_attributes (tree_key); - - -- ------------------------------------------------------ - - /* Gifts for metze. Automatically updated meta-data */ - CREATE TRIGGER ldb_object_insert_tr - AFTER INSERT - ON ldb_object - FOR EACH ROW - BEGIN - UPDATE ldb_object - SET max_child_num = max_child_num + 1 - WHERE tree_key = new.parent_tree_key; - UPDATE usn SET value = value + 1; - UPDATE ldb_object - SET tree_key = - (SELECT - new.tree_key || - base160(SELECT max_child_num - FROM ldb_object - WHERE tree_key = - new.parent_tree_key)); - max_child_num = 0, - object_guid = random_guid(), - timestamp = strftime('%s', 'now'), - usn = (SELECT value FROM usn); - WHERE tree_key = new.tree_key; - END; - - CREATE TRIGGER ldb_object_update_tr - AFTER UPDATE - ON ldb_object - FOR EACH ROW - BEGIN - UPDATE usn SET value = value + 1; - UPDATE ldb_object - SET timestamp = strftime('%s', 'now'), - usn = (SELECT value FROM usn); - WHERE tree_key = new.tree_key; - END; - - CREATE TRIGGER ldb_attributes_insert_tr - AFTER INSERT - ON ldb_attributes - FOR EACH ROW - BEGIN - UPDATE ldb_attributes - SET max_child_num = max_child_num + 1 - WHERE tree_key = new.parent_tree_key; - UPDATE ldb_attributes - SET tree_key = - (SELECT - new.tree_key || - base160(SELECT max_child_num - FROM ldb_attributes - WHERE tree_key = - new.parent_tree_key)); - max_child_num = 0 - WHERE tree_key = new.tree_key; - END; - - - -- ------------------------------------------------------ - - /* Initialize usn */ - INSERT INTO usn (value) VALUES (0); - - /* Create root object */ - INSERT INTO ldb_object - (tree_key, parent_tree_key, - dn, - object_type, max_child_num) - VALUES ('', NULL, - '', - 1, 0); - - /* We need an implicit "top" level object class */ - INSERT INTO ldb_attributes (attr_name, - parent_tree_key) - SELECT 'top', ''; - - -- ------------------------------------------------------ - - COMMIT; - - -- ------------------------------------------------------ - -/* - * dn: o=University of Michigan,c=US - * objectclass: organization - * objectclass: domainRelatedObject - */ --- newDN -BEGIN; - -INSERT OR IGNORE INTO ldb_object - (parent_tree_key - dn, - attr_name, attr_value, object_type, max_child_num) - VALUES ('', - 'c=US', - 'c', 'US', 1, 0); - -INSERT INTO ldb_object - (parent_tree_key, - dn, - attr_name, attr_value, object_type, max_child_num) - VALUES ('0001', - 'o=University of Michigan,c=US', - 'o', 'University of Michigan', 1, 0); - --- newObjectClass -INSERT OR IGNORE INTO ldb_attributes - (attr_name, parent_tree_key, objectclass_p) - VALUES - ('objectclass', '', 1); - -INSERT INTO ldb_object - (parent_tree_key, - dn, - attr_name, attr_value, object_type, max_child_num) - VALUES ('00010001', - NULL, - 'objectclass', 'organization', 2, 0); - -INSERT OR IGNORE INTO ldb_attributes - (attr_name, parent_tree_key, objectclass_p) - VALUES - ('objectclass', '', 1); - -INSERT INTO ldb_object - (parent_tree_key, - dn, - attr_name, attr_value, object_type, max_child_num) - VALUES ('00010001', - NULL, - 'objectclass', 'domainRelatedObject', 2, 0); - -COMMIT; - - -/* - * dn: o=University of Michigan,c=US - * l: Ann Arbor, Michigan - * st: Michigan - * o: University of Michigan - * o: UMICH - * seeAlso: - * telephonenumber: +1 313 764-1817 - */ --- addAttrValuePair -BEGIN; - -INSERT INTO ldb_object - (parent_tree_key, dn, - attr_name, attr_value, object_type, max_child_num) - VALUES ('00010001', NULL, - 'l', 'Ann Arbor, Michigan', 2, 0); - -INSERT INTO ldb_object - (parent_tree_key, dn, - attr_name, attr_value, object_type, max_child_num) - VALUES ('00010001', NULL, - 'st', 'Michigan', 2, 0); - -INSERT INTO ldb_object - (parent_tree_key, dn, - attr_name, attr_value, object_type, max_child_num) - VALUES ('00010001', NULL, - 'o', 'University of Michigan', 2, 0); - -INSERT INTO ldb_object - (parent_tree_key, dn, - attr_name, attr_value, object_type, max_child_num) - VALUES ('00010001', NULL, - 'o', 'UMICH', 2, 0); - -INSERT INTO ldb_object - (parent_tree_key, dn, - attr_name, attr_value, object_type, max_child_num) - VALUES ('00010001', NULL, - 'seeAlso', '', 2, 0); - -INSERT INTO ldb_object - (parent_tree_key, dn, - attr_name, attr_value, object_type, max_child_num) - VALUES ('00010001', NULL, - 'telephonenumber', '+1 313 764-1817', 2, 0); - -COMMIT; - --- ---------------------------------------------------------------------- - -/* - * dn: @ATTRIBUTES - * uid: CASE_INSENSITIVE WILDCARD - * cn: CASE_INSENSITIVE - * ou: CASE_INSENSITIVE - * dn: CASE_INSENSITIVE - */ --- newAttribute - -BEGIN; - -INSERT OR IGNORE INTO ldb_attributes - (attr_name, parent_tree_key, objectclass_p) - VALUES - ('uid', '', 0); - -UPDATE ldb_attributes - SET case_insensitive_p = 1, - wildcard_p = 1, - hidden_p = 0, - integer_p = 0 - WHERE attr_name = 'uid' - -UPDATE ldb_attributes - SET case_insensitive_p = 1, - wildcard_p = 0, - hidden_p = 0, - integer_p = 0 - WHERE attr_name = 'cn' - -UPDATE ldb_attributes - SET case_insensitive_p = 1, - wildcard_p = 0, - hidden_p = 0, - integer_p = 0 - WHERE attr_name = 'ou' - -UPDATE ldb_attributes - SET case_insensitive_p = 1, - wildcard_p = 0, - hidden_p = 0, - integer_p = 0 - WHERE attr_name = 'dn' - --- ---------------------------------------------------------------------- - -/* - * dn: @SUBCLASSES - * top: domain - * top: person - * domain: domainDNS - * person: organizationalPerson - * person: fooPerson - * organizationalPerson: user - * organizationalPerson: OpenLDAPperson - * user: computer - */ --- insertSubclass - -/* NOT YET UPDATED!!! * - - -INSERT OR REPLACE INTO ldb_object_classes (class_name, tree_key) - SELECT 'domain', /* next_tree_key('top') */ '00010001'; -INSERT OR REPLACE INTO ldb_object_classes (class_name, tree_key) - SELECT 'person', /* next_tree_key('top') */ '00010002'; -INSERT OR REPLACE INTO ldb_object_classes (class_name, tree_key) - SELECT 'domainDNS', /* next_tree_key('domain') */ '000100010001'; -INSERT OR REPLACE INTO ldb_object_classes (class_name, tree_key) - SELECT 'organizationalPerson', /* next_tree_key('person') */ '000100020001'; -INSERT OR REPLACE INTO ldb_object_classes (class_name, tree_key) - SELECT 'fooPerson', /* next_tree_key('person') */ '000100020002'; -INSERT OR REPLACE INTO ldb_object_classes (class_name, tree_key) - SELECT 'user', /* next_tree_key('organizationalPerson') */ '0001000200010001'; -INSERT OR REPLACE INTO ldb_object_classes (class_name, tree_key) - SELECT 'OpenLDAPperson', /* next_tree_key('organizationPerson') */ '0001000200010002'; -INSERT OR REPLACE INTO ldb_object_classes (class_name, tree_key) - SELECT 'computer', /* next_tree_key('user') */ '0001000200010001'; - diff --git a/source/lib/ldb/ldb_sqlite3/trees.ps b/source/lib/ldb/ldb_sqlite3/trees.ps deleted file mode 100644 index 433a064816c..00000000000 --- a/source/lib/ldb/ldb_sqlite3/trees.ps +++ /dev/null @@ -1,1760 +0,0 @@ -%!PS-Adobe-2.0 -%%Creator: dvips(k) 5.86 Copyright 1999 Radical Eye Software -%%Title: trees.dvi -%%Pages: 7 -%%PageOrder: Ascend -%%BoundingBox: 0 0 596 842 -%%EndComments -%DVIPSWebPage: (www.radicaleye.com) -%DVIPSCommandLine: dvips -f trees.dvi -%DVIPSParameters: dpi=600, compressed -%DVIPSSource: TeX output 2000.05.06:2055 -%%BeginProcSet: texc.pro -%! -/TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S -N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72 -mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0 -0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{ -landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize -mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[ -matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round -exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{ -statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0] -N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin -/FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array -/BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2 -array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N -df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A -definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get -}B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub} -B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr -1 add N}if}B/id 0 N/rw 0 N/rc 0 N/gp 0 N/cp 0 N/G 0 N/CharBuilder{save 3 -1 roll S A/base get 2 index get S/BitMaps get S get/Cd X pop/ctr 0 N Cdx -0 Cx Cy Ch sub Cx Cw add Cy setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx -sub Cy .1 sub]/id Ci N/rw Cw 7 add 8 idiv string N/rc 0 N/gp 0 N/cp 0 N{ -rc 0 ne{rc 1 sub/rc X rw}{G}ifelse}imagemask restore}B/G{{id gp get/gp -gp 1 add N A 18 mod S 18 idiv pl S get exec}loop}B/adv{cp add/cp X}B -/chg{rw cp id gp 4 index getinterval putinterval A gp add/gp X adv}B/nd{ -/cp 0 N rw exit}B/lsh{rw cp 2 copy get A 0 eq{pop 1}{A 255 eq{pop 254}{ -A A add 255 and S 1 and or}ifelse}ifelse put 1 adv}B/rsh{rw cp 2 copy -get A 0 eq{pop 128}{A 255 eq{pop 127}{A 2 idiv S 128 and or}ifelse} -ifelse put 1 adv}B/clr{rw cp 2 index string putinterval adv}B/set{rw cp -fillstr 0 4 index getinterval putinterval adv}B/fillstr 18 string 0 1 17 -{2 copy 255 put pop}for N/pl[{adv 1 chg}{adv 1 chg nd}{1 add chg}{1 add -chg nd}{adv lsh}{adv lsh nd}{adv rsh}{adv rsh nd}{1 add adv}{/rc X nd}{ -1 add set}{1 add clr}{adv 2 chg}{adv 2 chg nd}{pop nd}]A{bind pop} -forall N/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn -/BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put -}if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{ -bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A -mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{ -SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{ -userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X -1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4 -index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N -/p{show}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0 N/Ry 0 N/V{}B/RV/v{ -/Ry X/Rx X V}B statusdict begin/product where{pop false[(Display)(NeXT) -(LaserWriter 16/600)]{A length product length le{A length product exch 0 -exch getinterval eq{pop true exit}if}{pop}ifelse}forall}{false}ifelse -end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{BDot}imagemask -grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat{BDot} -imagemask grestore}}ifelse B/QV{gsave newpath transform round exch round -exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0 rlineto -fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B/M{S p -delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M}B/g{0 M} -B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p -3 w}B/n{ -p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{0 S -rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end - -%%EndProcSet -TeXDict begin 39158280 55380996 1000 600 600 (trees.dvi) -@start -%DVIPSBitmapFont: Fa cmr10 10 6 -/Fa 6 55 df<146014E0EB01C0EB0380EB0700130E131E5B5BA25B485AA2485AA212075B -120F90C7FCA25A121EA2123EA35AA65AB2127CA67EA3121EA2121F7EA27F12077F1203A2 -6C7EA26C7E1378A27F7F130E7FEB0380EB01C0EB00E01460135278BD20>40 -D<12C07E12707E7E7E120F6C7E6C7EA26C7E6C7EA21378A2137C133C133E131EA2131F7F -A21480A3EB07C0A6EB03E0B2EB07C0A6EB0F80A31400A25B131EA2133E133C137C1378A2 -5BA2485A485AA2485A48C7FC120E5A5A5A5A5A13527CBD20>I<15301578B3A6007FB812 -F8B912FCA26C17F8C80078C8FCB3A6153036367BAF41>43 D<EB03F8EB1FFF90387E0FC0 -9038F803E03901E000F0484813780007147C48487FA248C77EA2481580A3007EEC0FC0A6 -00FE15E0B3007E15C0A4007F141F6C1580A36C15006D5B000F143EA26C6C5B6C6C5B6C6C -485A6C6C485A90387E0FC0D91FFFC7FCEB03F8233A7DB72A>48 D<EB01C013031307131F -13FFB5FCA2131F1200B3B3A8497E007FB512F0A31C3879B72A>I<EC3FC0903801FFF001 -0713FC90380FE03E90383F800790387E001F49EB3F804848137F485AA2485A000FEC3F00 -49131E001F91C7FCA2485AA3127F90C9FCEB01FC903807FF8039FF1E07E090383801F049 -6C7E01607F01E0137E497FA249148016C0151FA290C713E0A57EA56C7E16C0A2121FED3F -807F000F15006C6C5B15FE6C6C5B6C6C485A3900FE07F090383FFFC06D90C7FCEB03FC23 -3A7DB72A>54 D E -%EndDVIPSBitmapFont -%DVIPSBitmapFont: Fb cmr7 7 3 -/Fb 3 55 df<EB3F803801FFF03803E0F83807803C48487E001E7F003E1480A2003C1307 -007C14C0A400FC14E0AE007C14C0A36CEB0F80A36CEB1F006C131E6C6C5A3803E0F86CB4 -5A38003F801B277EA521>48 D<13381378EA01F8121F12FE12E01200B3AB487EB512F8A2 -15267BA521>I<EB0FE0EB3FF8EBF81C3801E0063803C01F48485AEA0F005A121E003E13 -1E91C7FC5AA21304EB3FC038FCFFF038FDC078EB003CB4133E48131E141FA2481480A412 -7CA4003C1400123E001E131E143E6C133C6C6C5A3803C1F03801FFC06C6CC7FC19277DA5 -21>54 D E -%EndDVIPSBitmapFont -%DVIPSBitmapFont: Fc cmmi10 10 1 -/Fc 1 69 df<0103B7FC4916E018F8903B0007F80007FE4BEB00FFF03F80020FED1FC018 -0F4B15E0F007F0021F1503A24B15F81801143F19FC5DA2147FA292C8FCA25C18035CA213 -0119F84A1507A2130319F04A150FA2010717E0181F4A16C0A2010FEE3F80A24AED7F0018 -7E011F16FE4D5A4A5D4D5A013F4B5A4D5A4A4A5A057FC7FC017F15FEEE03FC91C7EA0FF0 -49EC7FC0B8C8FC16FC16C03E397DB845>68 D E -%EndDVIPSBitmapFont -%DVIPSBitmapFont: Fd ectt1000 10 73 -/Fd 73 126 df<D807801307D81FE0EB0F80151F487E486C133F1600007C5CD8FCFC137E -EAF87C15FE5D14015DA21403D8FCFC5BEA7CF8007F13075D383FF00FD81FE05BA2380780 -1FC75B143F92C7FCA25C147E14FE5CA213015CA213035C13075CA2130F5C131FEC800FED -3FC0013FEB7FE0140049EBFFF0017E13F9A2D9FE0113F801FC13F0A2120113F8120313F0 -15F90007010013F05B000F14FF49EB7FE0A20007EC3FC06C48EB0F0025417DB92C>37 -D<EA0F80EA1FE0EA3FF0127F13F8A213FCA2123F121F120FEA007CA313FC13F8A2120113 -F01203EA07E0A2EA0FC0EA3F80127FEAFF005A12F812700E1D71B22C>39 -D<143814FC13011303EB07F8EB0FF0EB1FC0EB3F80EB7F0013FE485A485A5B12075B120F -5B485AA2123F90C7FCA25A127EA312FE5AAC7E127EA3127F7EA27F121FA26C7E7F12077F -12037F6C7E6C7E137FEB3F80EB1FC0EB0FF0EB07F8EB03FC130113001438164272B92C> -I<127012FC7E7E6C7E6C7EEA0FE06C7E6C7E6C7E6C7E137F7F1480131F14C0130FEB07E0 -A214F01303A214F81301A314FC1300AC130114F8A3130314F0A2130714E0A2EB0FC0131F -1480133F14005B13FE485A485A485A485AEA3FC0485A48C7FC5A5A1270164279B92C>I< -EB0380497EA60020140800F8143E00FE14FE00FF13C1EBC7C7EBE7CF003FB512F8000F14 -E0000314806C140038007FFCA248B5FC481480000F14E0003F14F839FFE7CFFEEBC7C7EB -07C100FE13C000F8143E0020140800001400A66D5A1F247AAA2C>I<147014F8AF003FB6 -12E0B712F8A4C700F8C7FCB0147025267DAB2C>I<EA0F80EA1FE0EA3FF0EA7FF8A213FC -A3123F121F120F120013F8A21201EA03F01207EA1FE0EA7FC0EAFF80130012FC12700E17 -718A2C>I<121FEA3F80EA7FC0EAFFE0A5EA7FC0EA3F80EA1F000B0B708A2C>46 -D<1507ED0F80A2151F16005D153E157E157CA215FC5D14015D14035D14075D140F5D141F -92C7FC5C143EA2147E147C14FC5C13015C13035C13075C130F5C131F91C8FC5B133EA213 -7E137C13FC5B12015B12035B12075B120F5B121F90C9FCA25A123E127E127C12FC5AA212 -7021417BB92C>I<EB03F8EB0FFE90383FFF80497F90B57E3901FE0FF03903F803F84848 -6C7EEBE0004848137EA248487FA248C7EA1F80A2003E140F007E15C0A3007C140700FC15 -E0AC6C140F007E15C0A46CEC1F80A36C6CEB3F00A26C6C137E6D13FE00075CEBF0016C6C -485A3901FE0FF06CB55A6D5B6D5BD90FFEC7FCEB03F823357CB32C>I<1307497EA2131F -A2133F137F13FF5A1207127FB5FC13DF139FEA7C1F1200B3AE007FB512E0B612F0A36C14 -E01C3477B32C>I<EB0FF890387FFF8048B512E00007804814FC391FF80FFE393FE001FF -903880007F48C7EA3F80007E141F00FE15C0150F6C15E01507A3127E123CC8FCA2150F16 -C0151F1680153F16005D15FE4A5A14034A5A4A5A4A5A4A5AECFF804948C7FC495A495A49 -5AEB3FE0EB7F8049C8FC485A4848EB03C04848EB07E0EA1FE0485A48B6FCB7FCA36C15C0 -23347CB32C>I<000FB512FE4880A35D0180C8FCADEB83FE90389FFF8090B512E015F881 -9038FE03FE9038F000FF01C07F49EB3F8090C7121F6C15C0C8120FA2ED07E0A4123C127E -B4FC150F16C0A248141F007EEC3F80007FEC7F006C6C5B6D485A391FF80FFC6CB55A6C5C -000114C06C6C90C7FCEB0FF823347CB22C>53 D<EC3FC0903801FFF801077F011F7F497F -90387FE07F9039FF003F804848137FEA03F8485A5B000FEC3F004848131E4990C7FC123F -90C9FCA25A127EEB03FE90381FFF80D8FC7F13E000FDB57EB67E9038FE07FC9038F001FE -9038C0007F49EB3F8090C7121F16C048140F16E01507A3127EA47E150F6D14C0001F141F -6D1480000F143F6DEB7F003907F801FE3903FE07FC6CB55A6C5C6D5B011F1380D907FCC7 -FC23357CB32C>I<1278B712C016E0A316C000FCC7EA3F80ED7F0015FE00785CC712014A -5A4A5A5D140F5D4A5A143F92C7FC5C147E14FE5C13015CA2495AA213075CA3495AA4495A -A5133F91C8FCAA131E23357CB32C>I<EA0F80EA1FC0EA3FE0EA7FF0A5EA3FE0EA1FC0EA -0F80C7FCAEEA0F80EA1FE0EA3FF0EA7FF8A213FCA3123F121F120F120013F8A21201EA03 -F01207EA1FE0EA7FC0EAFF80130012FC12700E3071A32C>59 D<1502ED0F80151F157F15 -FF913803FE00EC0FFCEC1FF0EC7FE0ECFF80D903FEC7FC495AEB1FF0495AEBFF80000390 -C8FCEA07FCEA1FF8EA3FE0EAFF8090C9FCA27FEA3FE0EA1FF8EA07FC6CB4FCC67FEB3FE0 -6D7EEB07FC6D7E903800FF80EC7FE0EC1FF0EC0FFCEC03FE913800FF80157F151F150FED -0200212A7BAD2C>I<007FB612F0B712F8A36C15F0CAFCA8007FB612F0B712F8A36C15F0 -25127DA12C>I<122012F87EB4FC7FEA3FE0EA1FF8EA07FC6CB4FCC67FEB3FE06D7EEB07 -FC6D7E903800FF80EC7FE0EC1FF0EC0FFCEC03FE913800FF80157FA215FF913803FE00EC -0FFCEC1FF0EC7FE0ECFF80D903FEC7FC495AEB1FF0495AEBFF80000390C8FCEA07FCEA1F -F8EA3FE0EAFF8090C9FC12FC5A1220212A7BAD2C>I<14FE497EA4497FA214EFA2130781 -A214C7A2010F7FA314C390381F83F0A590383F01F8A490387E00FCA549137E90B512FEA3 -4880A29038F8003FA34848EB1F80A4000715C049130FD87FFEEBFFFC6D5AB514FE6C15FC -497E27347EB32C>65 D<007FB512E015F8B612FE6C8016C03903F0003FED0FE0ED07F015 -03A2ED01F8A6ED03F0A21507ED0FE0ED1FC0EDFF8090B612005D5D15FF16C09039F0001F -E0ED07F0ED03F81501ED00FCA216FE167EA616FE16FC1501ED03F8150FED3FF0007FB612 -E016C0B712806CECFE0015F027337FB22C>I<02FF13700107EBE0F84913F9013F13FD49 -13FFEBFF813901FE007F4848131FD807F0130F1507485A491303485A150148C7FCA25A00 -7EEC00F01600A212FE5AAB7E127EA3007F15F06CEC01F8A26C7EA26C6C13036D14F06C6C -130716E0D803FC131F6C6CEB3FC03A00FF81FF806DB512006D5B010F5B6D13F001001380 -25357DB32C>I<007FB5FCB612C015F0816C803907E003FEEC00FFED7F80153FED1FC0ED -0FE0A2150716F0150316F81501A4ED00FCACED01F8A3150316F0A2150716E0150FED1FC0 -153FED7F80EDFF00EC03FE007FB55AB65A5D15C06C91C7FC26337EB22C>I<007FB612F0 -B712F8A37E3903F00001A7ED00F01600A4EC01E04A7EA490B5FCA5EBF003A46E5A91C8FC -A5163C167EA8007FB612FEB7FCA36C15FC27337EB22C>I<007FB612F8B712FCA37ED803 -F0C7FCA716781600A515F04A7EA490B5FCA5EBF001A46E5A92C7FCAD387FFFE0B5FC805C -7E26337EB22C>I<903901FC038090390FFF87C04913EF017F13FF90B6FC4813073803FC -01497E4848137F4848133F49131F121F5B003F140F90C7FCA2127EED078092C7FCA212FE -5AA8913803FFF84A13FCA27E007E6D13F89138000FC0A36C141FA27F121F6D133F120F6D -137F6C7E6C6C13FF6D5A3801FF076C90B5FC6D13EF011F13CF6DEB0780D901FCC7FC2635 -7DB32C>I<D87FFEEBFFFCB54813FEA36C486C13FCD807E0EB0FC0B190B6FCA59038E000 -0FB3D87FFEEBFFFCB54813FEA36C486C13FC27337EB22C>I<007FB512F8B612FCA36C14 -F839000FC000B3B3A5007FB512F8B612FCA36C14F81E3379B22C>I<D87FFCEB7FF8486C -EBFFFCA36C48EB7FF8D807C0EB1F80153FED7F00157E5D4A5A14034A5A5D4A5A4A5A143F -4AC7FC147E5CEBC1F813C3EBC7FCA2EBCFFEEBDFBEEBFFBF141F01FE7F496C7E13F86E7E -EBF00301E07FEBC001816E7EA2157E153E153F811680ED0FC0A2ED07E0D87FFCEB1FFC48 -6CEB3FFEA36C48EB1FFC27337EB22C>75 D<387FFFE0B57EA36C5BD803F0C8FCB3AE16F0 -ED01F8A8007FB6FCB7FCA36C15F025337DB22C>I<D87FE0EB0FFC486CEB1FFEA26D133F -007F15FC000F15E001BC137BA4019E13F3A3EB9F01A2018F13E3A21483A2018713C314C7 -A201831383A214EFA201811303A214FFEB80FEA3147C14381400ACD87FF0EB1FFC486CEB -3FFEA36C48EB1FFC27337EB22C>I<D87FF0EB7FFC486CEBFFFEA27F007FEC7FFCD807FE -EB07C013DEA213DF13CFA2148013C714C0A213C314E0A213C114F0A213C014F8A2147CA3 -143EA2141E141FA2140F1587A2140715C7A2140315E71401A215F71400A215FFD87FFC13 -7F487E153FA26C48EB1F8027337EB22C>I<EB7FFF0003B512E0000F14F848804880EBE0 -03EB800048C7127FA2007E80A300FE158048141FB3A86C143FA2007E1500A3007F5CA26C -6C13FEEBF00790B5FC6C5C6C5C000314E0C66C90C7FC21357BB32C>I<007FB512C0B612 -F88115FF6C15802603F00013C0153FED0FE0ED07F0A2150316F81501A6150316F01507A2 -ED0FE0ED3FC015FF90B61280160015FC5D15C001F0C8FCB0387FFF80B57EA36C5B25337E -B22C>I<EB7FFF0003B512E0000F14F848804880EBF007EB800048C7127FA2007E80A300 -FE158048141FB3A7EB01F0EB03F800FE143F267E01FC1300A2EB00FE007F5C147FD83F80 -13FEEBF03F90B5FC6C5C6C5C000314E0C67E90380007F0A26E7EA26E7EA26E7EA2157FA2 -153E21407BB32C>I<387FFFFCB67E15E015F86C803907E007FE1401EC007F6F7E151FA2 -6F7EA64B5AA2153F4BC7FCEC01FE140790B55A5D15E081819038E007FCEC01FE1400157F -81A8160FEE1F80A5D87FFEEB1FBFB5ECFF00815E6C486D5AC8EA01F029347EB22C>I<90 -381FF80790B5EA0F804814CF000714FF5A381FF01F383FC003497E48C7FC007E147F00FE -143F5A151FA46CEC0F00007E91C7FC127F7FEA3FE0EA1FFCEBFFC06C13FC0003EBFFC06C -14F06C6C7F01077F9038007FFEEC07FF02001380153FED1FC0A2ED0FE0A20078140712FC -A56CEC0FC0A26CEC1F806D133F01E0EB7F009038FE01FF90B55A5D00F914F0D8F83F13C0 -D8700790C7FC23357CB32C>I<007FB612FCB712FEA43AFC007E007EA70078153CC71400 -B3AF90383FFFFCA2497F6D5BA227337EB22C>I<3B7FFF803FFFC0B56C4813E0A36C496C -13C03B03F00001F800B3AF6D130300015DA26D130700005D6D130F017F495A6D6C485AEC -E0FF6DB5C7FC6D5B010313F86D5B9038003F802B3480B22C>I<D87FFCEB7FFC486CEBFF -FEA36C48EB7FFCD80FC0EB07E06D130F000715C0A36D131F00031580A36D133F00011500 -A36D5B0000147EA4017E5BA46D485AA490381F83F0A4010F5B14C7A301075BA214EFA201 -035BA214FFA26D90C7FCA46D5A27347EB22C>I<D87FF0EB07FF486C491380A36C486D13 -00001FC8127CA46C6C5CA76C6C495AA4143E147FA33A03E0FF83E0A214F7A201E113C3A3 -000101E35BA201F113C701F313E7A314C1A200005DA201F713F71480A301FF13FF017F91 -C7FC4A7EA4013E133E29347FB22C>I<3A3FFF03FFE0484913F0148714076C6D13E03A01 -F800FE007F0000495A13FE017E5BEB7F03013F5B1487011F5B14CF010F5B14FF6D5BA26D -90C7FCA26D5AA26D5AA2497EA2497EA2497F81EB0FCF81EB1FC7EC87F0EB3F83EC03F8EB -7F01017E7FEBFE00497F0001147E49137F000380491480151FD87FFEEBFFFC6D5AB514FE -6C15FC497E27337EB22C>I<D87FFCEB7FFC486CEBFFFEA36C48EB7FFCD807F0EB0FC015 -1F000315806D133F12016DEB7F0012006D137E017E13FE017F5BEB3F01EC81F8131FEC83 -F0EB0FC314C7903807E7E0A201035B14EF6DB45AA292C7FC7F5C147EB0903807FFE0497F -A36D5B27337EB22C>I<387FFFFCB512FEA314FC00FCC7FCB3B3B3B512FC14FEA36C13FC -17416FB92C>91 D<127012F8A27E127C127E123E123F7EA27F120F7F12077F12037F1201 -7F12007F137C137E133EA2133F7F80130F80130780130380130180130080147C147E143E -A2143F8081140F81140781140381140181140081157CA2157E153E153F811680150FA2ED -070021417BB92C>I<387FFFFCB512FEA37EC7127EB3B3B3387FFFFEB5FCA36C13FC1741 -7DB92C>I<EB07C0EB1FF0EB7FFC48B5FC000714C0001F14F0397FFC7FFC39FFF01FFEEB -C007EB0001007CEB007C003014181F0C7AAE2C>I<007FB6FCB71280A46C150021067B7D -2C>I<1338137CEA01FC1203EA07F813F0EA0FC0EA1F80A2EA3F00123E127E127CA212FC -5AA3EAFFC013E013F013F8A2127FA2123F13F0EA1FE0EA07C00E1D72B82C>I<3801FFF0 -000713FE001F6D7E15E048809038C01FF81407EC01FC381F80000006C77EC8127EA3ECFF -FE131F90B5FC1203120F48EB807E383FF800EA7FC090C7FC12FE5AA47E007F14FEEB8003 -383FE01F6CB612FC6C15FE6C14BF0001EBFE1F3A003FF007FC27247CA32C>I<EA7FF048 -7EA3127F1201AAEC1FE0ECFFF801FB13FE90B6FC16809138F07FC09138801FE091380007 -F049EB03F85BED01FC491300A216FE167EA816FE6D14FCA2ED01F86D13036DEB07F0150F -9138801FE09138E07FC091B51280160001FB5B01F813F83900F03FC027337FB22C>I<90 -3803FFE0011F13F8017F13FE48B5FC48804848C6FCEA0FF0485A49137E4848131890C9FC -5A127EA25AA8127EA2127F6C140F6DEB1F806C7E6D133F6C6CEB7F003907FE03FF6CB55A -6C5C6C6C5B011F13E0010390C7FC21247AA32C>I<EC0FFE4A7EA380EC003FAAEB07F8EB -3FFE90B512BF4814FF5A3807FC0F380FF00348487E497E48487F90C7FC007E80A212FE5A -A87E007E5CA2007F5C6C7E5C6C6C5A380FF0073807FC1F6CB612FC6CECBFFE6C143FEB3F -FC90390FF01FFC27337DB22C>I<EB03FE90381FFFC0017F13F048B57E48803907FE03FE -390FF800FFD81FE0EB3F805B4848EB1FC090C7120F5A007E15E015075AB7FCA416C000FC -C9FC7E127EA2127F6CEC03C06DEB07E06C7ED80FF0130F6C6CEB3FC001FF13FF000190B5 -12806C1500013F13FC010F13F00101138023247CA32C>I<ED03F8903907F80FFC90391F -FE3FFE017FB6FC48B7FC48ECFE7F9038FC0FF82607F003133E3A0FE001FC1CD9C0001300 -001F8049137EA66D13FE000F5CEBE0016C6C485A3903FC0FF048B5FC5D481480D99FFEC7 -FCEB87F80180C8FCA37F6C7E90B512F06C14FE48ECFF804815E04815F03A3FC0001FF848 -C7EA03FC007E1400007C157C00FC157E48153EA46C157E007E15FCD87F801303D83FE0EB -0FF8D81FFCEB7FF06CB612E0000315806C1500D8003F13F8010713C028387EA42C>103 -D<EA7FF0487EA3127F1201AAEC1FE0EC7FFC9038F9FFFE01FB7F90B6FC9138F03F80ECC0 -1F02807FEC000F5B5BA25BB3267FFFE0B5FCB500F11480A36C01E0140029337FB22C>I< -1307EB1FC0A2497EA36D5AA20107C7FC90C8FCA7387FFFC080B5FC7EA2EA0007B3A8007F -B512FCB612FEA36C14FC1F3479B32C>I<EA7FE0487EA3127F1201AA91381FFFF04A13F8 -A36E13F0913800FE004A5A4A5A4A5A4A5A4A5A4A5A4AC7FC14FEEBF1FC13F3EBF7FE90B5 -FCA2EC9F80EC0FC001FE7FEBFC07496C7E496C7E811400157E811680151F3A7FFFC0FFFC -B500E113FEA36C01C013FC27337EB22C>107 D<387FFFE0B57EA37EEA0003B3B3A5007F -B61280B712C0A36C158022337BB22C>I<3A7F83F007E09039CFFC1FF83AFFDFFE3FFCD8 -7FFF13FF91B57E3A07FE1FFC3E01FCEBF83F496C487E01F013E001E013C0A301C01380B3 -3B7FFC3FF87FF0027F13FFD8FFFE6D13F8D87FFC4913F0023F137F2D2481A32C>I<397F -F01FE039FFF87FFC9038F9FFFE01FB7F6CB6FC00019038F03F80ECC01F02807FEC000F5B -5BA25BB3267FFFE0B5FCB500F11480A36C01E0140029247FA32C>I<EB07FCEB1FFF017F -13C048B512F048803907FC07FC390FF001FE48486C7E0180133F003F158090C7121F007E -EC0FC0A348EC07E0A76C140F007E15C0A2007F141F6C15806D133F6C6CEB7F006D5B6C6C -485A3907FC07FC6CB55A6C5C6C6C13C0011F90C7FCEB07FC23247CA32C>I<397FF01FE0 -39FFF8FFF801FB13FE90B6FC6C158000019038F07FC09138801FE091380007F049EB03F8 -5BED01FC491300A216FE167EA816FE6D14FCA2ED01F86D13036DEB07F0150F9138801FE0 -9138E07FC091B51280160001FB5B01F813F8EC3FC091C8FCAD387FFFE0B57EA36C5B2736 -7FA32C>I<903903FC078090391FFF0FC0017F13CF48B512EF4814FF3807FE07380FF001 -48487E49137F4848133F90C7FC48141F127E150F5AA87E007E141FA26C143F7F6C6C137F -6D13FF380FF0033807FC0F6CB6FC6C14EF6C6C138F6D130FEB07F890C7FCAD0203B5FC4A -1480A36E140029367DA32C>I<D87FFEEB3FC0B53801FFF0020713F8021F13FC6C5B3900 -3F7FE1ECFF019138FC00F84A13704A13005CA25C5CA391C8FCAF007FB512E0B67EA36C5C -26247EA32C>I<90387FF8700003B512F8120F5A5A387FC00F387E00034813015AA36CEB -00F0007F140013F0383FFFC06C13FE6CEBFF80000314E0C66C13F8010113FCEB0007EC00 -FE0078147F00FC143F151F7EA26C143F6D133E6D13FE9038F007FC90B5FC15F815E000F8 -148039701FFC0020247AA32C>I<131E133FA9007FB6FCB71280A36C1500D8003FC8FCB1 -ED03C0ED07E0A5EC800F011FEB1FC0ECE07F6DB51280160001035B6D13F89038003FE023 -2E7EAD2C>I<3A7FF003FF80486C487FA3007F7F0001EB000FB3A3151FA2153F6D137F39 -00FE03FF90B7FC6D15807F6D13CF902603FE07130029247FA32C>I<3A3FFF03FFF04801 -8713F8A36C010313F03A00FC007E005D90387E01F8013F5BEB1F83EC87E090380FCFC090 -3807EF80EB03FF6D90C7FC5C6D5A147C14FE130180903803EF80903807CFC0EB0FC7EC83 -E090381F01F0013F7FEB7E00017C137C49137E0001803A7FFF01FFFC1483B514FE6C15FC -140127247EA32C>120 D<3A7FFF01FFFCB5008113FE148314816C010113FC3A03E0000F -806C7E151F6D140012005D6D133E137C017E137E013E137CA2013F13FC6D5BA2EB0F815D -A2EB07C1ECC3E0A2EB03E3ECE7C0130114F75DEB00FFA292C7FC80A2143EA2147E147CA2 -14FC5CA2EA0C01003F5BEA7F83EB87E0EA7E0F495A387FFF806C90C8FC6C5A6C5AEA07E0 -27367EA32C>I<15FF02071380141F147F91B512004913C04AC7FCEB03F85CB31307EB1F -E013FF007F5BB55A49C8FC6D7E6C7FC67F131FEB07F01303B380EB01FEECFFC06D13FF6E -1380141F14070200130021417BB92C>123 D<127812FCB3B3B3A9127806416DB92C>I<EA -7FC0EAFFF813FE6D7E6C7FC67F131FEB07F01303B380EB01FEECFFC06D13FF6E1380141F -147F91B512004913C04AC7FCEB03F85CB31307EB1FE013FF007F5BB55A49C8FC13F8EA7F -C021417BB92C>I E -%EndDVIPSBitmapFont -%DVIPSBitmapFont: Fe ecti1000 10 33 -/Fe 33 122 df<EE3FFC4BB51280923907E007C092391F8001E0DB3F0013F0037E13034B -1307A24A5A18E04A48EB038094C7FCA314075DA4140F5DA3010FB7FCA25F903A001F8000 -7EA217FE023F5C92C7FCA216015F5C147E16035FA214FE4A13075FA30101140F5F4AECC1 -C0A2161F1783010316805CA2EF870013074A5CEE0F8EEE079EEE03FC010FEC00F04A91C7 -FCA35C131FA2001C90CAFC127E5BEAFE3E133C137CEAF878EA78F0EA3FE0EA0F80344C82 -BA2F>28 D<150C151C153815F0EC01E0EC03C0EC0780EC0F00141E5C147C5C5C495A1303 -495A5C130F49C7FCA2133EA25BA25BA2485AA212035B12075BA2120F5BA2121FA290C8FC -A25AA2123EA2127EA2127CA412FC5AAD1278A57EA3121C121EA2120E7EA26C7E6C7EA212 -001E5274BD22>40 D<140C140E80EC0380A2EC01C015E0A2140015F0A21578A4157C153C -AB157CA715FCA215F8A21401A215F0A21403A215E0A21407A215C0140F1580A2141F1500 -A2143EA25CA25CA2495AA2495A5C1307495A91C7FC5B133E133C5B5B485A12035B48C8FC -120E5A12785A12C01E527FBD22>I<4B7EA3150393C8FCA35D1506A3150E150CA3151C15 -18A315381530A31570B912E0A2C80060C8FC15E05DA314015DA3140392C9FCA35C1406A3 -140E140CA3141C1418A2333275AD40>43 D<EA03C0EA07F0120F121F13F8A313F0EA07B0 -EA003013701360A213E013C01201EA038013005A120E5A5A5A5A5A0D197A8819>I<120E -EA3F80127F12FFA31300127E123C0909778819>46 D<0103B612FEEFFFC018F0903B0007 -F8000FF84BEB03FCEF00FE020F157FF03F804B141F19C0021F150F19E05D1807143F19F0 -5DA2147FA292C8FCA25C180F5CA2130119E04A151FA2130319C04A153FA201071780187F -4A1600A2010F16FEA24A4A5A60011F15034D5A4A5D4D5A013F4B5A173F4A4AC7FC17FC01 -7FEC03F84C5A91C7EA1FC04949B45A007F90B548C8FCB712F016803C397CB83F>68 -D<0103B512F8A390390007F8005DA2140FA25DA2141FA25DA2143FA25DA2147FA292C7FC -A25CA25CA21301A25CA21303A25CA21307A25CA2130FA25CA2131FA25CA2133FA25CA213 -7FA291C8FC497EB6FCA25C25397CB820>73 D<0107B512FCA25E9026000FF8C7FC5D5D14 -1FA25DA2143FA25DA2147FA292C8FCA25CA25CA21301A25CA21303A25CA21307A25CA213 -0F170C4A141CA2011F153C17384A1478A2013F157017F04A14E01601017F140317C091C7 -1207160F49EC1F80163F4914FF000102071300B8FCA25E2E397BB834>76 -D<ED03FE92383FFFC09238FC07F0913903E001F891390F80007C023FC77E027E8002F815 -804948EC0FC0EB07E04948EC07E0131F4A15F049C81203137E01FE16F8485AA2485AA248 -5AA2120F5B001F16075B123FA34848ED0FF0A448C9EA1FE0A3EF3FC0A21880177F18005F -5F16015F6C4B5A4C5AA24C5A6C4B5A6D4A5A001F93C7FC6D147E000F5D6C6CEB03F06C6C -495A6C6CEB0F806C6C013FC8FC90383F01FC90381FFFE0010190C9FC353D74BA40>79 -D<ED03FE92383FFFC09238FC07F0913903E001F891390FC0007C023FC77E027E804A1580 -D901F0EC0FC013074948EC07E0495A4A15F049C8FC49150301FE16F8485AA2485AA2485A -A2120F491507121FA2485AA34848ED0FF0A448C9EA1FE0A3EF3FC0A21880177F4817005F -5F16015F007F4B5A5F91380F800791393FE00FE06C903970601FC0902680E0305B261F81 -C049C7FC913880187ED80FC35C3A07E30019F00003EC1FE0D801FB14806CB46C48C8FC90 -263F81FC13186DB45A01010138133890C7003C1330177017F05FED3E03ED3F07EEFFC05F -A294C7FC5E6F5A6F5AED07E0354B74BA40>81 D<92383FC00E913901FFF01C020713FC91 -391FC07E3C91393F001F7C027CEB0FF84A130749481303495A4948EB01F0A2495AA2011F -15E091C7FCA34915C0A36E90C7FCA2806D7E14FCECFF806D13F015FE6D6D7E6D14E00100 -80023F7F14079138007FFC150F15031501A21500A2167C120EA3001E15FC5EA3003E4A5A -A24B5AA2007F4A5A4B5A6D49C7FC6D133ED8F9F013FC39F8FC03F839F07FFFE0D8E01F13 -8026C003FCC8FC2F3D7ABA2F>83 D<0007B812E0A25AD9F800EB001F01C049EB07C0485A -D900011403121E001C5C003C17801403123800785C00701607140700F01700485CA2140F -C792C7FC5DA2141FA25DA2143FA25DA2147FA292C9FCA25CA25CA21301A25CA21303A25C -A21307A25CA2130FA25CEB3FF0007FB512F8B6FCA2333971B83B>I<14F8EB07FE90381F -871C90383E03FE137CEBF801120148486C5A485A120FEBC001001F5CA2EA3F801403007F -5C1300A21407485C5AA2140F5D48ECC1C0A2141F15831680143F1587007C017F1300ECFF -076C485B9038038F8E391F0F079E3907FE03FC3901F000F0222677A42A>97 -D<133FEA1FFFA3C67E137EA313FE5BA312015BA312035BA31207EBE0F8EBE7FE9038EF0F -80390FFC07C013F89038F003E013E0D81FC013F0A21380A2123F1300A214075A127EA214 -0F12FE4814E0A2141F15C05AEC3F80A215005C147E5C387801F8007C5B383C03E0383E07 -C0381E1F80D80FFEC7FCEA01F01C3B77B926>I<147F903803FFC090380FC1E090381F00 -70017E13784913383901F801F83803F003120713E0120FD81FC013F091C7FC485AA2127F -90C8FCA35A5AA45AA3153015381578007C14F0007EEB01E0003EEB03C0EC0F806CEB3E00 -380F81F83803FFE0C690C7FC1D2677A426>I<ED01F815FFA3150316F0A21507A216E0A2 -150FA216C0A2151FA21680A2153FA202F81300EB07FE90381F877F90383E03FF017C5BEB -F80112013803F00048485B120FEBC001121F5DEA3F801403127F01005BA214075A485CA2 -140FA248ECC1C0A2141F15C3ED8380143F1587007C017F1300ECFF076C485B9038038F8E -391F0F079E3907FE03FC3901F000F0253B77B92A>I<147F903803FFC090380FC1E09038 -3F00F0017E13785B485A485A485A120F4913F8001F14F0383F8001EC07E0EC1F80397F81 -FF00EBFFF8148090C8FC5A5AA55AA21530007C14381578007E14F0003EEB01E0EC03C06C -EB0F806CEB3E00380781F83803FFE0C690C7FC1D2677A426>I<ED07C0ED1FF0ED3E38ED -7C3CEDF8FC15F9140115F1020313F8EDF0F0160014075DA4140F5DA4141F5D010FB512C0 -5B16809039003F800092C7FCA45C147EA414FE5CA413015CA413035CA413075CA4130F5C -A3131F5CA391C8FC5B121CEA7E3EA2EAFE3C137C1378EAF8F01278EA3FC0EA0F80264C82 -BA19>I<EC07C0EC3FF09138FC38E0903901F01FF0EB03E0903807C00FEB0F80011F1307 -D93F0013E05B017E130F13FE4914C01201151F1203491480A2153F1207491400A25DA249 -137EA215FEA25D00031301140314076C6C485A0000131FEB787BEB3FF390380FC3F0EB00 -031407A25DA2140F5D121C007E131F5D00FE49C7FC147E5C387801F8387C07E0381FFF80 -D803FEC8FC24367CA426>I<EB03F0EA01FFA3EA00075CA3130F5CA3131F5CA3133F91C8 -FCA35B90387E07F0EC1FFCEC783E9038FFE01F02C01380EC800F1400485A16C05B49EB1F -8012035BA2153F000715005BA25D000F147E5B15FE5D121FD98001131C15F8163C003F01 -031338010013F0A216704814E0007E15F016E0EDE1C000FE903801E38048903800FF0000 -38143C263B7BB92A>I<EB01C0EB07E014F0130F14E01307EB038090C7FCAB13F0EA03FC -EA071EEA0E1F121CA212385B1270A25BEAF07E12E013FEC65AA212015B1203A25B12075B -A2000F13E013C013C1001F13C01381A2EB83801303EB0700A2130E6C5AEA07F8EA01E014 -3879B619>I<EB0FC0EA07FFA3EA001F1480A2133FA21400A25BA2137EA213FEA25BA212 -01A25BA21203A25BA21207A25BA2120FA25BA2121FA25BA2123FA290C7FCA25AA2EA7E0E -A212FE131EEAFC1CA2133C133812F81378EA7870EA7CE0121FEA0F80123B79B915>108 -D<D801E001FEEB07F03C07F803FF801FFC3C0E3C0F07C0783E3C1E3E3C03E1E01F261C1F -78D9F3C013803C383FF001F7800F02E01400007801C013FE007018C002805B4A4848EB1F -80EAF07FD8E07E5CA200000207143F01FE1700495CA2030F5C0001177E495C18FE031F5C -120349DA8001131C18F8033F153C00070403133849020013F0A24B1570000F17E049017E -15F019E003FEECE1C0001FEE01E34949903800FF000007C70038143C3E2679A444>I<D8 -01E013FE3A07F803FF803A0E3C0F07C03A1E3E3C03E0261C1F787F39383FF00114E00078 -13C000708114804A485AEAF07FEAE07EA20000140701FE5C5BA2150F00015D5B151F5E12 -034990383F8380160316070007027F130049137EA2160E000F147C49141E161C5E001FEC -3C7849EB1FE00007C7EA0780292679A42F>I<147F903803FFC090380FC1F090381F00F8 -017E137C5B4848137E4848133E0007143F5B120F485AA2485A157F127F90C7FCA215FF5A -4814FEA2140115FC5AEC03F8A2EC07F015E0140F007C14C0007EEB1F80003EEB3F00147E -6C13F8380F83F03803FFC0C648C7FC202677A42A>I<9039078007C090391FE03FF09039 -3CF0787C903938F8E03E9038787FC00170497EECFF00D9F0FE148013E05CEA01E113C15C -A2D80003143FA25CA20107147FA24A1400A2010F5C5E5C4B5A131F5EEC80035E013F495A -6E485A5E6E48C7FC017F133EEC70FC90387E3FF0EC0F8001FEC9FCA25BA21201A25BA212 -03A25B1207B512C0A3293580A42A>I<3903C003F0390FF01FFC391E783C0F381C7C703A -3C3EE03F8038383FC0EB7F800078150000701300151CD8F07E90C7FCEAE0FE5BA2120012 -015BA312035BA312075BA3120F5BA3121F5BA3123F90C9FC120E212679A423>114 -D<14FE903807FF8090380F83C090383E00E04913F00178137001F813F00001130313F0A2 -15E00003EB01C06DC7FC7FEBFFC06C13F814FE6C7F6D13807F010F13C01300143F141F14 -0F123E127E00FE1480A348EB1F0012E06C133E00705B6C5B381E03E06CB45AD801FEC7FC -1C267AA422>I<EB0380EB07C0130FA4131F1480A3133F1400A35B137E007FB5FCA2B6FC -3800FC00A312015BA312035BA312075BA3120F5BA3121FEB801CA2143C003F1338EB0078 -147014F014E0EB01C0EA3E03381F0780380F0F00EA07FCEA01F0183579B31C>I<01F013 -0ED803FC133FD8071EEB7F80EA0E1F121C123C0038143F49131F0070140FA25BD8F07E14 -0000E08013FEC6485B150E12015B151E0003141C5BA2153C000714385B5DA35DA24A5A14 -0300035C6D48C7FC0001130E3800F83CEB7FF8EB0FC0212679A426>118 -D<903907E007C090391FF81FF89039787C383C9038F03E703A01E01EE0FE3803C01F0180 -13C0D8070014FC481480000E1570023F1300001E91C7FC121CA2C75AA2147EA214FEA25C -A21301A24A1370A2010314F016E0001C5B007E1401010714C000FEEC0380010F1307010E -EB0F0039781CF81E9038387C3C393FF03FF03907C00FC027267CA427>120 -D<13F0D803FCEB01C0D8071EEB03E0D80E1F1307121C123C0038140F4914C01270A24913 -1FD8F07E148012E013FEC648133F160012015B5D0003147E5BA215FE00075C5BA214015D -A314035D14070003130FEBF01F3901F87FE038007FF7EB1FC7EB000F5DA2141F003F5C48 -133F92C7FC147E147C007E13FC387001F8EB03E06C485A383C1F80D80FFEC8FCEA03F023 -3679A428>I E -%EndDVIPSBitmapFont -%DVIPSBitmapFont: Ff cmsy10 10 1 -/Ff 1 16 df<EB1FF0EBFFFE487F000714C04814E04814F04814F8A24814FCA3B612FEA9 -6C14FCA36C14F8A26C14F06C14E06C14C0000114006C5BEB1FF01F1F7BA42A>15 -D E -%EndDVIPSBitmapFont -%DVIPSBitmapFont: Fg ecbx1000 10 36 -/Fg 36 119 df<913803FFC0027F13F00103B512FC010FEB00FED93FF8133FD97FE0EBFF -8049485A5A1480484A13C04A6C1380A36F1300167E93C7FCA592383FFFC0B8FCA4000390 -C7FCB3ABB5D8FC3F13FFA4303A7EB935>28 D<B61280A819087F9620>45 -D<EA0F80EA3FE0EA7FF0A2EAFFF8A5EA7FF0A2EA3FE0EA0F800D0D798C1B>I<141E143E -14FE1307137FB5FCA3138FEA000FB3B3A5007FB61280A4213679B530>49 -D<EB0FFE90387FFFC048B512F0000714FC390FE03FFF261F800F1380263F000313C0D87F -8014E0EBE00100FF6D13F07FA2ED7FF8A46C5A6C5A0006C7FCC8FCEDFFF0A216E05C16C0 -4A138016004A5A4A5AEC1FF05D4A5A4AC7FC14FE495AD903F01378495A495A495A49C712 -F8017C14F05B49130148B6FC5A5A5A5A5A4815E0B7FCA425367BB530>I<EC0FF8ECFFFE -0103EBFF8090390FF80FC090393FE003E090397F8001F09038FF000F48EC1FF84848133F -485A120F5B121FA2003FEC1FF0ED0FE0484890C7FCA31408EC7FF039FFF1FFFC01F313FF -D9F78013809039FF007FC049EB3FE04914F0ED1FF85B16FCA34914FEA4127FA5123F16FC -A26C7E16F8000F143F6D14F0000715E06C6CEB7FC03A01FF81FF806C90B51200013F13FC -010F13F00101138027377CB530>54 D<EA0F80EA3FE0EA7FF0A2EAFFF8A5EA7FF0A2EA3F -E0EA0F80C7FCABEA0F80EA3FE0EA7FF0A2EAFFF8A5EA7FF0A2EA3FE0EA0F800D2579A41B ->58 D<B812C017FC17FF18C028007FF000037F04007F717E717E171F84A2717EA74D5AA2 -60173F4D5A4D5A4C13C0040F5B91B600FCC7FCA2EFFF8002F0C713F0EF3FF8717E717E71 -7E19807113C0A319E0A719C0A25F4D138019005FEF7FFE4C485AB912F018C095C7FC17F0 -3B397DB844>66 D<DB3FFCEB01C00203B5EAC003021FECF00791B6EAFC0F01039039FC00 -FF3F4901C0EB1FFFD91FFEC77E49481403D97FF080494880485B48177F4849153F4890C9 -FC181F485A180F123F5B1807127FA24993C7FC12FFAD127F7FF003C0123FA27F001F1707 -A26C6C1780180F6C6D16006C6D5D6C173E6C6D157ED97FF85D6D6C4A5A6DB44A5A010701 -C0EB0FE06D01FCEBFF80010090B548C7FC021F14F8020314E09126003FFEC8FC3A3B7BB9 -45>I<B87E17F817FF18C028007FF8000713F09338007FF8EF1FFE717E050313807113C0 -A27113E0F07FF0A2F03FF8A219FC181FA219FEA419FFAC19FEA419FC183FA219F8187F19 -F0F0FFE0A24D13C04D13804D1300EF1FFEEF7FFC933807FFF0B912C095C7FC17FC178040 -397DB849>I<B612FCA439007FF800B3B3ADB612FCA41E397DB824>73 -D<B7FCA426007FF8C9FCB3ACEF0780A5170F1800A35FA25FA25F5F5E5EEE0FFE167FB8FC -A431397DB839>76 D<B500F80403B512F06E5EA26E5ED8007FF1E000A2D97BFF161EA201 -796D5DA201786D5DA26E6C5DA36E6C4A5AA26E6C4A5AA26E6C4A5AA26E6C4A5AA26E6C14 -1EA36E6D5BA26E6D5BA26F6C5BA26F6C485AA36F6C485AA26F6C485AA26F6C48C7FCA292 -3803FF1EA36F13BCA26F13F8A2705AA2705AA213FCB500FC6D4848B612F0A2EE0F80EE07 -0054397DB85B>I<B500FC0203B512F0A28080C66C6D90390003F0006F6E5A81017B7F13 -798101787F6E7E6E7E6E7F6E7FA26E7F6E7F6E7F6E7F6F7E153F826F13806F13C06F13E0 -6F13F06F13F88117FCEE7FFEEE3FFF7013817013C17013E18218F17013F97013FDEF7FFF -8383A28383838383187FA2183F181F01FC160FB500FC150718031801A244397DB84B>I< -EDFFF8020FEBFF80027F14F0903A01FFC01FFC010790380007FFD91FFC010113C0D93FF0 -6D6C7E49486E7E49486E7E48496E7E48834890C86C7EA248486F1380A248486F13C0A200 -3F18E0A348486F13F0A400FF18F8AC007F18F06D5DA3003F18E0A26D5D001F18C0A26C6C -4B13806C18006E5C6C6D4A5A6C5F6C6D4A5A6D6C4A5AD93FFC49485A6DB401075B0107D9 -C01F90C7FC010190B512FC6D6C14F0020F1480020001F8C8FC3D3B7BB948>I<B8FC17F0 -17FEEFFF8028007FF8000F13C0040113E07013F0EF7FF8EF3FFCA2EF1FFEA218FFA818FE -A2EF3FFCA2EF7FF8EFFFF04C13E0040F13C091B7120017FC17E002F8C9FCB3A4B612FCA4 -38397DB841>I<EDFFF8020FEBFF80027F14F0903A01FFE03FFC010790380007FFD91FFC -010113C049486D7FD97FE0EC3FF049486E7E488348496E7E4890C86C7EA248486F1380A2 -001F18C04981003F18E0A3007F18F04981A300FF18F8AC007F18F0A36D5D003F18E0A36C -6C4B13C0A2000FDA1FC014806C6C90267FF0071300EDFFF86C903A81F07C0FFE6C903AC3 -C01E1FFC6CDA800F5BD97FE3ECBFF0D93FF36DB45AD91FFF5D010701C091C7FC01019038 -F01FFC6D6CB500F01308020F6E131C0200EBF9FC92260001FE133C9438FF80FC18FF8219 -F8A28319F0A27113E0A27113C0711380711300EF01FC3E4A7BB948>I<D907FF130E013F -EBE01E90B5EAF83E0003ECFE7E3A07FC01FFFE390FF0001F4848130F4848130349130100 -7F140090C8FC167E5A163EA27F161E7F7F6D91C7FC13FC387FFFE014FEECFFF06C14FE6F -7E6C816C15F06C816C81C681133F010F801301D9000F1480EC007F030F13C01503818100 -F0157FA3163FA27E17807E167F6C16007E6D14FE01E0495A01F813039039FF801FF800FC -90B512E0D8F83F5CD8F00749C7FC39E0007FF02A3B7BB935>83 D<B600FC011FB512C0A4 -26007FF8C8381FC000725AB3B3181F013F94C7FC8060011F163E6D6C157E187C6D6C15FC -6D6D495A6D6DEB07F06D01F0EB1FE0DA7FFEEBFFC0021FB6C8FC02075C020014F0030F13 -80423A7DB849>85 D<B600F00103B512E0A4C601F0C83807F0006E5E017F5F6E150FA201 -3F5F6E151F011F94C7FC6E5D6D163E6F147E6D167CA26F14FC6D5E6F13016D5E6F13036D -5E811707027F5D6F130F023F5D6F131F021F92C8FC815F6E143EEE807E6E147CEEC0FC6E -5C16E016E16E5C16F36E5C16FF6F5BA36F5BA26F90C9FCA26F5AA36F5AA26F5AA26F5A43 -3A7EB848>I<B6D8E01FB500FC90383FFFFCA4000101F0C7D83FFCC8EA7E006C71153C17 -1F6E197C017F701578836E7014F8013F6F5E6E1801011F4B6D5CA26E18036D4B6D5CA26D -6D496D495A173C6F170F6D037C6D91C7FCEF787F6F5F6D4B6C6C131E816D02016E5BEFE0 -1F03F8177C027F01036E13784D7E03FCEE80F8023F49486C5C15FE021F010FEDC1E04D7E -03FF16C36E49EDE3C0041E7F049E15F76E01BC6D5C04FC15FF6E95C8FC4C80A26E5F4C14 -3F6E5F4C141FA2037F5E4C140FA26F486E5AA2031F5E93C812036F5E5E3A7EB863>I<13 -FFB5FCA412077EAF4AB47E020F13F0023F13FC9138FE03FFDAF00013804AEB7FC00280EB -3FE091C713F0EE1FF8A217FC160FA217FEAA17FCA3EE1FF8A217F06E133F6EEB7FE06E14 -C0903AFDF001FF80903AF8FC07FE009039F03FFFF8D9E00F13E0D9C00390C7FC2F3A7EB9 -35>98 D<EE7F80ED7FFFA4150381AF903801FF81010F13F1013F13FD9038FFC07F0003EB -001FD807FC1307000F8048487F5B123FA2485AA312FFAA127FA27F123FA26C6C5B000F5C -6C6C5B6C6C4913C02701FF80FD13FE39007FFFF9011F13E1010113012F3A7DB935>100 -D<903803FF80011F13F0017F13FC3901FF83FE3A03FE007F804848133F484814C0001FEC -1FE05B003FEC0FF0A2485A16F8150712FFA290B6FCA301E0C8FCA4127FA36C7E1678121F -6C6C14F86D14F000071403D801FFEB0FE06C9038C07FC06DB51200010F13FC010113E025 -257DA42C>I<EC1FF0903801FFFC010713FF90391FF87F8090383FE0FFD9FFC113C0A248 -1381A24813016E1380A2ED3E0092C7FCA8B6FCA4000390C8FCB3ABB512FEA4223A7DB91D ->I<161FD907FEEBFFC090387FFFE348B6EAEFE02607FE07138F260FF801131F48486C13 -8F003F15CF4990387FC7C0EEC000007F81A6003F5DA26D13FF001F5D6C6C4890C7FC3907 -FE07FE48B512F86D13E0261E07FEC8FC90CAFCA2123E123F7F6C7E90B512F8EDFF8016E0 -6C15F86C816C815A001F81393FC0000F48C8138048157F5A163FA36C157F6C16006D5C6C -6C495AD81FF0EB07FCD807FEEB3FF00001B612C06C6C91C7FC010713F02B377DA530>I< -EA01F0EA07FC487EA2487EA56C5AA26C5AEA01F0C8FCA913FF127FA412077EB3A9B512F8 -A4153B7DBA1B>105 D<13FFB5FCA412077EAF92380FFFE0A4923803FC0016F0ED0FE0ED -1F804BC7FC157E5DEC03F8EC07E04A5A141FEC7FE04A7E8181A2ECCFFEEC0FFF496C7F80 -6E7F6E7F82157F6F7E6F7E82150F82B5D8F83F13F8A42D3A7EB932>107 -D<13FFB5FCA412077EB3B3ACB512FCA4163A7DB91B>I<01FED97FE0EB0FFC00FF902601 -FFFC90383FFF80020701FF90B512E0DA1F81903983F03FF0DA3C00903887801F000749DA -CF007F00034914DE6D48D97FFC6D7E4A5CA24A5CA291C75BB3A3B5D8FC1FB50083B512F0 -A44C257DA451>I<01FEEB7FC000FF903803FFF8020F13FE91381F03FFDA3C0113800007 -13780003497E6D4814C05CA25CA291C7FCB3A3B5D8FC3F13FFA430257DA435>I<903801 -FFC0010F13F8017F13FFD9FF807F3A03FE003FE048486D7E48486D7E48486D7EA2003F81 -491303007F81A300FF1680A9007F1600A3003F5D6D1307001F5DA26C6C495A6C6C495A6C -6C495A6C6C6CB45A6C6CB5C7FC011F13FC010113C029257DA430>I<9038FE03F000FFEB -0FFEEC3FFF91387C7F809138F8FFC000075B6C6C5A5CA29138807F80ED3F00150C92C7FC -91C8FCB3A2B512FEA422257EA427>114 D<90383FF0383903FFFEF8000F13FF381FC00F -383F0003007E1301007C130012FC15787E7E6D130013FCEBFFE06C13FCECFF806C14C06C -14F06C14F81203C614FC131F9038007FFE140700F0130114007E157E7E157C6C14FC6C14 -F8EB80019038F007F090B512C000F8140038E01FF81F257DA426>I<130FA55BA45BA25B -5BA25A1207001FEBFFE0B6FCA3000390C7FCB21578A815F86CEB80F014816CEBC3E09038 -3FFFC06D1380903803FE001D357EB425>I<B539F001FFF8A4000390C7EA1F00161E6E13 -3E6C153C6E137C6C15786E13F8017F5CECF001013F5C14F8011F495AA2ECFC07010F5CEC -FE0F010791C7FC6E5A6D131E15BE6D13BC15FC6D5BA36E5AA26E5AA26E5AA26E5AA22D25 -7EA432>118 D E -%EndDVIPSBitmapFont -%DVIPSBitmapFont: Fh ecrm1000 10 89 -/Fh 89 126 df<486C1360000314E039070001C0000EEB038048EB070000181306003813 -0E0030130C0070131C00601318A200E01338481330A400CEEB338039FF803FE001C013F0 -A3007F131FA2393F800FE0390E0003801C1981B91C>16 D<001C1307007FEB1FC039FF80 -3FE0A201C013F0A3007F131F001CEB073000001300A400011470491360A2000314E090C7 -12C048130100061480000E130348EB070048130E485B006013181C1980B91C>I<B81280 -A2290280962A>21 D<DA0FF813FC91397FFF07FF903B01F807DF83C0903A07E001FF0F90 -3B1F8007FE1FE090393F000FFC137E16F85B9338F007804848010790C7FC1503ACB812F8 -A32801F80003F0C7FCB3AB486C497E267FFFE0B512F0A3333B7FBA30>27 -D<EC0FF8EC7FFE903901F80780903907E001C090391F8000E090383F0007017E497EA25B -A2485A6F5AED018092C8FCA9ED03F0B7FCA33901F8000F1503B3AA486C497E267FFFE0B5 -12C0A32A3B7FBA2E>I<DA0FF0EB1FF0DA7FFEEBFFFC903B01F80F83F00F903C07E001CF -C00380903C1F8000FF0001C090273F0007FE130F017E4948497EA2495CA248485C03076E -5A03030203C7FC95C8FCA9F007E0BAFCA33C01F80003F0001F1807B3AA486C496C497E26 -7FFFE0B500C1B51280A3413B7FBA45>30 D<EB0380A3EB0FF0EB7FFE48B512803903F38F -C03907C381E0390F8380F0D81F031338123E003C141C007C140C150E0078143E00F814FE -1481A400FCEB80FC157800FE140012FF127F13C313E3EA3FFF6C7F14F86C13FE6CEBFF80 -000114C06C14E0013F13F01303ECBFF8148FEC83FC1481A2EC80FE157E123C12FF153EA4 -12FE00F8143C00E0147C12600070147815F8003814F0003C1381001EEB83E0000FEB87C0 -3907E39F803901FFFE006C5BEB1FE0EB0380A41F437BBD2A>36 D<141FEC7FC0903801F0 -E0903803C0600107137090380F803090381F00381518A25BA2133E133F15381530A21570 -5D5D140190381F838092CAFC1487148E02DC49B51280EB0FF85C4A9039003FF8000107ED -0FC06E5D71C7FC6E140E010F150CD91DFC141C01391518D970FE143801E015302601C07F -1470D803805D00076D6C5BD80F00EBC00148011F5C4890380FE003003E6E48C8FC007E90 -3807F8060203130E00FE6E5A6E6C5A1400ED7F706C4B13036F5A6F7E6C6C6D6C5B701306 -6C6C496C130E6DD979FE5B281FF001F07F133C3C07F80FE03FC0F86CB539800FFFF0C690 -26FE000313C0D91FF0D9007FC7FC393E7DBB41>38 D<121C127FEAFF80A213C0A3127F12 -1C1200A412011380A2120313005A1206120E5A5A5A12600A1979B917>I<146014E0EB01 -C0EB0380EB0700130E131E5B5BA25B485AA2485AA212075B120F90C7FCA25A121EA2123E -A35AA65AB2127CA67EA3121EA2121F7EA27F12077F1203A26C7EA26C7E1378A27F7F130E -7FEB0380EB01C0EB00E01460135278BD20>I<12C07E12707E7E7E120F6C7E6C7EA26C7E -6C7EA21378A2137C133C133E131EA2131F7FA21480A3EB07C0A6EB03E0B2EB07C0A6EB0F -80A31400A25B131EA2133E133C137C1378A25BA2485A485AA2485A48C7FC120E5A5A5A5A -5A13527CBD20>I<1530B3A8B912FCA2C80030C8FCB3A836367BAF41>43 -D<121C127FEAFF80A213C0A3127F121C1200A412011380A2120313005A1206120E5A5A5A -12600A19798817>I<B512FCA516057F941C>I<121C127FEAFF80A5EA7F00121C09097988 -17>I<1506A2150E150CA2151C151815381530A215701560A215E015C0A214011580A214 -0315005C1406A2140E140CA2141C1418A214381430A21470146014E05CA213015CA21303 -91C7FCA25B1306A2130E130C131C1318A213381330A213701360A213E05BA212015B1203 -90C8FCA25A1206A2120E120CA2121C1218A21238123012701260A212E05AA21F537BBD2A ->I<EB03F8EB1FFF90387E0FC09038F803E03901E000F0484813780007147C48487FA248 -C77EA2481580A3007EEC0FC0A500FE15E0B3007E15C0A4007F141F6C1580A36C1500A26C -6C133EA26C6C5B6C6C5BEBF0013900F803E090387E0FC0D91FFFC7FCEB03F823397DB62A ->I<EB01C013031307131F13FFB5FCA2131F1200B3B3A7497E007FB512F0A31C3779B62A> -I<EB0FF0EB7FFE48B57E3903E03FE0390F000FF0001E6D7E001C6D7E486D7E5A6E7E1260 -12FE6CEC7F807FA56CC7FC121CC8FCEDFF00A25D14015D14035D4A5A4A5A5D4A5A4AC7FC -147E5C495A14E0495A495A49C8FC011EEB01805B5B49130348481400485A485A90C75A48 -B6FC5A5A485CB6FCA321377CB62A>I<EB07F8EB3FFF90B512C03901F80FF03903C007F8 -48486C7E390E0001FEEA0F80391FE000FF7FA56C5A6C5AC7485AA25D14035D4A5A5DEC0F -80027FC7FCEB1FFCECFF809038000FE06E7EEC01FC816E7EED7F80A216C0A2153F16E0A2 -121EEA7F80A2487EA316C0157F491480007EC7FC0070ECFF006C495A121E390F8003F839 -07F00FF00001B512C06C6C90C7FCEB0FF823397DB62A>I<1538A2157815F8A214011403 -1407A2140F141F141B14331473146314C313011483EB030313071306130C131C13181330 -1370136013C01201EA038013005A120E120C5A123812305A12E0B712F8A3C73803F800AA -4A7E0103B512F8A325387EB72A>I<0006140CD80780133C9038F003F890B5FC5D5D1580 -92C7FC14FC38067FE090C9FCAAEB07F8EB1FFE9038780F809038E007E03907C003F0496C -7E130000066D7E81C8FC8181A21680A4121C127F5A7FA390C713005D12FC00605C12704A -5A6C5C6C1303001E495A6C6C485A3907E03F800001B5C7FC38007FFCEB1FE021397CB62A ->I<EC3FC0903801FFF0010713FC90380FE03E90383F800790387E001F49EB3F80484813 -7F485A12075B000FEC3F0049131E001F91C7FC5B123FA3127F90C9FCEB01FC903807FF80 -39FF1E07E090383801F0496C7E01607F01E0137E497F16805BED1FC0A390C713E0A57EA4 -7F123F16C0A2001FEC3F807F000F15006D5B000714FE6C6C5B6C6C485A3900FE07F09038 -7FFFC0011F90C7FCEB03FC23397DB62A>I<12301238123E003FB612E0A316C05A168016 -000070C712060060140E5D5D00E014304814705D5DC712014A5A4AC7FC1406140E5CA25C -1478147014F05C1301A213035C1307A2130FA3131F5CA2133FA5137FA96DC8FC131E233A -7BB72A>I<EB03F8EB1FFF017F13C09038FC07F03901E001F83903C0007C4848133C90C7 -123E48141E000E141F001E80A3121FA26D5B6D131E7FD80FF85B6D137C01FF13786C6D5A -6CEBE3E0ECF780C601FFC7FC6D5A6D6C7E010F13E0013F7F01F97F3901E07FFE48486C7E -380F800F48486C1380001E010113C0487F007C143F0078EC1FE0150F00F81407481403A2 -1501A36C15C0A200781403007C15806C14076CEC0F006C6C131ED807E0137C3903F803F0 -C6B55A013F1380D907FCC7FC23397DB62A>I<EB03F8EB1FFF017F13C03901FC07E04848 -6C7E3907E001F8000F6D7E4848137E5B003F80A248C71380A25AED1FC0A516E0A56C143F -A36C7E157F121F6C6C13FF6C6C13DF000313013901F0039F3900FC0F1FD93FFC13C0EB07 -F090C7FCA2153F1680A216005D120F486C137E486C5BA24A5A4A5A49485A381F000F001C -EB1F80260F807FC7FC3807FFFE000113F838003FC023397DB62A>I<121C127FEAFF80A5 -EA7F00121CC7FCB2121C127FEAFF80A5EA7F00121C092479A317>I<121C127FEAFF80A5 -EA7F00121CC7FCB2121C127FEAFF80A213C0A3127F121C1200A412011380A2120313005A -1206120E5A5A5A12600A3479A317>I<EF01C0EF0780EF1E0017F8EE03E0040FC7FC163C -16F0ED03C0030FC8FC153CEC01F0EC07C0021EC9FC1478EB01E0EB0780011ECAFC13F8EA -03E0000FCBFC123C12F0A2123C120FEA03E0EA00F8131EEB0780EB01E0EB0078141EEC07 -C0EC01F0EC003C150FED03C0ED00F0163C160FEE03E0EE00F8171EEF0780EF01C0322E79 -AB41>I<007FB812F8B912FCCCFCB0B912FC6C17F836147B9E41>I<12E01278121EEA07C0 -EA01F0EA003C130FEB03C0EB00F0143C140FEC03E0EC00F8151EED0780ED01E0ED007816 -1EEE07C0EE01F0EE003C170FEF03C0A2EF0F00173CEE01F0EE07C0041EC7FC1678ED01E0 -ED0780031EC8FC15F8EC03E0020FC9FC143C14F0EB03C0010FCAFC133CEA01F0EA07C000 -1ECBFC127812E0322E79AB41>I<EB3FE03801FFFE3907C03F80390E000FC0003CEB07F0 -00301303007014F8007C130100FE14FC7EA4127E003CEB03F8C7FCEC07F0A2EC0FE0EC1F -80EC3F00147E147C5C495A5C495A5CA249C7FCA31306AA90C8FCA8130EEB3F80497EA56D -5A010EC7FC1E3B7CBA27>I<1538A3157CA315FEA34A7EA34A6C7EA202077FEC063FA202 -0E7FEC0C1FA2021C7FEC180FA202387FEC3007A202707FEC6003A202C07F1501A2D90180 -7F81A249C77F167FA20106810107B6FCA24981010CC7121FA2496E7EA3496E7EA3496E7E -A213E0707E1201486C81D80FFC02071380B56C90B512FEA3373C7DBB3E>65 -D<B712E016FC16FF0001903980007FC06C90C7EA1FE0707E707E707EA2707EA283A75F16 -035F4C5A4C5A4C5A4C5AEEFF8091B500FCC7FCA291C7EA7F80EE1FE0EE07F0707E707E83 -707EA21880177F18C0A7188017FFA24C13005F16034C5AEE1FF8486DEB7FF0B812C094C7 -FC16F832397DB83B>I<913A01FF800180020FEBE003027F13F8903A01FF807E07903A03 -FC000F0FD90FF0EB039F4948EB01DFD93F80EB00FF49C8127F01FE153F12014848151F48 -48150FA248481507A2485A1703123F5B007F1601A35B00FF93C7FCAD127F6DED0180A312 -3F7F001F160318006C7E5F6C7E17066C6C150E6C6C5D00001618017F15386D6C5CD91FE0 -5C6D6CEB03C0D903FCEB0F80902701FF803FC7FC9039007FFFFC020F13F002011380313D -7BBA3C>I<B712C016F816FE000190398001FF806C90C7EA3FE0EE0FF0EE03F8707E707E -177FA2EF3F8018C0171F18E0170F18F0A3EF07F8A418FCAC18F8A4EF0FF0A218E0A2171F -18C0EF3F80A2EF7F0017FE4C5A4C5AEE0FF0EE3FE0486DEBFF80B8C7FC16F816C036397D -B83F>I<B812FEA3000190388000076C90C8FC173F838383A383A31880170116C0A394C7 -FCA31501A21503150F91B5FCA3EC000F15031501A21500A21860A318E093C712C0A41701 -A3EF0380A21707A2170F173F177F486D903807FF00B9FCA333397EB838>I<B812F8A300 -01903880001F6C90C71201EE00FC177C173C171CA2170CA4170E1706A2ED0180A21700A4 -1503A21507151F91B5FCA3EC001F15071503A21501A692C8FCAD4813C0B612C0A32F397D -B836>I<DBFF8013C0020FEBF001023F13FC9139FF803F03903A03FC000787D90FF0EB03 -CF4948EB00EF4948147F4948143F49C8121F485A4848150F48481507A248481503A2485A -1701123F5B007F1600A448481600AB93B6FCA26C7E9338007FE0EF3FC0A2123F7F121FA2 -6C7EA26C7EA26C7E6C7E6C6C157F6D7E6D6C14FF6D6C14EFD90FF8EB03C7D903FEEB0783 -903A00FFC03F0191393FFFFC00020F01F0130002001380383D7CBA41>I<B648B512FEA3 -0001902680000313006C90C76C5AB3A491B6FCA391C71201B3A6486D497EB648B512FEA3 -37397DB83E>I<B612C0A3C6EBC0006D5AB3B3AD497EB612C0A31A397EB81E>I<013FB512 -E0A39039001FFC00EC07F8B3B3A3123FEA7F80EAFFC0A44A5A1380D87F005B0070131F6C -5C6C495A6C49C7FC380781FC3801FFF038007F80233B7DB82B>I<B649B5FCA300010180 -9038007FF06C90C8EA3F80053EC7FC173C17385F5F4C5A4C5A4CC8FC160E5E5E5E5E4B5A -ED0780030EC9FC5D153E157E15FF5C4A7F4A6C7E140E4A6C7E4A6C7E14704A6C7E4A6C7E -14804A6C7E6F7EA26F7F707EA2707E707EA2707EA2707E707EA2707E707F8484486D497F -B6011FEBFF80A339397DB841>I<B612E0A3000101C0C8FC6C90C9FCB3AD1718A5173817 -30A31770A317F0A216011603160FEE1FE0486D13FFB8FCA32D397DB834>I<B5933807FF -F86E5DA20001F0FC002600DFC0ED1BF8A2D9CFE01533A3D9C7F01563A3D9C3F815C3A2D9 -C1FCEC0183A3D9C0FEEC0303A2027F1406A36E6C130CA36E6C1318A26E6C1330A36E6C13 -60A26E6C13C0A3913901FC0180A3913900FE0300A2ED7F06A3ED3F8CA2ED1FD8A3ED0FF0 -A3486C6D5A487ED80FFC6D48497EB500C00203B512F8A2ED018045397DB84C>I<B59138 -07FFFE8080C69238007FE06EEC1F80D9DFF0EC0F001706EBCFF8EBC7FCA2EBC3FEEBC1FF -A201C07F6E7EA26E7E6E7E81140F6E7E8114036E7E168080ED7FC016E0153FED1FF0ED0F -F8A2ED07FCED03FEA2ED01FF6F1386A2EE7FC6EE3FE6A2EE1FF6EE0FFEA216071603A216 -011600A2177E486C153E487ED80FFC151EB500C0140EA2170637397DB83E>I<EC03FF02 -1F13E09138FE01FC903901F8007ED907E0EB1F8049486D7ED93F80EB07F049C76C7E01FE -6E7E48486E7E49157E0003167F4848ED3F80A24848ED1FC0A2001F17E049150F003F17F0 -A3007F17F8491507A300FF17FCAC007F17F86D150FA3003F17F0A26C6CED1FE0A36C6CED -3FC0000717806D157F000317006C6C15FEA26C6C4A5A017F4A5A6D6C495A6D6C495AD907 -E0EB1F80D903F8017FC7FC903900FE01FC91381FFFE0020390C8FC363D7BBA41>I<B712 -C016FC16FF0001D9800013C06C90C7EA1FE0707EEE03F883707EA2707EA21880A71800A2 -4C5AA24C5A5FEE0FF04C5AEEFF8091B548C7FC16F091CAFCB3A5487FB6FCA331397EB838 ->I<EC03FF021F13E09138FE01FC903901F8007ED907E0EB1F8049486D7ED93F80EB07F0 -49C76C7E01FE6E7E48486E7EA24848157F0007178049153F000F17C049151F001F17E0A2 -4848ED0FF0A3007F17F8A2491507A200FF17FCAC007F17F8A26D150FA2003F17F0A26C6C -ED1FE0A36C6CED3FC00007027C14804AB4FC3C03F80383807F003B01FC0701C0FEEC0E00 -2600FE0CEBE1FC017FEC63F8D93F8CEB77F0D91FCCEB3FE0D907EE14806DB449C7FC0100 -D981FC130CEC1FFF0203131C91C7001E131C161F183CEF807CEFC0F8EE0FFFA318F08218 -E07013C07013809338007E00364B7BBA41>I<B612FEEDFFE016F8000190388007FE6C90 -C76C7EEE3FC0707E707E707EA2707EA283A65FA24C5AA24C5A4C5AEE3F8004FFC8FCED07 -FC91B512E05E9138000FF0ED03F8ED00FE82707E707EA2161F83A583A6F00180A217F816 -0F1803486D01071400B66D6C5A04011306933800FE0ECAEA3FFCEF07F0393B7DB83D>I< -D90FF813C090383FFE0190B512813903F807E33907E000F74848137F4848133F48C7121F -003E140F007E1407A2007C140312FC1501A36C1400A37E6D14006C7E7F13F86CB47E6C13 -F8ECFF806C14E06C14F86C14FEC680013F1480010714C0EB007F020713E0EC007FED3FF0 -151F150FED07F8A200C01403A21501A37EA216F07E15036C15E06C14076C15C06C140F6D -EB1F80D8FBF0EB3F00D8F0FE13FE39E03FFFF8010F13E0D8C00190C7FC253D7CBA2E>I< -003FB812E0A3D9C003EB001F273E0001FE130348EE01F00078160000701770A300601730 -A400E01738481718A4C71600B3B0913807FF80011FB612E0A335397DB83C>I<B6903807 -FFFEA3000101809038007FE06C90C8EA1F80EF0F001706B3B2170E6D150C80171C133F17 -186D6C14385F6D6C14F06D6C5C6D6C495A6D6CEB07806D6C49C7FC91387F807E91381FFF -F8020713E09138007F80373B7DB83E>I<B500FC91387FFF80A30003018091380FFC006C -90C8EA07E0715A6C705A6E1403017F93C7FCA280013F1506A26E140E011F150C80010F5D -A28001075DA26E147001031560A26D6C5CA2806D4A5AA2ED8003027F91C8FCA291383FC0 -06A215E0021F5BA2EDF01C020F1318A26E6C5AA215FC02035BA2EDFEE002015BA26E6C5A -A36FC9FCA3153EA2151CA3393B7EB83E>I<B5D8FC07B5D8F001B5FCA30007902780001F -FEC7EA1FF86C48C7D80FF8EC07E000010307ED03C01B807F6C6F6C1500A26E5F017F6E6C -1406A280013F4A6C5CA280011F4A6D5BEE067FA26D6C010E6D5BEE0C3FA26D6C011C6D5B -EE181FA26D6C6F5BEE300FA26D6C6F485AEE6007A26D6C4CC7FC9338C003FCA203805D91 -3B7F818001FE06A203C1150EDA3FC3C7EAFF0CA203E3151CDA1FE6EC7F98A215F6DA0FFC -EC3FF0A302075E4B141FA202035E4B140FA202015E4B1407A2020093C8FC4B80503B7EB8 -55>I<B500FE91383FFFE0A3000301E0913807FE00C649EC03F0017F6F5A606D6C5D6D6C -140395C7FC6D6C1406A26D6C5C6D6C141C17186D6C143817306D6D5B6E6C13E05F91383F -E0015F91381FF003DA0FF890C8FC1606913807FC0E160C913803FE1C913801FF185E6E13 -B016E0157F6F5AB3A24B7E023FB512C0A33B397FB83E>89 D<003FB7FCA39039FC0001FE -01C0130349495A003EC7FC003C4A5A5E0038141F00784A5A12704B5A5E006014FF4A90C7 -FCA24A5A5DC712074A5AA24A5A5D143F4A5AA24A5A92C8FC5B495AA2495A5C130F4948EB -0180A2495A5C137F495A16034890C7FC5B1203485AEE0700485A495C001F5D48485C5E48 -48495A49130FB8FCA329397BB833>I<EAFFFCA2EAFC00B3B3B3B3A7EAFFFCA20E5379BD -17>I<EAFFFCA21200B3B3B3B3A712FFA20E537FBD17>93 D<007FB81280B912C0A26C17 -803204797041>95 D<EB1FE0EBFFFC3803E03F3907000F80390F8007E0486C6C7E13E06E -7EA26E7E6C5A6C5AC8FCA4147FEB07FFEB3FE0EBFE00EA03F8EA0FF0EA1FC0123F485A90 -C7FC160C12FEA31401A26C13036CEB077C903980063E18383FC01E3A0FE0781FF03A03FF -F00FE03A007F8007C026277DA52A>97 D<EA03F012FFA3120F1203B0EC1FE0EC7FF89038 -F1E03E9039F3801F809039F7000FC001FEEB07E049EB03F049EB01F85BED00FCA216FEA2 -167E167FAA167E16FEA216FC15016D14F8ED03F07F01EEEB07E001C6EB0FC09039C7801F -00903881E07E903800FFF8C7EA1FC0283B7EB92E>I<EB03FC90381FFF8090387E03E039 -01F80070484813F83907E001FC380FC003A2EA1F80123F90380001F848EB00F01500A212 -7E12FEAA127E127FA26C14067F001F140E6D130C000F141C6C6C13386C6C13706C6C13E0 -39007C07C090381FFF00EB07F81F277DA525>I<ED0FC0EC03FFA3EC003F150FB0EB03F8 -EB1FFF90387E078F9038F801EF3903F0007F4848133F4848131FA24848130F123F90C7FC -5AA2127E12FEAA127E127FA27EA26C6C131FA26C6C133F6C6C137F6C6CEBEFF03A01F801 -CFFF39007C078F90381FFE0FD907F813C0283B7DB92E>I<EB07F8EB1FFF90387C0FC039 -01F803E03903F001F0D807E013F8380FC0004848137CA248C7127E153E5A153F127E12FE -A3B7FCA248C8FCA5127EA2127FA26C14037F001F14076C6C13060007140E6D131CD801F0 -13386C6C137090387E03E090381FFF80903803FC0020277EA525>I<147E903803FF8090 -380FC1E0EB1F8790383F0FF0137EA213FCA23901F803C091C7FCADB512FCA3D801F8C7FC -B3AB487E387FFFF8A31C3B7FBA19>I<ED03F090390FF00FF890393FFC3C3C9039F81F70 -7C3901F00FE03903E007C03A07C003E010000FECF000A248486C7EA86C6C485AA200075C -6C6C485A6D485A6D48C7FC38073FFC38060FF0000EC9FCA4120FA213C06CB512C015F86C -14FE6CECFF804815C03A0F80007FE048C7EA0FF0003E140348140116F8481400A56C1401 -007C15F06CEC03E0003F1407D80F80EB0F80D807E0EB3F003901FC01FC39007FFFF00107 -90C7FC26387EA52A>I<EA03F012FFA3120F1203B0EC0FF0EC3FFCECF03F9039F1C01F80 -9039F3800FC0EBF70013FE496D7EA25BA35BB3A3486C497EB500C1B51280A3293A7EB92E ->I<EA0380EA0FE0487EA56C5AEA0380C8FCAAEA03F012FFA312071203B3AA487EB512C0 -A312387EB717>I<EB01C0EB07F0EB0FF8A5EB07F0EB01C090C7FCAAEB01F813FFA31307 -1301B3B3A2123C127E00FF13F01303A214E038FE07C0127C383C0F00EA0FFEEA03F81549 -84B719>I<EA03F012FFA3120F1203B1913801FFFCA39138007FC01600157C15705D4A5A -4A5A4AC7FC141E1438147814FC13F1EBF3FEEBF73F01FE7FEBF81F496C7E8114076E7E6E -7E811400157E157F811680ED1FC0486CEB3FF0B500C0B5FCA3283A7EB92C>I<EA03F012 -FFA3120F1203B3B3AD487EB512C0A3123A7EB917>I<2703F00FF0EB1FE000FFD93FFCEB -7FF8913AF03F01E07E903BF1C01F83803F3D0FF3800FC7001F802603F70013CE01FE14DC -49D907F8EB0FC0A2495CA3495CB3A3486C496CEB1FE0B500C1B50083B5FCA340257EA445 ->I<3903F00FF000FFEB3FFCECF03F9039F1C01F803A0FF3800FC03803F70013FE496D7E -A25BA35BB3A3486C497EB500C1B51280A329257EA42E>I<EB03FE90380FFF8090383E03 -E09038F800F84848137C48487F48487F4848EB0F80001F15C090C712074815E0A2007EEC -03F0A400FE15F8A9007E15F0A2007F14076C15E0A26C6CEB0FC0000F15806D131F6C6CEB -3F006C6C137EC66C13F890387E03F090381FFFC0D903FEC7FC25277EA52A>I<3903F01F -E000FFEB7FF89038F1E07E9039F3801F803A07F7000FC0D803FEEB07E049EB03F04914F8 -49130116FC150016FEA3167FAA16FEA3ED01FCA26DEB03F816F06D13076DEB0FE001F614 -C09039F7803F009038F1E07E9038F0FFF8EC1FC091C8FCAB487EB512C0A328357EA42E> -I<D903F813C090381FFE0190387E07819038FC01C33903F000E300071477484813374913 -3F001F141F485A150F48C7FCA312FEAA127FA37E6D131F121F6D133F120F6C6C137F6C6C -13EF3901F801CF39007E078F90381FFE0FEB07F890C7FCABED1FE00203B5FCA328357DA4 -2C>I<3807E01F00FFEB7FC09038E1E3E09038E387F0380FE707EA03E613EE9038EC03E0 -9038FC0080491300A45BB3A2487EB512F0A31C257EA421>I<EBFF03000313E7380F80FF -381E003F487F487F00707F12F0A2807EA27EB490C7FCEA7FE013FF6C13E06C13F86C7F00 -037FC67F01071380EB007F141F00C0EB0FC01407A26C1303A37E15806C13077EEC0F00B4 -131E38F3C07C38E1FFF038C03F801A277DA521>I<1318A51338A31378A313F812011203 -1207001FB5FCB6FCA2D801F8C7FCB215C0A93800FC011580EB7C03017E13006D5AEB0FFE -EB01F81A347FB220>I<D803F0EB07E000FFEB01FFA3000FEB001F00031407B3A4150FA3 -151F12016D133F0000EC77F86D9038E7FF8090383F03C790381FFF87903A03FC07E00029 -267EA42E>I<B538803FFEA33A0FF8000FF06C48EB07E00003EC03C06D148000011500A2 -6C6C1306A26D130E017E130CA26D5BA2EC8038011F1330A26D6C5AA214E001075BA29038 -03F180A3D901FBC7FCA214FF6D5AA2147CA31438A227257EA32C>I<B53A1FFFE03FFEA3 -260FF8009038000FF86C48017EEB03E018C00003023EEB0180A26C6C013FEB0300A36C6C -EC8006156FA2017E9038EFC00C15C7171CD93F01EBE01815830281EBF038D91F83143015 -0102C3EBF87090260FC6001360A2D907E66D5A02EC137CA2D903FCEB7F804A133FA20101 -92C7FC4A7FA20100141E4A130E0260130C37257EA33C>I<B538807FFFA33A03FE003FF0 -0001EC1F80000092C7FC017E131C6D13186D6C5AECC070010F5B6D6C5AECF180EB03FB6D -B4C8FC6D5AA2147F804A7E8114CF903801C7E090380383F090380703F8EB0601496C7E01 -1C137E49137F01787F496D7E486C80000FEC3FF0D8FFFE90B51280A329247FA32C>I<B5 -38803FFEA33A0FF8000FF06C48EB07C00003EC03806C7E16007F00001406A2017E5BA213 -7F6D5BA26D6C5AA2ECC070010F1360A26D6C5AA214F101035BA2D901FBC7FCA214FF6D5A -A2147CA31438A21430A214701460A25CA2EA7C0100FE5B130391C8FC1306EAFC0EEA701C -6C5AEA1FF0EA0FC027357EA32C>I<003FB512FCA2EB8003D83E0013F8003CEB07F00038 -EB0FE012300070EB1FC0EC3F800060137F150014FE495AA2C6485A495AA2495A495A495A -A290387F000613FEA2485A485A0007140E5B4848130C4848131CA24848133C48C7127C48 -EB03FC90B5FCA21F247EA325>I<EC01F8140FEC3F80ECFC00495A495A495AA2130F5CB3 -A7131F5C133F49C7FC13FEEA03F8EA7FE048C8FCEA7FE0EA03F8EA00FE137F6D7E131F80 -130FB3A7801307A26D7E6D7E6D7EEC3F80EC0FF814011D537ABD2A>I<126012F0B3B3B3 -B3A91260045377BD17>I<12FCEAFFC0EA07F0EA01FCEA007E7F80131F80130FB3A78013 -07806D7E6D7EEB007EEC1FF0EC07F8EC1FF0EC7E00495A495A495A5C130F5CB3A7131F5C -133F91C7FC137E485AEA07F0EAFFC000FCC8FC1D537ABD2A>I E -%EndDVIPSBitmapFont -%DVIPSBitmapFont: Fi ecbx1440 14.4 34 -/Fi 34 118 df<EE7FFC031FB57E4AB612E0020715F8023F9038C00FFC913AFFFC0001FE -4901F0EB007F010701C0EB03FF4949497F4990C75A5B5C495A4D7F01FF6F5B5CA27190C7 -FC715AEF00F895C8FCAA0407B512C0BAFCA5C601F8C7120F83B3B3A6B6D8F807B612C0A5 -42547DD349>28 D<B712E0AB230B7F9F2C>45 D<151E153E15FE1403140F147FEB07FF00 -03B5FCB6FCA3EBF87FEAFC00C7FCB3B3B3A6007FB712FCA52E4E76CD42>49 -D<EC1FFE49B512F0010F14FC013FECFF804915E02701FF803F7F2703FC000713FCD807F0 -01017F48486D7FD81F806E138048C87E7013C0D87FE016E001F8806D16F000FF817F7013 -F8A56C5AA26C5A6C5AEA0380C914F05EA218E05E18C05E18804C13005F4C5A4C5A5F4B5B -4B5B4B5B94C7FCED0FFC4B5A4B5AED7FC04B5A4A90C8FCEC03FC4A5A4A4814F84A5A4A5A -4AC8FC02FEEC01F0495A495A495A5CD90F80140349C8FC013E1507017FB7FC90B812E05A -5A5A5A5A5A5AB9FC18C0A4354E7ACD42>I<913807FFC0027F13FC0103B67E010F15E090 -261FF80313F890267FC0007F01FEC7EA3FFE48488148486E138013FE486C6C6D13C08048 -17E080A66C5B18C06C5B6C90C75AD80038168090C8FC4C1300A24C5A5F4C5A4B5B4B13C0 -030F5BDB7FFEC7FC91387FFFF816C016FCEEFF80DA000313E09238007FF8EE3FFE707E70 -138018C07013E018F07013F8A218FC82A218FEA3EA03C0EA0FF0EA3FFC487EA2B5FCA218 -FCA25E18F8A26C4816F0495C4916E0D83FE04A13C06C485CD80FF04A1380D807FE91387F -FE003B03FFE003FFFC6C90B65A6C6C15E0010F92C7FC010114FCD9001F1380374F7BCD42 ->I<17FC1601A216031607160FA2161F163F167FA216FF5D5DA25D5D5D167F153E157E15 -FC15F8EC01F01403EC07E015C0EC0F80141FEC3F00143E5C14FC495A5C495A1307495A5C -49C7FC5B137E137C5B1201485A5B485A120F485A90C8FC123E127E5ABA1280A5C901FCC7 -FCAF021FB71280A5394F7CCE42>I<486C150601F0153E01FEEC01FED9FFF0133F91B65A -5F5F5F5F5F94C7FC16FC5E16E093C8FC15FC01F0138091CAFCAC913807FF80023F13F891 -B512FE01F36E7E9026FFFC0113E09139E0007FF891C76C7E496E7E01F86E7E5B70138049 -16C0C9FC18E08218F0A418F8A31203EA0FE0EA3FF8487EA212FF7FA218F0A25B5E6C4816 -E05B01C016C06CC85A18806C6C4A13007FD80FF04A5A6C6CECFFFCD803FE4913F02701FF -E00F5B6C6CB612806D92C7FC010F14F8010114C09026003FFCC8FC354F7ACD42>I<EA07 -E0EA1FF8EA3FFCEA7FFEA2B5FCA6EA7FFEA2EA3FFCEA1FF8EA07E0C7FCB3A3EA07E0EA1F -F8EA3FFCEA7FFEA2B5FCA6EA7FFEA2EA3FFCEA1FF8EA07E0103576B425>58 -D<932603FFF01407047F01FF5C0307B600E05B033F03F85B92B700FE5B02039126C003FF -5B020F01F8C7EA3FC1023F01C0EC0FE391B5C80003B5FC4901FC814949814901E082011F -498249498292CA7E4948834948835A4A83485B4885A2484984A2485B87A2485B87A25AA2 -98C8FC91CFFCA2B5FCAE7E067FB7128080A37E95C76C90C7FC807EA36C7FA26C7FA26C7F -7E806C7F137F6D7E816D6D93B5FC01077F6D01F85D6D7F6D01FF5D023F01E0EC0FEF020F -01FCEC3FE30203903AFFE001FF81020091B6C6FC033F03FC133F030703F0130FDB007F02 -801303040301F8CAFC595479D267>71 D<B81280A5D8000701F0C7FCB3B3B3B2B81280A5 -29527DD130>73 D<B812E0A5D8000F01E0CAFCB3B3A91AF8A419011AF0A51903A31907A2 -190F1AE0191FA2193F197F19FF60180760187F0503B5FCBB12C0A545527CD14F>76 -D<B600F84BB612FC818181A2D800076E91C7383FE00070EE0F80828214DF02CF7F02C77F -8202C37F14C102C0806F7F836F7F816F7F6F7F83816F7F6F80707F8482707F707F707F84 -82707F7080717F8583717F717F85717F83717F7114801AC07213E0847213F07213F81AFC -7213FE847213FF72148F1BCF7313EF857313FF85A285858585A286868686A286868686EB -1FF0B600FE177F1B3F1B1F1B0FA25E527CD167>78 D<B912FCF0FFE019FE737E1AE0D800 -0F01E0C7003F7F060313FC06007F737E7313807313C07313E0851BF0A21BF885A21BFCA9 -1BF8A3611BF0A21BE04F13C0614F13804F13004F5A060713F8063F5B92B812C097C7FC19 -F8198003E0CBFCB3AEB712FEA54E527CD15A>80 D<93381FFF800303B512FC033FECFFC0 -92B712F00207D9F80113FE021F903AC0003FFF804A48C700077FDAFFF8020113F049496E -7F49496F7E49496F7E49496F7E4990C96C7F4948707F4948707F01FF854849707F4A8248 -86A24849717E48864A83A2481B80A248497113C0A4481BE0A291CB7EA3B51AF0AF6C1BE0 -A36E5FA26C1BC0A36C1B806E5FA26C1B006E5F6C62A26C6DD903FC4A5A6CDB0FFF5D6E49 -EBC0016C4B01E05C6D6C90277E07F0035B6E9039F801F807902A3FFF01F000780F5B6D04 -7C5C6DD981E06D4890C7FC6D01E191381F7FFE010101F1EDFFF86DD9F9F06D5BDA3FFF16 -C06E6D013F5B02079027FE01FFFEC8FC020190B612F8DA003F4B141003071838DB001FEB -83F893C7EA03FC1C7885726C14F8F2C003F2F01F97B512F084A31CE085A27314C01C8085 -1C00735B735B735B735B9638003FC0556A79D263>I<B912E018FF19F019FE737ED80007 -01F0C714E0060F7F060313FC06007F737E737F8587737FA28785A287A863A26163636163 -4F90C8FC4F5A4F5A06035B060F13E095B5128092B748C9FC19F019C019F09226F0000713 -FC050013FF063F7F727F727F727F727FA2727FA28486A886A71D707513F8A2851C017301 -C013F0A273EBE003B86C6D9038F007E0739038FC1FC0070190B51280736C1400080F5BCE -13F85D537CD162>I<DA0FFE141C91B500F0133C010702FC137C011F02FF13FC017F15C1 -9026FFF00113E148903980001FFB4890C7EA07FFD807FC14014848804848153F171F4848 -150FA2007F1607491503A2170112FFA217007FA26D167CA27F7F6D93C7FC6C7E14C014F8 -ECFF806C14F8EDFFC06C15FC6CEDFF8017F06C16FC6C826C707E6C836D82011F82010782 -13016D6C81020781EC007F030380ED003F040314801600173F837113C0838312F883A383 -7EA319807EA26C5E19007F6D4B5A7F6D4B5A01FC4B5A6D151FD9FFC04A5AD97FF8ECFFE0 -28FE1FFF80075B010790B6C7FCD8FC0115FC486C6C14F048010F14C0489026007FFCC8FC -3A5479D249>I<003FBB12FCA59126C0007FEB000301FCC7ED003FD87FF0F00FFE491807 -49180349180190C81600A2007E1A7EA3007C1A3EA500FC1A3F481A1FA6C91700B3B3AC49 -B912C0A550517BD05B>I<EC3FFE0107B512E0011F14FC017F14FF2701FFC00F13C02703 -FE00037F486C01007F6E6D7E486D80707EA2707EA3707F6C5B6C90C7FC6C5AC9FCA60307 -B5FC0203B6FC147F0103B7FC011FEBF00F017F1300EBFFFC000313F04813C0485B4890C7 -FC5A5B485AF081F012FF5BA35EA26D5C127F6D5C003F03F713C36DD901E314E06CD9C007 -14FF00079026F01F8114C06C90B5C61480C602FC6D1300011F01F0EB3FFC01010180EB07 -F03C387CB642>97 D<913803FFE0023F13FE91B67E010315E0010F9038003FF8D93FFCEB -07FC4948497E4948131F4849497E485B485BA24890C7FC5A5B003F6F5A705A705A007F92 -C8FC5BA312FFAD127F7FA3123F7F6CEE0F80A26C6D141F18006C6D5C6C6D143E6C6D147E -6C6D5C6D6C495A6DB4EB07F0010F9038C01FE06D90B5128001014AC7FCD9003F13F80203 -138031387CB63A>99 D<943803FF80040FB5FCA5EE003F170FB3A4913803FF80023F13F8 -49B512FE0107ECFF8F011F9038C03FEF90273FFE0007B5FCD97FF8130149487F48498048 -4980484980488291C8FC5A5B123FA2127F5BA312FFAD127FA37F123FA3121F7F6C5E6C6D -5C5F6C6D91B5FC6C6D5B6C6D4914E0D97FFCD90FEFEBFF80D91FFFEB7F8F010790B5120F -010114FC6D6C13E00207010049C7FC41547CD249>I<913807FF80027F13F849B512FE01 -076E7E011F010313E0903A3FFC007FF0D97FF06D7E49486D7E4849130F48496D7E488248 -90C77E1880485A82003F17C0A3485A18E082A212FFA290B8FCA401FCCAFCA6127FA37F12 -3FA2EF03E06C7E17076C17C06C6D140F18806C6D141F6C6DEC3F006C6D147ED97FFC495A -D91FFFEB07F86D9038E03FF0010390B512C001005D023F01FCC7FC020113E033387CB63C ->I<ED1FF8913803FFFE020FEBFF80023F14C09139FFF83FE001039038E0FFF049138049 -010113F85BEB3FFEA2EB7FFCA26F13F0495AEE7FE0EE1F8093C7FCAEB712C0A5C601F8C8 -FCB3B3A7B612FEA52D547CD328>I<DA1FFE14FE49B539E007FF80010FDAFC1F13C0013F -DAFF7F13E090267FF807EBFF072701FFE001EBF07F48497E484990387FF83F91C7003F14 -C048EEFC1F489338FE070049021F90C7FCA2003F82A9001F5EA26D143F6C5E6C5E6E137F -6C6D495A6C6D485B6CD9F80713804890B6C8FCD803EF14FC01C114E02707C01FFEC9FC49 -CBFCA2487EA37FA27F13FC90B612FE6CEDFFF017FCEFFF806C8318F06C836C837F48B87E -1207D80FFCC700037F4848EC003F4848150F48486F138083485A83A56D5D007F18006D5D -003F5F6C6C4B5A01FE153FD807FFED7FF06C01C049485AC601FC011F1380013FB648C7FC -010F15F8010115C0D9000F01F8C8FC3B4F7CB542>I<EB3FF8B5FCA51203C6FCB3A4EE1F -FC93B57E030314E0030F14F892391FC07FFC92397E003FFE03F86D7EECF9F04B6D7FECFB -C0ECFF8092C76C7FA25CA25CA45CB3ACB6D8F807B612C0A542537CD249>I<133FEBFFC0 -487F487FA2487FA66C5BA26C5B6C5B013FC7FC90C8FCAEEB1FF8B5FCA512017EB3B3A6B6 -12F0A51C547CD324>I<EB3FF8B5FCA51203C6FCB3B3B3B1B612F8A51D537CD224>108 -D<D93FF0D91FF84AB47EB591B56C010F13F8030302E0013F13FE030F6E90B6FCDB3F8090 -27F803F80F7F922A7E007FFC07E0077F000302F890283FFE0F80037FC6D9F1F0011F4948 -7EDAF3E0DAFF3E814B153CDAF7805D92C76C496D7F14FF4A5EA24A5EA34A5EB3ADB6D8F8 -0FB66CB612F8A565367BB56E>I<D93FF0EB1FFCB591B57E030314E0030F14F892391FC0 -7FFC92397E003FFE000302F86D7EC6EBF1F04B6D7FECF3C0ECF78092C76C7F14FF5CA25C -A45CB3ACB6D8F807B612C0A542367CB549>I<913801FFC0023F13FE91B67E010315E001 -0F018013F8903A3FFC001FFED97FF0EB07FF49486D7F48496D7F48496D7F91C8127F4883 -488349153F001F83A2003F8349151FA2007F83A400FF1880AC007F1800A3003F5F6D153F -A2001F5FA26C6C4B5AA26C6D4A5A6C5F6C6D495B6C6D495B6D6C4990C7FCD93FFCEB1FFE -6DB46CB45A010790B512F0010115C0D9003F49C8FC020313E039387CB642>I<D93FF8EB -7FF0B50107B5FC031F14C0037F14F09126F9FF0013FCDAFFF8EB3FFF000302E0010F7FC6 -02806D7F92C76C7F4A824A804A6E7F85187F85A2183F85A4721380AD4E1300A44E5AA261 -18FF616E5C616E4A5B6E4A5B6F495B03E04990C7FC6FEB7FFE913AF9FE01FFF802F8B65A -033F14C0030749C8FC030013E093CAFCB1B612F8A5414D7DB549>I<90393FF001FCB590 -380FFF804B13E0037F13F09238FE1FF89138F1F83F00019138F07FFC6CEBF3E015C0ECF7 -80A2ECFF00EE3FF84AEB1FF0EE0FE093C7FC5CA45CB3ABB612FEA52E367DB535>114 -D<903903FFC00E011FEBFC1E90B6127E000315FE3907FE003FD80FF0130F484813034848 -1301491300127F90C8127EA248153EA27FA27F01F091C7FC13FCEBFF806C13FEECFFF06C -14FE6F7E6C15E06C816C15FC6C81C681133F010F15801301D9000F14C0EC003F030713E0 -150100F880167F6C153FA2161F7EA217C07E6D143F17807F6DEC7F0001F85C6DEB03FE90 -39FF801FFC486CB512F0D8F81F14C0D8F00791C7FC39E0007FF02B387CB634>I<147CA6 -14FCA41301A31303A21307A2130F131F133F137F13FF1203000F90B512FEB7FCA426007F -FCC8FCB3A9EE0F80ABEE1F006D7EA2011F143E806D6D5A6DEBC1F86DEBFFF001005C023F -1380DA03FEC7FC294D7ECB33>I<D93FF8913801FFC0B50207B5FCA50003ED001FC61607 -B3AE5FA35FA25F137F5F6D6C14F7DC01E713F06D6CD907C7EBFFC0903A0FFF801F876D90 -B51207010114FC6D6C13F0020701C091C7FC42377CB549>I E -%EndDVIPSBitmapFont -%DVIPSBitmapFont: Fj ecrm0900 9 5 -/Fj 5 109 df<123C127E12FFA4127E123C08087A8715>46 D<EB7F803803FFF0380F80 -FC381C003E003F133F6D6C7E6E7EA26E7EEA1F00C7FCA4EB01FF131FEBFF873803FC07EA -0FF0EA1FC0EA3F80127F13004815C05AA3140FA26C131F6C133B3A3F8071F180391FC1E1 -FF2607FFC013003900FE003C22237DA126>97 D<EA03F012FFA312071203AEEC3F80ECFF -E09038F3C0F89038F7007E01FE7F49EB1F8049EB0FC05BED07E016F0A2150316F8AA16F0 -150716E0A2ED0FC07F6DEB1F8001ECEB3F0001CF137C90388381F8903801FFE0C76CC7FC -25357EB32B>I<EA03F012FFA312071203AEEC1FC0EC7FF09038F1E0FC9038F3807C9038 -F7007E13FE497FA25BA25BB3486CEB7F80B538C7FFFCA326347EB32B>104 -D<EA07E012FFA3120F1207B3B3A7EA0FF0B5FCA310347EB315>108 -D E -%EndDVIPSBitmapFont -%DVIPSBitmapFont: Fk ecbx0900 9 7 -/Fk 7 117 df<ED1F80A24B7EA24B7EA34B7EA24A7FA34A7FA24A7F15CFA2020F7F1587 -021F801503023F80EC3E01A2027E80EC7C0002FC804A137FA20101814A133F0103814A13 -1FA249B67EA24981A290271F8000077F91C77EA24982013E80017E82017C80A201FC8249 -157FB500F0013FB512F0A43C347DB343>65 D<EB7FFE0003B512E04814F8390FF00FFC39 -1FF803FF806E138016C0157F6C5A6C5AEA0180C8FCEC7FFF010FB5FC90B6FC0003EBF07F -000F1300EA1FF8485A485A485A5BA315FF7F007F5B6D4813E03A3FF80FBFFF000FB5121F -0003EBFC0F39007FE00728217EA02B>97 D<EA01FC12FFA4120F1207ADEC0FF8EC7FFF01 -FDB512C09039FFF01FF09138800FF84A6C7E496D7E496D7EA2178081A217C0A91780A25D -1700A26D495A6D495A6E485A9039F7E03FF001E1B512C0D9C07F90C7FC9038801FF02A34 -7DB331>I<903807FF80013F13F090B512FC3903FE01FE4848487EEA0FF8EA1FF0EA3FE0 -A2007F6D5A496C5A153000FF91C7FCA9127F7FA2003FEC07807F6C6C130F000FEC1F00D8 -07FE133E3903FF80FCC6EBFFF8013F13E0010790C7FC21217DA027>I<3901F81F8000FF -EB7FF0ECFFF89038F9E3FC9038FBC7FE380FFF876C1307A213FEEC03FCEC01F8EC006049 -1300B1B512F0A41F217EA024>114 D<9038FFE1C0000713FF5A383F803F387E000F1407 -5A14037EA26C6CC7FC13FCEBFFE06C13FC806CEBFF80000F14C06C14E0C6FC010F13F0EB -007F140F00F0130714037EA26C14E06C13076CEB0FC09038C01F8090B5120000F913FC38 -E03FE01C217DA023>I<133CA5137CA313FCA21201A212031207001FB51280B6FCA3D807 -FCC7FCB0EC03C0A79038FE078012033901FF0F006C13FEEB3FFCEB0FF01A2F7EAE22>I -E -%EndDVIPSBitmapFont -%DVIPSBitmapFont: Fl ecrm1200 12 25 -/Fl 25 122 df<121EEA7F8012FF13C0A213E0A3127FEA1E601200A413E013C0A3120113 -80120313005A1206120E5A5A5A12600B1D78891B>44 D<14FF010713E090381F81F89038 -3E007C01FC133F4848EB1F8049130F4848EB07C04848EB03E0A2000F15F0491301001F15 -F8A2003F15FCA390C8FC4815FEA54815FFB3A46C15FEA56D1301003F15FCA3001F15F8A2 -6C6CEB03F0A36C6CEB07E0000315C06D130F6C6CEB1F806C6CEB3F00013E137C90381F81 -F8903807FFE0010090C7FC28447CC131>48 D<EB03FE90381FFFC0017F13F03901F80FFC -3903C001FE48486C7E000EC7EA7F8048EC3FC0ED1FE04815F00030140F007015F8006014 -07126CB415FC7F7F1503A46C4813076CC7FCC8FC16F8A2150F16F0151F16E0A2ED3FC0ED -7F8016005D5D4A5A4A5A4A5A5D4A5A4A5A4AC7FC147C5C5C495A495A495A49C7120C131E -5B013814185B5B485A4848143848C81230000E1570001FB612F0A25A5AB712E0A326427B -C131>50 D<EC07FCEC3FFF91B512C0903903FC03E0903907E000F0D91FC0133849C71258 -017EEB01FC01FE1303491307485A485AA24848EB03F8000FEC01F092C7FC485AA3485AA3 -127FA29038007F80903801FFF090380780FC39FF0E003E49EB1F8049EB0FC049EB07E013 -6001E0EB03F04914F8150116FC5BED00FEA390C812FFA47EA57F123FA216FE121F15016D -14FC120FED03F86C7EED07F06C6C14E06C6CEB0FC06C6CEB1F80017EEB3F0090383F80FE -90380FFFF8010313E00100138028447CC131>54 D<16C04B7EA34B7EA34B7EA34B7EA3ED -19FEA3ED30FFA203707FED607FA203E07FEDC03FA2020180ED801FA2DA03007F160FA202 -06801607A24A6D7EA34A6D7EA34A6D7EA20270810260147FA202E08191B7FCA249820280 -C7121FA249C87F170FA20106821707A2496F7EA3496F7EA3496F7EA201788313F8486C83 -D80FFF03037FB500E0027FEBFFC0A342477DC649>65 D<B8FC17E017FC00019039C00003 -FF6C6C4801007FEF3FC0717E717E717E84170384170184A760A21703601707604D5A4D5A -EF7FC04DC7FCEE03FEEE3FF091B65A17FC0280C7B47EEF1FC0EF0FF0717E717E717E717E -1980187F19C0A2183F19E0A8F07FC0A2198018FF4D1300A24D5AEF0FFC4D5AEF7FE04848 -6C903803FFC0B9C7FC17FC17C03B447CC345>I<B712FEEEFFE017F800019039C00007FE -6C6C48903800FF80EF3FC0EF0FF0717E717EEF00FE8484F03F80F01FC0A2F00FE019F018 -0719F8A2180319FCA3F001FEA419FFAD19FEA3180319FCA319F8180719F0180F19E0A2F0 -1FC0F03F80A2F07F0018FE4D5A4D5AEF0FF0EF3FE0EFFF8048486C010790C7FCB812FC17 -E04CC8FC40447CC34A>68 D<B56C933807FFFC6E5EA20001F1FE0026006FE0EE1BF8A3D9 -67F01633A2D963F81663A3D961FC16C3A3D960FEED0183A2027FED0303A36E6C1406A36E -6C140CA26E6C1418A36E6C1430A36E6C1460A26E6C14C0A36E6CEB0180A3037FEB0300A2 -92383F8006A36F6C5AA36F6C5AA26F6C5AA36F6C5AA36F6C5AA26FB45AA370C7FC13F0A2 -486C143ED80FFFEF0FFEB500F0011C0107B512FCA34E447BC359>77 -D<003FB912F8A3903BF0001FF8001F01806D481303003EC7150048187C0078183CA20070 -181CA30060180CA5481806A5C81600B3B3A54B7EED7FFE49B77EA33F447DC346>84 -D<B600C0010FB5FCA3000101E0C813F026007F80ED1F80F00F00A21806B3B3A7180E6D6C -150CA2181C131F6E1518010F163818306D6C1570606D6C14016D6C5D6D6CEC0780027F4A -C7FC6E6C131EDA1FE0137C913907FC03F00201B55A6E6C1380DB07FCC8FC40467CC349> -I<EB07FC90383FFF809038F80FE03903C003F048C66C7E000E6D7ED80FC0137E486C137F -6D6D7EA36F7EA26C5AEA0380C8FCA4EC0FFF49B5FC90380FFE1FEB3FC0EBFF00EA03FC48 -5A485A485A485A127F5B176048C7FCA3153FA36D137F007F14EF6D9038C7E0C0003F1301 -3A1FE00783F13B07F81E03FF802701FFFC0113003A001FE0007C2B2E7CAC31>97 -D<EC7F80903803FFF090380FC07C90383F000F01FCEB03804848EB01C00003140F4848EB -1FE049133F120F485AA2485AED1FC0007FEC070092C7FCA290C9FC5AAB7E7FA2123F1630 -7F001F15706C6C146016E06C6C14C06C6C13010001EC03806C6CEB0700013F131E90381F -C078903807FFF001001380242E7DAC2B>99 D<167FED3FFFA315018182B3EC7F80903803 -FFF090380FC07C90383F000E017E1307496D5AD803F87F48487F5B000F81485AA2485AA2 -127FA290C8FC5AAB7E7FA2123FA26C7EA2000F5D7F6C6C5B00035C6C6C9038077F806C6C -010E13C0013F011C13FE90380FC0F8903803FFE09026007F0013002F467DC436>I<EB01 -FE903807FFC090381F03F090387E00FC49137E48487F485A4848EB1F80000F15C049130F -121F484814E01507A2007F15F090C7FCA25AA390B6FCA290C9FCA67EA27FA2123F16306C -7E1670000F15606D14E06C6C14C0000314016C6CEB03806C6CEB0700013E131E90381F80 -F8903803FFE0010090C7FC242E7DAC2B>I<EE0F80D901FCEB7FE0903A0FFF81F0F09039 -3F07E3819039FC01FF033A01F800FE014848017E13E00007027FC7FC497F000F8149131F -001F81A9000F5D6D133F000792C7FC6D5B0003147E6C6C5B6D485A3903BF07E090380FFF -80260701FCC8FC90CAFCA25AA37F6C7E7F90B512F86C14FF16E06C15F86C6C8048B67E3A -07C0000FFF48481300003FC8EA3F80003E151F48ED0FC0A2481507A56C150F007C168000 -7E151F003E16006C153E6C6C5CD807E0495AD801F8EB07E0D8007FEB3F8090261FFFFEC7 -FC010113E02C427DAC31>103 D<EA01E0EA07F8A2487EA46C5AA2EA01E0C8FCADEA01FC -12FFA3120712031201B3B0487EB512F8A315437DC21C>105 D<EA01FC12FFA312071203 -1201B3B3B3A5487EB512F8A315457DC41C>108 D<3901FC01FE00FF903807FFC091381E -07F091383801F8000701707F0003EBE0002601FDC07F5C01FF147F91C7FCA25BA35BB3A8 -486CECFF80B5D8F83F13FEA32F2C7DAB36>110 D<EC7F80903803FFF090380FC0FC9038 -3E001F496D7E496D7E48486D7E48486D7E48486D7E000F81A24848147E003F157FA290C8 -7E481680A44816C0AA6C1680A26D147F003F1600A2001F157E6D14FE000F5D6D13010007 -5D6C6C495A6C6C495A6C6C495A013E49C7FC90381FC0FE903807FFF89038007F802A2E7D -AC31>I<3903F803F000FFEB1FFCEC3C3EEC707F0007EBE0FF3803F9C000015B13FBEC00 -7E153C01FF13005BA45BB3A748B4FCB512FEA3202C7DAB26>114 -D<90383FE0183901FFFC383907E01F78390F0003F8001E1301481300007C1478127800F8 -1438A21518A27EA27E6C6C13006C7E13FC383FFFE06C13FC6C13FF6C14C06C14E0C614F0 -011F13F81300EC0FFC140300C0EB01FE1400157E7E153EA27EA36C143C6C147C15786C14 -F86CEB01F039F38003E039F1F00F8039E07FFE0038C00FF01F2E7DAC26>I<1306A5130E -A4131EA3133E137EA213FE12011207001FB512F0B6FCA2C648C7FCB3A4150CAA017E131C -017F1318A26D133890381F8030ECC070903807E0E0903801FFC09038007F001E3E7EBC26 ->I<D801FC147F00FFEC3FFFA300071401000380000181B3A85EA35DA212006D5B017E90 -38077F80017F010E13C06D011C13FE90380FC078903803FFF09026007F8013002F2D7DAB -36>I<B539F001FFFCA3000790C7EA7FE06C48EC1F8000011600160E1200160C017F5CA2 -80013F5CA26E1370011F146080010F5CA2ECF00101075CA26D6C48C7FCA26E5A01011306 -A26D6C5AA214FF6E5AA215B8EC3FB015F06E5AA36E5AA26E5AA36EC8FC2E2C7EAA33>I< -B539F001FFFCA3000790C7EA7FE06C48EC1F8000011600160E0000150C6D141C6D1418A2 -6E1338013F1430A26D6C5BA26E13E0010F5CA26D6C485AA2ECF803010391C7FCA2903801 -FC06A2ECFE0E0100130CA2EC7F18A215B8EC3FB0A2EC1FE0A36E5AA26E5AA36EC8FCA214 -06A35CA25CA2123C007E5BB4FC5CA25CEAFE01387C0380D87007C9FCEA3C1EEA0FFCEA03 -F02E3F7EAA33>121 D E -%EndDVIPSBitmapFont -%DVIPSBitmapFont: Fm ecbx1200 12 47 -/Fm 47 123 df<0118140C017C143E01FC147E48485C4848495A495C4848495A4848495A -001F140F90C75B003E4AC7FCA2003C141E007C143E0078143CA200F8147CA2481478D8F1 -F014F8D8F7FCEB7BFEB46CEB7FFF6D1580028014C0A36C80A36C806C496C13806C486D13 -006C486D5AD801F0EB00F82A2283C427>16 D<D807C0EB03E0D81FF0EB0FF8486C497E48 -6C497E486C497E6D1580A3028014C0A36C806C80D81FF7EB0FFBD807C7EB03E3D80007EB -0003010F1407A291C71380A249140F011E1500013E5CA249143E01FC147E49147C48485C -4848495A000714034848495A4848495A90C75B000C0206C7FC2A2281C427>I<ED0FFF4A -B512C0020F14F0027F80903A01FFF803FC499038C000FE010FEB00034948497E49485B5C -495A4C138001FF6E13005CA3705AEE01F893C8FCA74BB51280B9FCA5C69038E00003B3B0 -007FD9FFC1B6FCA538467EC53E>28 D<EA07C0EA1FF0EA3FF8EA7FFCEAFFFEA7EA7FFCEA -3FF8EA1FF0EA07C00F0F788E1F>46 D<EC3FF849B5FC010F14E0013F14F890397FF01FFC -9039FFC007FE4890380001FF48486D1380000716C049147F000F16E049143F001F16F0A2 -003F16F8A249141F007F16FCA600FF16FEB3A3007F16FCA56C6CEC3FF8A3001F16F0A200 -0F16E06D147F000716C06D14FF6C6C4913806C6D4813006C6D485A90397FF01FFC6DB55A -010F14E0010314809026003FF8C7FC2F427CC038>48 D<EC03C01407141F147FEB03FF13 -3FB6FCA413C3EA0003B3B3ADB712FCA5264177C038>I<ECFFE0010F13FE013F6D7E90B6 -12E0000315F82607FC0313FE3A0FE0007FFFD81F806D138048C7000F13C0488001C015E0 -01F07F00FF6E13F07F17F881A46C5A6C5A6C5AC9FC17F05DA217E05D17C04B13804B1300 -A2ED1FFC4B5A5E4B5A4B5A4A90C7FC4A5A4A5AEC0FF04A5AEC3F804AC7127814FE495A49 -4814F8D907E014F0495A495A49C8FC017C140149140348B7FC4816E05A5A5A5A5AB8FC17 -C0A42D417BC038>I<ECFFF0010713FF011F14C0017F14F049C66C7ED803F8EB3FFED807 -E06D7E81D80FF86D138013FE001F16C07FA66C5A6C4815806C485BC814005D5E4B5A4B5A -4B5A4A5B020F1380902607FFFEC7FC15F815FF16C090C713F0ED3FFCED0FFEEEFF80816F -13C017E0A26F13F0A217F8A3EA0FC0EA3FF0487EA2487EA217F0A25D17E06C5A494913C0 -5BD83F80491380D81FF0491300D80FFEEBFFFE6CB612F800015D6C6C14C0011F49C7FC01 -0113E02D427BC038>I<163FA25E5E5D5DA25D5D5D5DA25D92B5FCEC01F7EC03E7140715 -C7EC0F87EC1F07143E147E147C14F8EB01F0EB03E0130714C0EB0F80EB1F00133E5BA25B -485A485A485A120F5B48C7FC123E5A12FCB91280A5C8000F90C7FCAC027FB61280A53141 -7DC038>I<0007150301E0143F01FFEB07FF91B6FC5E5E5E5E5E16804BC7FC5D15E092C8 -FC01C0C9FCAAEC3FF001C1B5FC01C714C001DF14F09039FFE03FFC9138000FFE01FC6D7E -01F06D13804915C0497F6C4815E0C8FC6F13F0A317F8A4EA0F80EA3FE0487E12FF7FA317 -F05B5D6C4815E05B007EC74813C0123E003F4A1380D81FC0491300D80FF0495AD807FEEB -FFFC6CB612F0C65D013F1480010F01FCC7FC010113C02D427BC038>I<4AB47E021F13F0 -027F13FC49B6FC01079038807F8090390FFC001FD93FF014C04948137F4948EBFFE04849 -5A5A1400485A120FA248486D13C0EE7F80EE1E00003F92C7FCA25B127FA2EC07FC91381F -FF8000FF017F13E091B512F89039F9F01FFC9039FBC007FE9039FF8003FF17804A6C13C0 -5B6F13E0A24915F0A317F85BA4127FA5123FA217F07F121FA2000F4A13E0A26C6C15C06D -4913806C018014006C6D485A6C9038E01FFC6DB55A011F5C010714C0010191C7FC903800 -3FF02D427BC038>I<121E121F13FC90B712FEA45A17FC17F817F017E017C0A248168000 -7EC8EA3F00007C157E5E00785D15014B5A00F84A5A484A5A5E151FC848C7FC157E5DA24A -5A14035D14074A5AA2141F5D143FA2147F5D14FFA25BA35B92C8FCA35BA55BAA6D5A6D5A -6D5A2F447AC238>I<EA07C0EA1FF0EA3FF8EA7FFCEAFFFEA7EA7FFCEA3FF8EA1FF0EA07 -C0C7FCAEEA07C0EA1FF0EA3FF8EA7FFCEAFFFEA7EA7FFCEA3FF8EA1FF0EA07C00F2C78AB -1F>58 D<1A60F101F01907191FF17FC0953801FF00F007FCF01FF0F07FC04D48C7FCEF07 -FCEF3FF0EFFFC0040390C8FCEE0FFCEE3FE0EEFF80DB03FEC9FCED0FF8ED3FE0EDFF80DA -07FECAFCEC1FF8EC7FE0903801FF80D907FCCBFCEB1FF0EB7FC04848CCFCEA07FCEA1FF0 -EA7FC048CDFCA2EA7FC0EA1FF0EA07FCEA01FF38007FC0EB1FF0EB07FC903801FF809038 -007FE0EC1FF8EC07FE913800FF80ED3FE0ED0FF8ED03FE923800FF80EE3FE0EE0FFCEE03 -FF040013C0EF3FF0EF07FCEF01FF9438007FC0F01FF0F007FCF001FF9538007FC0F11FF0 -19071901F10060444277B957>60 D<126012F812FE6C7EEA3FE0EA0FF8EA03FEC66C7EEB -3FE0EB0FF8EB03FE903800FFC0EC3FF0EC0FFCEC03FF9138007FC0ED1FF0ED07FCED01FF -9238007FC0EE1FF0EE07FE933801FF809338007FE0EF1FF8EF03FE943800FF80F03FE0F0 -0FF8F003FE953800FF80F13FE0F10FF0A2F13FE0F1FF80953803FE00F00FF8F03FE0F0FF -80DD03FEC7FCEF1FF8EF7FE0933801FF80DC07FEC8FCEE1FF0EE7FC04B48C9FCED07FCED -1FF0ED7FC0DA03FFCAFCEC0FFCEC3FF0ECFFC0D903FECBFCEB0FF8EB3FE0EBFF80D803FE -CCFCEA0FF8EA3FE0EAFF8048CDFC12F81260444277B957>62 D<923803FFF0037FEBFF80 -0203B612F0020F15FC913A3FFC000FFFDAFFC0010013C0D903FEC8EA1FF0D907F0ED03F8 -D91FC0ED00FE4948167F017ECAEA1F8049717E4848717E49DAFF8013034848010F01F06D -7E4848013F01FC6D7E92B6FC4848489026C07F80137C49489026001FC0133C484948D907 -E0133E001E49486D6C131E003E49480101141F023F913800FFE0003C4A82007C017F1880 -007819074A5AA300F81AC04848491603AB6C6C7F12781B801A076E7E127C003C133F003E -6E1700021F4A5C001E6D6C5B001F6D6C49EBF01E6C6D6C011F143E6D6CD9C07F6D5A6C6C -6C90B5383FFFF8033FD9FC0F5B6C6C010FD9F0035B6C6C0100903980007F806D91CBFC6C -7E137E6D7E6D6CEF7FC0D907F0EE03FFD903FE043F1300902600FFC0913803FFF8DA3FFC -49B512C0020FB748C7FC020316E0DA007F02FCC8FC030349C9FC4A477AC557>64 -D<EE1F80A24C7EA24C7EA34C7EA24B7FA34B7FA24B7FA34B7F169F031F80161F82033F80 -ED3E07037E80157C8203FC804B7E02018115F0820203814B137F0207815D173F020F814B -7F021F8292C77EA24A82023E80027E82027FB7FCA291B87EA2498302F0C8FCA20103834A -157F0107834A153FA249488284011F8491C97E4984133E017E82B6020FB612F0A54C457C -C455>I<B9FC18F018FE727E19E026003FFCC700077F05017F716C7E727E727EA2721380 -A37213C0A74E1380A24E1300A24E5A4E5A4E5A4D5B05075B94B5128091B700FCC7FC18F0 -18FF19E002FCC7000113F8716C7EF01FFE727E7213801AC07213E0A27213F0A31AF8A71A -F0A2601AE0604E13C0604E138095B5120005075BBA12F86119C04EC7FC18E045447CC350 ->I<DCFFF01470031F01FF14F04AB6EAE0010207EDF803023FEDFE0791B539E001FF0F49 -49C7EA3F9F010701F0EC0FFF4901C0804990C87E4948814948814948167F4849163F4849 -161F5A4A160F485B19074890CAFC19035A5BA2007F1801A34994C7FC12FFAE127F7F1AF0 -A2123FA27F6C18011AE06C7F19036C6D17C06E16077E6C6DEE0F806C6DEE1F006D6C5E6D -6C167E6D6C6C5D6D6D4A5A6D01F0EC07F0010101FEEC1FE06D903AFFF001FF80023F90B6 -C7FC020715FC020115F0DA001F1480030001F8C8FC44467AC451>I<B9FC18F018FE727E -19E026003FFEC7001F13F805017F9438003FFF060F7F727F727F727F84737E737EA2737E -A2737EA21B80A2851BC0A51BE0AD1BC0A51B8061A21B006162193F624F5A19FF624E5B06 -075B4E5B063F90C7FC4DB45A050F13F8BA5A19C04EC8FC18F095C9FC4B447CC356>I<B7 -12E0A5D8001F90C7FCB3B3B3A4B712E0A523447DC32A>73 D<B500FE067FB512806E95B6 -FCA26F5EA2D8003F50C7FC013D6DEE03DFA2013C6DEE079FA26E6CEE0F1FA26E6C161EA2 -6E6C163CA36E6C1678A26E6C16F0A26E6DEC01E0A26E6DEC03C0A36E6DEC0780A26F6CEC -0F00A26F6C141EA26F6C5CA36F6C5CA26F6C5CA26F6D485AA26F6D485AA26F6D485AA370 -6C48C7FCA293383FF81EA2706C5AA2706C5AA3706C5AA2705BA2705BA2705BA2B6057FB6 -128071C7FCA2173E171C61447CC36A>77 D<923807FFC092B512FE0207ECFFC0021F15F0 -91267FFE0013FC902601FFF0EB1FFF01070180010313C04990C76C7FD91FFC6E6C7E4948 -6F7E49486F7E01FF8348496F7E48496F1380A248496F13C0A24890C96C13E0A24819F049 -82003F19F8A3007F19FC49177FA400FF19FEAD007F19FC6D17FFA3003F19F8A26D5E6C19 -F0A26E5D6C19E0A26C6D4B13C06C19806E5D6C6D4B13006C6D4B5A6D6C4B5A6D6C4B5A6D -6C4A5B6D01C001075B6D01F0011F5B010101FE90B5C7FC6D90B65A023F15F8020715C002 -004AC8FC030713C047467AC454>79 D<DAFFE0131C010701FE133C013F9038FF807C90B6 -EAE0FC4815F9489038801FFF3907FC00014848EB007F4848143F4848140F491407007F15 -035B1601160012FF177CA27FA26D153C7F7F6D92C7FC6C7EEBFFE014FE6CEBFFF015FF6C -15E016FC6C816C6F7E6C826C826C6C81011F810107811300020F80140003077FED007F82 -040F1380828212F082A282A27EA218007EA26C5D6C5E6D14036D5D6D140701F84A5A01FF -EC3FF002F8EBFFE0486CB65AD8FC1F92C7FCD8F80714FC48C614F0480107138031467AC4 -3E>83 D<007FBA12E0BB12F0A46C19E04406776757>95 D<903801FFE0011F13FE017F6D -7E48B612E03A03FE007FF84848EB1FFC6D6D7E486C6D7EA26F7FA36F7F6C5A6C5AEA00F0 -90C7FCA40203B5FC91B6FC1307013F13F19038FFFC01000313E0481380381FFE00485A5B -127F5B12FF5BA35DA26D5B6C6C5B4B13F0D83FFE013EEBFFC03A1FFF80FC7F0007EBFFF8 -6CECE01FC66CEB8007D90FFCC9FC322F7DAD36>97 D<EB7FC0B5FCA512037EB1ED0FF892 -B57E02C314E002CF14F89139DFC03FFC9139FF000FFE02FCEB03FF4A6D13804A15C04A6D -13E05CEF7FF0A218F8173FA318FCAC18F8A2177F18F0A3EFFFE06E15C06E5B6E49138002 -7C491300496C495A903AFC1FC07FFC496CB512F0D9F00314C049C691C7FCC8EA1FF03646 -7DC43E>I<EC3FFC49B512C0010F14F0013F14FC90397FF003FE9039FFC001FF0003495A -48494813805B120F485AA2485A6F1300007F6E5AED00784991C7FCA212FFAC6C7EA3123F -6DEC03C0A26C6C1407000F16806D140F6C6DEB1F006C6D133E6C01F05B3A007FFC03F86D -B55A010F14C0010391C7FC9038003FF82A2F7CAD32>I<EE03FEED07FFA5ED001F160FB1 -EC3FE0903803FFFC010FEBFF8F013F14CF9039FFF807FF48EBC00148903880007F4890C7 -123F4848141F49140F121F485AA3127F5BA212FFAC127FA37F123FA26C6C141FA26C6C14 -3F0007157F6C6C91B5FC6CD9C00314FC6C9038F01FEF6DB5128F011FEBFE0F010713F890 -26007FC0EBF80036467CC43E>I<EC3FF80103B57E010F14E0013F8090397FF83FF89039 -FFC007FC48496C7E48496C7E48486D1380485A001FED7FC05B003FED3FE0A2127F5B17F0 -161F12FFA290B7FCA401F0C9FCA5127FA27FA2123F17F06C7E16016C6C15E06C6C14036C -6DEB07C06C6DEB0F806C01F0EB3F0090397FFE01FE011FB55A010714F0010114C0902600 -1FFEC7FC2C2F7DAD33>I<EDFF80020F13E0027F13F049B512F849EB8FFC90390FFE0FFE -90381FFC1F14F8133FEB7FF0A2ED0FFCEBFFE0ED03F0ED00C01600ABB612F8A5C601E0C7 -FCB3B0007FEBFFE0A527467DC522>I<DAFFE0137E010F9039FE03FF80013FEBFF8F90B8 -12C048D9C07F133F489038001FF84848EB0FFC4848903907FE1F80001F9238FF0F00496D -90C7FCA2003F82A8001F93C7FCA26D5B000F5D6C6C495A6C6C495A6C9038C07FF04890B5 -5A1680D8078F49C8FC018013E0000F90CAFCA47F7F7F90B612C016FC6CEDFF8017E06C82 -6C16FC7E000382000F82D81FF0C77ED83FC014074848020113808248C9FC177FA46D15FF -007F17006D5C6C6C4A5A6C6C4A5AD80FFEEC3FF83B07FFC001FFF0000190B612C06C6C92 -C7FC010F14F8D9007F90C8FC32427DAC38>I<EB7FC0B5FCA512037EB1ED07FE92383FFF -8092B512E002C114F89139C7F03FFC9138CF801F9139DF000FFE14DE14FC4A6D7E5CA25C -A35CB3A7B60083B512FEA537457CC43E>I<137C48B4FC4813804813C0A24813E0A56C13 -C0A26C13806C1300EA007C90C7FCAAEB7FC0EA7FFFA512037EB3AFB6FCA518467CC520> -I<EB7FC0B5FCA512037EB3B3B3A3B61280A519457CC420>108 D<90277F8007FEEC0FFC -B590263FFFC090387FFF8092B5D8F001B512E002816E4880913D87F01FFC0FE03FF8913D -8FC00FFE1F801FFC0003D99F009026FF3E007F6C019E6D013C130F02BC5D02F86D496D7E -A24A5D4A5DA34A5DB3A7B60081B60003B512FEA5572D7CAC5E>I<90397F8007FEB59038 -3FFF8092B512E0028114F8913987F03FFC91388F801F000390399F000FFE6C139E14BC02 -F86D7E5CA25CA35CB3A7B60083B512FEA5372D7CAC3E>I<EC1FFC49B512C0010714F001 -1F14FC90397FF80FFF9026FFC0017F48496C7F4848C7EA3FE000078248486E7E49140F00 -1F82A2003F82491407007F82A400FF1780AA007F1700A46C6C4A5AA2001F5E6D141F000F -5E6C6C4A5AA26C6C6CEBFFE06C6D485B27007FF80F90C7FC6DB55A010F14F8010114C090 -26001FFCC8FC312F7DAD38>I<90397FC00FF8B590B57E02C314E002CF14F89139DFC03F -FC9139FF001FFE000301FCEB07FF6C496D13804A15C04A6D13E05C7013F0A2EF7FF8A4EF -3FFCACEF7FF8A318F017FFA24C13E06E15C06E5B6E4913806E4913006E495A9139DFC07F -FC02CFB512F002C314C002C091C7FCED1FF092C9FCADB67EA536407DAC3E>I<DA3FE013 -1E902603FFFC133E010F01FF137E013F1480903AFFF80FE0FE489038E003F148EBC00148 -90388000FB4890C7127F49143F001F151F485A160F5B127FA3485AAC6C7EA46C7EA26C6C -141F163F6C6C147F6C15FF6C6D5A6C9038E003EF6C9038F01FCF6DB5128F011FEBFE0F01 -0313F89038007FC091C7FCAD0307B512FCA536407CAC3B>I<90387F807FB53881FFE002 -8313F0028F13F8ED8FFC91389F1FFE000313BE6C13BC14F8A214F0ED0FFC9138E007F8ED -01E092C7FCA35CB3A5B612E0A5272D7DAC2E>I<90391FFC038090B51287000314FF120F -381FF003383FC00049133F48C7121F127E00FE140FA215077EA27F01E090C7FC13FE387F -FFF014FF6C14C015F06C14FC6C800003806C15806C7E010F14C0EB003F020313E0140000 -F0143FA26C141F150FA27EA26C15C06C141FA26DEB3F8001E0EB7F009038F803FE90B55A -00FC5CD8F03F13E026E007FEC7FC232F7CAD2C>I<EB01E0A51303A41307A2130FA2131F -A2133F137F13FF1203000F90B51280B7FCA4C601E0C7FCB3A3ED01E0A9150302F013C013 -7F150790393FF80F8090391FFC1F006DB5FC6D13FC01015B9038003FE023407EBE2C>I< -D97FC049B4FCB50103B5FCA50003EC000F6C81B3A85EA25EA25E7E6E491380017FD901F7 -13FE9138F807E76DB512C7010F1407010313FE9026007FF0EBFC00372E7CAC3E>I<B690 -3803FFFCA5000101E09038003E006C163C80017F5D8017F8013F5D6E1301011F5D6E1303 -010F5D6E13076D5DED800F6D92C7FC15C05E6DEBE01E163E6D143CEDF07C027F1378EDF8 -F8023F5B15FD021F5B15FF6E5BA36E5BA26E90C8FCA26E5AA26E5AA21578362C7EAB3B> -I<B500FE90383FFFF0A5C601F0903803E0006D6C495A6D6C495A011F4AC7FC6E5B6D6C13 -7E6DEB807C6D6D5A6DEBC1F0EDE3E06DEBF7C06EB45A806E90C8FC5D6E7E6E7F6E7FA24A -7F4A7F8291381F3FFCEC3E1F027C7F4A6C7E49486C7F01036D7F49487E02C08049486C7F -49C76C7E013E6E7E017E141FB500E090B512FCA5362C7EAB3B>120 -D<001FB71280A49026FC001F130001E0495A5B49495A90C7485A48495B123E4A5B4A5B00 -3C495BA24A90C7FC4A5A4A5AC7FC4A5A495B495BA2495B499038800780491300A2495A49 -48130F49481400A2485B48495B485BA248495B4890C75A48485C15034848EB1FFEB7FCA4 -292C7DAB32>122 D E -%EndDVIPSBitmapFont -%DVIPSBitmapFont: Fn ecrm1728 17.28 8 -/Fn 8 117 df<B912F018FF19E019F8C601FCC8EA7FFED93FF892380FFF80011F04017F -9538007FF0F11FF8737EF103FE737E737F747E747E747E1A0F87747E1A0387747EA27413 -80A2F37FC0A21CE01B3FA21CF0A21B1F1CF8A31CFCA21B0FA41CFEAF1CFCA51B1F1CF8A4 -F33FF0A21CE0A21B7F1CC01BFF1C80A2501300A2505A505AA2505A505A505A505A1AFF4F -5B4F90C7FCF107FCF11FF8F17FF0953801FFC0013F04075BD9FFFCDB7FFEC8FCBA12F819 -E096C9FC18F0576278E167>68 D<BB12FCA4C601FCC8120FD93FF89238007FFE011F171F -190719031900A21A7E1A3EA21A1EA21A1F86A486A6F20380A318E0A297C7FCA61701A417 -031707170F171F17FF91B7FCA402F8C7FC171F170F170717031701A41700A895C9FCB3A5 -80133F90B57EB712E0A4496278E158>70 D<EC3FE0903803FFFE010F6D7E90393FC03FE0 -90397C000FF801F0EB03FC48486D7E48486D7E48486E7E48C86C7E7F01F06E7E487E6D6E -7EA3707EA36C5AEA03E0C9FCA6167FED7FFF020FB5FC91387FF807903801FF80903807FC -00EB1FF0EB7FC0495AD803FEC7FC485A120F5B485A485AA24848EE01C0A312FF5BA2160F -A3161F6D141B007F153B16736D17806C6C9138E1FC03001FEC03C16C6C903A0780FE0700 -D807FE49486C5A2701FF807CEB7FFE6C6CB4486D5A011F01E06D5A010390C7EA07E03A41 -79BF43>97 D<ED1FE0EDFFF8020313FE91380FF03F91391FC01F8091383F807F91397F00 -FFC014FE1301495A5C0107EC7F80A24948EB1E0093C7FCA2495AB3A5B712E0A426001FE0 -C8FCB3B3B0497EEB7FFC003FB512FEA42A657DE429>102 D<1378EA01FE487E487FA66C -90C7FC6C5AEA007890C8FCB3A2EB0780EA0FFFB5FCA41203C6FCA2137FB3B3AC497E487F -B61280A4195F7BDE25>105 D<010FEB07F8D80FFFEB1FFEB590387FFF809238F81FC091 -3801E03F913903C07FE00003EB0780C6EB0F00140E6D5A0218EB3FC00238EB1F800230EB -0600027090C7FCA2146014E0A25CA55CB3B0497E4813F0B612F8A42B3F7BBE34>114 -D<9138FFC003010FEBF807017FEBFE0F3A01FF003F9FD803F0EB07DF48486DB4FCD80F80 -1300001F8148C8FC003E81007E81127C00FC81A4827EA27E7F6C7E6D91C7FC13F8EA3FFE -381FFFE06C13FF15F0000314FE6C6E7E6C6C14E0011F14F801078001008002077FDA003F -13801507030113C0ED007F00E0ED3FE0161F17F06C150F1607A36C1503A37EA26C16E016 -077E17C06D140F6D15806D141FD8FDF0EC3F00D8F8F8147E017C495A3AF01F801FF06DB5 -12C0D8E00391C7FC39C0007FF02C417CBF35>I<1470A714F0A51301A31303A21307A213 -0FA2131F133F137F13FF1203000F90B6FCB8FCA326000FF0C8FCB3AEEE01C0AE6D6CEB03 -80A316076D6C14005E6D6C130E6D6C131E6E6C5A91383FE0F86EB45A020713C0020090C7 -FC2A597ED734>I E -%EndDVIPSBitmapFont -%DVIPSBitmapFont: Fo ecbx1728 17.28 18 -/Fo 18 117 df<BB7E1AFCF2FFC01BF01BFED8000191C8001F6D7E070014E0081F7F0807 -13FC08017F747F093F7F757F757F757F757F757F757FA2767E1E80881EC0881EE0881EF0 -A2881EF8A31EFC88A31EFEA61EFFB01EFEA61EFCA2641EF8A31EF064A21EE0641EC0641E -80521300A2525A515B515BA2515B515B093F5B515B504848C7FC08075B081F5B97B512E0 -070F1480BC48C8FC1BF81BC008FCC9FC1A8068627BE177>68 D<942603FFF8151C94B66C -143C040F03F0147C047F03FC14FC0303B81301030FDAC00113C0033F01F8C7381FF00392 -B500C0913807F807020349C83801FE0F020F01F89238007F1F4A01E0EE3FBF4A49EE0FFF -91B5CA7E494983494983494983495B4949187F4B183F491A1F495B90B5CC120FA2484919 -075A4A19035A4A19015AA24A19005AA348491A7CA35A9AC8FCA35CA2B5FCB07EA26E043F -B81280A47E96C7000701FCC7FCA26C7FA37E80A27E807E807E6C7FA26D7F6D7F7F816D7F -6D6D5F6D7F6D6D5F6D6D7E023F6D5E6E01F05E6E6DEEFE7F020301FF923801FC3F020002 -C0913807F80F033F01FC91381FF007030F903BFFE001FFC001030391B6EA8000DB007F4B -C7123C040F03F8140C040003C091C8FC050301F8CBFC696677E37A>71 -D<BA12E0F1FF801AF81AFF1BC0D8000191C7000114F0DE000F13FC070313FF070080083F -7F747F747F747F747FA2747F88A28986A389A865A35091C8FCA26462646462505B505B50 -138097B5C9FC070313FC070F5B4EB512C093B8CAFC1AF81AC01AF893C7000713FE06006D -7E073F7F7313F007077F737F87737F85888688A2747FAA88A91F707614F8A286A2746D13 -011FF086746D13037614E0B800FE6EED07C0746CEBC00F759038F07F80090F90B5120009 -035CCF6C13F80A0313E06D647BE173>82 D<001FBD12F0A59126F8000191C7123F4801C0 -060713F849C71700491A7F01F01A1F491A0F491A07A2491A03A290C81801A2007EF300FC -A4007C1C7CA7481C3EA5C91900B3B3B3A5023FB912F8A55F617AE06C>84 -D<913803FFF0027F13FF0103B612E0010F15F890263FFC0013FED97FC090381FFF8049C7 -6C7F4801C06D7F486D6D7F6E6D7F48836E7F84177F84A36C496E7FA26C5B6C5B013FC8FC -90C9FCA75F0307B6FC4AB7FC141F91B5EAF03F0103EBFE00010F13F0013F1380D9FFFEC7 -FC485B485B485B485B485B485BA24890C8FC1A7CA2485AA35FA394B5FC7F6C5D6EEB03DF -6CDB07CFEBC0F86C6DEB0F8F6C6DD91F07EBF3F06C01F8017E14FF6C9027FE01FC0314E0 -C690B5D8F00114C0013F9126C0007F1380010791C7383FFE009026003FF8EC07F846437B -C14D>97 D<903807FF80B6FCA5C6FC7F7FB3A9933801FFE0041F13FE047FEBFFC00381B6 -12F0922687FC0113FC923A9FE0003FFEDBBF8090380FFF8003FEC76C7F4B6E7F4B6E7F4B -6E7F4B824B157F4B82737EA21B80851BC0A31BE085A41BF0AE1BE0A44F13C0A31B80A24F -1300A262197F6F5E6F4B5A4E5B6F4A5BDAFCF84A5BDAF87E4A5B4A6C4A90C7FC9126E01F -C0EB7FFC913BC00FF803FFF8DA8003B612E091C71580013E023F01FCC8FC90C800031380 -4C657CE356>I<ED1FFF4AB512F8020F14FF027F15C0902701FFF80013F04901E0EB0FF8 -010F0180EB03FC4990C7EA0FFE49484A7E49485C4948168048495C5A5C5A485BA2487013 -005C48705A715AEF03F04893C8FC91CBFCA4B5FCAE7EA280A27EA36C7FF003E07E6E1507 -6C18C06E150F6C18806C6D151F6C6DED3F006D6C157E6D6C15FE6D6D495A6D6D495A6D01 -F0EB0FE0010101FEEB7FC06D6CB6C7FC021F14FC020314E09126001FFEC8FC3B437BC145 ->I<ED3FFE0203B512E0021F14FC027F14FF902701FFF80F13C00107D9C0037F4990C77F -49486E7E49486E7E49486E7E49486E7E5A48496E13805A4A16C0488219E0485B834818F0 -A34890C8FCA27113F8A3B5FCA391B8FCA491CBFCA67EA4807EA27E19F8806C17016C18F0 -806C17036C6DED07E06E16C06C170F6D6CED1F806D6CED3F006D6C6C14FE01076DEB03FC -6D01F8EB0FF8010001FFEB7FE0023F90B51280020F4AC7FC020114F8DA000F13803D437C -C146>101 D<EEFFE0031F13FC92B6FC02031580020F9038E03FC04A903800FFE091267F -FE0113F04A485A49494813F84913F04913E0A25B15C05B7013F04913807013E09338007F -80EF1E0094C7FCB1B8FCA5D8003F0180C8FCB3B3B2B712F8A535657CE42F>I<F13F8091 -2601FFF0903801FFE0021F01FF010713F091B6D8E01F13F801039238F87FCF010F903BC0 -7FFEFC0FFC903B1FFE000FFFF0D97FFC6DEBE01F49486D140F48496D13F01AF848496DEB -F807489438FC01E096C7FC48496E7EA44883A96C5FA46C6D4A5AA26C5F6C6D495BA26C6D -495B6D6C495B6D6C4990C8FC903A7FFFC07FFE017B90B512F801F015E0021F91C9FC0001 -010113F049CCFC1203A27FA37FA27F7F6D7E91B612FCEFFFE06C17FCF0FF806C18E0856D -17FC6D836D837F017F188048BA12C000070180C712074848C96C13E04848160F48481603 -4982007F19F084485A197FA56D17FF007F19E0A26D5E6C6C4C13C0001F19806D5E6C6C4C -1300000301C0ED3FFC6C01F0EDFFF826007FFC020313E090261FFFE0017F1380010790B6 -48C7FC010116F8D9001F1580DA007F01E0C8FC46607CC14D>I<EB0FE0EB3FF8497E497E -487FA24880A76C91C7FCA26C5B6D5A6D5AEB0FE090C9FCB1903807FF80007FB5FCA5C6FC -7F7FB3B3B0B712C0A522657CE42A>105 D<903807FF80B6FCA5C6FC7F7FB3B3B3B3AFB7 -12E0A523647CE32A>108 D<D90FFFEC7FF8B60103B5FC040F14E0043F80DC7F0113FC92 -2601F8007FC6DA03E06D7E6D49487F6D49488193C77E031E825D153803788003708215F0 -5DA35DA35DB3B3A2B7D8E03FB612F8A54D417BC056>110 D<92381FFF804AB512F8020F -14FF023F15C09126FFFC0313F001039039E0007FFC490180EB1FFED91FFEC73807FF8049 -486E7F49486E7F49486E7F48496F7EA248496F7E4884A248496F7EA2481980A24819C091 -C97EA24819E0A5B518F0AD6C19E0A46C6D4B13C0A36C1980A26C6D4B1300A26C606E157F -6C606C6D4B5A6C606D6C4A5B6D6C4A5B6D6C4A5B6D6C6C011F90C7FC010301E0EB7FFC6D -9039FC03FFF86D6CB612E0020F92C8FC020114F8DA001F138044437CC14D>I<903B07FF -8001FFE0B6011F13FE047FEBFFC00381B612F0922687FC0313FC923A9FE0007FFEC6DABF -806D6C7E6D01FEC7000F7F6D496E7F4B824B6E7F4B6E7F4B804B82737EA21B80851BC0A2 -851BE0A4851BF0AE4F13E0A41BC061A21B80A24F1300A24F5AA26F4A5B6F4A5B626F4A5B -6F4A5B03FE4A5B03BF027F90C7FCDB9FC0EBFFFC92268FF8075B0383B612E00380158004 -3F01FCC8FC0403138093CBFCB3A4B712E0A54C5D7CC056>I<D90FFFEB07F8B6EB3FFF4C -13804BB512E0923903F83FF0923907E07FF8C691380F80FF6D020113FC6D131E153E153C -1578A21570DBF00013F8EF7FF04BEB3FE0EF0F8094C7FC5DA65DB3B1B712F8A536417DC0 -3E>114 D<DA7FFC131C0107B5EAC03C011FECF0FC90B612FD489038C003FFD807FEC712 -7FD80FF8143F49140F4848140748481403A248481401A2160012FFA26D157CA27F7F7F6D -92C7FCEBFF806C13F0ECFFC015FE6CECFFC016F86C15FE6C6F7E6C826C826C826C82013F -81010F81010181EB003F02011580EC000F1500041F13C000F88182826C8182A26C167FA3 -7E18807F17FF6D16007F6D4A5A7F6D4A5A6DEC0FF86D6C495A3BFE1FF001FFE0486CB612 -80D8F8034AC7FC48C614F048010F90C8FC32437BC13D>I<EC07C0A6140FA5141FA3143F -A2147FA214FF5BA25B5B5B5B137F48B5FC000F91B512F8B8FCA4D8001F01C0C7FCB3B017 -1FAD6D153E81A26D157C816D15F86D7F6D9038FC01F091397FFF07E06EEBFFC0020F1480 -0203EBFE009138003FF8305C7DDA3C>I E -%EndDVIPSBitmapFont -end -%%EndProlog -%%BeginSetup -%%Feature: *Resolution 600dpi -TeXDict begin -%%PaperSize: A4 - -%%EndSetup -%%Page: 1 1 -1 0 bop 290 639 a Fo(Genealogical)56 b(Represen)l(tation)e(of)f(T)-13 -b(rees)52 b(in)g(Databases)1686 822 y Fn(First)46 b(Draft)1247 -1063 y Fm(Miguel)36 b(Sofer)i(<mig@utdt.edu>)1359 1179 -y Fl(Univ)m(ersidad)33 b(T)-8 b(orcuato)33 b(Di)f(T)-8 -b(ella)1728 1295 y(Buenos)33 b(Aires)1797 1411 y(Argen)m(tina)1746 -1606 y(Ma)m(y)h(6,)e(2000)1839 1905 y Fk(Abstract)441 -2035 y Fj(blah)25 b(blah)h(.)13 b(.)g(.)118 2310 y Fi(1)131 -b(In)l(tro)t(duction)118 2491 y Fh(T)-7 b(rees)28 b(are)h(a)g(v)n(ery)f -(frequen)n(t)h(data)f(structure.)41 b(They)30 b(are)e(the)h(natural)g -(represen)n(tation)e(for)i(instance)g(for)f(organiza-)118 -2591 y(tional)f(c)n(harts,)g(threaded)g(discussion)g(groups,)f(some)h -(bills)g(of)h(materials,)e(.)14 b(.)g(.)243 2691 y(A)n(t)28 -b(least)f(t)n(w)n(o)f(alternativ)n(e)h(represen)n(tations)e(for)i -(trees)g(in)h(RDBMs)g(are)e(kno)n(wn)h(and)h(used:)220 -2857 y(1.)41 b Fg(P)m(oin)m(ters:)k Fh(a)31 b(\034eld)h(in)h(the)f(c)n -(hild)g(record)e(references)h(the)h(paren)n(t)f(no)r(de.)50 -b(This)32 b(seems)g(to)f(b)r(e)i(the)f(canonical)326 -2956 y(represen)n(tation.)38 b(Some)29 b(DB)g(engines)f(pro)n(vide)g -(sp)r(ecial)g(SQL)g(extensions)g(to)h(simplify)g(tree)g(searc)n(hes;)e -(Oracle)326 3056 y(tree)d(extensions)g(are)g(an)h(example)f(\(see)h -(for)f(instance)g([1]\);)i(DB2's)f(WITH)g(can)f(b)r(e)i(used)e(for)h -(this)g(purp)r(ose)f(to)r(o)326 3156 y(\(see)j([3],)g(pp)h(139-162\).) -220 3322 y(2.)41 b Fg(Nested)35 b(Sets:)43 b Fh(t)n(w)n(o)30 -b(n)n(umeric)h(\034elds)g(in)g(ev)n(ery)f(no)r(de)h(record)f(co)r(de)h -(the)g(tree)g(structure.)47 b(I)31 b(can't)g(pro)n(vide)f(a)326 -3421 y(b)r(etter)e(or)e(briefer)h(description)g(of)h(this)g(metho)r(d)g -(than)f(the)h(four)f(articles)g([2].)118 3587 y(These)g(t)n(w)n(o)g -(metho)r(ds)h(o\033er)f(di\033eren)n(t)h(adv)-5 b(an)n(tages)25 -b(and)j(disadv)-5 b(an)n(tages:)243 3753 y Ff(\017)41 -b Fh(P)n(oin)n(ters)30 b(are)g(extremely)g(e\036cien)n(t)h(for)f(no)r -(de)h(insertion)f(and/or)g(deletion,)h(but)h(require)e(recursiv)n(e)f -(table)i(ac-)326 3853 y(cesses)e(to)h(searc)n(h)f(the)h(tree)g(\(I)h -(do)f(not)g(kno)n(w)f(the)i(implemen)n(tation)f(details)g(of)g(the)h -(Oracle)e(tree)g(extensions,)326 3953 y(whic)n(h)e(as)g(far)g(as)g(I)g -(kno)n(w)g(ma)n(y)g(solv)n(e)f(this)i(problem)f(in)n(ternally;)g(they)g -(de\034nitely)h(solv)n(e)f(it)g(for)g(the)h(end)g(user\).)243 -4119 y Ff(\017)41 b Fh(Nested)30 b(sets)g(are)f(v)n(ery)f(e\036cien)n -(t)i(for)g(tree)f(searc)n(hes,)g(but)i(are)e(rather)f(exp)r(ensiv)n(e)i -(for)f(no)r(de)h(insertion)f(and/or)326 4218 y(deletion:)37 -b(they)27 b(require)g(up)r(dating)g(p)r(oten)n(tially)h(man)n(y)f(no)r -(des.)243 4384 y(W)-7 b(e)30 b(prop)r(ose)f(here)h(a)g(di\033eren)n(t)h -(represen)n(tation,)e(based)g(on)i(no)r(de)f(iden)n(ti\034ers)g(whic)n -(h)g(are)f(\020genealogical)f(iden)n(ti-)118 4484 y(\034ers\021:)44 -b(they)32 b(con)n(tain)f(the)h(complete)f(genealogy)f(of)h(the)h(no)r -(de,)h(i.e.,)g(the)f(list)g(of)g(ancestors)d(up)j(to)g(the)g(ro)r(ot)f -(of)g(the)118 4584 y(tree.)243 4683 y(This)j(allo)n(ws)f(to)i(replace)e -(man)n(y)h(searc)n(hes)f(in)h(database)g(tables)g(with)h(string)f(op)r -(erations)f(on)h(the)h(index.)58 b(The)118 4783 y(result,)24 -b(as)f(explained)h(in)g(Section)g(3)f(is)h(that)g(tree)f(searc)n(hes)f -(pro)r(ceed)h(at)h(\020nested)f(sets\021)30 b(sp)r(eed,)25 -b(while)f(no)r(de)g(insertions)118 4882 y(and)k(deletions)f(are)f(as)h -(fast)h(as)f(with)h(p)r(oin)n(ters.)243 4982 y(The)i(ob)n(vious)f(do)n -(wnside)h(of)h(the)g(metho)r(d)g(is)f(that)h(the)g(primary)f(k)n(ey)f -(in)i(the)g(tree)f(needs)h(to)f(b)r(e)h(a)g(v)-5 b(ariable)29 -b(size)118 5082 y(text)j(\034eld,)h(and)f(that)g(the)g(iden)n -(ti\034ers)f(ma)n(y)g(b)r(e)i(extremelly)e(long)g(for)g(deep)h(trees.) -49 b(W)-7 b(e)32 b(will)g(pro)n(vide)e(estimates)i(of)118 -5181 y(the)c(size)f(required)g(as)g(a)g(function)h(of)g(the)f -(magnitude)h(of)f(the)h(tree.)1987 5653 y(1)p eop -%%Page: 2 2 -2 1 bop 118 291 a Fi(2)131 b(Genealogical)45 b(iden)l(ti\034ers)g(for)f -(trees)118 489 y Fm(2.1)112 b(De\034nition)118 642 y -Fh(W)-7 b(e)28 b(de\034ne)g Fe(gene)l(alo)l(gic)l(al)k(identi\034ers)j -Fh(recursiv)n(ely)25 b(as)i(follo)n(ws:)326 808 y Fg(De\034nition:)59 -b Fe(The)42 b(gene)l(alo)l(gic)l(al)h(identi\034er)f(\(gID\))e(of)i(a)f -(no)l(de)h(is)f(obtaine)l(d)h(by)g(app)l(ending)g(a)f(child)326 -908 y(identi\034er)30 b(to)g(the)g(gene)l(alo)l(gic)l(al)h -(identi\034er)g(of)f(the)g(p)l(ar)l(ent)f(no)l(de.)243 -1074 y Fh(Remark)40 b(that)h(genealogical)e(iden)n(ti\034ers)i(are)f -(rather)g(w)n(ell)h(kno)n(wn)f(and)h(used;)48 b(common)41 -b(examples)f(are)g(the)118 1174 y(\020path+\034le-name\021)33 -b(in)28 b(a)f(computer)g(\034le)h(system)f(and)h(the)f(URLs)h(within)g -(a)f(WWW.)243 1273 y(The)d(name)g(\020genealogical)e(iden)n -(ti\034er\021)30 b(is)24 b(suggested)g(b)n(y)g(the)g(fact)h(that)f(the) -h(v)-5 b(alue)24 b(of)g(the)h(iden)n(ti\034er)f(con)n(tains)f(the)118 -1373 y(complete)30 b(genealogy)d(of)j(the)g(no)r(de:)41 -b(it)30 b(con)n(tains)e(as)h(a)h(substring)f(the)h(gID)f(of)h(its)g -(father,)g(whic)n(h)f(in)h(turn)g(con)n(tains)118 1472 -y(as)d(a)g(substring)g(the)h(gID)g(of)f(the)h(grandfather,)e(.)14 -b(.)g(.)243 1572 y(The)27 b(ro)r(ot)g(no)r(de)h(of)f(the)h(tree)f(has)g -(a)h(gID)f(with)h(v)-5 b(alue)28 b(\021)34 b(\(the)28 -b(empt)n(y)g(string\),)f(as)g(it)h(has)f(no)g(paren)n(t.)118 -1804 y Fm(2.2)112 b(Child)36 b(iden)m(ti\034ers)118 1958 -y Fh(The)26 b(ob)n(vious)e(c)n(hild)i(iden)n(ti\034er)g(is)f(a)h -(zero-based)d(coun)n(ter:)35 b(iden)n(tify)26 b(the)h(c)n(hild)e(b)n(y) -h(the)g(n)n(um)n(b)r(er)f(of)h(older)f(brethren)g(it)118 -2057 y(has.)243 2157 y(W)-7 b(e)25 b(could)f(represen)n(t)g(the)h(coun) -n(ter)f(in)h(base)f(10;)h(this)g(ho)n(w)n(ev)n(er)e(is)i(extremely)f(w) -n(asteful)g(of)h(resources.)34 b(It)25 b(is)g(m)n(uc)n(h)118 -2257 y(b)r(etter)33 b(to)f(represen)n(t)f(the)h(coun)n(ter)g(in)g(as)g -(large)e(a)i(base)g(as)f(p)r(ossible:)46 b(in)n(terpret)32 -b(as)f(n)n(um)n(b)r(ers)h(a)g(set)g(of)g(c)n(haracters)118 -2356 y(larger)26 b(than)h({0,1,.)14 b(.)g(.)g(9}.)243 -2456 y(As)26 b(tree)f(op)r(erations)f(will)i(in)n(v)n(olv)n(e)f(string) -g(op)r(erations)f(on)i(the)g(indices,)g(in)g(order)f(to)g(a)n(v)n(oid)g -(a)g(\020quoting)g(hell\021)33 b(it)26 b(is)118 2555 -y(desirable)d(to)h(a)n(v)n(oid)e(using)h(an)n(y)g(c)n(haracter)f(with)i -(a)g(sp)r(ecial)f(meaning)h(in)g(LIKE)g(expressions)e(or)g(regular)g -(expressions;)118 2655 y(i.e.,)28 b(w)n(e)f(will)h(not)f(use)h(an)n(y)f -(of)g(the)h(sym)n(b)r(ols)70 b Fd(.)44 b(*)f(^)g(\\)g([)g(])g({)h(})f -(\()g(\))g(<)g(>)71 b Fh(?)37 b(|)28 b(&)f($)243 2755 -y(W)-7 b(e)28 b(prop)r(ose)e(to)h(reserv)n(e)f(also)g(/)i(as)f(a)g -(separator)e(\(see)i(\020V)-7 b(ariable)27 b(Sized)g(gID\021)34 -b(b)r(elo)n(w\).)243 2854 y(If)g(w)n(e)f(limit)i(ourselv)n(es)d(to)i -(ascii)f(c)n(haracters,)g(and)h(a)n(v)n(oid)e(to)i(b)r(e)g(safe)f(a)h -(lot)g(of)g(other)f(c)n(haracters,)g(w)n(e)g(can)h(use)118 -2954 y(n)n(um)n(b)r(ers)27 b(in)h(base)f(64)g(b)n(y)g(represen)n(ting) -243 3120 y Ff(\017)41 b Fh(0-9)26 b(with)i('0'-'9')f(\(dec)g(ascii)g -(co)r(de)h(48-57\))243 3286 y Ff(\017)41 b Fh(10)26 b(with)i(':')37 -b(\(dec)28 b(ascii)f(co)r(de)h(58\))243 3452 y Ff(\017)41 -b Fh(11)26 b(with)i(';')g(\(dec)g(ascii)f(co)r(de)g(59\))243 -3618 y Ff(\017)41 b Fh(12-37)25 b(with)j('A'-'Z')g(\(dec)f(ascii)g(co)r -(de)h(65-90\))243 3784 y Ff(\017)41 b Fh(38-63)25 b(with)j('a'-'z')f -(\(dec)h(ascii)f(co)r(de)g(97-122\))118 3950 y(By)g(using)g(base)f(64,) -h(up)g(to)h(4096)d(c)n(hildren)i(can)f(b)r(e)i(represen)n(ted)e(using)h -(t)n(w)n(o)f(suc)n(h)h(digits,)g(up)h(to)f(262144)d(with)k(three)118 -4050 y(digits,)g(and)f(up)h(to)f(16777216)d(with)k(four)f(digits.)243 -4149 y(If)37 b(the)g(RDBMs)g(supp)r(orts)f(in)n(ternational)g(c)n -(haracters,)h(it)g(is)g(p)r(ossible)f(to)h(further)f(increase)g(the)h -(base;)k(as)36 b(an)118 4249 y(example,)30 b(b)n(y)f(using)g(the)h(95)f -(additional)g(c)n(haracters)e(of)i(the)h(latin-1)f(c)n(haracter)e(set,) -k(w)n(e)e(could)g(co)r(de)g(n)n(um)n(b)r(ers)g(in)h(a)118 -4349 y(base)f(up)g(to)g(160)f(\025)g(remark)g(that)h(ev)n(ery)f(single) -h(digit)g(is)g(still)h(one)e(b)n(yte)h(in)h(this)f(represen)n(tation.) -40 b(This)29 b(means)f(that)118 4448 y(w)n(e)f(expand)h(the)f(sym)n(b)r -(ols)g(ab)r(o)n(v)n(e)f(b)n(y)i(represen)n(ting)243 4614 -y Ff(\017)41 b Fh(64-159)25 b(with)j(dec)f(latin1)g(co)r(de)h(160-255) -243 4780 y(In)23 b(base)g(160,)g(up)g(to)h(25600)d(c)n(hildren)i(can)f -(b)r(e)i(represen)n(ted)e(using)h(t)n(w)n(o)g(digits,)h(up)g(to)f -(4096000)d(with)k(three)f(digits,)118 4880 y(and)28 b(up)f(to)h -(6.5E+08)e(with)i(four)f(digits.)243 4980 y(Remark)g(that)h(base)f(con) -n(v)n(ersions)f(only)h(need)i(to)e(b)r(e)i(p)r(erformed)e(at)h -(insertion)g(time,)g(when)h(the)f(index)g(of)g(a)g(new)118 -5079 y(no)r(de)g(is)f(computed.)37 b(They)28 b(will)f(therefore)g(only) -g(ha)n(v)n(e)f(an)i(impact)f(on)h(insertion)f(timings.)1987 -5653 y(2)p eop -%%Page: 3 3 -3 2 bop 118 291 a Fm(2.3)112 b(Coun)m(ters:)50 b(\020delimited\021)44 -b(vs.)51 b(\020\034xed)38 b(size\021)118 444 y Fh(The)33 -b(standard)g(represen)n(tation)e(of)i(gID)h(uses)e(a)h(v)-5 -b(ariable)32 b(size)h(c)n(hild)h(iden)n(ti\034er,)g(and)f(delimiters)g -(to)h(separate)d(the)118 543 y(gID)f(of)g(the)h(c)n(hild)f(no)r(de)g -(from)f(the)i(gID)f(of)g(its)g(paren)n(t.)43 b(F)-7 b(or)30 -b(example,)g(w)n(e)g(can)f(represen)n(t)g(the)i(\034fth)g(c)n(hild)f -(of)g(no)r(de)118 643 y('/23/27/1')24 b(as)j('/23/27/1/4'.)32 -b(Let)c(us)f(call)g(this)h(a)f Fg(vgID)h Fh(represen)n(tation)e(\(V)-7 -b(ariable)27 b(Size)h(Genealogical)d(ID\).)243 743 y(This)30 -b(represen)n(tation)f(allo)n(ws)f(for)i(an)n(y)g(n)n(um)n(b)r(er)g(of)g -(c)n(hildren)g(of)h(a)f(no)r(de,)h(sub)5 b(ject)30 b(only)g(to)g(the)h -(limitations)f(the)118 842 y(RDBMS)e(ma)n(y)f(ha)n(v)n(e)f(as)h(to)h -(the)g(length)f(of)h(a)f(v)-5 b(ariable)27 b(sized)g(string.)243 -942 y(Alternativ)n(ely)-7 b(,)24 b(w)n(e)f(could)h(c)n(ho)r(ose)f(to)h -(limit)g(from)g(the)g(outset)g(the)g(quan)n(tit)n(y)g(of)f(c)n(hildren) -h(that)g(a)g(no)r(de)g(ma)n(y)f(ha)n(v)n(e;)118 1042 -y(this)28 b(limit)g(w)n(ould)f(dep)r(end)i(of)e(course)f(on)i(the)g -(application.)36 b(Let)27 b(us)h(call)f(this)h(a)f Fg(fgID)h -Fh(represen)n(tation.)243 1141 y(F)-7 b(or)25 b(example,)h(if)g(no)g -(no)r(de)f(is)h(allo)n(w)n(ed)f(to)g(ha)n(v)n(e)g(more)g(than)h(25600)d -(c)n(hildren,)j(w)n(e)g(could)f(represen)n(t)g(the)h(coun)n(ters)118 -1241 y(alw)n(a)n(ys)36 b(with)i(2)f(digits.)67 b(The)38 -b(no)r(de)f(whic)n(h)h(w)n(as)f(previously)f('/23/27/1/4')d(is)k(no)n -(w)g('23270104'.)64 b(If)38 b(w)n(e)f(require)118 1340 -y(a)g(three)g(digit)h(represen)n(tation)d(of)i(no)r(des)g(\(up)h(to)f -(ab)r(out)h(4)f(million)g(c)n(hildren\),)j(then)d(it)h(will)g(b)r(e)f -(represen)n(ted)f(as)118 1440 y('023027001004'.)118 1672 -y Fm(2.4)112 b(Ordering)37 b(of)h(no)s(des)118 1825 y -Fh(F)-7 b(or)35 b(some)g(applications)g(it)h(is)f(necessary)f(to)i -(obtain)f(subtrees)g(ordered)f(according)g(to)i(some)f(sp)r(ecial)g -(rules.)60 b(F)-7 b(or)118 1925 y(instance:)220 2090 -y(1.)41 b(the)34 b(complete)g(subtree)f(starting)g(at)h(a)f(no)r(de)h -(is)g(listed)g(immediately)g(after)f(the)i(no)r(de)f(in)g(question)f -(\(\020depth)326 2189 y(\034rst\021\))220 2354 y(2.)41 -b(no)r(des)27 b(with)h(a)f(common)g(paren)n(t)g(are)g(listed)g(c)n -(hronologically)243 2519 y(F)-7 b(or)39 b(instance,)k(the)d(displa)n(y) -f(of)h(an)f(organization)f(c)n(hart)h(is)g(usually)h(required)e(to)i -(satisfy)g(at)f(least)h(the)g(\034rst)118 2619 y(condition.)h(In)29 -b(a)g(threaded)f(discussion)h(group)e(one)i(wishes)g(to)f(satisfy)h(b)r -(oth)h(conditions)e(to)h(displa)n(y)f(the)h(messages)118 -2718 y(in)20 b(a)g(thread)g(\025)f(the)i(threads)e(themselv)n(es)h -(\(i.e.,)i(c)n(hildren)e(of)g(the)g(ro)r(ot)f(no)r(de\))i(are)e -(usually)g(listed)i(in)f(in)n(v)n(erse)f(c)n(hronolical)118 -2818 y(order.)243 2917 y(T)-7 b(o)35 b(mak)n(e)f(a)h(particular)f -(ordering)g(e\036cien)n(t,)j(it)f(w)n(ould)f(b)r(e)h(a)f(nice)g -(feature)g(if)h(it)g(could)f(b)r(e)h(made)f(to)g(coincide)118 -3017 y(with)28 b(a)f(lexicographic)f(ordering)f(of)j(the)g(indices)f -(\025i.e.,)g(as)g(pro)r(duced)g(b)n(y)h(an)f(\020ORDER)h(BY)f(id)h -(ASC\021)35 b(in)27 b(SQL.)h(The)118 3117 y(lexicographic)d(ordering)h -(of)h(fgID)h(satis\034es)e(b)r(oth)i(conditions.)36 b(The)27 -b(lexicographic)f(ordering)f(of)i(vgID)g(as)g(describ)r(ed)118 -3216 y(ab)r(o)n(v)n(e)34 b(satis\034es)g(the)h(\034rst)g(requisite)f -(if)i(the)f(separator)d(has)j(the)g(minimal)g(binary)g(represen)n -(tation)e(of)i(all)f(allo)n(w)n(ed)118 3316 y(sym)n(b)r(ols)c(in)h(an)f -(index)h(\025)f(this)h(is)g(wh)n(y)f(w)n(e)g(reserv)n(ed)f(/)h(for)g -(the)i(separator.)43 b(But)31 b(the)g(second)f(prop)r(ert)n(y)g(is)g -(missing:)118 3416 y(for)d(instance,)g(the)h(index)g('/1/10')d(is)j -(lexicographically)d(b)r(efore)i('/1/2'.)243 3515 y(If)c(the)h(second)e -(prop)r(ert)n(y)g(is)i(also)e(required)g(for)h(vgID,)g(w)n(e)f(can)h -(sp)r(ecify)h(the)f(c)n(hild)h(iden)n(ti\034ers)e(with)i(coun)n(ters)e -(built)118 3615 y(in)28 b(the)g(follo)n(wing)e(w)n(a)n(y:)36 -b(represen)n(t)26 b(a)h(n)n(um)n(b)r(er)h(b)n(y)f(a)g(string)g(of)g -(digits,)h(where)243 3779 y Ff(\017)41 b Fh(the)25 b(\034rst)g(digit)h -Fc(D)896 3791 y Fb(0)958 3779 y Fh(represen)n(ts)e(the)i(length)f(in)h -(digits)f(of)g(the)h(decimal)f(expansion)f(of)i(the)f(n)n(um)n(b)r(er,) -h(min)n(us)f(one)243 3945 y Ff(\017)41 b Fh(the)28 b(follo)n(wing)e -Fa(\()p Fc(D)920 3957 y Fb(0)976 3945 y Fa(+)18 b(1\))27 -b Fh(digits)h(are)e(the)i(decimal)g(expansion)e(of)i(the)g(n)n(um)n(b)r -(er)118 4109 y(Let)g(us)f(call)h(these)f(iden)n(ti\034ers)g -Fg(m-vgID)p Fh(,)g(\020m\021)34 b(for)27 b(mo)r(di\034ed.)243 -4209 y(As)e(an)f(example,)h(the)g(no)r(de)g(whic)n(h)g(w)n(as)f -(previously)f(represen)n(ted)h(b)n(y)g(/15/3/182)d(will,)k(after)g -(this)g(mo)r(di\034cation,)118 4309 y(ha)n(v)n(e)h(the)i(index)g -(/115/03/2182.)243 4408 y(The)37 b(lexicographic)f(ordering)g(of)i -(m-vgID)f(is)h(the)g(desired)f(ordering)f(of)h(the)h(tree)g(no)r(des.) -67 b(The)38 b(cost)f(of)g(this)118 4508 y(prop)r(ert)n(y)31 -b(is)i(that)f(\(a\))h(the)g(ID)f(are)g(no)n(w)g(longer,)g(\(b\))h(no)f -(no)r(de)g(can)g(ha)n(v)n(e)g(more)f(than)i Fa(160)3106 -4478 y Fb(160)3240 4508 y Fh(c)n(hildren)f(\(actually)-7 -b(,)118 4607 y(this)32 b(is)g(a)f(non-issue\),)h(and)f(\(c\))h(the)g -(index)g(structure)f(is)h(redundan)n(t,)g(some)f(formally)f(correct)h -(indices)g(are)g(in)n(v)-5 b(alid)118 4707 y(\025e.g.,)24 -b(/316/013/11.)30 b(The)24 b(third)g(issue)g(can)g(b)r(e)g(addressed)f -(b)n(y)g(k)n(eeping)g(a)h(strict)g(con)n(trol)e(on)i(the)g(generation)f -(of)h(new)118 4807 y(indices)k(to)f(insure)g(that)h(all)f(indices)h -(are)e(formally)h(correct.)243 4906 y(The)32 b(issue)f(of)h(the)g(rev)n -(erse)e(c)n(hronological)f(indexing)j(of)f(threads)h(in)g(threaded)f -(discussion)g(groups)g(can)g(b)r(e)h(ad-)118 5006 y(dressed)d(easily)f -(enough)h(in)h(fgID:)f(coun)n(t)g(\020do)n(wn\021)36 -b(instead)29 b(of)g(\020up\021)36 b(the)30 b(c)n(hildren)f(of)g(the)h -(ro)r(ot)e(no)r(de)i(\025)f(this)h(implies)118 5106 y(only)e(an)g -(inconsequen)n(tial)f(mo)r(di\034cation)h(of)g(the)g(no)r(de)h -(insertion)e(routine,)h(as)g(sho)n(wn)f(b)r(elo)n(w.)38 -b(The)29 b(problem)e(is)h(less)118 5205 y(trivial)i(with)g(vgID;)h(in)f -(this)h(case,)f(ma)n(yb)r(e)f(a)h(thread)g(iden)n(ti\034er)g(should)g -(b)r(e)h(k)n(ept)f(in)g(a)g(di\033eren)n(t)g(\034eld)h(-)f(i.e.,)h -(repre-)118 5305 y(sen)n(ting)h(the)h(structure)f(as)g(a)h(forest)f -(rather)f(than)i(a)f(tree,)i(where)e(the)h(thread_id)f(\034eld)h -(selects)f(the)h(\020tree\021)38 b(in)33 b(the)118 5404 -y(forest.)1987 5653 y(3)p eop -%%Page: 4 4 -4 3 bop 118 291 a Fi(3)131 b(T)-11 b(ree)45 b(op)t(erations)e(using)h -(genealogical)g(indices)118 472 y Fh(In)32 b(this)f(section)g(w)n(e)g -(sho)n(w)g(ho)n(w)g(to)g(implemen)n(t)h(v)-5 b(arious)30 -b(tree)h(op)r(erations)f(using)h(gID)g(as)g(the)h(primary)e(k)n(ey)h -(in)g(the)118 572 y(no)r(de)d(table.)243 672 y(Some)h(implemen)n -(tation)h(issues)g(are)f(relev)-5 b(an)n(t)29 b(here,)h(esp)r(ecially)f -(concerning)g(the)h(utilisation)g(of)g(indices)g(b)n(y)f(the)118 -771 y(DB)f(engine.)243 871 y(W)-7 b(e)28 b(discuss)f(a)g(tree)g -(represen)n(ted)f(in)i(a)f(table)h(of)f(the)h(form)326 -1034 y Fd(CREATE)41 b(TABLE)g(tree)h(\()456 1134 y(gid)304 -b(text)42 b(PRIMARY)f(KEY,)456 1234 y(nchildren)f(integer)h(DEFAULT)f -(0,)456 1333 y(\\ldots)h(the)i(actual)e(node)h(data)326 -1433 y(\);)118 1597 y Fh(The)26 b(\034eld)g(\020nc)n(hildren\021)32 -b(is)26 b(a)f(coun)n(ter)g(for)g(the)i(n)n(um)n(b)r(er)e(of)h(c)n -(hildren)f(that)h(the)h(no)r(de)f(has)f Fe(ever)35 b -Fh(had;)27 b(w)n(e)e(assume)g(here)118 1696 y(it)j(is)g(not)f(up)r -(dated)h(when)g(no)r(des)f(or)g(subtrees)g(are)f(deleted.)243 -1796 y(Section)h(4)g(pro)n(vides)f(a)i(complete)f(implemen)n(tation)h -(of)f(these)h(op)r(erations)e(for)h(fgID)h(in)g(P)n(ostgreSQL.)118 -2028 y Fm(3.1)112 b(Computing)37 b(the)g(lev)m(el)f(of)h(a)h(no)s(de) -118 2181 y Fg(Cost:)f Fe(string)30 b(op)l(er)l(ations)g(\(no)g(table)g -(ac)l(c)l(ess\))243 2280 y Fh(This)d(is)h(a)f(pure)g(string)g(op)r -(eration,)f(no)i(table)f(access)g(is)g(required.)243 -2460 y Ff(\017)41 b Fg(vgID:)27 b Fh(coun)n(t)h(the)g(n)n(um)n(b)r(er)f -(of)g(separators)e(\('/'\))j(in)g(the)g(PK)243 2625 y -Ff(\017)41 b Fg(fgID:)27 b Fh(coun)n(t)g(the)h(n)n(um)n(b)r(er)g(of)f -(c)n(haracters)e(in)j(the)g(PK,)g(divide)g(b)n(y)f(the)h(\034xed)f -(size)h(of)f(the)h(coun)n(ters.)118 2857 y Fm(3.2)112 -b(Selecting)36 b(or)h(deleting)f(a)i(subtree)118 3010 -y Fg(Cost:)f Fe(index)30 b(sc)l(an)g(of)g(the)g(tr)l(e)l(e)243 -3173 y Ff(\017)41 b Fg(vgID:)27 b Fh(The)h(subtree)f(ro)r(oted)g(at)g -(/26/5/7)e(is)i(selected)g(b)n(y)508 3338 y Fd(...)43 -b(WHERE)e(id)i(LIKE)f('/26/5/7\045')d(AND)j(id)h(<)g('/26/5/70')243 -3503 y Ff(\017)e Fg(m-vgID:)26 b Fh(The)h(subtree)h(ro)r(oted)e(at)i -(/126/05/07)22 b(is)28 b(selected)f(b)n(y)508 3668 y -Fd(...)43 b(WHERE)e(id)i(LIKE)f('/126/06/07\045')243 -3833 y Ff(\017)f Fg(fgID:)27 b Fh(The)h(subtree)f(ro)r(oted)g(at)g -(260507)e(is)i(selected)h(b)n(y)508 3997 y Fd(...)43 -b(WHERE)e(id)i(LIKE)f('260507\045')118 4229 y Fm(3.3)112 -b(Selecting)36 b(the)h(direct)f(c)m(hildren)g(of)i(a)g(no)s(de)118 -4382 y Fg(Cost:)f Fe(index)30 b(sc)l(an)g(of)g(the)g(tr)l(e)l(e)243 -4562 y Ff(\017)41 b Fg(vgID:)27 b Fh(The)h(direct)f(c)n(hildren)g(of)h -(/26/5/7)c(are)j(selected)g(b)n(y)508 4727 y Fd(...)43 -b(WHERE)e(id)i(LIKE)f('/26/5/7/\045')d(AND)j(id)h(NOT)f(LIKE)g -('26/5/7/\045/\045')243 4892 y Ff(\017)f Fg(m-vgID:)26 -b Fh(The)h(direct)h(c)n(hildren)f(of)g(/26/5/7)e(are)h(selected)i(b)n -(y)508 5056 y Fd(...)43 b(WHERE)e(id)i(LIKE)f('/126/06/07/\045')37 -b(AND)43 b(id)f(NOT)h(LIKE)f('/126/05/07/\045/\045)o(')243 -5221 y Ff(\017)f Fg(fgID:)27 b Fh(The)h(direct)f(c)n(hildren)g(of)h -(260507)c(are)j(selected)g(b)n(y)508 5386 y Fd(...)43 -b(WHERE)e(id)i(LIKE)f('260507\045')d(AND)k(char_length\(id\))37 -b(=)43 b(\(char_length\('26)o(05)o(07')o(\)+)o(2\))1987 -5653 y Fh(4)p eop -%%Page: 5 5 -5 4 bop 118 291 a Fm(3.4)112 b(Inserting)37 b(a)h(no)s(de)g(or)f(a)h -(subtree)118 444 y Fg(Cost:)f Fe(index)30 b(sc)l(an)g(of)g(the)g(tr)l -(e)l(e)f(+)h(string)f(and)h(math)g(op)l(er)l(ations)243 -543 y Fh(Insertion)f(is)g(a)h(pro)r(cedural)e(op)r(eration.)42 -b(As)30 b(eac)n(h)f(RDBMS)h(has)f(a)h(di\033eren)n(t)f(w)n(a)n(y)g(of)g -(de\034ning)h(pro)r(cedures,)f(w)n(e)118 643 y(will)f(just)g(describ)r -(e)f(here)g(the)h(necessary)e(steps.)37 b(Examples)27 -b(for)g(P)n(ostgreSQL)f(are)h(pro)n(vided)f(in)i(4.)243 -743 y(In)22 b(order)f(to)h(insert)g(a)g(new)g(c)n(hild)h(of)f -(\020daddy\021)28 b(\(either)23 b(one)f(of)g(/26/5/7,)e(/126/05/07)d -(or)22 b(260507)d(in)k(the)f(examples)118 842 y(ab)r(o)n(v)n(e\))27 -b(y)n(ou)f(ha)n(v)n(e)h(to)220 1008 y(1.)41 b(add)27 -b(one)g(to)h(the)g(n)n(um)n(b)r(er)f(of)g(c)n(hildren)h(of)f -(\020daddy\021)508 1174 y Fd(UPDATE)41 b(tree)h(SET)h(nchildren)c(=)k -(\(nchildren)d(+)j(1\))g(WHERE)e(ID)i(=)g(``daddy'';)220 -1340 y Fh(2.)e(enco)r(de)27 b(the)h(n)n(um)n(b)r(er)f(of)g(c)n(hildren) -g(of)h(\020daddy\021)33 b(in)28 b(base)f(160,)f(bring)h(it)h(to)f(the)h -(correct)e(format)h(dep)r(ending)h(on)326 1440 y(the)c(v)-5 -b(arian)n(t)23 b(of)h(gID)g(\(pad)g(with)h(0)e(or)g(not,)i(prep)r(end)f -(a)g(digit)g(coun)n(ter)f(or)g(not,)i(prep)r(end)f(/)g(or)f(not,)i -(coun)n(t)e(do)n(wn)326 1540 y(or)j(up,)i(.)14 b(.)g(.)g(\))37 -b(and)28 b(app)r(end)f(it)h(to)g(daddy's)f(gID)g(to)h(obtain)f(the)h -(new)g(no)r(de's)f(gID.)220 1706 y(3.)41 b(insert)27 -b(the)h(new)f(no)r(de)243 1872 y(When)35 b(inserting)g(a)f(subtree,)j -(the)e(index)g(of)g(the)h(ro)r(ot)e(of)h(the)g(subtree)g(has)f(to)h(b)r -(e)h(computed)f(as)f(ab)r(o)n(v)n(e,)i(and)118 1971 y(prep)r(ended)28 -b(to)f(the)h(index)g(of)f(eac)n(h)g(no)r(de)h(of)f(the)h(subtree)f(b)r -(efore)h(insertion.)243 2071 y(Remark)e(that)i(only)f(the)h(paren)n(t)f -(no)r(de)h(has)f(to)g(b)r(e)h(up)r(dated)g(on)f(insertion.)118 -2303 y Fm(3.5)112 b(Selecting)36 b(the)h(ancestors)h(of)g(a)g(no)s(de) -118 2457 y Fg(Cost:)f Fe(index)30 b(sc)l(an)g(of)g(the)g(tr)l(e)l(e)243 -2556 y Fh(Y)-7 b(ou)27 b(can)g(sp)r(ecify)h(all)g(ancestors)d(of)j(a)f -(no)r(de)h(in)f(a)h(single)f(SQL)g(statemen)n(t;)g(for)g(instance)h -(for)f(vgID)326 2722 y Fd(...)42 b(WHERE)f('/25/6/7')f(LIKE)i(\(id)g -(||)h('/\045'\))f(AND)g(id)h(<)g('/25/6/7')118 2888 y -Fh(The)31 b(second)e(part)h(of)h(the)g(clause,)f(while)h(logically)e -(redundan)n(t,)h(is)h(a)f(\020hin)n(t\021)37 b(to)30 -b(the)h(optimizer.)45 b(A)n(t)31 b(least)f(in)g(P)n(ost-)118 -2988 y(greSQL,)c(without)i(it)g(the)g(optimizer)f(will)h(c)n(ho)r(ose)e -(a)i(sequen)n(tial)e(scan)h(of)h(the)g(table)f(and)h(disregard)d(the)j -(index.)118 3220 y Fm(3.6)112 b(Selecting)36 b(all)g(lea)m(v)m(es)118 -3374 y Fg(Cost:)h Fe(sc)l(an)30 b(of)g(the)g(tr)l(e)l(e)243 -3473 y Fh(A)e(leaf)f(is)g(a)h(no)r(de)f(without)h(descendan)n(ts:)36 -b(it)28 b(has)f(0)g(c)n(hildren.)37 b(Hence)326 3639 -y Fd(...)42 b(WHERE)f(nchildren)f(=)j(0)118 3805 y Fh(If)28 -b(this)g(t)n(yp)r(e)g(of)f(query)g(is)h(often)f(necessary)-7 -b(,)26 b(y)n(ou)h(ma)n(y)g(b)r(e)h(w)n(ell)f(advised)g(to)g(k)n(eep)g -(an)h(index)f(on)h(tree\(nc)n(hildren\).)118 4038 y Fm(3.7)112 -b(Determining)35 b(if)i(A)g(is)g(a)h(descendan)m(t)g(of)g(B)118 -4191 y Fg(Cost:)f Fe(string)30 b(op)l(er)l(ations,)h(no)f(table)g(ac)l -(c)l(ess)243 4291 y Fh(This)d(is)h(a)f(pure)g(string)g(op)r(eration)f -(on)i(the)g(indices,)f(no)g(table)h(access)e(is)i(necessary)-7 -b(.)118 4565 y Fi(4)131 b(Putting)45 b(it)f(all)h(together:)57 -b(a)44 b(P)l(ostgreSQL)f(implemen)l(tation)118 4747 y -Fh(h)n(ttp://www.p)r(ostgresql.org/mhonarc/pgsq)o(l-sql/)o(20)o(00)o -(-0)o(4/)o(msg0)o(02)o(67)o(.h)n(tml)243 4847 y(W)-7 -b(e)30 b(describ)r(e)g(here)g(a)g(small)f(pac)n(k)-5 -b(age)29 b(that)i(can)e(b)r(e)i(used)f(for)g(implemen)n(ting)g(gID)g -(on)g(P)n(ostgreSQL.)f(It)i(can)e(b)r(e)118 4946 y(found)f(at)f(<h)n -(ttp://...>)243 5046 y(The)21 b(pac)n(k)-5 b(age)21 b(uses)g(the)h(pro) -r(cedural)e(language)h(PL/PGsql.)35 b(A)22 b(b)r(etter)g(implemen)n -(tation)g(w)n(ould)f(probably)g(de\034ne)118 5145 y(the)28 -b(gID)g(as)f(new)g(P)n(ostgres)f(t)n(yp)r(es,)i(and)f(co)r(de)g(all)h -(this)g(in)f(C.)243 5245 y(The)g(\034les)h(should)f(b)r(e)h(loaded)f -(in)h(alphab)r(etical)f(order.)1987 5653 y(5)p eop -%%Page: 6 6 -6 5 bop 118 291 a Fm(4.1)112 b(tree0_enco)s(ding.sql)118 -444 y Fh(This)28 b(\034le)f(de\034nes)h(and)f(p)r(opulates)h(the)f -(table)h(_b160_digits)d(of)j(\020digits\021)33 b(in)28 -b(base)f(160,)326 604 y Fd(CREATE)41 b(TABLE)g(\\_b160\\_digits)d -(\(deci)j(integer,)f(code)i(char\);)118 764 y Fh(and)28 -b(the)f(t)n(w)n(o)g(functions)326 924 y Fd(CREATE)41 -b(FUNCTION)f(\\_b160\\_encode\(i)o(nt)o(eg)o(er\))d(RETURNS)j(string) -413 1024 y(AS)j('....')e(LANGUAGE)f('plpgsql';)326 1124 -y(CREATE)h(FUNCTION)f(\\_b160\\_encode\(i)o(nt)o(eg)o(er,)o(in)o(te)o -(ger)o(\))d(RETURNS)k(string)413 1223 y(AS)i('....')e(LANGUAGE)f -('plpgsql';)118 1384 y Fh(The)22 b(\034rst)h(function)f(returns)g(a)g -(v)-5 b(ariable)21 b(size)h(enco)r(ding;)i(the)f(second)e(a)h(\034xed)h -(size)f(enco)r(ding)g(\(the)h(second)e(parameter)118 -1483 y(is)g(the)h(size\),)g(and)f(raises)e(an)i(exception)g(if)h(the)f -(n)n(um)n(b)r(er)g(is)g(to)r(o)g(large)e(to)i(b)r(e)h(represen)n(ted)e -(with)h(the)h(requested)e(n)n(um)n(b)r(er)118 1583 y(of)28 -b(digits.)118 1814 y Fm(4.2)112 b(tree1_de\034ne.sql)118 -1967 y Fh(This)28 b(\034le)f(pro)n(vides)f(a)i(function)326 -2127 y Fd(CREATE)41 b(FUNCTION)f(_tree_create\(tex)o(t,)o(in)o(teg)o -(er)o(,t)o(ext)o(,t)o(ex)o(t\))d(RETURNS)k(bpchar)413 -2227 y(AS)i('....')e(LANGUAGE)f('plpgsql';)118 2387 y -Fh(that)e(creates)f(a)h(tree)f(infrastructure)g(of)h(either)g(fgID)g -(or)f(vgID.)h(Assuming)f(y)n(ou)g(ha)n(v)n(e)g(a)h(table)f(\020m)n -(ytable\021)44 b(with)118 2487 y(primary)26 b(k)n(ey)h(\020m)n -(yid\021,)g(then)h(calling)326 2647 y Fd(SELECT)41 b(_tree_create\('m)o -(yt)o(ree)o(',)o(2,')o(my)o(ta)o(ble)o(',)o('m)o(yid)o('\))o(;)118 -2807 y Fh(will)28 b(cause:)220 2967 y(1.)41 b(the)28 -b(creation)e(of)i(a)f(table)508 3131 y Fd(CREATE)41 b(TABLE)h -(mytree_bkg\()683 3230 y(gid)g(text)g(PRIMARY)e(KEY,)683 -3330 y(nchildren)f(int,)683 3429 y(sid)j(integer)f(REFERENCES)e -(mytable\(myid\))508 3529 y(\);)508 3629 y(CREATE)i(UNIQUE)g(INDEX)h -(mytree_bkg_sid)37 b(ON)43 b(mytree_bkg\(sid\);)326 3792 -y Fh(for)27 b(the)h(tree)f(structure.)220 3955 y(2.)41 -b(the)28 b(creation)e(of)i(a)f(view)508 4118 y Fd(CREATE)41 -b(VIEW)h(mytree)f(AS)639 4218 y(SELECT)g(t.gid,n.*)900 -4317 y(FROM)h(mytable)f(n,)i(mytree_bkg)c(t)900 4417 -y(WHERE)j(t.sid=n.myid;)326 4580 y Fh(with:)35 b(a)23 -b(trigger)e(on)i(UPD)n(A)-7 b(TE)25 b(that)e(blo)r(c)n(ks)g(up)r -(dating)g(the)h(gid)f(and)g(allo)n(ws)f(up)r(dating)h(the)g(no)r(de)h -(data,)f(a)g(rule)326 4680 y(on)k(DELETE)i(that)f(deletes)f(the)h -(corresp)r(onding)e(en)n(try)h(b)r(oth)h(in)g(m)n(ytree_bkg)d(and)j(m)n -(ytable,)f(and)g(a)g(trigger)326 4779 y(ON)h(INSER)-7 -b(T)30 b(that)f(raises)e(an)h(exception)g(and)g(informs)h(the)f(user)g -(to)h(use)f(the)h(insertion)f(function)h(describ)r(ed)326 -4879 y(b)r(elo)n(w.)220 5042 y(3.)41 b(t)n(w)n(o)26 b(insertion)h -(functions)h(that)g(compute)g(automatically)e(the)i(gID)g(of)f(the)h -(new)g(no)r(de:)425 5205 y Ff(\017)41 b Fh(a)27 b(function)i(m)n -(ytree_insert\(text,text,in)n(teger,text\))d(for)h(insertion)g(sim)n -(ultaneosly)f(in)i(b)r(oth)g(tables:)508 5305 y(m)n -(ytree_insert\('2201','hello',0,'not)15 b(m)n(uc)n(h'\))j(inserts)g(a)g -(new)g(c)n(hild)h(of)f(2201)f(with)h(data1='hello',)h(data2=0)508 -5404 y(and)28 b(data3='not)e(m)n(uc)n(h')1987 5653 y(6)p -eop -%%Page: 7 7 -7 6 bop 425 291 a Ff(\017)41 b Fh(a)27 b(function)i(m)n -(ytree_insert_no)r(de\(text,in)n(teger\))c(for)i(insertion)g(in)h(m)n -(ytree_bkg)508 390 y(m)n(ytree_insert\('2201',25\))c(inserts)j(in)h(m)n -(ytree_bkg)e(a)h(new)h(c)n(hild)f(of)h(2201)d(with)j(sid=25)220 -556 y(4.)41 b(a)27 b(function)h(m)n(ytree_mo)n(v)n(e\(text,text\))e -(that)i(mo)n(v)n(es)e(subtrees:)326 656 y(m)n(ytree_mo)n(v)n -(e\('2201','23'\))d(mo)n(v)n(es)j(the)i(subtree)f(ro)r(oted)g(at)g -(2201)f(to)h(a)h(place)f(b)r(elo)n(w)g(23)f(\(ma)n(yb)r(e)i(2307\))220 -822 y(5.)41 b(a)c(function)g(m)n(ytree_len\(\))g(that)h(returns)e(the)i -(length)f(of)g(the)h(enco)r(dings)f(used)g(in)h(the)f(gID)g(\(2)h -(here;)j(0)c(if)326 922 y(v)-5 b(ariable)26 b(size\).)118 -1196 y Fi(5)131 b(Non-tree)44 b(hierarc)l(hies)118 1378 -y Fh(sequence)22 b(as)f(id,)j(table)e(with)h(\(id,g-index\))f(with)g(p) -r(ossibly)g(man)n(y)g(g-indices)f(for)h(eac)n(h)f(id)h(\(if)h(TOO)f -(man)n(y)-7 b(,)23 b(bad)f(mo)r(del:)118 1478 y(list)28 -b(all)f(genealogies,)f(i.e.,)h(paths)h(from)f(the)h(ro)r(ot\))118 -1752 y Fi(References)160 1934 y Fh([1])41 b(Philip)28 -b(Greenspun,)g Fe(T)-6 b(r)l(e)l(es)29 b(in)h(Or)l(acle)g(SQL)p -Fh(,)d(in)h Fg(SQL)k(for)g(W)-8 b(eb)31 b(Nerds)289 2033 -y Fh(<h)n(ttp://photo.net/sql/trees.h)n(tml>)160 2200 -y([2])41 b(Jo)r(e)27 b(Celk)n(o,)f Fe(SQL)j(for)i(Smarties)p -Fh(,)d(in)g Fg(DBMS)j(Online)p Fh(,)26 b(Marc)n(h)h(to)g(June)h(1996) -289 2299 y(<h)n(ttp://www.dbmsmag.com/9603d06.h)n(tml>)289 -2399 y(<h)n(ttp://www.dbmsmag.com/9604d06.h)n(tml>)289 -2498 y(<h)n(ttp://www.dbmsmag.com/9605d06.h)n(tml>)289 -2598 y(<h)n(ttp://www.dbmsmag.com/9606d06.h)n(tml>)160 -2764 y([3])41 b(Graeme)26 b(Birc)n(hall,)h Fg(DB2)32 -b(UDB)g(V6.1)f(SQL)h(Co)s(okb)s(o)s(ok)p Fh(,)289 2864 -y(<h)n(ttp://ourw)n(orld.compuserv)n(e.com/homepag)o(es/)o(Gra)o -(eme_Bir)o(c)n(ha)o(ll/HTM_CO)o(OK)o(.HTM>)1987 5653 -y(7)p eop -%%Trailer -end -userdict /end-hook known{end-hook}if -%%EOF diff --git a/source/lib/ldb/ldb_tdb/ldb_cache.c b/source/lib/ldb/ldb_tdb/ldb_cache.c deleted file mode 100644 index c90885bfab8..00000000000 --- a/source/lib/ldb/ldb_tdb/ldb_cache.c +++ /dev/null @@ -1,561 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - * Name: ldb - * - * Component: ldb tdb cache functions - * - * Description: cache special records in a ldb/tdb - * - * Author: Andrew Tridgell - */ - -#include "includes.h" -#include "ldb/include/includes.h" - -#include "ldb/ldb_tdb/ldb_tdb.h" - -#define LTDB_FLAG_CASE_INSENSITIVE (1<<0) -#define LTDB_FLAG_INTEGER (1<<1) -#define LTDB_FLAG_HIDDEN (1<<2) -#define LTDB_FLAG_OBJECTCLASS (1<<3) - -int ltdb_attribute_flags(struct ldb_module *module, const char *attr_name); - -/* valid attribute flags */ -static const struct { - const char *name; - int value; -} ltdb_valid_attr_flags[] = { - { "CASE_INSENSITIVE", LTDB_FLAG_CASE_INSENSITIVE }, - { "INTEGER", LTDB_FLAG_INTEGER }, - { "HIDDEN", LTDB_FLAG_HIDDEN }, - { "NONE", 0 }, - { NULL, 0 } -}; - - -/* - de-register any special handlers for @ATTRIBUTES -*/ -static void ltdb_attributes_unload(struct ldb_module *module) -{ - struct ltdb_private *ltdb = - (struct ltdb_private *)module->private_data; - struct ldb_message *msg; - int i; - - if (ltdb->cache->attributes == NULL) { - /* no previously loaded attributes */ - return; - } - - msg = ltdb->cache->attributes; - for (i=0;i<msg->num_elements;i++) { - ldb_remove_attrib_handler(module->ldb, msg->elements[i].name); - } - - talloc_free(ltdb->cache->attributes); - ltdb->cache->attributes = NULL; -} - -/* - add up the attrib flags for a @ATTRIBUTES element -*/ -static int ltdb_attributes_flags(struct ldb_message_element *el, unsigned *v) -{ - int i; - unsigned value = 0; - for (i=0;i<el->num_values;i++) { - int j; - for (j=0;ltdb_valid_attr_flags[j].name;j++) { - if (strcmp(ltdb_valid_attr_flags[j].name, - (char *)el->values[i].data) == 0) { - value |= ltdb_valid_attr_flags[j].value; - break; - } - } - if (ltdb_valid_attr_flags[j].name == NULL) { - return -1; - } - } - *v = value; - return 0; -} - -/* - register any special handlers from @ATTRIBUTES -*/ -static int ltdb_attributes_load(struct ldb_module *module) -{ - struct ltdb_private *ltdb = - (struct ltdb_private *)module->private_data; - struct ldb_message *msg = ltdb->cache->attributes; - struct ldb_dn *dn; - int i; - - dn = ldb_dn_explode(module->ldb, LTDB_ATTRIBUTES); - if (dn == NULL) goto failed; - - if (ltdb_search_dn1(module, dn, msg) == -1) { - talloc_free(dn); - goto failed; - } - talloc_free(dn); - /* mapping these flags onto ldap 'syntaxes' isn't strictly correct, - but its close enough for now */ - for (i=0;i<msg->num_elements;i++) { - unsigned flags; - const char *syntax; - const struct ldb_attrib_handler *h; - struct ldb_attrib_handler h2; - - if (ltdb_attributes_flags(&msg->elements[i], &flags) != 0) { - ldb_debug(module->ldb, LDB_DEBUG_ERROR, "Invalid @ATTRIBUTES element for '%s'\n", msg->elements[i].name); - goto failed; - } - switch (flags & ~LTDB_FLAG_HIDDEN) { - case 0: - syntax = LDB_SYNTAX_OCTET_STRING; - break; - case LTDB_FLAG_CASE_INSENSITIVE: - syntax = LDB_SYNTAX_DIRECTORY_STRING; - break; - case LTDB_FLAG_INTEGER: - syntax = LDB_SYNTAX_INTEGER; - break; - default: - ldb_debug(module->ldb, LDB_DEBUG_ERROR, - "Invalid flag combination 0x%x for '%s' in @ATTRIBUTES\n", - flags, msg->elements[i].name); - goto failed; - } - - h = ldb_attrib_handler_syntax(module->ldb, syntax); - if (h == NULL) { - ldb_debug(module->ldb, LDB_DEBUG_ERROR, - "Invalid attribute syntax '%s' for '%s' in @ATTRIBUTES\n", - syntax, msg->elements[i].name); - goto failed; - } - h2 = *h; - h2.attr = msg->elements[i].name; - h2.flags |= LDB_ATTR_FLAG_ALLOCATED; - if (ldb_set_attrib_handlers(module->ldb, &h2, 1) != 0) { - goto failed; - } - } - - return 0; -failed: - return -1; -} - - -/* - register any subclasses from @SUBCLASSES -*/ -static int ltdb_subclasses_load(struct ldb_module *module) -{ - struct ltdb_private *ltdb = - (struct ltdb_private *)module->private_data; - struct ldb_message *msg = ltdb->cache->subclasses; - struct ldb_dn *dn; - int i, j; - - dn = ldb_dn_explode(module->ldb, LTDB_SUBCLASSES); - if (dn == NULL) goto failed; - - if (ltdb_search_dn1(module, dn, msg) == -1) { - talloc_free(dn); - goto failed; - } - talloc_free(dn); - - for (i=0;i<msg->num_elements;i++) { - struct ldb_message_element *el = &msg->elements[i]; - for (j=0;j<el->num_values;j++) { - if (ldb_subclass_add(module->ldb, el->name, - (char *)el->values[j].data) != 0) { - goto failed; - } - } - } - - return 0; -failed: - return -1; -} - - -/* - de-register any @SUBCLASSES -*/ -static void ltdb_subclasses_unload(struct ldb_module *module) -{ - struct ltdb_private *ltdb = - (struct ltdb_private *)module->private_data; - struct ldb_message *msg; - int i; - - if (ltdb->cache->subclasses == NULL) { - /* no previously loaded subclasses */ - return; - } - - msg = ltdb->cache->subclasses; - for (i=0;i<msg->num_elements;i++) { - ldb_subclass_remove(module->ldb, msg->elements[i].name); - } - - talloc_free(ltdb->cache->subclasses); - ltdb->cache->subclasses = NULL; -} - - -/* - initialise the baseinfo record -*/ -static int ltdb_baseinfo_init(struct ldb_module *module) -{ - struct ltdb_private *ltdb = - (struct ltdb_private *)module->private_data; - struct ldb_message *msg; - struct ldb_message_element el; - struct ldb_val val; - int ret; - /* the initial sequence number must be different from the one - set in ltdb_cache_free(). Thanks to Jon for pointing this - out. */ - const char *initial_sequence_number = "1"; - - ltdb->sequence_number = atof(initial_sequence_number); - - msg = talloc(ltdb, struct ldb_message); - if (msg == NULL) { - goto failed; - } - - msg->num_elements = 1; - msg->elements = ⪙ - msg->dn = ldb_dn_explode(msg, LTDB_BASEINFO); - if (!msg->dn) { - goto failed; - } - el.name = talloc_strdup(msg, LTDB_SEQUENCE_NUMBER); - if (!el.name) { - goto failed; - } - el.values = &val; - el.num_values = 1; - el.flags = 0; - val.data = (uint8_t *)talloc_strdup(msg, initial_sequence_number); - if (!val.data) { - goto failed; - } - val.length = 1; - - ret = ltdb_store(module, msg, TDB_INSERT); - - talloc_free(msg); - - return ret; - -failed: - talloc_free(msg); - errno = ENOMEM; - return -1; -} - -/* - free any cache records - */ -static void ltdb_cache_free(struct ldb_module *module) -{ - struct ltdb_private *ltdb = - (struct ltdb_private *)module->private_data; - - ltdb->sequence_number = 0; - talloc_free(ltdb->cache); - ltdb->cache = NULL; -} - -/* - force a cache reload -*/ -int ltdb_cache_reload(struct ldb_module *module) -{ - ltdb_attributes_unload(module); - ltdb_subclasses_unload(module); - ltdb_cache_free(module); - return ltdb_cache_load(module); -} - -/* - load the cache records -*/ -int ltdb_cache_load(struct ldb_module *module) -{ - struct ltdb_private *ltdb = - (struct ltdb_private *)module->private_data; - struct ldb_dn *baseinfo_dn = NULL; - struct ldb_dn *indexlist_dn = NULL; - uint64_t seq; - struct ldb_message *baseinfo = NULL; - - /* a very fast check to avoid extra database reads */ - if (ltdb->cache != NULL && - tdb_get_seqnum(ltdb->tdb) == ltdb->tdb_seqnum) { - return 0; - } - - if (ltdb->cache == NULL) { - ltdb->cache = talloc_zero(ltdb, struct ltdb_cache); - if (ltdb->cache == NULL) goto failed; - ltdb->cache->indexlist = talloc_zero(ltdb->cache, struct ldb_message); - ltdb->cache->subclasses = talloc_zero(ltdb->cache, struct ldb_message); - ltdb->cache->attributes = talloc_zero(ltdb->cache, struct ldb_message); - if (ltdb->cache->indexlist == NULL || - ltdb->cache->subclasses == NULL || - ltdb->cache->attributes == NULL) { - goto failed; - } - } - - baseinfo = talloc(ltdb->cache, struct ldb_message); - if (baseinfo == NULL) goto failed; - - baseinfo_dn = ldb_dn_explode(module->ldb, LTDB_BASEINFO); - if (baseinfo_dn == NULL) goto failed; - - if (ltdb_search_dn1(module, baseinfo_dn, baseinfo) == -1) { - goto failed; - } - - /* possibly initialise the baseinfo */ - if (!baseinfo->dn) { - if (ltdb_baseinfo_init(module) != 0) { - goto failed; - } - if (ltdb_search_dn1(module, baseinfo_dn, baseinfo) != 1) { - goto failed; - } - } - - ltdb->tdb_seqnum = tdb_get_seqnum(ltdb->tdb); - - /* if the current internal sequence number is the same as the one - in the database then assume the rest of the cache is OK */ - seq = ldb_msg_find_attr_as_uint64(baseinfo, LTDB_SEQUENCE_NUMBER, 0); - if (seq == ltdb->sequence_number) { - goto done; - } - ltdb->sequence_number = seq; - - talloc_free(ltdb->cache->last_attribute.name); - memset(<db->cache->last_attribute, 0, sizeof(ltdb->cache->last_attribute)); - - ltdb_attributes_unload(module); - ltdb_subclasses_unload(module); - - talloc_free(ltdb->cache->indexlist); - talloc_free(ltdb->cache->subclasses); - - ltdb->cache->indexlist = talloc_zero(ltdb->cache, struct ldb_message); - ltdb->cache->subclasses = talloc_zero(ltdb->cache, struct ldb_message); - ltdb->cache->attributes = talloc_zero(ltdb->cache, struct ldb_message); - if (ltdb->cache->indexlist == NULL || - ltdb->cache->subclasses == NULL || - ltdb->cache->attributes == NULL) { - goto failed; - } - - indexlist_dn = ldb_dn_explode(module->ldb, LTDB_INDEXLIST); - if (indexlist_dn == NULL) goto failed; - - if (ltdb_search_dn1(module, indexlist_dn, ltdb->cache->indexlist) == -1) { - goto failed; - } - - if (ltdb_attributes_load(module) == -1) { - goto failed; - } - if (ltdb_subclasses_load(module) == -1) { - goto failed; - } - -done: - talloc_free(baseinfo); - talloc_free(baseinfo_dn); - talloc_free(indexlist_dn); - return 0; - -failed: - talloc_free(baseinfo); - talloc_free(baseinfo_dn); - talloc_free(indexlist_dn); - return -1; -} - - -/* - increase the sequence number to indicate a database change -*/ -int ltdb_increase_sequence_number(struct ldb_module *module) -{ - struct ltdb_private *ltdb = - (struct ltdb_private *)module->private_data; - struct ldb_message *msg; - struct ldb_message_element el[2]; - struct ldb_val val; - struct ldb_val val_time; - time_t t = time(NULL); - char *s = NULL; - int ret; - - msg = talloc(ltdb, struct ldb_message); - if (msg == NULL) { - errno = ENOMEM; - return -1; - } - - s = talloc_asprintf(msg, "%llu", ltdb->sequence_number+1); - if (!s) { - errno = ENOMEM; - return -1; - } - - msg->num_elements = ARRAY_SIZE(el); - msg->elements = el; - msg->dn = ldb_dn_explode(msg, LTDB_BASEINFO); - if (msg->dn == NULL) { - talloc_free(msg); - errno = ENOMEM; - return -1; - } - el[0].name = talloc_strdup(msg, LTDB_SEQUENCE_NUMBER); - if (el[0].name == NULL) { - talloc_free(msg); - errno = ENOMEM; - return -1; - } - el[0].values = &val; - el[0].num_values = 1; - el[0].flags = LDB_FLAG_MOD_REPLACE; - val.data = (uint8_t *)s; - val.length = strlen(s); - - el[1].name = talloc_strdup(msg, LTDB_MOD_TIMESTAMP); - if (el[1].name == NULL) { - talloc_free(msg); - errno = ENOMEM; - return -1; - } - el[1].values = &val_time; - el[1].num_values = 1; - el[1].flags = LDB_FLAG_MOD_REPLACE; - - s = ldb_timestring(msg, t); - if (s == NULL) { - return -1; - } - - val_time.data = (uint8_t *)s; - val_time.length = strlen(s); - - ret = ltdb_modify_internal(module, msg); - - talloc_free(msg); - - if (ret == 0) { - ltdb->sequence_number += 1; - } - - return ret; -} - - -/* - return the attribute flags from the @ATTRIBUTES record - for the given attribute -*/ -int ltdb_attribute_flags(struct ldb_module *module, const char *attr_name) -{ - struct ltdb_private *ltdb = - (struct ltdb_private *)module->private_data; - const struct ldb_message_element *attr_el; - int i, j, ret=0; - - if (ltdb->cache->last_attribute.name && - ldb_attr_cmp(ltdb->cache->last_attribute.name, attr_name) == 0) { - return ltdb->cache->last_attribute.flags; - } - - /* objectclass is a special default case */ - if (ldb_attr_cmp(attr_name, LTDB_OBJECTCLASS) == 0) { - ret = LTDB_FLAG_OBJECTCLASS | LTDB_FLAG_CASE_INSENSITIVE; - } - - attr_el = ldb_msg_find_element(ltdb->cache->attributes, attr_name); - - if (!attr_el) { - /* check if theres a wildcard attribute */ - attr_el = ldb_msg_find_element(ltdb->cache->attributes, "*"); - - if (!attr_el) { - return ret; - } - } - - for (i = 0; i < attr_el->num_values; i++) { - for (j=0; ltdb_valid_attr_flags[j].name; j++) { - if (strcmp(ltdb_valid_attr_flags[j].name, - (char *)attr_el->values[i].data) == 0) { - ret |= ltdb_valid_attr_flags[j].value; - } - } - } - - talloc_free(ltdb->cache->last_attribute.name); - - ltdb->cache->last_attribute.name = talloc_strdup(ltdb->cache, attr_name); - ltdb->cache->last_attribute.flags = ret; - - return ret; -} - -int ltdb_check_at_attributes_values(const struct ldb_val *value) -{ - int i; - - for (i = 0; ltdb_valid_attr_flags[i].name != NULL; i++) { - if ((strcmp(ltdb_valid_attr_flags[i].name, (char *)value->data) == 0)) { - return 0; - } - } - - return -1; -} - diff --git a/source/lib/ldb/ldb_tdb/ldb_index.c b/source/lib/ldb/ldb_tdb/ldb_index.c deleted file mode 100644 index 672bc1f6259..00000000000 --- a/source/lib/ldb/ldb_tdb/ldb_index.c +++ /dev/null @@ -1,1179 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - * Name: ldb - * - * Component: ldb tdb backend - indexing - * - * Description: indexing routines for ldb tdb backend - * - * Author: Andrew Tridgell - */ - -#include "includes.h" -#include "ldb/include/includes.h" - -#include "ldb/ldb_tdb/ldb_tdb.h" - -/* - find an element in a list, using the given comparison function and - assuming that the list is already sorted using comp_fn - - return -1 if not found, or the index of the first occurance of needle if found -*/ -static int ldb_list_find(const void *needle, - const void *base, size_t nmemb, size_t size, - comparison_fn_t comp_fn) -{ - const char *base_p = (const char *)base; - size_t min_i, max_i, test_i; - - if (nmemb == 0) { - return -1; - } - - min_i = 0; - max_i = nmemb-1; - - while (min_i < max_i) { - int r; - - test_i = (min_i + max_i) / 2; - /* the following cast looks strange, but is - correct. The key to understanding it is that base_p - is a pointer to an array of pointers, so we have to - dereference it after casting to void **. The strange - const in the middle gives us the right type of pointer - after the dereference (tridge) */ - r = comp_fn(needle, *(void * const *)(base_p + (size * test_i))); - if (r == 0) { - /* scan back for first element */ - while (test_i > 0 && - comp_fn(needle, *(void * const *)(base_p + (size * (test_i-1)))) == 0) { - test_i--; - } - return test_i; - } - if (r < 0) { - if (test_i == 0) { - return -1; - } - max_i = test_i - 1; - } - if (r > 0) { - min_i = test_i + 1; - } - } - - if (comp_fn(needle, *(void * const *)(base_p + (size * min_i))) == 0) { - return min_i; - } - - return -1; -} - -struct dn_list { - unsigned int count; - char **dn; -}; - -/* - return the dn key to be used for an index - caller frees -*/ -static struct ldb_dn *ldb_dn_key(struct ldb_context *ldb, - const char *attr, const struct ldb_val *value) -{ - struct ldb_dn *ret; - char *dn; - struct ldb_val v; - const struct ldb_attrib_handler *h; - char *attr_folded; - - attr_folded = ldb_attr_casefold(ldb, attr); - if (!attr_folded) { - return NULL; - } - - h = ldb_attrib_handler(ldb, attr); - if (h->canonicalise_fn(ldb, ldb, value, &v) != 0) { - /* canonicalisation can be refused. For example, - a attribute that takes wildcards will refuse to canonicalise - if the value contains a wildcard */ - talloc_free(attr_folded); - return NULL; - } - if (ldb_should_b64_encode(&v)) { - char *vstr = ldb_base64_encode(ldb, (char *)v.data, v.length); - if (!vstr) return NULL; - dn = talloc_asprintf(ldb, "%s:%s::%s", LTDB_INDEX, attr_folded, vstr); - talloc_free(vstr); - if (v.data != value->data) { - talloc_free(v.data); - } - talloc_free(attr_folded); - if (dn == NULL) return NULL; - goto done; - } - - dn = talloc_asprintf(ldb, "%s:%s:%.*s", - LTDB_INDEX, attr_folded, (int)v.length, (char *)v.data); - - if (v.data != value->data) { - talloc_free(v.data); - } - talloc_free(attr_folded); - -done: - ret = ldb_dn_explode(ldb, dn); - talloc_free(dn); - return ret; -} - -/* - see if a attribute value is in the list of indexed attributes -*/ -static int ldb_msg_find_idx(const struct ldb_message *msg, const char *attr, - unsigned int *v_idx, const char *key) -{ - unsigned int i, j; - for (i=0;i<msg->num_elements;i++) { - if (ldb_attr_cmp(msg->elements[i].name, key) == 0) { - const struct ldb_message_element *el = - &msg->elements[i]; - for (j=0;j<el->num_values;j++) { - if (ldb_attr_cmp((char *)el->values[j].data, attr) == 0) { - if (v_idx) { - *v_idx = j; - } - return i; - } - } - } - } - return -1; -} - -/* used in sorting dn lists */ -static int list_cmp(const char **s1, const char **s2) -{ - return strcmp(*s1, *s2); -} - -/* - return a list of dn's that might match a simple indexed search or - */ -static int ltdb_index_dn_simple(struct ldb_module *module, - const struct ldb_parse_tree *tree, - const struct ldb_message *index_list, - struct dn_list *list) -{ - struct ldb_context *ldb = module->ldb; - struct ldb_dn *dn; - int ret; - unsigned int i, j; - struct ldb_message *msg; - - list->count = 0; - list->dn = NULL; - - /* if the attribute isn't in the list of indexed attributes then - this node needs a full search */ - if (ldb_msg_find_idx(index_list, tree->u.equality.attr, NULL, LTDB_IDXATTR) == -1) { - return -1; - } - - /* the attribute is indexed. Pull the list of DNs that match the - search criterion */ - dn = ldb_dn_key(ldb, tree->u.equality.attr, &tree->u.equality.value); - if (!dn) return -1; - - msg = talloc(list, struct ldb_message); - if (msg == NULL) { - return -1; - } - - ret = ltdb_search_dn1(module, dn, msg); - talloc_free(dn); - if (ret == 0 || ret == -1) { - return ret; - } - - for (i=0;i<msg->num_elements;i++) { - struct ldb_message_element *el; - - if (strcmp(msg->elements[i].name, LTDB_IDX) != 0) { - continue; - } - - el = &msg->elements[i]; - - list->dn = talloc_array(list, char *, el->num_values); - if (!list->dn) { - talloc_free(msg); - return -1; - } - - for (j=0;j<el->num_values;j++) { - list->dn[list->count] = - talloc_strdup(list->dn, (char *)el->values[j].data); - if (!list->dn[list->count]) { - talloc_free(msg); - return -1; - } - list->count++; - } - } - - talloc_free(msg); - - if (list->count > 1) { - qsort(list->dn, list->count, sizeof(char *), (comparison_fn_t) list_cmp); - } - - return 1; -} - - -static int list_union(struct ldb_context *, struct dn_list *, const struct dn_list *); - -/* - return a list of dn's that might match a simple indexed search on - the special objectclass attribute - */ -static int ltdb_index_dn_objectclass(struct ldb_module *module, - const struct ldb_parse_tree *tree, - const struct ldb_message *index_list, - struct dn_list *list) -{ - struct ldb_context *ldb = module->ldb; - unsigned int i; - int ret; - const char *target = (const char *)tree->u.equality.value.data; - const char **subclasses; - - list->count = 0; - list->dn = NULL; - - ret = ltdb_index_dn_simple(module, tree, index_list, list); - - subclasses = ldb_subclass_list(module->ldb, target); - - if (subclasses == NULL) { - return ret; - } - - for (i=0;subclasses[i];i++) { - struct ldb_parse_tree tree2; - struct dn_list *list2; - tree2.operation = LDB_OP_EQUALITY; - tree2.u.equality.attr = LTDB_OBJECTCLASS; - if (!tree2.u.equality.attr) { - return -1; - } - tree2.u.equality.value.data = - (uint8_t *)talloc_strdup(list, subclasses[i]); - if (tree2.u.equality.value.data == NULL) { - return -1; - } - tree2.u.equality.value.length = strlen(subclasses[i]); - list2 = talloc(list, struct dn_list); - if (list2 == NULL) { - talloc_free(tree2.u.equality.value.data); - return -1; - } - if (ltdb_index_dn_objectclass(module, &tree2, - index_list, list2) == 1) { - if (list->count == 0) { - *list = *list2; - ret = 1; - } else { - list_union(ldb, list, list2); - talloc_free(list2); - } - } - talloc_free(tree2.u.equality.value.data); - } - - return ret; -} - -/* - return a list of dn's that might match a leaf indexed search - */ -static int ltdb_index_dn_leaf(struct ldb_module *module, - const struct ldb_parse_tree *tree, - const struct ldb_message *index_list, - struct dn_list *list) -{ - if (ldb_attr_cmp(tree->u.equality.attr, LTDB_OBJECTCLASS) == 0) { - return ltdb_index_dn_objectclass(module, tree, index_list, list); - } - if (ldb_attr_dn(tree->u.equality.attr) == 0) { - list->dn = talloc_array(list, char *, 1); - if (list->dn == NULL) { - ldb_oom(module->ldb); - return -1; - } - list->dn[0] = talloc_strdup(list->dn, (char *)tree->u.equality.value.data); - if (list->dn[0] == NULL) { - ldb_oom(module->ldb); - return -1; - } - list->count = 1; - return 1; - } - return ltdb_index_dn_simple(module, tree, index_list, list); -} - - -/* - list intersection - list = list & list2 - relies on the lists being sorted -*/ -static int list_intersect(struct ldb_context *ldb, - struct dn_list *list, const struct dn_list *list2) -{ - struct dn_list *list3; - unsigned int i; - - if (list->count == 0 || list2->count == 0) { - /* 0 & X == 0 */ - return 0; - } - - list3 = talloc(ldb, struct dn_list); - if (list3 == NULL) { - return -1; - } - - list3->dn = talloc_array(list3, char *, list->count); - if (!list3->dn) { - talloc_free(list3); - return -1; - } - list3->count = 0; - - for (i=0;i<list->count;i++) { - if (ldb_list_find(list->dn[i], list2->dn, list2->count, - sizeof(char *), (comparison_fn_t)strcmp) != -1) { - list3->dn[list3->count] = talloc_move(list3->dn, &list->dn[i]); - list3->count++; - } else { - talloc_free(list->dn[i]); - } - } - - talloc_free(list->dn); - list->dn = talloc_move(list, &list3->dn); - list->count = list3->count; - talloc_free(list3); - - return 0; -} - - -/* - list union - list = list | list2 - relies on the lists being sorted -*/ -static int list_union(struct ldb_context *ldb, - struct dn_list *list, const struct dn_list *list2) -{ - unsigned int i; - char **d; - unsigned int count = list->count; - - if (list->count == 0 && list2->count == 0) { - /* 0 | 0 == 0 */ - return 0; - } - - d = talloc_realloc(list, list->dn, char *, list->count + list2->count); - if (!d) { - return -1; - } - list->dn = d; - - for (i=0;i<list2->count;i++) { - if (ldb_list_find(list2->dn[i], list->dn, count, - sizeof(char *), (comparison_fn_t)strcmp) == -1) { - list->dn[list->count] = talloc_strdup(list->dn, list2->dn[i]); - if (!list->dn[list->count]) { - return -1; - } - list->count++; - } - } - - if (list->count != count) { - qsort(list->dn, list->count, sizeof(char *), (comparison_fn_t)list_cmp); - } - - return 0; -} - -static int ltdb_index_dn(struct ldb_module *module, - const struct ldb_parse_tree *tree, - const struct ldb_message *index_list, - struct dn_list *list); - - -/* - OR two index results - */ -static int ltdb_index_dn_or(struct ldb_module *module, - const struct ldb_parse_tree *tree, - const struct ldb_message *index_list, - struct dn_list *list) -{ - struct ldb_context *ldb = module->ldb; - unsigned int i; - int ret; - - ret = -1; - list->dn = NULL; - list->count = 0; - - for (i=0;i<tree->u.list.num_elements;i++) { - struct dn_list *list2; - int v; - - list2 = talloc(module, struct dn_list); - if (list2 == NULL) { - return -1; - } - - v = ltdb_index_dn(module, tree->u.list.elements[i], index_list, list2); - - if (v == 0) { - /* 0 || X == X */ - if (ret == -1) { - ret = 0; - } - talloc_free(list2); - continue; - } - - if (v == -1) { - /* 1 || X == 1 */ - talloc_free(list->dn); - talloc_free(list2); - return -1; - } - - if (ret == -1) { - ret = 1; - list->dn = talloc_move(list, &list2->dn); - list->count = list2->count; - } else { - if (list_union(ldb, list, list2) == -1) { - talloc_free(list2); - return -1; - } - ret = 1; - } - talloc_free(list2); - } - - if (list->count == 0) { - return 0; - } - - return ret; -} - - -/* - NOT an index results - */ -static int ltdb_index_dn_not(struct ldb_module *module, - const struct ldb_parse_tree *tree, - const struct ldb_message *index_list, - struct dn_list *list) -{ - /* the only way to do an indexed not would be if we could - negate the not via another not or if we knew the total - number of database elements so we could know that the - existing expression covered the whole database. - - instead, we just give up, and rely on a full index scan - (unless an outer & manages to reduce the list) - */ - return -1; -} - -/* - AND two index results - */ -static int ltdb_index_dn_and(struct ldb_module *module, - const struct ldb_parse_tree *tree, - const struct ldb_message *index_list, - struct dn_list *list) -{ - struct ldb_context *ldb = module->ldb; - unsigned int i; - int ret; - - ret = -1; - list->dn = NULL; - list->count = 0; - - for (i=0;i<tree->u.list.num_elements;i++) { - struct dn_list *list2; - int v; - - list2 = talloc(module, struct dn_list); - if (list2 == NULL) { - return -1; - } - - v = ltdb_index_dn(module, tree->u.list.elements[i], index_list, list2); - - if (v == 0) { - /* 0 && X == 0 */ - talloc_free(list->dn); - talloc_free(list2); - return 0; - } - - if (v == -1) { - talloc_free(list2); - continue; - } - - if (ret == -1) { - ret = 1; - talloc_free(list->dn); - list->dn = talloc_move(list, &list2->dn); - list->count = list2->count; - } else { - if (list_intersect(ldb, list, list2) == -1) { - talloc_free(list2); - return -1; - } - } - - talloc_free(list2); - - if (list->count == 0) { - talloc_free(list->dn); - return 0; - } - } - - return ret; -} - -/* - return a list of dn's that might match a indexed search or - -1 if an error. return 0 for no matches, or 1 for matches - */ -static int ltdb_index_dn(struct ldb_module *module, - const struct ldb_parse_tree *tree, - const struct ldb_message *index_list, - struct dn_list *list) -{ - int ret = -1; - - switch (tree->operation) { - case LDB_OP_AND: - ret = ltdb_index_dn_and(module, tree, index_list, list); - break; - - case LDB_OP_OR: - ret = ltdb_index_dn_or(module, tree, index_list, list); - break; - - case LDB_OP_NOT: - ret = ltdb_index_dn_not(module, tree, index_list, list); - break; - - case LDB_OP_EQUALITY: - ret = ltdb_index_dn_leaf(module, tree, index_list, list); - break; - - case LDB_OP_SUBSTRING: - case LDB_OP_GREATER: - case LDB_OP_LESS: - case LDB_OP_PRESENT: - case LDB_OP_APPROX: - case LDB_OP_EXTENDED: - /* we can't index with fancy bitops yet */ - ret = -1; - break; - } - - return ret; -} - -/* - filter a candidate dn_list from an indexed search into a set of results - extracting just the given attributes -*/ -static int ltdb_index_filter(const struct dn_list *dn_list, - struct ldb_handle *handle) -{ - struct ltdb_context *ac = talloc_get_type(handle->private_data, struct ltdb_context); - struct ldb_reply *ares = NULL; - unsigned int i; - - if (!ac) { - return LDB_ERR_OPERATIONS_ERROR; - } - - for (i = 0; i < dn_list->count; i++) { - struct ldb_dn *dn; - int ret; - - ares = talloc_zero(ac, struct ldb_reply); - if (!ares) { - handle->status = LDB_ERR_OPERATIONS_ERROR; - handle->state = LDB_ASYNC_DONE; - return LDB_ERR_OPERATIONS_ERROR; - } - - ares->message = ldb_msg_new(ares); - if (!ares->message) { - handle->status = LDB_ERR_OPERATIONS_ERROR; - handle->state = LDB_ASYNC_DONE; - talloc_free(ares); - return LDB_ERR_OPERATIONS_ERROR; - } - - - dn = ldb_dn_explode(ares->message, dn_list->dn[i]); - if (dn == NULL) { - talloc_free(ares); - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ltdb_search_dn1(ac->module, dn, ares->message); - talloc_free(dn); - if (ret == 0) { - /* the record has disappeared? yes, this can happen */ - talloc_free(ares); - continue; - } - - if (ret == -1) { - /* an internal error */ - talloc_free(ares); - return LDB_ERR_OPERATIONS_ERROR; - } - - if (!ldb_match_msg(ac->module->ldb, ares->message, ac->tree, ac->base, ac->scope)) { - talloc_free(ares); - continue; - } - - /* filter the attributes that the user wants */ - ret = ltdb_filter_attrs(ares->message, ac->attrs); - - if (ret == -1) { - handle->status = LDB_ERR_OPERATIONS_ERROR; - handle->state = LDB_ASYNC_DONE; - talloc_free(ares); - return LDB_ERR_OPERATIONS_ERROR; - } - - ares->type = LDB_REPLY_ENTRY; - handle->state = LDB_ASYNC_PENDING; - handle->status = ac->callback(ac->module->ldb, ac->context, ares); - - if (handle->status != LDB_SUCCESS) { - handle->state = LDB_ASYNC_DONE; - return handle->status; - } - } - - return LDB_SUCCESS; -} - -/* - search the database with a LDAP-like expression using indexes - returns -1 if an indexed search is not possible, in which - case the caller should call ltdb_search_full() -*/ -int ltdb_search_indexed(struct ldb_handle *handle) -{ - struct ltdb_context *ac; - struct ltdb_private *ltdb; - struct dn_list *dn_list; - int ret; - - if (!(ac = talloc_get_type(handle->private_data, - struct ltdb_context)) || - !(ltdb = talloc_get_type(ac->module->private_data, - struct ltdb_private))) { - return -1; - } - - if (ltdb->cache->indexlist->num_elements == 0 && - ac->scope != LDB_SCOPE_BASE) { - /* no index list? must do full search */ - return -1; - } - - dn_list = talloc(handle, struct dn_list); - if (dn_list == NULL) { - return -1; - } - - if (ac->scope == LDB_SCOPE_BASE) { - /* with BASE searches only one DN can match */ - dn_list->dn = talloc_array(dn_list, char *, 1); - if (dn_list->dn == NULL) { - ldb_oom(ac->module->ldb); - return -1; - } - dn_list->dn[0] = ldb_dn_linearize(dn_list, ac->base); - if (dn_list->dn[0] == NULL) { - ldb_oom(ac->module->ldb); - return -1; - } - dn_list->count = 1; - ret = 1; - } else { - ret = ltdb_index_dn(ac->module, ac->tree, ltdb->cache->indexlist, dn_list); - } - - if (ret == 1) { - /* we've got a candidate list - now filter by the full tree - and extract the needed attributes */ - ret = ltdb_index_filter(dn_list, handle); - handle->status = ret; - handle->state = LDB_ASYNC_DONE; - } - - talloc_free(dn_list); - - return ret; -} - -/* - add a index element where this is the first indexed DN for this value -*/ -static int ltdb_index_add1_new(struct ldb_context *ldb, - struct ldb_message *msg, - struct ldb_message_element *el, - const char *dn) -{ - struct ldb_message_element *el2; - - /* add another entry */ - el2 = talloc_realloc(msg, msg->elements, - struct ldb_message_element, msg->num_elements+1); - if (!el2) { - return -1; - } - - msg->elements = el2; - msg->elements[msg->num_elements].name = talloc_strdup(msg->elements, LTDB_IDX); - if (!msg->elements[msg->num_elements].name) { - return -1; - } - msg->elements[msg->num_elements].num_values = 0; - msg->elements[msg->num_elements].values = talloc(msg->elements, struct ldb_val); - if (!msg->elements[msg->num_elements].values) { - return -1; - } - msg->elements[msg->num_elements].values[0].length = strlen(dn); - msg->elements[msg->num_elements].values[0].data = discard_const_p(uint8_t, dn); - msg->elements[msg->num_elements].num_values = 1; - msg->num_elements++; - - return 0; -} - - -/* - add a index element where this is not the first indexed DN for this - value -*/ -static int ltdb_index_add1_add(struct ldb_context *ldb, - struct ldb_message *msg, - struct ldb_message_element *el, - int idx, - const char *dn) -{ - struct ldb_val *v2; - unsigned int i; - - /* for multi-valued attributes we can end up with repeats */ - for (i=0;i<msg->elements[idx].num_values;i++) { - if (strcmp(dn, (char *)msg->elements[idx].values[i].data) == 0) { - return 0; - } - } - - v2 = talloc_realloc(msg->elements, msg->elements[idx].values, - struct ldb_val, - msg->elements[idx].num_values+1); - if (!v2) { - return -1; - } - msg->elements[idx].values = v2; - - msg->elements[idx].values[msg->elements[idx].num_values].length = strlen(dn); - msg->elements[idx].values[msg->elements[idx].num_values].data = discard_const_p(uint8_t, dn); - msg->elements[idx].num_values++; - - return 0; -} - -/* - add an index entry for one message element -*/ -static int ltdb_index_add1(struct ldb_module *module, const char *dn, - struct ldb_message_element *el, int v_idx) -{ - struct ldb_context *ldb = module->ldb; - struct ldb_message *msg; - struct ldb_dn *dn_key; - int ret; - unsigned int i; - - msg = talloc(module, struct ldb_message); - if (msg == NULL) { - errno = ENOMEM; - return -1; - } - - dn_key = ldb_dn_key(ldb, el->name, &el->values[v_idx]); - if (!dn_key) { - talloc_free(msg); - errno = ENOMEM; - return -1; - } - talloc_steal(msg, dn_key); - - ret = ltdb_search_dn1(module, dn_key, msg); - if (ret == -1) { - talloc_free(msg); - return -1; - } - - if (ret == 0) { - msg->dn = dn_key; - msg->num_elements = 0; - msg->elements = NULL; - } - - for (i=0;i<msg->num_elements;i++) { - if (strcmp(LTDB_IDX, msg->elements[i].name) == 0) { - break; - } - } - - if (i == msg->num_elements) { - ret = ltdb_index_add1_new(ldb, msg, el, dn); - } else { - ret = ltdb_index_add1_add(ldb, msg, el, i, dn); - } - - if (ret == 0) { - ret = ltdb_store(module, msg, TDB_REPLACE); - } - - talloc_free(msg); - - return ret; -} - -static int ltdb_index_add0(struct ldb_module *module, const char *dn, - struct ldb_message_element *elements, int num_el) -{ - struct ltdb_private *ltdb = - (struct ltdb_private *)module->private_data; - int ret; - unsigned int i, j; - - if (dn[0] == '@') { - return 0; - } - - if (ltdb->cache->indexlist->num_elements == 0) { - /* no indexed fields */ - return 0; - } - - for (i = 0; i < num_el; i++) { - ret = ldb_msg_find_idx(ltdb->cache->indexlist, elements[i].name, - NULL, LTDB_IDXATTR); - if (ret == -1) { - continue; - } - for (j = 0; j < elements[i].num_values; j++) { - ret = ltdb_index_add1(module, dn, &elements[i], j); - if (ret == -1) { - return -1; - } - } - } - - return 0; -} - -/* - add the index entries for a new record - return -1 on failure -*/ -int ltdb_index_add(struct ldb_module *module, const struct ldb_message *msg) -{ - struct ltdb_private *ltdb = - (struct ltdb_private *)module->private_data; - char *dn; - int ret; - - dn = ldb_dn_linearize(ltdb, msg->dn); - if (dn == NULL) { - return -1; - } - - ret = ltdb_index_add0(module, dn, msg->elements, msg->num_elements); - - talloc_free(dn); - - return ret; -} - - -/* - delete an index entry for one message element -*/ -int ltdb_index_del_value(struct ldb_module *module, const char *dn, - struct ldb_message_element *el, int v_idx) -{ - struct ldb_context *ldb = module->ldb; - struct ldb_message *msg; - struct ldb_dn *dn_key; - int ret, i; - unsigned int j; - - if (dn[0] == '@') { - return 0; - } - - dn_key = ldb_dn_key(ldb, el->name, &el->values[v_idx]); - if (!dn_key) { - return -1; - } - - msg = talloc(dn_key, struct ldb_message); - if (msg == NULL) { - talloc_free(dn_key); - return -1; - } - - ret = ltdb_search_dn1(module, dn_key, msg); - if (ret == -1) { - talloc_free(dn_key); - return -1; - } - - if (ret == 0) { - /* it wasn't indexed. Did we have an earlier error? If we did then - its gone now */ - talloc_free(dn_key); - return 0; - } - - i = ldb_msg_find_idx(msg, dn, &j, LTDB_IDX); - if (i == -1) { - ldb_debug(ldb, LDB_DEBUG_ERROR, - "ERROR: dn %s not found in %s\n", dn, - ldb_dn_linearize(dn_key, dn_key)); - /* it ain't there. hmmm */ - talloc_free(dn_key); - return 0; - } - - if (j != msg->elements[i].num_values - 1) { - memmove(&msg->elements[i].values[j], - &msg->elements[i].values[j+1], - (msg->elements[i].num_values-(j+1)) * - sizeof(msg->elements[i].values[0])); - } - msg->elements[i].num_values--; - - if (msg->elements[i].num_values == 0) { - ret = ltdb_delete_noindex(module, dn_key); - } else { - ret = ltdb_store(module, msg, TDB_REPLACE); - } - - talloc_free(dn_key); - - return ret; -} - -/* - delete the index entries for a record - return -1 on failure -*/ -int ltdb_index_del(struct ldb_module *module, const struct ldb_message *msg) -{ - struct ltdb_private *ltdb = - (struct ltdb_private *)module->private_data; - int ret; - char *dn; - unsigned int i, j; - - /* find the list of indexed fields */ - if (ltdb->cache->indexlist->num_elements == 0) { - /* no indexed fields */ - return 0; - } - - if (ldb_dn_is_special(msg->dn)) { - return 0; - } - - dn = ldb_dn_linearize(ltdb, msg->dn); - if (dn == NULL) { - return -1; - } - - for (i = 0; i < msg->num_elements; i++) { - ret = ldb_msg_find_idx(ltdb->cache->indexlist, msg->elements[i].name, - NULL, LTDB_IDXATTR); - if (ret == -1) { - continue; - } - for (j = 0; j < msg->elements[i].num_values; j++) { - ret = ltdb_index_del_value(module, dn, &msg->elements[i], j); - if (ret == -1) { - talloc_free(dn); - return -1; - } - } - } - - talloc_free(dn); - return 0; -} - - -/* - traversal function that deletes all @INDEX records -*/ -static int delete_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state) -{ - const char *dn = "DN=" LTDB_INDEX ":"; - if (strncmp((char *)key.dptr, dn, strlen(dn)) == 0) { - return tdb_delete(tdb, key); - } - return 0; -} - -/* - traversal function that adds @INDEX records during a re index -*/ -static int re_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state) -{ - struct ldb_module *module = (struct ldb_module *)state; - struct ldb_message *msg; - char *dn = NULL; - int ret; - TDB_DATA key2; - - if (strncmp((char *)key.dptr, "DN=@", 4) == 0 || - strncmp((char *)key.dptr, "DN=", 3) != 0) { - return 0; - } - - msg = talloc(module, struct ldb_message); - if (msg == NULL) { - return -1; - } - - ret = ltdb_unpack_data(module, &data, msg); - if (ret != 0) { - talloc_free(msg); - return -1; - } - - /* check if the DN key has changed, perhaps due to the - case insensitivity of an element changing */ - key2 = ltdb_key(module, msg->dn); - if (key2.dptr == NULL) { - /* probably a corrupt record ... darn */ - ldb_debug(module->ldb, LDB_DEBUG_ERROR, "Invalid DN in re_index: %s\n", - ldb_dn_linearize(msg, msg->dn)); - talloc_free(msg); - return 0; - } - if (strcmp((char *)key2.dptr, (char *)key.dptr) != 0) { - tdb_delete(tdb, key); - tdb_store(tdb, key2, data, 0); - } - talloc_free(key2.dptr); - - if (msg->dn == NULL) { - dn = (char *)key.dptr + 3; - } else { - if (!(dn = ldb_dn_linearize(msg->dn, msg->dn))) { - talloc_free(msg); - return -1; - } - } - - ret = ltdb_index_add0(module, dn, msg->elements, msg->num_elements); - - talloc_free(msg); - - return ret; -} - -/* - force a complete reindex of the database -*/ -int ltdb_reindex(struct ldb_module *module) -{ - struct ltdb_private *ltdb = - (struct ltdb_private *)module->private_data; - int ret; - - if (ltdb_cache_reload(module) != 0) { - return -1; - } - - /* first traverse the database deleting any @INDEX records */ - ret = tdb_traverse(ltdb->tdb, delete_index, NULL); - if (ret == -1) { - return -1; - } - - /* now traverse adding any indexes for normal LDB records */ - ret = tdb_traverse(ltdb->tdb, re_index, module); - if (ret == -1) { - return -1; - } - - return 0; -} diff --git a/source/lib/ldb/ldb_tdb/ldb_pack.c b/source/lib/ldb/ldb_tdb/ldb_pack.c deleted file mode 100644 index 45fcf354a5e..00000000000 --- a/source/lib/ldb/ldb_tdb/ldb_pack.c +++ /dev/null @@ -1,294 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - * Name: ldb - * - * Component: ldb pack/unpack - * - * Description: pack/unpack routines for ldb messages as key/value blobs - * - * Author: Andrew Tridgell - */ - -#include "includes.h" -#include "ldb/include/includes.h" - -#include "ldb/ldb_tdb/ldb_tdb.h" - -/* change this if the data format ever changes */ -#define LTDB_PACKING_FORMAT 0x26011967 - -/* old packing formats */ -#define LTDB_PACKING_FORMAT_NODN 0x26011966 - -/* use a portable integer format */ -static void put_uint32(uint8_t *p, int ofs, unsigned int val) -{ - p += ofs; - p[0] = val&0xFF; - p[1] = (val>>8) & 0xFF; - p[2] = (val>>16) & 0xFF; - p[3] = (val>>24) & 0xFF; -} - -static unsigned int pull_uint32(uint8_t *p, int ofs) -{ - p += ofs; - return p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24); -} - -static int attribute_storable_values(const struct ldb_message_element *el) -{ - if (el->num_values == 0) return 0; - - if (ldb_attr_cmp(el->name, "dn") == 0) return 0; - - if (ldb_attr_cmp(el->name, "distinguishedName") == 0) return 0; - - return el->num_values; -} - -/* - pack a ldb message into a linear buffer in a TDB_DATA - - note that this routine avoids saving elements with zero values, - as these are equivalent to having no element - - caller frees the data buffer after use -*/ -int ltdb_pack_data(struct ldb_module *module, - const struct ldb_message *message, - struct TDB_DATA *data) -{ - struct ldb_context *ldb = module->ldb; - unsigned int i, j, real_elements=0; - size_t size; - char *dn; - uint8_t *p; - size_t len; - - dn = ldb_dn_linearize(ldb, message->dn); - if (dn == NULL) { - errno = ENOMEM; - return -1; - } - - /* work out how big it needs to be */ - size = 8; - - size += 1 + strlen(dn); - - for (i=0;i<message->num_elements;i++) { - if (attribute_storable_values(&message->elements[i]) == 0) { - continue; - } - - real_elements++; - - size += 1 + strlen(message->elements[i].name) + 4; - for (j=0;j<message->elements[i].num_values;j++) { - size += 4 + message->elements[i].values[j].length + 1; - } - } - - /* allocate it */ - data->dptr = talloc_array(ldb, uint8_t, size); - if (!data->dptr) { - talloc_free(dn); - errno = ENOMEM; - return -1; - } - data->dsize = size; - - p = (uint8_t *)data->dptr; - put_uint32(p, 0, LTDB_PACKING_FORMAT); - put_uint32(p, 4, real_elements); - p += 8; - - /* the dn needs to be packed so we can be case preserving - while hashing on a case folded dn */ - len = strlen(dn); - memcpy(p, dn, len+1); - p += len + 1; - - for (i=0;i<message->num_elements;i++) { - if (attribute_storable_values(&message->elements[i]) == 0) { - continue; - } - len = strlen(message->elements[i].name); - memcpy(p, message->elements[i].name, len+1); - p += len + 1; - put_uint32(p, 0, message->elements[i].num_values); - p += 4; - for (j=0;j<message->elements[i].num_values;j++) { - put_uint32(p, 0, message->elements[i].values[j].length); - memcpy(p+4, message->elements[i].values[j].data, - message->elements[i].values[j].length); - p[4+message->elements[i].values[j].length] = 0; - p += 4 + message->elements[i].values[j].length + 1; - } - } - - talloc_free(dn); - return 0; -} - -/* - unpack a ldb message from a linear buffer in TDB_DATA - - Free with ltdb_unpack_data_free() -*/ -int ltdb_unpack_data(struct ldb_module *module, - const struct TDB_DATA *data, - struct ldb_message *message) -{ - struct ldb_context *ldb = module->ldb; - uint8_t *p; - unsigned int remaining; - unsigned int i, j; - unsigned format; - size_t len; - - message->elements = NULL; - - p = (uint8_t *)data->dptr; - if (data->dsize < 8) { - errno = EIO; - goto failed; - } - - format = pull_uint32(p, 0); - message->num_elements = pull_uint32(p, 4); - p += 8; - - remaining = data->dsize - 8; - - switch (format) { - case LTDB_PACKING_FORMAT_NODN: - message->dn = NULL; - break; - - case LTDB_PACKING_FORMAT: - len = strnlen((char *)p, remaining); - if (len == remaining) { - errno = EIO; - goto failed; - } - message->dn = ldb_dn_explode(message, (char *)p); - if (message->dn == NULL) { - errno = ENOMEM; - goto failed; - } - remaining -= len + 1; - p += len + 1; - break; - - default: - errno = EIO; - goto failed; - } - - if (message->num_elements == 0) { - message->elements = NULL; - return 0; - } - - if (message->num_elements > remaining / 6) { - errno = EIO; - goto failed; - } - - message->elements = talloc_array(message, struct ldb_message_element, message->num_elements); - if (!message->elements) { - errno = ENOMEM; - goto failed; - } - - memset(message->elements, 0, - message->num_elements * sizeof(struct ldb_message_element)); - - for (i=0;i<message->num_elements;i++) { - if (remaining < 10) { - errno = EIO; - goto failed; - } - len = strnlen((char *)p, remaining-6); - if (len == remaining-6) { - errno = EIO; - goto failed; - } - message->elements[i].flags = 0; - message->elements[i].name = talloc_strndup(message->elements, (char *)p, len); - if (message->elements[i].name == NULL) { - errno = ENOMEM; - goto failed; - } - remaining -= len + 1; - p += len + 1; - message->elements[i].num_values = pull_uint32(p, 0); - message->elements[i].values = NULL; - if (message->elements[i].num_values != 0) { - message->elements[i].values = talloc_array(message->elements, - struct ldb_val, - message->elements[i].num_values); - if (!message->elements[i].values) { - errno = ENOMEM; - goto failed; - } - } - p += 4; - remaining -= 4; - for (j=0;j<message->elements[i].num_values;j++) { - len = pull_uint32(p, 0); - if (len > remaining-5) { - errno = EIO; - goto failed; - } - - message->elements[i].values[j].length = len; - message->elements[i].values[j].data = (uint8_t *)talloc_size(message->elements[i].values, len+1); - if (message->elements[i].values[j].data == NULL) { - errno = ENOMEM; - goto failed; - } - memcpy(message->elements[i].values[j].data, p+4, len); - message->elements[i].values[j].data[len] = 0; - - remaining -= len+4+1; - p += len+4+1; - } - } - - if (remaining != 0) { - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Error: %d bytes unread in ltdb_unpack_data\n", remaining); - } - - return 0; - -failed: - talloc_free(message->elements); - return -1; -} diff --git a/source/lib/ldb/ldb_tdb/ldb_search.c b/source/lib/ldb/ldb_tdb/ldb_search.c deleted file mode 100644 index 7a6fe263fdd..00000000000 --- a/source/lib/ldb/ldb_tdb/ldb_search.c +++ /dev/null @@ -1,528 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - * Name: ldb - * - * Component: ldb search functions - * - * Description: functions to search ldb+tdb databases - * - * Author: Andrew Tridgell - */ - -#include "includes.h" -#include "ldb/include/includes.h" - -#include "ldb/ldb_tdb/ldb_tdb.h" - -/* - add one element to a message -*/ -static int msg_add_element(struct ldb_message *ret, - const struct ldb_message_element *el, - int check_duplicates) -{ - unsigned int i; - struct ldb_message_element *e2, *elnew; - - if (check_duplicates && ldb_msg_find_element(ret, el->name)) { - /* its already there */ - return 0; - } - - e2 = talloc_realloc(ret, ret->elements, struct ldb_message_element, ret->num_elements+1); - if (!e2) { - return -1; - } - ret->elements = e2; - - elnew = &e2[ret->num_elements]; - - elnew->name = talloc_strdup(ret->elements, el->name); - if (!elnew->name) { - return -1; - } - - if (el->num_values) { - elnew->values = talloc_array(ret->elements, struct ldb_val, el->num_values); - if (!elnew->values) { - return -1; - } - } else { - elnew->values = NULL; - } - - for (i=0;i<el->num_values;i++) { - elnew->values[i] = ldb_val_dup(elnew->values, &el->values[i]); - if (elnew->values[i].length != el->values[i].length) { - return -1; - } - } - - elnew->num_values = el->num_values; - - ret->num_elements++; - - return 0; -} - -/* - add the special distinguishedName element -*/ -static int msg_add_distinguished_name(struct ldb_message *msg) -{ - struct ldb_message_element el; - struct ldb_val val; - int ret; - - el.flags = 0; - el.name = "distinguishedName"; - el.num_values = 1; - el.values = &val; - val.data = (uint8_t *)ldb_dn_linearize(msg, msg->dn); - val.length = strlen((char *)val.data); - - ret = msg_add_element(msg, &el, 1); - return ret; -} - -/* - add all elements from one message into another - */ -static int msg_add_all_elements(struct ldb_module *module, struct ldb_message *ret, - const struct ldb_message *msg) -{ - struct ldb_context *ldb = module->ldb; - unsigned int i; - int check_duplicates = (ret->num_elements != 0); - - if (msg_add_distinguished_name(ret) != 0) { - return -1; - } - - for (i=0;i<msg->num_elements;i++) { - const struct ldb_attrib_handler *h; - h = ldb_attrib_handler(ldb, msg->elements[i].name); - if (h->flags & LDB_ATTR_FLAG_HIDDEN) { - continue; - } - if (msg_add_element(ret, &msg->elements[i], - check_duplicates) != 0) { - return -1; - } - } - - return 0; -} - - -/* - pull the specified list of attributes from a message - */ -static struct ldb_message *ltdb_pull_attrs(struct ldb_module *module, - TALLOC_CTX *mem_ctx, - const struct ldb_message *msg, - const char * const *attrs) -{ - struct ldb_message *ret; - int i; - - ret = talloc(mem_ctx, struct ldb_message); - if (!ret) { - return NULL; - } - - ret->dn = ldb_dn_copy(ret, msg->dn); - if (!ret->dn) { - talloc_free(ret); - return NULL; - } - - ret->num_elements = 0; - ret->elements = NULL; - - if (!attrs) { - if (msg_add_all_elements(module, ret, msg) != 0) { - talloc_free(ret); - return NULL; - } - return ret; - } - - for (i=0;attrs[i];i++) { - struct ldb_message_element *el; - - if (strcmp(attrs[i], "*") == 0) { - if (msg_add_all_elements(module, ret, msg) != 0) { - talloc_free(ret); - return NULL; - } - continue; - } - - if (ldb_attr_cmp(attrs[i], "distinguishedName") == 0) { - if (msg_add_distinguished_name(ret) != 0) { - return NULL; - } - continue; - } - - el = ldb_msg_find_element(msg, attrs[i]); - if (!el) { - continue; - } - if (msg_add_element(ret, el, 1) != 0) { - talloc_free(ret); - return NULL; - } - } - - return ret; -} - - -/* - search the database for a single simple dn, returning all attributes - in a single message - - return 1 on success, 0 on record-not-found and -1 on error -*/ -int ltdb_search_dn1(struct ldb_module *module, const struct ldb_dn *dn, struct ldb_message *msg) -{ - struct ltdb_private *ltdb = - (struct ltdb_private *)module->private_data; - int ret; - TDB_DATA tdb_key, tdb_data; - - memset(msg, 0, sizeof(*msg)); - - /* form the key */ - tdb_key = ltdb_key(module, dn); - if (!tdb_key.dptr) { - return -1; - } - - tdb_data = tdb_fetch(ltdb->tdb, tdb_key); - talloc_free(tdb_key.dptr); - if (!tdb_data.dptr) { - return 0; - } - - msg->num_elements = 0; - msg->elements = NULL; - - ret = ltdb_unpack_data(module, &tdb_data, msg); - free(tdb_data.dptr); - if (ret == -1) { - return -1; - } - - if (!msg->dn) { - msg->dn = ldb_dn_copy(msg, dn); - } - if (!msg->dn) { - return -1; - } - - return 1; -} - -/* - lock the database for read - use by ltdb_search -*/ -static int ltdb_lock_read(struct ldb_module *module) -{ - struct ltdb_private *ltdb = - (struct ltdb_private *)module->private_data; - return tdb_lockall_read(ltdb->tdb); -} - -/* - unlock the database after a ltdb_lock_read() -*/ -static int ltdb_unlock_read(struct ldb_module *module) -{ - struct ltdb_private *ltdb = - (struct ltdb_private *)module->private_data; - return tdb_unlockall_read(ltdb->tdb); -} - -/* - add a set of attributes from a record to a set of results - return 0 on success, -1 on failure -*/ -int ltdb_add_attr_results(struct ldb_module *module, - TALLOC_CTX *mem_ctx, - struct ldb_message *msg, - const char * const attrs[], - unsigned int *count, - struct ldb_message ***res) -{ - struct ldb_message *msg2; - struct ldb_message **res2; - - /* pull the attributes that the user wants */ - msg2 = ltdb_pull_attrs(module, mem_ctx, msg, attrs); - if (!msg2) { - return -1; - } - - /* add to the results list */ - res2 = talloc_realloc(mem_ctx, *res, struct ldb_message *, (*count)+2); - if (!res2) { - talloc_free(msg2); - return -1; - } - - (*res) = res2; - - (*res)[*count] = talloc_move(*res, &msg2); - (*res)[(*count)+1] = NULL; - (*count)++; - - return 0; -} - - - -/* - filter the specified list of attributes from a message - removing not requested attrs. - */ -int ltdb_filter_attrs(struct ldb_message *msg, const char * const *attrs) -{ - int i, keep_all = 0; - - if (attrs) { - /* check for special attrs */ - for (i = 0; attrs[i]; i++) { - if (strcmp(attrs[i], "*") == 0) { - keep_all = 1; - break; - } - - if (ldb_attr_cmp(attrs[i], "distinguishedName") == 0) { - if (msg_add_distinguished_name(msg) != 0) { - return -1; - } - } - } - } else { - keep_all = 1; - } - - if (keep_all) { - if (msg_add_distinguished_name(msg) != 0) { - return -1; - } - return 0; - } - - for (i = 0; i < msg->num_elements; i++) { - int j, found; - - for (j = 0, found = 0; attrs[j]; j++) { - if (ldb_attr_cmp(msg->elements[i].name, attrs[j]) == 0) { - found = 1; - break; - } - } - - if (!found) { - ldb_msg_remove_attr(msg, msg->elements[i].name); - i--; - } - } - - return 0; -} - -/* - search function for a non-indexed search - */ -static int search_func(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state) -{ - struct ldb_handle *handle = talloc_get_type(state, struct ldb_handle); - struct ltdb_context *ac = talloc_get_type(handle->private_data, struct ltdb_context); - struct ldb_reply *ares = NULL; - int ret; - - if (key.dsize < 4 || - strncmp((char *)key.dptr, "DN=", 3) != 0) { - return 0; - } - - ares = talloc_zero(ac, struct ldb_reply); - if (!ares) { - handle->status = LDB_ERR_OPERATIONS_ERROR; - handle->state = LDB_ASYNC_DONE; - return -1; - } - - ares->message = ldb_msg_new(ares); - if (!ares->message) { - handle->status = LDB_ERR_OPERATIONS_ERROR; - handle->state = LDB_ASYNC_DONE; - talloc_free(ares); - return -1; - } - - /* unpack the record */ - ret = ltdb_unpack_data(ac->module, &data, ares->message); - if (ret == -1) { - talloc_free(ares); - return -1; - } - - if (!ares->message->dn) { - ares->message->dn = ldb_dn_explode(ares->message, (char *)key.dptr + 3); - if (ares->message->dn == NULL) { - handle->status = LDB_ERR_OPERATIONS_ERROR; - handle->state = LDB_ASYNC_DONE; - talloc_free(ares); - return -1; - } - } - - /* see if it matches the given expression */ - if (!ldb_match_msg(ac->module->ldb, ares->message, ac->tree, - ac->base, ac->scope)) { - talloc_free(ares); - return 0; - } - - /* filter the attributes that the user wants */ - ret = ltdb_filter_attrs(ares->message, ac->attrs); - - if (ret == -1) { - handle->status = LDB_ERR_OPERATIONS_ERROR; - handle->state = LDB_ASYNC_DONE; - talloc_free(ares); - return -1; - } - - ares->type = LDB_REPLY_ENTRY; - handle->state = LDB_ASYNC_PENDING; - handle->status = ac->callback(ac->module->ldb, ac->context, ares); - - if (handle->status != LDB_SUCCESS) { - /* don't try to free ares here, the callback is in charge of that */ - return -1; - } - - return 0; -} - - -/* - search the database with a LDAP-like expression. - this is the "full search" non-indexed variant -*/ -static int ltdb_search_full(struct ldb_handle *handle) -{ - struct ltdb_context *ac = talloc_get_type(handle->private_data, struct ltdb_context); - struct ltdb_private *ltdb = talloc_get_type(ac->module->private_data, struct ltdb_private); - int ret; - - ret = tdb_traverse_read(ltdb->tdb, search_func, handle); - - if (ret == -1) { - handle->status = LDB_ERR_OPERATIONS_ERROR; - } - - handle->state = LDB_ASYNC_DONE; - return LDB_SUCCESS; -} - -/* - search the database with a LDAP-like expression. - choses a search method -*/ -int ltdb_search(struct ldb_module *module, struct ldb_request *req) -{ - struct ltdb_private *ltdb = talloc_get_type(module->private_data, struct ltdb_private); - struct ltdb_context *ltdb_ac; - struct ldb_reply *ares; - int ret; - - if ((req->op.search.base == NULL || ldb_dn_get_comp_num(req->op.search.base) == 0) && - (req->op.search.scope == LDB_SCOPE_BASE || req->op.search.scope == LDB_SCOPE_ONELEVEL)) - return LDB_ERR_OPERATIONS_ERROR; - - if (ltdb_lock_read(module) != 0) { - return LDB_ERR_OPERATIONS_ERROR; - } - - if (ltdb_cache_load(module) != 0) { - ltdb_unlock_read(module); - return LDB_ERR_OPERATIONS_ERROR; - } - - if (req->op.search.tree == NULL) { - ltdb_unlock_read(module); - return LDB_ERR_OPERATIONS_ERROR; - } - - req->handle = init_ltdb_handle(ltdb, module, req); - if (req->handle == NULL) { - ltdb_unlock_read(module); - return LDB_ERR_OPERATIONS_ERROR; - } - ltdb_ac = talloc_get_type(req->handle->private_data, struct ltdb_context); - - ltdb_ac->tree = req->op.search.tree; - ltdb_ac->scope = req->op.search.scope; - ltdb_ac->base = req->op.search.base; - ltdb_ac->attrs = req->op.search.attrs; - - ret = ltdb_search_indexed(req->handle); - if (ret == -1) { - ret = ltdb_search_full(req->handle); - } - if (ret != LDB_SUCCESS) { - ldb_set_errstring(module->ldb, "Indexed and full searches both failed!\n"); - req->handle->state = LDB_ASYNC_DONE; - req->handle->status = ret; - } - - /* Finally send an LDB_REPLY_DONE packet when searching is finished */ - - ares = talloc_zero(req, struct ldb_reply); - if (!ares) { - ltdb_unlock_read(module); - return LDB_ERR_OPERATIONS_ERROR; - } - - req->handle->state = LDB_ASYNC_DONE; - ares->type = LDB_REPLY_DONE; - - ret = req->callback(module->ldb, req->context, ares); - req->handle->status = ret; - - ltdb_unlock_read(module); - - return LDB_SUCCESS; -} - diff --git a/source/lib/ldb/ldb_tdb/ldb_tdb.c b/source/lib/ldb/ldb_tdb/ldb_tdb.c deleted file mode 100644 index 8b53982fdb3..00000000000 --- a/source/lib/ldb/ldb_tdb/ldb_tdb.c +++ /dev/null @@ -1,1085 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - Copyright (C) Stefan Metzmacher 2004 - Copyright (C) Simo Sorce 2006 - - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - * Name: ldb_tdb - * - * Component: ldb tdb backend - * - * Description: core functions for tdb backend - * - * Author: Andrew Tridgell - * Author: Stefan Metzmacher - * - * Modifications: - * - * - description: make the module use asyncronous calls - * date: Feb 2006 - * Author: Simo Sorce - */ - -#include "includes.h" -#include "ldb/include/includes.h" - -#include "ldb/ldb_tdb/ldb_tdb.h" - -int ltdb_check_special_dn(struct ldb_module *module, const struct ldb_message *msg); - -/* - map a tdb error code to a ldb error code -*/ -static int ltdb_err_map(enum TDB_ERROR tdb_code) -{ - switch (tdb_code) { - case TDB_SUCCESS: - return LDB_SUCCESS; - case TDB_ERR_CORRUPT: - case TDB_ERR_OOM: - case TDB_ERR_EINVAL: - return LDB_ERR_OPERATIONS_ERROR; - case TDB_ERR_IO: - return LDB_ERR_PROTOCOL_ERROR; - case TDB_ERR_LOCK: - case TDB_ERR_NOLOCK: - return LDB_ERR_BUSY; - case TDB_ERR_LOCK_TIMEOUT: - return LDB_ERR_TIME_LIMIT_EXCEEDED; - case TDB_ERR_EXISTS: - return LDB_ERR_ENTRY_ALREADY_EXISTS; - case TDB_ERR_NOEXIST: - return LDB_ERR_NO_SUCH_OBJECT; - case TDB_ERR_RDONLY: - return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS; - } - return LDB_ERR_OTHER; -} - - -struct ldb_handle *init_ltdb_handle(struct ltdb_private *ltdb, struct ldb_module *module, - struct ldb_request *req) -{ - struct ltdb_context *ac; - struct ldb_handle *h; - - h = talloc_zero(req, struct ldb_handle); - if (h == NULL) { - ldb_set_errstring(module->ldb, "Out of Memory"); - return NULL; - } - - h->module = module; - - ac = talloc_zero(h, struct ltdb_context); - if (ac == NULL) { - ldb_set_errstring(module->ldb, "Out of Memory"); - talloc_free(h); - return NULL; - } - - h->private_data = (void *)ac; - - h->state = LDB_ASYNC_INIT; - h->status = LDB_SUCCESS; - - ac->module = module; - ac->context = req->context; - ac->callback = req->callback; - - return h; -} - -/* - form a TDB_DATA for a record key - caller frees - - note that the key for a record can depend on whether the - dn refers to a case sensitive index record or not -*/ -struct TDB_DATA ltdb_key(struct ldb_module *module, const struct ldb_dn *dn) -{ - struct ldb_context *ldb = module->ldb; - TDB_DATA key; - char *key_str = NULL; - char *dn_folded = NULL; - - /* - most DNs are case insensitive. The exception is index DNs for - case sensitive attributes - - there are 3 cases dealt with in this code: - - 1) if the dn doesn't start with @ then uppercase the attribute - names and the attributes values of case insensitive attributes - 2) if the dn starts with @ then leave it alone - the indexing code handles - the rest - */ - - dn_folded = ldb_dn_linearize_casefold(ldb, ldb, dn); - if (!dn_folded) { - goto failed; - } - - key_str = talloc_asprintf(ldb, "DN=%s", dn_folded); - - talloc_free(dn_folded); - - if (!key_str) { - goto failed; - } - - key.dptr = (uint8_t *)key_str; - key.dsize = strlen(key_str) + 1; - - return key; - -failed: - errno = ENOMEM; - key.dptr = NULL; - key.dsize = 0; - return key; -} - -/* - check special dn's have valid attributes - currently only @ATTRIBUTES is checked -*/ -int ltdb_check_special_dn(struct ldb_module *module, const struct ldb_message *msg) -{ - int i, j; - - if (! ldb_dn_is_special(msg->dn) || - ! ldb_dn_check_special(msg->dn, LTDB_ATTRIBUTES)) { - return 0; - } - - /* we have @ATTRIBUTES, let's check attributes are fine */ - /* should we check that we deny multivalued attributes ? */ - for (i = 0; i < msg->num_elements; i++) { - for (j = 0; j < msg->elements[i].num_values; j++) { - if (ltdb_check_at_attributes_values(&msg->elements[i].values[j]) != 0) { - ldb_set_errstring(module->ldb, "Invalid attribute value in an @ATTRIBUTES entry"); - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - } - } - - return 0; -} - - -/* - we've made a modification to a dn - possibly reindex and - update sequence number -*/ -static int ltdb_modified(struct ldb_module *module, const struct ldb_dn *dn) -{ - int ret = 0; - - if (ldb_dn_is_special(dn) && - (ldb_dn_check_special(dn, LTDB_INDEXLIST) || - ldb_dn_check_special(dn, LTDB_ATTRIBUTES)) ) { - ret = ltdb_reindex(module); - } - - if (ret == 0 && - !(ldb_dn_is_special(dn) && - ldb_dn_check_special(dn, LTDB_BASEINFO)) ) { - ret = ltdb_increase_sequence_number(module); - } - - return ret; -} - -/* - store a record into the db -*/ -int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flgs) -{ - struct ltdb_private *ltdb = - talloc_get_type(module->private_data, struct ltdb_private); - TDB_DATA tdb_key, tdb_data; - int ret; - - tdb_key = ltdb_key(module, msg->dn); - if (!tdb_key.dptr) { - return LDB_ERR_OTHER; - } - - ret = ltdb_pack_data(module, msg, &tdb_data); - if (ret == -1) { - talloc_free(tdb_key.dptr); - return LDB_ERR_OTHER; - } - - ret = tdb_store(ltdb->tdb, tdb_key, tdb_data, flgs); - if (ret == -1) { - ret = ltdb_err_map(tdb_error(ltdb->tdb)); - goto done; - } - - ret = ltdb_index_add(module, msg); - if (ret == -1) { - tdb_delete(ltdb->tdb, tdb_key); - } - -done: - talloc_free(tdb_key.dptr); - talloc_free(tdb_data.dptr); - - return ret; -} - - -static int ltdb_add_internal(struct ldb_module *module, const struct ldb_message *msg) -{ - int ret; - - ret = ltdb_check_special_dn(module, msg); - if (ret != LDB_SUCCESS) { - return ret; - } - - if (ltdb_cache_load(module) != 0) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ltdb_store(module, msg, TDB_INSERT); - - if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) { - char *dn; - - dn = ldb_dn_linearize(module, msg->dn); - if (!dn) { - return ret; - } - ldb_asprintf_errstring(module->ldb, "Entry %s already exists", dn); - talloc_free(dn); - return ret; - } - - if (ret == LDB_SUCCESS) { - ret = ltdb_modified(module, msg->dn); - if (ret != LDB_SUCCESS) { - return LDB_ERR_OPERATIONS_ERROR; - } - } - - return ret; -} - -/* - add a record to the database -*/ -static int ltdb_add(struct ldb_module *module, struct ldb_request *req) -{ - struct ltdb_private *ltdb = talloc_get_type(module->private_data, struct ltdb_private); - struct ltdb_context *ltdb_ac; - int tret, ret = LDB_SUCCESS; - - if (req->controls != NULL) { - ldb_debug(module->ldb, LDB_DEBUG_WARNING, "Controls should not reach the ldb_tdb backend!\n"); - if (check_critical_controls(req->controls)) { - return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION; - } - } - - req->handle = init_ltdb_handle(ltdb, module, req); - if (req->handle == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - ltdb_ac = talloc_get_type(req->handle->private_data, struct ltdb_context); - - tret = ltdb_add_internal(module, req->op.add.message); - if (tret != LDB_SUCCESS) { - req->handle->status = tret; - goto done; - } - - if (ltdb_ac->callback) { - ret = ltdb_ac->callback(module->ldb, ltdb_ac->context, NULL); - } -done: - req->handle->state = LDB_ASYNC_DONE; - return ret; -} - -/* - delete a record from the database, not updating indexes (used for deleting - index records) -*/ -int ltdb_delete_noindex(struct ldb_module *module, const struct ldb_dn *dn) -{ - struct ltdb_private *ltdb = - talloc_get_type(module->private_data, struct ltdb_private); - TDB_DATA tdb_key; - int ret; - - tdb_key = ltdb_key(module, dn); - if (!tdb_key.dptr) { - return LDB_ERR_OTHER; - } - - ret = tdb_delete(ltdb->tdb, tdb_key); - talloc_free(tdb_key.dptr); - - if (ret != 0) { - ret = ltdb_err_map(tdb_error(ltdb->tdb)); - } - - return ret; -} - -static int ltdb_delete_internal(struct ldb_module *module, const struct ldb_dn *dn) -{ - struct ldb_message *msg; - int ret; - - msg = talloc(module, struct ldb_message); - if (msg == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* in case any attribute of the message was indexed, we need - to fetch the old record */ - ret = ltdb_search_dn1(module, dn, msg); - if (ret != 1) { - /* not finding the old record is an error */ - talloc_free(msg); - return LDB_ERR_NO_SUCH_OBJECT; - } - - ret = ltdb_delete_noindex(module, dn); - if (ret != LDB_SUCCESS) { - talloc_free(msg); - return LDB_ERR_NO_SUCH_OBJECT; - } - - /* remove any indexed attributes */ - ret = ltdb_index_del(module, msg); - if (ret != LDB_SUCCESS) { - talloc_free(msg); - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ltdb_modified(module, dn); - if (ret != LDB_SUCCESS) { - talloc_free(msg); - return LDB_ERR_OPERATIONS_ERROR; - } - - talloc_free(msg); - return LDB_SUCCESS; -} - -/* - delete a record from the database -*/ -static int ltdb_delete(struct ldb_module *module, struct ldb_request *req) -{ - struct ltdb_private *ltdb = talloc_get_type(module->private_data, struct ltdb_private); - struct ltdb_context *ltdb_ac; - int tret, ret = LDB_SUCCESS; - - if (req->controls != NULL) { - ldb_debug(module->ldb, LDB_DEBUG_WARNING, "Controls should not reach the ldb_tdb backend!\n"); - if (check_critical_controls(req->controls)) { - return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION; - } - } - - req->handle = NULL; - - if (ltdb_cache_load(module) != 0) { - return LDB_ERR_OPERATIONS_ERROR; - } - - req->handle = init_ltdb_handle(ltdb, module, req); - if (req->handle == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - ltdb_ac = talloc_get_type(req->handle->private_data, struct ltdb_context); - - tret = ltdb_delete_internal(module, req->op.del.dn); - if (tret != LDB_SUCCESS) { - req->handle->status = tret; - goto done; - } - - if (ltdb_ac->callback) { - ret = ltdb_ac->callback(module->ldb, ltdb_ac->context, NULL); - } -done: - req->handle->state = LDB_ASYNC_DONE; - return ret; -} - -/* - find an element by attribute name. At the moment this does a linear search, it should - be re-coded to use a binary search once all places that modify records guarantee - sorted order - - return the index of the first matching element if found, otherwise -1 -*/ -static int find_element(const struct ldb_message *msg, const char *name) -{ - unsigned int i; - for (i=0;i<msg->num_elements;i++) { - if (ldb_attr_cmp(msg->elements[i].name, name) == 0) { - return i; - } - } - return -1; -} - - -/* - add an element to an existing record. Assumes a elements array that we - can call re-alloc on, and assumed that we can re-use the data pointers from the - passed in additional values. Use with care! - - returns 0 on success, -1 on failure (and sets errno) -*/ -static int msg_add_element(struct ldb_context *ldb, - struct ldb_message *msg, struct ldb_message_element *el) -{ - struct ldb_message_element *e2; - unsigned int i; - - e2 = talloc_realloc(msg, msg->elements, struct ldb_message_element, - msg->num_elements+1); - if (!e2) { - errno = ENOMEM; - return -1; - } - - msg->elements = e2; - - e2 = &msg->elements[msg->num_elements]; - - e2->name = el->name; - e2->flags = el->flags; - e2->values = NULL; - if (el->num_values != 0) { - e2->values = talloc_array(msg->elements, struct ldb_val, el->num_values); - if (!e2->values) { - errno = ENOMEM; - return -1; - } - } - for (i=0;i<el->num_values;i++) { - e2->values[i] = el->values[i]; - } - e2->num_values = el->num_values; - - msg->num_elements++; - - return 0; -} - -/* - delete all elements having a specified attribute name -*/ -static int msg_delete_attribute(struct ldb_module *module, - struct ldb_context *ldb, - struct ldb_message *msg, const char *name) -{ - char *dn; - unsigned int i, j; - - dn = ldb_dn_linearize(ldb, msg->dn); - if (dn == NULL) { - return -1; - } - - for (i=0;i<msg->num_elements;i++) { - if (ldb_attr_cmp(msg->elements[i].name, name) == 0) { - for (j=0;j<msg->elements[i].num_values;j++) { - ltdb_index_del_value(module, dn, &msg->elements[i], j); - } - talloc_free(msg->elements[i].values); - if (msg->num_elements > (i+1)) { - memmove(&msg->elements[i], - &msg->elements[i+1], - sizeof(struct ldb_message_element)* - (msg->num_elements - (i+1))); - } - msg->num_elements--; - i--; - msg->elements = talloc_realloc(msg, msg->elements, - struct ldb_message_element, - msg->num_elements); - } - } - - talloc_free(dn); - return 0; -} - -/* - delete all elements matching an attribute name/value - - return 0 on success, -1 on failure -*/ -static int msg_delete_element(struct ldb_module *module, - struct ldb_message *msg, - const char *name, - const struct ldb_val *val) -{ - struct ldb_context *ldb = module->ldb; - unsigned int i; - int found; - struct ldb_message_element *el; - const struct ldb_attrib_handler *h; - - found = find_element(msg, name); - if (found == -1) { - return -1; - } - - el = &msg->elements[found]; - - h = ldb_attrib_handler(ldb, el->name); - - for (i=0;i<el->num_values;i++) { - if (h->comparison_fn(ldb, ldb, &el->values[i], val) == 0) { - if (i<el->num_values-1) { - memmove(&el->values[i], &el->values[i+1], - sizeof(el->values[i])*(el->num_values-(i+1))); - } - el->num_values--; - if (el->num_values == 0) { - return msg_delete_attribute(module, ldb, msg, name); - } - return 0; - } - } - - return -1; -} - - -/* - modify a record - internal interface - - yuck - this is O(n^2). Luckily n is usually small so we probably - get away with it, but if we ever have really large attribute lists - then we'll need to look at this again -*/ -int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *msg) -{ - struct ldb_context *ldb = module->ldb; - struct ltdb_private *ltdb = - talloc_get_type(module->private_data, struct ltdb_private); - TDB_DATA tdb_key, tdb_data; - struct ldb_message *msg2; - unsigned i, j; - int ret; - - tdb_key = ltdb_key(module, msg->dn); - if (!tdb_key.dptr) { - return LDB_ERR_OTHER; - } - - tdb_data = tdb_fetch(ltdb->tdb, tdb_key); - if (!tdb_data.dptr) { - talloc_free(tdb_key.dptr); - return ltdb_err_map(tdb_error(ltdb->tdb)); - } - - msg2 = talloc(tdb_key.dptr, struct ldb_message); - if (msg2 == NULL) { - talloc_free(tdb_key.dptr); - return LDB_ERR_OTHER; - } - - ret = ltdb_unpack_data(module, &tdb_data, msg2); - if (ret == -1) { - ret = LDB_ERR_OTHER; - goto failed; - } - - if (!msg2->dn) { - msg2->dn = msg->dn; - } - - for (i=0;i<msg->num_elements;i++) { - struct ldb_message_element *el = &msg->elements[i]; - struct ldb_message_element *el2; - struct ldb_val *vals; - char *dn; - - switch (msg->elements[i].flags & LDB_FLAG_MOD_MASK) { - - case LDB_FLAG_MOD_ADD: - /* add this element to the message. fail if it - already exists */ - ret = find_element(msg2, el->name); - - if (ret == -1) { - if (msg_add_element(ldb, msg2, el) != 0) { - ret = LDB_ERR_OTHER; - goto failed; - } - continue; - } - - el2 = &msg2->elements[ret]; - - /* An attribute with this name already exists, add all - * values if they don't already exist. */ - - for (j=0;j<el->num_values;j++) { - if (ldb_msg_find_val(el2, &el->values[j])) { - ldb_set_errstring(module->ldb, "Type or value exists"); - ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; - goto failed; - } - } - - vals = talloc_realloc(msg2->elements, el2->values, struct ldb_val, - el2->num_values + el->num_values); - - if (vals == NULL) { - ret = LDB_ERR_OTHER; - goto failed; - } - - for (j=0;j<el->num_values;j++) { - vals[el2->num_values + j] = - ldb_val_dup(vals, &el->values[j]); - } - - el2->values = vals; - el2->num_values += el->num_values; - - break; - - case LDB_FLAG_MOD_REPLACE: - /* replace all elements of this attribute name with the elements - listed. The attribute not existing is not an error */ - msg_delete_attribute(module, ldb, msg2, msg->elements[i].name); - - /* add the replacement element, if not empty */ - if (msg->elements[i].num_values != 0 && - msg_add_element(ldb, msg2, &msg->elements[i]) != 0) { - ret = LDB_ERR_OTHER; - goto failed; - } - break; - - case LDB_FLAG_MOD_DELETE: - - dn = ldb_dn_linearize(msg2, msg->dn); - if (dn == NULL) { - ret = LDB_ERR_OTHER; - goto failed; - } - - /* we could be being asked to delete all - values or just some values */ - if (msg->elements[i].num_values == 0) { - if (msg_delete_attribute(module, ldb, msg2, - msg->elements[i].name) != 0) { - ldb_asprintf_errstring(module->ldb, "No such attribute: %s for delete on %s", msg->elements[i].name, dn); - ret = LDB_ERR_NO_SUCH_ATTRIBUTE; - goto failed; - } - break; - } - for (j=0;j<msg->elements[i].num_values;j++) { - if (msg_delete_element(module, - msg2, - msg->elements[i].name, - &msg->elements[i].values[j]) != 0) { - ldb_asprintf_errstring(module->ldb, "No matching attribute value when deleting attribute: %s on %s", msg->elements[i].name, dn); - ret = LDB_ERR_NO_SUCH_ATTRIBUTE; - goto failed; - } - if (ltdb_index_del_value(module, dn, &msg->elements[i], j) != 0) { - ret = LDB_ERR_OTHER; - goto failed; - } - } - break; - default: - ldb_asprintf_errstring(module->ldb, "Invalid ldb_modify flags on %s: 0x%x", - msg->elements[i].name, - msg->elements[i].flags & LDB_FLAG_MOD_MASK); - ret = LDB_ERR_PROTOCOL_ERROR; - goto failed; - } - } - - /* we've made all the mods - save the modified record back into the database */ - ret = ltdb_store(module, msg2, TDB_MODIFY); - if (ret != LDB_SUCCESS) { - goto failed; - } - - if (ltdb_modified(module, msg->dn) != LDB_SUCCESS) { - ret = LDB_ERR_OPERATIONS_ERROR; - goto failed; - } - - talloc_free(tdb_key.dptr); - free(tdb_data.dptr); - return ret; - -failed: - talloc_free(tdb_key.dptr); - free(tdb_data.dptr); - return ret; -} - -/* - modify a record -*/ -static int ltdb_modify(struct ldb_module *module, struct ldb_request *req) -{ - struct ltdb_private *ltdb = talloc_get_type(module->private_data, struct ltdb_private); - struct ltdb_context *ltdb_ac; - int tret, ret = LDB_SUCCESS; - - if (req->controls != NULL) { - ldb_debug(module->ldb, LDB_DEBUG_WARNING, "Controls should not reach the ldb_tdb backend!\n"); - if (check_critical_controls(req->controls)) { - return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION; - } - } - - req->handle = NULL; - - req->handle = init_ltdb_handle(ltdb, module, req); - if (req->handle == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - ltdb_ac = talloc_get_type(req->handle->private_data, struct ltdb_context); - - tret = ltdb_check_special_dn(module, req->op.mod.message); - if (tret != LDB_SUCCESS) { - req->handle->status = tret; - goto done; - } - - if (ltdb_cache_load(module) != 0) { - ret = LDB_ERR_OPERATIONS_ERROR; - goto done; - } - - tret = ltdb_modify_internal(module, req->op.mod.message); - if (tret != LDB_SUCCESS) { - req->handle->status = tret; - goto done; - } - - if (ltdb_ac->callback) { - ret = ltdb_ac->callback(module->ldb, ltdb_ac->context, NULL); - } -done: - req->handle->state = LDB_ASYNC_DONE; - return ret; -} - -/* - rename a record -*/ -static int ltdb_rename(struct ldb_module *module, struct ldb_request *req) -{ - struct ltdb_private *ltdb = talloc_get_type(module->private_data, struct ltdb_private); - struct ltdb_context *ltdb_ac; - struct ldb_message *msg; - int tret, ret = LDB_SUCCESS; - - if (req->controls != NULL) { - ldb_debug(module->ldb, LDB_DEBUG_WARNING, "Controls should not reach the ldb_tdb backend!\n"); - if (check_critical_controls(req->controls)) { - return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION; - } - } - - req->handle = NULL; - - if (ltdb_cache_load(module) != 0) { - return LDB_ERR_OPERATIONS_ERROR; - } - - req->handle = init_ltdb_handle(ltdb, module, req); - if (req->handle == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - ltdb_ac = talloc_get_type(req->handle->private_data, struct ltdb_context); - - msg = talloc(ltdb_ac, struct ldb_message); - if (msg == NULL) { - ret = LDB_ERR_OPERATIONS_ERROR; - goto done; - } - - /* in case any attribute of the message was indexed, we need - to fetch the old record */ - tret = ltdb_search_dn1(module, req->op.rename.olddn, msg); - if (tret != 1) { - /* not finding the old record is an error */ - req->handle->status = LDB_ERR_NO_SUCH_OBJECT; - goto done; - } - - msg->dn = ldb_dn_copy(msg, req->op.rename.newdn); - if (!msg->dn) { - ret = LDB_ERR_OPERATIONS_ERROR; - goto done; - } - - tret = ltdb_add_internal(module, msg); - if (tret != LDB_SUCCESS) { - ret = LDB_ERR_OPERATIONS_ERROR; - goto done; - } - - tret = ltdb_delete_internal(module, req->op.rename.olddn); - if (tret != LDB_SUCCESS) { - ltdb_delete_internal(module, req->op.rename.newdn); - ret = LDB_ERR_OPERATIONS_ERROR; - goto done; - } - - if (ltdb_ac->callback) { - ret = ltdb_ac->callback(module->ldb, ltdb_ac->context, NULL); - } -done: - req->handle->state = LDB_ASYNC_DONE; - return ret; -} - -static int ltdb_start_trans(struct ldb_module *module) -{ - struct ltdb_private *ltdb = - talloc_get_type(module->private_data, struct ltdb_private); - - if (tdb_transaction_start(ltdb->tdb) != 0) { - return ltdb_err_map(tdb_error(ltdb->tdb)); - } - - return LDB_SUCCESS; -} - -static int ltdb_end_trans(struct ldb_module *module) -{ - struct ltdb_private *ltdb = - talloc_get_type(module->private_data, struct ltdb_private); - - if (tdb_transaction_commit(ltdb->tdb) != 0) { - return ltdb_err_map(tdb_error(ltdb->tdb)); - } - - return LDB_SUCCESS; -} - -static int ltdb_del_trans(struct ldb_module *module) -{ - struct ltdb_private *ltdb = - talloc_get_type(module->private_data, struct ltdb_private); - - if (tdb_transaction_cancel(ltdb->tdb) != 0) { - return ltdb_err_map(tdb_error(ltdb->tdb)); - } - - return LDB_SUCCESS; -} - -static int ltdb_wait(struct ldb_handle *handle, enum ldb_wait_type type) -{ - return handle->status; -} - -static int ltdb_request(struct ldb_module *module, struct ldb_request *req) -{ - /* check for oustanding critical controls and return an error if found */ - if (req->controls != NULL) { - ldb_debug(module->ldb, LDB_DEBUG_WARNING, "Controls should not reach the ldb_tdb backend!\n"); - if (check_critical_controls(req->controls)) { - return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION; - } - } - - /* search, add, modify, delete, rename are handled by their own, no other op supported */ - return LDB_ERR_OPERATIONS_ERROR; -} - -/* - return sequenceNumber from @BASEINFO -*/ -static int ltdb_sequence_number(struct ldb_module *module, struct ldb_request *req) -{ - TALLOC_CTX *tmp_ctx = talloc_new(req); - struct ldb_message *msg = NULL; - struct ldb_dn *dn = ldb_dn_explode(tmp_ctx, LTDB_BASEINFO); - int tret; - - if (tmp_ctx == NULL) { - talloc_free(tmp_ctx); - return LDB_ERR_OPERATIONS_ERROR; - } - - msg = talloc(tmp_ctx, struct ldb_message); - if (msg == NULL) { - talloc_free(tmp_ctx); - return LDB_ERR_OPERATIONS_ERROR; - } - - req->op.seq_num.flags = 0; - - tret = ltdb_search_dn1(module, dn, msg); - if (tret != 1) { - talloc_free(tmp_ctx); - req->op.seq_num.seq_num = 0; - /* zero is as good as anything when we don't know */ - return LDB_SUCCESS; - } - - switch (req->op.seq_num.type) { - case LDB_SEQ_HIGHEST_SEQ: - req->op.seq_num.seq_num = ldb_msg_find_attr_as_uint64(msg, LTDB_SEQUENCE_NUMBER, 0); - break; - case LDB_SEQ_NEXT: - req->op.seq_num.seq_num = ldb_msg_find_attr_as_uint64(msg, LTDB_SEQUENCE_NUMBER, 0); - req->op.seq_num.seq_num++; - break; - case LDB_SEQ_HIGHEST_TIMESTAMP: - { - const char *date = ldb_msg_find_attr_as_string(msg, LTDB_MOD_TIMESTAMP, NULL); - if (date) { - req->op.seq_num.seq_num = ldb_string_to_time(date); - } else { - req->op.seq_num.seq_num = 0; - /* zero is as good as anything when we don't know */ - } - break; - } - } - talloc_free(tmp_ctx); - return LDB_SUCCESS; -} - -static const struct ldb_module_ops ltdb_ops = { - .name = "tdb", - .search = ltdb_search, - .add = ltdb_add, - .modify = ltdb_modify, - .del = ltdb_delete, - .rename = ltdb_rename, - .request = ltdb_request, - .start_transaction = ltdb_start_trans, - .end_transaction = ltdb_end_trans, - .del_transaction = ltdb_del_trans, - .wait = ltdb_wait, - .sequence_number = ltdb_sequence_number -}; - -/* - connect to the database -*/ -static int ltdb_connect(struct ldb_context *ldb, const char *url, - unsigned int flags, const char *options[], - struct ldb_module **module) -{ - const char *path; - int tdb_flags, open_flags; - struct ltdb_private *ltdb; - - /* parse the url */ - if (strchr(url, ':')) { - if (strncmp(url, "tdb://", 6) != 0) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid tdb URL '%s'", url); - return -1; - } - path = url+6; - } else { - path = url; - } - - tdb_flags = TDB_DEFAULT | TDB_SEQNUM; - - /* check for the 'nosync' option */ - if (flags & LDB_FLG_NOSYNC) { - tdb_flags |= TDB_NOSYNC; - } - - /* and nommap option */ - if (flags & LDB_FLG_NOMMAP) { - tdb_flags |= TDB_NOMMAP; - } - - if (flags & LDB_FLG_RDONLY) { - open_flags = O_RDONLY; - } else { - open_flags = O_CREAT | O_RDWR; - } - - ltdb = talloc_zero(ldb, struct ltdb_private); - if (!ltdb) { - ldb_oom(ldb); - return -1; - } - - /* note that we use quite a large default hash size */ - ltdb->tdb = ltdb_wrap_open(ltdb, path, 10000, - tdb_flags, open_flags, - ldb->create_perms, ldb); - if (!ltdb->tdb) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "Unable to open tdb '%s'\n", path); - talloc_free(ltdb); - return -1; - } - - ltdb->sequence_number = 0; - - *module = talloc(ldb, struct ldb_module); - if (!module) { - ldb_oom(ldb); - talloc_free(ltdb); - return -1; - } - talloc_set_name_const(*module, "ldb_tdb backend"); - (*module)->ldb = ldb; - (*module)->prev = (*module)->next = NULL; - (*module)->private_data = ltdb; - (*module)->ops = <db_ops; - - if (ltdb_cache_load(*module) != 0) { - talloc_free(*module); - talloc_free(ltdb); - return -1; - } - - return 0; -} - -int ldb_tdb_init(void) -{ - return ldb_register_backend("tdb", ltdb_connect); -} diff --git a/source/lib/ldb/ldb_tdb/ldb_tdb.h b/source/lib/ldb/ldb_tdb/ldb_tdb.h deleted file mode 100644 index 42f3dc24212..00000000000 --- a/source/lib/ldb/ldb_tdb/ldb_tdb.h +++ /dev/null @@ -1,129 +0,0 @@ - -#ifdef _SAMBA_BUILD_ -#include "system/filesys.h" -#endif - -#if (_SAMBA_BUILD_ >= 4) -#include "lib/tdb/include/tdb.h" -#elif defined(_SAMBA_BUILD_) -#include "tdb/include/tdb.h" -#else -#include "tdb.h" -#endif - -/* this private structure is used by the ltdb backend in the - ldb_context */ -struct ltdb_private { - TDB_CONTEXT *tdb; - unsigned int connect_flags; - - /* a double is used for portability and ease of string - handling. It has plenty of digits of precision */ - unsigned long long sequence_number; - - /* the low level tdb seqnum - used to avoid loading BASEINFO when - possible */ - int tdb_seqnum; - - struct ltdb_cache { - struct ldb_message *indexlist; - struct ldb_message *attributes; - struct ldb_message *subclasses; - - struct { - char *name; - int flags; - } last_attribute; - } *cache; -}; - -/* - the async local context - holds also internal search state during a full db search -*/ -struct ltdb_context { - struct ldb_module *module; - - /* search stuff */ - const struct ldb_parse_tree *tree; - const struct ldb_dn *base; - enum ldb_scope scope; - const char * const *attrs; - - /* async stuff */ - void *context; - int (*callback)(struct ldb_context *, void *, struct ldb_reply *); -}; - -/* special record types */ -#define LTDB_INDEX "@INDEX" -#define LTDB_INDEXLIST "@INDEXLIST" -#define LTDB_IDX "@IDX" -#define LTDB_IDXATTR "@IDXATTR" -#define LTDB_BASEINFO "@BASEINFO" -#define LTDB_ATTRIBUTES "@ATTRIBUTES" -#define LTDB_SUBCLASSES "@SUBCLASSES" - -/* special attribute types */ -#define LTDB_SEQUENCE_NUMBER "sequenceNumber" -#define LTDB_MOD_TIMESTAMP "whenChanged" -#define LTDB_OBJECTCLASS "objectClass" - -/* The following definitions come from lib/ldb/ldb_tdb/ldb_cache.c */ - -int ltdb_cache_reload(struct ldb_module *module); -int ltdb_cache_load(struct ldb_module *module); -int ltdb_increase_sequence_number(struct ldb_module *module); -int ltdb_check_at_attributes_values(const struct ldb_val *value); - -/* The following definitions come from lib/ldb/ldb_tdb/ldb_index.c */ - -struct ldb_parse_tree; - -int ltdb_search_indexed(struct ldb_handle *handle); -int ltdb_index_add(struct ldb_module *module, const struct ldb_message *msg); -int ltdb_index_del(struct ldb_module *module, const struct ldb_message *msg); -int ltdb_reindex(struct ldb_module *module); - -/* The following definitions come from lib/ldb/ldb_tdb/ldb_pack.c */ - -int ltdb_pack_data(struct ldb_module *module, - const struct ldb_message *message, - struct TDB_DATA *data); -void ltdb_unpack_data_free(struct ldb_module *module, - struct ldb_message *message); -int ltdb_unpack_data(struct ldb_module *module, - const struct TDB_DATA *data, - struct ldb_message *message); - -/* The following definitions come from lib/ldb/ldb_tdb/ldb_search.c */ - -int ltdb_has_wildcard(struct ldb_module *module, const char *attr_name, - const struct ldb_val *val); -void ltdb_search_dn1_free(struct ldb_module *module, struct ldb_message *msg); -int ltdb_search_dn1(struct ldb_module *module, const struct ldb_dn *dn, struct ldb_message *msg); -int ltdb_add_attr_results(struct ldb_module *module, - TALLOC_CTX *mem_ctx, - struct ldb_message *msg, - const char * const attrs[], - unsigned int *count, - struct ldb_message ***res); -int ltdb_filter_attrs(struct ldb_message *msg, const char * const *attrs); -int ltdb_search(struct ldb_module *module, struct ldb_request *req); - -/* The following definitions come from lib/ldb/ldb_tdb/ldb_tdb.c */ -struct ldb_handle *init_ltdb_handle(struct ltdb_private *ltdb, struct ldb_module *module, - struct ldb_request *req); -struct TDB_DATA ltdb_key(struct ldb_module *module, const struct ldb_dn *dn); -int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flgs); -int ltdb_delete_noindex(struct ldb_module *module, const struct ldb_dn *dn); -int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *msg); - -int ltdb_index_del_value(struct ldb_module *module, const char *dn, - struct ldb_message_element *el, int v_idx); - -struct tdb_context *ltdb_wrap_open(TALLOC_CTX *mem_ctx, - const char *path, int hash_size, int tdb_flags, - int open_flags, mode_t mode, - struct ldb_context *ldb); - diff --git a/source/lib/ldb/ldb_tdb/ldb_tdb_wrap.c b/source/lib/ldb/ldb_tdb/ldb_tdb_wrap.c deleted file mode 100644 index 03c9ae85b25..00000000000 --- a/source/lib/ldb/ldb_tdb/ldb_tdb_wrap.c +++ /dev/null @@ -1,155 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2005 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include "includes.h" -#include "ldb/include/includes.h" - -#include "ldb/ldb_tdb/ldb_tdb.h" - -/* - the purpose of this code is to work around the braindead posix locking - rules, to allow us to have a ldb open more than once while allowing - locking to work -*/ - -struct ltdb_wrap { - struct ltdb_wrap *next, *prev; - struct tdb_context *tdb; - dev_t device; - ino_t inode; -}; - -static struct ltdb_wrap *tdb_list; - -/* destroy the last connection to a tdb */ -static int ltdb_wrap_destructor(struct ltdb_wrap *w) -{ - tdb_close(w->tdb); - if (w->next) { - w->next->prev = w->prev; - } - if (w->prev) { - w->prev->next = w->next; - } - if (w == tdb_list) { - tdb_list = w->next; - } - return 0; -} - -static void ltdb_log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) PRINTF_ATTRIBUTE(3, 4); -static void ltdb_log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) -{ - va_list ap; - const char *name = tdb_name(tdb); - struct ldb_context *ldb = talloc_get_type(tdb_get_logging_private(tdb), struct ldb_context); - enum ldb_debug_level ldb_level; - char *message; - va_start(ap, fmt); - message = talloc_vasprintf(ldb, fmt, ap); - va_end(ap); - - switch (level) { - case TDB_DEBUG_FATAL: - ldb_level = LDB_DEBUG_FATAL; - break; - case TDB_DEBUG_ERROR: - ldb_level = LDB_DEBUG_ERROR; - break; - case TDB_DEBUG_WARNING: - ldb_level = LDB_DEBUG_WARNING; - break; - case TDB_DEBUG_TRACE: - ldb_level = LDB_DEBUG_TRACE; - break; - default: - ldb_level = LDB_DEBUG_FATAL; - } - - ldb_debug(ldb, ldb_level, "ltdb: tdb(%s): %s", name, message); - talloc_free(message); -} - -/* - wrapped connection to a tdb database. The caller should _not_ free - this as it is not a talloc structure (as tdb does not use talloc - yet). It will auto-close when the caller frees the mem_ctx that is - passed to this call - */ -struct tdb_context *ltdb_wrap_open(TALLOC_CTX *mem_ctx, - const char *path, int hash_size, - int tdb_flags, - int open_flags, mode_t mode, - struct ldb_context *ldb) -{ - struct ltdb_wrap *w; - struct stat st; - struct tdb_logging_context log_ctx; - - log_ctx.log_fn = ltdb_log_fn; - log_ctx.log_private = ldb; - - if (stat(path, &st) == 0) { - for (w=tdb_list;w;w=w->next) { - if (st.st_dev == w->device && st.st_ino == w->inode) { - if (!talloc_reference(mem_ctx, w)) { - return NULL; - } - return w->tdb; - } - } - } - - w = talloc(mem_ctx, struct ltdb_wrap); - if (w == NULL) { - return NULL; - } - - w->tdb = tdb_open_ex(path, hash_size, tdb_flags, open_flags, mode, &log_ctx, NULL); - if (w->tdb == NULL) { - talloc_free(w); - return NULL; - } - - if (fstat(tdb_fd(w->tdb), &st) != 0) { - tdb_close(w->tdb); - talloc_free(w); - return NULL; - } - - w->device = st.st_dev; - w->inode = st.st_ino; - - talloc_set_destructor(w, ltdb_wrap_destructor); - - w->next = tdb_list; - w->prev = NULL; - if (tdb_list) { - tdb_list->prev = w; - } - tdb_list = w; - - return w->tdb; -} - diff --git a/source/lib/ldb/libldb.m4 b/source/lib/ldb/libldb.m4 deleted file mode 100644 index 845563b4a18..00000000000 --- a/source/lib/ldb/libldb.m4 +++ /dev/null @@ -1,33 +0,0 @@ -SMB_ENABLE(ldb_sqlite3,$with_sqlite3_support) - -AC_MSG_CHECKING([for Python]) - -PYTHON= - -AC_ARG_WITH(python, -[ --with-python=PYTHONNAME build Python libraries], -[ case "${withval-python}" in - yes) - PYTHON=python - ;; - no) - PYTHON= - ;; - *) - PYTHON=${withval-python} - ;; - esac ]) - -if test x"$PYTHON" != "x"; then - incdir=`python -c 'import sys; print "%s/include/python%d.%d" % (sys.prefix, sys.version_info[[0]], sys.version_info[[1]])'` - CPPFLAGS="$CPPFLAGS -I $incdir" -fi - -if test x"$PYTHON" != "x"; then - AC_MSG_RESULT([${withval-python}]) -else - AC_MSG_RESULT(no) - SMB_ENABLE(swig_ldb, NO) -fi - -AC_SUBST(PYTHON) diff --git a/source/lib/ldb/mainpage.dox b/source/lib/ldb/mainpage.dox deleted file mode 100644 index bbd8d9c5025..00000000000 --- a/source/lib/ldb/mainpage.dox +++ /dev/null @@ -1,80 +0,0 @@ -/** - -\mainpage ldb - -\section Overview - -ldb is a LDAP-like embedded database. It is not at all LDAP standards -compliant, so if you want a standards compliant database then please -see the excellent <a href="http://www.openldap.org/">OpenLDAP</a> -project.<p> - -What ldb does is provide a fast database with an LDAP-like API -designed to be used within an application. In some ways it can be seen -as a intermediate solution between key-value pair databases and a real -LDAP database.<p> - -ldb is the database engine used in Samba4. - -\section Features - -The main features that separate ldb from other solutions are: - - Safe multi-reader, multi-writer, using byte range locking - - LDAP-like API - - fast operation - - choice of local tdb, local sqlite3 or remote LDAP backends - - integration with <a href="http://talloc.samba.org">talloc</a> - - schema-less operation, for trivial setup - - modules for extensions (such as schema support) - - easy setup of indexes and attribute properties - - ldbedit tool for database editing (reminiscent of 'vipw') - - ldif for import/export - -\section Documentation - -ldb has limited programmer and administrator documentation: - - a list of <a href="globals_func.html">functions</a> - - a list of <a href="examples.html">examples</a> - - a list of <a href="annotated.html">data structures</a> - - a list of <a href="globals_defs.html">constants</a> - -If you need more information than is presented in this document, you -may wish to look at the source code, especially the source code in the -<a href="http://samba.org/ftp/unpacked/samba4/source/lib/ldb/tools/">tools directory</a>. - -ldb makes use of the LDAP Data Interchange Format (LDIF), which is -documented in <a href="http://www.ietf.org/rfc/rfc2849.txt">RFC -2849</a>. - -\section Support - -ldb does not currently have its own mailing list or bug tracking -system. For now, please use the <a -href="https://lists.samba.org/mailman/listinfo/samba-technical">samba-technical</a> -mailing list, and the <a href="http://bugzilla.samba.org/">Samba -bugzilla</a> bug tracking system. - -\section Download - -You can download the latest release either via rsync or anonymous -svn. To fetch via svn use the following commands: - -\verbatim - svn co svn://svnanon.samba.org/samba/branches/SAMBA_4_0/source/lib/ldb ldb - svn co svn://svnanon.samba.org/samba/branches/SAMBA_4_0/source/lib/tdb tdb - svn co svn://svnanon.samba.org/samba/branches/SAMBA_4_0/source/lib/talloc talloc -\endverbatim - -To fetch via rsync use these commands: - -\verbatim - rsync -Pavz samba.org::ftp/unpacked/samba4/source/lib/ldb . - rsync -Pavz samba.org::ftp/unpacked/samba4/source/lib/tdb . - rsync -Pavz samba.org::ftp/unpacked/samba4/source/lib/talloc . -\endverbatim - -\section Credits - -ldb is another product of the prolific <a href="http://samba.org/~tridge/">Andrew Tridgell</a>. - -*/ diff --git a/source/lib/ldb/man/ad2oLschema.1.xml b/source/lib/ldb/man/ad2oLschema.1.xml deleted file mode 100644 index 6ae89964775..00000000000 --- a/source/lib/ldb/man/ad2oLschema.1.xml +++ /dev/null @@ -1,87 +0,0 @@ -<?xml version="1.0" encoding="iso-8859-1"?> -<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> -<refentry id="ad2oLschema.1"> - -<refmeta> - <refentrytitle>ad2oLschema</refentrytitle> - <manvolnum>1</manvolnum> -</refmeta> - - -<refnamediv> - <refname>ad2oLschema</refname> - <refpurpose>Converts AC-like LDAP schemas to OpenLDAP - compatible schema files</refpurpose> -</refnamediv> - -<refsynopsisdiv> - <cmdsynopsis> - <command>ad2oLschema</command> - <arg choice="opt">-I INPUT-FILE</arg> - <arg choice="opt">-O OUTPUT-FILE</arg> - </cmdsynopsis> -</refsynopsisdiv> - -<refsect1> - <title>DESCRIPTION</title> - - <para>ad2oLschema is a simple tool that converts AD-like LDIF - schema files into OpenLDAP schema files.</para> -</refsect1> - - -<refsect1> - <title>OPTIONS</title> - - <variablelist> - <varlistentry> - <term>-H url</term> - <listitem><para>URL to an LDB or LDAP server with an AD schema to read. </para></listitem> - </varlistentry> - - <varlistentry> - <term>-I input-file</term> <listitem><para>AD schema - to read. If neither this nor -H is specified, the - schema file will be read from standard input. - </para></listitem> - </varlistentry> - - <varlistentry> - <term>-O output-file</term> - <listitem><para>File to write OpenLDAP version of schema to. - </para></listitem> - </varlistentry> - </variablelist> -</refsect1> - -<refsect1> - <title>VERSION</title> - - <para>This man page is correct for version 4.0 of the Samba suite.</para> -</refsect1> - -<refsect1> - <title>SEE ALSO</title> - - <para>ldb(7), ldbmodify, ldbdel, ldif(5)</para> - -</refsect1> - -<refsect1> - <title>AUTHOR</title> - - <para> ldb was written by - <ulink url="http://samba.org/~tridge/">Andrew Tridgell</ulink>. - ad2oLschema was written by <ulink - url="http://samba.org/~abartlet/">Andrew Bartlett</ulink>. - </para> - - <para> -If you wish to report a problem or make a suggestion then please see -the <ulink url="http://ldb.samba.org/"/> web site for -current contact and maintainer information. - </para> - -</refsect1> - -</refentry> diff --git a/source/lib/ldb/man/ldb.3.xml b/source/lib/ldb/man/ldb.3.xml deleted file mode 100644 index 19d9a89e102..00000000000 --- a/source/lib/ldb/man/ldb.3.xml +++ /dev/null @@ -1,262 +0,0 @@ -<?xml version="1.0" encoding="iso-8859-1"?> -<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> -<refentry id="ldb.3"> - -<refmeta> - <refentrytitle>ldb</refentrytitle> - <manvolnum>3</manvolnum> -</refmeta> - -<refnamediv> - <refname>ldb</refname> - <refclass>The Samba Project</refclass> - <refpurpose>A light-weight database library</refpurpose> -</refnamediv> - -<refsynopsisdiv> - <synopsis>#include <ldb.h></synopsis> -</refsynopsisdiv> - -<refsect1> - <title>description</title> - - <para> -ldb is a light weight embedded database library and API. With a -programming interface that is very similar to LDAP, ldb can store its -data either in a tdb(3) database or in a real LDAP database. - </para> - - <para> -When used with the tdb backend ldb does not require any database -daemon. Instead, ldb function calls are processed immediately by the -ldb library, which does IO directly on the database, while allowing -multiple readers/writers using operating system byte range locks. This -leads to an API with very low overheads, often resulting in speeds of -more than 10x what can be achieved with a more traditional LDAP -architecture. - </para> - - <para> -In a taxonomy of databases ldb would sit half way between key/value -pair databases (such as berkley db or tdb) and a full LDAP -database. With a structured attribute oriented API like LDAP and good -indexing capabilities, ldb can be used for quite sophisticated -applications that need a light weight database, without the -administrative overhead of a full LDAP installation. - </para> - - <para> -Included with ldb are a number of useful command line tools for -manipulating a ldb database. These tools are similar in style to the -equivalent ldap command line tools. - </para> - - <para> -In its default mode of operation with a tdb backend, ldb can also be -seen as a "schema-less LDAP". By default ldb does not require a -schema, which greatly reduces the complexity of getting started with -ldb databases. As the complexity of you application grows you can take -advantage of some of the optional schema-like attributes that ldb -offers, or you can migrate to using the full LDAP api while keeping -your exiting ldb code. - </para> - - <para> -If you are new to ldb, then I suggest starting with the manual pages -for ldbsearch(1) and ldbedit(1), and experimenting with a local -database. Then I suggest you look at the ldb_connect(3) and -ldb_search(3) manual pages. - </para> -</refsect1> - -<refsect1> - <title>TOOLS</title> - - <itemizedlist> - <listitem><para> - <application>ldbsearch(1)</application> - - command line ldb search utility - </para></listitem> - - <listitem><para> - <application>ldbedit(1)</application> - - edit all or part of a ldb database using your favourite editor - </para></listitem> - - <listitem><para> - <application>ldbadd(1)</application> - - add records to a ldb database using LDIF formatted input - </para></listitem> - - <listitem><para> - <application>ldbdel(1)</application> - - delete records from a ldb database - </para></listitem> - - <listitem><para> - <application>ldbmodify(1)</application> - - modify records in a ldb database using LDIF formatted input - </para></listitem> - </itemizedlist> -</refsect1> - -<refsect1> - <title>FUNCTIONS</title> - - <itemizedlist> - <listitem><para> - <function>ldb_connect(3)</function> - - connect to a ldb backend - </para></listitem> - - <listitem><para> - <function>ldb_search(3)</function> - - perform a database search - </para></listitem> - - <listitem><para> - <function>ldb_add(3)</function> - - add a record to the database - </para></listitem> - - <listitem><para> - <function>ldb_delete(3)</function> - - delete a record from the database - </para></listitem> - - <listitem><para> - <function>ldb_modify(3)</function> - - modify a record in the database - </para></listitem> - - <listitem><para> - <function>ldb_errstring(3)</function> - - retrieve extended error information from the last operation - </para></listitem> - - <listitem><para> - <function>ldb_ldif_write(3)</function> - - write a LDIF formatted message - </para></listitem> - - <listitem><para> - <function>ldb_ldif_write_file(3)</function> - - write a LDIF formatted message to a file - </para></listitem> - - <listitem><para> - <function>ldb_ldif_read(3)</function> - - read a LDIF formatted message - </para></listitem> - - <listitem><para> - <function>ldb_ldif_read_free(3)</function> - - free the result of a ldb_ldif_read() - </para></listitem> - - <listitem><para> - <function>ldb_ldif_read_file(3)</function> - - read a LDIF message from a file - </para></listitem> - - <listitem><para> - <function>ldb_ldif_read_string(3)</function> - - read a LDIF message from a string - </para></listitem> - - <listitem><para> - <function>ldb_msg_find_element(3)</function> - - find an element in a ldb_message - </para></listitem> - - <listitem><para> - <function>ldb_val_equal_exact(3)</function> - - compare two ldb_val structures - </para></listitem> - - <listitem><para> - <function>ldb_msg_find_val(3)</function> - - find an element by value - </para></listitem> - - <listitem><para> - <function>ldb_msg_add_empty(3)</function> - - add an empty message element to a ldb_message - </para></listitem> - - - <listitem><para> - <function>ldb_msg_add(3)</function> - - add a non-empty message element to a ldb_message - </para></listitem> - - - <listitem><para> - <function>ldb_msg_element_compare(3)</function> - - compare two ldb_message_element structures - </para></listitem> - - - <listitem><para> - <function>ldb_msg_find_int(3)</function> - - return an integer value from a ldb_message - </para></listitem> - - - <listitem><para> - <function>ldb_msg_find_uint(3)</function> - - return an unsigned integer value from a ldb_message - </para></listitem> - - - <listitem><para> - <function>ldb_msg_find_double(3)</function> - - return a double value from a ldb_message - </para></listitem> - - - <listitem><para> - <function>ldb_msg_find_string(3)</function> - - return a string value from a ldb_message - </para></listitem> - - - <listitem><para> - <function>ldb_set_alloc(3)</function> - - set the memory allocation function to be used by ldb - </para></listitem> - - - <listitem><para> - <function>ldb_set_debug(3)</function> - - set a debug handler to be used by ldb - </para></listitem> - - - <listitem><para> - <function>ldb_set_debug_stderr(3)</function> - - set a debug handler for stderr output - </para></listitem> - </itemizedlist> -</refsect1> - -<refsect1> - <title>Author</title> - - <para> - ldb was written by - <ulink url="http://samba.org/~tridge/">Andrew Tridgell</ulink>. - </para> - - <para> -If you wish to report a problem or make a suggestion then please see -the <ulink url="http://ldb.samba.org/"/> web site for -current contact and maintainer information. - </para> - - <para> -ldb is released under the GNU Lesser General Public License version 2 -or later. Please see the file COPYING for license details. - </para> -</refsect1> -</refentry> diff --git a/source/lib/ldb/man/ldbadd.1.xml b/source/lib/ldb/man/ldbadd.1.xml deleted file mode 100644 index 7ad0f835d0f..00000000000 --- a/source/lib/ldb/man/ldbadd.1.xml +++ /dev/null @@ -1,105 +0,0 @@ -<?xml version="1.0" encoding="iso-8859-1"?> -<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> -<refentry id="ldbadd.1"> - -<refmeta> - <refentrytitle>ldbadd</refentrytitle> - <manvolnum>1</manvolnum> -</refmeta> - - -<refnamediv> - <refname>ldbadd</refname> - <refpurpose>Command-line utility for adding records to an LDB</refpurpose> -</refnamediv> - -<refsynopsisdiv> - <cmdsynopsis> - <command>ldbadd</command> - <arg choice="opt">-h</arg> - <arg choice="opt">-H LDB-URL</arg> - <arg choice="opt">ldif-file1</arg> - <arg choice="opt">ldif-file2</arg> - <arg choice="opt">...</arg> - </cmdsynopsis> -</refsynopsisdiv> - -<refsect1> - <title>DESCRIPTION</title> - - <para>ldbadd adds records to an ldb(7) database. It reads - the ldif(5) files specified on the command line and adds - the records from these files to the LDB database, which is specified - by the -H option or the LDB_URL environment variable. - </para> - - <para>If - is specified as a ldb file, the ldif input is read from - standard input.</para> - -</refsect1> - - -<refsect1> - <title>OPTIONS</title> - - <variablelist> - <varlistentry> - <term>-h</term> - <listitem><para> - Show list of available options.</para></listitem> - </varlistentry> - - <varlistentry> - <term>-H <ldb-url></term> - <listitem><para> - LDB URL to connect to. See ldb(7) for details. - </para></listitem> - </varlistentry> - - </variablelist> - -</refsect1> - -<refsect1> - <title>ENVIRONMENT</title> - - <variablelist> - <varlistentry><term>LDB_URL</term> - <listitem><para>LDB URL to connect to (can be overrided by using the - -H command-line option.)</para></listitem> - </varlistentry> - </variablelist> - -</refsect1> - -<refsect1> - <title>VERSION</title> - - <para>This man page is correct for version 4.0 of the Samba suite.</para> -</refsect1> - -<refsect1> - <title>SEE ALSO</title> - - <para>ldb(7), ldbmodify, ldbdel, ldif(5)</para> - -</refsect1> - -<refsect1> - <title>AUTHOR</title> - - <para> ldb was written by - <ulink url="http://samba.org/~tridge/">Andrew Tridgell</ulink>. - </para> - - <para> -If you wish to report a problem or make a suggestion then please see -the <ulink url="http://ldb.samba.org/"/> web site for -current contact and maintainer information. - </para> - - <para>This manpage was written by Jelmer Vernooij.</para> - -</refsect1> - -</refentry> diff --git a/source/lib/ldb/man/ldbdel.1.xml b/source/lib/ldb/man/ldbdel.1.xml deleted file mode 100644 index 7dfc7366f6b..00000000000 --- a/source/lib/ldb/man/ldbdel.1.xml +++ /dev/null @@ -1,105 +0,0 @@ -<?xml version="1.0" encoding="iso-8859-1"?> -<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> -<refentry id="ldbdel.1"> - -<refmeta> - <refentrytitle>ldbdel</refentrytitle> - <manvolnum>1</manvolnum> -</refmeta> - - -<refnamediv> - <refname>ldbdel</refname> - <refpurpose>Command-line program for deleting LDB records</refpurpose> -</refnamediv> - -<refsynopsisdiv> - <cmdsynopsis> - <command>ldbdel</command> - <arg choice="opt">-h</arg> - <arg choice="opt">-H LDB-URL</arg> - <arg choice="opt">dn</arg> - <arg choice="opt">...</arg> - </cmdsynopsis> -</refsynopsisdiv> - -<refsect1> - <title>DESCRIPTION</title> - - <para>ldbdel deletes records from an ldb(7) database. - It deletes the records identified by the dn's specified - on the command-line. </para> - - <para>ldbdel uses either the database that is specified with - the -H option or the database specified by the LDB_URL environment - variable.</para> - -</refsect1> - - -<refsect1> - <title>OPTIONS</title> - - <variablelist> - <varlistentry> - <term>-h</term> - <listitem><para> - Show list of available options.</para></listitem> - </varlistentry> - - <varlistentry> - <term>-H <ldb-url></term> - <listitem><para> - LDB URL to connect to. See ldb(7) for details. - </para></listitem> - </varlistentry> - - </variablelist> - -</refsect1> - -<refsect1> - <title>ENVIRONMENT</title> - - <variablelist> - <varlistentry><term>LDB_URL</term> - <listitem><para>LDB URL to connect to (can be overrided by using the - -H command-line option.)</para></listitem> - </varlistentry> - </variablelist> - -</refsect1> - -<refsect1> - <title>VERSION</title> - - <para>This man page is correct for version 4.0 of the Samba suite.</para> -</refsect1> - -<refsect1> - <title>SEE ALSO</title> - - <para>ldb(7), ldbmodify, ldbadd, ldif(5)</para> - -</refsect1> - -<refsect1> - <title>AUTHOR</title> - - <para> ldb was written by - <ulink url="http://samba.org/~tridge/">Andrew Tridgell</ulink>. - </para> - - <para> -If you wish to report a problem or make a suggestion then please see -the <ulink url="http://ldb.samba.org/"/> web site for -current contact and maintainer information. - </para> - - <para>ldbdel was written by Andrew Tridgell.</para> - - <para>This manpage was written by Jelmer Vernooij.</para> - -</refsect1> - -</refentry> diff --git a/source/lib/ldb/man/ldbedit.1.xml b/source/lib/ldb/man/ldbedit.1.xml deleted file mode 100644 index 15c69b1b255..00000000000 --- a/source/lib/ldb/man/ldbedit.1.xml +++ /dev/null @@ -1,200 +0,0 @@ -<?xml version="1.0" encoding="iso-8859-1"?> -<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> -<refentry id="ldbedit.1"> - - <refmeta> - <refentrytitle>ldbedit</refentrytitle> - <manvolnum>1</manvolnum> - </refmeta> - - - <refnamediv> - <refname>ldbedit</refname> - <refpurpose>Edit LDB databases using your preferred editor</refpurpose> - </refnamediv> - - <refsynopsisdiv> - <cmdsynopsis> - <command>ldbedit</command> - <arg choice="opt">-?</arg> - <arg choice="opt">--usage</arg> - <arg choice="opt">-s base|one|sub</arg> - <arg choice="opt">-b basedn</arg> - <arg choice="opt">-a</arg> - <arg choice="opt">-e editor</arg> - <arg choice="opt">-H LDB-URL</arg> - <arg choice="opt">expression</arg> - <arg rep="repeat" choice="opt">attributes</arg> - </cmdsynopsis> -</refsynopsisdiv> - -<refsect1> - <title>DESCRIPTION</title> - - <para>ldbedit is a utility that allows you to edit LDB entries (in - tdb files, sqlite files or LDAP servers) using your preferred editor. - ldbedit generates an LDIF file based on your query, allows you to edit - the LDIF, and then merges that LDIF back into the LDB backend. - </para> - -</refsect1> - - - <refsect1> - <title>OPTIONS</title> - - <variablelist> - <varlistentry> - <term>-?</term> - <term>--help</term> - <listitem> - <para> - Show list of available options, and a phrase describing what that option - does. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>--usage</term> - <listitem> - <para> - Show list of available options. This is similar to the help option, - however it does not provide any description, and is hence shorter. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>-H <ldb-url></term> - <listitem> - <para> - LDB URL to connect to. For a tdb database, - this will be of the form - tdb://<replaceable>filename</replaceable>. - For a LDAP connection over unix domain - sockets, this will be of the form - ldapi://<replaceable>socket</replaceable>. For - a (potentially remote) LDAP connection over - TCP, this will be of the form - ldap://<replaceable>hostname</replaceable>. For - an SQLite database, this will be of the form - sqlite://<replaceable>filename</replaceable>. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>-s one|sub|base</term> - <listitem><para>Search scope to use. One-level, subtree or base.</para></listitem> - </varlistentry> - - <varlistentry> - <term>-a</term> - <term>-all</term> - <listitem> - <para>Edit all records. This allows you to - apply the same change to a number of records - at once. You probably want to combine this - with an expression of the form - "objectclass=*". - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>-e editor</term> - <term>--editor editor</term> - <listitem> - <para>Specify the editor that should be used (overrides - the VISUAL and EDITOR environment - variables). If this option is not used, and - neither VISUAL nor EDITOR environment variables - are set, then the vi editor will be used. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>-b basedn</term> - <listitem><para>Specify Base Distinguished Name to use.</para></listitem> - </varlistentry> - - <varlistentry> - <term>-v</term> - <term>--verbose</term> - <listitem> - <para>Make ldbedit more verbose about the - operations that are being performed. Without - this option, ldbedit will only provide a - summary change line. - </para> - </listitem> - </varlistentry> - - </variablelist> - - </refsect1> - - <refsect1> - <title>ENVIRONMENT</title> - - <variablelist> - <varlistentry> - <term>LDB_URL</term> - <listitem> - <para>LDB URL to connect to. This can be - overridden by using the -H command-line option.) - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>VISUAL and EDITOR</term> - <listitem> - <para> - Environment variables used to determine what - editor to use. VISUAL takes precedence over - EDITOR, and both are overridden by the - -e command-line option. - </para> - </listitem> - </varlistentry> - </variablelist> - - </refsect1> - - <refsect1> - <title>VERSION</title> - - <para>This man page is correct for version 4.0 of the Samba suite.</para> - </refsect1> - - <refsect1> - <title>SEE ALSO</title> - - <para>ldb(7), ldbmodify(1), ldbdel(1), ldif(5), vi(1)</para> - - </refsect1> - - <refsect1> - <title>AUTHOR</title> - - <para> - ldb was written by - <ulink url="http://samba.org/~tridge/">Andrew Tridgell</ulink>. - </para> - - <para> - If you wish to report a problem or make a suggestion then please see - the <ulink url="http://ldb.samba.org/"/> web site for - current contact and maintainer information. - </para> - - <para> - This manpage was written by Jelmer Vernooij and updated - by Brad Hards. - </para> - - </refsect1> - -</refentry> diff --git a/source/lib/ldb/man/ldbmodify.1.xml b/source/lib/ldb/man/ldbmodify.1.xml deleted file mode 100644 index bc196477857..00000000000 --- a/source/lib/ldb/man/ldbmodify.1.xml +++ /dev/null @@ -1,93 +0,0 @@ -<?xml version="1.0" encoding="iso-8859-1"?> -<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> -<refentry id="ldbmodify.1"> - -<refmeta> - <refentrytitle>ldbmodify</refentrytitle> - <manvolnum>1</manvolnum> -</refmeta> - - -<refnamediv> - <refname>ldbmodify</refname> - <refpurpose>Modify records in a LDB database</refpurpose> -</refnamediv> - -<refsynopsisdiv> - <cmdsynopsis> - <command>ldbmodify</command> - <arg choice="opt">-H LDB-URL</arg> - <arg choice="opt">ldif-file</arg> - </cmdsynopsis> -</refsynopsisdiv> - -<refsect1> - <title>DESCRIPTION</title> - - <para> - ldbmodify changes, adds and deletes records in a LDB database. - The changes that should be made to the LDB database are read from - the specified LDIF-file. If - is specified as the filename, input is read from stdin. - </para> - - <para>For now, see ldapmodify(1) for details on the LDIF file format.</para> - -</refsect1> - - -<refsect1> - <title>OPTIONS</title> - - <variablelist> - <varlistentry> - <term>-H <ldb-url></term> - <listitem><para> - LDB URL to connect to. See ldb(7) for details. - </para></listitem> - </varlistentry> - </variablelist> -</refsect1> - -<refsect1> - <title>ENVIRONMENT</title> - - <variablelist> - <varlistentry><term>LDB_URL</term> - <listitem><para>LDB URL to connect to (can be overrided by using the - -H command-line option.)</para></listitem> - </varlistentry> - </variablelist> - -</refsect1> - -<refsect1> - <title>VERSION</title> - - <para>This man page is correct for version 4.0 of the Samba suite.</para> -</refsect1> - -<refsect1> - <title>SEE ALSO</title> - - <para>ldb(7), ldbedit</para> - -</refsect1> - -<refsect1> - <title>AUTHOR</title> - - <para> ldb was written by - <ulink url="http://samba.org/~tridge/">Andrew Tridgell</ulink>. - </para> - - <para> -If you wish to report a problem or make a suggestion then please see -the <ulink url="http://ldb.samba.org/"/> web site for -current contact and maintainer information. - </para> - - <para>This manpage was written by Jelmer Vernooij.</para> - -</refsect1> - -</refentry> diff --git a/source/lib/ldb/man/ldbrename.1.xml b/source/lib/ldb/man/ldbrename.1.xml deleted file mode 100644 index 391ec84ccc3..00000000000 --- a/source/lib/ldb/man/ldbrename.1.xml +++ /dev/null @@ -1,107 +0,0 @@ -<?xml version="1.0" encoding="iso-8859-1"?> -<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> -<refentry id="ldbrename.1"> - -<refmeta> - <refentrytitle>ldbrename</refentrytitle> - <manvolnum>1</manvolnum> -</refmeta> - - -<refnamediv> - <refname>ldbrename</refname> - <refpurpose>Edit LDB databases using your favorite editor</refpurpose> -</refnamediv> - -<refsynopsisdiv> - <cmdsynopsis> - <command>ldbrename</command> - <arg choice="opt">-h</arg> - <arg choice="opt">-o options</arg> - <arg choice="req">olddn</arg> - <arg choice="req">newdb</arg> - </cmdsynopsis> -</refsynopsisdiv> - -<refsect1> - <title>DESCRIPTION</title> - - <para>ldbrename is a utility that allows you to rename trees in - an LDB database based by DN. This utility takes - two arguments: the original - DN name of the top element and the DN to change it to. - </para> - -</refsect1> - - -<refsect1> - <title>OPTIONS</title> - - <variablelist> - <varlistentry> - <term>-h</term> - <listitem><para> - Show list of available options.</para></listitem> - </varlistentry> - - <varlistentry> - <term>-H <ldb-url></term> - <listitem><para> - LDB URL to connect to. See ldb(7) for details. - </para></listitem> - </varlistentry> - - <varlistentry> - <term>-o options</term> - <listitem><para>Extra ldb options, such as - modules.</para></listitem> - </varlistentry> - - </variablelist> - -</refsect1> - -<refsect1> - <title>ENVIRONMENT</title> - - <variablelist> - <varlistentry><term>LDB_URL</term> - <listitem><para>LDB URL to connect to (can be overrided by using the - -H command-line option.)</para></listitem> - </varlistentry> - </variablelist> - -</refsect1> - -<refsect1> - <title>VERSION</title> - - <para>This man page is correct for version 4.0 of the Samba suite.</para> -</refsect1> - -<refsect1> - <title>SEE ALSO</title> - - <para>ldb(7), ldbmodify, ldbdel, ldif(5)</para> - -</refsect1> - -<refsect1> - <title>AUTHOR</title> - - <para> ldb was written by - <ulink url="http://samba.org/~tridge/">Andrew Tridgell</ulink>. - </para> - - <para> -If you wish to report a problem or make a suggestion then please see -the <ulink url="http://ldb.samba.org/"/> web site for -current contact and maintainer information. - </para> - - <para>This manpage was written by Jelmer Vernooij.</para> - -</refsect1> - -</refentry> diff --git a/source/lib/ldb/man/ldbsearch.1.xml b/source/lib/ldb/man/ldbsearch.1.xml deleted file mode 100644 index ed3749b9207..00000000000 --- a/source/lib/ldb/man/ldbsearch.1.xml +++ /dev/null @@ -1,119 +0,0 @@ -<?xml version="1.0" encoding="iso-8859-1"?> -<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> -<refentry id="ldbsearch.1"> - -<refmeta> - <refentrytitle>ldbsearch</refentrytitle> - <manvolnum>1</manvolnum> -</refmeta> - - -<refnamediv> - <refname>ldbsearch</refname> - <refpurpose>Search for records in a LDB database</refpurpose> -</refnamediv> - -<refsynopsisdiv> - <cmdsynopsis> - <command>ldbsearch</command> - <arg choice="opt">-h</arg> - <arg choice="opt">-s base|one|sub</arg> - <arg choice="opt">-b basedn</arg> - <arg chioce="opt">-i</arg> - <arg choice="opt">-H LDB-URL</arg> - <arg choice="opt">expression</arg> - <arg choice="opt">attributes</arg> - </cmdsynopsis> -</refsynopsisdiv> - -<refsect1> - <title>DESCRIPTION</title> - - <para>ldbsearch searches a LDB database for records matching the - specified expression (see the ldapsearch(1) manpage for - a description of the expression format). For each - record, the specified attributes are printed. - </para> - -</refsect1> - - -<refsect1> - <title>OPTIONS</title> - - <variablelist> - <varlistentry> - <term>-h</term> - <listitem><para> - Show list of available options.</para></listitem> - </varlistentry> - - <varlistentry> - <term>-H <ldb-url></term> - <listitem><para> - LDB URL to connect to. See ldb(7) for details. - </para></listitem> - </varlistentry> - - <varlistentry> - <term>-s one|sub|base</term> - <listitem><para>Search scope to use. One-level, subtree or base.</para></listitem> - </varlistentry> - - <varlistentry> - <term>-i</term> - <listitem><para>Read search expressions from stdin. </para></listitem> - </varlistentry> - - <varlistentry> - <term>-b basedn</term> - <listitem><para>Specify Base DN to use.</para></listitem> - </varlistentry> - - </variablelist> - -</refsect1> - -<refsect1> - <title>ENVIRONMENT</title> - - <variablelist> - <varlistentry><term>LDB_URL</term> - <listitem><para>LDB URL to connect to (can be overrided by using the - -H command-line option.)</para></listitem> - </varlistentry> - </variablelist> - -</refsect1> - -<refsect1> - <title>VERSION</title> - - <para>This man page is correct for version 4.0 of the Samba suite.</para> -</refsect1> - -<refsect1> - <title>SEE ALSO</title> - - <para>ldb(7), ldbedit(1)</para> - -</refsect1> - -<refsect1> - <title>AUTHOR</title> - - <para> ldb was written by - <ulink url="http://samba.org/~tridge/">Andrew Tridgell</ulink>. - </para> - - <para> -If you wish to report a problem or make a suggestion then please see -the <ulink url="http://ldb.samba.org/"/> web site for -current contact and maintainer information. - </para> - - <para>This manpage was written by Jelmer Vernooij.</para> - -</refsect1> - -</refentry> diff --git a/source/lib/ldb/man/oLschema2ldif.1.xml b/source/lib/ldb/man/oLschema2ldif.1.xml deleted file mode 100644 index b1e681be4e4..00000000000 --- a/source/lib/ldb/man/oLschema2ldif.1.xml +++ /dev/null @@ -1,79 +0,0 @@ -<?xml version="1.0" encoding="iso-8859-1"?> -<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> -<refentry id="oLschema2ldif.1"> - -<refmeta> - <refentrytitle>oLschema2ldif</refentrytitle> - <manvolnum>1</manvolnum> -</refmeta> - - -<refnamediv> - <refname>oLschema2ldif</refname> - <refpurpose>Converts LDAP schema's to LDB-compatible LDIF</refpurpose> -</refnamediv> - -<refsynopsisdiv> - <cmdsynopsis> - <command>oLschema2ldif</command> - <arg choice="opt">-I INPUT-FILE</arg> - <arg choice="opt">-O OUTPUT-FILE</arg> - </cmdsynopsis> -</refsynopsisdiv> - -<refsect1> - <title>DESCRIPTION</title> - - <para>oLschema2ldif is a simple tool that converts standard OpenLDAP schema files to a LDIF format that is understood by LDB.</para> -</refsect1> - - -<refsect1> - <title>OPTIONS</title> - - <variablelist> - <varlistentry> - <term>-I input-file</term> - <listitem><para>OpenLDAP schema to read. If none are specified, -the schema file will be read from standard input. - </para></listitem> - </varlistentry> - - <varlistentry> - <term>-O output-file</term> - <listitem><para>File to write ldif version of schema to. - </para></listitem> - </varlistentry> - </variablelist> -</refsect1> - -<refsect1> - <title>VERSION</title> - - <para>This man page is correct for version 4.0 of the Samba suite.</para> -</refsect1> - -<refsect1> - <title>SEE ALSO</title> - - <para>ldb(7), ldbmodify, ldbdel, ldif(5)</para> - -</refsect1> - -<refsect1> - <title>AUTHOR</title> - - <para> ldb was written by - <ulink url="http://samba.org/~tridge/">Andrew Tridgell</ulink>. - oLschema2ldif was written by <ulink url="mailto:idra@samba.org">Simo Sorce</ulink>. - </para> - - <para> -If you wish to report a problem or make a suggestion then please see -the <ulink url="http://ldb.samba.org/"/> web site for -current contact and maintainer information. - </para> - -</refsect1> - -</refentry> diff --git a/source/lib/ldb/modules/asq.c b/source/lib/ldb/modules/asq.c deleted file mode 100644 index 7d232023033..00000000000 --- a/source/lib/ldb/modules/asq.c +++ /dev/null @@ -1,489 +0,0 @@ -/* - ldb database library - - Copyright (C) Simo Sorce 2005 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - * Name: ldb - * - * Component: ldb attribute scoped query control module - * - * Description: this module searches all the the objects pointed - * by the DNs contained in the references attribute - * - * Author: Simo Sorce - */ - -#include "includes.h" -#include "ldb/include/includes.h" - -struct asq_context { - - enum {ASQ_SEARCH_BASE, ASQ_SEARCH_MULTI} step; - - struct ldb_module *module; - void *up_context; - int (*up_callback)(struct ldb_context *, void *, struct ldb_reply *); - - const char * const *req_attrs; - char *req_attribute; - enum { - ASQ_CTRL_SUCCESS = 0, - ASQ_CTRL_INVALID_ATTRIBUTE_SYNTAX = 21, - ASQ_CTRL_UNWILLING_TO_PERFORM = 53, - ASQ_CTRL_AFFECTS_MULTIPLE_DSA = 71 - } asq_ret; - - struct ldb_request *base_req; - struct ldb_reply *base_res; - - struct ldb_request **reqs; - int num_reqs; - int cur_req; - - struct ldb_control **controls; -}; - -static struct ldb_handle *init_handle(void *mem_ctx, struct ldb_module *module, - void *context, - int (*callback)(struct ldb_context *, void *, struct ldb_reply *)) -{ - struct asq_context *ac; - struct ldb_handle *h; - - h = talloc_zero(mem_ctx, struct ldb_handle); - if (h == NULL) { - ldb_set_errstring(module->ldb, "Out of Memory"); - return NULL; - } - - h->module = module; - - ac = talloc_zero(h, struct asq_context); - if (ac == NULL) { - ldb_set_errstring(module->ldb, "Out of Memory"); - talloc_free(h); - return NULL; - } - - h->private_data = (void *)ac; - - h->state = LDB_ASYNC_INIT; - h->status = LDB_SUCCESS; - - ac->module = module; - ac->up_context = context; - ac->up_callback = callback; - - return h; -} - -static int asq_terminate(struct ldb_handle *handle) -{ - struct asq_context *ac; - struct ldb_reply *ares; - struct ldb_asq_control *asq; - int i; - - ac = talloc_get_type(handle->private_data, struct asq_context); - if (ac == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - handle->status = LDB_SUCCESS; - handle->state = LDB_ASYNC_DONE; - - ares = talloc_zero(ac, struct ldb_reply); - if (ares == NULL) - return LDB_ERR_OPERATIONS_ERROR; - - ares->type = LDB_REPLY_DONE; - - if (ac->controls) { - for (i = 0; ac->controls[i]; i++); - ares->controls = talloc_move(ares, &ac->controls); - } else { - i = 0; - } - - ares->controls = talloc_realloc(ares, ares->controls, struct ldb_control *, i + 2); - - if (ares->controls == NULL) - return LDB_ERR_OPERATIONS_ERROR; - - ares->controls[i] = talloc(ares->controls, struct ldb_control); - if (ares->controls[i] == NULL) - return LDB_ERR_OPERATIONS_ERROR; - - ares->controls[i]->oid = LDB_CONTROL_ASQ_OID; - ares->controls[i]->critical = 0; - - asq = talloc_zero(ares->controls[i], struct ldb_asq_control); - if (asq == NULL) - return LDB_ERR_OPERATIONS_ERROR; - - asq->result = ac->asq_ret; - - ares->controls[i]->data = asq; - - ares->controls[i + 1] = NULL; - - ac->up_callback(ac->module->ldb, ac->up_context, ares); - - return LDB_SUCCESS; -} - -static int asq_base_callback(struct ldb_context *ldb, void *context, struct ldb_reply *ares) -{ - struct asq_context *ac; - - if (!context || !ares) { - ldb_set_errstring(ldb, "NULL Context or Result in callback"); - goto error; - } - - if (!(ac = talloc_get_type(context, struct asq_context))) { - goto error; - } - - /* we are interested only in the single reply (base search) we receive here */ - if (ares->type == LDB_REPLY_ENTRY) { - ac->base_res = talloc_move(ac, &ares); - } else { - talloc_free(ares); - } - - return LDB_SUCCESS; -error: - talloc_free(ares); - return LDB_ERR_OPERATIONS_ERROR; -} - -static int asq_reqs_callback(struct ldb_context *ldb, void *context, struct ldb_reply *ares) -{ - struct asq_context *ac; - - if (!context || !ares) { - ldb_set_errstring(ldb, "NULL Context or Result in callback"); - goto error; - } - - if (!(ac = talloc_get_type(context, struct asq_context))) { - goto error; - } - - /* we are interested only in the single reply (base search) we receive here */ - if (ares->type == LDB_REPLY_ENTRY) { - - /* pass the message up to the original callback as we - * do not have to elaborate on it any further */ - return ac->up_callback(ac->module->ldb, ac->up_context, ares); - - } else { /* ignore any REFERRAL or DONE reply */ - talloc_free(ares); - } - - return LDB_SUCCESS; -error: - talloc_free(ares); - return LDB_ERR_OPERATIONS_ERROR; -} - -static int asq_search(struct ldb_module *module, struct ldb_request *req) -{ - struct ldb_control *control; - struct ldb_asq_control *asq_ctrl; - struct asq_context *ac; - struct ldb_handle *h; - char **base_attrs; - int ret; - - /* check if there's a paged request control */ - control = get_control_from_list(req->controls, LDB_CONTROL_ASQ_OID); - if (control == NULL) { - /* not found go on */ - return ldb_next_request(module, req); - } - - req->handle = NULL; - - if (!req->callback || !req->context) { - ldb_set_errstring(module->ldb, - "Async interface called with NULL callback function or NULL context"); - return LDB_ERR_OPERATIONS_ERROR; - } - - asq_ctrl = talloc_get_type(control->data, struct ldb_asq_control); - if (!asq_ctrl) { - return LDB_ERR_PROTOCOL_ERROR; - } - - h = init_handle(req, module, req->context, req->callback); - if (!h) { - return LDB_ERR_OPERATIONS_ERROR; - } - if (!(ac = talloc_get_type(h->private_data, struct asq_context))) { - - return LDB_ERR_OPERATIONS_ERROR; - } - - req->handle = h; - - /* check the search is well formed */ - if (req->op.search.scope != LDB_SCOPE_BASE) { - ac->asq_ret = ASQ_CTRL_UNWILLING_TO_PERFORM; - return asq_terminate(h); - } - - ac->req_attrs = req->op.search.attrs; - ac->req_attribute = talloc_strdup(ac, asq_ctrl->source_attribute); - if (ac->req_attribute == NULL) - return LDB_ERR_OPERATIONS_ERROR; - - /* get the object to retrieve the DNs to search */ - ac->base_req = talloc_zero(req, struct ldb_request); - if (ac->base_req == NULL) - return LDB_ERR_OPERATIONS_ERROR; - ac->base_req->operation = req->operation; - ac->base_req->op.search.base = req->op.search.base; - ac->base_req->op.search.scope = LDB_SCOPE_BASE; - ac->base_req->op.search.tree = req->op.search.tree; - base_attrs = talloc_array(ac->base_req, char *, 2); - if (base_attrs == NULL) - return LDB_ERR_OPERATIONS_ERROR; - base_attrs[0] = talloc_strdup(base_attrs, asq_ctrl->source_attribute); - if (base_attrs[0] == NULL) - return LDB_ERR_OPERATIONS_ERROR; - base_attrs[1] = NULL; - ac->base_req->op.search.attrs = (const char * const *)base_attrs; - - ac->base_req->context = ac; - ac->base_req->callback = asq_base_callback; - ldb_set_timeout_from_prev_req(module->ldb, req, ac->base_req); - - ac->step = ASQ_SEARCH_BASE; - - ret = ldb_request(module->ldb, ac->base_req); - - if (ret != LDB_SUCCESS) { - return ret; - } - - return LDB_SUCCESS; -} - -static int asq_requests(struct ldb_handle *handle) { - struct asq_context *ac; - struct ldb_message_element *el; - int i; - - if (!(ac = talloc_get_type(handle->private_data, - struct asq_context))) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* look up the DNs */ - if (ac->base_res == NULL) { - return LDB_ERR_NO_SUCH_OBJECT; - } - el = ldb_msg_find_element(ac->base_res->message, ac->req_attribute); - /* no values found */ - if (el == NULL) { - ac->asq_ret = ASQ_CTRL_SUCCESS; - return asq_terminate(handle); - } - - /* build up the requests call chain */ - ac->num_reqs = el->num_values; - ac->cur_req = 0; - ac->reqs = talloc_array(ac, struct ldb_request *, ac->num_reqs); - if (ac->reqs == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - for (i = 0; i < el->num_values; i++) { - - ac->reqs[i] = talloc_zero(ac->reqs, struct ldb_request); - if (ac->reqs[i] == NULL) - return LDB_ERR_OPERATIONS_ERROR; - ac->reqs[i]->operation = LDB_SEARCH; - ac->reqs[i]->op.search.base = ldb_dn_explode(ac->reqs[i], (const char *)el->values[i].data); - if (ac->reqs[i]->op.search.base == NULL) { - ac->asq_ret = ASQ_CTRL_INVALID_ATTRIBUTE_SYNTAX; - return asq_terminate(handle); - } - ac->reqs[i]->op.search.scope = LDB_SCOPE_BASE; - ac->reqs[i]->op.search.tree = ac->base_req->op.search.tree; - ac->reqs[i]->op.search.attrs = ac->req_attrs; - - ac->reqs[i]->context = ac; - ac->reqs[i]->callback = asq_reqs_callback; - ldb_set_timeout_from_prev_req(ac->module->ldb, ac->base_req, ac->reqs[i]); - } - - ac->step = ASQ_SEARCH_MULTI; - - return LDB_SUCCESS; -} - -static int asq_wait_none(struct ldb_handle *handle) -{ - struct asq_context *ac; - int ret; - - if (!handle || !handle->private_data) { - return LDB_ERR_OPERATIONS_ERROR; - } - - if (handle->state == LDB_ASYNC_DONE) { - return handle->status; - } - - handle->state = LDB_ASYNC_PENDING; - handle->status = LDB_SUCCESS; - - if (!(ac = talloc_get_type(handle->private_data, - struct asq_context))) { - return LDB_ERR_OPERATIONS_ERROR; - } - - switch (ac->step) { - case ASQ_SEARCH_BASE: - ret = ldb_wait(ac->base_req->handle, LDB_WAIT_NONE); - - if (ret != LDB_SUCCESS) { - handle->status = ret; - goto done; - } - - if (ac->base_req->handle->status != LDB_SUCCESS) { - handle->status = ac->base_req->handle->status; - goto done; - } - if (ac->base_req->handle->state != LDB_ASYNC_DONE) { - return LDB_SUCCESS; - } - - ret = asq_requests(handle); - - /* no break nor return, - * the set of requests is performed in ASQ_SEARCH_MULTI - */ - - case ASQ_SEARCH_MULTI: - - if (ac->reqs[ac->cur_req]->handle == NULL) { - ret = ldb_request(ac->module->ldb, ac->reqs[ac->cur_req]); - if (ret != LDB_SUCCESS) { - return ret; - } - } - - ret = ldb_wait(ac->reqs[ac->cur_req]->handle, LDB_WAIT_NONE); - - if (ret != LDB_SUCCESS) { - handle->status = ret; - goto done; - } - if (ac->reqs[ac->cur_req]->handle->status != LDB_SUCCESS) { - handle->status = ac->reqs[ac->cur_req]->handle->status; - } - - if (ac->reqs[ac->cur_req]->handle->state == LDB_ASYNC_DONE) { - ac->cur_req++; - } - - if (ac->cur_req < ac->num_reqs) { - return LDB_SUCCESS; - } - - return asq_terminate(handle); - - default: - ret = LDB_ERR_OPERATIONS_ERROR; - goto done; - } - - ret = LDB_SUCCESS; - -done: - handle->state = LDB_ASYNC_DONE; - return ret; -} - -static int asq_wait_all(struct ldb_handle *handle) -{ - int ret; - - while (handle->state != LDB_ASYNC_DONE) { - ret = asq_wait_none(handle); - if (ret != LDB_SUCCESS) { - return ret; - } - } - - return handle->status; -} - -static int asq_wait(struct ldb_handle *handle, enum ldb_wait_type type) -{ - if (type == LDB_WAIT_ALL) { - return asq_wait_all(handle); - } else { - return asq_wait_none(handle); - } -} - -static int asq_init(struct ldb_module *module) -{ - struct ldb_request *req; - int ret; - - req = talloc_zero(module, struct ldb_request); - if (req == NULL) { - ldb_debug(module->ldb, LDB_DEBUG_ERROR, "asq: Out of memory!\n"); - return LDB_ERR_OPERATIONS_ERROR; - } - - req->operation = LDB_REQ_REGISTER_CONTROL; - req->op.reg_control.oid = LDB_CONTROL_ASQ_OID; - - ret = ldb_request(module->ldb, req); - if (ret != LDB_SUCCESS) { - ldb_debug(module->ldb, LDB_DEBUG_WARNING, "asq: Unable to register control with rootdse!\n"); - } - - return ldb_next_init(module); -} - - -static const struct ldb_module_ops asq_ops = { - .name = "asq", - .search = asq_search, - .wait = asq_wait, - .init_context = asq_init -}; - -int ldb_asq_init(void) -{ - return ldb_register_module(&asq_ops); -} diff --git a/source/lib/ldb/modules/ldb_map.c b/source/lib/ldb/modules/ldb_map.c deleted file mode 100644 index bbd7b9603de..00000000000 --- a/source/lib/ldb/modules/ldb_map.c +++ /dev/null @@ -1,1338 +0,0 @@ -/* - ldb database mapping module - - Copyright (C) Jelmer Vernooij 2005 - Copyright (C) Martin Kuehl <mkhl@samba.org> 2006 - - * NOTICE: this module is NOT released under the GNU LGPL license as - * other ldb code. This module is release under the GNU GPL v2 or - * later license. - - 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 ldb_map module - * - * Description: Map portions of data into a different format on a - * remote partition. - * - * Author: Jelmer Vernooij, Martin Kuehl - */ - -#include "includes.h" -#include "ldb/include/includes.h" - -#include "ldb/modules/ldb_map.h" -#include "ldb/modules/ldb_map_private.h" - -/* Description of the provided ldb requests: - - special attribute 'isMapped' - - - search: - - if parse tree can be split - - search remote records w/ remote attrs and parse tree - - otherwise - - enumerate all remote records - - for each remote result - - map remote result to local message - - search local result - - is present - - merge local into remote result - - run callback on merged result - - otherwise - - run callback on remote result - - - add: - - split message into local and remote part - - if local message is not empty - - add isMapped to local message - - add local message - - add remote message - - - modify: - - split message into local and remote part - - if local message is not empty - - add isMapped to local message - - search for local record - - if present - - modify local record - - otherwise - - add local message - - modify remote record - - - delete: - - search for local record - - if present - - delete local record - - delete remote record - - - rename: - - search for local record - - if present - - rename local record - - modify local isMapped - - rename remote record -*/ - - - -/* Private data structures - * ======================= */ - -/* Global private data */ -/* Extract mappings from private data. */ -const struct ldb_map_context *map_get_context(struct ldb_module *module) -{ - const struct map_private *data = talloc_get_type(module->private_data, struct map_private); - return data->context; -} - -/* Create a generic request context. */ -static struct map_context *map_init_context(struct ldb_handle *h, struct ldb_request *req) -{ - struct map_context *ac; - - ac = talloc_zero(h, struct map_context); - if (ac == NULL) { - map_oom(h->module); - return NULL; - } - - ac->module = h->module; - ac->orig_req = req; - - return ac; -} - -/* Create a search request context. */ -struct map_search_context *map_init_search_context(struct map_context *ac, struct ldb_reply *ares) -{ - struct map_search_context *sc; - - sc = talloc_zero(ac, struct map_search_context); - if (sc == NULL) { - map_oom(ac->module); - return NULL; - } - - sc->ac = ac; - sc->local_res = NULL; - sc->remote_res = ares; - - return sc; -} - -/* Create a request context and handle. */ -struct ldb_handle *map_init_handle(struct ldb_request *req, struct ldb_module *module) -{ - struct map_context *ac; - struct ldb_handle *h; - - h = talloc_zero(req, struct ldb_handle); - if (h == NULL) { - map_oom(module); - return NULL; - } - - h->module = module; - - ac = map_init_context(h, req); - if (ac == NULL) { - talloc_free(h); - return NULL; - } - - h->private_data = (void *)ac; - - h->state = LDB_ASYNC_INIT; - h->status = LDB_SUCCESS; - - return h; -} - - -/* Dealing with DNs for different partitions - * ========================================= */ - -/* Check whether any data should be stored in the local partition. */ -BOOL map_check_local_db(struct ldb_module *module) -{ - const struct ldb_map_context *data = map_get_context(module); - - if (!data->remote_base_dn || !data->local_base_dn) { - return False; - } - - return True; -} - -/* Copy a DN with the base DN of the local partition. */ -static struct ldb_dn *ldb_dn_rebase_local(void *mem_ctx, const struct ldb_map_context *data, const struct ldb_dn *dn) -{ - return ldb_dn_copy_rebase(mem_ctx, dn, data->remote_base_dn, data->local_base_dn); -} - -/* Copy a DN with the base DN of the remote partition. */ -static struct ldb_dn *ldb_dn_rebase_remote(void *mem_ctx, const struct ldb_map_context *data, const struct ldb_dn *dn) -{ - return ldb_dn_copy_rebase(mem_ctx, dn, data->local_base_dn, data->remote_base_dn); -} - -/* Run a request and make sure it targets the remote partition. */ -/* TODO: free old DNs and messages? */ -int ldb_next_remote_request(struct ldb_module *module, struct ldb_request *request) -{ - const struct ldb_map_context *data = map_get_context(module); - struct ldb_message *msg; - - switch (request->operation) { - case LDB_SEARCH: - if (request->op.search.base) { - request->op.search.base = ldb_dn_rebase_remote(request, data, request->op.search.base); - } else { - request->op.search.base = data->remote_base_dn; - /* TODO: adjust scope? */ - } - break; - - case LDB_ADD: - msg = ldb_msg_copy_shallow(request, request->op.add.message); - msg->dn = ldb_dn_rebase_remote(msg, data, msg->dn); - request->op.add.message = msg; - break; - - case LDB_MODIFY: - msg = ldb_msg_copy_shallow(request, request->op.mod.message); - msg->dn = ldb_dn_rebase_remote(msg, data, msg->dn); - request->op.mod.message = msg; - break; - - case LDB_DELETE: - request->op.del.dn = ldb_dn_rebase_remote(request, data, request->op.del.dn); - break; - - case LDB_RENAME: - request->op.rename.olddn = ldb_dn_rebase_remote(request, data, request->op.rename.olddn); - request->op.rename.newdn = ldb_dn_rebase_remote(request, data, request->op.rename.newdn); - break; - - default: - ldb_debug(module->ldb, LDB_DEBUG_ERROR, "ldb_map: " - "Invalid remote request!\n"); - return LDB_ERR_OPERATIONS_ERROR; - } - - return ldb_next_request(module, request); -} - - -/* Finding mappings for attributes and objectClasses - * ================================================= */ - -/* Find an objectClass mapping by the local name. */ -static const struct ldb_map_objectclass *map_objectclass_find_local(const struct ldb_map_context *data, const char *name) -{ - int i; - - for (i = 0; data->objectclass_maps && data->objectclass_maps[i].local_name; i++) { - if (ldb_attr_cmp(data->objectclass_maps[i].local_name, name) == 0) { - return &data->objectclass_maps[i]; - } - } - - return NULL; -} - -/* Find an objectClass mapping by the remote name. */ -static const struct ldb_map_objectclass *map_objectclass_find_remote(const struct ldb_map_context *data, const char *name) -{ - int i; - - for (i = 0; data->objectclass_maps && data->objectclass_maps[i].remote_name; i++) { - if (ldb_attr_cmp(data->objectclass_maps[i].remote_name, name) == 0) { - return &data->objectclass_maps[i]; - } - } - - return NULL; -} - -/* Find an attribute mapping by the local name. */ -const struct ldb_map_attribute *map_attr_find_local(const struct ldb_map_context *data, const char *name) -{ - int i; - - for (i = 0; data->attribute_maps[i].local_name; i++) { - if (ldb_attr_cmp(data->attribute_maps[i].local_name, name) == 0) { - return &data->attribute_maps[i]; - } - } - for (i = 0; data->attribute_maps[i].local_name; i++) { - if (ldb_attr_cmp(data->attribute_maps[i].local_name, "*") == 0) { - return &data->attribute_maps[i]; - } - } - - return NULL; -} - -/* Find an attribute mapping by the remote name. */ -const struct ldb_map_attribute *map_attr_find_remote(const struct ldb_map_context *data, const char *name) -{ - const struct ldb_map_attribute *map; - const struct ldb_map_attribute *wildcard = NULL; - int i, j; - - for (i = 0; data->attribute_maps[i].local_name; i++) { - map = &data->attribute_maps[i]; - if (ldb_attr_cmp(map->local_name, "*") == 0) { - wildcard = &data->attribute_maps[i]; - } - - switch (map->type) { - case MAP_IGNORE: - break; - - case MAP_KEEP: - if (ldb_attr_cmp(map->local_name, name) == 0) { - return map; - } - break; - - case MAP_RENAME: - case MAP_CONVERT: - if (ldb_attr_cmp(map->u.rename.remote_name, name) == 0) { - return map; - } - break; - - case MAP_GENERATE: - for (j = 0; map->u.generate.remote_names && map->u.generate.remote_names[j]; j++) { - if (ldb_attr_cmp(map->u.generate.remote_names[j], name) == 0) { - return map; - } - } - break; - } - } - - /* We didn't find it, so return the wildcard record if one was configured */ - return wildcard; -} - - -/* Mapping attributes - * ================== */ - -/* Check whether an attribute will be mapped into the remote partition. */ -BOOL map_attr_check_remote(const struct ldb_map_context *data, const char *attr) -{ - const struct ldb_map_attribute *map = map_attr_find_local(data, attr); - - if (map == NULL) { - return False; - } - if (map->type == MAP_IGNORE) { - return False; - } - - return True; -} - -/* Map an attribute name into the remote partition. */ -const char *map_attr_map_local(void *mem_ctx, const struct ldb_map_attribute *map, const char *attr) -{ - if (map == NULL) { - return talloc_strdup(mem_ctx, attr); - } - - switch (map->type) { - case MAP_KEEP: - return talloc_strdup(mem_ctx, attr); - - case MAP_RENAME: - case MAP_CONVERT: - return talloc_strdup(mem_ctx, map->u.rename.remote_name); - - default: - return NULL; - } -} - -/* Map an attribute name back into the local partition. */ -const char *map_attr_map_remote(void *mem_ctx, const struct ldb_map_attribute *map, const char *attr) -{ - if (map == NULL) { - return talloc_strdup(mem_ctx, attr); - } - - if (map->type == MAP_KEEP) { - return talloc_strdup(mem_ctx, attr); - } - - return talloc_strdup(mem_ctx, map->local_name); -} - - -/* Merge two lists of attributes into a single one. */ -int map_attrs_merge(struct ldb_module *module, void *mem_ctx, - const char ***attrs, const char * const *more_attrs) -{ - int i, j, k; - - for (i = 0; *attrs && (*attrs)[i]; i++) /* noop */ ; - for (j = 0; more_attrs && more_attrs[j]; j++) /* noop */ ; - - *attrs = talloc_realloc(mem_ctx, *attrs, const char *, i+j+1); - if (*attrs == NULL) { - map_oom(module); - return -1; - } - - for (k = 0; k < j; k++) { - (*attrs)[i + k] = more_attrs[k]; - } - - (*attrs)[i+k] = NULL; - - return 0; -} - -/* Mapping ldb values - * ================== */ - -/* Map an ldb value into the remote partition. */ -struct ldb_val ldb_val_map_local(struct ldb_module *module, void *mem_ctx, - const struct ldb_map_attribute *map, const struct ldb_val *val) -{ - if (map && (map->type == MAP_CONVERT) && (map->u.convert.convert_local)) { - return map->u.convert.convert_local(module, mem_ctx, val); - } - - return ldb_val_dup(mem_ctx, val); -} - -/* Map an ldb value back into the local partition. */ -struct ldb_val ldb_val_map_remote(struct ldb_module *module, void *mem_ctx, - const struct ldb_map_attribute *map, const struct ldb_val *val) -{ - if (map && (map->type == MAP_CONVERT) && (map->u.convert.convert_remote)) { - return map->u.convert.convert_remote(module, mem_ctx, val); - } - - return ldb_val_dup(mem_ctx, val); -} - - -/* Mapping DNs - * =========== */ - -/* Check whether a DN is below the local baseDN. */ -BOOL ldb_dn_check_local(struct ldb_module *module, const struct ldb_dn *dn) -{ - const struct ldb_map_context *data = map_get_context(module); - - if (!data->local_base_dn) { - return True; - } - - return ldb_dn_compare_base(module->ldb, data->local_base_dn, dn) == 0; -} - -/* Map a DN into the remote partition. */ -struct ldb_dn *ldb_dn_map_local(struct ldb_module *module, void *mem_ctx, const struct ldb_dn *dn) -{ - const struct ldb_map_context *data = map_get_context(module); - struct ldb_dn *newdn; - const struct ldb_map_attribute *map; - enum ldb_map_attr_type map_type; - const char *name; - struct ldb_val value; - int i, ret; - - if (dn == NULL) { - return NULL; - } - - newdn = ldb_dn_copy(mem_ctx, dn); - if (newdn == NULL) { - map_oom(module); - return NULL; - } - - /* For each RDN, map the component name and possibly the value */ - for (i = 0; i < ldb_dn_get_comp_num(newdn); i++) { - map = map_attr_find_local(data, ldb_dn_get_component_name(dn, i)); - - /* Unknown attribute - leave this RDN as is and hope the best... */ - if (map == NULL) { - map_type = MAP_KEEP; - } else { - map_type = map->type; - } - - switch (map_type) { - case MAP_IGNORE: - case MAP_GENERATE: - ldb_debug(module->ldb, LDB_DEBUG_ERROR, "ldb_map: " - "MAP_IGNORE/MAP_GENERATE attribute '%s' " - "used in DN!\n", ldb_dn_get_component_name(dn, i)); - goto failed; - - case MAP_CONVERT: - if (map->u.convert.convert_local == NULL) { - ldb_debug(module->ldb, LDB_DEBUG_ERROR, "ldb_map: " - "'convert_local' not set for attribute '%s' " - "used in DN!\n", ldb_dn_get_component_name(dn, i)); - goto failed; - } - /* fall through */ - case MAP_KEEP: - case MAP_RENAME: - name = map_attr_map_local(newdn, map, ldb_dn_get_component_name(dn, i)); - if (name == NULL) goto failed; - - value = ldb_val_map_local(module, newdn, map, ldb_dn_get_component_val(dn, i)); - if (value.data == NULL) goto failed; - - ret = ldb_dn_set_component(newdn, i, name, value); - if (ret != LDB_SUCCESS) { - goto failed; - } - - break; - } - } - - return newdn; - -failed: - talloc_free(newdn); - return NULL; -} - -/* Map a DN into the local partition. */ -struct ldb_dn *ldb_dn_map_remote(struct ldb_module *module, void *mem_ctx, const struct ldb_dn *dn) -{ - const struct ldb_map_context *data = map_get_context(module); - struct ldb_dn *newdn; - const struct ldb_map_attribute *map; - enum ldb_map_attr_type map_type; - const char *name; - struct ldb_val value; - int i, ret; - - if (dn == NULL) { - return NULL; - } - - newdn = ldb_dn_copy(mem_ctx, dn); - if (newdn == NULL) { - map_oom(module); - return NULL; - } - - /* For each RDN, map the component name and possibly the value */ - for (i = 0; i < ldb_dn_get_comp_num(newdn); i++) { - map = map_attr_find_remote(data, ldb_dn_get_component_name(dn, i)); - - /* Unknown attribute - leave this RDN as is and hope the best... */ - if (map == NULL) { - map_type = MAP_KEEP; - } else { - map_type = map->type; - } - - switch (map_type) { - case MAP_IGNORE: - case MAP_GENERATE: - ldb_debug(module->ldb, LDB_DEBUG_ERROR, "ldb_map: " - "MAP_IGNORE/MAP_GENERATE attribute '%s' " - "used in DN!\n", ldb_dn_get_component_name(dn, i)); - goto failed; - - case MAP_CONVERT: - if (map->u.convert.convert_remote == NULL) { - ldb_debug(module->ldb, LDB_DEBUG_ERROR, "ldb_map: " - "'convert_remote' not set for attribute '%s' " - "used in DN!\n", ldb_dn_get_component_name(dn, i)); - goto failed; - } - /* fall through */ - case MAP_KEEP: - case MAP_RENAME: - name = map_attr_map_remote(newdn, map, ldb_dn_get_component_name(dn, i)); - if (name == NULL) goto failed; - - value = ldb_val_map_remote(module, newdn, map, ldb_dn_get_component_val(dn, i)); - if (value.data == NULL) goto failed; - - ret = ldb_dn_set_component(newdn, i, name, value); - if (ret != LDB_SUCCESS) { - goto failed; - } - - break; - } - } - - return newdn; - -failed: - talloc_free(newdn); - return NULL; -} - -/* Map a DN and its base into the local partition. */ -/* TODO: This should not be required with GUIDs. */ -struct ldb_dn *ldb_dn_map_rebase_remote(struct ldb_module *module, void *mem_ctx, const struct ldb_dn *dn) -{ - const struct ldb_map_context *data = map_get_context(module); - struct ldb_dn *dn1, *dn2; - - dn1 = ldb_dn_rebase_local(mem_ctx, data, dn); - dn2 = ldb_dn_map_remote(module, mem_ctx, dn1); - - talloc_free(dn1); - return dn2; -} - - -/* Converting DNs and objectClasses (as ldb values) - * ================================================ */ - -/* Map a DN contained in an ldb value into the remote partition. */ -static struct ldb_val ldb_dn_convert_local(struct ldb_module *module, void *mem_ctx, const struct ldb_val *val) -{ - struct ldb_dn *dn, *newdn; - struct ldb_val newval; - - dn = ldb_dn_explode(mem_ctx, (char *)val->data); - newdn = ldb_dn_map_local(module, mem_ctx, dn); - talloc_free(dn); - - newval.length = 0; - newval.data = (uint8_t *)ldb_dn_linearize(mem_ctx, newdn); - if (newval.data) { - newval.length = strlen((char *)newval.data); - } - talloc_free(newdn); - - return newval; -} - -/* Map a DN contained in an ldb value into the local partition. */ -static struct ldb_val ldb_dn_convert_remote(struct ldb_module *module, void *mem_ctx, const struct ldb_val *val) -{ - struct ldb_dn *dn, *newdn; - struct ldb_val newval; - - dn = ldb_dn_explode(mem_ctx, (char *)val->data); - newdn = ldb_dn_map_remote(module, mem_ctx, dn); - talloc_free(dn); - - newval.length = 0; - newval.data = (uint8_t *)ldb_dn_linearize(mem_ctx, newdn); - if (newval.data) { - newval.length = strlen((char *)newval.data); - } - talloc_free(newdn); - - return newval; -} - -/* Map an objectClass into the remote partition. */ -static struct ldb_val map_objectclass_convert_local(struct ldb_module *module, void *mem_ctx, const struct ldb_val *val) -{ - const struct ldb_map_context *data = map_get_context(module); - const char *name = (char *)val->data; - const struct ldb_map_objectclass *map = map_objectclass_find_local(data, name); - struct ldb_val newval; - - if (map) { - newval.data = (uint8_t*)talloc_strdup(mem_ctx, map->remote_name); - newval.length = strlen((char *)newval.data); - return newval; - } - - return ldb_val_dup(mem_ctx, val); -} - -/* Generate a remote message with a mapped objectClass. */ -static void map_objectclass_generate_remote(struct ldb_module *module, const char *local_attr, const struct ldb_message *old, struct ldb_message *remote, struct ldb_message *local) -{ - struct ldb_message_element *el, *oc; - struct ldb_val val; - BOOL found_extensibleObject = False; - int i; - - /* Find old local objectClass */ - oc = ldb_msg_find_element(old, "objectClass"); - if (oc == NULL) { - return; - } - - /* Prepare new element */ - el = talloc_zero(remote, struct ldb_message_element); - if (el == NULL) { - ldb_oom(module->ldb); - return; /* TODO: fail? */ - } - - /* Copy local objectClass element, reverse space for an extra value */ - el->num_values = oc->num_values + 1; - el->values = talloc_array(el, struct ldb_val, el->num_values); - if (el->values == NULL) { - talloc_free(el); - ldb_oom(module->ldb); - return; /* TODO: fail? */ - } - - /* Copy local element name "objectClass" */ - el->name = talloc_strdup(el, local_attr); - - /* Convert all local objectClasses */ - for (i = 0; i < el->num_values - 1; i++) { - el->values[i] = map_objectclass_convert_local(module, el->values, &oc->values[i]); - if (ldb_attr_cmp((char *)el->values[i].data, "extensibleObject") == 0) { - found_extensibleObject = True; - } - } - - if (!found_extensibleObject) { - val.data = (uint8_t *)talloc_strdup(el->values, "extensibleObject"); - val.length = strlen((char *)val.data); - - /* Append additional objectClass "extensibleObject" */ - el->values[i] = val; - } else { - el->num_values--; - } - - /* Add new objectClass to remote message */ - ldb_msg_add(remote, el, 0); -} - -/* Map an objectClass into the local partition. */ -static struct ldb_val map_objectclass_convert_remote(struct ldb_module *module, void *mem_ctx, const struct ldb_val *val) -{ - const struct ldb_map_context *data = map_get_context(module); - const char *name = (char *)val->data; - const struct ldb_map_objectclass *map = map_objectclass_find_remote(data, name); - struct ldb_val newval; - - if (map) { - newval.data = (uint8_t*)talloc_strdup(mem_ctx, map->local_name); - newval.length = strlen((char *)newval.data); - return newval; - } - - return ldb_val_dup(mem_ctx, val); -} - -/* Generate a local message with a mapped objectClass. */ -static struct ldb_message_element *map_objectclass_generate_local(struct ldb_module *module, void *mem_ctx, const char *local_attr, const struct ldb_message *remote) -{ - struct ldb_message_element *el, *oc; - struct ldb_val val; - int i; - - /* Find old remote objectClass */ - oc = ldb_msg_find_element(remote, "objectClass"); - if (oc == NULL) { - return NULL; - } - - /* Prepare new element */ - el = talloc_zero(mem_ctx, struct ldb_message_element); - if (el == NULL) { - ldb_oom(module->ldb); - return NULL; - } - - /* Copy remote objectClass element */ - el->num_values = oc->num_values; - el->values = talloc_array(el, struct ldb_val, el->num_values); - if (el->values == NULL) { - talloc_free(el); - ldb_oom(module->ldb); - return NULL; - } - - /* Copy remote element name "objectClass" */ - el->name = talloc_strdup(el, local_attr); - - /* Convert all remote objectClasses */ - for (i = 0; i < el->num_values; i++) { - el->values[i] = map_objectclass_convert_remote(module, el->values, &oc->values[i]); - } - - val.data = (uint8_t *)talloc_strdup(el->values, "extensibleObject"); - val.length = strlen((char *)val.data); - - /* Remove last value if it was "extensibleObject" */ - if (ldb_val_equal_exact(&val, &el->values[i-1])) { - el->num_values--; - el->values = talloc_realloc(el, el->values, struct ldb_val, el->num_values); - if (el->values == NULL) { - talloc_free(el); - ldb_oom(module->ldb); - return NULL; - } - } - - return el; -} - -/* Mappings for searches on objectClass= assuming a one-to-one - * mapping. Needed because this is a generate operator for the - * add/modify code */ -static int map_objectclass_convert_operator(struct ldb_module *module, void *mem_ctx, - struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) -{ - - static const struct ldb_map_attribute objectclass_map = { - .local_name = "objectClass", - .type = MAP_CONVERT, - .u = { - .convert = { - .remote_name = "objectClass", - .convert_local = map_objectclass_convert_local, - .convert_remote = map_objectclass_convert_remote, - }, - }, - }; - - return map_subtree_collect_remote_simple(module, mem_ctx, new, tree, &objectclass_map); -} - -/* Auxiliary request construction - * ============================== */ - -/* Store the DN of a single search result in context. */ -static int map_search_self_callback(struct ldb_context *ldb, void *context, struct ldb_reply *ares) -{ - struct map_context *ac; - - if (context == NULL || ares == NULL) { - ldb_set_errstring(ldb, talloc_asprintf(ldb, "NULL Context or Result in callback")); - return LDB_ERR_OPERATIONS_ERROR; - } - - ac = talloc_get_type(context, struct map_context); - - /* We are interested only in the single reply */ - if (ares->type != LDB_REPLY_ENTRY) { - talloc_free(ares); - return LDB_SUCCESS; - } - - /* We have already found a remote DN */ - if (ac->local_dn) { - ldb_set_errstring(ldb, talloc_asprintf(ldb, "Too many results to base search")); - talloc_free(ares); - return LDB_ERR_OPERATIONS_ERROR; - } - - /* Store local DN */ - ac->local_dn = ares->message->dn; - - return LDB_SUCCESS; -} - -/* Build a request to search a record by its DN. */ -struct ldb_request *map_search_base_req(struct map_context *ac, const struct ldb_dn *dn, const char * const *attrs, const struct ldb_parse_tree *tree, void *context, ldb_search_callback callback) -{ - struct ldb_request *req; - - req = talloc_zero(ac, struct ldb_request); - if (req == NULL) { - map_oom(ac->module); - return NULL; - } - - req->operation = LDB_SEARCH; - req->op.search.base = dn; - req->op.search.scope = LDB_SCOPE_BASE; - req->op.search.attrs = attrs; - - if (tree) { - req->op.search.tree = tree; - } else { - req->op.search.tree = ldb_parse_tree(req, NULL); - if (req->op.search.tree == NULL) { - talloc_free(req); - return NULL; - } - } - - req->controls = NULL; - req->context = context; - req->callback = callback; - ldb_set_timeout_from_prev_req(ac->module->ldb, ac->orig_req, req); - - return req; -} - -/* Build a request to search the local record by its DN. */ -struct ldb_request *map_search_self_req(struct map_context *ac, const struct ldb_dn *dn) -{ - /* attrs[] is returned from this function in - * ac->search_req->op.search.attrs, so it must be static, as - * otherwise the compiler can put it on the stack */ - static const char * const attrs[] = { IS_MAPPED, NULL }; - struct ldb_parse_tree *tree; - - /* Limit search to records with 'IS_MAPPED' present */ - /* TODO: `tree = ldb_parse_tree(ac, IS_MAPPED);' won't do. */ - tree = talloc_zero(ac, struct ldb_parse_tree); - if (tree == NULL) { - map_oom(ac->module); - return NULL; - } - - tree->operation = LDB_OP_PRESENT; - tree->u.present.attr = talloc_strdup(tree, IS_MAPPED); - - return map_search_base_req(ac, dn, attrs, tree, ac, map_search_self_callback); -} - -/* Build a request to update the 'IS_MAPPED' attribute */ -struct ldb_request *map_build_fixup_req(struct map_context *ac, const struct ldb_dn *olddn, const struct ldb_dn *newdn) -{ - struct ldb_request *req; - struct ldb_message *msg; - const char *dn; - - /* Prepare request */ - req = talloc_zero(ac, struct ldb_request); - if (req == NULL) { - map_oom(ac->module); - return NULL; - } - - /* Prepare message */ - msg = ldb_msg_new(req); - if (msg == NULL) { - map_oom(ac->module); - goto failed; - } - - /* Update local 'IS_MAPPED' to the new remote DN */ - msg->dn = discard_const_p(struct ldb_dn, olddn); - dn = ldb_dn_linearize(msg, newdn); - if (dn == NULL) { - goto failed; - } - if (ldb_msg_add_empty(msg, IS_MAPPED, LDB_FLAG_MOD_REPLACE, NULL) != 0) { - goto failed; - } - if (ldb_msg_add_string(msg, IS_MAPPED, dn) != 0) { - goto failed; - } - - req->operation = LDB_MODIFY; - req->op.mod.message = msg; - req->controls = NULL; - req->handle = NULL; - req->context = NULL; - req->callback = NULL; - - return req; - -failed: - talloc_free(req); - return NULL; -} - - -/* Asynchronous call structure - * =========================== */ - -/* Figure out which request is currently pending. */ -static struct ldb_request *map_get_req(struct map_context *ac) -{ - switch (ac->step) { - case MAP_SEARCH_SELF_MODIFY: - case MAP_SEARCH_SELF_DELETE: - case MAP_SEARCH_SELF_RENAME: - return ac->search_req; - - case MAP_ADD_REMOTE: - case MAP_MODIFY_REMOTE: - case MAP_DELETE_REMOTE: - case MAP_RENAME_REMOTE: - return ac->remote_req; - - case MAP_RENAME_FIXUP: - return ac->down_req; - - case MAP_ADD_LOCAL: - case MAP_MODIFY_LOCAL: - case MAP_DELETE_LOCAL: - case MAP_RENAME_LOCAL: - return ac->local_req; - - case MAP_SEARCH_REMOTE: - /* Can't happen */ - break; - } - - return NULL; /* unreachable; silences a warning */ -} - -typedef int (*map_next_function)(struct ldb_handle *handle); - -/* Figure out the next request to run. */ -static map_next_function map_get_next(struct map_context *ac) -{ - switch (ac->step) { - case MAP_SEARCH_REMOTE: - return NULL; - - case MAP_ADD_LOCAL: - return map_add_do_remote; - case MAP_ADD_REMOTE: - return NULL; - - case MAP_SEARCH_SELF_MODIFY: - return map_modify_do_local; - case MAP_MODIFY_LOCAL: - return map_modify_do_remote; - case MAP_MODIFY_REMOTE: - return NULL; - - case MAP_SEARCH_SELF_DELETE: - return map_delete_do_local; - case MAP_DELETE_LOCAL: - return map_delete_do_remote; - case MAP_DELETE_REMOTE: - return NULL; - - case MAP_SEARCH_SELF_RENAME: - return map_rename_do_local; - case MAP_RENAME_LOCAL: - return map_rename_do_fixup; - case MAP_RENAME_FIXUP: - return map_rename_do_remote; - case MAP_RENAME_REMOTE: - return NULL; - } - - return NULL; /* unreachable; silences a warning */ -} - -/* Wait for the current pending request to finish and continue with the next. */ -static int map_wait_next(struct ldb_handle *handle) -{ - struct map_context *ac; - struct ldb_request *req; - map_next_function next; - int ret; - - if (handle == NULL || handle->private_data == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - if (handle->state == LDB_ASYNC_DONE) { - return handle->status; - } - - handle->state = LDB_ASYNC_PENDING; - handle->status = LDB_SUCCESS; - - ac = talloc_get_type(handle->private_data, struct map_context); - - if (ac->step == MAP_SEARCH_REMOTE) { - int i; - for (i = 0; i < ac->num_searches; i++) { - req = ac->search_reqs[i]; - ret = ldb_wait(req->handle, LDB_WAIT_NONE); - - if (ret != LDB_SUCCESS) { - handle->status = ret; - goto done; - } - if (req->handle->status != LDB_SUCCESS) { - handle->status = req->handle->status; - goto done; - } - if (req->handle->state != LDB_ASYNC_DONE) { - return LDB_SUCCESS; - } - } - } else { - - req = map_get_req(ac); - - ret = ldb_wait(req->handle, LDB_WAIT_NONE); - - if (ret != LDB_SUCCESS) { - handle->status = ret; - goto done; - } - if (req->handle->status != LDB_SUCCESS) { - handle->status = req->handle->status; - goto done; - } - if (req->handle->state != LDB_ASYNC_DONE) { - return LDB_SUCCESS; - } - - next = map_get_next(ac); - if (next) { - return next(handle); - } - } - - ret = LDB_SUCCESS; - -done: - handle->state = LDB_ASYNC_DONE; - return ret; -} - -/* Wait for all current pending requests to finish. */ -static int map_wait_all(struct ldb_handle *handle) -{ - int ret; - - while (handle->state != LDB_ASYNC_DONE) { - ret = map_wait_next(handle); - if (ret != LDB_SUCCESS) { - return ret; - } - } - - return handle->status; -} - -/* Wait for pending requests to finish. */ -static int map_wait(struct ldb_handle *handle, enum ldb_wait_type type) -{ - if (type == LDB_WAIT_ALL) { - return map_wait_all(handle); - } else { - return map_wait_next(handle); - } -} - - -/* Module initialization - * ===================== */ - -/* Provided module operations */ -static const struct ldb_module_ops map_ops = { - .name = "ldb_map", - .add = map_add, - .modify = map_modify, - .del = map_delete, - .rename = map_rename, - .search = map_search, - .wait = map_wait, -}; - -/* Builtin mappings for DNs and objectClasses */ -static const struct ldb_map_attribute builtin_attribute_maps[] = { - { - .local_name = "dn", - .type = MAP_CONVERT, - .u = { - .convert = { - .remote_name = "dn", - .convert_local = ldb_dn_convert_local, - .convert_remote = ldb_dn_convert_remote, - }, - }, - }, - { - .local_name = "objectClass", - .type = MAP_GENERATE, - .convert_operator = map_objectclass_convert_operator, - .u = { - .generate = { - .remote_names = { "objectClass", NULL }, - .generate_local = map_objectclass_generate_local, - .generate_remote = map_objectclass_generate_remote, - }, - }, - }, - { - .local_name = NULL, - } -}; - -/* Find the special 'MAP_DN_NAME' record and store local and remote - * base DNs in private data. */ -static int map_init_dns(struct ldb_module *module, struct ldb_map_context *data, const char *name) -{ - static const char * const attrs[] = { MAP_DN_FROM, MAP_DN_TO, NULL }; - struct ldb_dn *dn; - struct ldb_message *msg; - struct ldb_result *res; - int ret; - - if (!name) { - data->local_base_dn = NULL; - data->remote_base_dn = NULL; - return LDB_SUCCESS; - } - - dn = ldb_dn_string_compose(data, NULL, "%s=%s", MAP_DN_NAME, name); - if (dn == NULL) { - ldb_debug(module->ldb, LDB_DEBUG_ERROR, "ldb_map: " - "Failed to construct '%s' DN!\n", MAP_DN_NAME); - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldb_search(module->ldb, dn, LDB_SCOPE_BASE, NULL, attrs, &res); - talloc_free(dn); - if (ret != LDB_SUCCESS) { - return ret; - } - if (res->count == 0) { - ldb_debug(module->ldb, LDB_DEBUG_ERROR, "ldb_map: " - "No results for '%s=%s'!\n", MAP_DN_NAME, name); - talloc_free(res); - return LDB_ERR_CONSTRAINT_VIOLATION; - } - if (res->count > 1) { - ldb_debug(module->ldb, LDB_DEBUG_ERROR, "ldb_map: " - "Too many results for '%s=%s'!\n", MAP_DN_NAME, name); - talloc_free(res); - return LDB_ERR_CONSTRAINT_VIOLATION; - } - - msg = res->msgs[0]; - data->local_base_dn = ldb_msg_find_attr_as_dn(data, msg, MAP_DN_FROM); - data->remote_base_dn = ldb_msg_find_attr_as_dn(data, msg, MAP_DN_TO); - talloc_free(res); - - return LDB_SUCCESS; -} - -/* Store attribute maps and objectClass maps in private data. */ -static int map_init_maps(struct ldb_module *module, struct ldb_map_context *data, - const struct ldb_map_attribute *attrs, - const struct ldb_map_objectclass *ocls, - const char * const *wildcard_attributes) -{ - int i, j, last; - last = 0; - - /* Count specified attribute maps */ - for (i = 0; attrs[i].local_name; i++) /* noop */ ; - /* Count built-in attribute maps */ - for (j = 0; builtin_attribute_maps[j].local_name; j++) /* noop */ ; - - /* Store list of attribute maps */ - data->attribute_maps = talloc_array(data, struct ldb_map_attribute, i+j+1); - if (data->attribute_maps == NULL) { - map_oom(module); - return LDB_ERR_OPERATIONS_ERROR; - } - - /* Specified ones go first */ - for (i = 0; attrs[i].local_name; i++) { - data->attribute_maps[last] = attrs[i]; - last++; - } - - /* Built-in ones go last */ - for (i = 0; builtin_attribute_maps[i].local_name; i++) { - data->attribute_maps[last] = builtin_attribute_maps[i]; - last++; - } - - /* Ensure 'local_name == NULL' for the last entry */ - memset(&data->attribute_maps[last], 0, sizeof(struct ldb_map_attribute)); - - /* Store list of objectClass maps */ - data->objectclass_maps = ocls; - - data->wildcard_attributes = wildcard_attributes; - - return LDB_SUCCESS; -} - -/* Copy the list of provided module operations. */ -_PUBLIC_ struct ldb_module_ops ldb_map_get_ops(void) -{ - return map_ops; -} - -/* Initialize global private data. */ -_PUBLIC_ int ldb_map_init(struct ldb_module *module, const struct ldb_map_attribute *attrs, - const struct ldb_map_objectclass *ocls, - const char * const *wildcard_attributes, - const char *name) -{ - struct map_private *data; - int ret; - - /* Prepare private data */ - data = talloc_zero(module, struct map_private); - if (data == NULL) { - map_oom(module); - return LDB_ERR_OPERATIONS_ERROR; - } - - module->private_data = data; - - data->context = talloc_zero(data, struct ldb_map_context); - if (!data->context) { - map_oom(module); - return LDB_ERR_OPERATIONS_ERROR; - } - - /* Store local and remote baseDNs */ - ret = map_init_dns(module, data->context, name); - if (ret != LDB_SUCCESS) { - talloc_free(data); - return ret; - } - - /* Store list of attribute and objectClass maps */ - ret = map_init_maps(module, data->context, attrs, ocls, wildcard_attributes); - if (ret != LDB_SUCCESS) { - talloc_free(data); - return ret; - } - - return LDB_SUCCESS; -} - -/* Usage note for initialization of this module: - * - * ldb_map is meant to be used from a different module that sets up - * the mappings and gets registered in ldb. - * - * 'ldb_map_init' initializes the private data of this module and - * stores the attribute and objectClass maps in there. It also looks - * up the '@MAP' special DN so requests can be redirected to the - * remote partition. - * - * This function should be called from the 'init_context' op of the - * module using ldb_map. - * - * 'ldb_map_get_ops' returns a copy of ldb_maps module operations. - * - * It should be called from the initialize function of the using - * module, which should then override the 'init_context' op with a - * function making the appropriate calls to 'ldb_map_init'. - */ diff --git a/source/lib/ldb/modules/ldb_map.h b/source/lib/ldb/modules/ldb_map.h deleted file mode 100644 index c5c455bcb25..00000000000 --- a/source/lib/ldb/modules/ldb_map.h +++ /dev/null @@ -1,158 +0,0 @@ -/* - ldb database mapping module - - Copyright (C) Jelmer Vernooij 2005 - Copyright (C) Martin Kuehl <mkhl@samba.org> 2006 - - * NOTICE: this module is NOT released under the GNU LGPL license as - * other ldb code. This module is release under the GNU GPL v2 or - * later license. - - 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. -*/ - -#ifndef __LDB_MAP_H__ -#define __LDB_MAP_H__ - -/* ldb_map is a skeleton LDB module that can be used for any other modules - * that need to map attributes. - * - * The term 'remote' in this header refers to the connection where the - * original schema is used on while 'local' means the local connection - * that any upper layers will use. - * - * All local attributes will have to have a definition. Not all remote - * attributes need a definition as LDB is a lot less strict than LDAP - * (in other words, sending unknown attributes to an LDAP server hurts us, - * while returning too many attributes in ldb_search() doesn't) - */ - - -/* Name of the internal attribute pointing from the local to the - * remote part of a record */ -#define IS_MAPPED "isMapped" - - -struct ldb_map_context; - -/* convert a local ldb_val to a remote ldb_val */ -typedef struct ldb_val (*ldb_map_convert_func) (struct ldb_module *module, void *mem_ctx, const struct ldb_val *val); - -#define LDB_MAP_MAX_REMOTE_NAMES 10 - -/* map from local to remote attribute */ -struct ldb_map_attribute { - const char *local_name; /* local name */ - - enum ldb_map_attr_type { - MAP_IGNORE, /* Ignore this local attribute. Doesn't exist remotely. */ - MAP_KEEP, /* Keep as is. Same name locally and remotely. */ - MAP_RENAME, /* Simply rename the attribute. Name changes, data is the same */ - MAP_CONVERT, /* Rename + convert data */ - MAP_GENERATE /* Use generate function for generating new name/data. - Used for generating attributes based on - multiple remote attributes. */ - } type; - - /* if set, will be called for search expressions that contain this attribute */ - int (*convert_operator)(struct ldb_module *, TALLOC_CTX *ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *); - - union { - struct { - const char *remote_name; - } rename; - - struct { - const char *remote_name; - - /* Convert local to remote data */ - ldb_map_convert_func convert_local; - - /* Convert remote to local data */ - /* an entry can have convert_remote set to NULL, as long as there as an entry with the same local_name - * that is non-NULL before it. */ - ldb_map_convert_func convert_remote; - } convert; - - struct { - /* Generate the local attribute from remote message */ - struct ldb_message_element *(*generate_local)(struct ldb_module *, TALLOC_CTX *mem_ctx, const char *remote_attr, const struct ldb_message *remote); - - /* Update remote message with information from local message */ - void (*generate_remote)(struct ldb_module *, const char *local_attr, const struct ldb_message *old, struct ldb_message *remote, struct ldb_message *local); - - /* Name(s) for this attribute on the remote server. This is an array since - * one local attribute's data can be split up into several attributes - * remotely */ - const char *remote_names[LDB_MAP_MAX_REMOTE_NAMES]; - - /* Names of additional remote attributes - * required for the generation. NULL - * indicates that `local_attr' suffices. */ - /* -#define LDB_MAP_MAX_SELF_ATTRIBUTES 10 - const char *self_attrs[LDB_MAP_MAX_SELF_ATTRIBUTES]; - */ - } generate; - } u; -}; - - -#define LDB_MAP_MAX_SUBCLASSES 10 -#define LDB_MAP_MAX_MUSTS 10 -#define LDB_MAP_MAX_MAYS 50 - -/* map from local to remote objectClass */ -struct ldb_map_objectclass { - const char *local_name; - const char *remote_name; - const char *base_classes[LDB_MAP_MAX_SUBCLASSES]; - const char *musts[LDB_MAP_MAX_MUSTS]; - const char *mays[LDB_MAP_MAX_MAYS]; -}; - - -/* private context data */ -struct ldb_map_context { - struct ldb_map_attribute *attribute_maps; - /* NOTE: Always declare base classes first here */ - const struct ldb_map_objectclass *objectclass_maps; - - /* Remote (often operational) attributes that should be added - * to any wildcard search */ - const char * const *wildcard_attributes; - - /* struct ldb_context *mapped_ldb; */ - const struct ldb_dn *local_base_dn; - const struct ldb_dn *remote_base_dn; -}; - -/* Global private data */ -struct map_private { - void *caller_private; - struct ldb_map_context *context; -}; - -/* Initialize global private data. */ -int ldb_map_init(struct ldb_module *module, const struct ldb_map_attribute *attrs, - const struct ldb_map_objectclass *ocls, - const char * const *wildcard_attributes, - const char *name); - -/* get copy of map_ops */ -struct ldb_module_ops -ldb_map_get_ops(void); - -#endif /* __LDB_MAP_H__ */ diff --git a/source/lib/ldb/modules/ldb_map_inbound.c b/source/lib/ldb/modules/ldb_map_inbound.c deleted file mode 100644 index 38454b2b116..00000000000 --- a/source/lib/ldb/modules/ldb_map_inbound.c +++ /dev/null @@ -1,724 +0,0 @@ -/* - ldb database mapping module - - Copyright (C) Jelmer Vernooij 2005 - Copyright (C) Martin Kuehl <mkhl@samba.org> 2006 - - * NOTICE: this module is NOT released under the GNU LGPL license as - * other ldb code. This module is release under the GNU GPL v2 or - * later license. - - 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. -*/ - -#include "includes.h" -#include "ldb/include/includes.h" - -#include "ldb/modules/ldb_map.h" -#include "ldb/modules/ldb_map_private.h" - - -/* Mapping message elements - * ======================== */ - -/* Map a message element into the remote partition. */ -static struct ldb_message_element *ldb_msg_el_map_local(struct ldb_module *module, void *mem_ctx, const struct ldb_map_attribute *map, const struct ldb_message_element *old) -{ - struct ldb_message_element *el; - int i; - - el = talloc_zero(mem_ctx, struct ldb_message_element); - if (el == NULL) { - map_oom(module); - return NULL; - } - - el->num_values = old->num_values; - el->values = talloc_array(el, struct ldb_val, el->num_values); - if (el->values == NULL) { - talloc_free(el); - map_oom(module); - return NULL; - } - - el->name = map_attr_map_local(el, map, old->name); - - for (i = 0; i < el->num_values; i++) { - el->values[i] = ldb_val_map_local(module, el->values, map, &old->values[i]); - } - - return el; -} - -/* Add a message element either to a local or to a remote message, - * depending on whether it goes into the local or remote partition. */ -static int ldb_msg_el_partition(struct ldb_module *module, struct ldb_message *local, struct ldb_message *remote, const struct ldb_message *msg, const char *attr_name, /* const char * const names[], */ const struct ldb_message_element *old) -{ - const struct ldb_map_context *data = map_get_context(module); - const struct ldb_map_attribute *map = map_attr_find_local(data, attr_name); - struct ldb_message_element *el=NULL; - - /* Unknown attribute: ignore */ - if (map == NULL) { - ldb_debug(module->ldb, LDB_DEBUG_WARNING, "ldb_map: " - "Not mapping attribute '%s': no mapping found\n", - old->name); - goto local; - } - - switch (map->type) { - case MAP_IGNORE: - goto local; - - case MAP_CONVERT: - if (map->u.convert.convert_local == NULL) { - ldb_debug(module->ldb, LDB_DEBUG_WARNING, "ldb_map: " - "Not mapping attribute '%s': " - "'convert_local' not set\n", - map->local_name); - goto local; - } - /* fall through */ - case MAP_KEEP: - case MAP_RENAME: - el = ldb_msg_el_map_local(module, remote, map, old); - break; - - case MAP_GENERATE: - if (map->u.generate.generate_remote == NULL) { - ldb_debug(module->ldb, LDB_DEBUG_WARNING, "ldb_map: " - "Not mapping attribute '%s': " - "'generate_remote' not set\n", - map->local_name); - goto local; - } - - /* TODO: if this attr requires context: - * make sure all context attrs are mappable (in 'names') - * make sure all context attrs have already been mapped? - * maybe postpone generation until they have been mapped? - */ - - map->u.generate.generate_remote(module, map->local_name, msg, remote, local); - return 0; - } - - if (el == NULL) { - return -1; - } - - return ldb_msg_add(remote, el, old->flags); - -local: - el = talloc(local, struct ldb_message_element); - if (el == NULL) { - map_oom(module); - return -1; - } - - *el = *old; /* copy the old element */ - - return ldb_msg_add(local, el, old->flags); -} - -/* Mapping messages - * ================ */ - -/* Check whether a message will be (partially) mapped into the remote partition. */ -static BOOL ldb_msg_check_remote(struct ldb_module *module, const struct ldb_message *msg) -{ - const struct ldb_map_context *data = map_get_context(module); - BOOL ret; - int i; - - for (i = 0; i < msg->num_elements; i++) { - ret = map_attr_check_remote(data, msg->elements[i].name); - if (ret) { - return ret; - } - } - - return False; -} - -/* Split message elements that stay in the local partition from those - * that are mapped into the remote partition. */ -static int ldb_msg_partition(struct ldb_module *module, struct ldb_message *local, struct ldb_message *remote, const struct ldb_message *msg) -{ - /* const char * const names[]; */ - int i, ret; - - for (i = 0; i < msg->num_elements; i++) { - /* Skip 'IS_MAPPED' */ - if (ldb_attr_cmp(msg->elements[i].name, IS_MAPPED) == 0) { - ldb_debug(module->ldb, LDB_DEBUG_WARNING, "ldb_map: " - "Skipping attribute '%s'\n", - msg->elements[i].name); - continue; - } - - ret = ldb_msg_el_partition(module, local, remote, msg, msg->elements[i].name, &msg->elements[i]); - if (ret) { - return ret; - } - } - - return 0; -} - - -/* Inbound requests: add, modify, rename, delete - * ============================================= */ - -/* Add the remote record. */ -int map_add_do_remote(struct ldb_handle *handle) -{ - struct map_context *ac; - - ac = talloc_get_type(handle->private_data, struct map_context); - - ldb_set_timeout_from_prev_req(ac->module->ldb, ac->orig_req, ac->remote_req); - - ac->step = MAP_ADD_REMOTE; - - handle->state = LDB_ASYNC_INIT; - handle->status = LDB_SUCCESS; - - return ldb_next_remote_request(ac->module, ac->remote_req); -} - -/* Add the local record. */ -int map_add_do_local(struct ldb_handle *handle) -{ - struct map_context *ac; - - ac = talloc_get_type(handle->private_data, struct map_context); - - ldb_set_timeout_from_prev_req(ac->module->ldb, ac->orig_req, ac->local_req); - - ac->step = MAP_ADD_LOCAL; - - handle->state = LDB_ASYNC_INIT; - handle->status = LDB_SUCCESS; - - return ldb_next_request(ac->module, ac->local_req); -} - -/* Add a record. */ -int map_add(struct ldb_module *module, struct ldb_request *req) -{ - const struct ldb_message *msg = req->op.add.message; - struct ldb_handle *h; - struct map_context *ac; - struct ldb_message *local, *remote; - const char *dn; - - /* Do not manipulate our control entries */ - if (ldb_dn_is_special(msg->dn)) { - return ldb_next_request(module, req); - } - - /* No mapping requested (perhaps no DN mapping specified), skip to next module */ - if (!ldb_dn_check_local(module, msg->dn)) { - return ldb_next_request(module, req); - } - - /* No mapping needed, fail */ - if (!ldb_msg_check_remote(module, msg)) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* Prepare context and handle */ - h = map_init_handle(req, module); - if (h == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - ac = talloc_get_type(h->private_data, struct map_context); - - /* Prepare the local operation */ - ac->local_req = talloc(ac, struct ldb_request); - if (ac->local_req == NULL) { - goto oom; - } - - *(ac->local_req) = *req; /* copy the request */ - - ac->local_req->context = NULL; - ac->local_req->callback = NULL; - - /* Prepare the remote operation */ - ac->remote_req = talloc(ac, struct ldb_request); - if (ac->remote_req == NULL) { - goto oom; - } - - *(ac->remote_req) = *req; /* copy the request */ - - ac->remote_req->context = NULL; - ac->remote_req->callback = NULL; - - /* Prepare the local message */ - local = ldb_msg_new(ac->local_req); - if (local == NULL) { - goto oom; - } - local->dn = msg->dn; - - /* Prepare the remote message */ - remote = ldb_msg_new(ac->remote_req); - if (remote == NULL) { - goto oom; - } - remote->dn = ldb_dn_map_local(ac->module, remote, msg->dn); - - /* Split local from remote message */ - ldb_msg_partition(module, local, remote, msg); - ac->local_req->op.add.message = local; - ac->remote_req->op.add.message = remote; - - if ((local->num_elements == 0) || (!map_check_local_db(ac->module))) { - /* No local data or db, just run the remote request */ - talloc_free(ac->local_req); - req->handle = h; /* return our own handle to deal with this call */ - return map_add_do_remote(h); - } - - /* Store remote DN in 'IS_MAPPED' */ - /* TODO: use GUIDs here instead */ - dn = ldb_dn_linearize(local, remote->dn); - if (ldb_msg_add_string(local, IS_MAPPED, dn) != 0) { - goto failed; - } - - req->handle = h; /* return our own handle to deal with this call */ - return map_add_do_local(h); - -oom: - map_oom(module); -failed: - talloc_free(h); - return LDB_ERR_OPERATIONS_ERROR; -} - -/* Modify the remote record. */ -int map_modify_do_remote(struct ldb_handle *handle) -{ - struct map_context *ac; - - ac = talloc_get_type(handle->private_data, struct map_context); - - ldb_set_timeout_from_prev_req(ac->module->ldb, ac->orig_req, ac->remote_req); - - ac->step = MAP_MODIFY_REMOTE; - - handle->state = LDB_ASYNC_INIT; - handle->status = LDB_SUCCESS; - - return ldb_next_remote_request(ac->module, ac->remote_req); -} - -/* Modify the local record. */ -int map_modify_do_local(struct ldb_handle *handle) -{ - struct map_context *ac; - struct ldb_message *msg; - char *dn; - - ac = talloc_get_type(handle->private_data, struct map_context); - - if (ac->local_dn == NULL) { - /* No local record present, add it instead */ - msg = discard_const_p(struct ldb_message, ac->local_req->op.mod.message); - - /* Add local 'IS_MAPPED' */ - /* TODO: use GUIDs here instead */ - dn = ldb_dn_linearize(msg, ac->remote_req->op.mod.message->dn); - if (ldb_msg_add_empty(msg, IS_MAPPED, LDB_FLAG_MOD_ADD, NULL) != 0) { - return LDB_ERR_OPERATIONS_ERROR; - } - if (ldb_msg_add_string(msg, IS_MAPPED, dn) != 0) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* Turn request into 'add' */ - ac->local_req->operation = LDB_ADD; - ac->local_req->op.add.message = msg; - /* TODO: Could I just leave msg in there? I think so, - * but it looks clearer this way. */ - } - - ldb_set_timeout_from_prev_req(ac->module->ldb, ac->orig_req, ac->local_req); - - ac->step = MAP_MODIFY_LOCAL; - - handle->state = LDB_ASYNC_INIT; - handle->status = LDB_SUCCESS; - - return ldb_next_request(ac->module, ac->local_req); -} - -/* Modify a record. */ -int map_modify(struct ldb_module *module, struct ldb_request *req) -{ - const struct ldb_message *msg = req->op.mod.message; - struct ldb_handle *h; - struct map_context *ac; - struct ldb_message *local, *remote; - - /* Do not manipulate our control entries */ - if (ldb_dn_is_special(msg->dn)) { - return ldb_next_request(module, req); - } - - /* No mapping requested (perhaps no DN mapping specified), skip to next module */ - if (!ldb_dn_check_local(module, msg->dn)) { - return ldb_next_request(module, req); - } - - /* No mapping needed, skip to next module */ - /* TODO: What if the remote part exists, the local doesn't, - * and this request wants to modify local data and thus - * add the local record? */ - if (!ldb_msg_check_remote(module, msg)) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* Prepare context and handle */ - h = map_init_handle(req, module); - if (h == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - ac = talloc_get_type(h->private_data, struct map_context); - - /* Prepare the local operation */ - ac->local_req = talloc(ac, struct ldb_request); - if (ac->local_req == NULL) { - goto oom; - } - - *(ac->local_req) = *req; /* copy the request */ - - ac->local_req->context = NULL; - ac->local_req->callback = NULL; - - /* Prepare the remote operation */ - ac->remote_req = talloc(ac, struct ldb_request); - if (ac->remote_req == NULL) { - goto oom; - } - - *(ac->remote_req) = *req; /* copy the request */ - - ac->remote_req->context = NULL; - ac->remote_req->callback = NULL; - - /* Prepare the local message */ - local = ldb_msg_new(ac->local_req); - if (local == NULL) { - goto oom; - } - local->dn = msg->dn; - - /* Prepare the remote message */ - remote = ldb_msg_new(ac->remote_req); - if (remote == NULL) { - goto oom; - } - remote->dn = ldb_dn_map_local(ac->module, remote, msg->dn); - - /* Split local from remote message */ - ldb_msg_partition(module, local, remote, msg); - ac->local_req->op.mod.message = local; - ac->remote_req->op.mod.message = remote; - - if ((local->num_elements == 0) || (!map_check_local_db(ac->module))) { - /* No local data or db, just run the remote request */ - talloc_free(ac->local_req); - req->handle = h; /* return our own handle to deal with this call */ - return map_modify_do_remote(h); - } - - /* prepare the search operation */ - ac->search_req = map_search_self_req(ac, msg->dn); - if (ac->search_req == NULL) { - goto failed; - } - - ac->step = MAP_SEARCH_SELF_MODIFY; - - req->handle = h; /* return our own handle to deal with this call */ - return ldb_next_request(module, ac->search_req); - -oom: - map_oom(module); -failed: - talloc_free(h); - return LDB_ERR_OPERATIONS_ERROR; -} - -/* Delete the remote record. */ -int map_delete_do_remote(struct ldb_handle *handle) -{ - struct map_context *ac; - - ac = talloc_get_type(handle->private_data, struct map_context); - - ldb_set_timeout_from_prev_req(ac->module->ldb, ac->orig_req, ac->remote_req); - - ac->step = MAP_DELETE_REMOTE; - - handle->state = LDB_ASYNC_INIT; - handle->status = LDB_SUCCESS; - - return ldb_next_remote_request(ac->module, ac->remote_req); -} - -/* Delete the local record. */ -int map_delete_do_local(struct ldb_handle *handle) -{ - struct map_context *ac; - - ac = talloc_get_type(handle->private_data, struct map_context); - - /* No local record, continue remotely */ - if (ac->local_dn == NULL) { - return map_delete_do_remote(handle); - } - - ldb_set_timeout_from_prev_req(ac->module->ldb, ac->orig_req, ac->local_req); - - ac->step = MAP_DELETE_LOCAL; - - handle->state = LDB_ASYNC_INIT; - handle->status = LDB_SUCCESS; - - return ldb_next_request(ac->module, ac->local_req); -} - -/* Delete a record. */ -int map_delete(struct ldb_module *module, struct ldb_request *req) -{ - struct ldb_handle *h; - struct map_context *ac; - - /* Do not manipulate our control entries */ - if (ldb_dn_is_special(req->op.del.dn)) { - return ldb_next_request(module, req); - } - - /* No mapping requested (perhaps no DN mapping specified), skip to next module */ - if (!ldb_dn_check_local(module, req->op.del.dn)) { - return ldb_next_request(module, req); - } - - /* Prepare context and handle */ - h = map_init_handle(req, module); - if (h == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - ac = talloc_get_type(h->private_data, struct map_context); - - /* Prepare the local operation */ - ac->local_req = talloc(ac, struct ldb_request); - if (ac->local_req == NULL) { - goto oom; - } - - *(ac->local_req) = *req; /* copy the request */ - ac->local_req->op.del.dn = req->op.del.dn; - - ac->local_req->context = NULL; - ac->local_req->callback = NULL; - - /* Prepare the remote operation */ - ac->remote_req = talloc(ac, struct ldb_request); - if (ac->remote_req == NULL) { - goto oom; - } - - *(ac->remote_req) = *req; /* copy the request */ - ac->remote_req->op.del.dn = ldb_dn_map_local(module, ac->remote_req, req->op.del.dn); - - /* No local db, just run the remote request */ - if (!map_check_local_db(ac->module)) { - req->handle = h; /* return our own handle to deal with this call */ - return map_delete_do_remote(h); - } - - ac->remote_req->context = NULL; - ac->remote_req->callback = NULL; - - /* Prepare the search operation */ - ac->search_req = map_search_self_req(ac, req->op.del.dn); - if (ac->search_req == NULL) { - goto failed; - } - - req->handle = h; /* return our own handle to deal with this call */ - - ac->step = MAP_SEARCH_SELF_DELETE; - - return ldb_next_request(module, ac->search_req); - -oom: - map_oom(module); -failed: - talloc_free(h); - return LDB_ERR_OPERATIONS_ERROR; -} - -/* Rename the remote record. */ -int map_rename_do_remote(struct ldb_handle *handle) -{ - struct map_context *ac; - - ac = talloc_get_type(handle->private_data, struct map_context); - - ldb_set_timeout_from_prev_req(ac->module->ldb, ac->orig_req, ac->remote_req); - - ac->step = MAP_RENAME_REMOTE; - - handle->state = LDB_ASYNC_INIT; - handle->status = LDB_SUCCESS; - - return ldb_next_remote_request(ac->module, ac->remote_req); -} - -/* Update the local 'IS_MAPPED' attribute. */ -int map_rename_do_fixup(struct ldb_handle *handle) -{ - struct map_context *ac; - - ac = talloc_get_type(handle->private_data, struct map_context); - - ldb_set_timeout_from_prev_req(ac->module->ldb, ac->orig_req, ac->down_req); - - ac->step = MAP_RENAME_FIXUP; - - handle->state = LDB_ASYNC_INIT; - handle->status = LDB_SUCCESS; - - return ldb_next_request(ac->module, ac->down_req); -} - -/* Rename the local record. */ -int map_rename_do_local(struct ldb_handle *handle) -{ - struct map_context *ac; - - ac = talloc_get_type(handle->private_data, struct map_context); - - /* No local record, continue remotely */ - if (ac->local_dn == NULL) { - return map_rename_do_remote(handle); - } - - ldb_set_timeout_from_prev_req(ac->module->ldb, ac->orig_req, ac->local_req); - - ac->step = MAP_RENAME_LOCAL; - - handle->state = LDB_ASYNC_INIT; - handle->status = LDB_SUCCESS; - - return ldb_next_request(ac->module, ac->local_req); -} - -/* Rename a record. */ -int map_rename(struct ldb_module *module, struct ldb_request *req) -{ - struct ldb_handle *h; - struct map_context *ac; - - /* Do not manipulate our control entries */ - if (ldb_dn_is_special(req->op.rename.olddn)) { - return ldb_next_request(module, req); - } - - /* No mapping requested (perhaps no DN mapping specified), skip to next module */ - if ((!ldb_dn_check_local(module, req->op.rename.olddn)) && - (!ldb_dn_check_local(module, req->op.rename.newdn))) { - return ldb_next_request(module, req); - } - - /* Rename into/out of the mapped partition requested, bail out */ - if (!ldb_dn_check_local(module, req->op.rename.olddn) || - !ldb_dn_check_local(module, req->op.rename.newdn)) { - return LDB_ERR_AFFECTS_MULTIPLE_DSAS; - } - - /* Prepare context and handle */ - h = map_init_handle(req, module); - if (h == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - ac = talloc_get_type(h->private_data, struct map_context); - - /* Prepare the local operation */ - ac->local_req = talloc(ac, struct ldb_request); - if (ac->local_req == NULL) { - goto oom; - } - - *(ac->local_req) = *req; /* copy the request */ - ac->local_req->op.rename.olddn = req->op.rename.olddn; - ac->local_req->op.rename.newdn = req->op.rename.newdn; - - ac->local_req->context = NULL; - ac->local_req->callback = NULL; - - /* Prepare the remote operation */ - ac->remote_req = talloc(ac, struct ldb_request); - if (ac->remote_req == NULL) { - goto oom; - } - - *(ac->remote_req) = *req; /* copy the request */ - ac->remote_req->op.rename.olddn = ldb_dn_map_local(module, ac->remote_req, req->op.rename.olddn); - ac->remote_req->op.rename.newdn = ldb_dn_map_local(module, ac->remote_req, req->op.rename.newdn); - - ac->remote_req->context = NULL; - ac->remote_req->callback = NULL; - - /* No local db, just run the remote request */ - if (!map_check_local_db(ac->module)) { - req->handle = h; /* return our own handle to deal with this call */ - return map_rename_do_remote(h); - } - - /* Prepare the fixup operation */ - /* TODO: use GUIDs here instead -- or skip it when GUIDs are used. */ - ac->down_req = map_build_fixup_req(ac, req->op.rename.newdn, ac->remote_req->op.rename.newdn); - if (ac->down_req == NULL) { - goto failed; - } - - /* Prepare the search operation */ - ac->search_req = map_search_self_req(ac, req->op.rename.olddn); - if (ac->search_req == NULL) { - goto failed; - } - - req->handle = h; /* return our own handle to deal with this call */ - - ac->step = MAP_SEARCH_SELF_RENAME; - - return ldb_next_request(module, ac->search_req); - -oom: - map_oom(module); -failed: - talloc_free(h); - return LDB_ERR_OPERATIONS_ERROR; -} diff --git a/source/lib/ldb/modules/ldb_map_outbound.c b/source/lib/ldb/modules/ldb_map_outbound.c deleted file mode 100644 index 6305e6666fe..00000000000 --- a/source/lib/ldb/modules/ldb_map_outbound.c +++ /dev/null @@ -1,1286 +0,0 @@ -/* - ldb database mapping module - - Copyright (C) Jelmer Vernooij 2005 - Copyright (C) Martin Kuehl <mkhl@samba.org> 2006 - Copyright (C) Andrew Bartlett <abartlet@samba.org> 2006 - - * NOTICE: this module is NOT released under the GNU LGPL license as - * other ldb code. This module is release under the GNU GPL v2 or - * later license. - - 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. -*/ - -#include "includes.h" -#include "ldb/include/includes.h" - -#include "ldb/modules/ldb_map.h" -#include "ldb/modules/ldb_map_private.h" - - -/* Mapping attributes - * ================== */ - -/* Select attributes that stay in the local partition. */ -static const char **map_attrs_select_local(struct ldb_module *module, void *mem_ctx, const char * const *attrs) -{ - const struct ldb_map_context *data = map_get_context(module); - const char **result; - int i, last; - - if (attrs == NULL) - return NULL; - - last = 0; - result = talloc_array(mem_ctx, const char *, 1); - if (result == NULL) { - goto failed; - } - result[0] = NULL; - - for (i = 0; attrs[i]; i++) { - /* Wildcards and ignored attributes are kept locally */ - if ((ldb_attr_cmp(attrs[i], "*") == 0) || - (!map_attr_check_remote(data, attrs[i]))) { - result = talloc_realloc(mem_ctx, result, const char *, last+2); - if (result == NULL) { - goto failed; - } - - result[last] = talloc_strdup(result, attrs[i]); - result[last+1] = NULL; - last++; - } - } - - return result; - -failed: - talloc_free(result); - map_oom(module); - return NULL; -} - -/* Collect attributes that are mapped into the remote partition. */ -static const char **map_attrs_collect_remote(struct ldb_module *module, void *mem_ctx, - const char * const *attrs) -{ - const struct ldb_map_context *data = map_get_context(module); - const char **result; - const struct ldb_map_attribute *map; - const char *name=NULL; - int i, j, last; - int ret; - - last = 0; - result = talloc_array(mem_ctx, const char *, 1); - if (result == NULL) { - goto failed; - } - result[0] = NULL; - - for (i = 0; attrs[i]; i++) { - /* Wildcards are kept remotely, too */ - if (ldb_attr_cmp(attrs[i], "*") == 0) { - const char **new_attrs = NULL; - ret = map_attrs_merge(module, mem_ctx, &new_attrs, attrs); - if (ret != LDB_SUCCESS) { - goto failed; - } - ret = map_attrs_merge(module, mem_ctx, &new_attrs, data->wildcard_attributes); - if (ret != LDB_SUCCESS) { - goto failed; - } - - attrs = new_attrs; - break; - } - } - - for (i = 0; attrs[i]; i++) { - /* Wildcards are kept remotely, too */ - if (ldb_attr_cmp(attrs[i], "*") == 0) { - /* Add all 'include in wildcard' attributes */ - name = attrs[i]; - goto named; - } - - /* Add remote names of mapped attrs */ - map = map_attr_find_local(data, attrs[i]); - if (map == NULL) { - continue; - } - - switch (map->type) { - case MAP_IGNORE: - continue; - - case MAP_KEEP: - name = attrs[i]; - goto named; - - case MAP_RENAME: - case MAP_CONVERT: - name = map->u.rename.remote_name; - goto named; - - case MAP_GENERATE: - /* Add all remote names of "generate" attrs */ - for (j = 0; map->u.generate.remote_names[j]; j++) { - result = talloc_realloc(mem_ctx, result, const char *, last+2); - if (result == NULL) { - goto failed; - } - - result[last] = talloc_strdup(result, map->u.generate.remote_names[j]); - result[last+1] = NULL; - last++; - } - continue; - } - - named: /* We found a single remote name, add that */ - result = talloc_realloc(mem_ctx, result, const char *, last+2); - if (result == NULL) { - goto failed; - } - - result[last] = talloc_strdup(result, name); - result[last+1] = NULL; - last++; - } - - return result; - -failed: - talloc_free(result); - map_oom(module); - return NULL; -} - -/* Split attributes that stay in the local partition from those that - * are mapped into the remote partition. */ -static int map_attrs_partition(struct ldb_module *module, void *mem_ctx, const char ***local_attrs, const char ***remote_attrs, const char * const *attrs) -{ - *local_attrs = map_attrs_select_local(module, mem_ctx, attrs); - *remote_attrs = map_attrs_collect_remote(module, mem_ctx, attrs); - - return 0; -} - -/* Mapping message elements - * ======================== */ - -/* Add an element to a message, overwriting any old identically named elements. */ -static int ldb_msg_replace(struct ldb_message *msg, const struct ldb_message_element *el) -{ - struct ldb_message_element *old; - - old = ldb_msg_find_element(msg, el->name); - - /* no local result, add as new element */ - if (old == NULL) { - if (ldb_msg_add_empty(msg, el->name, 0, &old) != 0) { - return -1; - } - talloc_free(old->name); - } - - /* copy new element */ - *old = *el; - - /* and make sure we reference the contents */ - if (!talloc_reference(msg->elements, el->name)) { - return -1; - } - if (!talloc_reference(msg->elements, el->values)) { - return -1; - } - - return 0; -} - -/* Map a message element back into the local partition. */ -static struct ldb_message_element *ldb_msg_el_map_remote(struct ldb_module *module, - void *mem_ctx, - const struct ldb_map_attribute *map, - const char *attr_name, - const struct ldb_message_element *old) -{ - struct ldb_message_element *el; - int i; - - el = talloc_zero(mem_ctx, struct ldb_message_element); - if (el == NULL) { - map_oom(module); - return NULL; - } - - el->num_values = old->num_values; - el->values = talloc_array(el, struct ldb_val, el->num_values); - if (el->values == NULL) { - talloc_free(el); - map_oom(module); - return NULL; - } - - el->name = talloc_strdup(el, attr_name); - if (el->name == NULL) { - talloc_free(el); - map_oom(module); - return NULL; - } - - for (i = 0; i < el->num_values; i++) { - el->values[i] = ldb_val_map_remote(module, el->values, map, &old->values[i]); - } - - return el; -} - -/* Merge a remote message element into a local message. */ -static int ldb_msg_el_merge(struct ldb_module *module, struct ldb_message *local, - struct ldb_message *remote, const char *attr_name) -{ - const struct ldb_map_context *data = map_get_context(module); - const struct ldb_map_attribute *map; - struct ldb_message_element *old, *el=NULL; - const char *remote_name = NULL; - - /* We handle wildcards in ldb_msg_el_merge_wildcard */ - if (ldb_attr_cmp(attr_name, "*") == 0) { - return 0; - } - - map = map_attr_find_local(data, attr_name); - - /* Unknown attribute in remote message: - * skip, attribute was probably auto-generated */ - if (map == NULL) { - return 0; - } - - switch (map->type) { - case MAP_IGNORE: - break; - case MAP_CONVERT: - remote_name = map->u.convert.remote_name; - break; - case MAP_KEEP: - remote_name = attr_name; - break; - case MAP_RENAME: - remote_name = map->u.rename.remote_name; - break; - case MAP_GENERATE: - break; - } - - switch (map->type) { - case MAP_IGNORE: - return 0; - - case MAP_CONVERT: - if (map->u.convert.convert_remote == NULL) { - ldb_debug(module->ldb, LDB_DEBUG_ERROR, "ldb_map: " - "Skipping attribute '%s': " - "'convert_remote' not set\n", - attr_name); - return 0; - } - /* fall through */ - case MAP_KEEP: - case MAP_RENAME: - old = ldb_msg_find_element(remote, remote_name); - if (old) { - el = ldb_msg_el_map_remote(module, local, map, attr_name, old); - } else { - return LDB_ERR_NO_SUCH_ATTRIBUTE; - } - break; - - case MAP_GENERATE: - if (map->u.generate.generate_local == NULL) { - ldb_debug(module->ldb, LDB_DEBUG_ERROR, "ldb_map: " - "Skipping attribute '%s': " - "'generate_local' not set\n", - attr_name); - return 0; - } - - el = map->u.generate.generate_local(module, local, attr_name, remote); - if (!el) { - /* Generation failure is probably due to lack of source attributes */ - return LDB_ERR_NO_SUCH_ATTRIBUTE; - } - break; - } - - if (el == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - return ldb_msg_replace(local, el); -} - -/* Handle wildcard parts of merging a remote message element into a local message. */ -static int ldb_msg_el_merge_wildcard(struct ldb_module *module, struct ldb_message *local, - struct ldb_message *remote) -{ - const struct ldb_map_context *data = map_get_context(module); - const struct ldb_map_attribute *map = map_attr_find_local(data, "*"); - struct ldb_message_element *el=NULL; - int i, ret; - - /* Perhaps we have a mapping for "*" */ - if (map && map->type == MAP_KEEP) { - /* We copy everything over, and hope that anything with a - more specific rule is overwritten */ - for (i = 0; i < remote->num_elements; i++) { - el = ldb_msg_el_map_remote(module, local, map, remote->elements[i].name, - &remote->elements[i]); - if (el == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldb_msg_replace(local, el); - if (ret) { - return ret; - } - } - } - - /* Now walk the list of possible mappings, and apply each */ - for (i = 0; data->attribute_maps[i].local_name; i++) { - ret = ldb_msg_el_merge(module, local, remote, - data->attribute_maps[i].local_name); - if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) { - continue; - } else if (ret) { - return ret; - } else { - continue; - } - } - - return 0; -} - -/* Mapping messages - * ================ */ - -/* Merge two local messages into a single one. */ -static int ldb_msg_merge_local(struct ldb_module *module, struct ldb_message *msg1, struct ldb_message *msg2) -{ - int i, ret; - - for (i = 0; i < msg2->num_elements; i++) { - ret = ldb_msg_replace(msg1, &msg2->elements[i]); - if (ret) { - return ret; - } - } - - return 0; -} - -/* Merge a local and a remote message into a single local one. */ -static int ldb_msg_merge_remote(struct map_context *ac, struct ldb_message *local, - struct ldb_message *remote) -{ - int i, ret; - const char * const *attrs = ac->all_attrs; - if (!attrs) { - ret = ldb_msg_el_merge_wildcard(ac->module, local, remote); - if (ret) { - return ret; - } - } - - for (i = 0; attrs && attrs[i]; i++) { - if (ldb_attr_cmp(attrs[i], "*") == 0) { - ret = ldb_msg_el_merge_wildcard(ac->module, local, remote); - if (ret) { - return ret; - } - break; - } - } - - /* Try to map each attribute back; - * Add to local message is possible, - * Overwrite old local attribute if necessary */ - for (i = 0; attrs && attrs[i]; i++) { - ret = ldb_msg_el_merge(ac->module, local, remote, - attrs[i]); - if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) { - } else if (ret) { - return ret; - } - } - - return 0; -} - -/* Mapping search results - * ====================== */ - -/* Map a search result back into the local partition. */ -static int map_reply_remote(struct map_context *ac, struct ldb_reply *ares) -{ - struct ldb_message *msg; - struct ldb_dn *dn; - int ret; - - /* There is no result message, skip */ - if (ares->type != LDB_REPLY_ENTRY) { - return 0; - } - - /* Create a new result message */ - msg = ldb_msg_new(ares); - if (msg == NULL) { - map_oom(ac->module); - return -1; - } - - /* Merge remote message into new message */ - ret = ldb_msg_merge_remote(ac, msg, ares->message); - if (ret) { - talloc_free(msg); - return ret; - } - - /* Create corresponding local DN */ - dn = ldb_dn_map_rebase_remote(ac->module, msg, ares->message->dn); - if (dn == NULL) { - talloc_free(msg); - return -1; - } - msg->dn = dn; - - /* Store new message with new DN as the result */ - talloc_free(ares->message); - ares->message = msg; - - return 0; -} - -/* Mapping parse trees - * =================== */ - -/* Check whether a parse tree can safely be split in two. */ -static BOOL ldb_parse_tree_check_splittable(const struct ldb_parse_tree *tree) -{ - const struct ldb_parse_tree *subtree = tree; - BOOL negate = False; - - while (subtree) { - switch (subtree->operation) { - case LDB_OP_NOT: - negate = !negate; - subtree = subtree->u.isnot.child; - continue; - - case LDB_OP_AND: - return !negate; /* if negate: False */ - - case LDB_OP_OR: - return negate; /* if negate: True */ - - default: - return True; /* simple parse tree */ - } - } - - return True; /* no parse tree */ -} - -/* Collect a list of attributes required to match a given parse tree. */ -static int ldb_parse_tree_collect_attrs(struct ldb_module *module, void *mem_ctx, const char ***attrs, const struct ldb_parse_tree *tree) -{ - const char **new_attrs; - int i, ret; - - if (tree == NULL) { - return 0; - } - - switch (tree->operation) { - case LDB_OP_OR: - case LDB_OP_AND: /* attributes stored in list of subtrees */ - for (i = 0; i < tree->u.list.num_elements; i++) { - ret = ldb_parse_tree_collect_attrs(module, mem_ctx, - attrs, tree->u.list.elements[i]); - if (ret) { - return ret; - } - } - return 0; - - case LDB_OP_NOT: /* attributes stored in single subtree */ - return ldb_parse_tree_collect_attrs(module, mem_ctx, attrs, tree->u.isnot.child); - - default: /* single attribute in tree */ - new_attrs = ldb_attr_list_copy_add(mem_ctx, *attrs, tree->u.equality.attr); - talloc_free(*attrs); - *attrs = new_attrs; - return 0; - } - - return -1; -} - -static int map_subtree_select_local(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree); - -/* Select a negated subtree that queries attributes in the local partition */ -static int map_subtree_select_local_not(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) -{ - struct ldb_parse_tree *child; - int ret; - - /* Prepare new tree */ - *new = talloc_memdup(mem_ctx, tree, sizeof(struct ldb_parse_tree)); - if (*new == NULL) { - map_oom(module); - return -1; - } - - /* Generate new subtree */ - ret = map_subtree_select_local(module, *new, &child, tree->u.isnot.child); - if (ret) { - talloc_free(*new); - return ret; - } - - /* Prune tree without subtree */ - if (child == NULL) { - talloc_free(*new); - *new = NULL; - return 0; - } - - (*new)->u.isnot.child = child; - - return ret; -} - -/* Select a list of subtrees that query attributes in the local partition */ -static int map_subtree_select_local_list(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) -{ - int i, j, ret=0; - - /* Prepare new tree */ - *new = talloc_memdup(mem_ctx, tree, sizeof(struct ldb_parse_tree)); - if (*new == NULL) { - map_oom(module); - return -1; - } - - /* Prepare list of subtrees */ - (*new)->u.list.num_elements = 0; - (*new)->u.list.elements = talloc_array(*new, struct ldb_parse_tree *, tree->u.list.num_elements); - if ((*new)->u.list.elements == NULL) { - map_oom(module); - talloc_free(*new); - return -1; - } - - /* Generate new list of subtrees */ - j = 0; - for (i = 0; i < tree->u.list.num_elements; i++) { - struct ldb_parse_tree *child; - ret = map_subtree_select_local(module, *new, &child, tree->u.list.elements[i]); - if (ret) { - talloc_free(*new); - return ret; - } - - if (child) { - (*new)->u.list.elements[j] = child; - j++; - } - } - - /* Prune tree without subtrees */ - if (j == 0) { - talloc_free(*new); - *new = NULL; - return 0; - } - - /* Fix subtree list size */ - (*new)->u.list.num_elements = j; - (*new)->u.list.elements = talloc_realloc(*new, (*new)->u.list.elements, struct ldb_parse_tree *, (*new)->u.list.num_elements); - - return ret; -} - -/* Select a simple subtree that queries attributes in the local partition */ -static int map_subtree_select_local_simple(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) -{ - /* Prepare new tree */ - *new = talloc_memdup(mem_ctx, tree, sizeof(struct ldb_parse_tree)); - if (*new == NULL) { - map_oom(module); - return -1; - } - - return 0; -} - -/* Select subtrees that query attributes in the local partition */ -static int map_subtree_select_local(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) -{ - const struct ldb_map_context *data = map_get_context(module); - - if (tree == NULL) { - return 0; - } - - if (tree->operation == LDB_OP_NOT) { - return map_subtree_select_local_not(module, mem_ctx, new, tree); - } - - if (tree->operation == LDB_OP_AND || tree->operation == LDB_OP_OR) { - return map_subtree_select_local_list(module, mem_ctx, new, tree); - } - - if (map_attr_check_remote(data, tree->u.equality.attr)) { - *new = NULL; - return 0; - } - - return map_subtree_select_local_simple(module, mem_ctx, new, tree); -} - -static int map_subtree_collect_remote(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree); - -/* Collect a negated subtree that queries attributes in the remote partition */ -static int map_subtree_collect_remote_not(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) -{ - struct ldb_parse_tree *child; - int ret; - - /* Prepare new tree */ - *new = talloc_memdup(mem_ctx, tree, sizeof(struct ldb_parse_tree)); - if (*new == NULL) { - map_oom(module); - return -1; - } - - /* Generate new subtree */ - ret = map_subtree_collect_remote(module, *new, &child, tree->u.isnot.child); - if (ret) { - talloc_free(*new); - return ret; - } - - /* Prune tree without subtree */ - if (child == NULL) { - talloc_free(*new); - *new = NULL; - return 0; - } - - (*new)->u.isnot.child = child; - - return ret; -} - -/* Collect a list of subtrees that query attributes in the remote partition */ -static int map_subtree_collect_remote_list(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) -{ - int i, j, ret=0; - - /* Prepare new tree */ - *new = talloc_memdup(mem_ctx, tree, sizeof(struct ldb_parse_tree)); - if (*new == NULL) { - map_oom(module); - return -1; - } - - /* Prepare list of subtrees */ - (*new)->u.list.num_elements = 0; - (*new)->u.list.elements = talloc_array(*new, struct ldb_parse_tree *, tree->u.list.num_elements); - if ((*new)->u.list.elements == NULL) { - map_oom(module); - talloc_free(*new); - return -1; - } - - /* Generate new list of subtrees */ - j = 0; - for (i = 0; i < tree->u.list.num_elements; i++) { - struct ldb_parse_tree *child; - ret = map_subtree_collect_remote(module, *new, &child, tree->u.list.elements[i]); - if (ret) { - talloc_free(*new); - return ret; - } - - if (child) { - (*new)->u.list.elements[j] = child; - j++; - } - } - - /* Prune tree without subtrees */ - if (j == 0) { - talloc_free(*new); - *new = NULL; - return 0; - } - - /* Fix subtree list size */ - (*new)->u.list.num_elements = j; - (*new)->u.list.elements = talloc_realloc(*new, (*new)->u.list.elements, struct ldb_parse_tree *, (*new)->u.list.num_elements); - - return ret; -} - -/* Collect a simple subtree that queries attributes in the remote partition */ -int map_subtree_collect_remote_simple(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree, const struct ldb_map_attribute *map) -{ - const char *attr; - - /* Prepare new tree */ - *new = talloc(mem_ctx, struct ldb_parse_tree); - if (*new == NULL) { - map_oom(module); - return -1; - } - **new = *tree; - - if (map->type == MAP_KEEP) { - /* Nothing to do here */ - return 0; - } - - /* Store attribute and value in new tree */ - switch (tree->operation) { - case LDB_OP_PRESENT: - attr = map_attr_map_local(*new, map, tree->u.present.attr); - (*new)->u.present.attr = attr; - break; - case LDB_OP_SUBSTRING: - { - attr = map_attr_map_local(*new, map, tree->u.substring.attr); - (*new)->u.substring.attr = attr; - break; - } - case LDB_OP_EQUALITY: - attr = map_attr_map_local(*new, map, tree->u.equality.attr); - (*new)->u.equality.attr = attr; - break; - case LDB_OP_LESS: - case LDB_OP_GREATER: - case LDB_OP_APPROX: - attr = map_attr_map_local(*new, map, tree->u.comparison.attr); - (*new)->u.comparison.attr = attr; - break; - case LDB_OP_EXTENDED: - attr = map_attr_map_local(*new, map, tree->u.extended.attr); - (*new)->u.extended.attr = attr; - break; - default: /* unknown kind of simple subtree */ - talloc_free(*new); - return -1; - } - - if (attr == NULL) { - talloc_free(*new); - *new = NULL; - return 0; - } - - if (map->type == MAP_RENAME) { - /* Nothing more to do here, the attribute has been renamed */ - return 0; - } - - /* Store attribute and value in new tree */ - switch (tree->operation) { - case LDB_OP_PRESENT: - break; - case LDB_OP_SUBSTRING: - { - int i; - /* Map value */ - (*new)->u.substring.chunks = NULL; - for (i=0; tree->u.substring.chunks[i]; i++) { - (*new)->u.substring.chunks = talloc_realloc(*new, (*new)->u.substring.chunks, struct ldb_val *, i+2); - if (!(*new)->u.substring.chunks) { - talloc_free(*new); - *new = NULL; - return 0; - } - (*new)->u.substring.chunks[i] = talloc(*new, struct ldb_val); - if (!(*new)->u.substring.chunks[i]) { - talloc_free(*new); - *new = NULL; - return 0; - } - *(*new)->u.substring.chunks[i] = ldb_val_map_local(module, *new, map, tree->u.substring.chunks[i]); - (*new)->u.substring.chunks[i+1] = NULL; - } - break; - } - case LDB_OP_EQUALITY: - (*new)->u.equality.value = ldb_val_map_local(module, *new, map, &tree->u.equality.value); - break; - case LDB_OP_LESS: - case LDB_OP_GREATER: - case LDB_OP_APPROX: - (*new)->u.comparison.value = ldb_val_map_local(module, *new, map, &tree->u.comparison.value); - break; - case LDB_OP_EXTENDED: - (*new)->u.extended.value = ldb_val_map_local(module, *new, map, &tree->u.extended.value); - (*new)->u.extended.rule_id = talloc_strdup(*new, tree->u.extended.rule_id); - break; - default: /* unknown kind of simple subtree */ - talloc_free(*new); - return -1; - } - - return 0; -} - -/* Collect subtrees that query attributes in the remote partition */ -static int map_subtree_collect_remote(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) -{ - const struct ldb_map_context *data = map_get_context(module); - const struct ldb_map_attribute *map; - - if (tree == NULL) { - return 0; - } - - if (tree->operation == LDB_OP_NOT) { - return map_subtree_collect_remote_not(module, mem_ctx, new, tree); - } - - if ((tree->operation == LDB_OP_AND) || (tree->operation == LDB_OP_OR)) { - return map_subtree_collect_remote_list(module, mem_ctx, new, tree); - } - - if (!map_attr_check_remote(data, tree->u.equality.attr)) { - *new = NULL; - return 0; - } - - map = map_attr_find_local(data, tree->u.equality.attr); - if (map->convert_operator) { - return map->convert_operator(module, mem_ctx, new, tree); - } - - if (map->type == MAP_GENERATE) { - ldb_debug(module->ldb, LDB_DEBUG_WARNING, "ldb_map: " - "Skipping attribute '%s': " - "'convert_operator' not set\n", - tree->u.equality.attr); - *new = NULL; - return 0; - } - - return map_subtree_collect_remote_simple(module, mem_ctx, new, tree, map); -} - -/* Split subtrees that query attributes in the local partition from - * those that query the remote partition. */ -static int ldb_parse_tree_partition(struct ldb_module *module, void *local_ctx, void *remote_ctx, struct ldb_parse_tree **local_tree, struct ldb_parse_tree **remote_tree, const struct ldb_parse_tree *tree) -{ - int ret; - - *local_tree = NULL; - *remote_tree = NULL; - - /* No original tree */ - if (tree == NULL) { - return 0; - } - - /* Generate local tree */ - ret = map_subtree_select_local(module, local_ctx, local_tree, tree); - if (ret) { - return ret; - } - - /* Generate remote tree */ - ret = map_subtree_collect_remote(module, remote_ctx, remote_tree, tree); - if (ret) { - talloc_free(*local_tree); - return ret; - } - - return 0; -} - -/* Collect a list of attributes required either explicitly from a - * given list or implicitly from a given parse tree; split the - * collected list into local and remote parts. */ -static int map_attrs_collect_and_partition(struct ldb_module *module, struct map_context *ac, - const char * const *search_attrs, - const struct ldb_parse_tree *tree) -{ - void *tmp_ctx; - const char **tree_attrs; - const char **remote_attrs; - const char **local_attrs; - int ret; - - /* Clear initial lists of partitioned attributes */ - - /* Clear initial lists of partitioned attributes */ - - /* There is no tree, just partition the searched attributes */ - if (tree == NULL) { - ret = map_attrs_partition(module, ac, - &local_attrs, &remote_attrs, search_attrs); - if (ret == 0) { - ac->local_attrs = local_attrs; - ac->remote_attrs = remote_attrs; - ac->all_attrs = search_attrs; - } - return ret; - } - - /* Create context for temporary memory */ - tmp_ctx = talloc_new(ac); - if (tmp_ctx == NULL) { - goto oom; - } - - /* Prepare list of attributes from tree */ - tree_attrs = talloc_array(tmp_ctx, const char *, 1); - if (tree_attrs == NULL) { - talloc_free(tmp_ctx); - goto oom; - } - tree_attrs[0] = NULL; - - /* Collect attributes from tree */ - ret = ldb_parse_tree_collect_attrs(module, tmp_ctx, &tree_attrs, tree); - if (ret) { - goto done; - } - - /* Merge attributes from search operation */ - ret = map_attrs_merge(module, tmp_ctx, &tree_attrs, search_attrs); - if (ret) { - goto done; - } - - /* Split local from remote attributes */ - ret = map_attrs_partition(module, ac, &local_attrs, - &remote_attrs, tree_attrs); - - if (ret == 0) { - ac->local_attrs = local_attrs; - ac->remote_attrs = remote_attrs; - talloc_steal(ac, tree_attrs); - ac->all_attrs = tree_attrs; - } -done: - /* Free temporary memory */ - talloc_free(tmp_ctx); - return ret; - -oom: - map_oom(module); - return -1; -} - - -/* Outbound requests: search - * ========================= */ - -/* Pass a merged search result up the callback chain. */ -int map_up_callback(struct ldb_context *ldb, const struct ldb_request *req, struct ldb_reply *ares) -{ - int i; - - /* No callback registered, stop */ - if (req->callback == NULL) { - return LDB_SUCCESS; - } - - /* Only records need special treatment */ - if (ares->type != LDB_REPLY_ENTRY) { - return req->callback(ldb, req->context, ares); - } - - /* Merged result doesn't match original query, skip */ - if (!ldb_match_msg(ldb, ares->message, req->op.search.tree, req->op.search.base, req->op.search.scope)) { - ldb_debug(ldb, LDB_DEBUG_TRACE, "ldb_map: " - "Skipping record '%s': " - "doesn't match original search\n", - ldb_dn_linearize(ldb, ares->message->dn)); - return LDB_SUCCESS; - } - - /* Limit result to requested attrs */ - if ((req->op.search.attrs) && (!ldb_attr_in_list(req->op.search.attrs, "*"))) { - for (i = 0; i < ares->message->num_elements; ) { - struct ldb_message_element *el = &ares->message->elements[i]; - if (!ldb_attr_in_list(req->op.search.attrs, el->name)) { - ldb_msg_remove_element(ares->message, el); - } else { - i++; - } - } - } - - return req->callback(ldb, req->context, ares); -} - -/* Merge the remote and local parts of a search result. */ -int map_local_merge_callback(struct ldb_context *ldb, void *context, struct ldb_reply *ares) -{ - struct map_search_context *sc; - int ret; - - if (context == NULL || ares == NULL) { - ldb_set_errstring(ldb, talloc_asprintf(ldb, "ldb_map: " - "NULL Context or Result in `map_local_merge_callback`")); - return LDB_ERR_OPERATIONS_ERROR; - } - - sc = talloc_get_type(context, struct map_search_context); - - switch (ares->type) { - case LDB_REPLY_ENTRY: - /* We have already found a local record */ - if (sc->local_res) { - ldb_set_errstring(ldb, talloc_asprintf(ldb, "ldb_map: " - "Too many results to base search for local entry")); - talloc_free(ares); - return LDB_ERR_OPERATIONS_ERROR; - } - - /* Store local result */ - sc->local_res = ares; - - /* Merge remote into local message */ - ret = ldb_msg_merge_local(sc->ac->module, ares->message, sc->remote_res->message); - if (ret) { - talloc_free(ares); - return LDB_ERR_OPERATIONS_ERROR; - } - - return map_up_callback(ldb, sc->ac->orig_req, ares); - - case LDB_REPLY_DONE: - /* No local record found, continue with remote record */ - if (sc->local_res == NULL) { - return map_up_callback(ldb, sc->ac->orig_req, sc->remote_res); - } - return LDB_SUCCESS; - - default: - ldb_set_errstring(ldb, talloc_asprintf(ldb, "ldb_map: " - "Unexpected result type in base search for local entry")); - talloc_free(ares); - return LDB_ERR_OPERATIONS_ERROR; - } -} - -/* Search the local part of a remote search result. */ -int map_remote_search_callback(struct ldb_context *ldb, void *context, struct ldb_reply *ares) -{ - struct map_context *ac; - struct map_search_context *sc; - struct ldb_request *req; - int ret; - - if (context == NULL || ares == NULL) { - ldb_set_errstring(ldb, talloc_asprintf(ldb, "ldb_map: " - "NULL Context or Result in `map_remote_search_callback`")); - return LDB_ERR_OPERATIONS_ERROR; - } - - ac = talloc_get_type(context, struct map_context); - - /* It's not a record, stop searching */ - if (ares->type != LDB_REPLY_ENTRY) { - return map_up_callback(ldb, ac->orig_req, ares); - } - - /* Map result record into a local message */ - ret = map_reply_remote(ac, ares); - if (ret) { - talloc_free(ares); - return LDB_ERR_OPERATIONS_ERROR; - } - - /* There is no local db, stop searching */ - if (!map_check_local_db(ac->module)) { - return map_up_callback(ldb, ac->orig_req, ares); - } - - /* Prepare local search context */ - sc = map_init_search_context(ac, ares); - if (sc == NULL) { - talloc_free(ares); - return LDB_ERR_OPERATIONS_ERROR; - } - - /* Prepare local search request */ - /* TODO: use GUIDs here instead? */ - - ac->search_reqs = talloc_realloc(ac, ac->search_reqs, struct ldb_request *, ac->num_searches + 2); - if (ac->search_reqs == NULL) { - talloc_free(ares); - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->search_reqs[ac->num_searches] - = req = map_search_base_req(ac, ares->message->dn, - NULL, NULL, sc, map_local_merge_callback); - if (req == NULL) { - talloc_free(sc); - talloc_free(ares); - return LDB_ERR_OPERATIONS_ERROR; - } - ac->num_searches++; - ac->search_reqs[ac->num_searches] = NULL; - - return ldb_next_request(ac->module, req); -} - -/* Search a record. */ -int map_search(struct ldb_module *module, struct ldb_request *req) -{ - struct ldb_handle *h; - struct map_context *ac; - struct ldb_parse_tree *local_tree, *remote_tree; - int ret; - - const char *wildcard[] = { "*", NULL }; - const char * const *attrs; - - /* Do not manipulate our control entries */ - if (ldb_dn_is_special(req->op.search.base)) - return ldb_next_request(module, req); - - /* No mapping requested, skip to next module */ - if ((req->op.search.base) && (!ldb_dn_check_local(module, req->op.search.base))) { - return ldb_next_request(module, req); - } - - /* TODO: How can we be sure about which partition we are - * targetting when there is no search base? */ - - /* Prepare context and handle */ - h = map_init_handle(req, module); - if (h == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - ac = talloc_get_type(h->private_data, struct map_context); - - ac->search_reqs = talloc_array(ac, struct ldb_request *, 2); - if (ac->search_reqs == NULL) { - talloc_free(h); - return LDB_ERR_OPERATIONS_ERROR; - } - ac->num_searches = 1; - ac->search_reqs[1] = NULL; - - /* Prepare the remote operation */ - ac->search_reqs[0] = talloc(ac, struct ldb_request); - if (ac->search_reqs[0] == NULL) { - goto oom; - } - - *(ac->search_reqs[0]) = *req; /* copy the request */ - - ac->search_reqs[0]->handle = h; /* return our own handle to deal with this call */ - - ac->search_reqs[0]->context = ac; - ac->search_reqs[0]->callback = map_remote_search_callback; - - /* It is easier to deal with the two different ways of - * expressing the wildcard in the same codepath */ - attrs = req->op.search.attrs; - if (attrs == NULL) { - attrs = wildcard; - } - - /* Split local from remote attrs */ - ret = map_attrs_collect_and_partition(module, ac, - attrs, req->op.search.tree); - if (ret) { - goto failed; - } - - ac->search_reqs[0]->op.search.attrs = ac->remote_attrs; - - /* Split local from remote tree */ - ret = ldb_parse_tree_partition(module, ac, ac->search_reqs[0], - &local_tree, &remote_tree, - req->op.search.tree); - if (ret) { - goto failed; - } - - if (((local_tree != NULL) && (remote_tree != NULL)) && - (!ldb_parse_tree_check_splittable(req->op.search.tree))) { - /* The query can't safely be split, enumerate the remote partition */ - local_tree = NULL; - remote_tree = NULL; - } - - if (local_tree == NULL) { - /* Construct default local parse tree */ - local_tree = talloc_zero(ac, struct ldb_parse_tree); - if (local_tree == NULL) { - map_oom(ac->module); - goto failed; - } - - local_tree->operation = LDB_OP_PRESENT; - local_tree->u.present.attr = talloc_strdup(local_tree, IS_MAPPED); - } - if (remote_tree == NULL) { - /* Construct default remote parse tree */ - remote_tree = ldb_parse_tree(ac->search_reqs[0], NULL); - if (remote_tree == NULL) { - goto failed; - } - } - - ac->local_tree = local_tree; - ac->search_reqs[0]->op.search.tree = remote_tree; - - ldb_set_timeout_from_prev_req(module->ldb, req, ac->search_reqs[0]); - - h->state = LDB_ASYNC_INIT; - h->status = LDB_SUCCESS; - - ac->step = MAP_SEARCH_REMOTE; - - ret = ldb_next_remote_request(module, ac->search_reqs[0]); - if (ret == LDB_SUCCESS) { - req->handle = h; - } - return ret; - -oom: - map_oom(module); -failed: - talloc_free(h); - return LDB_ERR_OPERATIONS_ERROR; -} diff --git a/source/lib/ldb/modules/ldb_map_private.h b/source/lib/ldb/modules/ldb_map_private.h deleted file mode 100644 index 8a08d0a5b6f..00000000000 --- a/source/lib/ldb/modules/ldb_map_private.h +++ /dev/null @@ -1,117 +0,0 @@ - -/* A handy macro to report Out of Memory conditions */ -#define map_oom(module) ldb_set_errstring(module->ldb, talloc_asprintf(module, "Out of Memory")); - -/* The type of search callback functions */ -typedef int (*ldb_search_callback)(struct ldb_context *, void *, struct ldb_reply *); - -/* The special DN from which the local and remote base DNs are fetched */ -#define MAP_DN_NAME "@MAP" -#define MAP_DN_FROM "@FROM" -#define MAP_DN_TO "@TO" - -/* Private data structures - * ======================= */ - -/* Context data for mapped requests */ -struct map_context { - enum map_step { - MAP_SEARCH_REMOTE, - MAP_ADD_REMOTE, - MAP_ADD_LOCAL, - MAP_SEARCH_SELF_MODIFY, - MAP_MODIFY_REMOTE, - MAP_MODIFY_LOCAL, - MAP_SEARCH_SELF_DELETE, - MAP_DELETE_REMOTE, - MAP_DELETE_LOCAL, - MAP_SEARCH_SELF_RENAME, - MAP_RENAME_REMOTE, - MAP_RENAME_FIXUP, - MAP_RENAME_LOCAL - } step; - - struct ldb_module *module; - - const struct ldb_dn *local_dn; - const struct ldb_parse_tree *local_tree; - const char * const *local_attrs; - const char * const *remote_attrs; - const char * const *all_attrs; - - struct ldb_request *orig_req; - struct ldb_request *local_req; - struct ldb_request *remote_req; - struct ldb_request *down_req; - struct ldb_request *search_req; - - /* for search, we may have a lot of contexts */ - int num_searches; - struct ldb_request **search_reqs; -}; - -/* Context data for mapped search requests */ -struct map_search_context { - struct map_context *ac; - struct ldb_reply *local_res; - struct ldb_reply *remote_res; -}; - - -/* Common operations - * ================= */ - -/* The following definitions come from lib/ldb/modules/ldb_map.c */ -const struct ldb_map_context *map_get_context(struct ldb_module *module); -struct map_search_context *map_init_search_context(struct map_context *ac, struct ldb_reply *ares); -struct ldb_handle *map_init_handle(struct ldb_request *req, struct ldb_module *module); - -int ldb_next_remote_request(struct ldb_module *module, struct ldb_request *request); - -BOOL map_check_local_db(struct ldb_module *module); -BOOL map_attr_check_remote(const struct ldb_map_context *data, const char *attr); -BOOL ldb_dn_check_local(struct ldb_module *module, const struct ldb_dn *dn); - -const struct ldb_map_attribute *map_attr_find_local(const struct ldb_map_context *data, const char *name); -const struct ldb_map_attribute *map_attr_find_remote(const struct ldb_map_context *data, const char *name); - -const char *map_attr_map_local(void *mem_ctx, const struct ldb_map_attribute *map, const char *attr); -const char *map_attr_map_remote(void *mem_ctx, const struct ldb_map_attribute *map, const char *attr); -int map_attrs_merge(struct ldb_module *module, void *mem_ctx, const char ***attrs, const char * const *more_attrs); - -struct ldb_val ldb_val_map_local(struct ldb_module *module, void *mem_ctx, const struct ldb_map_attribute *map, const struct ldb_val *val); -struct ldb_val ldb_val_map_remote(struct ldb_module *module, void *mem_ctx, const struct ldb_map_attribute *map, const struct ldb_val *val); - -struct ldb_dn *ldb_dn_map_local(struct ldb_module *module, void *mem_ctx, const struct ldb_dn *dn); -struct ldb_dn *ldb_dn_map_remote(struct ldb_module *module, void *mem_ctx, const struct ldb_dn *dn); -struct ldb_dn *ldb_dn_map_rebase_remote(struct ldb_module *module, void *mem_ctx, const struct ldb_dn *dn); - -struct ldb_request *map_search_base_req(struct map_context *ac, const struct ldb_dn *dn, const char * const *attrs, const struct ldb_parse_tree *tree, void *context, ldb_search_callback callback); -struct ldb_request *map_search_self_req(struct map_context *ac, const struct ldb_dn *dn); -struct ldb_request *map_build_fixup_req(struct map_context *ac, const struct ldb_dn *olddn, const struct ldb_dn *newdn); - -int map_subtree_collect_remote_simple(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree, const struct ldb_map_attribute *map); - -/* LDB Requests - * ============ */ - -/* The following definitions come from lib/ldb/modules/ldb_map_inbound.c */ -int map_add_do_remote(struct ldb_handle *handle); -int map_add_do_local(struct ldb_handle *handle); -int map_add(struct ldb_module *module, struct ldb_request *req); - -int map_modify_do_remote(struct ldb_handle *handle); -int map_modify_do_local(struct ldb_handle *handle); -int map_modify(struct ldb_module *module, struct ldb_request *req); - -int map_delete_do_remote(struct ldb_handle *handle); -int map_delete_do_local(struct ldb_handle *handle); -int map_delete(struct ldb_module *module, struct ldb_request *req); - -int map_rename_do_remote(struct ldb_handle *handle); -int map_rename_do_fixup(struct ldb_handle *handle); -int map_rename_do_local(struct ldb_handle *handle); -int map_rename(struct ldb_module *module, struct ldb_request *req); - -/* The following definitions come from lib/ldb/modules/ldb_map_outbound.c */ -int map_search(struct ldb_module *module, struct ldb_request *req); diff --git a/source/lib/ldb/modules/objectclass.c b/source/lib/ldb/modules/objectclass.c deleted file mode 100644 index 191238f9c95..00000000000 --- a/source/lib/ldb/modules/objectclass.c +++ /dev/null @@ -1,694 +0,0 @@ -/* - ldb database library - - Copyright (C) Simo Sorce 2006 - Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005-2006 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - * Name: ldb - * - * Component: objectClass sorting module - * - * Description: sort the objectClass attribute into the class hierarchy - * - * Author: Andrew Bartlett - */ - -#include "includes.h" -#include "ldb/include/includes.h" - -struct oc_context { - - enum oc_step {OC_DO_REQ, OC_SEARCH_SELF, OC_DO_MOD} step; - - struct ldb_module *module; - struct ldb_request *orig_req; - - struct ldb_request *down_req; - - struct ldb_request *search_req; - struct ldb_reply *search_res; - - struct ldb_request *mod_req; -}; - -struct class_list { - struct class_list *prev, *next; - const char *objectclass; -}; - -static struct ldb_handle *oc_init_handle(struct ldb_request *req, struct ldb_module *module) -{ - struct oc_context *ac; - struct ldb_handle *h; - - h = talloc_zero(req, struct ldb_handle); - if (h == NULL) { - ldb_set_errstring(module->ldb, "Out of Memory"); - return NULL; - } - - h->module = module; - - ac = talloc_zero(h, struct oc_context); - if (ac == NULL) { - ldb_set_errstring(module->ldb, "Out of Memory"); - talloc_free(h); - return NULL; - } - - h->private_data = (void *)ac; - - h->state = LDB_ASYNC_INIT; - h->status = LDB_SUCCESS; - - ac->module = module; - ac->orig_req = req; - - return h; -} - -static int objectclass_sort(struct ldb_module *module, - TALLOC_CTX *mem_ctx, - struct ldb_message_element *objectclass_element, - struct class_list **sorted_out) -{ - int i; - int layer; - struct class_list *sorted = NULL, *parent_class = NULL, - *subclass = NULL, *unsorted = NULL, *current, *poss_subclass; - /* DESIGN: - * - * We work on 4 different 'bins' (implemented here as linked lists): - * - * * sorted: the eventual list, in the order we wish to push - * into the database. This is the only ordered list. - * - * * parent_class: The current parent class 'bin' we are - * trying to find subclasses for - * - * * subclass: The subclasses we have found so far - * - * * unsorted: The remaining objectClasses - * - * The process is a matter of filtering objectClasses up from - * unsorted into sorted. Order is irrelevent in the later 3 'bins'. - * - * We start with 'top' (found and promoted to parent_class - * initially). Then we find (in unsorted) all the direct - * subclasses of 'top'. parent_classes is concatenated onto - * the end of 'sorted', and subclass becomes the list in - * parent_class. - * - * We then repeat, until we find no more subclasses. Any left - * over classes are added to the end. - * - */ - - /* Firstly, dump all the objectClass elements into the - * unsorted bin, except for 'top', which is special */ - for (i=0; i < objectclass_element->num_values; i++) { - current = talloc(mem_ctx, struct class_list); - if (!current) { - ldb_set_errstring(module->ldb, "objectclass: out of memory allocating objectclass list"); - talloc_free(mem_ctx); - return LDB_ERR_OPERATIONS_ERROR; - } - current->objectclass = (const char *)objectclass_element->values[i].data; - - /* this is the root of the tree. We will start - * looking for subclasses from here */ - if (ldb_attr_cmp("top", current->objectclass) == 0) { - DLIST_ADD(parent_class, current); - } else { - DLIST_ADD(unsorted, current); - } - } - - /* DEBUGGING aid: how many layers are we down now? */ - layer = 0; - do { - layer++; - /* Find all the subclasses of classes in the - * parent_classes. Push them onto the subclass list */ - - /* Ensure we don't bother if there are no unsorted entries left */ - for (current = parent_class; unsorted && current; current = current->next) { - const char **subclasses = ldb_subclass_list(module->ldb, current->objectclass); - - /* Walk the list of possible subclasses in unsorted */ - for (poss_subclass = unsorted; poss_subclass; ) { - struct class_list *next; - - /* Save the next pointer, as the DLIST_ macros will change poss_subclass->next */ - next = poss_subclass->next; - - for (i = 0; subclasses && subclasses[i]; i++) { - if (ldb_attr_cmp(poss_subclass->objectclass, subclasses[i]) == 0) { - DLIST_REMOVE(unsorted, poss_subclass); - DLIST_ADD(subclass, poss_subclass); - - break; - } - } - poss_subclass = next; - } - } - - /* Now push the parent_classes as sorted, we are done with - these. Add to the END of the list by concatenation */ - DLIST_CONCATENATE(sorted, parent_class, struct class_list *); - - /* and now find subclasses of these */ - parent_class = subclass; - subclass = NULL; - - /* If we didn't find any subclasses we will fall out - * the bottom here */ - } while (parent_class); - - /* This shouldn't happen, and would break MMC, but we can't - * afford to loose objectClasses. Perhaps there was no 'top', - * or some other schema error? - * - * Detecting schema errors is the job of the schema module, so - * at this layer we just try not to loose data - */ - DLIST_CONCATENATE(sorted, unsorted, struct class_list *); - - *sorted_out = sorted; - return LDB_SUCCESS; -} - -static int objectclass_add(struct ldb_module *module, struct ldb_request *req) -{ - struct ldb_message_element *objectclass_element; - struct class_list *sorted, *current; - struct ldb_request *down_req; - struct ldb_message *msg; - int ret; - TALLOC_CTX *mem_ctx; - - ldb_debug(module->ldb, LDB_DEBUG_TRACE, "objectclass_add\n"); - - if (ldb_dn_is_special(req->op.add.message->dn)) { /* do not manipulate our control entries */ - return ldb_next_request(module, req); - } - - objectclass_element = ldb_msg_find_element(req->op.add.message, "objectClass"); - - /* If no part of this add has an objectClass, then we don't - * need to make any changes. cn=rootdse doesn't have an objectClass */ - if (!objectclass_element) { - return ldb_next_request(module, req); - } - - mem_ctx = talloc_new(req); - if (mem_ctx == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = objectclass_sort(module, mem_ctx, objectclass_element, &sorted); - if (ret != LDB_SUCCESS) { - return ret; - } - - /* prepare the first operation */ - down_req = talloc(req, struct ldb_request); - if (down_req == NULL) { - ldb_set_errstring(module->ldb, "Out of memory!"); - talloc_free(mem_ctx); - return LDB_ERR_OPERATIONS_ERROR; - } - - *down_req = *req; /* copy the request */ - - down_req->op.add.message = msg = ldb_msg_copy_shallow(down_req, req->op.add.message); - - if (down_req->op.add.message == NULL) { - talloc_free(mem_ctx); - return LDB_ERR_OPERATIONS_ERROR; - } - - ldb_msg_remove_attr(msg, "objectClass"); - ret = ldb_msg_add_empty(msg, "objectClass", 0, NULL); - - if (ret != LDB_SUCCESS) { - talloc_free(mem_ctx); - return ret; - } - - /* We must completely replace the existing objectClass entry, - * because we need it sorted */ - - /* Move from the linked list back into an ldb msg */ - for (current = sorted; current; current = current->next) { - ret = ldb_msg_add_string(msg, "objectClass", current->objectclass); - if (ret != LDB_SUCCESS) { - ldb_set_errstring(module->ldb, "objectclass: could not re-add sorted objectclass to modify msg"); - talloc_free(mem_ctx); - return ret; - } - } - - talloc_free(mem_ctx); - ret = ldb_msg_sanity_check(module->ldb, msg); - - if (ret != LDB_SUCCESS) { - return ret; - } - - /* go on with the call chain */ - ret = ldb_next_request(module, down_req); - - /* do not free down_req as the call results may be linked to it, - * it will be freed when the upper level request get freed */ - if (ret == LDB_SUCCESS) { - req->handle = down_req->handle; - } - return ret; -} - -static int objectclass_modify(struct ldb_module *module, struct ldb_request *req) -{ - struct ldb_message_element *objectclass_element; - struct ldb_message *msg; - ldb_debug(module->ldb, LDB_DEBUG_TRACE, "objectclass_modify\n"); - - if (ldb_dn_is_special(req->op.mod.message->dn)) { /* do not manipulate our control entries */ - return ldb_next_request(module, req); - } - - objectclass_element = ldb_msg_find_element(req->op.mod.message, "objectClass"); - - /* If no part of this touches the objectClass, then we don't - * need to make any changes. */ - /* If the only operation is the deletion of the objectClass then go on */ - if (!objectclass_element) { - return ldb_next_request(module, req); - } - - switch (objectclass_element->flags & LDB_FLAG_MOD_MASK) { - case LDB_FLAG_MOD_DELETE: - /* Delete everything? Probably totally illigal, but hey! */ - if (objectclass_element->num_values == 0) { - return ldb_next_request(module, req); - } - break; - case LDB_FLAG_MOD_REPLACE: - { - struct ldb_request *down_req; - struct class_list *sorted, *current; - TALLOC_CTX *mem_ctx; - int ret; - mem_ctx = talloc_new(req); - if (mem_ctx == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* prepare the first operation */ - down_req = talloc(req, struct ldb_request); - if (down_req == NULL) { - ldb_set_errstring(module->ldb, "Out of memory!"); - talloc_free(mem_ctx); - return LDB_ERR_OPERATIONS_ERROR; - } - - *down_req = *req; /* copy the request */ - - down_req->op.mod.message = msg = ldb_msg_copy_shallow(down_req, req->op.mod.message); - - if (down_req->op.add.message == NULL) { - talloc_free(mem_ctx); - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = objectclass_sort(module, mem_ctx, objectclass_element, &sorted); - if (ret != LDB_SUCCESS) { - return ret; - } - - /* We must completely replace the existing objectClass entry, - * because we need it sorted */ - - ldb_msg_remove_attr(msg, "objectClass"); - ret = ldb_msg_add_empty(msg, "objectClass", LDB_FLAG_MOD_REPLACE, NULL); - - if (ret != LDB_SUCCESS) { - talloc_free(mem_ctx); - return ret; - } - - /* Move from the linked list back into an ldb msg */ - for (current = sorted; current; current = current->next) { - ret = ldb_msg_add_string(msg, "objectClass", current->objectclass); - if (ret != LDB_SUCCESS) { - ldb_set_errstring(module->ldb, "objectclass: could not re-add sorted objectclass to modify msg"); - talloc_free(mem_ctx); - return ret; - } - } - - talloc_free(mem_ctx); - - ret = ldb_msg_sanity_check(module->ldb, msg); - if (ret != LDB_SUCCESS) { - talloc_free(mem_ctx); - return ret; - } - - /* go on with the call chain */ - ret = ldb_next_request(module, down_req); - - /* do not free down_req as the call results may be linked to it, - * it will be freed when the upper level request get freed */ - if (ret == LDB_SUCCESS) { - req->handle = down_req->handle; - } - return ret; - } - } - - { - struct ldb_handle *h; - struct oc_context *ac; - - h = oc_init_handle(req, module); - if (!h) { - return LDB_ERR_OPERATIONS_ERROR; - } - ac = talloc_get_type(h->private_data, struct oc_context); - - /* return or own handle to deal with this call */ - req->handle = h; - - /* prepare the first operation */ - ac->down_req = talloc(ac, struct ldb_request); - if (ac->down_req == NULL) { - ldb_set_errstring(module->ldb, "Out of memory!"); - return LDB_ERR_OPERATIONS_ERROR; - } - - *(ac->down_req) = *req; /* copy the request */ - - ac->down_req->context = NULL; - ac->down_req->callback = NULL; - ldb_set_timeout_from_prev_req(module->ldb, req, ac->down_req); - - ac->step = OC_DO_REQ; - - return ldb_next_request(module, ac->down_req); - } -} - -static int get_self_callback(struct ldb_context *ldb, void *context, struct ldb_reply *ares) -{ - struct oc_context *ac; - - if (!context || !ares) { - ldb_set_errstring(ldb, "NULL Context or Result in callback"); - return LDB_ERR_OPERATIONS_ERROR; - } - - ac = talloc_get_type(context, struct oc_context); - - /* we are interested only in the single reply (base search) we receive here */ - if (ares->type == LDB_REPLY_ENTRY) { - if (ac->search_res != NULL) { - ldb_set_errstring(ldb, "Too many results"); - talloc_free(ares); - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->search_res = talloc_move(ac, &ares); - } else { - talloc_free(ares); - } - - return LDB_SUCCESS; -} - -static int objectclass_search_self(struct ldb_handle *h) { - - struct oc_context *ac; - static const char * const attrs[] = { "objectClass", NULL }; - - ac = talloc_get_type(h->private_data, struct oc_context); - - /* prepare the search operation */ - ac->search_req = talloc_zero(ac, struct ldb_request); - if (ac->search_req == NULL) { - ldb_debug(ac->module->ldb, LDB_DEBUG_ERROR, "Out of Memory!\n"); - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->search_req->operation = LDB_SEARCH; - ac->search_req->op.search.base = ac->orig_req->op.mod.message->dn; - ac->search_req->op.search.scope = LDB_SCOPE_BASE; - ac->search_req->op.search.tree = ldb_parse_tree(ac->search_req, NULL); - if (ac->search_req->op.search.tree == NULL) { - ldb_set_errstring(ac->module->ldb, "objectclass: Internal error producing null search"); - return LDB_ERR_OPERATIONS_ERROR; - } - ac->search_req->op.search.attrs = attrs; - ac->search_req->controls = NULL; - ac->search_req->context = ac; - ac->search_req->callback = get_self_callback; - ldb_set_timeout_from_prev_req(ac->module->ldb, ac->orig_req, ac->search_req); - - ac->step = OC_SEARCH_SELF; - - return ldb_next_request(ac->module, ac->search_req); -} - -static int objectclass_do_mod(struct ldb_handle *h) { - - struct oc_context *ac; - struct ldb_message_element *objectclass_element; - struct ldb_message *msg; - TALLOC_CTX *mem_ctx; - struct class_list *sorted, *current; - int ret; - - ac = talloc_get_type(h->private_data, struct oc_context); - - mem_ctx = talloc_new(ac); - if (mem_ctx == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->mod_req = talloc(ac, struct ldb_request); - if (ac->mod_req == NULL) { - talloc_free(mem_ctx); - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->mod_req->operation = LDB_MODIFY; - ac->mod_req->controls = NULL; - ac->mod_req->context = ac; - ac->mod_req->callback = NULL; - ldb_set_timeout_from_prev_req(ac->module->ldb, ac->orig_req, ac->mod_req); - - /* use a new message structure */ - ac->mod_req->op.mod.message = msg = ldb_msg_new(ac->mod_req); - if (msg == NULL) { - ldb_set_errstring(ac->module->ldb, "objectclass: could not create new modify msg"); - talloc_free(mem_ctx); - return LDB_ERR_OPERATIONS_ERROR; - } - - /* This is now the objectClass list from the database */ - objectclass_element = ldb_msg_find_element(ac->search_res->message, - "objectClass"); - if (!objectclass_element) { - /* Where did it go? Move along now, nothing to see here */ - talloc_free(mem_ctx); - return LDB_SUCCESS; - } - - /* modify dn */ - msg->dn = ac->orig_req->op.mod.message->dn; - - ret = objectclass_sort(ac->module, mem_ctx, objectclass_element, &sorted); - if (ret != LDB_SUCCESS) { - return ret; - } - - /* We must completely replace the existing objectClass entry. - * We could do a constrained add/del, but we are meant to be - * in a transaction... */ - - ret = ldb_msg_add_empty(msg, "objectClass", LDB_FLAG_MOD_REPLACE, NULL); - if (ret != LDB_SUCCESS) { - ldb_set_errstring(ac->module->ldb, "objectclass: could not clear objectclass in modify msg"); - talloc_free(mem_ctx); - return ret; - } - - /* Move from the linked list back into an ldb msg */ - for (current = sorted; current; current = current->next) { - ret = ldb_msg_add_string(msg, "objectClass", current->objectclass); - if (ret != LDB_SUCCESS) { - ldb_set_errstring(ac->module->ldb, "objectclass: could not re-add sorted objectclass to modify msg"); - talloc_free(mem_ctx); - return ret; - } - } - - ret = ldb_msg_sanity_check(ac->module->ldb, msg); - if (ret != LDB_SUCCESS) { - talloc_free(mem_ctx); - return ret; - } - - - h->state = LDB_ASYNC_INIT; - h->status = LDB_SUCCESS; - - ac->step = OC_DO_MOD; - - talloc_free(mem_ctx); - /* perform the search */ - return ldb_next_request(ac->module, ac->mod_req); -} - -static int oc_wait(struct ldb_handle *handle) { - struct oc_context *ac; - int ret; - - if (!handle || !handle->private_data) { - return LDB_ERR_OPERATIONS_ERROR; - } - - if (handle->state == LDB_ASYNC_DONE) { - return handle->status; - } - - handle->state = LDB_ASYNC_PENDING; - handle->status = LDB_SUCCESS; - - ac = talloc_get_type(handle->private_data, struct oc_context); - - switch (ac->step) { - case OC_DO_REQ: - ret = ldb_wait(ac->down_req->handle, LDB_WAIT_NONE); - - if (ret != LDB_SUCCESS) { - handle->status = ret; - goto done; - } - if (ac->down_req->handle->status != LDB_SUCCESS) { - handle->status = ac->down_req->handle->status; - goto done; - } - - if (ac->down_req->handle->state != LDB_ASYNC_DONE) { - return LDB_SUCCESS; - } - - /* mods done, go on */ - return objectclass_search_self(handle); - - case OC_SEARCH_SELF: - ret = ldb_wait(ac->search_req->handle, LDB_WAIT_NONE); - - if (ret != LDB_SUCCESS) { - handle->status = ret; - goto done; - } - if (ac->search_req->handle->status != LDB_SUCCESS) { - handle->status = ac->search_req->handle->status; - goto done; - } - - if (ac->search_req->handle->state != LDB_ASYNC_DONE) { - return LDB_SUCCESS; - } - - /* self search done, go on */ - return objectclass_do_mod(handle); - - case OC_DO_MOD: - ret = ldb_wait(ac->mod_req->handle, LDB_WAIT_NONE); - - if (ret != LDB_SUCCESS) { - handle->status = ret; - goto done; - } - if (ac->mod_req->handle->status != LDB_SUCCESS) { - handle->status = ac->mod_req->handle->status; - goto done; - } - - if (ac->mod_req->handle->state != LDB_ASYNC_DONE) { - return LDB_SUCCESS; - } - - break; - - default: - ret = LDB_ERR_OPERATIONS_ERROR; - goto done; - } - - ret = LDB_SUCCESS; - -done: - handle->state = LDB_ASYNC_DONE; - return ret; -} - -static int oc_wait_all(struct ldb_handle *handle) { - - int ret; - - while (handle->state != LDB_ASYNC_DONE) { - ret = oc_wait(handle); - if (ret != LDB_SUCCESS) { - return ret; - } - } - - return handle->status; -} - -static int objectclass_wait(struct ldb_handle *handle, enum ldb_wait_type type) -{ - if (type == LDB_WAIT_ALL) { - return oc_wait_all(handle); - } else { - return oc_wait(handle); - } -} - -static const struct ldb_module_ops objectclass_ops = { - .name = "objectclass", - .add = objectclass_add, - .modify = objectclass_modify, - .wait = objectclass_wait -}; - -int ldb_objectclass_init(void) -{ - return ldb_register_module(&objectclass_ops); -} - diff --git a/source/lib/ldb/modules/operational.c b/source/lib/ldb/modules/operational.c deleted file mode 100644 index 953cbd593ef..00000000000 --- a/source/lib/ldb/modules/operational.c +++ /dev/null @@ -1,312 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2005 - Copyright (C) Simo Sorce 2006 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -/* - handle operational attributes - */ - -/* - createTimestamp: HIDDEN, searchable, ldaptime, alias for whenCreated - modifyTimestamp: HIDDEN, searchable, ldaptime, alias for whenChanged - - for the above two, we do the search as normal, and if - createTimestamp or modifyTimestamp is asked for, then do - additional searches for whenCreated and whenChanged and fill in - the resulting values - - we also need to replace these with the whenCreated/whenChanged - equivalent in the search expression trees - - whenCreated: not-HIDDEN, CONSTRUCTED, SEARCHABLE - whenChanged: not-HIDDEN, CONSTRUCTED, SEARCHABLE - - on init we need to setup attribute handlers for these so - comparisons are done correctly. The resolution is 1 second. - - on add we need to add both the above, for current time - - on modify we need to change whenChanged - - - subschemaSubentry: HIDDEN, not-searchable, - points at DN CN=Aggregate,CN=Schema,CN=Configuration,$BASEDN - - for this one we do the search as normal, then add the static - value if requested. How do we work out the $BASEDN from inside a - module? - - - structuralObjectClass: HIDDEN, CONSTRUCTED, not-searchable. always same as objectclass? - - for this one we do the search as normal, then if requested ask - for objectclass, change the attribute name, and add it - - allowedAttributesEffective: HIDDEN, CONSTRUCTED, not-searchable, - list of attributes that can be modified - requires schema lookup - - - attributeTypes: in schema only - objectClasses: in schema only - matchingRules: in schema only - matchingRuleUse: in schema only - creatorsName: not supported by w2k3? - modifiersName: not supported by w2k3? -*/ - -#include "includes.h" -#include "ldb/include/includes.h" - -/* - construct a canonical name from a message -*/ -static int construct_canonical_name(struct ldb_module *module, struct ldb_message *msg) -{ - char *canonicalName; - canonicalName = ldb_dn_canonical_string(msg, msg->dn); - if (canonicalName == NULL) { - return -1; - } - return ldb_msg_add_steal_string(msg, "canonicalName", canonicalName); -} - -/* - a list of attribute names that should be substituted in the parse - tree before the search is done -*/ -static const struct { - const char *attr; - const char *replace; -} parse_tree_sub[] = { - { "createTimestamp", "whenCreated" }, - { "modifyTimestamp", "whenChanged" } -}; - - -/* - a list of attribute names that are hidden, but can be searched for - using another (non-hidden) name to produce the correct result -*/ -static const struct { - const char *attr; - const char *replace; - int (*constructor)(struct ldb_module *, struct ldb_message *); -} search_sub[] = { - { "createTimestamp", "whenCreated", NULL }, - { "modifyTimestamp", "whenChanged", NULL }, - { "structuralObjectClass", "objectClass", NULL }, - { "canonicalName", "distinguishedName", construct_canonical_name } -}; - -/* - post process a search result record. For any search_sub[] attributes that were - asked for, we need to call the appropriate copy routine to copy the result - into the message, then remove any attributes that we added to the search but were - not asked for by the user -*/ -static int operational_search_post_process(struct ldb_module *module, - struct ldb_message *msg, - const char * const *attrs) -{ - int i, a=0; - - for (a=0;attrs && attrs[a];a++) { - for (i=0;i<ARRAY_SIZE(search_sub);i++) { - if (ldb_attr_cmp(attrs[a], search_sub[i].attr) != 0) { - continue; - } - - /* construct the new attribute, using either a supplied - constructor or a simple copy */ - if (search_sub[i].constructor) { - if (search_sub[i].constructor(module, msg) != 0) { - goto failed; - } - } else if (ldb_msg_copy_attr(msg, - search_sub[i].replace, - search_sub[i].attr) != 0) { - goto failed; - } - - /* remove the added search attribute, unless it was asked for - by the user */ - if (search_sub[i].replace == NULL || - ldb_attr_in_list(attrs, search_sub[i].replace) || - ldb_attr_in_list(attrs, "*")) { - continue; - } - - ldb_msg_remove_attr(msg, search_sub[i].replace); - } - } - - return 0; - -failed: - ldb_debug_set(module->ldb, LDB_DEBUG_WARNING, - "operational_search_post_process failed for attribute '%s'\n", - attrs[a]); - return -1; -} - - -/* - hook search operations -*/ - -struct operational_context { - - struct ldb_module *module; - void *up_context; - int (*up_callback)(struct ldb_context *, void *, struct ldb_reply *); - - const char * const *attrs; -}; - -static int operational_callback(struct ldb_context *ldb, void *context, struct ldb_reply *ares) -{ - struct operational_context *ac; - - if (!context || !ares) { - ldb_set_errstring(ldb, "NULL Context or Result in callback"); - goto error; - } - - ac = talloc_get_type(context, struct operational_context); - - if (ares->type == LDB_REPLY_ENTRY) { - /* for each record returned post-process to add any derived - attributes that have been asked for */ - if (operational_search_post_process(ac->module, ares->message, ac->attrs) != 0) { - goto error; - } - } - - return ac->up_callback(ldb, ac->up_context, ares); - -error: - talloc_free(ares); - return LDB_ERR_OPERATIONS_ERROR; -} - -static int operational_search(struct ldb_module *module, struct ldb_request *req) -{ - struct operational_context *ac; - struct ldb_request *down_req; - const char **search_attrs = NULL; - int i, a, ret; - - req->handle = NULL; - - ac = talloc(req, struct operational_context); - if (ac == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->module = module; - ac->up_context = req->context; - ac->up_callback = req->callback; - ac->attrs = req->op.search.attrs; - - down_req = talloc_zero(req, struct ldb_request); - if (down_req == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - down_req->operation = req->operation; - down_req->op.search.base = req->op.search.base; - down_req->op.search.scope = req->op.search.scope; - down_req->op.search.tree = req->op.search.tree; - - /* FIXME: I hink we should copy the tree and keep the original - * unmodified. SSS */ - /* replace any attributes in the parse tree that are - searchable, but are stored using a different name in the - backend */ - for (i=0;i<ARRAY_SIZE(parse_tree_sub);i++) { - ldb_parse_tree_attr_replace(discard_const_p(struct ldb_parse_tree, req->op.search.tree), - parse_tree_sub[i].attr, - parse_tree_sub[i].replace); - } - - /* in the list of attributes we are looking for, rename any - attributes to the alias for any hidden attributes that can - be fetched directly using non-hidden names */ - for (a=0;ac->attrs && ac->attrs[a];a++) { - for (i=0;i<ARRAY_SIZE(search_sub);i++) { - if (ldb_attr_cmp(ac->attrs[a], search_sub[i].attr) == 0 && - search_sub[i].replace) { - if (!search_attrs) { - search_attrs = ldb_attr_list_copy(req, ac->attrs); - if (search_attrs == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - } - search_attrs[a] = search_sub[i].replace; - } - } - } - - /* use new set of attrs if any */ - if (search_attrs) down_req->op.search.attrs = search_attrs; - else down_req->op.search.attrs = req->op.search.attrs; - - down_req->controls = req->controls; - - down_req->context = ac; - down_req->callback = operational_callback; - ldb_set_timeout_from_prev_req(module->ldb, req, down_req); - - /* perform the search */ - ret = ldb_next_request(module, down_req); - - /* do not free down_req as the call results may be linked to it, - * it will be freed when the upper level request get freed */ - if (ret == LDB_SUCCESS) { - req->handle = down_req->handle; - } - - return ret; -} - -static int operational_init(struct ldb_module *ctx) -{ - /* setup some standard attribute handlers */ - ldb_set_attrib_handler_syntax(ctx->ldb, "whenCreated", LDB_SYNTAX_UTC_TIME); - ldb_set_attrib_handler_syntax(ctx->ldb, "whenChanged", LDB_SYNTAX_UTC_TIME); - ldb_set_attrib_handler_syntax(ctx->ldb, "subschemaSubentry", LDB_SYNTAX_DN); - ldb_set_attrib_handler_syntax(ctx->ldb, "structuralObjectClass", LDB_SYNTAX_OBJECTCLASS); - - return ldb_next_init(ctx); -} - -static const struct ldb_module_ops operational_ops = { - .name = "operational", - .search = operational_search, - .init_context = operational_init -}; - -int ldb_operational_init(void) -{ - return ldb_register_module(&operational_ops); -} diff --git a/source/lib/ldb/modules/paged_results.c b/source/lib/ldb/modules/paged_results.c deleted file mode 100644 index 02d15fe8a6f..00000000000 --- a/source/lib/ldb/modules/paged_results.c +++ /dev/null @@ -1,567 +0,0 @@ -/* - ldb database library - - Copyright (C) Simo Sorce 2005-2006 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - * Name: paged_result - * - * Component: ldb paged results control module - * - * Description: this module caches a complete search and sends back - * results in chunks as asked by the client - * - * Author: Simo Sorce - */ - -#include "includes.h" -#include "ldb/include/includes.h" - -struct message_store { - /* keep the whole ldb_reply as an optimization - * instead of freeing and talloc-ing the container - * on each result */ - struct ldb_reply *r; - struct message_store *next; -}; - -struct private_data; - -struct results_store { - - struct private_data *priv; - - char *cookie; - time_t timestamp; - - struct results_store *prev; - struct results_store *next; - - struct message_store *first; - struct message_store *last; - int num_entries; - - struct message_store *first_ref; - struct message_store *last_ref; - - struct ldb_control **controls; - - struct ldb_request *req; -}; - -struct private_data { - - int next_free_id; - struct results_store *store; - -}; - -int store_destructor(struct results_store *store); - -int store_destructor(struct results_store *store) -{ - if (store->prev) { - store->prev->next = store->next; - } - if (store->next) { - store->next->prev = store->prev; - } - - if (store == store->priv->store) { - store->priv->store = NULL; - } - - return 0; -} - -static struct results_store *new_store(struct private_data *priv) -{ - struct results_store *newr; - int new_id = priv->next_free_id++; - - /* TODO: we should have a limit on the number of - * outstanding paged searches - */ - - newr = talloc(priv, struct results_store); - if (!newr) return NULL; - - newr->priv = priv; - - newr->cookie = talloc_asprintf(newr, "%d", new_id); - if (!newr->cookie) { - talloc_free(newr); - return NULL; - } - - newr->timestamp = time(NULL); - - newr->first = NULL; - newr->num_entries = 0; - newr->first_ref = NULL; - newr->controls = NULL; - - /* put this entry as first */ - newr->prev = NULL; - newr->next = priv->store; - if (priv->store != NULL) priv->store->prev = newr; - priv->store = newr; - - talloc_set_destructor(newr, store_destructor); - - return newr; -} - -struct paged_context { - struct ldb_module *module; - void *up_context; - int (*up_callback)(struct ldb_context *, void *, struct ldb_reply *); - - int size; - - struct results_store *store; -}; - -static struct ldb_handle *init_handle(void *mem_ctx, struct ldb_module *module, - void *context, - int (*callback)(struct ldb_context *, void *, struct ldb_reply *)) -{ - struct paged_context *ac; - struct ldb_handle *h; - - h = talloc_zero(mem_ctx, struct ldb_handle); - if (h == NULL) { - ldb_set_errstring(module->ldb, "Out of Memory"); - return NULL; - } - - h->module = module; - - ac = talloc_zero(h, struct paged_context); - if (ac == NULL) { - ldb_set_errstring(module->ldb, "Out of Memory"); - talloc_free(h); - return NULL; - } - - h->private_data = (void *)ac; - - h->state = LDB_ASYNC_INIT; - h->status = LDB_SUCCESS; - - ac->module = module; - ac->up_context = context; - ac->up_callback = callback; - - return h; -} - -static int paged_search_callback(struct ldb_context *ldb, void *context, struct ldb_reply *ares) -{ - struct paged_context *ac = NULL; - - if (!context || !ares) { - ldb_set_errstring(ldb, "NULL Context or Result in callback"); - goto error; - } - - ac = talloc_get_type(context, struct paged_context); - - if (ares->type == LDB_REPLY_ENTRY) { - if (ac->store->first == NULL) { - ac->store->first = ac->store->last = talloc(ac->store, struct message_store); - } else { - ac->store->last->next = talloc(ac->store, struct message_store); - ac->store->last = ac->store->last->next; - } - if (ac->store->last == NULL) { - goto error; - } - - ac->store->num_entries++; - - ac->store->last->r = talloc_steal(ac->store->last, ares); - ac->store->last->next = NULL; - } - - if (ares->type == LDB_REPLY_REFERRAL) { - if (ac->store->first_ref == NULL) { - ac->store->first_ref = ac->store->last_ref = talloc(ac->store, struct message_store); - } else { - ac->store->last_ref->next = talloc(ac->store, struct message_store); - ac->store->last_ref = ac->store->last_ref->next; - } - if (ac->store->last_ref == NULL) { - goto error; - } - - ac->store->last_ref->r = talloc_steal(ac->store->last, ares); - ac->store->last_ref->next = NULL; - } - - if (ares->type == LDB_REPLY_DONE) { - ac->store->controls = talloc_move(ac->store, &ares->controls); - talloc_free(ares); - } - - return LDB_SUCCESS; - -error: - talloc_free(ares); - return LDB_ERR_OPERATIONS_ERROR; -} - -static int paged_search(struct ldb_module *module, struct ldb_request *req) -{ - struct ldb_control *control; - struct private_data *private_data; - struct ldb_paged_control *paged_ctrl; - struct ldb_control **saved_controls; - struct paged_context *ac; - struct ldb_handle *h; - int ret; - - /* check if there's a paged request control */ - control = get_control_from_list(req->controls, LDB_CONTROL_PAGED_RESULTS_OID); - if (control == NULL) { - /* not found go on */ - return ldb_next_request(module, req); - } - - private_data = talloc_get_type(module->private_data, struct private_data); - - req->handle = NULL; - - if (!req->callback || !req->context) { - ldb_set_errstring(module->ldb, - "Async interface called with NULL callback function or NULL context"); - return LDB_ERR_OPERATIONS_ERROR; - } - - paged_ctrl = talloc_get_type(control->data, struct ldb_paged_control); - if (!paged_ctrl) { - return LDB_ERR_PROTOCOL_ERROR; - } - - h = init_handle(req, module, req->context, req->callback); - if (!h) { - return LDB_ERR_OPERATIONS_ERROR; - } - ac = talloc_get_type(h->private_data, struct paged_context); - - ac->size = paged_ctrl->size; - - /* check if it is a continuation search the store */ - if (paged_ctrl->cookie_len == 0) { - - ac->store = new_store(private_data); - if (ac->store == NULL) { - talloc_free(h); - return LDB_ERR_UNWILLING_TO_PERFORM; - } - - ac->store->req = talloc(ac->store, struct ldb_request); - if (!ac->store->req) - return LDB_ERR_OPERATIONS_ERROR; - - ac->store->req->operation = req->operation; - ac->store->req->op.search.base = req->op.search.base; - ac->store->req->op.search.scope = req->op.search.scope; - ac->store->req->op.search.tree = req->op.search.tree; - ac->store->req->op.search.attrs = req->op.search.attrs; - ac->store->req->controls = req->controls; - - /* save it locally and remove it from the list */ - /* we do not need to replace them later as we - * are keeping the original req intact */ - if (!save_controls(control, ac->store->req, &saved_controls)) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->store->req->context = ac; - ac->store->req->callback = paged_search_callback; - ldb_set_timeout_from_prev_req(module->ldb, req, ac->store->req); - - ret = ldb_next_request(module, ac->store->req); - - } else { - struct results_store *current = NULL; - - for (current = private_data->store; current; current = current->next) { - if (strcmp(current->cookie, paged_ctrl->cookie) == 0) { - current->timestamp = time(NULL); - break; - } - } - if (current == NULL) { - talloc_free(h); - return LDB_ERR_UNWILLING_TO_PERFORM; - } - - ac->store = current; - ret = LDB_SUCCESS; - } - - req->handle = h; - - /* check if it is an abandon */ - if (ac->size == 0) { - talloc_free(ac->store); - h->status = LDB_SUCCESS; - h->state = LDB_ASYNC_DONE; - return LDB_SUCCESS; - } - - /* TODO: age out old outstanding requests */ - - return ret; - -} - -static int paged_results(struct ldb_handle *handle) -{ - struct paged_context *ac; - struct ldb_paged_control *paged; - struct ldb_reply *ares; - struct message_store *msg; - int i, num_ctrls, ret; - - ac = talloc_get_type(handle->private_data, struct paged_context); - - if (ac->store == NULL) - return LDB_ERR_OPERATIONS_ERROR; - - while (ac->store->num_entries > 0 && ac->size > 0) { - msg = ac->store->first; - ret = ac->up_callback(ac->module->ldb, ac->up_context, msg->r); - if (ret != LDB_SUCCESS) { - handle->status = ret; - handle->state = LDB_ASYNC_DONE; - return ret; - } - - ac->store->first = msg->next; - talloc_free(msg); - ac->store->num_entries--; - ac->size--; - } - - handle->state = LDB_ASYNC_DONE; - - while (ac->store->first_ref != NULL) { - msg = ac->store->first_ref; - ret = ac->up_callback(ac->module->ldb, ac->up_context, msg->r); - if (ret != LDB_SUCCESS) { - handle->status = ret; - handle->state = LDB_ASYNC_DONE; - return ret; - } - - ac->store->first_ref = msg->next; - talloc_free(msg); - } - - ares = talloc_zero(ac->store, struct ldb_reply); - if (ares == NULL) { - handle->status = LDB_ERR_OPERATIONS_ERROR; - return handle->status; - } - num_ctrls = 2; - i = 0; - - if (ac->store->controls != NULL) { - ares->controls = ac->store->controls; - while (ares->controls[i]) i++; /* counting */ - - ares->controls = talloc_move(ares, &ac->store->controls); - num_ctrls += i; - } - - ares->controls = talloc_realloc(ares, ares->controls, struct ldb_control *, num_ctrls); - if (ares->controls == NULL) { - handle->status = LDB_ERR_OPERATIONS_ERROR; - return handle->status; - } - - ares->controls[i] = talloc(ares->controls, struct ldb_control); - if (ares->controls[i] == NULL) { - handle->status = LDB_ERR_OPERATIONS_ERROR; - return handle->status; - } - - ares->controls[i]->oid = talloc_strdup(ares->controls[i], LDB_CONTROL_PAGED_RESULTS_OID); - if (ares->controls[i]->oid == NULL) { - handle->status = LDB_ERR_OPERATIONS_ERROR; - return handle->status; - } - - ares->controls[i]->critical = 0; - ares->controls[i + 1] = NULL; - - paged = talloc(ares->controls[i], struct ldb_paged_control); - if (paged == NULL) { - handle->status = LDB_ERR_OPERATIONS_ERROR; - return handle->status; - } - - ares->controls[i]->data = paged; - - if (ac->size > 0) { - paged->size = 0; - paged->cookie = NULL; - paged->cookie_len = 0; - } else { - paged->size = ac->store->num_entries; - paged->cookie = talloc_strdup(paged, ac->store->cookie); - paged->cookie_len = strlen(paged->cookie) + 1; - } - - ares->type = LDB_REPLY_DONE; - - ret = ac->up_callback(ac->module->ldb, ac->up_context, ares); - - handle->status = ret; - - return ret; -} - -static int paged_wait(struct ldb_handle *handle, enum ldb_wait_type type) -{ - struct paged_context *ac; - int ret; - - if (!handle || !handle->private_data) { - return LDB_ERR_OPERATIONS_ERROR; - } - - if (handle->state == LDB_ASYNC_DONE) { - return handle->status; - } - - handle->state = LDB_ASYNC_PENDING; - - ac = talloc_get_type(handle->private_data, struct paged_context); - - if (ac->store->req->handle->state == LDB_ASYNC_DONE) { - /* if lower level is finished we do not need to call it anymore */ - /* return all we have until size == 0 or we empty storage */ - ret = paged_results(handle); - - /* we are done, if num_entries is zero free the storage - * as that mean we delivered the last batch */ - if (ac->store->num_entries == 0) { - talloc_free(ac->store); - } - - return ret; - } - - if (type == LDB_WAIT_ALL) { - while (ac->store->req->handle->state != LDB_ASYNC_DONE) { - ret = ldb_wait(ac->store->req->handle, type); - if (ret != LDB_SUCCESS) { - handle->state = LDB_ASYNC_DONE; - handle->status = ret; - return ret; - } - } - - ret = paged_results(handle); - - /* we are done, if num_entries is zero free the storage - * as that mean we delivered the last batch */ - if (ac->store->num_entries == 0) { - talloc_free(ac->store); - } - - return ret; - } - - ret = ldb_wait(ac->store->req->handle, type); - if (ret != LDB_SUCCESS) { - handle->state = LDB_ASYNC_DONE; - handle->status = ret; - return ret; - } - - handle->status = ret; - - if (ac->store->num_entries >= ac->size || - ac->store->req->handle->state == LDB_ASYNC_DONE) { - - ret = paged_results(handle); - - /* we are done, if num_entries is zero free the storage - * as that mean we delivered the last batch */ - if (ac->store->num_entries == 0) { - talloc_free(ac->store); - } - } - - return ret; -} - -static int paged_request_init(struct ldb_module *module) -{ - struct private_data *data; - struct ldb_request *req; - int ret; - - data = talloc(module, struct private_data); - if (data == NULL) { - return LDB_ERR_OTHER; - } - - data->next_free_id = 1; - data->store = NULL; - module->private_data = data; - - req = talloc(module, struct ldb_request); - if (req == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - req->operation = LDB_REQ_REGISTER_CONTROL; - req->op.reg_control.oid = LDB_CONTROL_PAGED_RESULTS_OID; - req->controls = NULL; - - ret = ldb_request(module->ldb, req); - if (ret != LDB_SUCCESS) { - ldb_debug(module->ldb, LDB_DEBUG_WARNING, "paged_request: Unable to register control with rootdse!\n"); - } - - talloc_free(req); - return ldb_next_init(module); -} - -static const struct ldb_module_ops paged_ops = { - .name = "paged_results", - .search = paged_search, - .wait = paged_wait, - .init_context = paged_request_init -}; - -int ldb_paged_results_init(void) -{ - return ldb_register_module(&paged_ops); -} - diff --git a/source/lib/ldb/modules/paged_searches.c b/source/lib/ldb/modules/paged_searches.c deleted file mode 100644 index c7d163307de..00000000000 --- a/source/lib/ldb/modules/paged_searches.c +++ /dev/null @@ -1,468 +0,0 @@ -/* - ldb database library - - Copyright (C) Simo Sorce 2005-2006 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - * Name: paged_searches - * - * Component: ldb paged searches module - * - * Description: this module detects if the remote ldap server supports - * paged results and use them to transparently access all objects - * - * Author: Simo Sorce - */ - -#include "includes.h" -#include "ldb/include/includes.h" - -#define PS_DEFAULT_PAGE_SIZE 500 -/* 500 objects per query seem to be a decent compromise - * the default AD limit per request is 1000 entries */ - -struct private_data { - - bool paged_supported; -}; - -struct ps_context { - struct ldb_module *module; - void *up_context; - int (*up_callback)(struct ldb_context *, void *, struct ldb_reply *); - - struct ldb_request *orig_req; - - struct ldb_request *new_req; - - bool pending; - - char **saved_referrals; - int num_referrals; -}; - -static struct ldb_handle *init_handle(void *mem_ctx, struct ldb_module *module, - void *context, - int (*callback)(struct ldb_context *, void *, struct ldb_reply *)) -{ - struct ps_context *ac; - struct ldb_handle *h; - - h = talloc_zero(mem_ctx, struct ldb_handle); - if (h == NULL) { - ldb_set_errstring(module->ldb, "Out of Memory"); - return NULL; - } - - h->module = module; - - ac = talloc_zero(h, struct ps_context); - if (ac == NULL) { - ldb_set_errstring(module->ldb, "Out of Memory"); - talloc_free(h); - return NULL; - } - - h->private_data = (void *)ac; - - h->state = LDB_ASYNC_INIT; - h->status = LDB_SUCCESS; - - ac->module = module; - ac->up_context = context; - ac->up_callback = callback; - - ac->pending = False; - ac->saved_referrals = NULL; - ac->num_referrals = 0; - - return h; -} - -static int check_ps_continuation(struct ldb_reply *ares, struct ps_context *ac) -{ - struct ldb_paged_control *rep_control, *req_control; - - /* look up our paged control */ - if (!ares->controls || strcmp(LDB_CONTROL_PAGED_RESULTS_OID, ares->controls[0]->oid) != 0) { - /* something wrong here */ - return LDB_ERR_OPERATIONS_ERROR; - } - - rep_control = talloc_get_type(ares->controls[0]->data, struct ldb_paged_control); - if (rep_control->cookie_len == 0) { - /* we are done */ - ac->pending = False; - return LDB_SUCCESS; - } - - /* more processing required */ - /* let's fill in the request control with the new cookie */ - /* if there's a reply control we must find a request - * control matching it */ - - if (strcmp(LDB_CONTROL_PAGED_RESULTS_OID, ac->new_req->controls[0]->oid) != 0) { - /* something wrong here */ - return LDB_ERR_OPERATIONS_ERROR; - } - - req_control = talloc_get_type(ac->new_req->controls[0]->data, struct ldb_paged_control); - - if (req_control->cookie) { - talloc_free(req_control->cookie); - } - - req_control->cookie = talloc_memdup(req_control, - rep_control->cookie, - rep_control->cookie_len); - req_control->cookie_len = rep_control->cookie_len; - - ac->pending = True; - return LDB_SUCCESS; -} - -static int store_referral(char *referral, struct ps_context *ac) -{ - ac->saved_referrals = talloc_realloc(ac, ac->saved_referrals, char *, ac->num_referrals + 2); - if (!ac->saved_referrals) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->saved_referrals[ac->num_referrals] = talloc_strdup(ac->saved_referrals, referral); - if (!ac->saved_referrals[ac->num_referrals]) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->num_referrals++; - ac->saved_referrals[ac->num_referrals] = NULL; - - return LDB_SUCCESS; -} - -static int send_referrals(struct ldb_context *ldb, struct ps_context *ac) -{ - struct ldb_reply *ares; - int i; - - for (i = 0; i < ac->num_referrals; i++) { - ares = talloc_zero(ac, struct ldb_reply); - if (!ares) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ares->type = LDB_REPLY_REFERRAL; - ares->referral = ac->saved_referrals[i]; - - ac->up_callback(ldb, ac->up_context, ares); - } - - return LDB_SUCCESS; -} - -static int ps_callback(struct ldb_context *ldb, void *context, struct ldb_reply *ares) -{ - struct ps_context *ac = NULL; - int ret = LDB_ERR_OPERATIONS_ERROR; - - if (!context || !ares) { - ldb_set_errstring(ldb, "NULL Context or Result in callback"); - goto error; - } - - ac = talloc_get_type(context, struct ps_context); - - switch (ares->type) { - case LDB_REPLY_ENTRY: - ac->up_callback(ldb, ac->up_context, ares); - break; - - case LDB_REPLY_REFERRAL: - ret = store_referral(ares->referral, ac); - if (ret != LDB_SUCCESS) { - goto error; - } - break; - - case LDB_REPLY_DONE: - ret = check_ps_continuation(ares, ac); - if (ret != LDB_SUCCESS) { - goto error; - } - if (!ac->pending) { - /* send referrals */ - ret = send_referrals(ldb, ac); - if (ret != LDB_SUCCESS) { - goto error; - } - - /* send REPLY_DONE */ - ac->up_callback(ldb, ac->up_context, ares); - } - break; - default: - goto error; - } - - return LDB_SUCCESS; - -error: - talloc_free(ares); - return ret; -} - -static int ps_search(struct ldb_module *module, struct ldb_request *req) -{ - struct private_data *private_data; - struct ldb_paged_control *control; - struct ps_context *ac; - struct ldb_handle *h; - - private_data = talloc_get_type(module->private_data, struct private_data); - - /* check if paging is supported and if there is a any control */ - if (!private_data || !private_data->paged_supported || req->controls) { - /* do not touch this request paged controls not - * supported or explicit controls have been set or we - * are just not setup yet */ - return ldb_next_request(module, req); - } - - if (!req->callback || !req->context) { - ldb_set_errstring(module->ldb, - "Async interface called with NULL callback function or NULL context"); - return LDB_ERR_OPERATIONS_ERROR; - } - - h = init_handle(req, module, req->context, req->callback); - if (!h) { - return LDB_ERR_OPERATIONS_ERROR; - } - ac = talloc_get_type(h->private_data, struct ps_context); - - ac->new_req = talloc(ac, struct ldb_request); - if (!ac->new_req) return LDB_ERR_OPERATIONS_ERROR; - - ac->new_req->controls = talloc_array(ac->new_req, struct ldb_control *, 2); - if (!ac->new_req->controls) return LDB_ERR_OPERATIONS_ERROR; - - ac->new_req->controls[0] = talloc(ac->new_req->controls, struct ldb_control); - if (!ac->new_req->controls[0]) return LDB_ERR_OPERATIONS_ERROR; - - control = talloc(ac->new_req->controls[0], struct ldb_paged_control); - if (!control) return LDB_ERR_OPERATIONS_ERROR; - - control->size = PS_DEFAULT_PAGE_SIZE; - control->cookie = NULL; - control->cookie_len = 0; - - ac->new_req->controls[0]->oid = LDB_CONTROL_PAGED_RESULTS_OID; - ac->new_req->controls[0]->critical = 1; - ac->new_req->controls[0]->data = control; - - ac->new_req->controls[1] = NULL; - - ac->new_req->operation = req->operation; - ac->new_req->op.search.base = req->op.search.base; - ac->new_req->op.search.scope = req->op.search.scope; - ac->new_req->op.search.tree = req->op.search.tree; - ac->new_req->op.search.attrs = req->op.search.attrs; - ac->new_req->context = ac; - ac->new_req->callback = ps_callback; - ldb_set_timeout_from_prev_req(module->ldb, req, ac->new_req); - - req->handle = h; - - return ldb_next_request(module, ac->new_req); -} - -static int ps_continuation(struct ldb_handle *handle) -{ - struct ps_context *ac; - - if (!handle || !handle->private_data) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ac = talloc_get_type(handle->private_data, struct ps_context); - - /* reset the requests handle */ - ac->new_req->handle = NULL; - - return ldb_next_request(handle->module, ac->new_req); -} - -static int ps_wait_none(struct ldb_handle *handle) -{ - struct ps_context *ac; - int ret; - - if (!handle || !handle->private_data) { - return LDB_ERR_OPERATIONS_ERROR; - } - - if (handle->state == LDB_ASYNC_DONE) { - return handle->status; - } - - handle->state = LDB_ASYNC_PENDING; - handle->status = LDB_SUCCESS; - - ac = talloc_get_type(handle->private_data, struct ps_context); - - ret = ldb_wait(ac->new_req->handle, LDB_WAIT_NONE); - - if (ret != LDB_SUCCESS) { - handle->status = ret; - goto done; - } - - if (ac->new_req->handle->status != LDB_SUCCESS) { - handle->status = ac->new_req->handle->status; - goto done; - } - - if (ac->new_req->handle->state != LDB_ASYNC_DONE) { - return LDB_SUCCESS; - } - - /* see if we need to send another request for the next batch */ - if (ac->pending) { - ret = ps_continuation(handle); - if (ret != LDB_SUCCESS) { - handle->status = ret; - goto done; - } - - /* continue the search with the next request */ - return LDB_SUCCESS; - } - - ret = LDB_SUCCESS; - -done: - handle->state = LDB_ASYNC_DONE; - return ret; -} - -static int ps_wait_all(struct ldb_handle *handle) -{ - int ret; - - while (handle->state != LDB_ASYNC_DONE) { - ret = ps_wait_none(handle); - if (ret != LDB_SUCCESS) { - return ret; - } - } - - return handle->status; -} - -static int ps_wait(struct ldb_handle *handle, enum ldb_wait_type type) -{ - if (type == LDB_WAIT_ALL) { - return ps_wait_all(handle); - } else { - return ps_wait_none(handle); - } -} - -static int check_supported_paged(struct ldb_context *ldb, void *context, - struct ldb_reply *ares) -{ - struct private_data *data; - data = talloc_get_type(context, - struct private_data); - if (ares->type == LDB_REPLY_ENTRY) { - if (ldb_msg_check_string_attribute(ares->message, - "supportedControl", - LDB_CONTROL_PAGED_RESULTS_OID)) { - data->paged_supported = True; - } - } - return LDB_SUCCESS; -} - - -static int ps_init(struct ldb_module *module) -{ - static const char *attrs[] = { "supportedControl", NULL }; - struct private_data *data; - int ret; - struct ldb_request *req; - - data = talloc(module, struct private_data); - if (data == NULL) { - return LDB_ERR_OTHER; - } - module->private_data = data; - data->paged_supported = False; - - req = talloc(module, struct ldb_request); - if (req == NULL) { - ldb_set_errstring(module->ldb, "Out of Memory"); - return LDB_ERR_OPERATIONS_ERROR; - } - - req->operation = LDB_SEARCH; - req->op.search.base = ldb_dn_new(req); - req->op.search.scope = LDB_SCOPE_BASE; - - req->op.search.tree = ldb_parse_tree(req, "objectClass=*"); - if (req->op.search.tree == NULL) { - ldb_set_errstring(module->ldb, "Unable to parse search expression"); - talloc_free(req); - return LDB_ERR_OPERATIONS_ERROR; - } - - req->op.search.attrs = attrs; - req->controls = NULL; - req->context = data; - req->callback = check_supported_paged; - ldb_set_timeout(module->ldb, req, 0); /* use default timeout */ - - ret = ldb_next_request(module, req); - - if (ret == LDB_SUCCESS) { - ret = ldb_wait(req->handle, LDB_WAIT_ALL); - } - - talloc_free(req); - if (ret != LDB_SUCCESS) { - return ret; - } - - return ldb_next_init(module); -} - -static const struct ldb_module_ops ps_ops = { - .name = "paged_searches", - .search = ps_search, - .wait = ps_wait, - .init_context = ps_init -}; - -int ldb_paged_searches_init(void) -{ - return ldb_register_module(&ps_ops); -} - diff --git a/source/lib/ldb/modules/rdn_name.c b/source/lib/ldb/modules/rdn_name.c deleted file mode 100644 index bab5f6a0149..00000000000 --- a/source/lib/ldb/modules/rdn_name.c +++ /dev/null @@ -1,343 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Bartlet 2005 - Copyright (C) Simo Sorce 2006 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - * Name: rdb_name - * - * Component: ldb rdn name module - * - * Description: keep a consistent name attribute on objects manpulations - * - * Author: Andrew Bartlet - * - * Modifications: - * - made the module async - * Simo Sorce Mar 2006 - */ - -#include "includes.h" -#include "ldb/include/includes.h" - -static struct ldb_message_element *rdn_name_find_attribute(const struct ldb_message *msg, const char *name) -{ - int i; - - for (i = 0; i < msg->num_elements; i++) { - if (ldb_attr_cmp(name, msg->elements[i].name) == 0) { - return &msg->elements[i]; - } - } - - return NULL; -} - -static int rdn_name_add(struct ldb_module *module, struct ldb_request *req) -{ - struct ldb_request *down_req; - struct ldb_message *msg; - struct ldb_message_element *attribute; - const char *rdn_name; - struct ldb_val rdn_val; - int i, ret; - - ldb_debug(module->ldb, LDB_DEBUG_TRACE, "rdn_name_add_record\n"); - - /* do not manipulate our control entries */ - if (ldb_dn_is_special(req->op.add.message->dn)) { - return ldb_next_request(module, req); - } - - down_req = talloc(req, struct ldb_request); - if (down_req == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - *down_req = *req; - - down_req->op.add.message = msg = ldb_msg_copy_shallow(down_req, req->op.add.message); - if (msg == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - rdn_name = ldb_dn_get_rdn_name(msg->dn); - if (rdn_name == NULL) { - talloc_free(down_req); - return LDB_ERR_OPERATIONS_ERROR; - } - - rdn_val = ldb_val_dup(msg, ldb_dn_get_rdn_val(msg->dn)); - - /* Perhaps someone above us tried to set this? */ - if ((attribute = rdn_name_find_attribute(msg, "name")) != NULL ) { - attribute->num_values = 0; - } - - if (ldb_msg_add_value(msg, "name", &rdn_val, NULL) != 0) { - talloc_free(down_req); - return LDB_ERR_OPERATIONS_ERROR; - } - - attribute = rdn_name_find_attribute(msg, rdn_name); - - if (!attribute) { - if (ldb_msg_add_value(msg, rdn_name, &rdn_val, NULL) != 0) { - talloc_free(down_req); - return LDB_ERR_OPERATIONS_ERROR; - } - } else { - const struct ldb_attrib_handler *handler = ldb_attrib_handler(module->ldb, rdn_name); - - for (i = 0; i < attribute->num_values; i++) { - if (handler->comparison_fn(module->ldb, msg, &rdn_val, &attribute->values[i]) == 0) { - /* overwrite so it matches in case */ - attribute->values[i] = rdn_val; - break; - } - } - if (i == attribute->num_values) { - ldb_debug_set(module->ldb, LDB_DEBUG_FATAL, - "RDN mismatch on %s: %s (%s)", - ldb_dn_linearize(msg, msg->dn), rdn_name, rdn_val.data); - talloc_free(down_req); - return LDB_ERR_OPERATIONS_ERROR; - } - } - - /* go on with the call chain */ - ret = ldb_next_request(module, down_req); - - /* do not free down_req as the call results may be linked to it, - * it will be freed when the upper level request get freed */ - if (ret == LDB_SUCCESS) { - req->handle = down_req->handle; - } - - return ret; -} - -struct rename_context { - - enum {RENAME_RENAME, RENAME_MODIFY} step; - struct ldb_request *orig_req; - struct ldb_request *down_req; - struct ldb_request *mod_req; -}; - -static int rdn_name_rename(struct ldb_module *module, struct ldb_request *req) -{ - struct ldb_handle *h; - struct rename_context *ac; - - ldb_debug(module->ldb, LDB_DEBUG_TRACE, "rdn_name_rename\n"); - - /* do not manipulate our control entries */ - if (ldb_dn_is_special(req->op.rename.newdn)) { - return ldb_next_request(module, req); - } - - h = talloc_zero(req, struct ldb_handle); - if (h == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - h->module = module; - - ac = talloc_zero(h, struct rename_context); - if (ac == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - h->private_data = (void *)ac; - - h->state = LDB_ASYNC_INIT; - h->status = LDB_SUCCESS; - - ac->orig_req = req; - ac->down_req = talloc(req, struct ldb_request); - if (ac->down_req == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - *(ac->down_req) = *req; - - ac->step = RENAME_RENAME; - - req->handle = h; - - /* rename first, modify "name" if rename is ok */ - return ldb_next_request(module, ac->down_req); -} - -static int rdn_name_rename_do_mod(struct ldb_handle *h) { - - struct rename_context *ac; - const char *rdn_name; - struct ldb_val rdn_val; - struct ldb_message *msg; - - ac = talloc_get_type(h->private_data, struct rename_context); - - ac->mod_req = talloc_zero(ac, struct ldb_request); - - ac->mod_req->operation = LDB_MODIFY; - ac->mod_req->op.mod.message = msg = ldb_msg_new(ac->mod_req); - if (msg == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - msg->dn = ldb_dn_copy(msg, ac->orig_req->op.rename.newdn); - if (msg->dn == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - rdn_name = ldb_dn_get_rdn_name(ac->orig_req->op.rename.newdn); - if (rdn_name == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - rdn_val = ldb_val_dup(msg, ldb_dn_get_rdn_val(ac->orig_req->op.rename.newdn)); - - if (ldb_msg_add_empty(msg, rdn_name, LDB_FLAG_MOD_REPLACE, NULL) != 0) { - return LDB_ERR_OPERATIONS_ERROR; - } - if (ldb_msg_add_value(msg, rdn_name, &rdn_val, NULL) != 0) { - return LDB_ERR_OPERATIONS_ERROR; - } - if (ldb_msg_add_empty(msg, "name", LDB_FLAG_MOD_REPLACE, NULL) != 0) { - return LDB_ERR_OPERATIONS_ERROR; - } - if (ldb_msg_add_value(msg, "name", &rdn_val, NULL) != 0) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ldb_set_timeout_from_prev_req(h->module->ldb, ac->orig_req, ac->mod_req); - - ac->step = RENAME_MODIFY; - - /* do the mod call */ - return ldb_request(h->module->ldb, ac->mod_req); -} - -static int rename_wait(struct ldb_handle *handle) -{ - struct rename_context *ac; - int ret; - - if (!handle || !handle->private_data) { - return LDB_ERR_OPERATIONS_ERROR; - } - - if (handle->state == LDB_ASYNC_DONE) { - return handle->status; - } - - handle->state = LDB_ASYNC_PENDING; - handle->status = LDB_SUCCESS; - - ac = talloc_get_type(handle->private_data, struct rename_context); - - switch(ac->step) { - case RENAME_RENAME: - ret = ldb_wait(ac->down_req->handle, LDB_WAIT_NONE); - if (ret != LDB_SUCCESS) { - handle->status = ret; - goto done; - } - if (ac->down_req->handle->status != LDB_SUCCESS) { - handle->status = ac->down_req->handle->status; - goto done; - } - - if (ac->down_req->handle->state != LDB_ASYNC_DONE) { - return LDB_SUCCESS; - } - - /* rename operation done */ - return rdn_name_rename_do_mod(handle); - - case RENAME_MODIFY: - ret = ldb_wait(ac->mod_req->handle, LDB_WAIT_NONE); - if (ret != LDB_SUCCESS) { - handle->status = ret; - goto done; - } - if (ac->mod_req->handle->status != LDB_SUCCESS) { - handle->status = ac->mod_req->handle->status; - goto done; - } - - if (ac->mod_req->handle->state != LDB_ASYNC_DONE) { - return LDB_SUCCESS; - } - - break; - - default: - ret = LDB_ERR_OPERATIONS_ERROR; - goto done; - } - - ret = LDB_SUCCESS; - -done: - handle->state = LDB_ASYNC_DONE; - return ret; -} - -static int rename_wait_all(struct ldb_handle *handle) { - - int ret; - - while (handle->state != LDB_ASYNC_DONE) { - ret = rename_wait(handle); - if (ret != LDB_SUCCESS) { - return ret; - } - } - - return handle->status; -} - -static int rdn_name_wait(struct ldb_handle *handle, enum ldb_wait_type type) -{ - if (type == LDB_WAIT_ALL) { - return rename_wait_all(handle); - } else { - return rename_wait(handle); - } -} - -static const struct ldb_module_ops rdn_name_ops = { - .name = "rdn_name", - .add = rdn_name_add, - .rename = rdn_name_rename, - .wait = rdn_name_wait -}; - - -int ldb_rdn_name_init(void) -{ - return ldb_register_module(&rdn_name_ops); -} diff --git a/source/lib/ldb/modules/skel.c b/source/lib/ldb/modules/skel.c deleted file mode 100644 index 2adef580b1c..00000000000 --- a/source/lib/ldb/modules/skel.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - ldb database library - - Copyright (C) Simo Sorce 2004 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - * Name: ldb - * - * Component: ldb skel module - * - * Description: example module - * - * Author: Simo Sorce - */ - -#include "includes.h" -#include "ldb/include/includes.h" - -struct private_data { - - char *some_private_data; -}; - -/* search */ -static int skel_search(struct ldb_module *module, struct ldb_request *req) -{ - return ldb_next_request(module, req); -} - -/* add */ -static int skel_add(struct ldb_module *module, struct ldb_request *req){ - return ldb_next_request(module, req); -} - -/* modify */ -static int skel_modify(struct ldb_module *module, struct ldb_request *req) -{ - return ldb_next_request(module, req); -} - -/* delete */ -static int skel_delete(struct ldb_module *module, struct ldb_request *req) -{ - return ldb_next_request(module, req); -} - -/* rename */ -static int skel_rename(struct ldb_module *module, struct ldb_request *req) -{ - return ldb_next_request(module, req); -} - -/* start a transaction */ -static int skel_start_trans(struct ldb_module *module) -{ - return ldb_next_start_trans(module); -} - -/* end a transaction */ -static int skel_end_trans(struct ldb_module *module) -{ - return ldb_next_end_trans(module); -} - -/* delete a transaction */ -static int skel_del_trans(struct ldb_module *module) -{ - return ldb_next_del_trans(module); -} - -static int skel_destructor(struct ldb_module *ctx) -{ - struct private_data *data = talloc_get_type(ctx->private_data, struct private_data); - /* put your clean-up functions here */ - if (data->some_private_data) talloc_free(data->some_private_data); - return 0; -} - -static int skel_request(struct ldb_module *module, struct ldb_request *req) -{ - return ldb_next_request(module, req); -} - -static int skel_init(struct ldb_module *ctx) -{ - struct private_data *data; - - data = talloc(ctx, struct private_data); - if (data == NULL) { - return 1; - } - - data->some_private_data = NULL; - ctx->private_data = data; - - talloc_set_destructor (ctx, skel_destructor); - - return ldb_next_init(ctx); -} - -static const struct ldb_module_ops skel_ops = { - .name = "skel", - .init_context = skel_init, - .search = skel_search, - .add = skel_add, - .modify = skel_modify, - .del = skel_delete, - .rename = skel_rename, - .request = skel_request, - .start_transaction = skel_start_trans, - .end_transaction = skel_end_trans, - .del_transaction = skel_del_trans, -}; - -int ldb_skel_init(void) -{ - return ldb_register_module(&skel_ops); -} diff --git a/source/lib/ldb/modules/sort.c b/source/lib/ldb/modules/sort.c deleted file mode 100644 index 4fa03f8bfa3..00000000000 --- a/source/lib/ldb/modules/sort.c +++ /dev/null @@ -1,443 +0,0 @@ -/* - ldb database library - - Copyright (C) Simo Sorce 2005 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - * Name: ldb - * - * Component: ldb server side sort control module - * - * Description: this module sorts the results of a search - * - * Author: Simo Sorce - */ - -#include "includes.h" -#include "ldb/include/includes.h" - -struct opaque { - struct ldb_context *ldb; - const struct ldb_attrib_handler *h; - const char *attribute; - int reverse; - int result; -}; - -struct sort_context { - struct ldb_module *module; - void *up_context; - int (*up_callback)(struct ldb_context *, void *, struct ldb_reply *); - - char *attributeName; - char *orderingRule; - int reverse; - - struct ldb_request *req; - struct ldb_message **msgs; - char **referrals; - struct ldb_control **controls; - int num_msgs; - int num_refs; - - const struct ldb_attrib_handler *h; - int sort_result; -}; - -static struct ldb_handle *init_handle(void *mem_ctx, struct ldb_module *module, - void *context, - int (*callback)(struct ldb_context *, void *, struct ldb_reply *)) -{ - struct sort_context *ac; - struct ldb_handle *h; - - h = talloc_zero(mem_ctx, struct ldb_handle); - if (h == NULL) { - ldb_set_errstring(module->ldb, "Out of Memory"); - return NULL; - } - - h->module = module; - - ac = talloc_zero(h, struct sort_context); - if (ac == NULL) { - ldb_set_errstring(module->ldb, "Out of Memory"); - talloc_free(h); - return NULL; - } - - h->private_data = (void *)ac; - - h->state = LDB_ASYNC_INIT; - h->status = LDB_SUCCESS; - - ac->module = module; - ac->up_context = context; - ac->up_callback = callback; - - return h; -} - -static int build_response(void *mem_ctx, struct ldb_control ***ctrls, int result, const char *desc) -{ - struct ldb_control **controls; - struct ldb_sort_resp_control *resp; - int i; - - if (*ctrls) { - controls = *ctrls; - for (i = 0; controls[i]; i++); - controls = talloc_realloc(mem_ctx, controls, struct ldb_control *, i + 2); - } else { - i = 0; - controls = talloc_array(mem_ctx, struct ldb_control *, 2); - } - if (! controls ) - return LDB_ERR_OPERATIONS_ERROR; - - *ctrls = controls; - - controls[i+1] = NULL; - controls[i] = talloc(controls, struct ldb_control); - if (! controls[i] ) - return LDB_ERR_OPERATIONS_ERROR; - - controls[i]->oid = LDB_CONTROL_SORT_RESP_OID; - controls[i]->critical = 0; - - resp = talloc(controls[i], struct ldb_sort_resp_control); - if (! resp ) - return LDB_ERR_OPERATIONS_ERROR; - - resp->result = result; - resp->attr_desc = talloc_strdup(resp, desc); - - if (! resp->attr_desc ) - return LDB_ERR_OPERATIONS_ERROR; - - controls[i]->data = resp; - - return LDB_SUCCESS; -} - -static int sort_compare(struct ldb_message **msg1, struct ldb_message **msg2, void *opaque) -{ - struct sort_context *ac = talloc_get_type(opaque, struct sort_context); - struct ldb_message_element *el1, *el2; - - if (ac->sort_result != 0) { - /* an error occurred previously, - * let's exit the sorting by returning always 0 */ - return 0; - } - - el1 = ldb_msg_find_element(*msg1, ac->attributeName); - el2 = ldb_msg_find_element(*msg2, ac->attributeName); - - if (!el1 || !el2) { - /* the attribute was not found return and - * set an error */ - ac->sort_result = 53; - return 0; - } - - if (ac->reverse) - return ac->h->comparison_fn(ac->module->ldb, ac, &el2->values[0], &el1->values[0]); - - return ac->h->comparison_fn(ac->module->ldb, ac, &el1->values[0], &el2->values[0]); -} - -static int server_sort_search_callback(struct ldb_context *ldb, void *context, struct ldb_reply *ares) -{ - struct sort_context *ac = NULL; - - if (!context || !ares) { - ldb_set_errstring(ldb, "NULL Context or Result in callback"); - goto error; - } - - ac = talloc_get_type(context, struct sort_context); - - if (ares->type == LDB_REPLY_ENTRY) { - ac->msgs = talloc_realloc(ac, ac->msgs, struct ldb_message *, ac->num_msgs + 2); - if (! ac->msgs) { - goto error; - } - - ac->msgs[ac->num_msgs + 1] = NULL; - - ac->msgs[ac->num_msgs] = talloc_move(ac->msgs, &ares->message); - ac->num_msgs++; - } - - if (ares->type == LDB_REPLY_REFERRAL) { - ac->referrals = talloc_realloc(ac, ac->referrals, char *, ac->num_refs + 2); - if (! ac->referrals) { - goto error; - } - - ac->referrals[ac->num_refs + 1] = NULL; - ac->referrals[ac->num_refs] = talloc_move(ac->referrals, &ares->referral); - - ac->num_refs++; - } - - if (ares->type == LDB_REPLY_DONE) { - ac->controls = talloc_move(ac, &ares->controls); - } - - talloc_free(ares); - return LDB_SUCCESS; - -error: - talloc_free(ares); - return LDB_ERR_OPERATIONS_ERROR; -} - -static int server_sort_search(struct ldb_module *module, struct ldb_request *req) -{ - struct ldb_control *control; - struct ldb_server_sort_control **sort_ctrls; - struct ldb_control **saved_controls; - struct sort_context *ac; - struct ldb_handle *h; - int ret; - - /* check if there's a paged request control */ - control = get_control_from_list(req->controls, LDB_CONTROL_SERVER_SORT_OID); - if (control == NULL) { - /* not found go on */ - return ldb_next_request(module, req); - } - - req->handle = NULL; - - if (!req->callback || !req->context) { - ldb_set_errstring(module->ldb, - "Async interface called with NULL callback function or NULL context"); - return LDB_ERR_OPERATIONS_ERROR; - } - - h = init_handle(req, module, req->context, req->callback); - if (!h) { - return LDB_ERR_OPERATIONS_ERROR; - } - ac = talloc_get_type(h->private_data, struct sort_context); - - sort_ctrls = talloc_get_type(control->data, struct ldb_server_sort_control *); - if (!sort_ctrls) { - return LDB_ERR_PROTOCOL_ERROR; - } - - /* FIXME: we do not support more than one attribute for sorting right now */ - /* FIXME: we need to check if the attribute type exist or return an error */ - - if (sort_ctrls[1] != NULL) { - if (control->critical) { - struct ldb_reply *ares; - - ares = talloc_zero(req, struct ldb_reply); - if (!ares) - return LDB_ERR_OPERATIONS_ERROR; - - /* 53 = unwilling to perform */ - ares->type = LDB_REPLY_DONE; - if ((ret = build_response(ares, &ares->controls, 53, "sort control is not complete yet")) != LDB_SUCCESS) { - return ret; - } - - h->status = LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION; - h->state = LDB_ASYNC_DONE; - ret = ac->up_callback(module->ldb, ac->up_context, ares); - - return ret; - } else { - /* just pass the call down and don't do any sorting */ - ldb_next_request(module, req); - } - } - - ac->attributeName = sort_ctrls[0]->attributeName; - ac->orderingRule = sort_ctrls[0]->orderingRule; - ac->reverse = sort_ctrls[0]->reverse; - - ac->req = talloc(req, struct ldb_request); - if (!ac->req) - return LDB_ERR_OPERATIONS_ERROR; - - ac->req->operation = req->operation; - ac->req->op.search.base = req->op.search.base; - ac->req->op.search.scope = req->op.search.scope; - ac->req->op.search.tree = req->op.search.tree; - ac->req->op.search.attrs = req->op.search.attrs; - ac->req->controls = req->controls; - - /* save it locally and remove it from the list */ - /* we do not need to replace them later as we - * are keeping the original req intact */ - if (!save_controls(control, ac->req, &saved_controls)) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->req->context = ac; - ac->req->callback = server_sort_search_callback; - ldb_set_timeout_from_prev_req(module->ldb, req, ac->req); - - req->handle = h; - - return ldb_next_request(module, ac->req); -} - -static int server_sort_results(struct ldb_handle *handle) -{ - struct sort_context *ac; - struct ldb_reply *ares; - int i, ret; - - ac = talloc_get_type(handle->private_data, struct sort_context); - - ac->h = ldb_attrib_handler(ac->module->ldb, ac->attributeName); - ac->sort_result = 0; - - ldb_qsort(ac->msgs, ac->num_msgs, - sizeof(struct ldb_message *), - ac, (ldb_qsort_cmp_fn_t)sort_compare); - - for (i = 0; i < ac->num_msgs; i++) { - ares = talloc_zero(ac, struct ldb_reply); - if (!ares) { - handle->status = LDB_ERR_OPERATIONS_ERROR; - return handle->status; - } - - ares->type = LDB_REPLY_ENTRY; - ares->message = talloc_move(ares, &ac->msgs[i]); - - handle->status = ac->up_callback(ac->module->ldb, ac->up_context, ares); - if (handle->status != LDB_SUCCESS) { - return handle->status; - } - } - - for (i = 0; i < ac->num_refs; i++) { - ares = talloc_zero(ac, struct ldb_reply); - if (!ares) { - handle->status = LDB_ERR_OPERATIONS_ERROR; - return handle->status; - } - - ares->type = LDB_REPLY_REFERRAL; - ares->referral = talloc_move(ares, &ac->referrals[i]); - - handle->status = ac->up_callback(ac->module->ldb, ac->up_context, ares); - if (handle->status != LDB_SUCCESS) { - return handle->status; - } - } - - ares = talloc_zero(ac, struct ldb_reply); - if (!ares) { - handle->status = LDB_ERR_OPERATIONS_ERROR; - return handle->status; - } - - ares->type = LDB_REPLY_DONE; - ares->controls = talloc_move(ares, &ac->controls); - - handle->status = ac->up_callback(ac->module->ldb, ac->up_context, ares); - if (handle->status != LDB_SUCCESS) { - return handle->status; - } - - if ((ret = build_response(ac, &ac->controls, ac->sort_result, "sort control is not complete yet")) != LDB_SUCCESS) { - return ret; - } - - return LDB_SUCCESS; -} - -static int server_sort_wait(struct ldb_handle *handle, enum ldb_wait_type type) -{ - struct sort_context *ac; - int ret; - - if (!handle || !handle->private_data) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ac = talloc_get_type(handle->private_data, struct sort_context); - - ret = ldb_wait(ac->req->handle, type); - - if (ret != LDB_SUCCESS) { - handle->status = ret; - return ret; - } - - handle->state = ac->req->handle->state; - handle->status = ac->req->handle->status; - - if (handle->status != LDB_SUCCESS) { - return handle->status; - } - - if (handle->state == LDB_ASYNC_DONE) { - ret = server_sort_results(handle); - } - - return ret; -} - -static int server_sort_init(struct ldb_module *module) -{ - struct ldb_request *req; - int ret; - - req = talloc(module, struct ldb_request); - if (req == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - req->operation = LDB_REQ_REGISTER_CONTROL; - req->op.reg_control.oid = LDB_CONTROL_SERVER_SORT_OID; - req->controls = NULL; - - ret = ldb_request(module->ldb, req); - if (ret != LDB_SUCCESS) { - ldb_debug(module->ldb, LDB_DEBUG_WARNING, "server_sort: Unable to register control with rootdse!\n"); - } - - talloc_free(req); - return ldb_next_init(module); -} - -static const struct ldb_module_ops server_sort_ops = { - .name = "server_sort", - .search = server_sort_search, - .wait = server_sort_wait, - .init_context = server_sort_init -}; - -int ldb_sort_init(void) -{ - return ldb_register_module(&server_sort_ops); -} diff --git a/source/lib/ldb/nssldb/README.txt b/source/lib/ldb/nssldb/README.txt deleted file mode 100644 index ddba62b3804..00000000000 --- a/source/lib/ldb/nssldb/README.txt +++ /dev/null @@ -1,34 +0,0 @@ - -This test code requires a tdb that is configured for to use the asq module. -You can do that adding the following record to a tdb: - -dn: @MODULES -@LIST: asq - -Other modules can be used as well (like rdn_name for example) - -The uidNumber 0 and the gidNumber 0 are considered invalid. - -The user records should contain the followin attributes: -uid (required) the user name -userPassword (optional) the user password (if not present "LDB" is - returned in the password field) -uidNumber (required) the user uid -gidNumber (required) the user primary gid -gecos (optional) the GECOS -homeDirectory (required) the home directory -loginShell (required) the login shell -memberOf (required) all the groups the user is member of should - be reported here using their DNs. The - primary group as well. - -The group accounts should contain the following attributes: -cn (required) the group name -uesrPassword (optional) the group password (if not present "LDB" is - returned in the password field) -gidNumber (required) the group gid -member (optional) the DNs of the member users, also the ones - that have this group as primary - - -SSS diff --git a/source/lib/ldb/nssldb/ldb-grp.c b/source/lib/ldb/nssldb/ldb-grp.c deleted file mode 100644 index f33ec65c55e..00000000000 --- a/source/lib/ldb/nssldb/ldb-grp.c +++ /dev/null @@ -1,427 +0,0 @@ -/* - LDB nsswitch module - - Copyright (C) Simo Sorce 2006 - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the - Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. -*/ - -#include "ldb-nss.h" - -extern struct _ldb_nss_context *_ldb_nss_ctx; - -const char *_ldb_nss_gr_attrs[] = { - "cn", - "userPassword", - "gidNumber", - NULL -}; - -const char *_ldb_nss_mem_attrs[] = { - "uid", - NULL -}; - -#define _NSS_LDB_ENOMEM(amem) \ - do { \ - if ( ! amem) { \ - errno = ENOMEM; \ - talloc_free(memctx); \ - return NSS_STATUS_UNAVAIL; \ - } \ - } while(0) - -/* This setgrent, getgrent, endgrent is not very efficient */ - -NSS_STATUS _nss_ldb_setgrent(void) -{ - int ret; - - ret = _ldb_nss_init(); - if (ret != NSS_STATUS_SUCCESS) { - return ret; - } - - _ldb_nss_ctx->gr_cur = 0; - if (_ldb_nss_ctx->gr_res != NULL) { - talloc_free(_ldb_nss_ctx->gr_res); - _ldb_nss_ctx->gr_res = NULL; - } - - ret = ldb_search(_ldb_nss_ctx->ldb, - _ldb_nss_ctx->base, - LDB_SCOPE_SUBTREE, - _LDB_NSS_GRENT_FILTER, - _ldb_nss_gr_attrs, - &_ldb_nss_ctx->gr_res); - if (ret != LDB_SUCCESS) { - return NSS_STATUS_UNAVAIL; - } - - return NSS_STATUS_SUCCESS; -} - -NSS_STATUS _nss_ldb_endgrent(void) -{ - int ret; - - ret = _ldb_nss_init(); - if (ret != NSS_STATUS_SUCCESS) { - return ret; - } - - _ldb_nss_ctx->gr_cur = 0; - if (_ldb_nss_ctx->gr_res) { - talloc_free(_ldb_nss_ctx->gr_res); - _ldb_nss_ctx->gr_res = NULL; - } - - return NSS_STATUS_SUCCESS; -} - -NSS_STATUS _nss_ldb_getgrent_r(struct group *result_buf, char *buffer, size_t buflen, int *errnop) -{ - int ret; - struct ldb_result *res; - - ret = _ldb_nss_init(); - if (ret != NSS_STATUS_SUCCESS) { - return ret; - } - - *errnop = 0; - - if (_ldb_nss_ctx->gr_cur >= _ldb_nss_ctx->gr_res->count) { - /* already returned all entries */ - return NSS_STATUS_NOTFOUND; - } - - res = talloc_zero(_ldb_nss_ctx->gr_res, struct ldb_result); - if ( ! res) { - errno = *errnop = ENOMEM; - _ldb_nss_ctx->gr_cur++; /* skip this entry */ - return NSS_STATUS_UNAVAIL; - } - - ret = _ldb_nss_group_request(&res, - _ldb_nss_ctx->gr_res->msgs[_ldb_nss_ctx->gr_cur]->dn, - _ldb_nss_mem_attrs, - "member"); - - if (ret != NSS_STATUS_SUCCESS) { - *errnop = errno; - talloc_free(res); - _ldb_nss_ctx->gr_cur++; /* skip this entry */ - return ret; - } - - ret = _ldb_nss_fill_group(result_buf, - buffer, - buflen, - errnop, - _ldb_nss_ctx->gr_res->msgs[_ldb_nss_ctx->gr_cur], - res); - - talloc_free(res); - - if (ret != NSS_STATUS_SUCCESS) { - if (ret != NSS_STATUS_TRYAGAIN) { - _ldb_nss_ctx->gr_cur++; /* skip this entry */ - } - return ret; - } - - /* this entry is ok, increment counter to nex entry */ - _ldb_nss_ctx->gr_cur++; - - return NSS_STATUS_SUCCESS; -} - -NSS_STATUS _nss_ldb_getgrnam_r(const char *name, struct group *result_buf, char *buffer, size_t buflen, int *errnop) -{ - int ret; - char *filter; - TALLOC_CTX *ctx; - struct ldb_result *gr_res; - struct ldb_result *mem_res; - - ret = _ldb_nss_init(); - if (ret != NSS_STATUS_SUCCESS) { - return ret; - } - - ctx = talloc_new(_ldb_nss_ctx->ldb); - if ( ! ctx) { - *errnop = errno = ENOMEM; - return NSS_STATUS_UNAVAIL; - } - - /* build the filter for this uid */ - filter = talloc_asprintf(ctx, _LDB_NSS_GRNAM_FILTER, name); - if (filter == NULL) { - /* this is a fatal error */ - *errnop = errno = ENOMEM; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - /* search the entry */ - ret = ldb_search(_ldb_nss_ctx->ldb, - _ldb_nss_ctx->base, - LDB_SCOPE_SUBTREE, - filter, - _ldb_nss_gr_attrs, - &gr_res); - if (ret != LDB_SUCCESS) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - talloc_steal(ctx, gr_res); - - /* if none found return */ - if (gr_res->count == 0) { - *errnop = errno = ENOENT; - ret = NSS_STATUS_NOTFOUND; - goto done; - } - - if (gr_res->count != 1) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - mem_res = talloc_zero(ctx, struct ldb_result); - if ( ! mem_res) { - errno = *errnop = ENOMEM; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - ret = _ldb_nss_group_request(&mem_res, - gr_res->msgs[0]->dn, - _ldb_nss_mem_attrs, - "member"); - - if (ret != NSS_STATUS_SUCCESS) { - *errnop = errno; - goto done; - } - - ret = _ldb_nss_fill_group(result_buf, - buffer, - buflen, - errnop, - gr_res->msgs[0], - mem_res); - - if (ret != NSS_STATUS_SUCCESS) { - goto done; - } - - ret = NSS_STATUS_SUCCESS; -done: - talloc_free(ctx); - return ret; -} - -NSS_STATUS _nss_ldb_getgrgid_r(gid_t gid, struct group *result_buf, char *buffer, size_t buflen, int *errnop) -{ - int ret; - char *filter; - TALLOC_CTX *ctx; - struct ldb_result *gr_res; - struct ldb_result *mem_res; - - if (gid == 0) { /* we don't serve root gid by policy */ - *errnop = errno = ENOENT; - return NSS_STATUS_NOTFOUND; - } - - ret = _ldb_nss_init(); - if (ret != NSS_STATUS_SUCCESS) { - return ret; - } - - ctx = talloc_new(_ldb_nss_ctx->ldb); - if ( ! ctx) { - *errnop = errno = ENOMEM; - return NSS_STATUS_UNAVAIL; - } - - /* build the filter for this uid */ - filter = talloc_asprintf(ctx, _LDB_NSS_GRGID_FILTER, gid); - if (filter == NULL) { - /* this is a fatal error */ - *errnop = errno = ENOMEM; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - /* search the entry */ - ret = ldb_search(_ldb_nss_ctx->ldb, - _ldb_nss_ctx->base, - LDB_SCOPE_SUBTREE, - filter, - _ldb_nss_gr_attrs, - &gr_res); - if (ret != LDB_SUCCESS) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - talloc_steal(ctx, gr_res); - - /* if none found return */ - if (gr_res->count == 0) { - *errnop = errno = ENOENT; - ret = NSS_STATUS_NOTFOUND; - goto done; - } - - if (gr_res->count != 1) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - mem_res = talloc_zero(ctx, struct ldb_result); - if ( ! mem_res) { - errno = *errnop = ENOMEM; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - ret = _ldb_nss_group_request(&mem_res, - gr_res->msgs[0]->dn, - _ldb_nss_mem_attrs, - "member"); - - if (ret != NSS_STATUS_SUCCESS) { - *errnop = errno; - goto done; - } - - ret = _ldb_nss_fill_group(result_buf, - buffer, - buflen, - errnop, - gr_res->msgs[0], - mem_res); - - if (ret != NSS_STATUS_SUCCESS) { - goto done; - } - - ret = NSS_STATUS_SUCCESS; -done: - talloc_free(ctx); - return ret; -} - -NSS_STATUS _nss_ldb_initgroups_dyn(const char *user, gid_t group, long int *start, long int *size, gid_t **groups, long int limit, int *errnop) -{ - int ret; - char *filter; - const char * attrs[] = { "uidNumber", "gidNumber", NULL }; - struct ldb_result *uid_res; - struct ldb_result *mem_res; - - ret = _ldb_nss_init(); - if (ret != NSS_STATUS_SUCCESS) { - return ret; - } - - mem_res = talloc_zero(_ldb_nss_ctx, struct ldb_result); - if ( ! mem_res) { - errno = *errnop = ENOMEM; - return NSS_STATUS_UNAVAIL; - } - - /* build the filter for this name */ - filter = talloc_asprintf(mem_res, _LDB_NSS_PWNAM_FILTER, user); - if (filter == NULL) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - /* search the entry */ - ret = ldb_search(_ldb_nss_ctx->ldb, - _ldb_nss_ctx->base, - LDB_SCOPE_SUBTREE, - filter, - attrs, - &uid_res); - if (ret != LDB_SUCCESS) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - talloc_steal(mem_res, uid_res); - - /* if none found return */ - if (uid_res->count == 0) { - *errnop = errno = ENOENT; - ret = NSS_STATUS_NOTFOUND; - goto done; - } - - if (uid_res->count != 1) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - ret = _ldb_nss_group_request(&mem_res, - uid_res->msgs[0]->dn, - attrs, - "memberOf"); - - if (ret != NSS_STATUS_SUCCESS) { - *errnop = errno; - goto done; - } - - ret = _ldb_nss_fill_initgr(group, - limit, - start, - size, - groups, - errnop, - mem_res); - - if (ret != NSS_STATUS_SUCCESS) { - goto done; - } - - ret = NSS_STATUS_SUCCESS; - -done: - talloc_free(mem_res); - return ret; -} diff --git a/source/lib/ldb/nssldb/ldb-nss.c b/source/lib/ldb/nssldb/ldb-nss.c deleted file mode 100644 index 614f6e170fe..00000000000 --- a/source/lib/ldb/nssldb/ldb-nss.c +++ /dev/null @@ -1,402 +0,0 @@ -/* - LDB nsswitch module - - Copyright (C) Simo Sorce 2006 - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the - Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. -*/ - -#include "ldb-nss.h" - -struct _ldb_nss_context *_ldb_nss_ctx = NULL; - -NSS_STATUS _ldb_nss_init(void) -{ - int ret; - - pid_t mypid = getpid(); - - if (_ldb_nss_ctx != NULL) { - if (_ldb_nss_ctx->pid == mypid) { - /* already initialized */ - return NSS_STATUS_SUCCESS; - } else { - /* we are in a forked child now, reinitialize */ - talloc_free(_ldb_nss_ctx); - _ldb_nss_ctx = NULL; - } - } - - _ldb_nss_ctx = talloc_named(NULL, 0, "_ldb_nss_ctx(%u)", mypid); - if (_ldb_nss_ctx == NULL) { - return NSS_STATUS_UNAVAIL; - } - - _ldb_nss_ctx->pid = mypid; - - ret = ldb_global_init(); - if (ret != 0) { - goto failed; - } - - _ldb_nss_ctx->ldb = ldb_init(_ldb_nss_ctx); - if (_ldb_nss_ctx->ldb == NULL) { - goto failed; - } - - ret = ldb_connect(_ldb_nss_ctx->ldb, _LDB_NSS_URL, LDB_FLG_RDONLY, NULL); - if (ret != LDB_SUCCESS) { - goto failed; - } - - _ldb_nss_ctx->base = ldb_dn_explode(_ldb_nss_ctx, _LDB_NSS_BASEDN); - if (_ldb_nss_ctx->base == NULL) { - goto failed; - } - - _ldb_nss_ctx->pw_cur = 0; - _ldb_nss_ctx->pw_res = NULL; - _ldb_nss_ctx->gr_cur = 0; - _ldb_nss_ctx->gr_res = NULL; - - return NSS_STATUS_SUCCESS; - -failed: - /* talloc_free(_ldb_nss_ctx); */ - _ldb_nss_ctx = NULL; - return NSS_STATUS_UNAVAIL; -} - -NSS_STATUS _ldb_nss_fill_passwd(struct passwd *result, - char *buffer, - int buflen, - int *errnop, - struct ldb_message *msg) -{ - int len; - int bufpos; - const char *tmp; - - bufpos = 0; - - /* get username */ - tmp = ldb_msg_find_attr_as_string(msg, "uid", NULL); - if (tmp == NULL) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - return NSS_STATUS_UNAVAIL; - } - len = strlen(tmp)+1; - if (bufpos + len > buflen) { - /* buffer too small */ - *errnop = errno = EAGAIN; - return NSS_STATUS_TRYAGAIN; - } - memcpy(&buffer[bufpos], tmp, len); - result->pw_name = &buffer[bufpos]; - bufpos += len; - - /* get userPassword */ - tmp = ldb_msg_find_attr_as_string(msg, "userPassword", NULL); - if (tmp == NULL) { - tmp = "LDB"; - } - len = strlen(tmp)+1; - if (bufpos + len > buflen) { - /* buffer too small */ - *errnop = errno = EAGAIN; - return NSS_STATUS_TRYAGAIN; - } - memcpy(&buffer[bufpos], tmp, len); - result->pw_passwd = &buffer[bufpos]; - bufpos += len; - - /* this backend never serves an uid 0 user */ - result->pw_uid = ldb_msg_find_attr_as_int(msg, "uidNumber", 0); - if (result->pw_uid == 0) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - return NSS_STATUS_UNAVAIL; - } - - result->pw_gid = ldb_msg_find_attr_as_int(msg, "gidNumber", 0); - if (result->pw_gid == 0) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - return NSS_STATUS_UNAVAIL; - } - - /* get gecos */ - tmp = ldb_msg_find_attr_as_string(msg, "gecos", NULL); - if (tmp == NULL) { - tmp = ""; - } - len = strlen(tmp)+1; - if (bufpos + len > buflen) { - /* buffer too small */ - *errnop = errno = EAGAIN; - return NSS_STATUS_TRYAGAIN; - } - memcpy(&buffer[bufpos], tmp, len); - result->pw_gecos = &buffer[bufpos]; - bufpos += len; - - /* get homeDirectory */ - tmp = ldb_msg_find_attr_as_string(msg, "homeDirectory", NULL); - if (tmp == NULL) { - tmp = ""; - } - len = strlen(tmp)+1; - if (bufpos + len > buflen) { - /* buffer too small */ - *errnop = errno = EAGAIN; - return NSS_STATUS_TRYAGAIN; - } - memcpy(&buffer[bufpos], tmp, len); - result->pw_dir = &buffer[bufpos]; - bufpos += len; - - /* get shell */ - tmp = ldb_msg_find_attr_as_string(msg, "loginShell", NULL); - if (tmp == NULL) { - tmp = ""; - } - len = strlen(tmp)+1; - if (bufpos + len > buflen) { - /* buffer too small */ - *errnop = errno = EAGAIN; - return NSS_STATUS_TRYAGAIN; - } - memcpy(&buffer[bufpos], tmp, len); - result->pw_shell = &buffer[bufpos]; - bufpos += len; - - return NSS_STATUS_SUCCESS; -} - -NSS_STATUS _ldb_nss_fill_group(struct group *result, - char *buffer, - int buflen, - int *errnop, - struct ldb_message *group, - struct ldb_result *members) -{ - const char *tmp; - size_t len; - size_t bufpos; - size_t lsize; - int i; - - bufpos = 0; - - /* get group name */ - tmp = ldb_msg_find_attr_as_string(group, "cn", NULL); - if (tmp == NULL) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - return NSS_STATUS_UNAVAIL; - } - len = strlen(tmp)+1; - if (bufpos + len > buflen) { - /* buffer too small */ - *errnop = errno = EAGAIN; - return NSS_STATUS_TRYAGAIN; - } - memcpy(&buffer[bufpos], tmp, len); - result->gr_name = &buffer[bufpos]; - bufpos += len; - - /* get userPassword */ - tmp = ldb_msg_find_attr_as_string(group, "userPassword", NULL); - if (tmp == NULL) { - tmp = "LDB"; - } - len = strlen(tmp)+1; - if (bufpos + len > buflen) { - /* buffer too small */ - *errnop = errno = EAGAIN; - return NSS_STATUS_TRYAGAIN; - } - memcpy(&buffer[bufpos], tmp, len); - result->gr_passwd = &buffer[bufpos]; - bufpos += len; - - result->gr_gid = ldb_msg_find_attr_as_int(group, "gidNumber", 0); - if (result->gr_gid == 0) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - return NSS_STATUS_UNAVAIL; - } - - /* check if there is enough memory for the list of pointers */ - lsize = (members->count + 1) * sizeof(char *); - - /* align buffer on pointer boundary */ - bufpos += (sizeof(char*) - ((unsigned long)(buffer) % sizeof(char*))); - if ((buflen - bufpos) < lsize) { - /* buffer too small */ - *errnop = errno = EAGAIN; - return NSS_STATUS_TRYAGAIN; - } - - result->gr_mem = (char **)&buffer[bufpos]; - bufpos += lsize; - - for (i = 0; i < members->count; i++) { - tmp = ldb_msg_find_attr_as_string(members->msgs[i], "uid", NULL); - if (tmp == NULL) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - return NSS_STATUS_UNAVAIL; - } - len = strlen(tmp)+1; - if (bufpos + len > buflen) { - /* buffer too small */ - *errnop = errno = EAGAIN; - return NSS_STATUS_TRYAGAIN; - } - memcpy(&buffer[bufpos], tmp, len); - result->gr_mem[i] = &buffer[bufpos]; - bufpos += len; - } - - result->gr_mem[i] = NULL; - - return NSS_STATUS_SUCCESS; -} - -NSS_STATUS _ldb_nss_fill_initgr(gid_t group, - long int limit, - long int *start, - long int *size, - gid_t **groups, - int *errnop, - struct ldb_result *grlist) -{ - NSS_STATUS ret; - int i; - - for (i = 0; i < grlist->count; i++) { - - if (limit && (*start > limit)) { - /* TODO: warn no all groups were reported */ - *errnop = 0; - ret = NSS_STATUS_SUCCESS; - goto done; - } - - if (*start == *size) { - /* buffer full, enlarge it */ - long int gs; - gid_t *gm; - - gs = (*size) + 32; - if (limit && (gs > limit)) { - gs = limit; - } - - gm = (gid_t *)realloc((*groups), gs * sizeof(gid_t)); - if ( ! gm) { - *errnop = ENOMEM; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - *groups = gm; - *size = gs; - } - - (*groups)[*start] = ldb_msg_find_attr_as_int(grlist->msgs[i], "gidNumber", 0); - if ((*groups)[*start] == 0 || (*groups)[*start] == group) { - /* skip root group or primary group */ - continue; - } - (*start)++; - - } - - *errnop = 0; - ret = NSS_STATUS_SUCCESS; -done: - return ret; -} - -#define _LDB_NSS_ALLOC_CHECK(mem) do { if (!mem) { errno = ENOMEM; return NSS_STATUS_UNAVAIL; } } while(0) - -NSS_STATUS _ldb_nss_group_request(struct ldb_result **_res, - struct ldb_dn *group_dn, - const char * const *attrs, - const char *mattr) -{ - struct ldb_control **ctrls; - struct ldb_control *ctrl; - struct ldb_asq_control *asqc; - struct ldb_request *req; - int ret; - struct ldb_result *res = *_res; - - ctrls = talloc_array(res, struct ldb_control *, 2); - _LDB_NSS_ALLOC_CHECK(ctrls); - - ctrl = talloc(ctrls, struct ldb_control); - _LDB_NSS_ALLOC_CHECK(ctrl); - - asqc = talloc(ctrl, struct ldb_asq_control); - _LDB_NSS_ALLOC_CHECK(asqc); - - asqc->source_attribute = talloc_strdup(asqc, mattr); - _LDB_NSS_ALLOC_CHECK(asqc->source_attribute); - - asqc->request = 1; - asqc->src_attr_len = strlen(asqc->source_attribute); - ctrl->oid = LDB_CONTROL_ASQ_OID; - ctrl->critical = 1; - ctrl->data = asqc; - ctrls[0] = ctrl; - ctrls[1] = NULL; - - ret = ldb_build_search_req( - &req, - _ldb_nss_ctx->ldb, - res, - group_dn, - LDB_SCOPE_BASE, - "(objectClass=*)", - attrs, - ctrls, - res, - ldb_search_default_callback); - - if (ret != LDB_SUCCESS) { - errno = ENOENT; - return NSS_STATUS_UNAVAIL; - } - - ldb_set_timeout(_ldb_nss_ctx->ldb, req, 0); - - ret = ldb_request(_ldb_nss_ctx->ldb, req); - - if (ret == LDB_SUCCESS) { - ret = ldb_wait(req->handle, LDB_WAIT_ALL); - } else { - talloc_free(req); - return NSS_STATUS_UNAVAIL; - } - - talloc_free(req); - return NSS_STATUS_SUCCESS; -} - diff --git a/source/lib/ldb/nssldb/ldb-nss.h b/source/lib/ldb/nssldb/ldb-nss.h deleted file mode 100644 index c780a21e811..00000000000 --- a/source/lib/ldb/nssldb/ldb-nss.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - LDB nsswitch module - - Copyright (C) Simo Sorce 2006 - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the - Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. -*/ - -#ifndef _LDB_NSS -#define _LDB_NSS - -#include "includes.h" -#include "ldb/include/includes.h" - -#include <nss.h> -#include <pwd.h> -#include <grp.h> - -#define _LDB_NSS_URL "etc/users.ldb" -#define _LDB_NSS_BASEDN "CN=Users,CN=System" -#define _LDB_NSS_PWENT_FILTER "(&(objectClass=posixAccount)(!(uidNumber=0))(!(gidNumber=0)))" -#define _LDB_NSS_PWUID_FILTER "(&(objectClass=posixAccount)(uidNumber=%d)(!(gidNumber=0)))" -#define _LDB_NSS_PWNAM_FILTER "(&(objectClass=posixAccount)(uid=%s)(!(uidNumber=0))(!(gidNumber=0)))" - -#define _LDB_NSS_GRENT_FILTER "(&(objectClass=posixGroup)(!(gidNumber=0)))" -#define _LDB_NSS_GRGID_FILTER "(&(objectClass=posixGroup)(gidNumber=%d)))" -#define _LDB_NSS_GRNAM_FILTER "(&(objectClass=posixGroup)(cn=%s)(!(gidNumber=0)))" - -typedef enum nss_status NSS_STATUS; - -struct _ldb_nss_context { - - pid_t pid; - - struct ldb_context *ldb; - const struct ldb_dn *base; - - int pw_cur; - struct ldb_result *pw_res; - - int gr_cur; - struct ldb_result *gr_res; -}; - -NSS_STATUS _ldb_nss_init(void); - -NSS_STATUS _ldb_nss_fill_passwd(struct passwd *result, - char *buffer, - int buflen, - int *errnop, - struct ldb_message *msg); - -NSS_STATUS _ldb_nss_fill_group(struct group *result, - char *buffer, - int buflen, - int *errnop, - struct ldb_message *group, - struct ldb_result *members); - -NSS_STATUS _ldb_nss_fill_initgr(gid_t group, - long int limit, - long int *start, - long int *size, - gid_t **groups, - int *errnop, - struct ldb_result *grlist); - -NSS_STATUS _ldb_nss_group_request(struct ldb_result **res, - struct ldb_dn *group_dn, - const char * const *attrs, - const char *mattr); - -#endif /* _LDB_NSS */ diff --git a/source/lib/ldb/nssldb/ldb-pwd.c b/source/lib/ldb/nssldb/ldb-pwd.c deleted file mode 100644 index e4bafdcf7c3..00000000000 --- a/source/lib/ldb/nssldb/ldb-pwd.c +++ /dev/null @@ -1,241 +0,0 @@ -/* - LDB nsswitch module - - Copyright (C) Simo Sorce 2006 - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the - Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. -*/ - -#include "ldb-nss.h" - -extern struct _ldb_nss_context *_ldb_nss_ctx; - -const char *_ldb_nss_pw_attrs[] = { - "uid", - "userPassword", - "uidNumber", - "gidNumber", - "gecos", - "homeDirectory", - "loginShell", - NULL -}; - -NSS_STATUS _nss_ldb_setpwent(void) -{ - int ret; - ret = _ldb_nss_init(); - if (ret != NSS_STATUS_SUCCESS) { - return ret; - } - - _ldb_nss_ctx->pw_cur = 0; - if (_ldb_nss_ctx->pw_res != NULL) { - talloc_free(_ldb_nss_ctx->pw_res); - _ldb_nss_ctx->pw_res = NULL; - } - - ret = ldb_search(_ldb_nss_ctx->ldb, - _ldb_nss_ctx->base, - LDB_SCOPE_SUBTREE, - _LDB_NSS_PWENT_FILTER, - _ldb_nss_pw_attrs, - &_ldb_nss_ctx->pw_res); - if (ret != LDB_SUCCESS) { - return NSS_STATUS_UNAVAIL; - } - - return NSS_STATUS_SUCCESS; -} - -NSS_STATUS _nss_ldb_endpwent(void) -{ - int ret; - - ret = _ldb_nss_init(); - if (ret != NSS_STATUS_SUCCESS) { - return ret; - } - - _ldb_nss_ctx->pw_cur = 0; - if (_ldb_nss_ctx->pw_res) { - talloc_free(_ldb_nss_ctx->pw_res); - _ldb_nss_ctx->pw_res = NULL; - } - - return NSS_STATUS_SUCCESS; -} - -NSS_STATUS _nss_ldb_getpwent_r(struct passwd *result_buf, - char *buffer, - int buflen, - int *errnop) -{ - int ret; - - ret = _ldb_nss_init(); - if (ret != NSS_STATUS_SUCCESS) { - return ret; - } - - *errnop = 0; - - if (_ldb_nss_ctx->pw_cur >= _ldb_nss_ctx->pw_res->count) { - /* already returned all entries */ - return NSS_STATUS_NOTFOUND; - } - - ret = _ldb_nss_fill_passwd(result_buf, - buffer, - buflen, - errnop, - _ldb_nss_ctx->pw_res->msgs[_ldb_nss_ctx->pw_cur]); - if (ret != NSS_STATUS_SUCCESS) { - return ret; - } - - _ldb_nss_ctx->pw_cur++; - - return NSS_STATUS_SUCCESS; -} - -NSS_STATUS _nss_ldb_getpwuid_r(uid_t uid, struct passwd *result_buf, char *buffer, size_t buflen, int *errnop) -{ - int ret; - char *filter; - struct ldb_result *res; - - if (uid == 0) { /* we don't serve root uid by policy */ - *errnop = errno = ENOENT; - return NSS_STATUS_NOTFOUND; - } - - ret = _ldb_nss_init(); - if (ret != NSS_STATUS_SUCCESS) { - return ret; - } - - /* build the filter for this uid */ - filter = talloc_asprintf(_ldb_nss_ctx, _LDB_NSS_PWUID_FILTER, uid); - if (filter == NULL) { - /* this is a fatal error */ - *errnop = errno = ENOMEM; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - /* search the entry */ - ret = ldb_search(_ldb_nss_ctx->ldb, - _ldb_nss_ctx->base, - LDB_SCOPE_SUBTREE, - filter, - _ldb_nss_pw_attrs, - &res); - if (ret != LDB_SUCCESS) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - /* if none found return */ - if (res->count == 0) { - *errnop = errno = ENOENT; - ret = NSS_STATUS_NOTFOUND; - goto done; - } - - if (res->count != 1) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - /* fill in the passwd struct */ - ret = _ldb_nss_fill_passwd(result_buf, - buffer, - buflen, - errnop, - res->msgs[0]); - -done: - talloc_free(filter); - talloc_free(res); - return ret; -} - -NSS_STATUS _nss_ldb_getpwnam_r(const char *name, struct passwd *result_buf, char *buffer, size_t buflen, int *errnop) -{ - int ret; - char *filter; - struct ldb_result *res; - - ret = _ldb_nss_init(); - if (ret != NSS_STATUS_SUCCESS) { - return ret; - } - - /* build the filter for this name */ - filter = talloc_asprintf(_ldb_nss_ctx, _LDB_NSS_PWNAM_FILTER, name); - if (filter == NULL) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - /* search the entry */ - ret = ldb_search(_ldb_nss_ctx->ldb, - _ldb_nss_ctx->base, - LDB_SCOPE_SUBTREE, - filter, - _ldb_nss_pw_attrs, - &res); - if (ret != LDB_SUCCESS) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - /* if none found return */ - if (res->count == 0) { - *errnop = errno = ENOENT; - ret = NSS_STATUS_NOTFOUND; - goto done; - } - - if (res->count != 1) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - /* fill in the passwd struct */ - ret = _ldb_nss_fill_passwd(result_buf, - buffer, - buflen, - errnop, - res->msgs[0]); - -done: - talloc_free(filter); - talloc_free(res); - return ret; -} - diff --git a/source/lib/ldb/samba/README b/source/lib/ldb/samba/README deleted file mode 100644 index 3fa47159ca9..00000000000 --- a/source/lib/ldb/samba/README +++ /dev/null @@ -1,7 +0,0 @@ -This directory contains Samba specific extensions to ldb. It also -serves as example code on how to extend ldb for your own application. - -The main extension Samba uses is to provide ldif encode/decode -routines for specific attributes, so users can get nice pretty -printing of attributes in ldbedit, while the attributes are stored in -the standard NDR format in the database. diff --git a/source/lib/ldb/samba/ldif_handlers.c b/source/lib/ldb/samba/ldif_handlers.c deleted file mode 100644 index 8abfb872382..00000000000 --- a/source/lib/ldb/samba/ldif_handlers.c +++ /dev/null @@ -1,484 +0,0 @@ -/* - ldb database library - ldif handlers for Samba - - Copyright (C) Andrew Tridgell 2005 - Copyright (C) Andrew Bartlett 2006 - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include "includes.h" -#include "ldb/include/includes.h" - -#include "librpc/gen_ndr/ndr_security.h" -#include "librpc/gen_ndr/ndr_misc.h" -#include "dsdb/samdb/samdb.h" -#include "libcli/security/security.h" - -/* - convert a ldif formatted objectSid to a NDR formatted blob -*/ -static int ldif_read_objectSid(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - struct dom_sid *sid; - NTSTATUS status; - sid = dom_sid_parse_talloc(mem_ctx, (const char *)in->data); - if (sid == NULL) { - return -1; - } - status = ndr_push_struct_blob(out, mem_ctx, sid, - (ndr_push_flags_fn_t)ndr_push_dom_sid); - talloc_free(sid); - if (!NT_STATUS_IS_OK(status)) { - return -1; - } - return 0; -} - -/* - convert a NDR formatted blob to a ldif formatted objectSid -*/ -static int ldif_write_objectSid(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - struct dom_sid *sid; - NTSTATUS status; - sid = talloc(mem_ctx, struct dom_sid); - if (sid == NULL) { - return -1; - } - status = ndr_pull_struct_blob(in, sid, sid, - (ndr_pull_flags_fn_t)ndr_pull_dom_sid); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(sid); - return -1; - } - out->data = (uint8_t *)dom_sid_string(mem_ctx, sid); - talloc_free(sid); - if (out->data == NULL) { - return -1; - } - out->length = strlen((const char *)out->data); - return 0; -} - -static BOOL ldb_comparision_objectSid_isString(const struct ldb_val *v) -{ - if (v->length < 3) { - return False; - } - - if (strncmp("S-", (const char *)v->data, 2) != 0) return False; - - return True; -} - -/* - compare two objectSids -*/ -static int ldb_comparison_objectSid(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *v1, const struct ldb_val *v2) -{ - if (ldb_comparision_objectSid_isString(v1) && ldb_comparision_objectSid_isString(v2)) { - return strcmp((const char *)v1->data, (const char *)v2->data); - } else if (ldb_comparision_objectSid_isString(v1) - && !ldb_comparision_objectSid_isString(v2)) { - struct ldb_val v; - int ret; - if (ldif_read_objectSid(ldb, mem_ctx, v1, &v) != 0) { - return -1; - } - ret = ldb_comparison_binary(ldb, mem_ctx, &v, v2); - talloc_free(v.data); - return ret; - } else if (!ldb_comparision_objectSid_isString(v1) - && ldb_comparision_objectSid_isString(v2)) { - struct ldb_val v; - int ret; - if (ldif_read_objectSid(ldb, mem_ctx, v2, &v) != 0) { - return -1; - } - ret = ldb_comparison_binary(ldb, mem_ctx, v1, &v); - talloc_free(v.data); - return ret; - } - return ldb_comparison_binary(ldb, mem_ctx, v1, v2); -} - -/* - canonicalise a objectSid -*/ -static int ldb_canonicalise_objectSid(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - if (ldb_comparision_objectSid_isString(in)) { - return ldif_read_objectSid(ldb, mem_ctx, in, out); - } - return ldb_handler_copy(ldb, mem_ctx, in, out); -} - -/* - convert a ldif formatted objectGUID to a NDR formatted blob -*/ -static int ldif_read_objectGUID(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - struct GUID guid; - NTSTATUS status; - - status = GUID_from_string((const char *)in->data, &guid); - if (!NT_STATUS_IS_OK(status)) { - return -1; - } - - status = ndr_push_struct_blob(out, mem_ctx, &guid, - (ndr_push_flags_fn_t)ndr_push_GUID); - if (!NT_STATUS_IS_OK(status)) { - return -1; - } - return 0; -} - -/* - convert a NDR formatted blob to a ldif formatted objectGUID -*/ -static int ldif_write_objectGUID(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - struct GUID guid; - NTSTATUS status; - status = ndr_pull_struct_blob(in, mem_ctx, &guid, - (ndr_pull_flags_fn_t)ndr_pull_GUID); - if (!NT_STATUS_IS_OK(status)) { - return -1; - } - out->data = (uint8_t *)GUID_string(mem_ctx, &guid); - if (out->data == NULL) { - return -1; - } - out->length = strlen((const char *)out->data); - return 0; -} - -static BOOL ldb_comparision_objectGUID_isString(const struct ldb_val *v) -{ - struct GUID guid; - NTSTATUS status; - - if (v->length < 33) return False; - - /* see if the input if null-terninated (safety check for the below) */ - if (v->data[v->length] != '\0') return False; - - status = GUID_from_string((const char *)v->data, &guid); - if (!NT_STATUS_IS_OK(status)) { - return False; - } - - return True; -} - -/* - compare two objectGUIDs -*/ -static int ldb_comparison_objectGUID(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *v1, const struct ldb_val *v2) -{ - if (ldb_comparision_objectGUID_isString(v1) && ldb_comparision_objectGUID_isString(v2)) { - return strcmp((const char *)v1->data, (const char *)v2->data); - } else if (ldb_comparision_objectGUID_isString(v1) - && !ldb_comparision_objectGUID_isString(v2)) { - struct ldb_val v; - int ret; - if (ldif_read_objectGUID(ldb, mem_ctx, v1, &v) != 0) { - return -1; - } - ret = ldb_comparison_binary(ldb, mem_ctx, &v, v2); - talloc_free(v.data); - return ret; - } else if (!ldb_comparision_objectGUID_isString(v1) - && ldb_comparision_objectGUID_isString(v2)) { - struct ldb_val v; - int ret; - if (ldif_read_objectGUID(ldb, mem_ctx, v2, &v) != 0) { - return -1; - } - ret = ldb_comparison_binary(ldb, mem_ctx, v1, &v); - talloc_free(v.data); - return ret; - } - return ldb_comparison_binary(ldb, mem_ctx, v1, v2); -} - -/* - canonicalise a objectGUID -*/ -static int ldb_canonicalise_objectGUID(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - if (ldb_comparision_objectGUID_isString(in)) { - return ldif_read_objectGUID(ldb, mem_ctx, in, out); - } - return ldb_handler_copy(ldb, mem_ctx, in, out); -} - - -/* - convert a ldif (SDDL) formatted ntSecurityDescriptor to a NDR formatted blob -*/ -static int ldif_read_ntSecurityDescriptor(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - struct security_descriptor *sd; - NTSTATUS status; - - sd = sddl_decode(mem_ctx, (const char *)in->data, NULL); - if (sd == NULL) { - return -1; - } - status = ndr_push_struct_blob(out, mem_ctx, sd, - (ndr_push_flags_fn_t)ndr_push_security_descriptor); - talloc_free(sd); - if (!NT_STATUS_IS_OK(status)) { - return -1; - } - return 0; -} - -/* - convert a NDR formatted blob to a ldif formatted ntSecurityDescriptor (SDDL format) -*/ -static int ldif_write_ntSecurityDescriptor(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - struct security_descriptor *sd; - NTSTATUS status; - - sd = talloc(mem_ctx, struct security_descriptor); - if (sd == NULL) { - return -1; - } - status = ndr_pull_struct_blob(in, sd, sd, - (ndr_pull_flags_fn_t)ndr_pull_security_descriptor); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(sd); - return -1; - } - out->data = (uint8_t *)sddl_encode(mem_ctx, sd, NULL); - talloc_free(sd); - if (out->data == NULL) { - return -1; - } - out->length = strlen((const char *)out->data); - return 0; -} - -/* - canonicolise an objectCategory. We use the short form as the cannoical form: - cn=Person,cn=Schema,cn=Configuration,<basedn> becomes 'person' -*/ - -static int ldif_canonicalise_objectCategory(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - struct ldb_dn *dn1 = NULL; - char *oc1, *oc2; - - dn1 = ldb_dn_explode(mem_ctx, (char *)in->data); - if (dn1 == NULL) { - oc1 = talloc_strndup(mem_ctx, (char *)in->data, in->length); - } else if (ldb_dn_get_comp_num(dn1) >= 1 && strcasecmp(ldb_dn_get_rdn_name(dn1), "cn") == 0) { - const struct ldb_val *val = ldb_dn_get_rdn_val(dn1); - oc1 = talloc_strndup(mem_ctx, (char *)val->data, val->length); - } else { - return -1; - } - - oc2 = ldb_casefold(ldb, mem_ctx, oc1); - out->data = (void *)oc2; - out->length = strlen(oc2); - talloc_free(oc1); - talloc_free(dn1); - return 0; -} - -static int ldif_comparison_objectCategory(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *v1, - const struct ldb_val *v2) -{ - struct ldb_dn *dn1 = NULL, *dn2 = NULL; - const char *oc1, *oc2; - - dn1 = ldb_dn_explode(mem_ctx, (char *)v1->data); - if (dn1 == NULL) { - oc1 = talloc_strndup(mem_ctx, (char *)v1->data, v1->length); - } else if (ldb_dn_get_comp_num(dn1) >= 1 && strcasecmp(ldb_dn_get_rdn_name(dn1), "cn") == 0) { - const struct ldb_val *val = ldb_dn_get_rdn_val(dn1); - oc1 = talloc_strndup(mem_ctx, (char *)val->data, val->length); - } else { - oc1 = NULL; - } - - dn2 = ldb_dn_explode(mem_ctx, (char *)v2->data); - if (dn2 == NULL) { - oc2 = talloc_strndup(mem_ctx, (char *)v2->data, v2->length); - } else if (ldb_dn_get_comp_num(dn2) >= 2 && strcasecmp(ldb_dn_get_rdn_name(dn2), "cn") == 0) { - const struct ldb_val *val = ldb_dn_get_rdn_val(dn2); - oc2 = talloc_strndup(mem_ctx, (char *)val->data, val->length); - } else { - oc2 = NULL; - } - - oc1 = ldb_casefold(ldb, mem_ctx, oc1); - oc2 = ldb_casefold(ldb, mem_ctx, oc2); - if (!oc1 && oc2) { - return -1; - } - if (oc1 && !oc2) { - return 1; - } - if (!oc1 && !oc2) { - return -1; - } - - return strcmp(oc1, oc2); -} - -static const struct ldb_attrib_handler samba_handlers[] = { - { - .attr = "objectSid", - .flags = 0, - .ldif_read_fn = ldif_read_objectSid, - .ldif_write_fn = ldif_write_objectSid, - .canonicalise_fn = ldb_canonicalise_objectSid, - .comparison_fn = ldb_comparison_objectSid - }, - { - .attr = "securityIdentifier", - .flags = 0, - .ldif_read_fn = ldif_read_objectSid, - .ldif_write_fn = ldif_write_objectSid, - .canonicalise_fn = ldb_canonicalise_objectSid, - .comparison_fn = ldb_comparison_objectSid - }, - { - .attr = "ntSecurityDescriptor", - .flags = 0, - .ldif_read_fn = ldif_read_ntSecurityDescriptor, - .ldif_write_fn = ldif_write_ntSecurityDescriptor, - .canonicalise_fn = ldb_handler_copy, - .comparison_fn = ldb_comparison_binary - }, - { - .attr = "objectGUID", - .flags = 0, - .ldif_read_fn = ldif_read_objectGUID, - .ldif_write_fn = ldif_write_objectGUID, - .canonicalise_fn = ldb_canonicalise_objectGUID, - .comparison_fn = ldb_comparison_objectGUID - }, - { - .attr = "invocationId", - .flags = 0, - .ldif_read_fn = ldif_read_objectGUID, - .ldif_write_fn = ldif_write_objectGUID, - .canonicalise_fn = ldb_canonicalise_objectGUID, - .comparison_fn = ldb_comparison_objectGUID - }, - { - .attr = "schemaIDGUID", - .flags = 0, - .ldif_read_fn = ldif_read_objectGUID, - .ldif_write_fn = ldif_write_objectGUID, - .canonicalise_fn = ldb_canonicalise_objectGUID, - .comparison_fn = ldb_comparison_objectGUID - }, - { - .attr = "attributeSecurityGUID", - .flags = 0, - .ldif_read_fn = ldif_read_objectGUID, - .ldif_write_fn = ldif_write_objectGUID, - .canonicalise_fn = ldb_canonicalise_objectGUID, - .comparison_fn = ldb_comparison_objectGUID - }, - { - .attr = "parentGUID", - .flags = 0, - .ldif_read_fn = ldif_read_objectGUID, - .ldif_write_fn = ldif_write_objectGUID, - .canonicalise_fn = ldb_canonicalise_objectGUID, - .comparison_fn = ldb_comparison_objectGUID - }, - { - .attr = "siteGUID", - .flags = 0, - .ldif_read_fn = ldif_read_objectGUID, - .ldif_write_fn = ldif_write_objectGUID, - .canonicalise_fn = ldb_canonicalise_objectGUID, - .comparison_fn = ldb_comparison_objectGUID - }, - { - .attr = "pKTGUID", - .flags = 0, - .ldif_read_fn = ldif_read_objectGUID, - .ldif_write_fn = ldif_write_objectGUID, - .canonicalise_fn = ldb_canonicalise_objectGUID, - .comparison_fn = ldb_comparison_objectGUID - }, - { - .attr = "fRSVersionGUID", - .flags = 0, - .ldif_read_fn = ldif_read_objectGUID, - .ldif_write_fn = ldif_write_objectGUID, - .canonicalise_fn = ldb_canonicalise_objectGUID, - .comparison_fn = ldb_comparison_objectGUID - }, - { - .attr = "fRSReplicaSetGUID", - .flags = 0, - .ldif_read_fn = ldif_read_objectGUID, - .ldif_write_fn = ldif_write_objectGUID, - .canonicalise_fn = ldb_canonicalise_objectGUID, - .comparison_fn = ldb_comparison_objectGUID - }, - { - .attr = "netbootGUID", - .flags = 0, - .ldif_read_fn = ldif_read_objectGUID, - .ldif_write_fn = ldif_write_objectGUID, - .canonicalise_fn = ldb_canonicalise_objectGUID, - .comparison_fn = ldb_comparison_objectGUID - }, - { - .attr = "objectCategory", - .flags = 0, - .ldif_read_fn = ldb_handler_copy, - .ldif_write_fn = ldb_handler_copy, - .canonicalise_fn = ldif_canonicalise_objectCategory, - .comparison_fn = ldif_comparison_objectCategory, - } -}; - -/* - register the samba ldif handlers -*/ -int ldb_register_samba_handlers(struct ldb_context *ldb) -{ - return ldb_set_attrib_handlers(ldb, samba_handlers, ARRAY_SIZE(samba_handlers)); -} diff --git a/source/lib/ldb/sqlite3.m4 b/source/lib/ldb/sqlite3.m4 deleted file mode 100644 index d0a74ee53cc..00000000000 --- a/source/lib/ldb/sqlite3.m4 +++ /dev/null @@ -1,62 +0,0 @@ -######################################################## -# Compile with SQLITE3 support? - -SQLITE3_LIBS="" -with_sqlite3_support=no -AC_MSG_CHECKING([for SQLITE3 support]) - -AC_ARG_WITH(sqlite3, -AS_HELP_STRING([--with-sqlite3],[SQLITE3 backend support (default=no)]), -[ case "$withval" in - yes|no|auto) - with_sqlite3_support=$withval - ;; - esac ]) - -AC_MSG_RESULT($with_sqlite3_support) - -if test x"$with_sqlite3_support" != x"no"; then - ################################################################## - # first test for sqlite3.h - AC_CHECK_HEADERS(sqlite3.h) - - if test x"$ac_cv_header_sqlite3_h" != x"yes"; then - if test x"$with_sqlite3_support" = x"yes"; then - AC_MSG_ERROR(sqlite3.h is needed for SQLITE3 support) - else - AC_MSG_WARN(sqlite3.h is needed for SQLITE3 support) - fi - - with_sqlite3_support=no - fi -fi - -if test x"$with_sqlite3_support" != x"no"; then - ac_save_LIBS=$LIBS - - ######################################################## - # now see if we can find the sqlite3 libs in standard paths - AC_CHECK_LIB_EXT(sqlite3, SQLITE3_LIBS, sqlite3_open) - - if test x"$ac_cv_lib_ext_sqlite3_sqlite3_open" = x"yes"; then - AC_DEFINE(HAVE_SQLITE3,1,[Whether sqlite3 is available]) - AC_DEFINE(HAVE_LDB_SQLITE3,1,[Whether ldb_sqlite3 is available]) - AC_MSG_CHECKING(whether SQLITE3 support is used) - AC_MSG_RESULT(yes) - with_sqlite3_support=yes - SMB_ENABLE(SQLITE3,YES) - else - if test x"$with_sqlite3_support" = x"yes"; then - AC_MSG_ERROR(libsqlite3 is needed for SQLITE3 support) - else - AC_MSG_WARN(libsqlite3 is needed for SQLITE3 support) - fi - - SQLITE3_LIBS="" - with_sqlite3_support=no - fi - - LIBS=$ac_save_LIBS; -fi - -SMB_EXT_LIB(SQLITE3,[${SQLITE3_LIBS}],[${SQLITE3_CFLAGS}],[${SQLITE3_CPPFLAGS}],[${SQLITE3_LDFLAGS}]) diff --git a/source/lib/ldb/standalone.sh b/source/lib/ldb/standalone.sh deleted file mode 100755 index fa1b9bafe3b..00000000000 --- a/source/lib/ldb/standalone.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/sh - -cd ../replace -make clean - -cd ../talloc -make clean - -cd ../tdb -make clean - -cd ../ldb -make clean - -./autogen.sh - -rm -fr build -mkdir build -cd build - -../configure $* -make dirs -make all - -cd .. diff --git a/source/lib/ldb/swig/Ldb.py b/source/lib/ldb/swig/Ldb.py deleted file mode 100644 index c7e6191c8a6..00000000000 --- a/source/lib/ldb/swig/Ldb.py +++ /dev/null @@ -1,179 +0,0 @@ -"""Provide a more Pythonic and object-oriented interface to ldb.""" - -# -# Swig interface to Samba -# -# Copyright (C) Tim Potter 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. -# - -# -# Interface notes: -# -# - should an empty dn be represented as None, or an empty string? -# -# - should single-valued attributes be a string, or a list with one -# element? -# - -from ldb import * - -# Global initialisation - -result = ldb_global_init() - -if result != 0: - raise LdbError, (result, 'ldb_global_init failed') - -# Ldb exceptions - -class LdbError(Exception): - """An exception raised when a ldb error occurs. - The exception data is a tuple consisting of the ldb number and a - string description of the error.""" - pass - -# Ldb classes - -class LdbMessage: - """A class representing a ldb message as a Python dictionary.""" - - def __init__(self): - self.mem_ctx = talloc_init(None) - self.msg = ldb_msg_new(self.mem_ctx) - - def __del__(self): - if self.mem_ctx is not None: - talloc_free(self.mem_ctx) - self.mem_ctx = None - self.msg = None - - # Make the dn attribute of the object dynamic - - def __getattr__(self, attr): - if attr == 'dn': - return ldb_dn_linearize(None, self.msg.dn) - return self.__dict__[attr] - - def __setattr__(self, attr, value): - if attr == 'dn': - self.msg.dn = ldb_dn_explode(self.msg, value) - if self.msg.dn == None: - err = LDB_ERR_INVALID_DN_SYNTAX - raise LdbError(err, ldb_strerror(err)) - return - self.__dict__[attr] = value - - # Get and set individual elements - - def __getitem__(self, key): - - elt = ldb_msg_find_element(self.msg, key) - - if elt is None: - raise KeyError, "No such attribute '%s'" % key - - return [ldb_val_array_getitem(elt.values, i) - for i in range(elt.num_values)] - - def __setitem__(self, key, value): - ldb_msg_remove_attr(self.msg, key) - if type(value) in (list, tuple): - [ldb_msg_add_value(self.msg, key, v) for v in value] - else: - ldb_msg_add_value(self.msg, key, value) - - # Dictionary interface - # TODO: move to iterator based interface - - def len(self): - return self.msg.num_elements - - def keys(self): - return [ldb_message_element_array_getitem(self.msg.elements, i).name - for i in range(self.msg.num_elements)] - - def values(self): - return [self[k] for k in self.keys()] - - def items(self): - return [(k, self[k]) for k in self.keys()] - - # Misc stuff - - def sanity_check(self): - return ldb_msg_sanity_check(self.msg) - -class Ldb: - """A class representing a binding to a ldb file.""" - - def __init__(self, url, flags = 0): - """Initialise underlying ldb.""" - - self.mem_ctx = talloc_init('mem_ctx for ldb 0x%x' % id(self)) - self.ldb_ctx = ldb_init(self.mem_ctx) - - result = ldb_connect(self.ldb_ctx, url, flags, None) - - if result != LDB_SUCCESS: - raise LdbError, (result, ldb_strerror(result)) - - def __del__(self): - """Called when the object is to be garbage collected.""" - self.close() - - def close(self): - """Close down a ldb.""" - if self.mem_ctx is not None: - talloc_free(self.mem_ctx) - self.mem_ctx = None - self.ldb_ctx = None - - def _ldb_call(self, fn, *args): - """Call a ldb function with args. Raise a LdbError exception - if the function returns a non-zero return value.""" - - result = fn(*args) - - if result != LDB_SUCCESS: - raise LdbError, (result, ldb_strerror(result)) - - def search(self, expression): - """Search a ldb for a given expression.""" - - self._ldb_call(ldb_search, self.ldb_ctx, None, LDB_SCOPE_DEFAULT, - expression, None); - - return [LdbMessage(ldb_message_ptr_array_getitem(result.msgs, ndx)) - for ndx in range(result.count)] - - def delete(self, dn): - """Delete a dn.""" - - _dn = ldb_dn_explode(self.ldb_ctx, dn) - - self._ldb_call(ldb_delete, self.ldb_ctx, _dn) - - def rename(self, olddn, newdn): - """Rename a dn.""" - - _olddn = ldb_dn_explode(self.ldb_ctx, olddn) - _newdn = ldb_dn_explode(self.ldb_ctx, newdn) - - self._ldb_call(ldb_rename, self.ldb_ctx, _olddn, _newdn) - - def add(self, m): - self._ldb_call(ldb_add, self.ldb_ctx, m.msg) diff --git a/source/lib/ldb/swig/ldb.i b/source/lib/ldb/swig/ldb.i deleted file mode 100644 index 09d3461c2a9..00000000000 --- a/source/lib/ldb/swig/ldb.i +++ /dev/null @@ -1,240 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Swig interface to ldb. - - Copyright (C) 2005,2006 Tim Potter <tpot@samba.org> - Copyright (C) 2006 Simo Sorce <idra@samba.org> - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -%module ldb - -%{ - -/* Some typedefs to help swig along */ - -typedef unsigned char uint8_t; -typedef unsigned long long uint64_t; -typedef long long int64_t; - -/* Include headers */ - -#include "lib/ldb/include/ldb.h" -#include "lib/talloc/talloc.h" - -%} - -%include "carrays.i" -%include "exception.i" - -/* - * Constants - */ - -#define LDB_SUCCESS 0 -#define LDB_ERR_OPERATIONS_ERROR 1 -#define LDB_ERR_PROTOCOL_ERROR 2 -#define LDB_ERR_TIME_LIMIT_EXCEEDED 3 -#define LDB_ERR_SIZE_LIMIT_EXCEEDED 4 -#define LDB_ERR_COMPARE_FALSE 5 -#define LDB_ERR_COMPARE_TRUE 6 -#define LDB_ERR_AUTH_METHOD_NOT_SUPPORTED 7 -#define LDB_ERR_STRONG_AUTH_REQUIRED 8 -/* 9 RESERVED */ -#define LDB_ERR_REFERRAL 10 -#define LDB_ERR_ADMIN_LIMIT_EXCEEDED 11 -#define LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION 12 -#define LDB_ERR_CONFIDENTIALITY_REQUIRED 13 -#define LDB_ERR_SASL_BIND_IN_PROGRESS 14 -#define LDB_ERR_NO_SUCH_ATTRIBUTE 16 -#define LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE 17 -#define LDB_ERR_INAPPROPRIATE_MATCHING 18 -#define LDB_ERR_CONSTRAINT_VIOLATION 19 -#define LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS 20 -#define LDB_ERR_INVALID_ATTRIBUTE_SYNTAX 21 -/* 22-31 unused */ -#define LDB_ERR_NO_SUCH_OBJECT 32 -#define LDB_ERR_ALIAS_PROBLEM 33 -#define LDB_ERR_INVALID_DN_SYNTAX 34 -/* 35 RESERVED */ -#define LDB_ERR_ALIAS_DEREFERENCING_PROBLEM 36 -/* 37-47 unused */ -#define LDB_ERR_INAPPROPRIATE_AUTHENTICATION 48 -#define LDB_ERR_INVALID_CREDENTIALS 49 -#define LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS 50 -#define LDB_ERR_BUSY 51 -#define LDB_ERR_UNAVAILABLE 52 -#define LDB_ERR_UNWILLING_TO_PERFORM 53 -#define LDB_ERR_LOOP_DETECT 54 -/* 55-63 unused */ -#define LDB_ERR_NAMING_VIOLATION 64 -#define LDB_ERR_OBJECT_CLASS_VIOLATION 65 -#define LDB_ERR_NOT_ALLOWED_ON_NON_LEAF 66 -#define LDB_ERR_NOT_ALLOWED_ON_RDN 67 -#define LDB_ERR_ENTRY_ALREADY_EXISTS 68 -#define LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED 69 -/* 70 RESERVED FOR CLDAP */ -#define LDB_ERR_AFFECTS_MULTIPLE_DSAS 71 -/* 72-79 unused */ -#define LDB_ERR_OTHER 80 - -enum ldb_scope {LDB_SCOPE_DEFAULT=-1, - LDB_SCOPE_BASE=0, - LDB_SCOPE_ONELEVEL=1, - LDB_SCOPE_SUBTREE=2}; - -/* - * Wrap struct ldb_context - */ - -/* The ldb functions will crash if a NULL ldb context is passed so - catch this before it happens. */ - -%typemap(check) struct ldb_context* { - if ($1 == NULL) - SWIG_exception(SWIG_ValueError, - "ldb context must be non-NULL"); -} - -/* - * Wrap a small bit of talloc - */ - -/* Use talloc_init() to create a parameter to pass to ldb_init(). Don't - forget to free it using talloc_free() afterwards. */ - -TALLOC_CTX *talloc_init(char *name); -int talloc_free(TALLOC_CTX *ptr); - -/* - * Wrap struct ldb_val - */ - -%typemap(in) struct ldb_val *INPUT (struct ldb_val temp) { - $1 = &temp; - if (!PyString_Check($input)) { - PyErr_SetString(PyExc_TypeError, "string arg expected"); - return NULL; - } - $1->length = PyString_Size($input); - $1->data = PyString_AsString($input); -} - -%typemap(out) struct ldb_val { - $result = PyString_FromStringAndSize($1.data, $1.length); -} - -/* - * Wrap struct ldb_result - */ - -%typemap(in, numinputs=0) struct ldb_result **OUT (struct ldb_result *temp_ldb_result) { - $1 = &temp_ldb_result; -} - -%typemap(argout) struct ldb_result ** { - resultobj = SWIG_NewPointerObj(*$1, SWIGTYPE_p_ldb_result, 0); -} - -%types(struct ldb_result *); - -/* - * Wrap struct ldb_message_element - */ - -%array_functions(struct ldb_val, ldb_val_array); - -struct ldb_message_element { - unsigned int flags; - const char *name; - unsigned int num_values; - struct ldb_val *values; -}; - -/* - * Wrap struct ldb_message - */ - -%array_functions(struct ldb_message_element, ldb_message_element_array); - -struct ldb_message { - struct ldb_dn *dn; - unsigned int num_elements; - struct ldb_message_element *elements; - void *private_data; -}; - -/* - * Wrap struct ldb_result - */ - -%array_functions(struct ldb_message *, ldb_message_ptr_array); - -struct ldb_result { - unsigned int count; - struct ldb_message **msgs; - char **refs; - struct ldb_control **controls; -}; - -/* - * Wrap ldb functions - */ - -/* Initialisation */ - -int ldb_global_init(void); -struct ldb_context *ldb_init(TALLOC_CTX *mem_ctx); - -/* Error handling */ - -const char *ldb_errstring(struct ldb_context *ldb); -const char *ldb_strerror(int ldb_err); - -/* Top-level ldb operations */ - -int ldb_connect(struct ldb_context *ldb, const char *url, unsigned int flags, const char *options[]); - -int ldb_search(struct ldb_context *ldb, const struct ldb_dn *base, enum ldb_scope scope, const char *expression, const char * const *attrs, struct ldb_result **OUT); - -int ldb_delete(struct ldb_context *ldb, const struct ldb_dn *dn); - -int ldb_rename(struct ldb_context *ldb, const struct ldb_dn *olddn, const struct ldb_dn *newdn); - -int ldb_add(struct ldb_context *ldb, const struct ldb_message *message); - -/* Ldb message operations */ - -struct ldb_message *ldb_msg_new(void *mem_ctx); - -struct ldb_message_element *ldb_msg_find_element(const struct ldb_message *msg, const char *attr_name); - -int ldb_msg_add_value(struct ldb_message *msg, const char *attr_name, const struct ldb_val *INPUT); - -void ldb_msg_remove_attr(struct ldb_message *msg, const char *attr); - -int ldb_msg_sanity_check(struct ldb_message *msg); - -/* DN operations */ - -struct ldb_dn *ldb_dn_explode(void *mem_ctx, const char *dn); - -char *ldb_dn_linearize(void *mem_ctx, const struct ldb_dn *dn); diff --git a/source/lib/ldb/tests/init.ldif b/source/lib/ldb/tests/init.ldif deleted file mode 100644 index 2e0b83c7695..00000000000 --- a/source/lib/ldb/tests/init.ldif +++ /dev/null @@ -1,40 +0,0 @@ -dn: o=University of Michigan,c=TEST -objectclass: organization -objectclass: domainRelatedObject -l: Ann Arbor, Michigan -st: Michigan -o: University of Michigan -o: UMICH -o: UM -o: U-M -o: U of M -description: The University of Michigan at Ann Arbor -seeAlso: -postaladdress: University of Michigan $ 535 W. William St. $ Ann Arbor, MI 481 - 09 $ US -telephonenumber: +1 313 764-1817 -associateddomain: example.com - -dn: ou=People,o=University of Michigan,c=TEST -objectclass: organizationalUnit -objectclass: extensibleObject -ou: People -uidNumber: 0 -gidNumber: 0 - -dn: ou=Ldb Test,ou=People,o=University of Michigan,c=TEST -objectclass: organizationalUnit -objectclass: extensibleObject -ou: People -ou: Ldb Test -uidNumber: 0 -gidNumber: 0 - -dn: ou=LdbTspace,ou=People,o=University of Michigan,c=TEST -objectclass: organizationalUnit -objectclass: extensibleObject -ou: People -ou: LdbTspace -description: test white space removal in comparisons -uidNumber: 0 -gidNumber: 0 diff --git a/source/lib/ldb/tests/init_slapd.sh b/source/lib/ldb/tests/init_slapd.sh deleted file mode 100755 index cf06acd08b9..00000000000 --- a/source/lib/ldb/tests/init_slapd.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/sh - -if [ -z "$LDBDIR" ]; then - LDBDIR=`dirname $0`/.. - export LDBDIR -fi - -rm -rf tests/tmp/db -mkdir -p tests/tmp/db - -if [ -f tests/tmp/slapd.pid ]; then - kill `cat tests/tmp/slapd.pid` - sleep 1 -fi -if [ -f tests/tmp/slapd.pid ]; then - kill -9 `cat tests/tmp/slapd.pid` - rm -f tests/tmp/slapd.pid -fi - -# we don't consider a slapadd failure as a test suite failure, as it -# has nothing to do with ldb - -MODCONF=tests/tmp/modules.conf -rm -f $MODCONF -touch $MODCONF || exit 1 - -slaptest -u -f $LDBDIR/tests/slapd.conf > /dev/null 2>&1 || { - echo "enabling sladp modules" -cat > $MODCONF <<EOF -modulepath /usr/lib/ldap -moduleload back_bdb -EOF -} - -slaptest -u -f $LDBDIR/tests/slapd.conf || { - echo "slaptest failed - skipping ldap tests" - exit 0 -} - -slapadd -f $LDBDIR/tests/slapd.conf < $LDBDIR/tests/init.ldif || exit 0 - diff --git a/source/lib/ldb/tests/kill_slapd.sh b/source/lib/ldb/tests/kill_slapd.sh deleted file mode 100755 index 91beb108149..00000000000 --- a/source/lib/ldb/tests/kill_slapd.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh - -if [ -z "$LDBDIR" ]; then - LDBDIR=`dirname $0`/.. - export LDBDIR -fi - -if [ -f tests/tmp/slapd.pid ]; then - echo "killing slapd process `cat tests/tmp/slapd.pid`" - kill -9 `cat tests/tmp/slapd.pid` - rm -f tests/tmp/slapd.pid -fi diff --git a/source/lib/ldb/tests/ldapi_url.sh b/source/lib/ldb/tests/ldapi_url.sh deleted file mode 100755 index fef6c35f2be..00000000000 --- a/source/lib/ldb/tests/ldapi_url.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh - -# aargh, did LDAP ever have to expose this crap to users ... - -BASE=`pwd` - -TMPDIR=$BASE/tests/tmp - -LDAPI_ESCAPE=`echo $TMPDIR/ldapi | sed 's|/|%2F|g'` - -echo "ldapi://$LDAPI_ESCAPE" diff --git a/source/lib/ldb/tests/photo.ldif b/source/lib/ldb/tests/photo.ldif deleted file mode 100644 index 28981b1f24b..00000000000 --- a/source/lib/ldb/tests/photo.ldif +++ /dev/null @@ -1,5 +0,0 @@ -dn: cn=Hampster Ursula,ou=Alumni Association,ou=People,o=University of Michigan,c=TEST -changetype: modify -add: jpegPhoto -jpegPhoto:< file://tests/tmp/samba4.png - diff --git a/source/lib/ldb/tests/samba4.png b/source/lib/ldb/tests/samba4.png Binary files differdeleted file mode 100644 index c8096889a67..00000000000 --- a/source/lib/ldb/tests/samba4.png +++ /dev/null diff --git a/source/lib/ldb/tests/schema-tests/schema-add-test.ldif b/source/lib/ldb/tests/schema-tests/schema-add-test.ldif deleted file mode 100644 index 997b801d840..00000000000 --- a/source/lib/ldb/tests/schema-tests/schema-add-test.ldif +++ /dev/null @@ -1,66 +0,0 @@ -dn: CN=Users,DC=schema,DC=test -objectClass: top -objectClass: container -cn: Users -description: Default container for upgraded user accounts -instanceType: 4 -whenCreated: 20050116175504.0Z -whenChanged: 20050116175504.0Z -uSNCreated: 1 -uSNChanged: 1 -showInAdvancedViewOnly: FALSE -name: Users -objectGUID: b847056a-9934-d87b-8a1a-99fabe0863c8 -systemFlags: 0x8c000000 -objectCategory: CN=Container,CN=Schema,CN=Configuration,DC=schema,DC=test -isCriticalSystemObject: TRUE -nTSecurityDescriptor: foo - -dn: CN=Administrator,CN=Users,DC=schema,DC=test -objectClass: top -objectClass: person -objectClass: organizationalPerson -objectClass: user -cn: Administrator -description: Built-in account for administering the computer/domain -instanceType: 4 -whenCreated: 20050116175504.0Z -whenChanged: 20050116175504.0Z -uSNCreated: 1 -memberOf: CN=Group Policy Creator Owners,CN=Users,DC=schema,DC=test -memberOf: CN=Domain Admins,CN=Users,DC=schema,DC=test -memberOf: CN=Enterprise Admins,CN=Users,DC=schema,DC=test -memberOf: CN=Schema Admins,CN=Users,DC=schema,DC=test -memberOf: CN=Administrators,CN=Builtin,DC=schema,DC=test -uSNChanged: 1 -name: Administrator -objectGUID: 6c02f98c-46c6-aa38-5f13-a510cac04e6c -userAccountControl: 0x10200 -badPwdCount: 0 -codePage: 0 -countryCode: 0 -badPasswordTime: 0 -lastLogoff: 0 -lastLogon: 0 -pwdLastSet: 0 -primaryGroupID: 513 -objectSid: S-1-5-21-43662522-77495566-38969261-500 -adminCount: 1 -accountExpires: -1 -logonCount: 0 -sAMAccountName: Administrator -sAMAccountType: 0x30000000 -objectCategory: CN=Person,CN=Schema,CN=Configuration,DC=schema,DC=test -isCriticalSystemObject: TRUE -unicodePwd: samba -nTSecurityDescriptor: foo - -dn: CN=Test,CN=Users,DC=schema,DC=test -objectClass: top -objectClass: test -cn: Test -description: This is a test -objectCategory: CN=Test,CN=Schema,CN=Configuration,DC=schema,DC=test -nTSecurityDescriptor: foo -instanceType: 4 - diff --git a/source/lib/ldb/tests/schema-tests/schema-mod-test-1.ldif b/source/lib/ldb/tests/schema-tests/schema-mod-test-1.ldif deleted file mode 100644 index b9767244854..00000000000 --- a/source/lib/ldb/tests/schema-tests/schema-mod-test-1.ldif +++ /dev/null @@ -1,5 +0,0 @@ -dn: CN=Test,CN=Users,DC=schema,DC=test -changetype: modify -replace: description -description: this test must not fail - diff --git a/source/lib/ldb/tests/schema-tests/schema-mod-test-2.ldif b/source/lib/ldb/tests/schema-tests/schema-mod-test-2.ldif deleted file mode 100644 index fa193af6832..00000000000 --- a/source/lib/ldb/tests/schema-tests/schema-mod-test-2.ldif +++ /dev/null @@ -1,5 +0,0 @@ -dn: CN=Test,CN=Users,DC=schema,DC=test -changetype: modify -delete: description -# this test must not fail - diff --git a/source/lib/ldb/tests/schema-tests/schema-mod-test-3.ldif b/source/lib/ldb/tests/schema-tests/schema-mod-test-3.ldif deleted file mode 100644 index 8ab7798f9ce..00000000000 --- a/source/lib/ldb/tests/schema-tests/schema-mod-test-3.ldif +++ /dev/null @@ -1,5 +0,0 @@ -dn: CN=Test,CN=Users,DC=schema,DC=test -changetype: modify -add: description -description: this test must not fail - diff --git a/source/lib/ldb/tests/schema-tests/schema-mod-test-4.ldif b/source/lib/ldb/tests/schema-tests/schema-mod-test-4.ldif deleted file mode 100644 index cbf0e60bbea..00000000000 --- a/source/lib/ldb/tests/schema-tests/schema-mod-test-4.ldif +++ /dev/null @@ -1,5 +0,0 @@ -dn: CN=Test,CN=Users,DC=schema,DC=test -changetype: modify -add: foo -foo: this test must fail - diff --git a/source/lib/ldb/tests/schema-tests/schema-mod-test-5.ldif b/source/lib/ldb/tests/schema-tests/schema-mod-test-5.ldif deleted file mode 100644 index bc64e9edb61..00000000000 --- a/source/lib/ldb/tests/schema-tests/schema-mod-test-5.ldif +++ /dev/null @@ -1,5 +0,0 @@ -dn: CN=Test,CN=Users,DC=schema,DC=test -changetype: modify -delete: nTSecurityDescriptor -# this test must fail - diff --git a/source/lib/ldb/tests/schema-tests/schema.ldif b/source/lib/ldb/tests/schema-tests/schema.ldif deleted file mode 100644 index 515408144ab..00000000000 --- a/source/lib/ldb/tests/schema-tests/schema.ldif +++ /dev/null @@ -1,112 +0,0 @@ -dn: @INDEXLIST -@IDXATTR: name -@IDXATTR: sAMAccountName -@IDXATTR: objectSid -@IDXATTR: objectClass -@IDXATTR: member -@IDXATTR: uidNumber -@IDXATTR: gidNumber -@IDXATTR: unixName -@IDXATTR: privilege -@IDXATTR: lDAPDisplayName - -dn: @ATTRIBUTES -realm: CASE_INSENSITIVE -userPrincipalName: CASE_INSENSITIVE -servicePrincipalName: CASE_INSENSITIVE -name: CASE_INSENSITIVE -dn: CASE_INSENSITIVE -sAMAccountName: CASE_INSENSITIVE -objectClass: CASE_INSENSITIVE -unicodePwd: HIDDEN -ntPwdHash: HIDDEN -ntPwdHistory: HIDDEN -lmPwdHash: HIDDEN -lmPwdHistory: HIDDEN -createTimestamp: HIDDEN -modifyTimestamp: HIDDEN - -dn: @SUBCLASSES -top: domain -top: person -top: group -domain: domainDNS -domain: builtinDomain -person: organizationalPerson -organizationalPerson: user -user: computer -template: userTemplate -template: groupTemplate - -dn: @MODULES -@LIST: timestamps,schema - -dn: CN=Top,CN=Schema,CN=Configuration,DC=schema,DC=test -objectClass: top -objectClass: classSchema -lDAPDisplayName: top -cn: Top -uSNCreated: 1 -uSNChanged: 1 -subClassOf: top -systemMustContain: objectClass -systemMayContain: structuralObjectClass -systemMayContain: createTimeStamp -systemMayContain: modifyTimeStamp -systemMayContain: creatorsName -systemMayContain: modifiersName -systemMayContain: hasSubordinates -systemMayContain: subschemaSubentry -systemMayContain: collectiveSubentry -systemMayContain: entryUUID -systemMayContain: entryCSN -systemMayContain: namingCSN -systemMayContain: superiorUUID -systemMayContain: contextCSN -systemMayContain: whenCreated -systemMayContain: whenChanged -systemMayContain: uSNCreated -systemMayContain: uSNChanged -systemMayContain: distinguishedName -systemMayContain: name -systemMayContain: cn -systemMayContain: userPassword -systemMayContain: labeledURI - -dn: CN=Class-Schema,CN=Schema,CN=Configuration,DC=schema,DC=test -objectClass: top -objectClass: classSchema -lDAPDisplayName: classSchema -cn: Class-Schema -uSNCreated: 2 -uSNChanged: 2 -lDAPDisplayName: classSchema -subClassOf: top -systemMustContain: cn -systemMustContain: subClassOf -systemMayContain: systemPossSuperiors -systemMayContain: systemOnly -systemMayContain: systemMustContain -systemMayContain: systemMayContain -systemMayContain: systemAuxiliaryClass -systemMayContain: possSuperiors -systemMayContain: mustContain -systemMayContain: mayContain -systemMayContain: lDAPDisplayName -systemMayContain: auxiliaryClass - -dn: CN=Attribute-Schema,CN=Schema,CN=Configuration,DC=schema,DC=test -objectClass: top -objectClass: classSchema -cn: Attribute-Schema -uSNCreated: 3 -uSNChanged: 3 -lDAPDisplayName: attributeSchema -subClassOf: top -systemMustContain: oMSyntax -systemMustContain: lDAPDisplayName -systemMustContain: isSingleValued -systemMustContain: cn -systemMustContain: attributeSyntax -systemMustContain: attributeID - diff --git a/source/lib/ldb/tests/slapd.conf b/source/lib/ldb/tests/slapd.conf deleted file mode 100644 index fa2789d8c17..00000000000 --- a/source/lib/ldb/tests/slapd.conf +++ /dev/null @@ -1,26 +0,0 @@ -loglevel 0 - -include tests/schema/core.schema -include tests/schema/cosine.schema -include tests/schema/inetorgperson.schema -include tests/schema/openldap.schema -include tests/schema/nis.schema - - -pidfile tests/tmp/slapd.pid -argsfile tests/tmp/slapd.args - -access to * by * write - -allow update_anon bind_anon_dn - -include tests/tmp/modules.conf - -defaultsearchbase "o=University of Michigan,c=TEST" - -backend bdb -database bdb -suffix "o=University of Michigan,c=TEST" -directory tests/tmp/db -index objectClass eq -index uid eq diff --git a/source/lib/ldb/tests/start_slapd.sh b/source/lib/ldb/tests/start_slapd.sh deleted file mode 100755 index 22e8548791a..00000000000 --- a/source/lib/ldb/tests/start_slapd.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -if [ -z "$LDBDIR" ]; then - LDBDIR=`dirname $0`/.. - export LDBDIR -fi - -mkdir -p $LDBDIR/tests/tmp/db - -# running slapd with -d0 means it stays in the same process group, so it can be -# killed by timelimit -slapd -d0 -f $LDBDIR/tests/slapd.conf -h "`$LDBDIR/tests/ldapi_url.sh`" $* & - -sleep 2 diff --git a/source/lib/ldb/tests/test-attribs.ldif b/source/lib/ldb/tests/test-attribs.ldif deleted file mode 100644 index 0bb3ebead68..00000000000 --- a/source/lib/ldb/tests/test-attribs.ldif +++ /dev/null @@ -1,15 +0,0 @@ -dn: @ATTRIBUTES -uid: CASE_INSENSITIVE -cn: CASE_INSENSITIVE -ou: CASE_INSENSITIVE -dn: CASE_INSENSITIVE - -dn: @SUBCLASSES -top: domain -top: person -domain: domainDNS -person: organizationalPerson -person: fooPerson -organizationalPerson: user -organizationalPerson: OpenLDAPperson -user: computer diff --git a/source/lib/ldb/tests/test-config.ldif b/source/lib/ldb/tests/test-config.ldif deleted file mode 100644 index 7926a9e3c58..00000000000 --- a/source/lib/ldb/tests/test-config.ldif +++ /dev/null @@ -1,67 +0,0 @@ -############################## -# global configuration options -dn: cn=Global,cn=Config,cn=Samba -objectclass: globalconfig -LocalConfigCn: cn=%U,cn=Config,cn=Samba -LocalConfigCn;1: cn=%U,cn=Config,cn=Samba -LocalConfigCn;2: cn=%I,cn=Config,cn=Samba -LocalConfigCn;3: cn=%M,cn=Config,cn=Samba - -############# -dn: cn=Protocol,cn=Global,cn=Config,cn=Samba -maxXmit: 7000 - -################################ -dn: cn=Volker,cn=Config,cn=Samba -Workgroup: VNET3 -UnixCharset: UTF8 -Security: user -Interfaces: vmnet* eth* -NetbiosName: blu -GuestAccount: tridge - -################################# -dn: cn=Volker,cn=Config,cn=Samba -Workgroup: VNET3 -UnixCharset: UTF8 -Security: user -Interfaces: vmnet* eth* -NetbiosName: blu -GuestAccount: tridge -Include: cn=%U,cn=MyConfig,cn=Config,cn=Samba - -#### ((objectClass=fileshare)(cn=test)) -############################## -# [test] share -dn: cn=test,cn=Shares,cn=Config,cn=Samba -objectclass: fileshare -cn: test -Comment: a test share -Path: /home/tridge/samba4/prefix/test -ReadOnly: no - -##################################### -# [msdn] a remote proxy share, stored -# on \\msdn\test -dn: cn=msdn,cn=Shares,cn=Config,cn=Samba -objectclass: fileshare -cn: msdn -NtvfsHandler: cifs -ReadOnly: no -_CifsServer: msdn -_CifsUser: administrator -_CifsPassword: penguin -_CifsDomain: winxp -_CifsShare: test - - -############################## -# [VisualC] share -dn: cn=visualc,cn=Shares,cn=Config,cn=Samba -objectclass: fileshare -cn: VisualC -Comment: VisualC development -Path: /home/tridge/VisualC -ReadOnly: no -NtvfsHandler: simple - diff --git a/source/lib/ldb/tests/test-default-config.ldif b/source/lib/ldb/tests/test-default-config.ldif deleted file mode 100644 index 87b7bcd3cc7..00000000000 --- a/source/lib/ldb/tests/test-default-config.ldif +++ /dev/null @@ -1,17 +0,0 @@ -############################## -# global configuration options -dn: cn=Global,cn=DefaultConfig,cn=Samba -objectclass: globalconfig -Workgroup: WORKGROUP -UnixCharset: UTF8 -Security: user -NetbiosName: blu -GuestAccount: nobody - -############################## -# [_default_] share -dn: cn=_default_,cn=Shares,cn=DefaultConfig,cn=Samba -objectclass: fileshare -cn: _default_ -Path: /tmp -ReadOnly: yes diff --git a/source/lib/ldb/tests/test-extended.sh b/source/lib/ldb/tests/test-extended.sh deleted file mode 100755 index a84e3b78a38..00000000000 --- a/source/lib/ldb/tests/test-extended.sh +++ /dev/null @@ -1,69 +0,0 @@ -#!/bin/sh - -echo "Running extended search tests" - -mv $LDB_URL $LDB_URL.1 - -cat <<EOF | bin/ldbadd || exit 1 -dn: cn=testrec1,cn=TEST -i1: 1 -i2: 0 -i3: 1234 -i4: 0x7003004 - -dn: cn=testrec2,cn=TEST -i1: 0x800000 - -dn: cn=testrec3,cn=TEST -i1: 0x101010101 -i1: 7 - -dn: cn=auser1,cn=TEST -groupType: 2147483648 -samAccountType: 805306368 - -dn: cn=auser2,cn=TEST -groupType: 2147483648 -samAccountType: 805306369 - -dn: cn=auser3,cn=TEST -groupType: 2147483649 -samAccountType: 805306370 - -dn: cn=auser4,cn=TEST -groupType: 2147483649 -samAccountType: 805306369 -EOF - -checkcount() { - count=$1 - expression="$2" - n=`bin/ldbsearch "$expression" | grep '^dn' | wc -l` - if [ $n != $count ]; then - echo "Got $n but expected $count for $expression" - bin/ldbsearch "$expression" - exit 1 - fi - echo "OK: $count $expression" -} - -checkcount 1 '(i3=1234)' -checkcount 0 '(i3=12345)' - -checkcount 2 '(i1:1.2.840.113556.1.4.803:=1)' -checkcount 1 '(i1:1.2.840.113556.1.4.803:=3)' -checkcount 1 '(i1:1.2.840.113556.1.4.803:=7)' -checkcount 0 '(i1:1.2.840.113556.1.4.803:=15)' -checkcount 1 '(i1:1.2.840.113556.1.4.803:=0x800000)' -checkcount 1 '(i1:1.2.840.113556.1.4.803:=8388608)' - -checkcount 2 '(i1:1.2.840.113556.1.4.804:=1)' -checkcount 2 '(i1:1.2.840.113556.1.4.804:=3)' -checkcount 2 '(i1:1.2.840.113556.1.4.804:=7)' -checkcount 2 '(i1:1.2.840.113556.1.4.804:=15)' -checkcount 1 '(i1:1.2.840.113556.1.4.804:=0x800000)' -checkcount 1 '(i1:1.2.840.113556.1.4.804:=8388608)' - -# this is one that w2k gives -checkcount 3 '(|(|(&(!(groupType:1.2.840.113556.1.4.803:=1))(groupType:1.2.840.113556.1.4.803:=2147483648)(groupType:1.2.840.113556.1.4.804:=10))(samAccountType=805306368))(samAccountType=805306369))' - diff --git a/source/lib/ldb/tests/test-generic.sh b/source/lib/ldb/tests/test-generic.sh deleted file mode 100755 index 14337cc1352..00000000000 --- a/source/lib/ldb/tests/test-generic.sh +++ /dev/null @@ -1,128 +0,0 @@ -#!/bin/sh - -if [ -z "$LDB_SPECIALS" ]; then - LDB_SPECIALS=1 - export LDB_SPECIALS -fi - -echo "LDB_URL: $LDB_URL" - -echo "Adding base elements" -$VALGRIND ldbadd $LDBDIR/tests/test.ldif || exit 1 - -echo "Adding again - should fail" -ldbadd $LDBDIR/tests/test.ldif 2> /dev/null && { - echo "Should have failed to add again - gave $?" - exit 1 -} - -echo "Modifying elements" -$VALGRIND ldbmodify $LDBDIR/tests/test-modify.ldif || exit 1 - -echo "Showing modified record" -$VALGRIND ldbsearch '(uid=uham)' || exit 1 - -echo "Rename entry" -OLDDN="cn=Ursula Hampster,ou=Alumni Association,ou=People,o=University of Michigan,c=TEST" -NEWDN="cn=Hampster Ursula,ou=Alumni Association,ou=People,o=University of Michigan,c=TEST" -$VALGRIND ldbrename "$OLDDN" "$NEWDN" || exit 1 - -echo "Showing renamed record" -$VALGRIND ldbsearch '(uid=uham)' || exit 1 - -echo "Starting ldbtest" -$VALGRIND ldbtest --num-records 100 --num-searches 10 || exit 1 - -if [ $LDB_SPECIALS = 1 ]; then - echo "Adding index" - $VALGRIND ldbadd $LDBDIR/tests/test-index.ldif || exit 1 -fi - -echo "Adding bad attributes - should fail" -$VALGRIND ldbadd $LDBDIR/tests/test-wrong_attributes.ldif && { - echo "Should fhave failed - gave $?" - exit 1 -} - -echo "testing indexed search" -$VALGRIND ldbsearch '(uid=uham)' || exit 1 -$VALGRIND ldbsearch '(&(objectclass=person)(objectclass=person)(objectclass=top))' || exit 1 -$VALGRIND ldbsearch '(&(uid=uham)(uid=uham))' || exit 1 -$VALGRIND ldbsearch '(|(uid=uham)(uid=uham))' || exit 1 -$VALGRIND ldbsearch '(|(uid=uham)(uid=uham)(objectclass=OpenLDAPperson))' || exit 1 -$VALGRIND ldbsearch '(&(uid=uham)(uid=uham)(!(objectclass=xxx)))' || exit 1 -$VALGRIND ldbsearch '(&(objectclass=person)(uid=uham)(!(uid=uhamxx)))' uid \* \+ dn || exit 1 -$VALGRIND ldbsearch '(&(uid=uham)(uid=uha*)(title=*))' uid || exit 1 - -# note that the "((" is treated as an attribute not an expression -# this matches the openldap ldapsearch behaviour of looking for a '=' -# to see if the first argument is an expression or not -$VALGRIND ldbsearch '((' uid || exit 1 -$VALGRIND ldbsearch '(objectclass=)' uid || exit 1 -$VALGRIND ldbsearch -b 'cn=Hampster Ursula,ou=Alumni Association,ou=People,o=University of Michigan,c=TEST' -s base "" sn || exit 1 - -echo "Test wildcard match" -$VALGRIND ldbadd $LDBDIR/tests/test-wildcard.ldif || exit 1 -$VALGRIND ldbsearch '(cn=test*multi)' || exit 1 -$VALGRIND ldbsearch '(cn=*test*multi*)' || exit 1 -$VALGRIND ldbsearch '(cn=*test_multi)' || exit 1 -$VALGRIND ldbsearch '(cn=test_multi*)' || exit 1 -$VALGRIND ldbsearch '(cn=test*multi*test*multi)' || exit 1 -$VALGRIND ldbsearch '(cn=test*multi*test*multi*multi_*)' || exit 1 - -echo "Starting ldbtest indexed" -$VALGRIND ldbtest --num-records 100 --num-searches 500 || exit 1 - -echo "Testing one level search" -count=`$VALGRIND ldbsearch -b 'ou=Groups,o=University of Michigan,c=TEST' -s one 'objectclass=*' none |grep '^dn' | wc -l` -if [ $count != 3 ]; then - echo returned $count records - expected 3 - exit 1 -fi - -echo "Testing binary file attribute value" -mkdir -p tests/tmp -cp $LDBDIR/tests/samba4.png tests/tmp/samba4.png -$VALGRIND ldbmodify $LDBDIR/tests/photo.ldif || exit 1 -count=`$VALGRIND ldbsearch '(cn=Hampster Ursula)' jpegPhoto | grep '^dn' | wc -l` -if [ $count != 1 ]; then - echo returned $count records - expected 1 - exit 1 -fi -rm -f tests/tmp/samba4.png - -echo "*TODO* Testing UTF8 upper lower case searches !!" - -echo "Testing compare" -count=`$VALGRIND ldbsearch '(cn>=t)' cn | grep '^dn' | wc -l` -if [ $count != 2 ]; then - echo returned $count records - expected 2 - echo "this fails on openLdap ..." -fi - -count=`$VALGRIND ldbsearch '(cn<=t)' cn | grep '^dn' | wc -l` -if [ $count != 13 ]; then - echo returned $count records - expected 13 - echo "this fails on opsnLdap ..." -fi - -checkcount() { - count=$1 - scope=$2 - basedn=$3 - expression="$4" - n=`bin/ldbsearch -s "$scope" -b "$basedn" "$expression" | grep '^dn' | wc -l` - if [ $n != $count ]; then - echo "Got $n but expected $count for $expression" - bin/ldbsearch "$expression" - exit 1 - fi - echo "OK: $count $expression" -} - -checkcount 0 'base' '' '(uid=uham)' -checkcount 0 'one' '' '(uid=uham)' - -checkcount 1 'base' 'cn=Hampster Ursula,ou=Alumni Association,ou=People,o=University of Michigan,c=TEST' '(uid=uham)' -checkcount 1 'one' 'ou=Alumni Association,ou=People,o=University of Michigan,c=TEST' '(uid=uham)' -checkcount 1 'one' 'ou=People,o=University of Michigan,c=TEST' '(ou=ldb test)' diff --git a/source/lib/ldb/tests/test-index.ldif b/source/lib/ldb/tests/test-index.ldif deleted file mode 100644 index a7935371878..00000000000 --- a/source/lib/ldb/tests/test-index.ldif +++ /dev/null @@ -1,11 +0,0 @@ -dn: @INDEXLIST -@IDXATTR: uid -@IDXATTR: objectclass - -dn: @ATTRIBUTES -uid: CASE_INSENSITIVE - -dn: @SUBCLASSES -top: person -person: organizationalPerson -organizationalPerson: OpenLDAPperson diff --git a/source/lib/ldb/tests/test-ldap.sh b/source/lib/ldb/tests/test-ldap.sh deleted file mode 100755 index b9d224e0af0..00000000000 --- a/source/lib/ldb/tests/test-ldap.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/bin/sh - -PATH=/usr/local/sbin:/usr/sbin:/sbin:$PATH -export PATH -SCHEMA_NEEDED="core nis cosine inetorgperson openldap" - -# setup needed schema files -for f in $SCHEMA_NEEDED; do - if [ ! -r tests/schema/$f.schema ]; then - mkdir -p tests/schema - if [ -r /etc/ldap/schema/$f.schema ]; then - ln -s /etc/ldap/schema/$f.schema tests/schema/$f.schema - continue; - fi - if [ -r /etc/openldap/schema/$f.schema ]; then - ln -s /etc/openldap/schema/$f.schema tests/schema/$f.schema - continue; - fi - - echo "SKIPPING TESTS: you need the following OpenLDAP schema files" - for f in $SCHEMA_NEEDED; do - echo " $f.schema" - done - exit 0 - fi -done - -if [ -z "$LDBDIR" ]; then - LDBDIR=`dirname $0`/.. - export LDBDIR -fi - -LDB_URL=`$LDBDIR/tests/ldapi_url.sh` -export LDB_URL - -PATH=bin:$PATH -export PATH - -LDB_SPECIALS=0 -export LDB_SPECIALS - -if $LDBDIR/tests/init_slapd.sh && - $LDBDIR/tests/start_slapd.sh && - $LDBDIR/tests/test-generic.sh; then - echo "ldap tests passed"; - ret=0 -else - echo "ldap tests failed"; - ret=$? -fi - -$LDBDIR/tests/kill_slapd.sh - -exit $ret diff --git a/source/lib/ldb/tests/test-modify.ldif b/source/lib/ldb/tests/test-modify.ldif deleted file mode 100644 index e5b9ca40861..00000000000 --- a/source/lib/ldb/tests/test-modify.ldif +++ /dev/null @@ -1,23 +0,0 @@ -dn: cn=Ursula Hampster,ou=Alumni Association,ou=People,o=University of Michiga - n,c=TEST -changetype: modify -add: drink -drink: mango lassi -- -add: drink -drink: lemonade -- -delete: pager -- -replace: telephonenumber -telephonenumber: +61 2 6260 6012 -telephonenumber: +61 412 666 929 -- -delete: telephonenumber -telephonenumber: +61 2 6260 6012 -- -delete: telephonenumber -telephonenumber: +61 412 666 929 -- -add: telephonenumber -telephonenumber: +61 412 666 929 diff --git a/source/lib/ldb/tests/test-schema.sh b/source/lib/ldb/tests/test-schema.sh deleted file mode 100755 index 2f10fb45e2a..00000000000 --- a/source/lib/ldb/tests/test-schema.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/sh - -LDB_URL="tdb://schema.ldb" -export LDB_URL - -rm -f schema.ldb - -echo "LDB_URL: $LDB_URL" - -echo "Adding schema" -$VALGRIND bin/ldbadd $LDBDIR/tests/schema-tests/schema.ldif || exit 1 - -echo "Adding few test elements (no failure expected here)" -$VALGRIND bin/ldbadd $LDBDIR/tests/schema-tests/schema-add-test.ldif || exit 1 - -echo "Modifying elements (2 failures expected here)" - -$VALGRIND bin/ldbmodify $LDBDIR/tests/schema-tests/schema-mod-test-1.ldif || exit 1 -$VALGRIND bin/ldbmodify $LDBDIR/tests/schema-tests/schema-mod-test-2.ldif || exit 1 -$VALGRIND bin/ldbmodify $LDBDIR/tests/schema-tests/schema-mod-test-3.ldif || exit 1 -$VALGRIND bin/ldbmodify $LDBDIR/tests/schema-tests/schema-mod-test-4.ldif -if [ "$?" == "0" ]; then - echo "test failed!" - exit 1 -fi -$VALGRIND bin/ldbmodify $LDBDIR/tests/schema-tests/schema-mod-test-5.ldif -if [ "$?" == "0" ]; then - echo "test failed!" - exit 1 -fi - -echo "Showing modified record" -$VALGRIND bin/ldbsearch '(cn=Test)' || exit 1 - diff --git a/source/lib/ldb/tests/test-sqlite3.sh b/source/lib/ldb/tests/test-sqlite3.sh deleted file mode 100755 index 0cef318d98a..00000000000 --- a/source/lib/ldb/tests/test-sqlite3.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/sh - - -LDB_URL="sqlite3://sqltest.ldb" -export LDB_URL - -rm -f sqltest.ldb - -if [ -z "$LDBDIR" ]; then - LDBDIR=`dirname $0`/.. - export LDBDIR -fi - -PATH=bin:$PATH -export PATH - -LDB_SPECIALS=0 -export LDB_SPECIALS - -$LDBDIR/tests/test-generic.sh - -#. $LDBDIR/tests/test-extended.sh - -#. $LDBDIR/tests/test-tdb-features.sh - diff --git a/source/lib/ldb/tests/test-tdb-features.sh b/source/lib/ldb/tests/test-tdb-features.sh deleted file mode 100644 index 6f1afdcf334..00000000000 --- a/source/lib/ldb/tests/test-tdb-features.sh +++ /dev/null @@ -1,119 +0,0 @@ -#!/bin/sh - -echo "Running tdb feature tests" - -mv $LDB_URL $LDB_URL.2 - -checkcount() { - count=$1 - expression="$2" - n=`bin/ldbsearch "$expression" | grep '^dn' | wc -l` - if [ $n != $count ]; then - echo "Got $n but expected $count for $expression" - $VALGRIND bin/ldbsearch "$expression" - exit 1 - fi - echo "OK: $count $expression" -} - -echo "Testing case sensitive search" -cat <<EOF | $VALGRIND bin/ldbadd || exit 1 -dn: cn=t1,cn=TEST -objectClass: testclass -test: foo -EOF -checkcount 1 '(test=foo)' -checkcount 0 '(test=FOO)' -checkcount 0 '(test=FO*)' - -echo "Making case insensitive" -cat <<EOF | $VALGRIND bin/ldbmodify || exit 1 -dn: @ATTRIBUTES -changetype: add -add: test -test: CASE_INSENSITIVE -EOF - -echo $ldif | $VALGRIND bin/ldbmodify || exit 1 -checkcount 1 '(test=foo)' -checkcount 1 '(test=FOO)' -checkcount 1 '(test=fo*)' - -echo "adding i" -cat <<EOF | $VALGRIND bin/ldbmodify || exit 1 -dn: cn=t1,cn=TEST -changetype: modify -add: i -i: 0x100 -EOF -checkcount 1 '(i=0x100)' -checkcount 0 '(i=256)' - -echo "marking i as INTEGER" -cat <<EOF | $VALGRIND bin/ldbmodify || exit 1 -dn: @ATTRIBUTES -changetype: modify -add: i -i: INTEGER -EOF -checkcount 1 '(i=0x100)' -checkcount 1 '(i=256)' - -echo "adding j" -cat <<EOF | $VALGRIND bin/ldbmodify || exit 1 -dn: cn=t1,cn=TEST -changetype: modify -add: j -j: 0x100 -EOF -checkcount 1 '(j=0x100)' -checkcount 0 '(j=256)' - -echo "Adding wildcard attribute" -cat <<EOF | $VALGRIND bin/ldbmodify || exit 1 -dn: @ATTRIBUTES -changetype: modify -add: * -*: INTEGER -EOF -checkcount 1 '(j=0x100)' -checkcount 1 '(j=256)' - -echo "Testing class search" -checkcount 0 '(objectClass=otherclass)' -checkcount 1 '(objectClass=testclass)' - -echo "Adding subclass" -cat <<EOF | $VALGRIND bin/ldbmodify || exit 1 -dn: @SUBCLASSES -changetype: add -add: otherclass -otherclass: testclass -EOF -checkcount 1 '(objectClass=otherclass)' -checkcount 1 '(objectClass=testclass)' - -echo "Adding index" -cat <<EOF | $VALGRIND bin/ldbadd || exit 1 -dn: @INDEXLIST -@IDXATTR: i -@IDXATTR: test -EOF -checkcount 1 '(i=0x100)' -checkcount 1 '(i=256)' -checkcount 0 '(i=-256)' -checkcount 1 '(test=foo)' -checkcount 1 '(test=FOO)' -checkcount 1 '(test=*f*o)' - -echo "making test case sensitive" -cat <<EOF | $VALGRIND bin/ldbmodify || exit 1 -dn: @ATTRIBUTES -changetype: modify -replace: test -test: NONE -EOF -checkcount 1 '(test=foo)' -checkcount 0 '(test=FOO)' -checkcount 1 '(test=f*o*)' - diff --git a/source/lib/ldb/tests/test-tdb.sh b/source/lib/ldb/tests/test-tdb.sh deleted file mode 100755 index 7c4f5205b47..00000000000 --- a/source/lib/ldb/tests/test-tdb.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/sh - -if [ -n "$TEST_DATA_PREFIX" ]; then - LDB_URL="$TEST_DATA_PREFIX/tdbtest.ldb" -else - LDB_URL="tdbtest.ldb" -fi -export LDB_URL - -PATH=bin:$PATH -export PATH - -rm -f $LDB_URL* - -if [ -z "$LDBDIR" ]; then - LDBDIR=`dirname $0`/.. - export LDBDIR -fi - -cat <<EOF | $VALGRIND ldbadd || exit 1 -dn: @MODULES -@LIST: rdn_name -EOF - -$VALGRIND ldbadd $LDBDIR/tests/init.ldif || exit 1 - -. $LDBDIR/tests/test-generic.sh - -. $LDBDIR/tests/test-extended.sh - -. $LDBDIR/tests/test-tdb-features.sh diff --git a/source/lib/ldb/tests/test-wildcard.ldif b/source/lib/ldb/tests/test-wildcard.ldif deleted file mode 100644 index 222512eeabd..00000000000 --- a/source/lib/ldb/tests/test-wildcard.ldif +++ /dev/null @@ -1,5 +0,0 @@ -dn: cn=test_multi_test_multi_test_multi,o=University of Michigan,c=TEST -objectclass: person -cn: test_multi_test_multi_test_multi -sn: multi_test -description: test multi wildcards matching diff --git a/source/lib/ldb/tests/test-wrong_attributes.ldif b/source/lib/ldb/tests/test-wrong_attributes.ldif deleted file mode 100644 index 27f45f0e562..00000000000 --- a/source/lib/ldb/tests/test-wrong_attributes.ldif +++ /dev/null @@ -1,3 +0,0 @@ -dn: @ATTRIBUTES -uid: CASE_INTENSIVE - diff --git a/source/lib/ldb/tests/test.ldif b/source/lib/ldb/tests/test.ldif deleted file mode 100644 index e53fadc7009..00000000000 --- a/source/lib/ldb/tests/test.ldif +++ /dev/null @@ -1,411 +0,0 @@ -dn: ou=Groups,o=University of Michigan,c=TEST -objectclass: organizationalUnit -ou: Groups - -dn: ou=Information Technology Division,ou=People,o=University of Michigan,c=TEST -objectclass: organizationalUnit -ou: Information Technology Division -description:: aMODwoPDgsKCw4PCgsOCwotFVlZQw4PCg8OCwoPDg8KCw4LCv0zDg8KDw4LCgsOD - woLDgsKKT8ODwoPDgsKDw4PCgsOCwqs6w4PCg8OCwoLDg8KCw4LCjUQkw4PCg8OCwoLDg8KCw4LCi - 01QUcODwoPDgsKDw4PCgsOCwr/Dg8KDw4LCg8ODwoLDgsKMw4PCg8OCwoLDg8KCw4LCik/Dg8KDw4 - LCgsODwoLDgsKLRCQoZitEJMODwoPDgsKCw4PCgsOCwrfDg8KDw4LCg8ODwoLDgsKIw4PCg8OCwoP - Dg8KCw4LCgcODwoPDgsKDw4PCgsOCwqHDg8KDw4LCgsODwoLDgsKLRCQkZitEJMODwoPDgsKCw4PC - gsOCwrfDg8KDw4LCg8ODwoLDgsKQw4PCg8OCwoPDg8KCw4LCisODwoPDgsKCw4PCgsOCwotFUVZqU - MODwoPDgsKDw4PCgsOCwr/Dg8KDw4LCg8ODwoLDgsKAw4PCg8OCwoLDg8KCw4LCik85dCTDg8KDw4 - LCgsODwoLDgsKFQ8ODwoPDgsKDw4PCgsOCwr/Dg8KDw4LCg8ODwoLDgsK/w4PCg8OCwoPDg8KCw4L - Cvzl0JMODwoPDgsKCw4PCgsOCwoXDg8KDw4LCg8ODwoLDgsK/w4PCg8OCwoPDg8KCw4LCv8ODwoPD - gsKDw4PCgsOCwr/Dg8KDw4LCgsODwoLDgsKLRCTDg8KDw4LCgsODwoLDgsKDw4PCg8OCwoLDg8KCw - 4LCuMODwoPDgsKDw4PCgsOCwoR0Q8ODwoPDgsKCw4PCgsOCwoM9w4PCg8OCwoPDg8KCw4LChMODwo - PDgsKDw4PCgsOCwoFOdTrDg8KDw4LCg8ODwoLDgsKHw4PCg8OCwoPDg8KCw4LChMODwoPDgsKDw4P - CgsOCwoFOw4PCg8OCwoPDg8KCw4LCqMODwoPDgsKDw4PCgsOCwrtHw4PCg8OCwoLDg8KCw4LChcOD - woPDgsKDw4PCgsOCwoDDg8KDw4LCgsODwoLDgsK4dMODwoPDgsKDw4PCgsOCwqjDg8KDw4LCg8ODw - oLDgsKtR8ODwoPDgsKCw4PCgsOCwovDg8KDw4LCgsODwoLDgsKLw4PCg8OCwoPDg8KCw4LCiMODwo - PDgsKDw4PCgsOCwr9SfGrDg8KDw4LCgsODwoLDgsKLQGgxw4PCg8OCwoPDg8KCw4LCoWhQw4PCg8O - CwoPDg8KCw4LCv8ODwoPDgsKDw4PCgsOCwoDDg8KDw4LCgsODwoLDgsKKT8ODwoPDgsKCw4PCgsOC - wotEJDDDg8KDw4LCgsODwoLDgsKFw4PCg8OCwoPDg8KCw4LCgHTDg8KDw4LCgsODwoLDgsKDw4PCg - 8OCwoPDg8KCw4LCuHXDg8KDw4LCgsODwoLDgsKLRCRqw4PCg8OCwoLDg8KCw4LCi8ODwoPDgsKDw4 - PCgsOCwojDg8KDw4LCgsODwoLDgsKLw4PCg8OCwoPDg8KCw4LCv8ODwoPDgsKCw4PCgsOCwpPDg8K - Dw4LCg8ODwoLDgsKQXV9eW8ODwoPDgsKCw4PCgsOCwoPDg8KDw4LCg8ODwoLDgsKEw4PCg8OCwoPD - g8KCw4LCgsODwoPDgsKDw4PCgsOCwozDg8KDw4LCg8ODwoLDgsKMw4PCg8OCwoPDg8KCw4LCjMODw - oPDgsKDw4PCgsOCwozDg8KDw4LCg8ODwoLDgsKMw4PCg8OCwoPDg8KCw4LCjMODwoPDgsKDw4PCgs - OCwoxWV8ODwoPDgsKCw4PCgsOCwovDg8KDw4LCg8ODwoLDgsKxw4PCg8OCwoLDg8KCw4LCi3wkw4P - Cg8OCwoLDg8KCw4LCjcODwoPDgsKCw4PCgsOCwofDg8KDw4LCg8ODwoLDgsKof8ODwoPDgsKDw4PC - gsOCwr/Dg8KDw4LCg8ODwoLDgsK/w4PCg8OCwoLDg8KCw4LCg8ODwoPDgsKDw4PCgsOCwrh5w4PCg - 8OCwoLDg8KCw4LChzQzw4PCg8OCwoPDg8KCw4LCicODwoPDgsKCw4PCgsOCworDg8KDw4LCgsODwo - LDgsKIw4PCg8OCwoLDg8KCw4LCuDFBw4PCg8OCwoPDg8KCw4LCvyTDg8KDw4LCgsODwoLDgsKNdDF - Bw4PCg8OCwoLDg8KCw4LCuF9ew4PCg8OCwoPDg8KCw4LCgsODwoPDgsKCw4PCgsOCwrhfXsODwoPD - gsKDw4PCgsOCwoLDg8KDw4LCgsODwoLDgsK4X17Dg8KDw4LCg8ODwoLDgsKCw4PCg8OCwoLDg8KCw - 4LCi8ODwoPDgsKDw4PCgsOCwo7Dg8KDw4LCgsODwoLDgsKBw4PCg8OCwoPDg8KCw4LCv8ODwoPDgs - KCw4PCgsOCwoTDg8KDw4LCgsODwoLDgsKAdcODwoPDgsKDw4PCgsOCwqhtw4PCg8OCwoLDg8KCw4L - ChcODwoPDgsKDw4PCgsOCwoDDg8KDw4LCgsODwoLDgsKEw4PCg8OCwoPDg8KCw4LCsMODwoPDgsKC - w4PCgsOCwrhfXsODwoPDgsKDw4PCgsOCwoLDg8KDw4LCg8ODwoLDgsKow4PCg8OCwoLDg8KCw4LCt - sODwoPDgsKDw4PCgsOCwq7Dg8KDw4LCg8ODwoLDgsK/w4PCg8OCwoPDg8KCw4LCv8ODwoPDgsKCw4 - PCgsOCwoPDg8KDw4LCg8ODwoLDgsKoZsODwoPDgsKCw4PCgsOCwoPDg8KDw4LCg8ODwoLDgsK4w4P - Cg8OCwoLDg8KCw4LCh8ODwoPDgsKDw4PCgsOCwpUzw4PCg8OCwoPDg8KCw4LCicODwoPDgsKCw4PC - gsOCworDg8KDw4LCgsODwoLDgsKISDJBw4PCg8OCwoPDg8KCw4LCvyTDg8KDw4LCgsODwoLDgsKNN - DJBw4PCg8OCwoLDg8KCw4LCi8ODwoPDgsKCw4PCgsOCwovDg8KDw4LCg8ODwoLDgsKOw4PCg8OCwo - PDg8KCw4LCv8ODwoPDgsKCw4PCgsOCwpDDg8KDw4LCg8ODwoLDgsKIw4PCg8OCwoLDg8KCw4LCi8O - DwoPDgsKDw4PCgsOCwojDg8KDw4LCg8ODwoLDgsKow4PCg8OCwoPDg8KCw4LCnEzDg8KDw4LCgsOD - woLDgsKLSEBmw4PCg8OCwoLDg8KCw4LCg3lwdSTDg8KDw4LCgsODwoLDgsKBw4PCg8OCwoPDg8KCw - 4LCv8ODwoPDgsKCw4PCgsOCwobDg8KDw4LCgsODwoLDgsKAw4PCg8OCwoLDg8KCw4LChMODwoPDgs - KCw4PCgsOCwp/Dg8KDw4LCgsODwoLDgsKBw4PCg8OCwoPDg8KCw4LCv8ODwoPDgsKCw4PCgsOCwoj - Dg8KDw4LCgsODwoLDgsKAw4PCg8OCwoLDg8KCw4LChMODwoPDgsKCw4PCgsOCwpPDg8KDw4LCgsOD - woLDgsKBw4PCg8OCwoPDg8KCw4LCv1rDg8KDw4LCgsODwoLDgsKAw4PCg8OCwoLDg8KCw4LChMODw - oPDgsKCw4PCgsOCwodqw4PCg8OCwoLDg8KCw4LCi8ODwoPDgsKCw4PCgsOCwoBqaMODwoPDgsKCw4 - PCgsOCwpBQw4PCg8OCwoPDg8KCw4LCv8ODwoPDgsKDIMODwoPDgsKCw4PCgsOCwopPw4PCg8OCwoL - Dg8KCw4LChcODwoPDgsKDw4PCgsOCwoDDg8KDw4LCgsODwoLDgsKOacODwoPDgsKCw4PCgsOCwrhf - XsODwoPDgsKDw4PCgsOCwoLDg8KDw4LCgsODwoLDgsK4X17Dg8KDw4LCg8ODwoLDgsKCw4PCg8OCw - oLDg8KCw4LCgcODwoPDgsKDw4PCgsOCwr/Dg8KDw4LCgsODwoLDgsKGw4PCg8OCwoLDg8KCw4LCgM - ODwoPDgsKCw4PCgsOCwoRJw4PCg8OCwoLDg8KCw4LCgcODwoPDgsKDw4PCgsOCwr/Dg8KDw4LCgsO - DwoLDgsKIw4PCg8OCwoLDg8KCw4LCgMODwoPDgsKCw4PCgsOCwoQ9w4PCg8OCwoLDg8KCw4LCgcOD - woPDgsKDw4PCgsOCwr9aw4PCg8OCwoLDg8KCw4LCgMODwoPDgsKCw4PCgsOCwoQxw4PCg8OCwoLDg - 8KCw4LCuF9ew4PCg8OCwoPDg8KCw4LCgsODwoPDgsKCw4PCgsOCwoM9w4PCg8OCwoPDg8KCw4LCm0 - 7Dg8KDw4LCgsODwoLDgsKEw4PCg8OCwoLDg8KCw4LCuF9ew4PCg8OCwoPDg8KCw4LCgsODwoPDgsK - Cw4PCgsOCwrhfXsODwoPDgsKDw4PCgsOCwoLDg8KDw4LCgsODwoLDgsK4X17Dg8KDw4LCg8ODwoLD - gsKCw4PCg8OCwoLDg8KCw4LCuF9ew4PCg8OCwoPDg8KCw4LCgsODwoPDgsKCw4PCgsOCwrhfXsODw - oPDgsKDw4PCgsOCwoLDg8KDw4LCgsODwoLDgsKLw4PCg8OCwoLDg8KCw4LCi8ODwoPDgsKDw4PCgs - OCwo7Dg8KDw4LCg8ODwoLDgsK/w4PCg8OCwoLDg8KCw4LCkMODwoPDgsKDw4PCgsOCwojDg8KDw4L - CgsODwoLDgsKLw4PCg8OCwoPDg8KCw4LCiMODwoPDgsKDw4PCgsOCwqjDg8KDw4LCg8ODwoLDgsK+ - S8ODwoPDgsKCw4PCgsOCwovDg8KDw4LCg8ODwoLDgsKww4PCg8OCwoPDg8KCw4LCv8ODwoPDgsKDw - 4PCgsOCwoTDg8KDw4LCgsODwoLDgsKKT1DDg8KDw4LCg8ODwoLDgsKoRsODwoPDgsKCw4PCgsOCwo - vDg8KDw4LCg8ODwoLDgsK4w4PCg8OCwoLDg8KCw4LChcODwoPDgsKDw4PCgsOCwrZ0Y8ODwoPDgsK - Cw4PCgsOCwoXDg8KDw4LCg8ODwoLDgsK/dF/Dg8KDw4LCgsODwoLDgsKhdHpPw4PCg8OCwoLDg8KC - w4LCi8ODwoPDgsKDw4PCgsOCwo5Qw4PCg8OCwoPDg8KCw4LCqC1Jw4PCg8OCwoLDg8KCw4LChcODw - oPDgsKDw4PCgsOCwoB1RMODwoPDgsKCw4PCgsOCwqFwek/Dg8KDw4LCgsODwoLDgsKLw4PCg8OCwo - PDg8KCw4LCj1DDg8KDw4LCg8ODwoLDgsKoScODwoPDgsKCw4PCgsOCwoXDg8KDw4LCg8ODwoLDgsK - AdTPDg8KDw4LCgsODwoLDgsKhbHpPw4PCg8OCwoLDg8KCw4LCi8ODwoPDgsKDw4PCgsOCwo5Qw4PC - g8OCwoPDg8KCw4LCqEnDg8KDw4LCgsODwoLDgsKFw4PCg8OCwoPDg8KCw4LCgHXDg8KDw4LCgsODw - oLDgsKhaHpPw4PCg8OCwoLDg8KCw4LCi8ODwoPDgsKDw4PCgsOCwo9Qw4PCg8OCwoPDg8KCw4LCqM - ODwoPDgsKDw4PCgsOCwrpIw4PCg8OCwoLDg8KCw4LChcODwoPDgsKDw4PCgsOCwoB1M8ODwoPDgsK - Dw4PCgsOCwoBfXsODwoPDgsKDw4PCgsOCwoLDg8KDw4LCgsODwoLDgsK4X17Dg8KDw4LCg8ODwoLD - gsKCw4PCg8OCwoLDg8KCw4LCuF9ew4PCg8OCwoPDg8KCw4LCgjPDg8KDw4LCg8ODwoLDgsKAX17Dg - 8KDw4LCg8ODwoLDgsKCw4PCg8OCwoLDg8KCw4LCi8ODwoPDgsKDw4PCgsOCwo7Dg8KDw4LCg8ODwo - LDgsKoJ8ODwoPDgsKDw4PCgsOCwq3Dg8KDw4LCg8ODwoLDgsK/w4PCg8OCwoPDg8KCw4LCv8ODwoP - DgsKCw4PCgsOCwoPDg8KDw4LCg8ODwoLDgsK4aHU5w4PCg8OCwoLDg8KCw4LCi8ODwoPDgsKCw4PC - gsOCwovDg8KDw4LCg8ODwoLDgsKOw4PCg8OCwoPDg8KCw4LCv8ODwoPDgsKCw4PCgsOCwpDDg8KDw - 4LCg8ODwoLDgsKIw4PCg8OCwoLDg8KCw4LCi8ODwoPDgsKCw4PCgsOCwovDg8KDw4LCg8ODwoLDgs - KIw4PCg8OCwoPDg8KCw4LCv8ODwoPDgsKCw4PCgsOCwpLDg8KDw4LCg8ODwoLDgsKEw4PCg8OCwoL - Dg8KCw4LChcODwoPDgsKDw4PCgsOCwoB0IcODwoPDgsKCw4PCgsOCwovDg8KDw4LCgsODwoLDgsKA - w4PCg8OCwoPDg8KCw4LCtMODwoPDgsKCw4PCgsOCwoXDg8KDw4LCg8ODwoLDgsKAdGbDg8KDw4LCg - sODwoLDgsKLQGY9dGY9dTPDg8KDw4LCg8ODwoLDgsKAX17Dg8KDw4LCg8ODwoLDgsKCw4PCg8OCwo - LDg8KCw4LCuF9ew4PCg8OCwoPDg8KCw4LCgsODwoPDgsKCw4PCgsOCwrhfXsODwoPDgsKDw4PCgsO - CwoIzw4PCg8OCwoPDg8KCw4LCgF9ew4PCg8OCwoPDg8KCw4LCgsODwoPDgsKCw4PCgsOCwovDg8KD - w4LCg8ODwoLDgsK/Ri9BUC9BRi9BWi9BZC9BWzBBZC9BZTBBZC9BZC9BbzBBZC9BeTBBw4PCg8OCw - oLDg8KCw4LCgzBBMUFhMUFrMUE= -description:: UF7Dg8KDw4LCg8ODwoLDgsKCw4PCg8OCwoPDg8KCw4LCjMODwoPDgsKDw4PCgsOC - wozDg8KDw4LCg8ODwoLDgsKMw4PCg8OCwoPDg8KCw4LCjMODwoPDgsKDw4PCgsOCwozDg8KDw4LCg - 8ODwoLDgsKMw4PCg8OCwoPDg8KCw4LCqFDDg8KDw4LCg8ODwoLDgsKpRsODwoPDgsKDw4PCgsOCwo - zDg8KDw4LCg8ODwoLDgsKMw4PCg8OCwoPDg8KCw4LCjMODwoPDgsKDw4PCgsOCwozDg8KDw4LCg8O - DwoLDgsKMw4PCg8OCwoPDg8KCw4LCjMODwoPDgsKCw4PCgsOCwotEJCDDg8KDw4LCgsODwoLDgsKD - w4PCg8OCwoPDg8KCw4LCrMODwoPDgsKCw4PCgsOCwotUJCRTw4PCg8OCwoLDg8KCw4LCi1wkJFbDg - 8KDw4LCgsODwoLDgsKJTCRXVVBSU8ODwoPDgsKDw4PCgsOCwqjDg8KDw4LCg8ODwoLDgsKdT8ODwo - PDgsKCw4PCgsOCwoN8JDB1w4PCg8OCwoPDg8KCw4LCh8ODwoPDgsKDw4PCgsOCwoDDg8KDw4LCg8O - DwoLDgsKBTsODwoPDgsKDw4PCgsOCwqktw4PCg8OCwoLDg8KCw4LCg3wkMHTDg8KDw4LCgsODwoLD - gsKDfCQww4PCg8OCwoLDg8KCw4LChTPDg8KDw4LCg8ODwoLDgsK2OTXDg8KDw4LCg8ODwoLDgsKAw - 4PCg8OCwoPDg8KCw4LCgU7Dg8KDw4LCgsODwoLDgsKEIMODwoPDgsKCw4PCgsOCwqFIw4PCg8OCwo - PDg8KCw4LChU7Dg8KDw4LCgsODwoLDgsKJNcODwoPDgsKDw4PCgsOCwoDDg8KDw4LCg8ODwoLDgsK - BTsODwoPDgsKCw4PCgsOCwovDg8KDw4LCg8ODwoLDgsKIw4PCg8OCwoLDg8KCw4LCi8ODwoPDgsKD - w4PCgsOCwr9TXMODwoPDgsKCw4PCgsOCwolEJDvDg8KDw4LCg8ODwoLDgsKGw4PCg8OCwoLDg8KCw - 4LChMODwoPDgsKCw4PCgsOCwpHDg8KDw4LCgsODwoLDgsKNRCTDg8KDw4LCgsODwoLDgsKLIEjDg8 - KDw4LCg8ODwoLDgsKFTlDDg8KDw4LCgsODwoLDgsKLw4PCg8OCwoPDg8KCw4LCv1Ngw4PCg8OCwoL - Dg8KCw4LCi8ODwoPDgsKDw4PCgsOCwpjDg8KDw4LCgsODwoLDgsKFw4PCg8OCwoPDg8KCw4LCm3Rx - w4PCg8OCwoLDg8KCw4LCizvDg8KDw4LCgsODwoLDgsKLw4PCg8OCwoPDg8KCw4LCi8ODwoPDgsKDw - 4PCgsOCwr9XaMODwoPDgsKCw4PCgsOCwolEJDvDg8KDw4LCg8ODwoLDgsKGdGLDg8KDw4LCgsODwo - LDgsKLf2zDg8KDw4LCgsODwoLDgsKNRCTDg8KDw4LCgsODwoLDgsKLw4PCg8OCwoPDg8KCw4LCi1D - Dg8KDw4LCg8ODwoLDgsK/w4PCg8OCwoPDg8KCw4LCl8ODwoPDgsKCw4PCgsOCwovDg8KDw4LCg8OD - woLDgsKow4PCg8OCwoLDg8KCw4LChcODwoPDgsKDw4PCgsOCwq10SmgoT03Dg8KDw4LCgsODwoLDg - sKLw4PCg8OCwoPDg8KCw4LCjcODwoPDgsKDw4PCgsOCwqggTMODwoPDgsKCw4PCgsOCwoXDg8KDw4 - LCg8ODwoLDgsKAdDrDg8KDw4LCgsODwoLDgsKNRCTDg8KDw4LCgsODwoLDgsKLTSBQUcODwoPDgsK - Dw4PCgsOCwr/Dg8KDw4LCg8ODwoLDgsKMw4PCg8OCwoLDg8KCw4LCik/Dg8KDw4LCgsODwoLDgsKL - RCQoZitEJCDDg8KDw4LCgsODwoLDgsK3w4PCg8OCwoPDg8KCw4LCiMODwoPDgsKDw4PCgsOCwoHDg - 8KDw4LCg8ODwoLDgsKhw4PCg8OCwoLDg8KCw4LCi0QkJGYrRCTDg8KDw4LCgsODwoLDgsK3w4PCg8 - OCwoPDg8KCw4LCkMODwoPDgsKDw4PCgsOCworDg8KDw4LCgsODwoLDgsKLRSBRVmpQw4PCg8OCwoP - Dg8KCw4LCv8ODwoPDgsKDw4PCgsOCwoDDg8KDw4LCgsODwoLDgsKKTzl0JHXDg8KDw4LCgsODwoLD - gsKhOXQkw4PCg8OCwoLDg8KCw4LChW/Dg8KDw4LCg8ODwoLDgsK/w4PCg8OCwoPDg8KCw4LCv8ODw - oPDgsKDw4PCgsOCwr/Dg8KDw4LCgsODwoLDgsKhRMODwoPDgsKDw4PCgsOCwoVOw4PCg8OCwoLDg8 - KCw4LCi8ODwoPDgsKDw4PCgsOCwojDg8KDw4LCgsODwoLDgsKLw4PCg8OCwoPDg8KCw4LCv1Ncw4P - Cg8OCwoLDg8KCw4LCiUQkw4PCg8OCwoLDg8KCw4LChcODwoPDgsKDw4PCgsOCwoDDg8KDw4LCgsOD - woLDgsKEw4PCg8OCwoPDg8KCw4LCtjPDg8KDw4LCg8ODwoLDgsK2w4PCg8OCwoLDg8KCw4LCjUQkw - 4PCg8OCwoLDg8KCw4LCiyBEw4PCg8OCwoPDg8KCw4LChU5Qw4PCg8OCwoLDg8KCw4LCi8ODwoPDgs - KDw4PCgsOCwr9TYMODwoPDgsKCw4PCgsOCwovDg8KDw4LCg8ODwoLDgsK4w4PCg8OCwoLDg8KCw4L - ChcODwoPDgsKDw4PCgsOCwr/Dg8KDw4LCgsODwoLDgsKEw4PCg8OCwoPDg8KCw4LCkMODwoPDgsKC - w4PCgsOCwovDg8KDw4LCgsODwoLDgsKLw4PCg8OCwoPDg8KCw4LCj8ODwoPDgsKDw4PCgsOCwr9Ta - MODwoPDgsKCw4PCgsOCwolEJDvDg8KDw4LCg8ODwoLDgsKGw4PCg8OCwoLDg8KCw4LChMODwoPDgs - KCw4PCgsOCwr3Dg8KDw4LCgsODwoLDgsKNRCTDg8KDw4LCgsODwoLDgsKLw4PCg8OCwoPDg8KCw4L - Cj1DDg8KDw4LCg8ODwoLDgsK/U2zDg8KDw4LCgsODwoLDgsKLw4PCg8OCwoPDg8KCw4LCqMODwoPD - gsKCw4PCgsOCwoXDg8KDw4LCg8ODwoLDgsKtw4PCg8OCwoLDg8KCw4LChMODwoPDgsKCw4PCgsOCw - p9oMMODwoPDgsKDw4PCgsOCwolMw4PCg8OCwoLDg8KCw4LCi8ODwoPDgsKDw4PCgsOCwo3Dg8KDw4 - LCg8ODwoLDgsKow4PCg8OCwoPDg8KCw4LCq0vDg8KDw4LCgsODwoLDgsKFw4PCg8OCwoPDg8KCw4L - CgMODwoPDgsKCw4PCgsOCwoTDg8KDw4LCgsODwoLDgsKLw4PCg8OCwoLDg8KCw4LCi0QkOcODwoPD - gsKCw4PCgsOCwrDDg8KDw4LCg8ODwoLDgsKEdEU5w4PCg8OCwoLDg8KCw4LCtTR0PcODwoPDgsKCw - 4PCgsOCwovDg8KDw4LCg8ODwoLDgsKNw4PCg8OCwoPDg8KCw4LCqMODwoPDgsKDw4PCgsOCwo5Lw4 - PCg8OCwoLDg8KCw4LCi0AgUMODwoPDgsKDw4PCgsOCwr/Dg8KDw4LCgsODwoLDgsKsw4PCg8OCwoL - Dg8KCw4LCik/Dg8KDw4LCgsODwoLDgsKFw4PCg8OCwoPDg8KCw4LCgHUow4PCg8OCwoLDg8KCw4LC - i8ODwoPDgsKDw4PCgsOCwo3Dg8KDw4LCgsODwoLDgsKJw4PCg8OCwoLDg8KCw4LCtTTDg8KDw4LCg - 8ODwoLDgsKow4PCg8OCwoPDg8KCw4LCl8ODwoPDgsKDw4PCgsOCwrtWw4PCg8OCwoLDg8KCw4LCi8 - ODwoPDgsKDw4PCgsOCwo3Dg8KDw4LCg8ODwoLDgsKow4PCg8OCwoLDg8KCw4LCnw== - -#LEAD COMMENT - -# another comment -dn: CN=All Staff,ou=Groups,o=University of Michigan,c=TEST -#EMBEDDED COMMENT -member: cn=Manager,o=University of Michigan,c=TEST -member: cn=Barbara Jensen,ou=Information Technology Division,ou=People,o=Unive - rsity of Michigan,c=TEST -member: cn=Jane Doe,ou=Alumni Association,ou=People,o=University of Michigan,c - =US -member: cn=John Doe,ou=Information Technology Division,ou=People,o=University - of Michigan,c=TEST -member: cn=Mark Elliot,ou=Alumni Association,ou=People,o=University of Michiga - n,c=TEST -member: cn=James A Jones 1,ou=Alumni Association,ou=People,o=University of Mic - higan,c=TEST -member: cn=James A Jones 2,ou=Information Technology Division,ou=People,o=Univ - ersity of Michigan,c=TEST -member: cn=Jennifer Smith,ou=Alumni Association,ou=People,o=University of Mich - igan,c=TEST -member: cn=Dorothy Stevens,ou=Alumni Association,ou=People,o=University of Mic - higan,c=TEST -member: cn=Ursula Hampster,ou=Alumni Association,ou=People,o=University of Mic - higan,c=TEST -member: cn=Bjorn Jensen,ou=Information Technology Division,ou=People,o=Univers - ity of Michigan,c=TEST -owner: cn=Manager,o=University of Michigan,c=TEST -cn: All Staff -description: Everyone in the sample data -objectclass: groupofnames - -dn: cn=Alumni Assoc Staff,ou=Groups,o=University of Michigan,c=TEST -member: cn=Manager,o=University of Michigan,c=TEST -member: cn=Dorothy Stevens,ou=Alumni Association,ou=People,o=University of Mic - higan,c=TEST -member: cn=James A Jones 1,ou=Alumni Association,ou=People,o=University of Mic - higan,c=TEST -member: cn=Jane Doe,ou=Alumni Association,ou=People,o=University of Michigan,c - =US -member: cn=Jennifer Smith,ou=Alumni Association,ou=People,o=University of Mich - igan,c=TEST -member: cn=Mark Elliot,ou=Alumni Association,ou=People,o=University of Michiga - n,c=TEST -member: cn=Ursula Hampster,ou=Alumni Association,ou=People,o=University of Mic - higan,c=TEST -owner: cn=Manager,o=University of Michigan,c=TEST -description: All Alumni Assoc Staff -cn: Alumni Assoc Staff -objectclass: groupofnames - -dn: ou=Alumni Association,ou=People,o=University of Michigan,c=TEST -objectclass: organizationalUnit -ou: Alumni Association - -dn: cn=Barbara Jensen,ou=Information Technology Division,ou=People,o=Universit - y of Michigan,c=TEST -objectclass: OpenLDAPperson -cn: Barbara Jensen -cn: Babs Jensen -sn:: IEplbnNlbiA= -uid:: YmplCW5zZW4 -title: Mythical Manager, Research Systems -postaladdress: ITD Prod Dev & Deployment $ 535 W. William St. Room 4212 $ Ann - Arbor, MI 48103-4943 -seealso: cn=All Staff,ou=Groups,o=University of Michigan,c=TEST -userpassword:: YmplbnNlbg== -mail: bjensen@mailgw.example.com -homepostaladdress: 123 Wesley $ Ann Arbor, MI 48103 -description: Mythical manager of the rsdd unix project -drink: water -homephone: +1 313 555 2333 -pager: +1 313 555 3233 -facsimiletelephonenumber: +1 313 555 2274 -telephonenumber: +1 313 555 9022 - -dn: cn=Bjorn Jensen,ou=Information Technology Division,ou=People,o=University - of Michigan,c=TEST -objectclass: OpenLDAPperson -cn: Bjorn Jensen -cn: Biiff Jensen -sn: Jensen -uid: bjorn -seealso: cn=All Staff,ou=Groups,o=University of Michigan,c=TEST -userpassword:: Ympvcm4= -homepostaladdress: 19923 Seven Mile Rd. $ South Lyon, MI 49999 -drink: Iced Tea -description: Hiker, biker -title: Director, Embedded Systems -postaladdress: Info Tech Division $ 535 W. William St. $ Ann Arbor, MI 48103 -mail: bjorn@mailgw.example.com -homephone: +1 313 555 5444 -pager: +1 313 555 4474 -facsimiletelephonenumber: +1 313 555 2177 -telephonenumber: +1 313 555 0355 - -dn: cn=Dorothy Stevens,ou=Alumni Association,ou=People,o=University of Michiga - n,c=TEST -objectclass: OpenLDAPperson -cn: Dorothy Stevens -cn: Dot Stevens -sn: Stevens -uid: dots -title: Secretary, UM Alumni Association -postaladdress: Alumni Association $ 111 Maple St $ Ann Arbor, MI 48109 -seealso: cn=All Staff,ou=Groups,o=University of Michigan,c=TEST -drink: Lemonade -homepostaladdress: 377 White St. Apt. 3 $ Ann Arbor, MI 48104 -description: Very tall -facsimiletelephonenumber: +1 313 555 3223 -telephonenumber: +1 313 555 3664 -mail: dots@mail.alumni.example.com -homephone: +1 313 555 0454 - -dn: cn=ITD Staff,ou=Groups,o=University of Michigan,c=TEST -owner: cn=Manager,o=University of Michigan,c=TEST -description: All ITD Staff -cn: ITD Staff -objectclass: groupofuniquenames -uniquemember: cn=Manager,o=University of Michigan,c=TEST -uniquemember: cn=Bjorn Jensen,ou=Information Technology Division,ou=People,o=U - niversity of Michigan,c=TEST -uniquemember: cn=James A Jones 2,ou=Information Technology Division,ou=People, - o=University of Michigan,c=TEST -uniquemember: cn=John Doe,ou=Information Technology Division,ou=People,o=Unive - rsity of Michigan,c=TEST - -dn: cn=James A Jones 1,ou=Alumni Association,ou=People,o=University of Michiga - n,c=TEST -objectclass: OpenLDAPperson -cn: James A Jones 1 -cn: James Jones -cn: Jim Jones -sn: Jones -uid: jaj -postaladdress: Alumni Association $ 111 Maple St $ Ann Arbor, MI 48109 -seealso: cn=All Staff,ou=Groups,o=University of Michigan,c=TEST -userpassword:: amFq -homepostaladdress: 3882 Beverly Rd. $ Ann Arbor, MI 48105 -homephone: +1 313 555 4772 -description: Outstanding -title: Mad Cow Researcher, UM Alumni Association -pager: +1 313 555 3923 -mail: jaj@mail.alumni.example.com -facsimiletelephonenumber: +1 313 555 4332 -telephonenumber: +1 313 555 0895 - -dn: cn=James A Jones 2,ou=Information Technology Division,ou=People,o=Universi - ty of Michigan,c=TEST -objectclass: OpenLDAPperson -cn: James A Jones 2 -cn: James Jones -cn: Jim Jones -sn: Doe -uid: jjones -seealso: cn=All Staff,ou=Groups,o=University of Michigan,c=TEST -homepostaladdress: 933 Brooks $ Ann Arbor, MI 48104 -homephone: +1 313 555 8838 -title: Senior Manager, Information Technology Division -description: Not around very much -mail: jjones@mailgw.example.com -postaladdress: Info Tech Division $ 535 W William $ Ann Arbor, MI 48103 -pager: +1 313 555 2833 -facsimiletelephonenumber: +1 313 555 8688 -telephonenumber: +1 313 555 7334 - -dn: cn=Jane Doe,ou=Alumni Association,ou=People,o=University of Michigan,c=TEST -objectclass: OpenLDAPperson -cn: Jane Doe -cn: Jane Alverson -sn: Doe -uid: jdoe -title: Programmer Analyst, UM Alumni Association -postaladdress: Alumni Association $ 111 Maple St $ Ann Arbor, MI 48109 -seealso: cn=All Staff,ou=Groups,o=University of Michigan,c=TEST -homepostaladdress: 123 Anystreet $ Ann Arbor, MI 48104 -drink: diet coke -description: Enthusiastic -mail: jdoe@woof.net -homephone: +1 313 555 5445 -pager: +1 313 555 1220 -facsimiletelephonenumber: +1 313 555 2311 -telephonenumber: +1 313 555 4774 - -dn: cn=Jennifer Smith,ou=Alumni Association,ou=People,o=University of Michigan - ,c=TEST -objectclass: OpenLDAPperson -cn: Jennifer Smith -cn: Jen Smith -sn: Smith -uid: jen -postaladdress: Alumni Association $ 111 Maple St $ Ann Arbor, MI 48109 -seealso: cn=All Staff,ou=Groups,o=University of Michigan,c=TEST -drink: Sam Adams -homepostaladdress: 1000 Maple #44 $ Ann Arbor, MI 48103 -title: Telemarketer, UM Alumni Association -mail: jen@mail.alumni.example.com -homephone: +1 313 555 2333 -pager: +1 313 555 6442 -facsimiletelephonenumber: +1 313 555 2756 -telephonenumber: +1 313 555 8232 - -dn: cn=John Doe,ou=Information Technology Division,ou=People,o=University of M - ichigan,c=TEST -objectclass: OpenLDAPperson -cn: John Doe -cn: Jonathon Doe -sn: Doe -uid: johnd -postaladdress: ITD $ 535 W. William $ Ann Arbor, MI 48109 -seealso: cn=All Staff,ou=Groups,o=University of Michigan,c=TEST -homepostaladdress: 912 East Bllvd $ Ann Arbor, MI 48104 -title: System Administrator, Information Technology Division -description: overworked! -mail: johnd@mailgw.example.com -homephone: +1 313 555 3774 -pager: +1 313 555 6573 -facsimiletelephonenumber: +1 313 555 4544 -telephonenumber: +1 313 555 9394 - -dn: cn=Manager,o=University of Michigan,c=TEST -objectclass: person -cn: Manager -cn: Directory Manager -cn: Dir Man -sn: Manager -description: Manager of the directory -userpassword:: c2VjcmV0 - -dn: cn=Mark Elliot,ou=Alumni Association,ou=People,o=University of Michigan,c= - TEST -objectclass: OpenLDAPperson -cn: Mark Elliot -cn: Mark A Elliot -sn: Elliot -uid: melliot -postaladdress: Alumni Association $ 111 Maple St $ Ann Arbor, MI 48109 -seealso: cn=All Staff,ou=Groups,o=University of Michigan,c=TEST -homepostaladdress: 199 Outer Drive $ Ypsilanti, MI 48198 -homephone: +1 313 555 0388 -drink: Gasoline -title: Director, UM Alumni Association -mail: melliot@mail.alumni.example.com -pager: +1 313 555 7671 -facsimiletelephonenumber: +1 313 555 7762 -telephonenumber: +1 313 555 4177 - -dn: cn=Ursula Hampster,ou=Alumni Association,ou=People,o=University of Michiga - n,c=TEST -objectclass: OpenLDAPperson -cn: Ursula Hampster -sn: Hampster -uid: uham -title: Secretary, UM Alumni Association -postaladdress: Alumni Association $ 111 Maple St $ Ann Arbor, MI 48109 -seealso: cn=All Staff,ou=Groups,o=University of Michigan,c=TEST -homepostaladdress: 123 Anystreet $ Ann Arbor, MI 48104 -mail: uham@mail.alumni.example.com -description: a long attribute name, longer than 128 bytes so that we - trigger sign extension problems in tdb_pack, no thats not long enough - yet, maybe this is. I'll just keep going till it triggers the error -homephone: +1 313 555 8421 -pager: +1 313 555 2844 -facsimiletelephonenumber: +1 313 555 9700 -telephonenumber: +1 313 555 5331 diff --git a/source/lib/ldb/tests/testdata.txt b/source/lib/ldb/tests/testdata.txt deleted file mode 100644 index dadb9f0f98e..00000000000 --- a/source/lib/ldb/tests/testdata.txt +++ /dev/null @@ -1,8 +0,0 @@ -foo=bar5 -(&(|(a=b)(c=d))(e=f)) -(&(|(a=b)(c=d)(g=h))(e=f)) -name=firstname lastname -(&(sid=S-1-2-3)(name = fred bloggs)) -(&(|(a=b)(c=d))(g=f)) -(&(sid=S-1-2-3)(!(name = fred bloggs))) -(&(!(|(a=b)(c=d))(g=f))) diff --git a/source/lib/ldb/tests/testsearch.txt b/source/lib/ldb/tests/testsearch.txt deleted file mode 100644 index c5738639b7f..00000000000 --- a/source/lib/ldb/tests/testsearch.txt +++ /dev/null @@ -1,5 +0,0 @@ -(blah=foo) -(objectclass=person) -(dn=*) -(&(objectclass=person)(objectclass=person)) -(&(objectclass=person)(objectclass=personx)) diff --git a/source/lib/ldb/tools/ad2oLschema.c b/source/lib/ldb/tools/ad2oLschema.c deleted file mode 100644 index 62c6e01c2e2..00000000000 --- a/source/lib/ldb/tools/ad2oLschema.c +++ /dev/null @@ -1,630 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Bartlett 2006 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - * Name: ldb - * - * Component: ad2oLschema - * - * Description: utility to convert an AD schema into the format required by OpenLDAP - * - * Author: Andrew Tridgell - */ - -#include "includes.h" -#include "ldb/include/includes.h" -#include "system/locale.h" -#include "ldb/tools/cmdline.h" -#include "ldb/tools/convert.h" - -struct schema_conv { - int count; - int skipped; - int failures; -}; - -enum convert_target { - TARGET_OPENLDAP, - TARGET_FEDORA_DS -}; - - -static void usage(void) -{ - printf("Usage: ad2oLschema <options>\n"); - printf("\nConvert AD-like LDIF to OpenLDAP schema format\n\n"); - printf("Options:\n"); - printf(" -I inputfile inputfile of mapped OIDs and skipped attributes/ObjectClasses"); - printf(" -H url LDB or LDAP server to read schmea from\n"); - printf(" -O outputfile outputfile otherwise STDOUT\n"); - printf(" -o options pass options like modules to activate\n"); - printf(" e.g: -o modules:timestamps\n"); - printf("\n"); - printf("Converts records from an AD-like LDIF schema into an openLdap formatted schema\n\n"); - exit(1); -} - -static int fetch_attrs_schema(struct ldb_context *ldb, struct ldb_dn *schemadn, - TALLOC_CTX *mem_ctx, - struct ldb_result **attrs_res) -{ - TALLOC_CTX *local_ctx = talloc_new(mem_ctx); - int ret; - const char *attrs[] = { - "lDAPDisplayName", - "isSingleValued", - "attributeID", - "attributeSyntax", - "description", - NULL - }; - - if (!local_ctx) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* Downlaod schema */ - ret = ldb_search(ldb, schemadn, LDB_SCOPE_SUBTREE, - "objectClass=attributeSchema", - attrs, attrs_res); - if (ret != LDB_SUCCESS) { - printf("Search failed: %s\n", ldb_errstring(ldb)); - return LDB_ERR_OPERATIONS_ERROR; - } - - return ret; -} - -static const char *oc_attrs[] = { - "lDAPDisplayName", - "mayContain", - "mustContain", - "systemMayContain", - "systemMustContain", - "objectClassCategory", - "governsID", - "description", - "subClassOf", - NULL -}; - -static int fetch_oc_recursive(struct ldb_context *ldb, struct ldb_dn *schemadn, - TALLOC_CTX *mem_ctx, - struct ldb_result *search_from, - struct ldb_result *res_list) -{ - int i; - int ret = 0; - for (i=0; i < search_from->count; i++) { - struct ldb_result *res; - const char *name = ldb_msg_find_attr_as_string(search_from->msgs[i], - "lDAPDisplayname", NULL); - char *filter = talloc_asprintf(mem_ctx, "(&(&(objectClass=classSchema)(subClassOf=%s))(!(lDAPDisplayName=%s)))", - name, name); - - ret = ldb_search(ldb, schemadn, LDB_SCOPE_SUBTREE, - filter, - oc_attrs, &res); - talloc_free(filter); - if (ret != LDB_SUCCESS) { - printf("Search failed: %s\n", ldb_errstring(ldb)); - return ret; - } - - talloc_steal(mem_ctx, res); - - res_list->msgs = talloc_realloc(res_list, res_list->msgs, - struct ldb_message *, res_list->count + 2); - if (!res_list->msgs) { - return LDB_ERR_OPERATIONS_ERROR; - } - res_list->msgs[res_list->count] = talloc_move(res_list, - &search_from->msgs[i]); - res_list->count++; - res_list->msgs[res_list->count] = NULL; - - if (res->count > 0) { - ret = fetch_oc_recursive(ldb, schemadn, mem_ctx, res, res_list); - } - if (ret != LDB_SUCCESS) { - return ret; - } - } - return ret; -} - -static int fetch_objectclass_schema(struct ldb_context *ldb, struct ldb_dn *schemadn, - TALLOC_CTX *mem_ctx, - struct ldb_result **objectclasses_res) -{ - TALLOC_CTX *local_ctx = talloc_new(mem_ctx); - struct ldb_result *top_res, *ret_res; - int ret; - if (!local_ctx) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* Downlaod 'top' */ - ret = ldb_search(ldb, schemadn, LDB_SCOPE_SUBTREE, - "(&(objectClass=classSchema)(lDAPDisplayName=top))", - oc_attrs, &top_res); - if (ret != LDB_SUCCESS) { - printf("Search failed: %s\n", ldb_errstring(ldb)); - return LDB_ERR_OPERATIONS_ERROR; - } - - talloc_steal(local_ctx, top_res); - - if (top_res->count != 1) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret_res = talloc_zero(local_ctx, struct ldb_result); - if (!ret_res) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = fetch_oc_recursive(ldb, schemadn, local_ctx, top_res, ret_res); - - if (ret != LDB_SUCCESS) { - printf("Search failed: %s\n", ldb_errstring(ldb)); - return LDB_ERR_OPERATIONS_ERROR; - } - - *objectclasses_res = talloc_move(mem_ctx, &ret_res); - return ret; -} - -static struct ldb_dn *find_schema_dn(struct ldb_context *ldb, TALLOC_CTX *mem_ctx) -{ - const char *rootdse_attrs[] = {"schemaNamingContext", NULL}; - struct ldb_dn *schemadn; - struct ldb_dn *basedn = ldb_dn_explode(mem_ctx, ""); - struct ldb_result *rootdse_res; - int ldb_ret; - if (!basedn) { - return NULL; - } - - /* Search for rootdse */ - ldb_ret = ldb_search(ldb, basedn, LDB_SCOPE_BASE, NULL, rootdse_attrs, &rootdse_res); - if (ldb_ret != LDB_SUCCESS) { - printf("Search failed: %s\n", ldb_errstring(ldb)); - return NULL; - } - - talloc_steal(mem_ctx, rootdse_res); - - if (rootdse_res->count != 1) { - printf("Failed to find rootDSE"); - return NULL; - } - - /* Locate schema */ - schemadn = ldb_msg_find_attr_as_dn(mem_ctx, rootdse_res->msgs[0], "schemaNamingContext"); - if (!schemadn) { - return NULL; - } - - talloc_free(rootdse_res); - return schemadn; -} - -#define IF_NULL_FAIL_RET(x) do { \ - if (!x) { \ - ret.failures++; \ - return ret; \ - } \ - } while (0) - - -static struct schema_conv process_convert(struct ldb_context *ldb, enum convert_target target, FILE *in, FILE *out) -{ - /* Read list of attributes to skip, OIDs to map */ - TALLOC_CTX *mem_ctx = talloc_new(ldb); - char *line; - const char **attrs_skip = NULL; - int num_skip = 0; - struct oid_map { - char *old_oid; - char *new_oid; - } *oid_map = NULL; - int num_maps = 0; - struct ldb_result *attrs_res, *objectclasses_res; - struct ldb_dn *schemadn; - struct schema_conv ret; - - int ldb_ret, i; - - ret.count = 0; - ret.skipped = 0; - ret.failures = 0; - - while ((line = afdgets(fileno(in), mem_ctx, 0))) { - /* Blank Line */ - if (line[0] == '\0') { - continue; - } - /* Comment */ - if (line[0] == '#') { - continue; - } - if (isdigit(line[0])) { - char *p = strchr(line, ':'); - IF_NULL_FAIL_RET(p); - if (!p) { - ret.failures = 1; - return ret; - } - p[0] = '\0'; - p++; - oid_map = talloc_realloc(mem_ctx, oid_map, struct oid_map, num_maps + 2); - trim_string(line, " ", " "); - oid_map[num_maps].old_oid = talloc_move(oid_map, &line); - trim_string(p, " ", " "); - oid_map[num_maps].new_oid = p; - num_maps++; - oid_map[num_maps].old_oid = NULL; - } else { - attrs_skip = talloc_realloc(mem_ctx, attrs_skip, const char *, num_skip + 2); - trim_string(line, " ", " "); - attrs_skip[num_skip] = talloc_move(attrs_skip, &line); - num_skip++; - attrs_skip[num_skip] = NULL; - } - } - - schemadn = find_schema_dn(ldb, mem_ctx); - if (!schemadn) { - printf("Failed to find schema DN: %s\n", ldb_errstring(ldb)); - ret.failures = 1; - return ret; - } - - ldb_ret = fetch_attrs_schema(ldb, schemadn, mem_ctx, &attrs_res); - if (ldb_ret != LDB_SUCCESS) { - printf("Failed to fetch attribute schema: %s\n", ldb_errstring(ldb)); - ret.failures = 1; - return ret; - } - - switch (target) { - case TARGET_OPENLDAP: - break; - case TARGET_FEDORA_DS: - fprintf(out, "dn: cn=schema\n"); - break; - } - - for (i=0; i < attrs_res->count; i++) { - struct ldb_message *msg = attrs_res->msgs[i]; - - const char *name = ldb_msg_find_attr_as_string(msg, "lDAPDisplayName", NULL); - const char *description = ldb_msg_find_attr_as_string(msg, "description", NULL); - const char *oid = ldb_msg_find_attr_as_string(msg, "attributeID", NULL); - const char *syntax = ldb_msg_find_attr_as_string(msg, "attributeSyntax", NULL); - BOOL single_value = ldb_msg_find_attr_as_bool(msg, "isSingleValued", False); - const struct syntax_map *map = find_syntax_map_by_ad_oid(syntax); - char *schema_entry = NULL; - int j; - - /* We have been asked to skip some attributes/objectClasses */ - if (attrs_skip && str_list_check_ci(attrs_skip, name)) { - ret.skipped++; - continue; - } - - /* We might have been asked to remap this oid, due to a conflict */ - for (j=0; oid && oid_map[j].old_oid; j++) { - if (strcmp(oid, oid_map[j].old_oid) == 0) { - oid = oid_map[j].new_oid; - break; - } - } - - switch (target) { - case TARGET_OPENLDAP: - schema_entry = talloc_asprintf(mem_ctx, - "attributetype (\n" - " %s\n", oid); - break; - case TARGET_FEDORA_DS: - schema_entry = talloc_asprintf(mem_ctx, - "attributeTypes: (\n" - " %s\n", oid); - break; - } - IF_NULL_FAIL_RET(schema_entry); - - schema_entry = talloc_asprintf_append(schema_entry, - " NAME '%s'\n", name); - IF_NULL_FAIL_RET(schema_entry); - - if (description) { - schema_entry = talloc_asprintf_append(schema_entry, - " DESC %s\n", description); - IF_NULL_FAIL_RET(schema_entry); - } - - if (map) { - const char *syntax_oid; - if (map->equality) { - schema_entry = talloc_asprintf_append(schema_entry, - " EQUALITY %s\n", map->equality); - IF_NULL_FAIL_RET(schema_entry); - } - if (map->substring) { - schema_entry = talloc_asprintf_append(schema_entry, - " SUBSTR %s\n", map->substring); - IF_NULL_FAIL_RET(schema_entry); - } - syntax_oid = map->Standard_OID; - /* We might have been asked to remap this oid, - * due to a conflict, or lack of - * implementation */ - for (j=0; syntax_oid && oid_map[j].old_oid; j++) { - if (strcmp(syntax_oid, oid_map[j].old_oid) == 0) { - syntax_oid = oid_map[j].new_oid; - break; - } - } - schema_entry = talloc_asprintf_append(schema_entry, - " SYNTAX %s\n", syntax_oid); - IF_NULL_FAIL_RET(schema_entry); - } - - if (single_value) { - schema_entry = talloc_asprintf_append(schema_entry, - " SINGLE-VALUE\n"); - IF_NULL_FAIL_RET(schema_entry); - } - - schema_entry = talloc_asprintf_append(schema_entry, - " )"); - - switch (target) { - case TARGET_OPENLDAP: - fprintf(out, "%s\n\n", schema_entry); - break; - case TARGET_FEDORA_DS: - fprintf(out, "%s\n", schema_entry); - break; - } - ret.count++; - } - - ldb_ret = fetch_objectclass_schema(ldb, schemadn, mem_ctx, &objectclasses_res); - if (ldb_ret != LDB_SUCCESS) { - printf("Failed to fetch objectClass schema elements: %s\n", ldb_errstring(ldb)); - ret.failures = 1; - return ret; - } - - for (i=0; i < objectclasses_res->count; i++) { - struct ldb_message *msg = objectclasses_res->msgs[i]; - const char *name = ldb_msg_find_attr_as_string(msg, "lDAPDisplayName", NULL); - const char *description = ldb_msg_find_attr_as_string(msg, "description", NULL); - const char *oid = ldb_msg_find_attr_as_string(msg, "governsID", NULL); - const char *subClassOf = ldb_msg_find_attr_as_string(msg, "subClassOf", NULL); - int objectClassCategory = ldb_msg_find_attr_as_int(msg, "objectClassCategory", 0); - struct ldb_message_element *must = ldb_msg_find_element(msg, "mustContain"); - struct ldb_message_element *sys_must = ldb_msg_find_element(msg, "systemMustContain"); - struct ldb_message_element *may = ldb_msg_find_element(msg, "mayContain"); - struct ldb_message_element *sys_may = ldb_msg_find_element(msg, "systemMayContain"); - char *schema_entry = NULL; - int j; - - /* We have been asked to skip some attributes/objectClasses */ - if (attrs_skip && str_list_check_ci(attrs_skip, name)) { - ret.skipped++; - continue; - } - - /* We might have been asked to remap this oid, due to a conflict */ - for (j=0; oid_map[j].old_oid; j++) { - if (strcmp(oid, oid_map[j].old_oid) == 0) { - oid = oid_map[j].new_oid; - break; - } - } - - switch (target) { - case TARGET_OPENLDAP: - schema_entry = talloc_asprintf(mem_ctx, - "objectclass (\n" - " %s\n", oid); - break; - case TARGET_FEDORA_DS: - schema_entry = talloc_asprintf(mem_ctx, - "objectClasses: (\n" - " %s\n", oid); - break; - } - IF_NULL_FAIL_RET(schema_entry); - if (!schema_entry) { - ret.failures++; - break; - } - - schema_entry = talloc_asprintf_append(schema_entry, - " NAME '%s'\n", name); - IF_NULL_FAIL_RET(schema_entry); - - if (!schema_entry) return ret; - - if (description) { - schema_entry = talloc_asprintf_append(schema_entry, - " DESC %s\n", description); - IF_NULL_FAIL_RET(schema_entry); - } - - if (subClassOf) { - schema_entry = talloc_asprintf_append(schema_entry, - " SUP %s\n", subClassOf); - IF_NULL_FAIL_RET(schema_entry); - } - - switch (objectClassCategory) { - case 1: - schema_entry = talloc_asprintf_append(schema_entry, - " STRUCTURAL\n"); - IF_NULL_FAIL_RET(schema_entry); - break; - case 2: - schema_entry = talloc_asprintf_append(schema_entry, - " ABSTRACT\n"); - IF_NULL_FAIL_RET(schema_entry); - break; - case 3: - schema_entry = talloc_asprintf_append(schema_entry, - " AUXILIARY\n"); - IF_NULL_FAIL_RET(schema_entry); - break; - } - -#define APPEND_ATTRS(attributes) \ - do { \ - int k; \ - for (k=0; attributes && k < attributes->num_values; k++) { \ - schema_entry = talloc_asprintf_append(schema_entry, \ - " %s", \ - (const char *)attributes->values[k].data); \ - IF_NULL_FAIL_RET(schema_entry); \ - if (k != (attributes->num_values - 1)) { \ - schema_entry = talloc_asprintf_append(schema_entry, \ - " $"); \ - IF_NULL_FAIL_RET(schema_entry); \ - if (target == TARGET_OPENLDAP && ((k+1)%5 == 0)) { \ - schema_entry = talloc_asprintf_append(schema_entry, \ - "\n "); \ - IF_NULL_FAIL_RET(schema_entry); \ - } \ - } \ - } \ - } while (0) - - if (must || sys_must) { - schema_entry = talloc_asprintf_append(schema_entry, - " MUST ("); - IF_NULL_FAIL_RET(schema_entry); - - APPEND_ATTRS(must); - if (must && sys_must) { - schema_entry = talloc_asprintf_append(schema_entry, \ - " $"); \ - } - APPEND_ATTRS(sys_must); - - schema_entry = talloc_asprintf_append(schema_entry, - " )\n"); - IF_NULL_FAIL_RET(schema_entry); - } - - if (may || sys_may) { - schema_entry = talloc_asprintf_append(schema_entry, - " MAY ("); - IF_NULL_FAIL_RET(schema_entry); - - APPEND_ATTRS(may); - if (may && sys_may) { - schema_entry = talloc_asprintf_append(schema_entry, \ - " $"); \ - } - APPEND_ATTRS(sys_may); - - schema_entry = talloc_asprintf_append(schema_entry, - " )\n"); - IF_NULL_FAIL_RET(schema_entry); - } - - schema_entry = talloc_asprintf_append(schema_entry, - " )"); - - switch (target) { - case TARGET_OPENLDAP: - fprintf(out, "%s\n\n", schema_entry); - break; - case TARGET_FEDORA_DS: - fprintf(out, "%s\n", schema_entry); - break; - } - ret.count++; - } - - return ret; -} - - int main(int argc, const char **argv) -{ - TALLOC_CTX *ctx; - struct ldb_cmdline *options; - FILE *in = stdin; - FILE *out = stdout; - struct ldb_context *ldb; - struct schema_conv ret; - const char *target_str; - enum convert_target target; - - ldb_global_init(); - - ctx = talloc_new(NULL); - ldb = ldb_init(ctx); - - options = ldb_cmdline_process(ldb, argc, argv, usage); - - if (options->input) { - in = fopen(options->input, "r"); - if (!in) { - perror(options->input); - exit(1); - } - } - if (options->output) { - out = fopen(options->output, "w"); - if (!out) { - perror(options->output); - exit(1); - } - } - - target_str = lp_parm_string(-1, "convert", "target"); - - if (!target_str || strcasecmp(target_str, "openldap") == 0) { - target = TARGET_OPENLDAP; - } else if (strcasecmp(target_str, "fedora-ds") == 0) { - target = TARGET_FEDORA_DS; - } else { - printf("Unsupported target: %s\n", target_str); - exit(1); - } - - ret = process_convert(ldb, target, in, out); - - fclose(in); - fclose(out); - - printf("Converted %d records (skipped %d) with %d failures\n", ret.count, ret.skipped, ret.failures); - - return 0; -} diff --git a/source/lib/ldb/tools/cmdline.c b/source/lib/ldb/tools/cmdline.c deleted file mode 100644 index 8eb7a7e9525..00000000000 --- a/source/lib/ldb/tools/cmdline.c +++ /dev/null @@ -1,755 +0,0 @@ -/* - ldb database library - command line handling for ldb tools - - Copyright (C) Andrew Tridgell 2005 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include "includes.h" -#include "ldb/include/includes.h" -#include "ldb/tools/cmdline.h" - -#if (_SAMBA_BUILD_ >= 4) -#include "lib/cmdline/popt_common.h" -#include "lib/ldb/samba/ldif_handlers.h" -#include "auth/gensec/gensec.h" -#include "auth/auth.h" -#include "db_wrap.h" -#endif - - - -/* - process command line options -*/ -struct ldb_cmdline *ldb_cmdline_process(struct ldb_context *ldb, int argc, const char **argv, - void (*usage)(void)) -{ - static struct ldb_cmdline options; /* needs to be static for older compilers */ - struct ldb_cmdline *ret=NULL; - poptContext pc; -#if (_SAMBA_BUILD_ >= 4) - int r; -#endif - int num_options = 0; - int opt; - int flags = 0; - - struct poptOption popt_options[] = { - POPT_AUTOHELP - { "url", 'H', POPT_ARG_STRING, &options.url, 0, "database URL", "URL" }, - { "basedn", 'b', POPT_ARG_STRING, &options.basedn, 0, "base DN", "DN" }, - { "editor", 'e', POPT_ARG_STRING, &options.editor, 0, "external editor", "PROGRAM" }, - { "scope", 's', POPT_ARG_STRING, NULL, 's', "search scope", "SCOPE" }, - { "verbose", 'v', POPT_ARG_NONE, NULL, 'v', "increase verbosity", NULL }, - { "interactive", 'i', POPT_ARG_NONE, &options.interactive, 0, "input from stdin", NULL }, - { "recursive", 'r', POPT_ARG_NONE, &options.recursive, 0, "recursive delete", NULL }, - { "num-searches", 0, POPT_ARG_INT, &options.num_searches, 0, "number of test searches", NULL }, - { "num-records", 0, POPT_ARG_INT, &options.num_records, 0, "number of test records", NULL }, - { "all", 'a', POPT_ARG_NONE, &options.all_records, 0, "(|(objectClass=*)(distinguishedName=*))", NULL }, - { "nosync", 0, POPT_ARG_NONE, &options.nosync, 0, "non-synchronous transactions", NULL }, - { "sorted", 'S', POPT_ARG_NONE, &options.sorted, 0, "sort attributes", NULL }, - { "sasl-mechanism", 0, POPT_ARG_STRING, &options.sasl_mechanism, 0, "choose SASL mechanism", "MECHANISM" }, - { "input", 'I', POPT_ARG_STRING, &options.input, 0, "Input File", "Input" }, - { "output", 'O', POPT_ARG_STRING, &options.output, 0, "Output File", "Output" }, - { NULL, 'o', POPT_ARG_STRING, NULL, 'o', "ldb_connect option", "OPTION" }, - { "controls", 0, POPT_ARG_STRING, NULL, 'c', "controls", NULL }, -#if (_SAMBA_BUILD_ >= 4) - POPT_COMMON_SAMBA - POPT_COMMON_CREDENTIALS - POPT_COMMON_VERSION -#endif - { NULL } - }; - - ldb_global_init(); - -#if (_SAMBA_BUILD_ >= 4) - r = ldb_register_samba_handlers(ldb); - if (r != 0) { - goto failed; - } - -#endif - - ret = talloc_zero(ldb, struct ldb_cmdline); - if (ret == NULL) { - ldb_oom(ldb); - goto failed; - } - - options = *ret; - - /* pull in URL */ - options.url = getenv("LDB_URL"); - - /* and editor (used by ldbedit) */ - options.editor = getenv("VISUAL"); - if (!options.editor) { - options.editor = getenv("EDITOR"); - } - if (!options.editor) { - options.editor = "vi"; - } - - options.scope = LDB_SCOPE_DEFAULT; - - pc = poptGetContext(argv[0], argc, argv, popt_options, - POPT_CONTEXT_KEEP_FIRST); - - while((opt = poptGetNextOpt(pc)) != -1) { - switch (opt) { - case 's': { - const char *arg = poptGetOptArg(pc); - if (strcmp(arg, "base") == 0) { - options.scope = LDB_SCOPE_BASE; - } else if (strcmp(arg, "sub") == 0) { - options.scope = LDB_SCOPE_SUBTREE; - } else if (strcmp(arg, "one") == 0) { - options.scope = LDB_SCOPE_ONELEVEL; - } else { - fprintf(stderr, "Invalid scope '%s'\n", arg); - goto failed; - } - break; - } - - case 'v': - options.verbose++; - break; - - case 'o': - options.options = talloc_realloc(ret, options.options, - const char *, num_options+3); - if (options.options == NULL) { - ldb_oom(ldb); - goto failed; - } - options.options[num_options] = poptGetOptArg(pc); - options.options[num_options+1] = NULL; - num_options++; - break; - - case 'c': { - const char *cs = poptGetOptArg(pc); - const char *p, *q; - int cc; - - for (p = cs, cc = 1; (q = strchr(p, ',')); cc++, p = q + 1) ; - - options.controls = talloc_array(ret, char *, cc + 1); - if (options.controls == NULL) { - ldb_oom(ldb); - goto failed; - } - for (p = cs, cc = 0; p != NULL; cc++) { - const char *t; - - t = strchr(p, ','); - if (t == NULL) { - options.controls[cc] = talloc_strdup(options.controls, p); - p = NULL; - } else { - options.controls[cc] = talloc_strndup(options.controls, p, t-p); - p = t + 1; - } - } - options.controls[cc] = NULL; - - break; - } - default: - fprintf(stderr, "Invalid option %s: %s\n", - poptBadOption(pc, 0), poptStrerror(opt)); - if (usage) usage(); - goto failed; - } - } - - /* setup the remaining options for the main program to use */ - options.argv = poptGetArgs(pc); - if (options.argv) { - options.argv++; - while (options.argv[options.argc]) options.argc++; - } - - *ret = options; - - /* all utils need some option */ - if (ret->url == NULL) { - fprintf(stderr, "You must supply a url with -H or with $LDB_URL\n"); - if (usage) usage(); - goto failed; - } - - if (strcmp(ret->url, "NONE") == 0) { - return ret; - } - - if (options.nosync) { - flags |= LDB_FLG_NOSYNC; - } - -#if (_SAMBA_BUILD_ >= 4) - /* Must be after we have processed command line options */ - gensec_init(); - - if (ldb_set_opaque(ldb, "sessionInfo", system_session(ldb))) { - goto failed; - } - if (ldb_set_opaque(ldb, "credentials", cmdline_credentials)) { - goto failed; - } - ldb_set_utf8_fns(ldb, NULL, wrap_casefold); -#endif - - /* now connect to the ldb */ - if (ldb_connect(ldb, ret->url, flags, ret->options) != 0) { - fprintf(stderr, "Failed to connect to %s - %s\n", - ret->url, ldb_errstring(ldb)); - goto failed; - } - - return ret; - -failed: - talloc_free(ret); - exit(1); - return NULL; -} - -struct ldb_control **parse_controls(void *mem_ctx, char **control_strings) -{ - int i; - struct ldb_control **ctrl; - - if (control_strings == NULL || control_strings[0] == NULL) - return NULL; - - for (i = 0; control_strings[i]; i++); - - ctrl = talloc_array(mem_ctx, struct ldb_control *, i + 1); - - for (i = 0; control_strings[i]; i++) { - if (strncmp(control_strings[i], "vlv:", 4) == 0) { - struct ldb_vlv_req_control *control; - const char *p; - char attr[1024]; - char ctxid[1024]; - int crit, bc, ac, os, cc, ret; - - attr[0] = '\0'; - ctxid[0] = '\0'; - p = &(control_strings[i][4]); - ret = sscanf(p, "%d:%d:%d:%d:%d:%1023[^$]", &crit, &bc, &ac, &os, &cc, ctxid); - if (ret < 5) { - ret = sscanf(p, "%d:%d:%d:%1023[^:]:%1023[^$]", &crit, &bc, &ac, attr, ctxid); - } - - if ((ret < 4) || (crit < 0) || (crit > 1)) { - fprintf(stderr, "invalid server_sort control syntax\n"); - fprintf(stderr, " syntax: crit(b):bc(n):ac(n):<os(n):cc(n)|attr(s)>[:ctxid(o)]\n"); - fprintf(stderr, " note: b = boolean, n = number, s = string, o = b64 binary blob\n"); - return NULL; - } - if (!(ctrl[i] = talloc(ctrl, struct ldb_control))) { - fprintf(stderr, "talloc failed\n"); - return NULL; - } - ctrl[i]->oid = LDB_CONTROL_VLV_REQ_OID; - ctrl[i]->critical = crit; - if (!(control = talloc(ctrl[i], - struct ldb_vlv_req_control))) { - fprintf(stderr, "talloc failed\n"); - return NULL; - } - control->beforeCount = bc; - control->afterCount = ac; - if (attr[0]) { - control->type = 1; - control->match.gtOrEq.value = talloc_strdup(control, attr); - control->match.gtOrEq.value_len = strlen(attr); - } else { - control->type = 0; - control->match.byOffset.offset = os; - control->match.byOffset.contentCount = cc; - } - if (ctxid[0]) { - control->ctxid_len = ldb_base64_decode(ctxid); - control->contextId = (char *)talloc_memdup(control, ctxid, control->ctxid_len); - } else { - control->ctxid_len = 0; - control->contextId = NULL; - } - ctrl[i]->data = control; - - continue; - } - - if (strncmp(control_strings[i], "dirsync:", 8) == 0) { - struct ldb_dirsync_control *control; - const char *p; - char cookie[1024]; - int crit, flags, max_attrs, ret; - - cookie[0] = '\0'; - p = &(control_strings[i][8]); - ret = sscanf(p, "%d:%d:%d:%1023[^$]", &crit, &flags, &max_attrs, cookie); - - if ((ret < 3) || (crit < 0) || (crit > 1) || (flags < 0) || (max_attrs < 0)) { - fprintf(stderr, "invalid dirsync control syntax\n"); - fprintf(stderr, " syntax: crit(b):flags(n):max_attrs(n)[:cookie(o)]\n"); - fprintf(stderr, " note: b = boolean, n = number, o = b64 binary blob\n"); - return NULL; - } - - /* w2k3 seems to ignore the parameter, - * but w2k sends a wrong cookie when this value is to small - * this would cause looping forever, while getting - * the same data and same cookie forever - */ - if (max_attrs == 0) max_attrs = 0x0FFFFFFF; - - ctrl[i] = talloc(ctrl, struct ldb_control); - ctrl[i]->oid = LDB_CONTROL_DIRSYNC_OID; - ctrl[i]->critical = crit; - control = talloc(ctrl[i], struct ldb_dirsync_control); - control->flags = flags; - control->max_attributes = max_attrs; - if (*cookie) { - control->cookie_len = ldb_base64_decode(cookie); - control->cookie = (char *)talloc_memdup(control, cookie, control->cookie_len); - } else { - control->cookie = NULL; - control->cookie_len = 0; - } - ctrl[i]->data = control; - - continue; - } - - if (strncmp(control_strings[i], "asq:", 4) == 0) { - struct ldb_asq_control *control; - const char *p; - char attr[256]; - int crit, ret; - - attr[0] = '\0'; - p = &(control_strings[i][4]); - ret = sscanf(p, "%d:%255[^$]", &crit, attr); - if ((ret != 2) || (crit < 0) || (crit > 1) || (attr[0] == '\0')) { - fprintf(stderr, "invalid asq control syntax\n"); - fprintf(stderr, " syntax: crit(b):attr(s)\n"); - fprintf(stderr, " note: b = boolean, s = string\n"); - return NULL; - } - - ctrl[i] = talloc(ctrl, struct ldb_control); - ctrl[i]->oid = LDB_CONTROL_ASQ_OID; - ctrl[i]->critical = crit; - control = talloc(ctrl[i], struct ldb_asq_control); - control->request = 1; - control->source_attribute = talloc_strdup(control, attr); - control->src_attr_len = strlen(attr); - ctrl[i]->data = control; - - continue; - } - - if (strncmp(control_strings[i], "extended_dn:", 12) == 0) { - struct ldb_extended_dn_control *control; - const char *p; - int crit, type, ret; - - p = &(control_strings[i][12]); - ret = sscanf(p, "%d:%d", &crit, &type); - if ((ret != 2) || (crit < 0) || (crit > 1) || (type < 0) || (type > 1)) { - fprintf(stderr, "invalid extended_dn control syntax\n"); - fprintf(stderr, " syntax: crit(b):type(b)\n"); - fprintf(stderr, " note: b = boolean\n"); - return NULL; - } - - ctrl[i] = talloc(ctrl, struct ldb_control); - ctrl[i]->oid = LDB_CONTROL_EXTENDED_DN_OID; - ctrl[i]->critical = crit; - control = talloc(ctrl[i], struct ldb_extended_dn_control); - control->type = type; - ctrl[i]->data = control; - - continue; - } - - if (strncmp(control_strings[i], "sd_flags:", 9) == 0) { - struct ldb_sd_flags_control *control; - const char *p; - int crit, ret; - unsigned secinfo_flags; - - p = &(control_strings[i][9]); - ret = sscanf(p, "%d:%u", &crit, &secinfo_flags); - if ((ret != 2) || (crit < 0) || (crit > 1) || (secinfo_flags < 0) || (secinfo_flags > 0xF)) { - fprintf(stderr, "invalid sd_flags control syntax\n"); - fprintf(stderr, " syntax: crit(b):secinfo_flags(n)\n"); - fprintf(stderr, " note: b = boolean, n = number\n"); - return NULL; - } - - ctrl[i] = talloc(ctrl, struct ldb_control); - ctrl[i]->oid = LDB_CONTROL_SD_FLAGS_OID; - ctrl[i]->critical = crit; - control = talloc(ctrl[i], struct ldb_sd_flags_control); - control->secinfo_flags = secinfo_flags; - ctrl[i]->data = control; - - continue; - } - - if (strncmp(control_strings[i], "search_options:", 15) == 0) { - struct ldb_search_options_control *control; - const char *p; - int crit, ret; - unsigned search_options; - - p = &(control_strings[i][15]); - ret = sscanf(p, "%d:%u", &crit, &search_options); - if ((ret != 2) || (crit < 0) || (crit > 1) || (search_options < 0) || (search_options > 0xF)) { - fprintf(stderr, "invalid search_options control syntax\n"); - fprintf(stderr, " syntax: crit(b):search_options(n)\n"); - fprintf(stderr, " note: b = boolean, n = number\n"); - return NULL; - } - - ctrl[i] = talloc(ctrl, struct ldb_control); - ctrl[i]->oid = LDB_CONTROL_SEARCH_OPTIONS_OID; - ctrl[i]->critical = crit; - control = talloc(ctrl[i], struct ldb_search_options_control); - control->search_options = search_options; - ctrl[i]->data = control; - - continue; - } - - if (strncmp(control_strings[i], "domain_scope:", 13) == 0) { - const char *p; - int crit, ret; - - p = &(control_strings[i][13]); - ret = sscanf(p, "%d", &crit); - if ((ret != 1) || (crit < 0) || (crit > 1)) { - fprintf(stderr, "invalid domain_scope control syntax\n"); - fprintf(stderr, " syntax: crit(b)\n"); - fprintf(stderr, " note: b = boolean\n"); - return NULL; - } - - ctrl[i] = talloc(ctrl, struct ldb_control); - ctrl[i]->oid = LDB_CONTROL_DOMAIN_SCOPE_OID; - ctrl[i]->critical = crit; - ctrl[i]->data = NULL; - - continue; - } - - if (strncmp(control_strings[i], "paged_results:", 14) == 0) { - struct ldb_paged_control *control; - const char *p; - int crit, size, ret; - - p = &(control_strings[i][14]); - ret = sscanf(p, "%d:%d", &crit, &size); - - if ((ret != 2) || (crit < 0) || (crit > 1) || (size < 0)) { - fprintf(stderr, "invalid paged_results control syntax\n"); - fprintf(stderr, " syntax: crit(b):size(n)\n"); - fprintf(stderr, " note: b = boolean, n = number\n"); - return NULL; - } - - ctrl[i] = talloc(ctrl, struct ldb_control); - ctrl[i]->oid = LDB_CONTROL_PAGED_RESULTS_OID; - ctrl[i]->critical = crit; - control = talloc(ctrl[i], struct ldb_paged_control); - control->size = size; - control->cookie = NULL; - control->cookie_len = 0; - ctrl[i]->data = control; - - continue; - } - - if (strncmp(control_strings[i], "server_sort:", 12) == 0) { - struct ldb_server_sort_control **control; - const char *p; - char attr[256]; - char rule[128]; - int crit, rev, ret; - - attr[0] = '\0'; - rule[0] = '\0'; - p = &(control_strings[i][12]); - ret = sscanf(p, "%d:%d:%255[^:]:%127[^:]", &crit, &rev, attr, rule); - if ((ret < 3) || (crit < 0) || (crit > 1) || (rev < 0 ) || (rev > 1) ||attr[0] == '\0') { - fprintf(stderr, "invalid server_sort control syntax\n"); - fprintf(stderr, " syntax: crit(b):rev(b):attr(s)[:rule(s)]\n"); - fprintf(stderr, " note: b = boolean, s = string\n"); - return NULL; - } - ctrl[i] = talloc(ctrl, struct ldb_control); - ctrl[i]->oid = LDB_CONTROL_SERVER_SORT_OID; - ctrl[i]->critical = crit; - control = talloc_array(ctrl[i], struct ldb_server_sort_control *, 2); - control[0] = talloc(control, struct ldb_server_sort_control); - control[0]->attributeName = talloc_strdup(control, attr); - if (rule[0]) - control[0]->orderingRule = talloc_strdup(control, rule); - else - control[0]->orderingRule = NULL; - control[0]->reverse = rev; - control[1] = NULL; - ctrl[i]->data = control; - - continue; - } - - if (strncmp(control_strings[i], "notification:", 13) == 0) { - const char *p; - int crit, ret; - - p = &(control_strings[i][13]); - ret = sscanf(p, "%d", &crit); - if ((ret != 1) || (crit < 0) || (crit > 1)) { - fprintf(stderr, "invalid notification control syntax\n"); - fprintf(stderr, " syntax: crit(b)\n"); - fprintf(stderr, " note: b = boolean\n"); - return NULL; - } - - ctrl[i] = talloc(ctrl, struct ldb_control); - ctrl[i]->oid = LDB_CONTROL_NOTIFICATION_OID; - ctrl[i]->critical = crit; - ctrl[i]->data = NULL; - - continue; - } - - if (strncmp(control_strings[i], "show_deleted:", 13) == 0) { - const char *p; - int crit, ret; - - p = &(control_strings[i][13]); - ret = sscanf(p, "%d", &crit); - if ((ret != 1) || (crit < 0) || (crit > 1)) { - fprintf(stderr, "invalid show_deleted control syntax\n"); - fprintf(stderr, " syntax: crit(b)\n"); - fprintf(stderr, " note: b = boolean\n"); - return NULL; - } - - ctrl[i] = talloc(ctrl, struct ldb_control); - ctrl[i]->oid = LDB_CONTROL_SHOW_DELETED_OID; - ctrl[i]->critical = crit; - ctrl[i]->data = NULL; - - continue; - } - - if (strncmp(control_strings[i], "permissive_modify:", 18) == 0) { - const char *p; - int crit, ret; - - p = &(control_strings[i][18]); - ret = sscanf(p, "%d", &crit); - if ((ret != 1) || (crit < 0) || (crit > 1)) { - fprintf(stderr, "invalid permissive_modify control syntax\n"); - fprintf(stderr, " syntax: crit(b)\n"); - fprintf(stderr, " note: b = boolean\n"); - return NULL; - } - - ctrl[i] = talloc(ctrl, struct ldb_control); - ctrl[i]->oid = LDB_CONTROL_PERMISSIVE_MODIFY_OID; - ctrl[i]->critical = crit; - ctrl[i]->data = NULL; - - continue; - } - - /* no controls matched, throw an error */ - fprintf(stderr, "Invalid control name: '%s'\n", control_strings[i]); - return NULL; - } - - ctrl[i] = NULL; - - return ctrl; -} - - -/* this function check controls reply and determines if more - * processing is needed setting up the request controls correctly - * - * returns: - * -1 error - * 0 all ok - * 1 all ok, more processing required - */ -int handle_controls_reply(struct ldb_control **reply, struct ldb_control **request) -{ - int i, j; - int ret = 0; - - if (reply == NULL || request == NULL) return -1; - - for (i = 0; reply[i]; i++) { - if (strcmp(LDB_CONTROL_VLV_RESP_OID, reply[i]->oid) == 0) { - struct ldb_vlv_resp_control *rep_control; - - rep_control = talloc_get_type(reply[i]->data, struct ldb_vlv_resp_control); - - /* check we have a matching control in the request */ - for (j = 0; request[j]; j++) { - if (strcmp(LDB_CONTROL_VLV_REQ_OID, request[j]->oid) == 0) - break; - } - if (! request[j]) { - fprintf(stderr, "Warning VLV reply received but no request have been made\n"); - continue; - } - - /* check the result */ - if (rep_control->vlv_result != 0) { - fprintf(stderr, "Warning: VLV not performed with error: %d\n", rep_control->vlv_result); - } else { - fprintf(stderr, "VLV Info: target position = %d, content count = %d\n", rep_control->targetPosition, rep_control->contentCount); - } - - continue; - } - - if (strcmp(LDB_CONTROL_ASQ_OID, reply[i]->oid) == 0) { - struct ldb_asq_control *rep_control; - - rep_control = talloc_get_type(reply[i]->data, struct ldb_asq_control); - - /* check the result */ - if (rep_control->result != 0) { - fprintf(stderr, "Warning: ASQ not performed with error: %d\n", rep_control->result); - } - - continue; - } - - if (strcmp(LDB_CONTROL_PAGED_RESULTS_OID, reply[i]->oid) == 0) { - struct ldb_paged_control *rep_control, *req_control; - - rep_control = talloc_get_type(reply[i]->data, struct ldb_paged_control); - if (rep_control->cookie_len == 0) /* we are done */ - break; - - /* more processing required */ - /* let's fill in the request control with the new cookie */ - - for (j = 0; request[j]; j++) { - if (strcmp(LDB_CONTROL_PAGED_RESULTS_OID, request[j]->oid) == 0) - break; - } - /* if there's a reply control we must find a request - * control matching it */ - if (! request[j]) return -1; - - req_control = talloc_get_type(request[j]->data, struct ldb_paged_control); - - if (req_control->cookie) - talloc_free(req_control->cookie); - req_control->cookie = (char *)talloc_memdup( - req_control, rep_control->cookie, - rep_control->cookie_len); - req_control->cookie_len = rep_control->cookie_len; - - ret = 1; - - continue; - } - - if (strcmp(LDB_CONTROL_SORT_RESP_OID, reply[i]->oid) == 0) { - struct ldb_sort_resp_control *rep_control; - - rep_control = talloc_get_type(reply[i]->data, struct ldb_sort_resp_control); - - /* check we have a matching control in the request */ - for (j = 0; request[j]; j++) { - if (strcmp(LDB_CONTROL_SERVER_SORT_OID, request[j]->oid) == 0) - break; - } - if (! request[j]) { - fprintf(stderr, "Warning Server Sort reply received but no request found\n"); - continue; - } - - /* check the result */ - if (rep_control->result != 0) { - fprintf(stderr, "Warning: Sorting not performed with error: %d\n", rep_control->result); - } - - continue; - } - - if (strcmp(LDB_CONTROL_DIRSYNC_OID, reply[i]->oid) == 0) { - struct ldb_dirsync_control *rep_control, *req_control; - char *cookie; - - rep_control = talloc_get_type(reply[i]->data, struct ldb_dirsync_control); - if (rep_control->cookie_len == 0) /* we are done */ - break; - - /* more processing required */ - /* let's fill in the request control with the new cookie */ - - for (j = 0; request[j]; j++) { - if (strcmp(LDB_CONTROL_DIRSYNC_OID, request[j]->oid) == 0) - break; - } - /* if there's a reply control we must find a request - * control matching it */ - if (! request[j]) return -1; - - req_control = talloc_get_type(request[j]->data, struct ldb_dirsync_control); - - if (req_control->cookie) - talloc_free(req_control->cookie); - req_control->cookie = (char *)talloc_memdup( - req_control, rep_control->cookie, - rep_control->cookie_len); - req_control->cookie_len = rep_control->cookie_len; - - cookie = ldb_base64_encode(req_control, rep_control->cookie, rep_control->cookie_len); - printf("# DIRSYNC cookie returned was:\n# %s\n", cookie); - - continue; - } - - /* no controls matched, throw a warning */ - fprintf(stderr, "Unknown reply control oid: %s\n", reply[i]->oid); - } - - return ret; -} - diff --git a/source/lib/ldb/tools/cmdline.h b/source/lib/ldb/tools/cmdline.h deleted file mode 100644 index 0855f77575c..00000000000 --- a/source/lib/ldb/tools/cmdline.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - ldb database library - command line handling for ldb tools - - Copyright (C) Andrew Tridgell 2005 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include <popt.h> - -struct ldb_cmdline { - const char *url; - enum ldb_scope scope; - const char *basedn; - int interactive; - int sorted; - const char *editor; - int verbose; - int recursive; - int all_records; - int nosync; - const char **options; - int argc; - const char **argv; - int num_records; - int num_searches; - const char *sasl_mechanism; - const char *input; - const char *output; - char **controls; -}; - -struct ldb_cmdline *ldb_cmdline_process(struct ldb_context *ldb, int argc, const char **argv, - void (*usage)(void)); - - -struct ldb_control **parse_controls(void *mem_ctx, char **control_strings); -int handle_controls_reply(struct ldb_control **reply, struct ldb_control **request); diff --git a/source/lib/ldb/tools/convert.c b/source/lib/ldb/tools/convert.c deleted file mode 100644 index 23209700304..00000000000 --- a/source/lib/ldb/tools/convert.c +++ /dev/null @@ -1,166 +0,0 @@ -/* - ldb database library - - Copyright (C) Simo Sorce 2005 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include "convert.h" -#include "includes.h" -#include "ldb/include/includes.h" - -/* Shared map for converting syntax between formats */ -static const struct syntax_map syntax_map[] = { - { - .Standard_OID = "1.3.6.1.4.1.1466.115.121.1.12", - .AD_OID = "2.5.5.1", - .equality = "distinguishedNameMatch", - .comment = "Object(DS-DN) == a DN" - }, - { - .Standard_OID = "1.3.6.1.4.1.1466.115.121.1.38", - .AD_OID = "2.5.5.2", - .equality = "objectIdentifierMatch", - .comment = "OID String" - }, - { - .Standard_OID = "1.2.840.113556.1.4.905", - .AD_OID = "2.5.5.4", - .equality = "caseIgnoreMatch", - .substring = "caseIgnoreSubstringsMatch", - .comment = "Case Insensitive String" - }, - { - .Standard_OID = "1.3.6.1.4.1.1466.115.121.1.26", - .AD_OID = "2.5.5.5", - .equality = "caseExactIA5Match", - .comment = "Printable String" - }, - { - .Standard_OID = "1.3.6.1.4.1.1466.115.121.1.36", - .AD_OID = "2.5.5.6", - .equality = "numericStringMatch", - .substring = "numericStringSubstringsMatch", - .comment = "Numeric String" - }, - { - .Standard_OID = "1.2.840.113556.1.4.903", - .AD_OID = "2.5.5.7", - .equality = "distinguishedNameMatch", - .comment = "OctetString: Binary+DN" - }, - { - .Standard_OID = "1.3.6.1.4.1.1466.115.121.1.7", - .AD_OID = "2.5.5.8", - .equality = "booleanMatch", - .comment = "Boolean" - }, - { - .Standard_OID = "1.3.6.1.4.1.1466.115.121.1.27", - .AD_OID = "2.5.5.9", - .equality = "integerMatch", - .comment = "Integer" - }, - { - .Standard_OID = "1.3.6.1.4.1.1466.115.121.1.40", - .AD_OID = "2.5.5.10", - .equality = "octetStringMatch", - .comment = "Octet String" - }, - { - .Standard_OID = "1.3.6.1.4.1.1466.115.121.1.24", - .AD_OID = "2.5.5.11", - .equality = "generalizedTimeMatch", - .comment = "Generalized Time" - }, - { - .Standard_OID = "1.3.6.1.4.1.1466.115.121.1.53", - .AD_OID = "2.5.5.11", - .equality = "generalizedTimeMatch", - .comment = "UTC Time" - }, - { - .Standard_OID = "1.3.6.1.4.1.1466.115.121.1.15", - .AD_OID = "2.5.5.12", - .equality = "caseIgnoreMatch", - .substring = "caseIgnoreSubstringsMatch", - .comment = "Directory String" - }, - { - .Standard_OID = "1.3.6.1.4.1.1466.115.121.1.43", - .AD_OID = "2.5.5.13", - .comment = "Presentation Address" - }, - { - .Standard_OID = "Not Found Yet", - .AD_OID = "2.5.5.14", - .equality = "distinguishedNameMatch", - .comment = "OctetString: String+DN" - }, - { - .Standard_OID = "1.2.840.113556.1.4.907", - .AD_OID = "2.5.5.15", - .equality = "octetStringMatch", - .comment = "NT Security Descriptor" - }, - { - .Standard_OID = "1.2.840.113556.1.4.906", - .AD_OID = "2.5.5.16", - .equality = "integerMatch", - .comment = "Large Integer" - }, - { - .Standard_OID = "1.3.6.1.4.1.1466.115.121.1.40", - .AD_OID = "2.5.5.17", - .equality = "octetStringMatch", - .comment = "Octet String - Security Identifier (SID)" - }, - { - .Standard_OID = "1.3.6.1.4.1.1466.115.121.1.26", - .AD_OID = "2.5.5.5", - .equality = "caseExactIA5Match", - .comment = "IA5 String" - }, - { .Standard_OID = NULL - } -}; - - -const struct syntax_map *find_syntax_map_by_ad_oid(const char *ad_oid) -{ - int i; - for (i=0; syntax_map[i].Standard_OID; i++) { - if (strcasecmp(ad_oid, syntax_map[i].AD_OID) == 0) { - return &syntax_map[i]; - } - } - return NULL; -} - -const struct syntax_map *find_syntax_map_by_standard_oid(const char *standard_oid) -{ - int i; - for (i=0; syntax_map[i].Standard_OID; i++) { - if (strcasecmp(standard_oid, syntax_map[i].Standard_OID) == 0) { - return &syntax_map[i]; - } - } - return NULL; -} diff --git a/source/lib/ldb/tools/convert.h b/source/lib/ldb/tools/convert.h deleted file mode 100644 index de379343a68..00000000000 --- a/source/lib/ldb/tools/convert.h +++ /dev/null @@ -1,10 +0,0 @@ -struct syntax_map { - const char *Standard_OID; - const char *AD_OID; - const char *equality; - const char *substring; - const char *comment; -}; - -const struct syntax_map *find_syntax_map_by_ad_oid(const char *ad_oid); -const struct syntax_map *find_syntax_map_by_standard_oid(const char *standard_oid); diff --git a/source/lib/ldb/tools/ldbadd.c b/source/lib/ldb/tools/ldbadd.c deleted file mode 100644 index 9595703e92c..00000000000 --- a/source/lib/ldb/tools/ldbadd.c +++ /dev/null @@ -1,120 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - * Name: ldb - * - * Component: ldbadd - * - * Description: utility to add records - modelled on ldapadd - * - * Author: Andrew Tridgell - */ - -#include "includes.h" -#include "ldb/include/includes.h" -#include "ldb/tools/cmdline.h" - -static int failures; - -static void usage(void) -{ - printf("Usage: ldbadd <options> <ldif...>\n"); - printf("Options:\n"); - printf(" -H ldb_url choose the database (or $LDB_URL)\n"); - printf(" -o options pass options like modules to activate\n"); - printf(" e.g: -o modules:timestamps\n"); - printf("\n"); - printf("Adds records to a ldb, reading ldif the specified list of files\n\n"); - exit(1); -} - - -/* - add records from an opened file -*/ -static int process_file(struct ldb_context *ldb, FILE *f, int *count) -{ - struct ldb_ldif *ldif; - int ret = LDB_SUCCESS; - - while ((ldif = ldb_ldif_read_file(ldb, f))) { - if (ldif->changetype != LDB_CHANGETYPE_ADD && - ldif->changetype != LDB_CHANGETYPE_NONE) { - fprintf(stderr, "Only CHANGETYPE_ADD records allowed\n"); - break; - } - - ldif->msg = ldb_msg_canonicalize(ldb, ldif->msg); - - ret = ldb_add(ldb, ldif->msg); - if (ret != LDB_SUCCESS) { - fprintf(stderr, "ERR: \"%s\" on DN %s\n", - ldb_errstring(ldb), ldb_dn_linearize(ldb, ldif->msg->dn)); - failures++; - } else { - (*count)++; - } - ldb_ldif_read_free(ldb, ldif); - } - - return ret; -} - - - -int main(int argc, const char **argv) -{ - struct ldb_context *ldb; - int i, ret=0, count=0; - struct ldb_cmdline *options; - - ldb_global_init(); - - ldb = ldb_init(NULL); - - options = ldb_cmdline_process(ldb, argc, argv, usage); - - if (options->argc == 0) { - ret = process_file(ldb, stdin, &count); - } else { - for (i=0;i<options->argc;i++) { - const char *fname = options->argv[i]; - FILE *f; - f = fopen(fname, "r"); - if (!f) { - perror(fname); - exit(1); - } - ret = process_file(ldb, f, &count); - fclose(f); - } - } - - talloc_free(ldb); - - printf("Added %d records with %d failures\n", count, failures); - - return ret; -} diff --git a/source/lib/ldb/tools/ldbdel.c b/source/lib/ldb/tools/ldbdel.c deleted file mode 100644 index 94f1da99037..00000000000 --- a/source/lib/ldb/tools/ldbdel.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - * Name: ldb - * - * Component: ldbdel - * - * Description: utility to delete records - modelled on ldapdelete - * - * Author: Andrew Tridgell - */ - -#include "includes.h" -#include "ldb/include/includes.h" -#include "ldb/tools/cmdline.h" - -static int ldb_delete_recursive(struct ldb_context *ldb, const struct ldb_dn *dn) -{ - int ret, i, total=0; - const char *attrs[] = { NULL }; - struct ldb_result *res; - - ret = ldb_search(ldb, dn, LDB_SCOPE_SUBTREE, "distinguishedName=*", attrs, &res); - if (ret != LDB_SUCCESS) return -1; - - for (i = 0; i < res->count; i++) { - if (ldb_delete(ldb, res->msgs[i]->dn) == 0) { - total++; - } - } - - talloc_free(res); - - if (total == 0) { - return -1; - } - printf("Deleted %d records\n", total); - return 0; -} - -static void usage(void) -{ - printf("Usage: ldbdel <options> <DN...>\n"); - printf("Options:\n"); - printf(" -r recursively delete the given subtree\n"); - printf(" -H ldb_url choose the database (or $LDB_URL)\n"); - printf(" -o options pass options like modules to activate\n"); - printf(" e.g: -o modules:timestamps\n"); - printf("\n"); - printf("Deletes records from a ldb\n\n"); - exit(1); -} - -int main(int argc, const char **argv) -{ - struct ldb_context *ldb; - int ret = 0, i; - struct ldb_cmdline *options; - - ldb_global_init(); - - ldb = ldb_init(NULL); - - options = ldb_cmdline_process(ldb, argc, argv, usage); - - if (options->argc < 1) { - usage(); - exit(1); - } - - for (i=0;i<options->argc;i++) { - const struct ldb_dn *dn; - - dn = ldb_dn_explode(ldb, options->argv[i]); - if (dn == NULL) { - printf("Invalid DN format\n"); - exit(1); - } - if (options->recursive) { - ret = ldb_delete_recursive(ldb, dn); - } else { - ret = ldb_delete(ldb, dn); - if (ret == 0) { - printf("Deleted 1 record\n"); - } - } - if (ret != 0) { - printf("delete of '%s' failed - %s\n", - ldb_dn_linearize(ldb, dn), - ldb_errstring(ldb)); - } - } - - talloc_free(ldb); - - return ret; -} diff --git a/source/lib/ldb/tools/ldbedit.c b/source/lib/ldb/tools/ldbedit.c deleted file mode 100644 index 17ade152b78..00000000000 --- a/source/lib/ldb/tools/ldbedit.c +++ /dev/null @@ -1,333 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - * Name: ldb - * - * Component: ldbedit - * - * Description: utility for ldb database editing - * - * Author: Andrew Tridgell - */ - -#include "includes.h" -#include "ldb/include/includes.h" -#include "ldb/tools/cmdline.h" - -static struct ldb_cmdline *options; - -/* - debug routine -*/ -static void ldif_write_msg(struct ldb_context *ldb, - FILE *f, - enum ldb_changetype changetype, - struct ldb_message *msg) -{ - struct ldb_ldif ldif; - ldif.changetype = changetype; - ldif.msg = msg; - ldb_ldif_write_file(ldb, f, &ldif); -} - -/* - modify a database record so msg1 becomes msg2 - returns the number of modified elements -*/ -static int modify_record(struct ldb_context *ldb, - struct ldb_message *msg1, - struct ldb_message *msg2) -{ - struct ldb_message *mod; - - mod = ldb_msg_diff(ldb, msg1, msg2); - if (mod == NULL) { - fprintf(stderr, "Failed to calculate message differences\n"); - return -1; - } - - if (mod->num_elements == 0) { - return 0; - } - - if (options->verbose > 0) { - ldif_write_msg(ldb, stdout, LDB_CHANGETYPE_MODIFY, mod); - } - - if (ldb_modify(ldb, mod) != 0) { - fprintf(stderr, "failed to modify %s - %s\n", - ldb_dn_linearize(ldb, msg1->dn), ldb_errstring(ldb)); - return -1; - } - - return mod->num_elements; -} - -/* - find dn in msgs[] -*/ -static struct ldb_message *msg_find(struct ldb_context *ldb, - struct ldb_message **msgs, - int count, - const struct ldb_dn *dn) -{ - int i; - for (i=0;i<count;i++) { - if (ldb_dn_compare(ldb, dn, msgs[i]->dn) == 0) { - return msgs[i]; - } - } - return NULL; -} - -/* - merge the changes in msgs2 into the messages from msgs1 -*/ -static int merge_edits(struct ldb_context *ldb, - struct ldb_message **msgs1, int count1, - struct ldb_message **msgs2, int count2) -{ - int i; - struct ldb_message *msg; - int ret = 0; - int adds=0, modifies=0, deletes=0; - - /* do the adds and modifies */ - for (i=0;i<count2;i++) { - msg = msg_find(ldb, msgs1, count1, msgs2[i]->dn); - if (!msg) { - if (options->verbose > 0) { - ldif_write_msg(ldb, stdout, LDB_CHANGETYPE_ADD, msgs2[i]); - } - if (ldb_add(ldb, msgs2[i]) != 0) { - fprintf(stderr, "failed to add %s - %s\n", - ldb_dn_linearize(ldb, msgs2[i]->dn), - ldb_errstring(ldb)); - return -1; - } - adds++; - } else { - if (modify_record(ldb, msg, msgs2[i]) > 0) { - modifies++; - } - } - } - - /* do the deletes */ - for (i=0;i<count1;i++) { - msg = msg_find(ldb, msgs2, count2, msgs1[i]->dn); - if (!msg) { - if (options->verbose > 0) { - ldif_write_msg(ldb, stdout, LDB_CHANGETYPE_DELETE, msgs1[i]); - } - if (ldb_delete(ldb, msgs1[i]->dn) != 0) { - fprintf(stderr, "failed to delete %s - %s\n", - ldb_dn_linearize(ldb, msgs1[i]->dn), - ldb_errstring(ldb)); - return -1; - } - deletes++; - } - } - - printf("# %d adds %d modifies %d deletes\n", adds, modifies, deletes); - - return ret; -} - -/* - save a set of messages as ldif to a file -*/ -static int save_ldif(struct ldb_context *ldb, - FILE *f, struct ldb_message **msgs, int count) -{ - int i; - - fprintf(f, "# editing %d records\n", count); - - for (i=0;i<count;i++) { - struct ldb_ldif ldif; - fprintf(f, "# record %d\n", i+1); - - ldif.changetype = LDB_CHANGETYPE_NONE; - ldif.msg = msgs[i]; - - ldb_ldif_write_file(ldb, f, &ldif); - } - - return 0; -} - - -/* - edit the ldb search results in msgs using the user selected editor -*/ -static int do_edit(struct ldb_context *ldb, struct ldb_message **msgs1, int count1, - const char *editor) -{ - int fd, ret; - FILE *f; - char file_template[] = "/tmp/ldbedit.XXXXXX"; - char *cmd; - struct ldb_ldif *ldif; - struct ldb_message **msgs2 = NULL; - int count2 = 0; - - /* write out the original set of messages to a temporary - file */ - fd = mkstemp(file_template); - - if (fd == -1) { - perror(file_template); - return -1; - } - - f = fdopen(fd, "r+"); - - if (!f) { - perror("fopen"); - close(fd); - unlink(file_template); - return -1; - } - - if (save_ldif(ldb, f, msgs1, count1) != 0) { - return -1; - } - - fclose(f); - - cmd = talloc_asprintf(ldb, "%s %s", editor, file_template); - - if (!cmd) { - unlink(file_template); - fprintf(stderr, "out of memory\n"); - return -1; - } - - /* run the editor */ - ret = system(cmd); - talloc_free(cmd); - - if (ret != 0) { - unlink(file_template); - fprintf(stderr, "edit with %s failed\n", editor); - return -1; - } - - /* read the resulting ldif into msgs2 */ - f = fopen(file_template, "r"); - if (!f) { - perror(file_template); - return -1; - } - - while ((ldif = ldb_ldif_read_file(ldb, f))) { - msgs2 = talloc_realloc(ldb, msgs2, struct ldb_message *, count2+1); - if (!msgs2) { - fprintf(stderr, "out of memory"); - return -1; - } - msgs2[count2++] = ldif->msg; - } - - fclose(f); - unlink(file_template); - - return merge_edits(ldb, msgs1, count1, msgs2, count2); -} - -static void usage(void) -{ - printf("Usage: ldbedit <options> <expression> <attributes ...>\n"); - printf("Options:\n"); - printf(" -H ldb_url choose the database (or $LDB_URL)\n"); - printf(" -s base|sub|one choose search scope\n"); - printf(" -b basedn choose baseDN\n"); - printf(" -a edit all records (expression 'objectclass=*')\n"); - printf(" -e editor choose editor (or $VISUAL or $EDITOR)\n"); - printf(" -v verbose mode\n"); - exit(1); -} - -int main(int argc, const char **argv) -{ - struct ldb_context *ldb; - struct ldb_result *result = NULL; - struct ldb_dn *basedn = NULL; - int ret; - const char *expression = "(|(objectClass=*)(distinguishedName=*))"; - const char * const * attrs = NULL; - - ldb_global_init(); - - ldb = ldb_init(NULL); - - options = ldb_cmdline_process(ldb, argc, argv, usage); - - /* the check for '=' is for compatibility with ldapsearch */ - if (options->argc > 0 && - strchr(options->argv[0], '=')) { - expression = options->argv[0]; - options->argv++; - options->argc--; - } - - if (options->argc > 0) { - attrs = (const char * const *)(options->argv); - } - - if (options->basedn != NULL) { - basedn = ldb_dn_explode(ldb, options->basedn); - if (basedn == NULL) { - printf("Invalid Base DN format\n"); - exit(1); - } - } - - ret = ldb_search(ldb, basedn, options->scope, expression, attrs, &result); - if (ret != LDB_SUCCESS) { - printf("search failed - %s\n", ldb_errstring(ldb)); - exit(1); - } - - if (result->count == 0) { - printf("no matching records - cannot edit\n"); - return 0; - } - - do_edit(ldb, result->msgs, result->count, options->editor); - - if (result) { - ret = talloc_free(result); - if (ret == -1) { - fprintf(stderr, "talloc_free failed\n"); - exit(1); - } - } - - talloc_free(ldb); - return 0; -} diff --git a/source/lib/ldb/tools/ldbmodify.c b/source/lib/ldb/tools/ldbmodify.c deleted file mode 100644 index 962045ef7d7..00000000000 --- a/source/lib/ldb/tools/ldbmodify.c +++ /dev/null @@ -1,120 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - * Name: ldb - * - * Component: ldbmodify - * - * Description: utility to modify records - modelled on ldapmodify - * - * Author: Andrew Tridgell - */ - -#include "includes.h" -#include "ldb/include/includes.h" -#include "ldb/tools/cmdline.h" - -static int failures; - -static void usage(void) -{ - printf("Usage: ldbmodify <options> <ldif...>\n"); - printf("Options:\n"); - printf(" -H ldb_url choose the database (or $LDB_URL)\n"); - printf(" -o options pass options like modules to activate\n"); - printf(" e.g: -o modules:timestamps\n"); - printf("\n"); - printf("Modifies a ldb based upon ldif change records\n\n"); - exit(1); -} - -/* - process modifies for one file -*/ -static int process_file(struct ldb_context *ldb, FILE *f, int *count) -{ - struct ldb_ldif *ldif; - int ret = LDB_SUCCESS; - - while ((ldif = ldb_ldif_read_file(ldb, f))) { - switch (ldif->changetype) { - case LDB_CHANGETYPE_NONE: - case LDB_CHANGETYPE_ADD: - ret = ldb_add(ldb, ldif->msg); - break; - case LDB_CHANGETYPE_DELETE: - ret = ldb_delete(ldb, ldif->msg->dn); - break; - case LDB_CHANGETYPE_MODIFY: - ret = ldb_modify(ldb, ldif->msg); - break; - } - if (ret != LDB_SUCCESS) { - fprintf(stderr, "ERR: \"%s\" on DN %s\n", - ldb_errstring(ldb), ldb_dn_linearize(ldb, ldif->msg->dn)); - failures++; - } else { - (*count)++; - } - ldb_ldif_read_free(ldb, ldif); - } - - return ret; -} - -int main(int argc, const char **argv) -{ - struct ldb_context *ldb; - int count=0; - int i, ret=LDB_SUCCESS; - struct ldb_cmdline *options; - - ldb_global_init(); - - ldb = ldb_init(NULL); - - options = ldb_cmdline_process(ldb, argc, argv, usage); - - if (options->argc == 0) { - ret = process_file(ldb, stdin, &count); - } else { - for (i=0;i<options->argc;i++) { - const char *fname = options->argv[i]; - FILE *f; - f = fopen(fname, "r"); - if (!f) { - perror(fname); - exit(1); - } - ret = process_file(ldb, f, &count); - } - } - - talloc_free(ldb); - - printf("Modified %d records with %d failures\n", count, failures); - - return ret; -} diff --git a/source/lib/ldb/tools/ldbrename.c b/source/lib/ldb/tools/ldbrename.c deleted file mode 100644 index 9c0870721d4..00000000000 --- a/source/lib/ldb/tools/ldbrename.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - Copyright (C) Stefan Metzmacher 2004 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - * Name: ldb - * - * Component: ldbrename - * - * Description: utility to rename records - modelled on ldapmodrdn - * - * Author: Andrew Tridgell - * Author: Stefan Metzmacher - */ - -#include "includes.h" -#include "ldb/include/includes.h" -#include "ldb/tools/cmdline.h" - -static void usage(void) -{ - printf("Usage: ldbrename [<options>] <olddn> <newdn>\n"); - printf("Options:\n"); - printf(" -H ldb_url choose the database (or $LDB_URL)\n"); - printf(" -o options pass options like modules to activate\n"); - printf(" e.g: -o modules:timestamps\n"); - printf("\n"); - printf("Renames records in a ldb\n\n"); - exit(1); -} - - -int main(int argc, const char **argv) -{ - struct ldb_context *ldb; - int ret; - struct ldb_cmdline *options; - const struct ldb_dn *dn1, *dn2; - - ldb_global_init(); - - ldb = ldb_init(NULL); - - options = ldb_cmdline_process(ldb, argc, argv, usage); - - if (options->argc < 2) { - usage(); - } - - dn1 = ldb_dn_explode(ldb, options->argv[0]); - dn2 = ldb_dn_explode(ldb, options->argv[1]); - - ret = ldb_rename(ldb, dn1, dn2); - if (ret == 0) { - printf("Renamed 1 record\n"); - } else { - printf("rename of '%s' to '%s' failed - %s\n", - options->argv[0], options->argv[1], ldb_errstring(ldb)); - } - - talloc_free(ldb); - - return ret; -} diff --git a/source/lib/ldb/tools/ldbsearch.c b/source/lib/ldb/tools/ldbsearch.c deleted file mode 100644 index 837dfc9088c..00000000000 --- a/source/lib/ldb/tools/ldbsearch.c +++ /dev/null @@ -1,321 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - * Name: ldb - * - * Component: ldbsearch - * - * Description: utility for ldb search - modelled on ldapsearch - * - * Author: Andrew Tridgell - */ - -#include "includes.h" -#include "ldb/include/includes.h" -#include "ldb/tools/cmdline.h" - -static void usage(void) -{ - printf("Usage: ldbsearch <options> <expression> <attrs...>\n"); - printf("Options:\n"); - printf(" -H ldb_url choose the database (or $LDB_URL)\n"); - printf(" -s base|sub|one choose search scope\n"); - printf(" -b basedn choose baseDN\n"); - printf(" -i read search expressions from stdin\n"); - printf(" -S sort returned attributes\n"); - printf(" -o options pass options like modules to activate\n"); - printf(" e.g: -o modules:timestamps\n"); - exit(1); -} - -static int do_compare_msg(struct ldb_message **el1, - struct ldb_message **el2, - void *opaque) -{ - struct ldb_context *ldb = talloc_get_type(opaque, struct ldb_context); - return ldb_dn_compare(ldb, (*el1)->dn, (*el2)->dn); -} - -struct search_context { - struct ldb_control **req_ctrls; - - int sort; - int num_stored; - struct ldb_message **store; - char **refs_store; - - int entries; - int refs; - - int pending; - int status; -}; - -static int store_message(struct ldb_message *msg, struct search_context *sctx) { - - sctx->store = talloc_realloc(sctx, sctx->store, struct ldb_message *, sctx->num_stored + 2); - if (!sctx->store) { - fprintf(stderr, "talloc_realloc failed while storing messages\n"); - return -1; - } - - sctx->store[sctx->num_stored] = talloc_move(sctx->store, &msg); - sctx->num_stored++; - sctx->store[sctx->num_stored] = NULL; - - return 0; -} - -static int store_referral(char *referral, struct search_context *sctx) { - - sctx->refs_store = talloc_realloc(sctx, sctx->refs_store, char *, sctx->refs + 2); - if (!sctx->refs_store) { - fprintf(stderr, "talloc_realloc failed while storing referrals\n"); - return -1; - } - - sctx->refs_store[sctx->refs] = talloc_move(sctx->refs_store, &referral); - sctx->refs++; - sctx->refs_store[sctx->refs] = NULL; - - return 0; -} - -static int display_message(struct ldb_context *ldb, struct ldb_message *msg, struct search_context *sctx) { - struct ldb_ldif ldif; - - sctx->entries++; - printf("# record %d\n", sctx->entries); - - ldif.changetype = LDB_CHANGETYPE_NONE; - ldif.msg = msg; - - if (sctx->sort) { - /* - * Ensure attributes are always returned in the same - * order. For testing, this makes comparison of old - * vs. new much easier. - */ - ldb_msg_sort_elements(ldif.msg); - } - - ldb_ldif_write_file(ldb, stdout, &ldif); - - return 0; -} - -static int display_referral(char *referral, struct search_context *sctx) -{ - - sctx->refs++; - printf("# Referral\nref: %s\n\n", referral); - - return 0; -} - -static int search_callback(struct ldb_context *ldb, void *context, struct ldb_reply *ares) -{ - struct search_context *sctx = talloc_get_type(context, struct search_context); - int ret; - - switch (ares->type) { - - case LDB_REPLY_ENTRY: - if (sctx->sort) { - ret = store_message(ares->message, sctx); - } else { - ret = display_message(ldb, ares->message, sctx); - } - break; - - case LDB_REPLY_REFERRAL: - if (sctx->sort) { - ret = store_referral(ares->referral, sctx); - } else { - ret = display_referral(ares->referral, sctx); - } - break; - - case LDB_REPLY_DONE: - if (ares->controls) { - if (handle_controls_reply(ares->controls, sctx->req_ctrls) == 1) - sctx->pending = 1; - } - ret = 0; - break; - - default: - fprintf(stderr, "unknown Reply Type\n"); - return LDB_ERR_OTHER; - } - - if (talloc_free(ares) == -1) { - fprintf(stderr, "talloc_free failed\n"); - sctx->pending = 0; - return LDB_ERR_OPERATIONS_ERROR; - } - - if (ret) { - return LDB_ERR_OPERATIONS_ERROR; - } - - return LDB_SUCCESS; -} - -static int do_search(struct ldb_context *ldb, - const struct ldb_dn *basedn, - struct ldb_cmdline *options, - const char *expression, - const char * const *attrs) -{ - struct ldb_request *req; - struct search_context *sctx; - int ret; - - req = talloc(ldb, struct ldb_request); - if (!req) return -1; - - sctx = talloc(req, struct search_context); - if (!sctx) return -1; - - sctx->sort = options->sorted; - sctx->num_stored = 0; - sctx->store = NULL; - sctx->req_ctrls = parse_controls(ldb, options->controls); - if (options->controls != NULL && sctx->req_ctrls== NULL) return -1; - sctx->entries = 0; - sctx->refs = 0; - - if (basedn == NULL) { - basedn = ldb_get_default_basedn(ldb); - } - - req->operation = LDB_SEARCH; - req->op.search.base = basedn; - req->op.search.scope = options->scope; - req->op.search.tree = ldb_parse_tree(req, expression); - if (req->op.search.tree == NULL) return -1; - req->op.search.attrs = attrs; - req->controls = sctx->req_ctrls; - req->context = sctx; - req->callback = &search_callback; - ldb_set_timeout(ldb, req, 0); /* TODO: make this settable by command line */ - -again: - sctx->pending = 0; - - ret = ldb_request(ldb, req); - if (ret != LDB_SUCCESS) { - printf("search failed - %s\n", ldb_errstring(ldb)); - return -1; - } - - ret = ldb_wait(req->handle, LDB_WAIT_ALL); - if (ret != LDB_SUCCESS) { - printf("search error - %s\n", ldb_errstring(ldb)); - return -1; - } - - if (sctx->pending) - goto again; - - if (sctx->sort && sctx->num_stored != 0) { - int i; - - ldb_qsort(sctx->store, ret, sizeof(struct ldb_message *), - ldb, (ldb_qsort_cmp_fn_t)do_compare_msg); - - if (ret != 0) { - fprintf(stderr, "An error occurred while sorting messages\n"); - exit(1); - } - - for (i = 0; i < sctx->num_stored; i++) { - display_message(ldb, sctx->store[i], sctx); - } - - for (i = 0; i < sctx->refs; i++) { - display_referral(sctx->refs_store[i], sctx); - } - } - - printf("# returned %d records\n# %d entries\n# %d referrals\n", - sctx->entries + sctx->refs, sctx->entries, sctx->refs); - - talloc_free(req); - - return 0; -} - -int main(int argc, const char **argv) -{ - struct ldb_context *ldb; - struct ldb_dn *basedn = NULL; - const char * const * attrs = NULL; - struct ldb_cmdline *options; - int ret = -1; - const char *expression = "(|(objectClass=*)(distinguishedName=*))"; - - ldb_global_init(); - - ldb = ldb_init(NULL); - - options = ldb_cmdline_process(ldb, argc, argv, usage); - - /* the check for '=' is for compatibility with ldapsearch */ - if (!options->interactive && - options->argc > 0 && - strchr(options->argv[0], '=')) { - expression = options->argv[0]; - options->argv++; - options->argc--; - } - - if (options->argc > 0) { - attrs = (const char * const *)(options->argv); - } - - if (options->basedn != NULL) { - basedn = ldb_dn_explode(ldb, options->basedn); - if (basedn == NULL) { - fprintf(stderr, "Invalid Base DN format\n"); - exit(1); - } - } - - if (options->interactive) { - char line[1024]; - while (fgets(line, sizeof(line), stdin)) { - if (do_search(ldb, basedn, options, line, attrs) == -1) { - ret = -1; - } - } - } else { - ret = do_search(ldb, basedn, options, expression, attrs); - } - - talloc_free(ldb); - return ret; -} diff --git a/source/lib/ldb/tools/ldbtest.c b/source/lib/ldb/tools/ldbtest.c deleted file mode 100644 index 6cc8dfe19b2..00000000000 --- a/source/lib/ldb/tools/ldbtest.c +++ /dev/null @@ -1,410 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - * Name: ldb - * - * Component: ldbtest - * - * Description: utility to test ldb - * - * Author: Andrew Tridgell - */ - -#include "includes.h" -#include "ldb/include/includes.h" -#include "ldb/tools/cmdline.h" - -static struct timeval tp1,tp2; -static struct ldb_cmdline *options; - -static void _start_timer(void) -{ - gettimeofday(&tp1,NULL); -} - -static double _end_timer(void) -{ - gettimeofday(&tp2,NULL); - return((tp2.tv_sec - tp1.tv_sec) + - (tp2.tv_usec - tp1.tv_usec)*1.0e-6); -} - -static void add_records(struct ldb_context *ldb, - const struct ldb_dn *basedn, - int count) -{ - struct ldb_message msg; - int i; - -#if 0 - if (ldb_lock(ldb, "transaction") != 0) { - printf("transaction lock failed\n"); - exit(1); - } -#endif - for (i=0;i<count;i++) { - struct ldb_message_element el[6]; - struct ldb_val vals[6][1]; - char *name; - TALLOC_CTX *tmp_ctx = talloc_new(ldb); - - name = talloc_asprintf(tmp_ctx, "Test%d", i); - - msg.dn = ldb_dn_build_child(tmp_ctx, "cn", name, basedn); - msg.num_elements = 6; - msg.elements = el; - - el[0].flags = 0; - el[0].name = talloc_strdup(tmp_ctx, "cn"); - el[0].num_values = 1; - el[0].values = vals[0]; - vals[0][0].data = (uint8_t *)name; - vals[0][0].length = strlen(name); - - el[1].flags = 0; - el[1].name = "title"; - el[1].num_values = 1; - el[1].values = vals[1]; - vals[1][0].data = (uint8_t *)talloc_asprintf(tmp_ctx, "The title of %s", name); - vals[1][0].length = strlen((char *)vals[1][0].data); - - el[2].flags = 0; - el[2].name = talloc_strdup(tmp_ctx, "uid"); - el[2].num_values = 1; - el[2].values = vals[2]; - vals[2][0].data = (uint8_t *)ldb_casefold(ldb, tmp_ctx, name); - vals[2][0].length = strlen((char *)vals[2][0].data); - - el[3].flags = 0; - el[3].name = talloc_strdup(tmp_ctx, "mail"); - el[3].num_values = 1; - el[3].values = vals[3]; - vals[3][0].data = (uint8_t *)talloc_asprintf(tmp_ctx, "%s@example.com", name); - vals[3][0].length = strlen((char *)vals[3][0].data); - - el[4].flags = 0; - el[4].name = talloc_strdup(tmp_ctx, "objectClass"); - el[4].num_values = 1; - el[4].values = vals[4]; - vals[4][0].data = (uint8_t *)talloc_strdup(tmp_ctx, "OpenLDAPperson"); - vals[4][0].length = strlen((char *)vals[4][0].data); - - el[5].flags = 0; - el[5].name = talloc_strdup(tmp_ctx, "sn"); - el[5].num_values = 1; - el[5].values = vals[5]; - vals[5][0].data = (uint8_t *)name; - vals[5][0].length = strlen((char *)vals[5][0].data); - - ldb_delete(ldb, msg.dn); - - if (ldb_add(ldb, &msg) != 0) { - printf("Add of %s failed - %s\n", name, ldb_errstring(ldb)); - exit(1); - } - - printf("adding uid %s\r", name); - fflush(stdout); - - talloc_free(tmp_ctx); - } -#if 0 - if (ldb_unlock(ldb, "transaction") != 0) { - printf("transaction unlock failed\n"); - exit(1); - } -#endif - printf("\n"); -} - -static void modify_records(struct ldb_context *ldb, - const struct ldb_dn *basedn, - int count) -{ - struct ldb_message msg; - int i; - - for (i=0;i<count;i++) { - struct ldb_message_element el[3]; - struct ldb_val vals[3]; - char *name; - TALLOC_CTX *tmp_ctx = talloc_new(ldb); - - name = talloc_asprintf(tmp_ctx, "Test%d", i); - msg.dn = ldb_dn_build_child(tmp_ctx, "cn", name, basedn); - - msg.num_elements = 3; - msg.elements = el; - - el[0].flags = LDB_FLAG_MOD_DELETE; - el[0].name = talloc_strdup(tmp_ctx, "mail"); - el[0].num_values = 0; - - el[1].flags = LDB_FLAG_MOD_ADD; - el[1].name = talloc_strdup(tmp_ctx, "mail"); - el[1].num_values = 1; - el[1].values = &vals[1]; - vals[1].data = (uint8_t *)talloc_asprintf(tmp_ctx, "%s@other.example.com", name); - vals[1].length = strlen((char *)vals[1].data); - - el[2].flags = LDB_FLAG_MOD_REPLACE; - el[2].name = talloc_strdup(tmp_ctx, "mail"); - el[2].num_values = 1; - el[2].values = &vals[2]; - vals[2].data = (uint8_t *)talloc_asprintf(tmp_ctx, "%s@other2.example.com", name); - vals[2].length = strlen((char *)vals[2].data); - - if (ldb_modify(ldb, &msg) != 0) { - printf("Modify of %s failed - %s\n", name, ldb_errstring(ldb)); - exit(1); - } - - printf("Modifying uid %s\r", name); - fflush(stdout); - - talloc_free(tmp_ctx); - } - - printf("\n"); -} - - -static void delete_records(struct ldb_context *ldb, - const struct ldb_dn *basedn, - int count) -{ - int i; - - for (i=0;i<count;i++) { - struct ldb_dn *dn; - char *name = talloc_asprintf(ldb, "Test%d", i); - dn = ldb_dn_build_child(name, "cn", name, basedn); - - printf("Deleting uid Test%d\r", i); - fflush(stdout); - - if (ldb_delete(ldb, dn) != 0) { - printf("Delete of %s failed - %s\n", ldb_dn_linearize(ldb, dn), ldb_errstring(ldb)); - exit(1); - } - talloc_free(name); - } - - printf("\n"); -} - -static void search_uid(struct ldb_context *ldb, struct ldb_dn *basedn, int nrecords, int nsearches) -{ - int i; - - for (i=0;i<nsearches;i++) { - int uid = (i * 700 + 17) % (nrecords * 2); - char *expr; - struct ldb_result *res = NULL; - int ret; - - expr = talloc_asprintf(ldb, "(uid=TEST%d)", uid); - ret = ldb_search(ldb, basedn, LDB_SCOPE_SUBTREE, expr, NULL, &res); - - if (ret != LDB_SUCCESS || (uid < nrecords && res->count != 1)) { - printf("Failed to find %s - %s\n", expr, ldb_errstring(ldb)); - exit(1); - } - - if (uid >= nrecords && res->count > 0) { - printf("Found %s !? - %d\n", expr, ret); - exit(1); - } - - printf("testing uid %d/%d - %d \r", i, uid, res->count); - fflush(stdout); - - talloc_free(res); - talloc_free(expr); - } - - printf("\n"); -} - -static void start_test(struct ldb_context *ldb, int nrecords, int nsearches) -{ - struct ldb_dn *basedn; - - basedn = ldb_dn_explode(ldb, options->basedn); - - printf("Adding %d records\n", nrecords); - add_records(ldb, basedn, nrecords); - - printf("Starting search on uid\n"); - _start_timer(); - search_uid(ldb, basedn, nrecords, nsearches); - printf("uid search took %.2f seconds\n", _end_timer()); - - printf("Modifying records\n"); - modify_records(ldb, basedn, nrecords); - - printf("Deleting records\n"); - delete_records(ldb, basedn, nrecords); -} - - -/* - 2) Store an @indexlist record - - 3) Store a record that contains fields that should be index according -to @index - - 4) disconnection from database - - 5) connect to same database - - 6) search for record added in step 3 using a search key that should -be indexed -*/ -static void start_test_index(struct ldb_context **ldb) -{ - struct ldb_message *msg; - struct ldb_result *res = NULL; - struct ldb_dn *indexlist; - struct ldb_dn *basedn; - int ret; - int flags = 0; - const char *specials; - - specials = getenv("LDB_SPECIALS"); - if (specials && atoi(specials) == 0) { - printf("LDB_SPECIALS disabled - skipping index test\n"); - return; - } - - if (options->nosync) { - flags |= LDB_FLG_NOSYNC; - } - - printf("Starting index test\n"); - - indexlist = ldb_dn_explode(NULL, "@INDEXLIST"); - - ldb_delete(*ldb, indexlist); - - msg = ldb_msg_new(NULL); - - msg->dn = indexlist; - ldb_msg_add_string(msg, "@IDXATTR", strdup("uid")); - - if (ldb_add(*ldb, msg) != 0) { - printf("Add of %s failed - %s\n", ldb_dn_linearize(*ldb, msg->dn), ldb_errstring(*ldb)); - exit(1); - } - - basedn = ldb_dn_explode(NULL, options->basedn); - - memset(msg, 0, sizeof(*msg)); - msg->dn = ldb_dn_build_child(msg, "cn", "test", basedn); - ldb_msg_add_string(msg, "cn", strdup("test")); - ldb_msg_add_string(msg, "sn", strdup("test")); - ldb_msg_add_string(msg, "uid", strdup("test")); - ldb_msg_add_string(msg, "objectClass", strdup("OpenLDAPperson")); - - if (ldb_add(*ldb, msg) != 0) { - printf("Add of %s failed - %s\n", ldb_dn_linearize(*ldb, msg->dn), ldb_errstring(*ldb)); - exit(1); - } - - if (talloc_free(*ldb) != 0) { - printf("failed to free/close ldb database"); - exit(1); - } - - (*ldb) = ldb_init(options); - - ret = ldb_connect(*ldb, options->url, flags, NULL); - if (ret != 0) { - printf("failed to connect to %s\n", options->url); - exit(1); - } - - ret = ldb_search(*ldb, basedn, LDB_SCOPE_SUBTREE, "uid=test", NULL, &res); - if (ret != LDB_SUCCESS) { - printf("Search with (uid=test) filter failed!\n"); - exit(1); - } - if(res->count != 1) { - printf("Should have found 1 record - found %d\n", res->count); - exit(1); - } - - if (ldb_delete(*ldb, msg->dn) != 0 || - ldb_delete(*ldb, indexlist) != 0) { - printf("cleanup failed - %s\n", ldb_errstring(*ldb)); - exit(1); - } - - printf("Finished index test\n"); -} - - -static void usage(void) -{ - printf("Usage: ldbtest <options>\n"); - printf("Options:\n"); - printf(" -H ldb_url choose the database (or $LDB_URL)\n"); - printf(" --num-records nrecords database size to use\n"); - printf(" --num-searches nsearches number of searches to do\n"); - printf("\n"); - printf("tests ldb API\n\n"); - exit(1); -} - -int main(int argc, const char **argv) -{ - TALLOC_CTX *mem_ctx = talloc_new(NULL); - struct ldb_context *ldb; - - ldb_global_init(); - - ldb = ldb_init(mem_ctx); - - options = ldb_cmdline_process(ldb, argc, argv, usage); - - talloc_steal(mem_ctx, options); - - if (options->basedn == NULL) { - options->basedn = "ou=Ldb Test,ou=People,o=University of Michigan,c=TEST"; - } - - srandom(1); - - printf("Testing with num-records=%d and num-searches=%d\n", - options->num_records, options->num_searches); - - start_test(ldb, options->num_records, options->num_searches); - - start_test_index(&ldb); - - talloc_free(mem_ctx); - - return 0; -} diff --git a/source/lib/ldb/tools/oLschema2ldif.c b/source/lib/ldb/tools/oLschema2ldif.c deleted file mode 100644 index a9e157e3233..00000000000 --- a/source/lib/ldb/tools/oLschema2ldif.c +++ /dev/null @@ -1,608 +0,0 @@ -/* - ldb database library - - Copyright (C) Simo Sorce 2005 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - * Name: ldb - * - * Component: oLschema2ldif - * - * Description: utility to convert an OpenLDAP schema into AD LDIF - * - * Author: Simo Sorce - */ - -#include "includes.h" -#include "ldb/include/includes.h" -#include "ldb/tools/cmdline.h" -#include "ldb/tools/convert.h" - -#define SCHEMA_UNKNOWN 0 -#define SCHEMA_NAME 1 -#define SCHEMA_SUP 2 -#define SCHEMA_STRUCTURAL 3 -#define SCHEMA_ABSTRACT 4 -#define SCHEMA_AUXILIARY 5 -#define SCHEMA_MUST 6 -#define SCHEMA_MAY 7 -#define SCHEMA_SINGLE_VALUE 8 -#define SCHEMA_EQUALITY 9 -#define SCHEMA_ORDERING 10 -#define SCHEMA_SUBSTR 11 -#define SCHEMA_SYNTAX 12 -#define SCHEMA_DESC 13 - -struct schema_conv { - int count; - int failures; -}; - -struct schema_token { - int type; - char *value; -}; - -struct ldb_context *ldb_ctx; -struct ldb_dn *basedn; - -static int check_braces(const char *string) -{ - int b; - char *c; - - b = 0; - if ((c = strchr(string, '(')) == NULL) { - return -1; - } - b++; - c++; - while (b) { - c = strpbrk(c, "()"); - if (c == NULL) return 1; - if (*c == '(') b++; - if (*c == ')') b--; - c++; - } - return 0; -} - -static char *skip_spaces(char *string) { - return (string + strspn(string, " \t\n")); -} - -static int add_multi_string(struct ldb_message *msg, const char *attr, char *values) -{ - char *c; - char *s; - int n; - - c = skip_spaces(values); - while (*c) { - n = strcspn(c, " \t$"); - s = talloc_strndup(msg, c, n); - if (ldb_msg_add_string(msg, attr, s) != 0) { - return -1; - } - c += n; - c += strspn(c, " \t$"); - } - - return 0; -} - -#define MSG_ADD_STRING(a, v) do { if (ldb_msg_add_string(msg, a, v) != 0) goto failed; } while(0) -#define MSG_ADD_M_STRING(a, v) do { if (add_multi_string(msg, a, v) != 0) goto failed; } while(0) - -static char *get_def_value(TALLOC_CTX *ctx, char **string) -{ - char *c = *string; - char *value; - int n; - - if (*c == '\'') { - c++; - n = strcspn(c, "\'"); - value = talloc_strndup(ctx, c, n); - c += n; - c++; /* skip closing \' */ - } else { - n = strcspn(c, " \t\n"); - value = talloc_strndup(ctx, c, n); - c += n; - } - *string = c; - - return value; -} - -static struct schema_token *get_next_schema_token(TALLOC_CTX *ctx, char **string) -{ - char *c = skip_spaces(*string); - char *type; - struct schema_token *token; - int n; - - token = talloc(ctx, struct schema_token); - - n = strcspn(c, " \t\n"); - type = talloc_strndup(token, c, n); - c += n; - c = skip_spaces(c); - - if (strcasecmp("NAME", type) == 0) { - talloc_free(type); - token->type = SCHEMA_NAME; - /* we do not support aliases so we get only the first name given and skip others */ - if (*c == '(') { - char *s = strchr(c, ')'); - if (s == NULL) return NULL; - s = skip_spaces(s); - *string = s; - - c++; - c = skip_spaces(c); - } - - token->value = get_def_value(ctx, &c); - - if (*string < c) { /* single name */ - c = skip_spaces(c); - *string = c; - } - return token; - } - if (strcasecmp("SUP", type) == 0) { - talloc_free(type); - token->type = SCHEMA_SUP; - - if (*c == '(') { - c++; - n = strcspn(c, ")"); - token->value = talloc_strndup(ctx, c, n); - c += n; - c++; - } else { - token->value = get_def_value(ctx, &c); - } - - c = skip_spaces(c); - *string = c; - return token; - } - - if (strcasecmp("STRUCTURAL", type) == 0) { - talloc_free(type); - token->type = SCHEMA_STRUCTURAL; - *string = c; - return token; - } - - if (strcasecmp("ABSTRACT", type) == 0) { - talloc_free(type); - token->type = SCHEMA_ABSTRACT; - *string = c; - return token; - } - - if (strcasecmp("AUXILIARY", type) == 0) { - talloc_free(type); - token->type = SCHEMA_AUXILIARY; - *string = c; - return token; - } - - if (strcasecmp("MUST", type) == 0) { - talloc_free(type); - token->type = SCHEMA_MUST; - - if (*c == '(') { - c++; - n = strcspn(c, ")"); - token->value = talloc_strndup(ctx, c, n); - c += n; - c++; - } else { - token->value = get_def_value(ctx, &c); - } - - c = skip_spaces(c); - *string = c; - return token; - } - - if (strcasecmp("MAY", type) == 0) { - talloc_free(type); - token->type = SCHEMA_MAY; - - if (*c == '(') { - c++; - n = strcspn(c, ")"); - token->value = talloc_strndup(ctx, c, n); - c += n; - c++; - } else { - token->value = get_def_value(ctx, &c); - } - - c = skip_spaces(c); - *string = c; - return token; - } - - if (strcasecmp("SINGLE-VALUE", type) == 0) { - talloc_free(type); - token->type = SCHEMA_SINGLE_VALUE; - *string = c; - return token; - } - - if (strcasecmp("EQUALITY", type) == 0) { - talloc_free(type); - token->type = SCHEMA_EQUALITY; - - token->value = get_def_value(ctx, &c); - - c = skip_spaces(c); - *string = c; - return token; - } - - if (strcasecmp("ORDERING", type) == 0) { - talloc_free(type); - token->type = SCHEMA_ORDERING; - - token->value = get_def_value(ctx, &c); - - c = skip_spaces(c); - *string = c; - return token; - } - - if (strcasecmp("SUBSTR", type) == 0) { - talloc_free(type); - token->type = SCHEMA_SUBSTR; - - token->value = get_def_value(ctx, &c); - - c = skip_spaces(c); - *string = c; - return token; - } - - if (strcasecmp("SYNTAX", type) == 0) { - talloc_free(type); - token->type = SCHEMA_SYNTAX; - - token->value = get_def_value(ctx, &c); - - c = skip_spaces(c); - *string = c; - return token; - } - - if (strcasecmp("DESC", type) == 0) { - talloc_free(type); - token->type = SCHEMA_DESC; - - token->value = get_def_value(ctx, &c); - - c = skip_spaces(c); - *string = c; - return token; - } - - token->type = SCHEMA_UNKNOWN; - token->value = type; - if (*c == ')') { - *string = c; - return token; - } - if (*c == '\'') { - c = strchr(++c, '\''); - c++; - } else { - c += strcspn(c, " \t\n"); - } - c = skip_spaces(c); - *string = c; - - return token; -} - -static struct ldb_message *process_entry(TALLOC_CTX *mem_ctx, const char *entry) -{ - TALLOC_CTX *ctx; - struct ldb_message *msg; - struct schema_token *token; - char *c, *s; - int n; - - ctx = talloc_new(mem_ctx); - msg = ldb_msg_new(ctx); - - ldb_msg_add_string(msg, "objectClass", "top"); - - c = talloc_strdup(ctx, entry); - if (!c) return NULL; - - c = skip_spaces(c); - - switch (*c) { - case 'a': - if (strncmp(c, "attributetype", 13) == 0) { - c += 13; - MSG_ADD_STRING("objectClass", "attributeSchema"); - break; - } - goto failed; - case 'o': - if (strncmp(c, "objectclass", 11) == 0) { - c += 11; - MSG_ADD_STRING("objectClass", "classSchema"); - break; - } - goto failed; - default: - goto failed; - } - - c = strchr(c, '('); - if (c == NULL) goto failed; - c++; - - c = skip_spaces(c); - - /* get attributeID */ - n = strcspn(c, " \t"); - s = talloc_strndup(msg, c, n); - MSG_ADD_STRING("attributeID", s); - c += n; - c = skip_spaces(c); - - while (*c != ')') { - token = get_next_schema_token(msg, &c); - if (!token) goto failed; - - switch (token->type) { - case SCHEMA_NAME: - MSG_ADD_STRING("cn", token->value); - MSG_ADD_STRING("name", token->value); - MSG_ADD_STRING("lDAPDisplayName", token->value); - msg->dn = ldb_dn_string_compose(msg, basedn, - "CN=%s,CN=Schema,CN=Configuration", - token->value); - break; - - case SCHEMA_SUP: - MSG_ADD_M_STRING("subClassOf", token->value); - break; - - case SCHEMA_STRUCTURAL: - MSG_ADD_STRING("objectClassCategory", "1"); - break; - - case SCHEMA_ABSTRACT: - MSG_ADD_STRING("objectClassCategory", "2"); - break; - - case SCHEMA_AUXILIARY: - MSG_ADD_STRING("objectClassCategory", "3"); - break; - - case SCHEMA_MUST: - MSG_ADD_M_STRING("mustContain", token->value); - break; - - case SCHEMA_MAY: - MSG_ADD_M_STRING("mayContain", token->value); - break; - - case SCHEMA_SINGLE_VALUE: - MSG_ADD_STRING("isSingleValued", "TRUE"); - break; - - case SCHEMA_EQUALITY: - /* TODO */ - break; - - case SCHEMA_ORDERING: - /* TODO */ - break; - - case SCHEMA_SUBSTR: - /* TODO */ - break; - - case SCHEMA_SYNTAX: - { - const struct syntax_map *map = - find_syntax_map_by_standard_oid(token->value); - if (!map) { - break; - } - MSG_ADD_STRING("attributeSyntax", map->AD_OID); - break; - } - case SCHEMA_DESC: - MSG_ADD_STRING("description", token->value); - break; - - default: - fprintf(stderr, "Unknown Definition: %s\n", token->value); - } - } - - talloc_steal(mem_ctx, msg); - talloc_free(ctx); - return msg; - -failed: - talloc_free(ctx); - return NULL; -} - -static struct schema_conv process_file(FILE *in, FILE *out) -{ - TALLOC_CTX *ctx; - struct schema_conv ret; - char *entry; - int c, t, line; - struct ldb_ldif ldif; - - ldif.changetype = LDB_CHANGETYPE_NONE; - - ctx = talloc_new(NULL); - - ret.count = 0; - ret.failures = 0; - line = 0; - - while ((c = fgetc(in)) != EOF) { - line++; - /* fprintf(stderr, "Parsing line %d\n", line); */ - if (c == '#') { - do { - c = fgetc(in); - } while (c != EOF && c != '\n'); - continue; - } - if (c == '\n') { - continue; - } - - t = 0; - entry = talloc_array(ctx, char, 1024); - if (entry == NULL) exit(-1); - - do { - if (c == '\n') { - entry[t] = '\0'; - if (check_braces(entry) == 0) { - ret.count++; - ldif.msg = process_entry(ctx, entry); - if (ldif.msg == NULL) { - ret.failures++; - fprintf(stderr, "No valid msg from entry \n[%s]\n at line %d\n", entry, line); - break; - } - ldb_ldif_write_file(ldb_ctx, out, &ldif); - break; - } - line++; - } else { - entry[t] = c; - t++; - } - if ((t % 1023) == 0) { - entry = talloc_realloc(ctx, entry, char, t + 1024); - if (entry == NULL) exit(-1); - } - } while ((c = fgetc(in)) != EOF); - - if (c != '\n') { - entry[t] = '\0'; - if (check_braces(entry) == 0) { - ret.count++; - ldif.msg = process_entry(ctx, entry); - if (ldif.msg == NULL) { - ret.failures++; - fprintf(stderr, "No valid msg from entry \n[%s]\n at line %d\n", entry, line); - break; - } - ldb_ldif_write_file(ldb_ctx, out, &ldif); - } else { - fprintf(stderr, "malformed entry on line %d\n", line); - ret.failures++; - } - } - - if (c == EOF) break; - } - - return ret; -} - -static void usage(void) -{ - printf("Usage: oLschema2ldif -H NONE <options>\n"); - printf("\nConvert OpenLDAP schema to AD-like LDIF format\n\n"); - printf("Options:\n"); - printf(" -I inputfile inputfile of OpenLDAP style schema otherwise STDIN\n"); - printf(" -O outputfile outputfile otherwise STDOUT\n"); - printf(" -o options pass options like modules to activate\n"); - printf(" e.g: -o modules:timestamps\n"); - printf("\n"); - printf("Converts records from an openLdap formatted schema to an ldif schema\n\n"); - exit(1); -} - - int main(int argc, const char **argv) -{ - TALLOC_CTX *ctx; - struct schema_conv ret; - struct ldb_cmdline *options; - FILE *in = stdin; - FILE *out = stdout; - ldb_global_init(); - - ctx = talloc_new(NULL); - ldb_ctx = ldb_init(ctx); - - setenv("LDB_URL", "NONE", 1); - options = ldb_cmdline_process(ldb_ctx, argc, argv, usage); - - if (options->basedn == NULL) { - perror("Base DN not specified"); - exit(1); - } else { - basedn = ldb_dn_explode(ctx, options->basedn); - if (basedn == NULL) { - perror("Malformed Base DN"); - exit(1); - } - } - - if (options->input) { - in = fopen(options->input, "r"); - if (!in) { - perror(options->input); - exit(1); - } - } - if (options->output) { - out = fopen(options->output, "w"); - if (!out) { - perror(options->output); - exit(1); - } - } - - ret = process_file(in, out); - - fclose(in); - fclose(out); - - printf("Converted %d records with %d failures\n", ret.count, ret.failures); - - return 0; -} diff --git a/source/lib/ldb/web/index.html b/source/lib/ldb/web/index.html deleted file mode 100644 index 2715a0d8bd2..00000000000 --- a/source/lib/ldb/web/index.html +++ /dev/null @@ -1,89 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"> -<HTML> -<HEAD> -<TITLE>ldb</TITLE> -</HEAD> -<BODY BGCOLOR="#ffffff" TEXT="#000000" VLINK="#292555" LINK="#292555" ALINK="#cc0033"> - -<h1>ldb</h1> - -ldb is a LDAP-like embedded database. It is not at all LDAP standards -compliant, so if you want a standards compliant database then please -see the excellent <a href="http://www.openldap.org/">OpenLDAP</a> -project.<p> - -What ldb does is provide a fast database with an LDAP-like API -designed to be used within an application. In some ways it can be seen -as a intermediate solution between key-value pair databases and a real -LDAP database.<p> - -ldb is the database engine used in Samba4. - -<h2>Features</h2> - -The main features that separate ldb from other solutions are: - -<ul> -<li>Safe multi-reader, multi-writer, using byte range locking -<li>LDAP-like API -<li>fast operation -<li>choice of local tdb or remote LDAP backends -<li>integration with <a href="http://talloc.samba.org">talloc</a> -<li>schema-less operation, for trivial setup -<li>modules for extensions (such as schema support) -<li>easy setup of indexes and attribute properties -<li>ldbedit tool for database editing (reminiscent of 'vipw') -<li>ldif for import/export -</ul> - -<h2>Documentation</h2> - -Currently ldb is completely lacking in programmer or user -documentation. This is your opportunity to make a contribution! Start -with the public functions declared in <a -href="http://samba.org/ftp/unpacked/samba4/source/lib/ldb/include/ldb.h">ldb.h</a> -and the example code in the <a -href="http://samba.org/ftp/unpacked/samba4/source/lib/ldb/tools/">tools -directory</a>. Documentation in the same docbook format used by Samba -would be preferred. - -<h2>Discussion and bug reports</h2> - -ldb does not currently have its own mailing list or bug tracking -system. For now, please use the <a -href="https://lists.samba.org/mailman/listinfo/samba-technical">samba-technical</a> -mailing list, and the <a href="http://bugzilla.samba.org/">Samba -bugzilla</a> bug tracking system. - -<h2>Download</h2> - -You can download the latest release either via rsync or anonymous -svn. To fetch via svn use the following commands: - -<pre> - svn co svn://svnanon.samba.org/samba/branches/SAMBA_4_0/source/lib/ldb ldb - svn co svn://svnanon.samba.org/samba/branches/SAMBA_4_0/source/lib/tdb tdb - svn co svn://svnanon.samba.org/samba/branches/SAMBA_4_0/source/lib/talloc talloc - svn co svn://svnanon.samba.org/samba/branches/SAMBA_4_0/source/lib/replace libreplace -</pre> - -To fetch via rsync use these commands: - -<pre> - rsync -Pavz samba.org::ftp/unpacked/ldb . - rsync -Pavz samba.org::ftp/unpacked/tdb . - rsync -Pavz samba.org::ftp/unpacked/talloc . - rsync -Pavz samba.org::ftp/unpacked/libreplace . -</pre> - -and build in ldb. It will find the other libraries in the directory -above automatically. - -<hr> -<tiny> -<a href="http://samba.org/~tridge/">Andrew Tridgell</a><br> -ldb AT tridgell.net -</tiny> - -</BODY> -</HTML> diff --git a/source/lib/messages.c b/source/lib/messages.c index 54657d8d563..88b5f3ab936 100644 --- a/source/lib/messages.c +++ b/source/lib/messages.c @@ -4,7 +4,6 @@ Copyright (C) Andrew Tridgell 2000 Copyright (C) 2001 by Martin Pool Copyright (C) 2002 by Jeremy Allison - Copyright (C) 2007 by Volker Lendecke 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 @@ -47,33 +46,506 @@ */ #include "includes.h" -#include "librpc/gen_ndr/messaging.h" -#include "librpc/gen_ndr/ndr_messaging.h" -struct messaging_callback { - struct messaging_callback *prev, *next; - uint32 msg_type; - void (*fn)(struct messaging_context *msg, void *private_data, - uint32_t msg_type, - struct server_id server_id, DATA_BLOB *data); - void *private_data; +/* the locking database handle */ +static TDB_CONTEXT *tdb; +static int received_signal; + +/* change the message version with any incompatible changes in the protocol */ +#define MESSAGE_VERSION 1 + +struct message_rec { + int msg_version; + int msg_type; + struct process_id dest; + struct process_id src; + size_t len; }; +/* we have a linked list of dispatch handlers */ +static struct dispatch_fns { + struct dispatch_fns *next, *prev; + int msg_type; + void (*fn)(int msg_type, struct process_id pid, void *buf, size_t len, + void *private_data); + void *private_data; +} *dispatch_fns; + +/**************************************************************************** + Free global objects. +****************************************************************************/ + +void gfree_messages(void) +{ + struct dispatch_fns *dfn, *next; + + /* delete the dispatch_fns list */ + dfn = dispatch_fns; + while( dfn ) { + next = dfn->next; + DLIST_REMOVE(dispatch_fns, dfn); + SAFE_FREE(dfn); + dfn = next; + } +} + +/**************************************************************************** + Notifications come in as signals. +****************************************************************************/ + +static void sig_usr1(void) +{ + received_signal = 1; + sys_select_signal(SIGUSR1); +} + /**************************************************************************** A useful function for testing the message system. ****************************************************************************/ -static void ping_message(struct messaging_context *msg_ctx, - void *private_data, - uint32_t msg_type, - struct server_id src, - DATA_BLOB *data) +static void ping_message(int msg_type, struct process_id src, + void *buf, size_t len, void *private_data) { - const char *msg = data->data ? (const char *)data->data : "none"; + const char *msg = buf ? (const char *)buf : "none"; DEBUG(1,("INFO: Received PING message from PID %s [%s]\n", procid_str_static(&src), msg)); - messaging_send(msg_ctx, src, MSG_PONG, data); + message_send_pid(src, MSG_PONG, buf, len, True); +} + +/**************************************************************************** + Initialise the messaging functions. +****************************************************************************/ + +BOOL message_init(void) +{ + sec_init(); + + if (tdb) + return True; + + tdb = tdb_open_log(lock_path("messages.tdb"), + 0, TDB_CLEAR_IF_FIRST|TDB_DEFAULT, + O_RDWR|O_CREAT,0600); + + if (!tdb) { + DEBUG(0,("ERROR: Failed to initialise messages database\n")); + return False; + } + + /* Activate the per-hashchain freelist */ + tdb_set_max_dead(tdb, 5); + + CatchSignal(SIGUSR1, SIGNAL_CAST sig_usr1); + + message_register(MSG_PING, ping_message, NULL); + + /* Register some debugging related messages */ + + register_msg_pool_usage(); + register_dmalloc_msgs(); + + return True; +} + +/******************************************************************* + Form a static tdb key from a pid. +******************************************************************/ + +static TDB_DATA message_key_pid(struct process_id pid) +{ + static char key[20]; + TDB_DATA kbuf; + + slprintf(key, sizeof(key)-1, "PID/%s", procid_str_static(&pid)); + + kbuf.dptr = (char *)key; + kbuf.dsize = strlen(key)+1; + return kbuf; +} + +/**************************************************************************** + Notify a process that it has a message. If the process doesn't exist + then delete its record in the database. +****************************************************************************/ + +static NTSTATUS message_notify(struct process_id procid) +{ + pid_t pid = procid.pid; + int ret; + uid_t euid = geteuid(); + + /* + * Doing kill with a non-positive pid causes messages to be + * sent to places we don't want. + */ + + SMB_ASSERT(pid > 0); + + if (euid != 0) { + /* If we're not root become so to send the message. */ + save_re_uid(); + set_effective_uid(0); + } + + ret = kill(pid, SIGUSR1); + + if (euid != 0) { + /* Go back to who we were. */ + int saved_errno = errno; + restore_re_uid_fromroot(); + errno = saved_errno; + } + + if (ret == -1) { + if (errno == ESRCH) { + DEBUG(2,("pid %d doesn't exist - deleting messages record\n", + (int)pid)); + tdb_delete(tdb, message_key_pid(procid)); + + /* + * INVALID_HANDLE is the closest I can think of -- vl + */ + return NT_STATUS_INVALID_HANDLE; + } + + DEBUG(2,("message to process %d failed - %s\n", (int)pid, + strerror(errno))); + + /* + * No call to map_nt_error_from_unix -- don't want to link in + * errormap.o into lots of utils. + */ + + if (errno == EINVAL) return NT_STATUS_INVALID_PARAMETER; + if (errno == EPERM) return NT_STATUS_ACCESS_DENIED; + return NT_STATUS_UNSUCCESSFUL; + } + + return NT_STATUS_OK; +} + +/**************************************************************************** + Send a message to a particular pid. +****************************************************************************/ + +static NTSTATUS message_send_pid_internal(struct process_id pid, int msg_type, + const void *buf, size_t len, + BOOL duplicates_allowed, + unsigned int timeout) +{ + TDB_DATA kbuf; + TDB_DATA dbuf; + TDB_DATA old_dbuf; + struct message_rec rec; + char *ptr; + struct message_rec prec; + + /* NULL pointer means implicit length zero. */ + if (!buf) { + SMB_ASSERT(len == 0); + } + + /* + * Doing kill with a non-positive pid causes messages to be + * sent to places we don't want. + */ + + SMB_ASSERT(procid_to_pid(&pid) > 0); + + rec.msg_version = MESSAGE_VERSION; + rec.msg_type = msg_type; + rec.dest = pid; + rec.src = procid_self(); + rec.len = buf ? len : 0; + + kbuf = message_key_pid(pid); + + dbuf.dptr = (char *)SMB_MALLOC(len + sizeof(rec)); + if (!dbuf.dptr) { + return NT_STATUS_NO_MEMORY; + } + + memcpy(dbuf.dptr, &rec, sizeof(rec)); + if (len > 0 && buf) + memcpy((void *)((char*)dbuf.dptr+sizeof(rec)), buf, len); + + dbuf.dsize = len + sizeof(rec); + + if (duplicates_allowed) { + + /* If duplicates are allowed we can just append the message and return. */ + + /* lock the record for the destination */ + if (timeout) { + if (tdb_chainlock_with_timeout(tdb, kbuf, timeout) == -1) { + DEBUG(0,("message_send_pid_internal: failed to get " + "chainlock with timeout %ul.\n", timeout)); + SAFE_FREE(dbuf.dptr); + return NT_STATUS_IO_TIMEOUT; + } + } else { + if (tdb_chainlock(tdb, kbuf) == -1) { + DEBUG(0,("message_send_pid_internal: failed to get " + "chainlock.\n")); + SAFE_FREE(dbuf.dptr); + return NT_STATUS_LOCK_NOT_GRANTED; + } + } + tdb_append(tdb, kbuf, dbuf); + tdb_chainunlock(tdb, kbuf); + + SAFE_FREE(dbuf.dptr); + errno = 0; /* paranoia */ + return message_notify(pid); + } + + /* lock the record for the destination */ + if (timeout) { + if (tdb_chainlock_with_timeout(tdb, kbuf, timeout) == -1) { + DEBUG(0,("message_send_pid_internal: failed to get chainlock " + "with timeout %ul.\n", timeout)); + SAFE_FREE(dbuf.dptr); + return NT_STATUS_IO_TIMEOUT; + } + } else { + if (tdb_chainlock(tdb, kbuf) == -1) { + DEBUG(0,("message_send_pid_internal: failed to get " + "chainlock.\n")); + SAFE_FREE(dbuf.dptr); + return NT_STATUS_LOCK_NOT_GRANTED; + } + } + + old_dbuf = tdb_fetch(tdb, kbuf); + + if (!old_dbuf.dptr) { + /* its a new record */ + + tdb_store(tdb, kbuf, dbuf, TDB_REPLACE); + tdb_chainunlock(tdb, kbuf); + + SAFE_FREE(dbuf.dptr); + errno = 0; /* paranoia */ + return message_notify(pid); + } + + /* Not a new record. Check for duplicates. */ + + for(ptr = (char *)old_dbuf.dptr; ptr < old_dbuf.dptr + old_dbuf.dsize; ) { + /* + * First check if the message header matches, then, if it's a non-zero + * sized message, check if the data matches. If so it's a duplicate and + * we can discard it. JRA. + */ + + if (!memcmp(ptr, &rec, sizeof(rec))) { + if (!len || (len && !memcmp( ptr + sizeof(rec), buf, len))) { + tdb_chainunlock(tdb, kbuf); + DEBUG(10,("message_send_pid_internal: discarding " + "duplicate message.\n")); + SAFE_FREE(dbuf.dptr); + SAFE_FREE(old_dbuf.dptr); + return NT_STATUS_OK; + } + } + memcpy(&prec, ptr, sizeof(prec)); + ptr += sizeof(rec) + prec.len; + } + + /* we're adding to an existing entry */ + + tdb_append(tdb, kbuf, dbuf); + tdb_chainunlock(tdb, kbuf); + + SAFE_FREE(old_dbuf.dptr); + SAFE_FREE(dbuf.dptr); + + errno = 0; /* paranoia */ + return message_notify(pid); +} + +/**************************************************************************** + Send a message to a particular pid - no timeout. +****************************************************************************/ + +NTSTATUS message_send_pid(struct process_id pid, int msg_type, const void *buf, + size_t len, BOOL duplicates_allowed) +{ + return message_send_pid_internal(pid, msg_type, buf, len, + duplicates_allowed, 0); +} + +/**************************************************************************** + Send a message to a particular pid, with timeout in seconds. +****************************************************************************/ + +NTSTATUS message_send_pid_with_timeout(struct process_id pid, int msg_type, + const void *buf, size_t len, + BOOL duplicates_allowed, unsigned int timeout) +{ + return message_send_pid_internal(pid, msg_type, buf, len, duplicates_allowed, + timeout); +} + +/**************************************************************************** + Count the messages pending for a particular pid. Expensive.... +****************************************************************************/ + +unsigned int messages_pending_for_pid(struct process_id pid) +{ + TDB_DATA kbuf; + TDB_DATA dbuf; + char *buf; + unsigned int message_count = 0; + + kbuf = message_key_pid(pid); + + dbuf = tdb_fetch(tdb, kbuf); + if (dbuf.dptr == NULL || dbuf.dsize == 0) { + SAFE_FREE(dbuf.dptr); + return 0; + } + + for (buf = dbuf.dptr; dbuf.dsize > sizeof(struct message_rec);) { + struct message_rec rec; + memcpy(&rec, buf, sizeof(rec)); + buf += (sizeof(rec) + rec.len); + dbuf.dsize -= (sizeof(rec) + rec.len); + message_count++; + } + + SAFE_FREE(dbuf.dptr); + return message_count; +} + +/**************************************************************************** + Retrieve all messages for the current process. +****************************************************************************/ + +static BOOL retrieve_all_messages(char **msgs_buf, size_t *total_len) +{ + TDB_DATA kbuf; + TDB_DATA dbuf; + TDB_DATA null_dbuf; + + ZERO_STRUCT(null_dbuf); + + *msgs_buf = NULL; + *total_len = 0; + + kbuf = message_key_pid(pid_to_procid(sys_getpid())); + + if (tdb_chainlock(tdb, kbuf) == -1) + return False; + + dbuf = tdb_fetch(tdb, kbuf); + /* + * Replace with an empty record to keep the allocated + * space in the tdb. + */ + tdb_store(tdb, kbuf, null_dbuf, TDB_REPLACE); + tdb_chainunlock(tdb, kbuf); + + if (dbuf.dptr == NULL || dbuf.dsize == 0) { + SAFE_FREE(dbuf.dptr); + return False; + } + + *msgs_buf = dbuf.dptr; + *total_len = dbuf.dsize; + + return True; +} + +/**************************************************************************** + Parse out the next message for the current process. +****************************************************************************/ + +static BOOL message_recv(char *msgs_buf, size_t total_len, int *msg_type, + struct process_id *src, char **buf, size_t *len) +{ + struct message_rec rec; + char *ret_buf = *buf; + + *buf = NULL; + *len = 0; + + if (total_len - (ret_buf - msgs_buf) < sizeof(rec)) + return False; + + memcpy(&rec, ret_buf, sizeof(rec)); + ret_buf += sizeof(rec); + + if (rec.msg_version != MESSAGE_VERSION) { + DEBUG(0,("message version %d received (expected %d)\n", rec.msg_version, MESSAGE_VERSION)); + return False; + } + + if (rec.len > 0) { + if (total_len - (ret_buf - msgs_buf) < rec.len) + return False; + } + + *len = rec.len; + *msg_type = rec.msg_type; + *src = rec.src; + *buf = ret_buf; + + return True; +} + +/**************************************************************************** + Receive and dispatch any messages pending for this process. + JRA changed Dec 13 2006. Only one message handler now permitted per type. + *NOTE*: Dispatch functions must be able to cope with incoming + messages on an *odd* byte boundary. +****************************************************************************/ + +void message_dispatch(void) +{ + int msg_type; + struct process_id src; + char *buf; + char *msgs_buf; + size_t len, total_len; + int n_handled; + + if (!received_signal) + return; + + DEBUG(10,("message_dispatch: received_signal = %d\n", received_signal)); + + received_signal = 0; + + if (!retrieve_all_messages(&msgs_buf, &total_len)) + return; + + for (buf = msgs_buf; message_recv(msgs_buf, total_len, &msg_type, &src, &buf, &len); buf += len) { + struct dispatch_fns *dfn; + + DEBUG(10,("message_dispatch: received msg_type=%d " + "src_pid=%u\n", msg_type, + (unsigned int) procid_to_pid(&src))); + + n_handled = 0; + for (dfn = dispatch_fns; dfn; dfn = dfn->next) { + if (dfn->msg_type == msg_type) { + DEBUG(10,("message_dispatch: processing message of type %d.\n", msg_type)); + dfn->fn(msg_type, src, + len ? (void *)buf : NULL, len, + dfn->private_data); + n_handled++; + break; + } + } + if (!n_handled) { + DEBUG(5,("message_dispatch: warning: no handler registed for " + "msg_type %d in pid %u\n", + msg_type, (unsigned int)sys_getpid())); + } + } + SAFE_FREE(msgs_buf); } /**************************************************************************** @@ -83,12 +555,63 @@ static void ping_message(struct messaging_context *msg_ctx, messages on an *odd* byte boundary. ****************************************************************************/ +void message_register(int msg_type, + void (*fn)(int msg_type, struct process_id pid, + void *buf, size_t len, + void *private_data), + void *private_data) +{ + struct dispatch_fns *dfn; + + for (dfn = dispatch_fns; dfn; dfn = dfn->next) { + if (dfn->msg_type == msg_type) { + dfn->fn = fn; + return; + } + } + + dfn = SMB_MALLOC_P(struct dispatch_fns); + + if (dfn != NULL) { + + ZERO_STRUCTPN(dfn); + + dfn->msg_type = msg_type; + dfn->fn = fn; + dfn->private_data = private_data; + + DLIST_ADD(dispatch_fns, dfn); + } + else { + + DEBUG(0,("message_register: Not enough memory. malloc failed!\n")); + } +} + +/**************************************************************************** + De-register the function for a particular message type. +****************************************************************************/ + +void message_deregister(int msg_type) +{ + struct dispatch_fns *dfn, *next; + + for (dfn = dispatch_fns; dfn; dfn = next) { + next = dfn->next; + if (dfn->msg_type == msg_type) { + DLIST_REMOVE(dispatch_fns, dfn); + SAFE_FREE(dfn); + return; + } + } +} + struct msg_all { - struct messaging_context *msg_ctx; int msg_type; uint32 msg_flag; const void *buf; size_t len; + BOOL duplicates; int n_sent; }; @@ -96,38 +619,39 @@ struct msg_all { Send one of the messages for the broadcast. ****************************************************************************/ -static int traverse_fn(struct db_record *rec, - const struct connections_key *ckey, - const struct connections_data *crec, - void *state) +static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state) { + struct connections_data crec; struct msg_all *msg_all = (struct msg_all *)state; NTSTATUS status; - if (crec->cnum != -1) + if (dbuf.dsize != sizeof(crec)) + return 0; + + memcpy(&crec, dbuf.dptr, sizeof(crec)); + + if (crec.cnum != -1) return 0; /* Don't send if the receiver hasn't registered an interest. */ - if(!(crec->bcast_msg_flags & msg_all->msg_flag)) + if(!(crec.bcast_msg_flags & msg_all->msg_flag)) return 0; /* If the msg send fails because the pid was not found (i.e. smbd died), * the msg has already been deleted from the messages.tdb.*/ - status = messaging_send_buf(msg_all->msg_ctx, - crec->pid, msg_all->msg_type, - (uint8 *)msg_all->buf, msg_all->len); + status = message_send_pid(crec.pid, msg_all->msg_type, + msg_all->buf, msg_all->len, + msg_all->duplicates); if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) { /* If the pid was not found delete the entry from connections.tdb */ DEBUG(2,("pid %s doesn't exist - deleting connections %d [%s]\n", - procid_str_static(&crec->pid), crec->cnum, - crec->servicename)); - - rec->delete_rec(rec); + procid_str_static(&crec.pid), crec.cnum, crec.servicename)); + tdb_delete(the_tdb, kbuf); } msg_all->n_sent++; return 0; @@ -145,9 +669,9 @@ static int traverse_fn(struct db_record *rec, * * @retval True for success. **/ -BOOL message_send_all(struct messaging_context *msg_ctx, - int msg_type, +BOOL message_send_all(TDB_CONTEXT *conn_tdb, int msg_type, const void *buf, size_t len, + BOOL duplicates_allowed, int *n_sent) { struct msg_all msg_all; @@ -168,18 +692,61 @@ BOOL message_send_all(struct messaging_context *msg_ctx, msg_all.buf = buf; msg_all.len = len; + msg_all.duplicates = duplicates_allowed; msg_all.n_sent = 0; - msg_all.msg_ctx = msg_ctx; - connections_forall(traverse_fn, &msg_all); + tdb_traverse(conn_tdb, traverse_fn, &msg_all); if (n_sent) *n_sent = msg_all.n_sent; return True; } -struct event_context *messaging_event_context(struct messaging_context *msg_ctx) +/* + * Block and unblock receiving of messages. Allows removal of race conditions + * when doing a fork and changing message disposition. + */ + +void message_block(void) { - return msg_ctx->event_ctx; + BlockSignals(True, SIGUSR1); +} + +void message_unblock(void) +{ + BlockSignals(False, SIGUSR1); +} + +/* + * Samba4 API wrapper around the Samba3 implementation. Yes, I know, we could + * import the whole Samba4 thing, but I want notify.c from Samba4 in first. + */ + +struct messaging_callback { + struct messaging_callback *prev, *next; + uint32 msg_type; + void (*fn)(struct messaging_context *msg, void *private_data, + uint32_t msg_type, + struct server_id server_id, DATA_BLOB *data); + void *private_data; +}; + +struct messaging_context { + struct server_id id; + struct messaging_callback *callbacks; +}; + +static int messaging_context_destructor(struct messaging_context *ctx) +{ + struct messaging_callback *cb; + + for (cb = ctx->callbacks; cb; cb = cb->next) { + /* + * We unconditionally remove all instances of our callback + * from the tdb basis. + */ + message_deregister(cb->msg_type); + } + return 0; } struct messaging_context *messaging_init(TALLOC_CTX *mem_ctx, @@ -187,82 +754,47 @@ struct messaging_context *messaging_init(TALLOC_CTX *mem_ctx, struct event_context *ev) { struct messaging_context *ctx; - NTSTATUS status; if (!(ctx = TALLOC_ZERO_P(mem_ctx, struct messaging_context))) { return NULL; } ctx->id = server_id; - ctx->event_ctx = ev; - - status = messaging_tdb_init(ctx, ctx, &ctx->local); - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("messaging_tdb_init failed: %s\n", - nt_errstr(status))); - TALLOC_FREE(ctx); - return NULL; - } - -#ifdef CLUSTER_SUPPORT - if (lp_clustering()) { - status = messaging_ctdbd_init(ctx, ctx, &ctx->remote); - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("messaging_ctdb_init failed: %s\n", - nt_errstr(status))); - TALLOC_FREE(ctx); - return NULL; - } - } -#endif - - messaging_register(ctx, NULL, MSG_PING, ping_message); - - /* Register some debugging related messages */ - - register_msg_pool_usage(ctx); - register_dmalloc_msgs(ctx); - debug_register_msgs(ctx); - + talloc_set_destructor(ctx, messaging_context_destructor); return ctx; } -/* - * re-init after a fork - */ -NTSTATUS messaging_reinit(struct messaging_context *msg_ctx) +static void messaging_callback(int msg_type, struct process_id pid, + void *buf, size_t len, void *private_data) { -#ifdef CLUSTER_SUPPORT + struct messaging_context *ctx = talloc_get_type_abort( + private_data, struct messaging_context); + struct messaging_callback *cb, *next; - TALLOC_FREE(msg_ctx->remote); + for (cb = ctx->callbacks; cb; cb = next) { + /* + * Allow a callback to remove itself + */ + next = cb->next; - if (lp_clustering()) { - NTSTATUS status; + if (msg_type == cb->msg_type) { + DATA_BLOB blob; + struct server_id id; - status = messaging_ctdbd_init(msg_ctx, msg_ctx, - &msg_ctx->remote); + blob.data = (uint8 *)buf; + blob.length = len; + id.id = pid; - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("messaging_ctdb_init failed: %s\n", - nt_errstr(status))); - return status; + cb->fn(ctx, cb->private_data, msg_type, id, &blob); } } - -#endif - - return NT_STATUS_OK; } - /* * Register a dispatch function for a particular message type. Allow multiple * registrants */ -NTSTATUS messaging_register(struct messaging_context *msg_ctx, - void *private_data, +NTSTATUS messaging_register(struct messaging_context *ctx, void *private_data, uint32_t msg_type, void (*fn)(struct messaging_context *msg, void *private_data, @@ -272,19 +804,7 @@ NTSTATUS messaging_register(struct messaging_context *msg_ctx, { struct messaging_callback *cb; - /* - * Only one callback per type - */ - - for (cb = msg_ctx->callbacks; cb != NULL; cb = cb->next) { - if (cb->msg_type == msg_type) { - cb->fn = fn; - cb->private_data = private_data; - return NT_STATUS_OK; - } - } - - if (!(cb = talloc(msg_ctx, struct messaging_callback))) { + if (!(cb = talloc(ctx, struct messaging_callback))) { return NT_STATUS_NO_MEMORY; } @@ -292,7 +812,8 @@ NTSTATUS messaging_register(struct messaging_context *msg_ctx, cb->fn = fn; cb->private_data = private_data; - DLIST_ADD(msg_ctx->callbacks, cb); + DLIST_ADD(ctx->callbacks, cb); + message_register(msg_type, messaging_callback, ctx); return NT_STATUS_OK; } @@ -317,39 +838,12 @@ void messaging_deregister(struct messaging_context *ctx, uint32_t msg_type, /* Send a message to a particular server */ -NTSTATUS messaging_send(struct messaging_context *msg_ctx, - struct server_id server, uint32_t msg_type, - const DATA_BLOB *data) +NTSTATUS messaging_send(struct messaging_context *msg, + struct server_id server, + uint32_t msg_type, DATA_BLOB *data) { - return msg_ctx->local->send_fn(msg_ctx, server, msg_type, data, - msg_ctx->local); -} - -NTSTATUS messaging_send_buf(struct messaging_context *msg_ctx, - struct server_id server, uint32_t msg_type, - const uint8 *buf, size_t len) -{ - DATA_BLOB blob = data_blob_const(buf, len); - return messaging_send(msg_ctx, server, msg_type, &blob); -} - -/* - Dispatch one messsaging_rec -*/ -void messaging_dispatch_rec(struct messaging_context *msg_ctx, - struct messaging_rec *rec) -{ - struct messaging_callback *cb, *next; - - for (cb = msg_ctx->callbacks; cb != NULL; cb = next) { - next = cb->next; - if (cb->msg_type == rec->msg_type) { - cb->fn(msg_ctx, cb->private_data, rec->msg_type, - rec->src, &rec->buf); - return; - } - } - return; + return message_send_pid_internal(server.id, msg_type, data->data, + data->length, True, 0); } /** @} **/ diff --git a/source/lib/messages_ctdbd.c b/source/lib/messages_ctdbd.c deleted file mode 100644 index 4ac9ea99043..00000000000 --- a/source/lib/messages_ctdbd.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Samba internal messaging functions - Copyright (C) 2007 by Volker Lendecke - - 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. -*/ - -#include "includes.h" - -#ifdef CLUSTER_SUPPORT - -#include "librpc/gen_ndr/messaging.h" - -struct messaging_ctdbd_context { - struct ctdbd_connection *conn; -}; - -/* - * This is a Samba3 hack/optimization. Routines like process_exists need to - * talk to ctdbd, and they don't get handed a messaging context. - */ -struct ctdbd_connection *global_ctdbd_connection; - -struct ctdbd_connection *messaging_ctdbd_connection(void) -{ - return global_ctdbd_connection; -} - -static NTSTATUS messaging_ctdb_send(struct messaging_context *msg_ctx, - struct server_id pid, int msg_type, - const DATA_BLOB *data, - struct messaging_backend *backend) -{ - struct messaging_ctdbd_context *ctx = talloc_get_type_abort( - backend->private_data, struct messaging_ctdbd_context); - - struct messaging_rec msg; - - msg.msg_version = MESSAGE_VERSION; - msg.msg_type = msg_type; - msg.dest = pid; - msg.src = procid_self(); - msg.buf = *data; - - return ctdbd_messaging_send(ctx->conn, pid.vnn, pid.pid, &msg); -} - -static int messaging_ctdbd_destructor(struct messaging_ctdbd_context *ctx) -{ - /* - * The global connection just went away - */ - global_ctdbd_connection = NULL; - return 0; -} - -NTSTATUS messaging_ctdbd_init(struct messaging_context *msg_ctx, - TALLOC_CTX *mem_ctx, - struct messaging_backend **presult) -{ - struct messaging_backend *result; - struct messaging_ctdbd_context *ctx; - NTSTATUS status; - - if (!(result = TALLOC_P(mem_ctx, struct messaging_backend))) { - DEBUG(0, ("talloc failed\n")); - return NT_STATUS_NO_MEMORY; - } - - if (!(ctx = TALLOC_P(result, struct messaging_ctdbd_context))) { - DEBUG(0, ("talloc failed\n")); - TALLOC_FREE(result); - return NT_STATUS_NO_MEMORY; - } - - status = ctdbd_messaging_connection(ctx, &ctx->conn); - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(10, ("ctdbd_init_connection failed: %s\n", - nt_errstr(status))); - TALLOC_FREE(result); - return status; - } - - global_ctdbd_connection = ctx->conn; - talloc_set_destructor(ctx, messaging_ctdbd_destructor); - - set_my_vnn(ctdbd_vnn(ctx->conn)); - - result->send_fn = messaging_ctdb_send; - result->private_data = (void *)ctx; - - *presult = result; - return NT_STATUS_OK; -} - -#else - -NTSTATUS messaging_ctdbd_init(struct messaging_context *msg_ctx, - TALLOC_CTX *mem_ctx, - struct messaging_backend **presult) -{ - return NT_STATUS_NOT_IMPLEMENTED; -} - -#endif diff --git a/source/lib/messages_local.c b/source/lib/messages_local.c deleted file mode 100644 index 1f50e5bb6f2..00000000000 --- a/source/lib/messages_local.c +++ /dev/null @@ -1,432 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Samba internal messaging functions - Copyright (C) 2007 by Volker Lendecke - - 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. -*/ - -/** - @defgroup messages Internal messaging framework - @{ - @file messages.c - - @brief Module for internal messaging between Samba daemons. - - The idea is that if a part of Samba wants to do communication with - another Samba process then it will do a message_register() of a - dispatch function, and use message_send_pid() to send messages to - that process. - - The dispatch function is given the pid of the sender, and it can - use that to reply by message_send_pid(). See ping_message() for a - simple example. - - @caution Dispatch functions must be able to cope with incoming - messages on an *odd* byte boundary. - - This system doesn't have any inherent size limitations but is not - very efficient for large messages or when messages are sent in very - quick succession. - -*/ - -#include "includes.h" -#include "librpc/gen_ndr/messaging.h" -#include "librpc/gen_ndr/ndr_messaging.h" - -static int received_signal; - -static NTSTATUS messaging_tdb_send(struct messaging_context *msg_ctx, - struct server_id pid, int msg_type, - const DATA_BLOB *data, - struct messaging_backend *backend); - -/**************************************************************************** - Notifications come in as signals. -****************************************************************************/ - -static void sig_usr1(void) -{ - received_signal = 1; - sys_select_signal(SIGUSR1); -} - -static int messaging_tdb_destructor(struct messaging_backend *tdb_ctx) -{ - TDB_CONTEXT *tdb = (TDB_CONTEXT *)tdb_ctx->private_data; - tdb_close(tdb); - return 0; -} - -/**************************************************************************** - Initialise the messaging functions. -****************************************************************************/ - -NTSTATUS messaging_tdb_init(struct messaging_context *msg_ctx, - TALLOC_CTX *mem_ctx, - struct messaging_backend **presult) -{ - struct messaging_backend *result; - TDB_CONTEXT *tdb; - - if (!(result = TALLOC_P(mem_ctx, struct messaging_backend))) { - DEBUG(0, ("talloc failed\n")); - return NT_STATUS_NO_MEMORY; - } - - tdb = tdb_open_log(lock_path("messages.tdb"), - 0, TDB_CLEAR_IF_FIRST|TDB_DEFAULT, - O_RDWR|O_CREAT,0600); - - if (!tdb) { - NTSTATUS status = map_nt_error_from_unix(errno); - DEBUG(0, ("ERROR: Failed to initialise messages database: " - "%s\n", strerror(errno))); - TALLOC_FREE(result); - return status; - } - - sec_init(); - - /* Activate the per-hashchain freelist */ - tdb_set_max_dead(tdb, 5); - - CatchSignal(SIGUSR1, SIGNAL_CAST sig_usr1); - - result->private_data = (void *)tdb; - result->send_fn = messaging_tdb_send; - - talloc_set_destructor(result, messaging_tdb_destructor); - - *presult = result; - return NT_STATUS_OK; -} - -/******************************************************************* - Form a static tdb key from a pid. -******************************************************************/ - -static TDB_DATA message_key_pid(struct server_id pid) -{ - static char key[20]; - TDB_DATA kbuf; - - slprintf(key, sizeof(key)-1, "PID/%s", procid_str_static(&pid)); - - kbuf.dptr = (uint8 *)key; - kbuf.dsize = strlen(key)+1; - return kbuf; -} - -/* - Fetch the messaging array for a process - */ - -static NTSTATUS messaging_tdb_fetch(TDB_CONTEXT *msg_tdb, - TDB_DATA key, - TALLOC_CTX *mem_ctx, - struct messaging_array **presult) -{ - struct messaging_array *result; - TDB_DATA data; - DATA_BLOB blob; - NTSTATUS status; - - if (!(result = TALLOC_ZERO_P(mem_ctx, struct messaging_array))) { - return NT_STATUS_NO_MEMORY; - } - - data = tdb_fetch(msg_tdb, key); - - if (data.dptr == NULL) { - *presult = result; - return NT_STATUS_OK; - } - - blob = data_blob_const(data.dptr, data.dsize); - - status = ndr_pull_struct_blob( - &blob, result, result, - (ndr_pull_flags_fn_t)ndr_pull_messaging_array); - - SAFE_FREE(data.dptr); - - if (!NT_STATUS_IS_OK(status)) { - TALLOC_FREE(result); - return status; - } - - if (DEBUGLEVEL >= 10) { - DEBUG(10, ("messaging_tdb_fetch:\n")); - NDR_PRINT_DEBUG(messaging_array, result); - } - - *presult = result; - return NT_STATUS_OK; -} - -/* - Store a messaging array for a pid -*/ - -static NTSTATUS messaging_tdb_store(TDB_CONTEXT *msg_tdb, - TDB_DATA key, - struct messaging_array *array) -{ - TDB_DATA data; - DATA_BLOB blob; - NTSTATUS status; - TALLOC_CTX *mem_ctx; - int ret; - - if (array->num_messages == 0) { - tdb_delete(msg_tdb, key); - return NT_STATUS_OK; - } - - if (!(mem_ctx = talloc_new(array))) { - return NT_STATUS_NO_MEMORY; - } - - status = ndr_push_struct_blob( - &blob, mem_ctx, array, - (ndr_push_flags_fn_t)ndr_push_messaging_array); - - if (!NT_STATUS_IS_OK(status)) { - talloc_free(mem_ctx); - return status; - } - - if (DEBUGLEVEL >= 10) { - DEBUG(10, ("messaging_tdb_store:\n")); - NDR_PRINT_DEBUG(messaging_array, array); - } - - data.dptr = blob.data; - data.dsize = blob.length; - - ret = tdb_store(msg_tdb, key, data, TDB_REPLACE); - TALLOC_FREE(mem_ctx); - - return (ret == 0) ? NT_STATUS_OK : NT_STATUS_INTERNAL_DB_CORRUPTION; -} - -/**************************************************************************** - Notify a process that it has a message. If the process doesn't exist - then delete its record in the database. -****************************************************************************/ - -static NTSTATUS message_notify(struct server_id procid) -{ - pid_t pid = procid.pid; - int ret; - uid_t euid = geteuid(); - - /* - * Doing kill with a non-positive pid causes messages to be - * sent to places we don't want. - */ - - SMB_ASSERT(pid > 0); - - if (euid != 0) { - /* If we're not root become so to send the message. */ - save_re_uid(); - set_effective_uid(0); - } - - ret = kill(pid, SIGUSR1); - - if (euid != 0) { - /* Go back to who we were. */ - int saved_errno = errno; - restore_re_uid_fromroot(); - errno = saved_errno; - } - - if (ret == 0) { - return NT_STATUS_OK; - } - - /* - * Something has gone wrong - */ - - DEBUG(2,("message to process %d failed - %s\n", (int)pid, - strerror(errno))); - - /* - * No call to map_nt_error_from_unix -- don't want to link in - * errormap.o into lots of utils. - */ - - if (errno == ESRCH) return NT_STATUS_INVALID_HANDLE; - if (errno == EINVAL) return NT_STATUS_INVALID_PARAMETER; - if (errno == EPERM) return NT_STATUS_ACCESS_DENIED; - return NT_STATUS_UNSUCCESSFUL; -} - -/**************************************************************************** - Send a message to a particular pid. -****************************************************************************/ - -static NTSTATUS messaging_tdb_send(struct messaging_context *msg_ctx, - struct server_id pid, int msg_type, - const DATA_BLOB *data, - struct messaging_backend *backend) -{ - struct messaging_array *msg_array; - struct messaging_rec *rec; - TALLOC_CTX *mem_ctx; - NTSTATUS status; - TDB_DATA key = message_key_pid(pid); - TDB_CONTEXT *tdb = (TDB_CONTEXT *)backend->private_data; - - /* NULL pointer means implicit length zero. */ - if (!data->data) { - SMB_ASSERT(data->length == 0); - } - - /* - * Doing kill with a non-positive pid causes messages to be - * sent to places we don't want. - */ - - SMB_ASSERT(procid_to_pid(&pid) > 0); - - if (!(mem_ctx = talloc_init("message_send_pid"))) { - return NT_STATUS_NO_MEMORY; - } - - if (tdb_chainlock(tdb, key) == -1) { - TALLOC_FREE(mem_ctx); - return NT_STATUS_LOCK_NOT_GRANTED; - } - - status = messaging_tdb_fetch(tdb, key, mem_ctx, &msg_array); - - if (!NT_STATUS_IS_OK(status)) { - goto done; - } - - if ((msg_type & MSG_FLAG_LOWPRIORITY) - && (msg_array->num_messages > 1000)) { - DEBUG(5, ("Dropping message for PID %s\n", - procid_str_static(&pid))); - status = NT_STATUS_INSUFFICIENT_RESOURCES; - goto done; - } - - if (!(rec = TALLOC_REALLOC_ARRAY(mem_ctx, msg_array->messages, - struct messaging_rec, - msg_array->num_messages+1))) { - status = NT_STATUS_NO_MEMORY; - goto done; - } - - rec[msg_array->num_messages].msg_version = MESSAGE_VERSION; - rec[msg_array->num_messages].msg_type = msg_type & MSG_TYPE_MASK; - rec[msg_array->num_messages].dest = pid; - rec[msg_array->num_messages].src = procid_self(); - rec[msg_array->num_messages].buf = *data; - - msg_array->messages = rec; - msg_array->num_messages += 1; - - status = messaging_tdb_store(tdb, key, msg_array); - - if (!NT_STATUS_IS_OK(status)) { - goto done; - } - - status = message_notify(pid); - - if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) { - DEBUG(2, ("pid %s doesn't exist - deleting messages record\n", - procid_str_static(&pid))); - tdb_delete(tdb, message_key_pid(pid)); - } - - done: - tdb_chainunlock(tdb, key); - TALLOC_FREE(mem_ctx); - return status; -} - -/**************************************************************************** - Retrieve all messages for the current process. -****************************************************************************/ - -static NTSTATUS retrieve_all_messages(TDB_CONTEXT *msg_tdb, - TALLOC_CTX *mem_ctx, - struct messaging_array **presult) -{ - struct messaging_array *result; - TDB_DATA key = message_key_pid(procid_self()); - NTSTATUS status; - - if (tdb_chainlock(msg_tdb, key) == -1) { - return NT_STATUS_LOCK_NOT_GRANTED; - } - - status = messaging_tdb_fetch(msg_tdb, key, mem_ctx, &result); - - /* - * We delete the record here, tdb_set_max_dead keeps it around - */ - tdb_delete(msg_tdb, key); - tdb_chainunlock(msg_tdb, key); - - if (NT_STATUS_IS_OK(status)) { - *presult = result; - } - - return status; -} - -/**************************************************************************** - Receive and dispatch any messages pending for this process. - JRA changed Dec 13 2006. Only one message handler now permitted per type. - *NOTE*: Dispatch functions must be able to cope with incoming - messages on an *odd* byte boundary. -****************************************************************************/ - -void message_dispatch(struct messaging_context *msg_ctx) -{ - struct messaging_array *msg_array = NULL; - TDB_CONTEXT *tdb = (TDB_CONTEXT *)(msg_ctx->local->private_data); - uint32 i; - - if (!received_signal) - return; - - DEBUG(10, ("message_dispatch: received_signal = %d\n", - received_signal)); - - received_signal = 0; - - if (!NT_STATUS_IS_OK(retrieve_all_messages(tdb, NULL, &msg_array))) { - return; - } - - for (i=0; i<msg_array->num_messages; i++) { - messaging_dispatch_rec(msg_ctx, &msg_array->messages[i]); - } - - TALLOC_FREE(msg_array); -} - -/** @} **/ diff --git a/source/lib/module.c b/source/lib/module.c index 96a37ae6b55..092a68cd680 100644 --- a/source/lib/module.c +++ b/source/lib/module.c @@ -150,3 +150,88 @@ void init_modules(void) if(lp_preload_modules()) smb_load_modules(lp_preload_modules()); } + + +/*************************************************************************** + * This Function registers a idle event + * + * the registered funtions are run periodically + * and maybe shutdown idle connections (e.g. to an LDAP server) + ***************************************************************************/ +static smb_event_id_t smb_idle_event_id = 1; + +struct smb_idle_list_ent { + struct smb_idle_list_ent *prev,*next; + smb_event_id_t id; + smb_idle_event_fn *fn; + void *data; + time_t interval; + time_t lastrun; +}; + +static struct smb_idle_list_ent *smb_idle_event_list = NULL; + +smb_event_id_t smb_register_idle_event(smb_idle_event_fn *fn, void *data, time_t interval) +{ + struct smb_idle_list_ent *event; + + if (!fn) { + return SMB_EVENT_ID_INVALID; + } + + event = SMB_MALLOC_P(struct smb_idle_list_ent); + if (!event) { + DEBUG(0,("malloc() failed!\n")); + return SMB_EVENT_ID_INVALID; + } + event->fn = fn; + event->data = data; + event->interval = interval; + event->lastrun = 0; + event->id = smb_idle_event_id++; + + DLIST_ADD(smb_idle_event_list,event); + + return event->id; +} + +BOOL smb_unregister_idle_event(smb_event_id_t id) +{ + struct smb_idle_list_ent *event = smb_idle_event_list; + + while(event) { + if (event->id == id) { + DLIST_REMOVE(smb_idle_event_list,event); + SAFE_FREE(event); + return True; + } + event = event->next; + } + + return False; +} + +void smb_run_idle_events(time_t now) +{ + struct smb_idle_list_ent *event = smb_idle_event_list; + + while (event) { + struct smb_idle_list_ent *next = event->next; + time_t interval; + + if (event->interval <= 0) { + interval = SMB_IDLE_EVENT_DEFAULT_INTERVAL; + } else if (event->interval >= SMB_IDLE_EVENT_MIN_INTERVAL) { + interval = event->interval; + } else { + interval = SMB_IDLE_EVENT_MIN_INTERVAL; + } + if (now >(event->lastrun+interval)) { + event->lastrun = now; + event->fn(&event->data,&event->interval,now); + } + event = next; + } + + return; +} diff --git a/source/lib/packet.c b/source/lib/packet.c deleted file mode 100644 index 2473a771e0b..00000000000 --- a/source/lib/packet.c +++ /dev/null @@ -1,256 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Packet handling - Copyright (C) Volker Lendecke 2007 - - 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. -*/ - -#include "includes.h" - -struct packet_context { - int fd; - struct data_blob in, out; -}; - -/* - * Close the underlying fd - */ -static int packet_context_destructor(struct packet_context *ctx) -{ - return close(ctx->fd); -} - -/* - * Initialize a packet context. The fd is given to the packet context, meaning - * that it is automatically closed when the packet context is freed. - */ -struct packet_context *packet_init(TALLOC_CTX *mem_ctx, int fd) -{ - struct packet_context *result; - - if (!(result = TALLOC_ZERO_P(mem_ctx, struct packet_context))) { - return NULL; - } - - result->fd = fd; - talloc_set_destructor(result, packet_context_destructor); - return result; -} - -/* - * Pull data from the fd - */ -NTSTATUS packet_fd_read(struct packet_context *ctx) -{ - int res, available; - size_t new_size; - uint8 *in; - - res = ioctl(ctx->fd, FIONREAD, &available); - - if (res == -1) { - DEBUG(10, ("ioctl(FIONREAD) failed: %s\n", strerror(errno))); - return map_nt_error_from_unix(errno); - } - - SMB_ASSERT(available >= 0); - - if (available == 0) { - return NT_STATUS_END_OF_FILE; - } - - new_size = ctx->in.length + available; - - if (new_size < ctx->in.length) { - DEBUG(0, ("integer wrap\n")); - return NT_STATUS_NO_MEMORY; - } - - if (!(in = TALLOC_REALLOC_ARRAY(ctx, ctx->in.data, uint8, new_size))) { - DEBUG(10, ("talloc failed\n")); - return NT_STATUS_NO_MEMORY; - } - - res = recv(ctx->fd, in + ctx->in.length, available, 0); - - if (res < 0) { - DEBUG(10, ("recv failed: %s\n", strerror(errno))); - return map_nt_error_from_unix(errno); - } - - if (res == 0) { - return NT_STATUS_END_OF_FILE; - } - - ctx->in.data = in; - ctx->in.length += available; - - return NT_STATUS_OK; -} - -NTSTATUS packet_fd_read_sync(struct packet_context *ctx) -{ - int res; - fd_set r_fds; - - FD_ZERO(&r_fds); - FD_SET(ctx->fd, &r_fds); - - res = sys_select(ctx->fd+1, &r_fds, NULL, NULL, NULL); - - if (res == -1) { - DEBUG(10, ("select returned %s\n", strerror(errno))); - return map_nt_error_from_unix(errno); - } - - return packet_fd_read(ctx); -} - -BOOL packet_handler(struct packet_context *ctx, - BOOL (*full_req)(const struct data_blob *data, - size_t *length, - void *private_data), - NTSTATUS (*callback)(const struct data_blob *data, - void *private_data), - void *private_data, - NTSTATUS *status) -{ - size_t length; - struct data_blob data; - - if (!full_req(&ctx->in, &length, private_data)) { - return False; - } - - SMB_ASSERT(length <= ctx->in.length); - - data.data = ctx->in.data; - data.length = length; - - *status = callback(&data, private_data); - - memmove(ctx->in.data, ctx->in.data + length, - ctx->in.length - length); - ctx->in.length -= length; - - return True; -} - -/* - * How many bytes of outgoing data do we have pending? - */ -size_t packet_outgoing_bytes(struct packet_context *ctx) -{ - return ctx->out.length; -} - -/* - * Push data to the fd - */ -NTSTATUS packet_fd_write(struct packet_context *ctx) -{ - ssize_t sent; - - sent = send(ctx->fd, ctx->out.data, ctx->out.length, 0); - - if (sent == -1) { - DEBUG(0, ("send failed: %s\n", strerror(errno))); - return map_nt_error_from_unix(errno); - } - - memmove(ctx->out.data, ctx->out.data + sent, - ctx->out.length - sent); - ctx->out.length -= sent; - - return NT_STATUS_OK; -} - -/* - * Sync flush all outgoing bytes - */ -NTSTATUS packet_flush(struct packet_context *ctx) -{ - while (ctx->out.length != 0) { - NTSTATUS status = packet_fd_write(ctx); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - } - return NT_STATUS_OK; -} - -/* - * Send a list of DATA_BLOBs - * - * Example: packet_send(ctx, 2, data_blob_const(&size, sizeof(size)), - * data_blob_const(buf, size)); - */ -NTSTATUS packet_send(struct packet_context *ctx, int num_blobs, ...) -{ - va_list ap; - int i; - size_t len; - uint8 *out; - - len = ctx->out.length; - - va_start(ap, num_blobs); - for (i=0; i<num_blobs; i++) { - size_t tmp; - struct data_blob blob = va_arg(ap, struct data_blob); - - tmp = len + blob.length; - if (tmp < len) { - DEBUG(0, ("integer overflow\n")); - va_end(ap); - return NT_STATUS_NO_MEMORY; - } - len = tmp; - } - va_end(ap); - - if (len == 0) { - return NT_STATUS_OK; - } - - if (!(out = TALLOC_REALLOC_ARRAY(ctx, ctx->out.data, uint8, len))) { - DEBUG(0, ("talloc failed\n")); - return NT_STATUS_NO_MEMORY; - } - - ctx->out.data = out; - - va_start(ap, num_blobs); - for (i=0; i<num_blobs; i++) { - struct data_blob blob = va_arg(ap, struct data_blob); - - memcpy(ctx->out.data+ctx->out.length, blob.data, blob.length); - ctx->out.length += blob.length; - } - va_end(ap); - - SMB_ASSERT(ctx->out.length == len); - return NT_STATUS_OK; -} - -/* - * Get the packet context's file descriptor - */ -int packet_get_fd(struct packet_context *ctx) -{ - return ctx->fd; -} - diff --git a/source/lib/pam_errors.c b/source/lib/pam_errors.c index 42931383edd..9d9a377a912 100644 --- a/source/lib/pam_errors.c +++ b/source/lib/pam_errors.c @@ -21,11 +21,7 @@ #include "includes.h" #ifdef WITH_PAM -#if defined(HAVE_SECURITY_PAM_APPL_H) #include <security/pam_appl.h> -#elif defined(HAVE_PAM_PAM_APPL_H) -#include <pam/pam_appl.h> -#endif #if defined(PAM_AUTHTOK_RECOVERY_ERR) && !defined(PAM_AUTHTOK_RECOVER_ERR) #define PAM_AUTHTOK_RECOVER_ERR PAM_AUTHTOK_RECOVERY_ERR diff --git a/source/lib/pidfile.c b/source/lib/pidfile.c index 9dc4f2f1869..42ecede1175 100644 --- a/source/lib/pidfile.c +++ b/source/lib/pidfile.c @@ -34,15 +34,12 @@ pid_t pidfile_pid(const char *name) char pidstr[20]; pid_t pid; unsigned int ret; - char * pidFile; + pstring pidFile; - if (asprintf(&pidFile, "%s/%s.pid", lp_piddir(), name) == -1) { - return 0; - } + slprintf(pidFile, sizeof(pidFile)-1, "%s/%s.pid", lp_piddir(), name); fd = sys_open(pidFile, O_NONBLOCK | O_RDONLY, 0644); if (fd == -1) { - SAFE_FREE(pidFile); return 0; } @@ -71,14 +68,12 @@ pid_t pidfile_pid(const char *name) goto noproc; } - SAFE_FREE(pidFile); close(fd); return (pid_t)ret; noproc: close(fd); unlink(pidFile); - SAFE_FREE(pidFile); return 0; } @@ -88,14 +83,14 @@ void pidfile_create(const char *program_name) int fd; char buf[20]; char *short_configfile; - char *name; - char *pidFile; + pstring name; + pstring pidFile; pid_t pid; /* Add a suffix to the program name if this is a process with a * none default configuration file name. */ if (strcmp( CONFIGFILE, dyn_CONFIGFILE) == 0) { - name = SMB_STRDUP(program_name); + strncpy( name, program_name, sizeof( name)-1); } else { short_configfile = strrchr( dyn_CONFIGFILE, '/'); if (short_configfile == NULL) { @@ -105,15 +100,11 @@ void pidfile_create(const char *program_name) /* full/relative path provided */ short_configfile++; } - if (asprintf(&name, "%s-%s", program_name, - short_configfile+1) == -1) { - smb_panic("asprintf failed"); - } + slprintf( name, sizeof( name)-1, "%s-%s", program_name, + short_configfile ); } - if (asprintf(&pidFile, "%s/%s.pid", lp_piddir(), name) == -1) { - smb_panic("asprintf failed"); - } + slprintf(pidFile, sizeof(pidFile)-1, "%s/%s.pid", lp_piddir(), name); pid = pidfile_pid(name); if (pid != 0) { @@ -143,6 +134,4 @@ void pidfile_create(const char *program_name) exit(1); } /* Leave pid file open & locked for the duration... */ - SAFE_FREE(name); - SAFE_FREE(pidFile); } diff --git a/source/lib/privileges.c b/source/lib/privileges.c index 3714a906def..9c60b80e451 100644 --- a/source/lib/privileges.c +++ b/source/lib/privileges.c @@ -4,7 +4,6 @@ Copyright (C) Jean François Micouleau 1998-2001 Copyright (C) Simo Sorce 2002-2003 Copyright (C) Gerald (Jerry) Carter 2005 - Copyright (C) Michael Adam 2007 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 @@ -26,6 +25,84 @@ #define PRIVPREFIX "PRIV_" +static const SE_PRIV se_priv_all = SE_ALL_PRIVS; +static const SE_PRIV se_priv_end = SE_END; + +/* Define variables for all privileges so we can use the + SE_PRIV* in the various se_priv_XXX() functions */ + +const SE_PRIV se_priv_none = SE_NONE; +const SE_PRIV se_machine_account = SE_MACHINE_ACCOUNT; +const SE_PRIV se_print_operator = SE_PRINT_OPERATOR; +const SE_PRIV se_add_users = SE_ADD_USERS; +const SE_PRIV se_disk_operators = SE_DISK_OPERATOR; +const SE_PRIV se_remote_shutdown = SE_REMOTE_SHUTDOWN; +const SE_PRIV se_restore = SE_RESTORE; +const SE_PRIV se_take_ownership = SE_TAKE_OWNERSHIP; + +/******************************************************************** + This is a list of privileges reported by a WIndows 2000 SP4 AD DC + just for reference purposes (and I know the LUID is not guaranteed + across reboots): + + SeCreateTokenPrivilege Create a token object ( 0x0, 0x2 ) + SeAssignPrimaryTokenPrivilege Replace a process level token ( 0x0, 0x3 ) + SeLockMemoryPrivilege Lock pages in memory ( 0x0, 0x4 ) + SeIncreaseQuotaPrivilege Increase quotas ( 0x0, 0x5 ) + SeMachineAccountPrivilege Add workstations to domain ( 0x0, 0x6 ) + SeTcbPrivilege Act as part of the operating system ( 0x0, 0x7 ) + SeSecurityPrivilege Manage auditing and security log ( 0x0, 0x8 ) + SeTakeOwnershipPrivilege Take ownership of files or other objects ( 0x0, 0x9 ) + SeLoadDriverPrivilege Load and unload device drivers ( 0x0, 0xa ) + SeSystemProfilePrivilege Profile system performance ( 0x0, 0xb ) + SeSystemtimePrivilege Change the system time ( 0x0, 0xc ) + SeProfileSingleProcessPrivilege Profile single process ( 0x0, 0xd ) + SeIncreaseBasePriorityPrivilege Increase scheduling priority ( 0x0, 0xe ) + SeCreatePagefilePrivilege Create a pagefile ( 0x0, 0xf ) + SeCreatePermanentPrivilege Create permanent shared objects ( 0x0, 0x10 ) + SeBackupPrivilege Back up files and directories ( 0x0, 0x11 ) + SeRestorePrivilege Restore files and directories ( 0x0, 0x12 ) + SeShutdownPrivilege Shut down the system ( 0x0, 0x13 ) + SeDebugPrivilege Debug programs ( 0x0, 0x14 ) + SeAuditPrivilege Generate security audits ( 0x0, 0x15 ) + SeSystemEnvironmentPrivilege Modify firmware environment values ( 0x0, 0x16 ) + SeChangeNotifyPrivilege Bypass traverse checking ( 0x0, 0x17 ) + SeRemoteShutdownPrivilege Force shutdown from a remote system ( 0x0, 0x18 ) + SeUndockPrivilege Remove computer from docking station ( 0x0, 0x19 ) + SeSyncAgentPrivilege Synchronize directory service data ( 0x0, 0x1a ) + SeEnableDelegationPrivilege Enable computer and user accounts to be trusted for delegation ( 0x0, 0x1b ) + SeManageVolumePrivilege Perform volume maintenance tasks ( 0x0, 0x1c ) + SeImpersonatePrivilege Impersonate a client after authentication ( 0x0, 0x1d ) + SeCreateGlobalPrivilege Create global objects ( 0x0, 0x1e ) + + ********************************************************************/ + +/* we have to define the LUID here due to a horrible check by printmig.exe + that requires the SeBackupPrivilege match what is in Windows. So match + those that we implement and start Samba privileges at 0x1001 */ + +PRIVS privs[] = { +#if 0 /* usrmgr will display these twice if you include them. We don't + use them but we'll keep the bitmasks reserved in privileges.h anyways */ + + {SE_NETWORK_LOGON, "SeNetworkLogonRight", "Access this computer from network", { 0x0, 0x0 }}, + {SE_INTERACTIVE_LOGON, "SeInteractiveLogonRight", "Log on locally", { 0x0, 0x0 }}, + {SE_BATCH_LOGON, "SeBatchLogonRight", "Log on as a batch job", { 0x0, 0x0 }}, + {SE_SERVICE_LOGON, "SeServiceLogonRight", "Log on as a service", { 0x0, 0x0 }}, +#endif + {SE_MACHINE_ACCOUNT, "SeMachineAccountPrivilege", "Add machines to domain", { 0x0, 0x0006 }}, + {SE_TAKE_OWNERSHIP, "SeTakeOwnershipPrivilege", "Take ownership of files or other objects",{ 0x0, 0x0009 }}, + {SE_BACKUP, "SeBackupPrivilege", "Back up files and directories", { 0x0, 0x0011 }}, + {SE_RESTORE, "SeRestorePrivilege", "Restore files and directories", { 0x0, 0x0012 }}, + {SE_REMOTE_SHUTDOWN, "SeRemoteShutdownPrivilege", "Force shutdown from a remote system", { 0x0, 0x0018 }}, + + {SE_PRINT_OPERATOR, "SePrintOperatorPrivilege", "Manage printers", { 0x0, 0x1001 }}, + {SE_ADD_USERS, "SeAddUsersPrivilege", "Add users and groups to the domain", { 0x0, 0x1002 }}, + {SE_DISK_OPERATOR, "SeDiskOperatorPrivilege", "Manage disk shares", { 0x0, 0x1003 }}, + + {SE_END, "", "", { 0x0, 0x0 }} +}; + typedef struct { size_t count; DOM_SID *list; @@ -36,12 +113,131 @@ typedef struct { SID_LIST sids; } PRIV_SID_LIST; +/*************************************************************************** + copy an SE_PRIV structure +****************************************************************************/ + +BOOL se_priv_copy( SE_PRIV *dst, const SE_PRIV *src ) +{ + if ( !dst || !src ) + return False; + + memcpy( dst, src, sizeof(SE_PRIV) ); + + return True; +} + +/*************************************************************************** + combine 2 SE_PRIV structures and store the resulting set in mew_mask +****************************************************************************/ + +void se_priv_add( SE_PRIV *mask, const SE_PRIV *addpriv ) +{ + int i; + + for ( i=0; i<SE_PRIV_MASKSIZE; i++ ) { + mask->mask[i] |= addpriv->mask[i]; + } +} + +/*************************************************************************** + remove one SE_PRIV sytucture from another and store the resulting set + in mew_mask +****************************************************************************/ + +void se_priv_remove( SE_PRIV *mask, const SE_PRIV *removepriv ) +{ + int i; + + for ( i=0; i<SE_PRIV_MASKSIZE; i++ ) { + mask->mask[i] &= ~removepriv->mask[i]; + } +} + +/*************************************************************************** + invert a given SE_PRIV and store the set in new_mask +****************************************************************************/ + +static void se_priv_invert( SE_PRIV *new_mask, const SE_PRIV *mask ) +{ + SE_PRIV allprivs; + + se_priv_copy( &allprivs, &se_priv_all ); + se_priv_remove( &allprivs, mask ); + se_priv_copy( new_mask, &allprivs ); +} + +/*************************************************************************** + check if 2 SE_PRIV structure are equal +****************************************************************************/ + +static BOOL se_priv_equal( const SE_PRIV *mask1, const SE_PRIV *mask2 ) +{ + return ( memcmp(mask1, mask2, sizeof(SE_PRIV)) == 0 ); +} + +/*************************************************************************** + check if a SE_PRIV has any assigned privileges +****************************************************************************/ + +static BOOL se_priv_empty( const SE_PRIV *mask ) +{ + SE_PRIV p1; + int i; + + se_priv_copy( &p1, mask ); + + for ( i=0; i<SE_PRIV_MASKSIZE; i++ ) { + p1.mask[i] &= se_priv_all.mask[i]; + } + + return se_priv_equal( &p1, &se_priv_none ); +} + +/********************************************************************* + Lookup the SE_PRIV value for a privilege name +*********************************************************************/ + +BOOL se_priv_from_name( const char *name, SE_PRIV *mask ) +{ + int i; + + for ( i=0; !se_priv_equal(&privs[i].se_priv, &se_priv_end); i++ ) { + if ( strequal( privs[i].name, name ) ) { + se_priv_copy( mask, &privs[i].se_priv ); + return True; + } + } + + return False; +} + +/*************************************************************************** + dump an SE_PRIV structure to the log files +****************************************************************************/ + +void dump_se_priv( int dbg_cl, int dbg_lvl, const SE_PRIV *mask ) +{ + int i; + + DEBUGADDC( dbg_cl, dbg_lvl,("SE_PRIV ")); + + for ( i=0; i<SE_PRIV_MASKSIZE; i++ ) { + DEBUGADDC( dbg_cl, dbg_lvl,(" 0x%x", mask->mask[i] )); + } + + DEBUGADDC( dbg_cl, dbg_lvl, ("\n")); +} + +/*************************************************************************** + Retrieve the privilege mask (set) for a given SID +****************************************************************************/ static BOOL get_privileges( const DOM_SID *sid, SE_PRIV *mask ) { TDB_CONTEXT *tdb = get_account_pol_tdb(); fstring keystr; - TDB_DATA data; + TDB_DATA key, data; /* Fail if the admin has not enable privileges */ @@ -55,8 +251,10 @@ static BOOL get_privileges( const DOM_SID *sid, SE_PRIV *mask ) /* PRIV_<SID> (NULL terminated) as the key */ fstr_sprintf( keystr, "%s%s", PRIVPREFIX, sid_string_static(sid) ); + key.dptr = keystr; + key.dsize = strlen(keystr) + 1; - data = tdb_fetch_bystring( tdb, keystr ); + data = tdb_fetch( tdb, key ); if ( !data.dptr ) { DEBUG(3,("get_privileges: No privileges assigned to SID [%s]\n", @@ -80,7 +278,7 @@ static BOOL set_privileges( const DOM_SID *sid, SE_PRIV *mask ) { TDB_CONTEXT *tdb = get_account_pol_tdb(); fstring keystr; - TDB_DATA data; + TDB_DATA key, data; if ( !lp_enable_privileges() ) return False; @@ -96,13 +294,148 @@ static BOOL set_privileges( const DOM_SID *sid, SE_PRIV *mask ) /* PRIV_<SID> (NULL terminated) as the key */ fstr_sprintf( keystr, "%s%s", PRIVPREFIX, sid_string_static(sid) ); + key.dptr = keystr; + key.dsize = strlen(keystr) + 1; /* no packing. static size structure, just write it out */ - data.dptr = (uint8 *)mask; + data.dptr = (char*)mask; data.dsize = sizeof(SE_PRIV); - return ( tdb_store_bystring(tdb, keystr, data, TDB_REPLACE) != -1 ); + return ( tdb_store(tdb, key, data, TDB_REPLACE) != -1 ); +} + +/**************************************************************************** + check if the privilege is in the privilege list +****************************************************************************/ + +static BOOL is_privilege_assigned( const SE_PRIV *privileges, + const SE_PRIV *check ) +{ + SE_PRIV p1, p2; + + if ( !privileges || !check ) + return False; + + /* everyone has privileges if you aren't checking for any */ + + if ( se_priv_empty( check ) ) { + DEBUG(1,("is_privilege_assigned: no privileges in check_mask!\n")); + return True; + } + + se_priv_copy( &p1, check ); + + /* invert the SE_PRIV we want to check for and remove that from the + original set. If we are left with the SE_PRIV we are checking + for then return True */ + + se_priv_invert( &p1, check ); + se_priv_copy( &p2, privileges ); + se_priv_remove( &p2, &p1 ); + + return se_priv_equal( &p2, check ); +} + +/**************************************************************************** + check if the privilege is in the privilege list +****************************************************************************/ + +static BOOL is_any_privilege_assigned( SE_PRIV *privileges, const SE_PRIV *check ) +{ + SE_PRIV p1, p2; + + if ( !privileges || !check ) + return False; + + /* everyone has privileges if you aren't checking for any */ + + if ( se_priv_empty( check ) ) { + DEBUG(1,("is_any_privilege_assigned: no privileges in check_mask!\n")); + return True; + } + + se_priv_copy( &p1, check ); + + /* invert the SE_PRIV we want to check for and remove that from the + original set. If we are left with the SE_PRIV we are checking + for then return True */ + + se_priv_invert( &p1, check ); + se_priv_copy( &p2, privileges ); + se_priv_remove( &p2, &p1 ); + + /* see if we have any bits left */ + + return !se_priv_empty( &p2 ); +} + +/**************************************************************************** + add a privilege to a privilege array + ****************************************************************************/ + +static BOOL privilege_set_add(PRIVILEGE_SET *priv_set, LUID_ATTR set) +{ + LUID_ATTR *new_set; + + /* we can allocate memory to add the new privilege */ + + new_set = TALLOC_REALLOC_ARRAY(priv_set->mem_ctx, priv_set->set, LUID_ATTR, priv_set->count + 1); + if ( !new_set ) { + DEBUG(0,("privilege_set_add: failed to allocate memory!\n")); + return False; + } + + new_set[priv_set->count].luid.high = set.luid.high; + new_set[priv_set->count].luid.low = set.luid.low; + new_set[priv_set->count].attr = set.attr; + + priv_set->count++; + priv_set->set = new_set; + + return True; +} + +/********************************************************************* + Generate the LUID_ATTR structure based on a bitmask + The assumption here is that the privilege has already been validated + so we are guaranteed to find it in the list. +*********************************************************************/ + +LUID_ATTR get_privilege_luid( SE_PRIV *mask ) +{ + LUID_ATTR priv_luid; + int i; + + ZERO_STRUCT( priv_luid ); + + for ( i=0; !se_priv_equal(&privs[i].se_priv, &se_priv_end); i++ ) { + + if ( se_priv_equal( &privs[i].se_priv, mask ) ) { + priv_luid.luid = privs[i].luid; + break; + } + } + + return priv_luid; +} + +/********************************************************************* + Generate the LUID_ATTR structure based on a bitmask +*********************************************************************/ + +const char* get_privilege_dispname( const char *name ) +{ + int i; + + for ( i=0; !se_priv_equal(&privs[i].se_priv, &se_priv_end); i++ ) { + + if ( strequal( privs[i].name, name ) ) { + return privs[i].description; + } + } + + return NULL; } /********************************************************************* @@ -153,7 +486,7 @@ static int priv_traverse_fn(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *s /* check we have a PRIV_+SID entry */ - if ( strncmp((const char *)key.dptr, PRIVPREFIX, prefixlen) != 0) + if ( strncmp(key.dptr, PRIVPREFIX, prefixlen) != 0) return 0; /* check to see if we are looking for a particular privilege */ @@ -170,7 +503,7 @@ static int priv_traverse_fn(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *s return 0; } - fstrcpy( sid_string, (const char *)&key.dptr[strlen(PRIVPREFIX)] ); + fstrcpy( sid_string, &key.dptr[strlen(PRIVPREFIX)] ); /* this is a last ditch safety check to preventing returning and invalid SID (i've somehow run into this on development branches) */ @@ -253,15 +586,17 @@ BOOL grant_privilege(const DOM_SID *sid, const SE_PRIV *priv_mask) BOOL grant_privilege_by_name(DOM_SID *sid, const char *name) { - SE_PRIV mask; + int i; - if (! se_priv_from_name(name, &mask)) { - DEBUG(3, ("grant_privilege_by_name: " - "No Such Privilege Found (%s)\n", name)); - return False; - } + for ( i=0; !se_priv_equal(&privs[i].se_priv, &se_priv_end); i++ ) { + if ( strequal(privs[i].name, name) ) { + return grant_privilege( sid, &privs[i].se_priv ); + } + } - return grant_privilege( sid, &mask ); + DEBUG(3, ("grant_privilege_by_name: No Such Privilege Found (%s)\n", name)); + + return False; } /*************************************************************************** @@ -305,16 +640,17 @@ BOOL revoke_all_privileges( DOM_SID *sid ) BOOL revoke_privilege_by_name(DOM_SID *sid, const char *name) { - SE_PRIV mask; + int i; - if (! se_priv_from_name(name, &mask)) { - DEBUG(3, ("revoke_privilege_by_name: " - "No Such Privilege Found (%s)\n", name)); - return False; - } + for ( i=0; !se_priv_equal(&privs[i].se_priv, &se_priv_end); i++ ) { + if ( strequal(privs[i].name, name) ) { + return revoke_privilege( sid, &privs[i].se_priv ); + } + } - return revoke_privilege(sid, &mask); + DEBUG(3, ("revoke_privilege_by_name: No Such Privilege Found (%s)\n", name)); + return False; } /*************************************************************************** @@ -406,6 +742,139 @@ NTSTATUS dup_luid_attr(TALLOC_CTX *mem_ctx, LUID_ATTR **new_la, LUID_ATTR *old_l return NT_STATUS_OK; } +/**************************************************************************** + Does the user have the specified privilege ? We only deal with one privilege + at a time here. +*****************************************************************************/ + +BOOL user_has_privileges(const NT_USER_TOKEN *token, const SE_PRIV *privilege) +{ + if ( !token ) + return False; + + return is_privilege_assigned( &token->privileges, privilege ); +} + +/**************************************************************************** + Does the user have any of the specified privileges ? We only deal with one privilege + at a time here. +*****************************************************************************/ + +BOOL user_has_any_privilege(NT_USER_TOKEN *token, const SE_PRIV *privilege) +{ + if ( !token ) + return False; + + return is_any_privilege_assigned( &token->privileges, privilege ); +} + +/**************************************************************************** + Convert a LUID to a named string +****************************************************************************/ + +char* luid_to_privilege_name(const LUID *set) +{ + static fstring name; + int i; + + if (set->high != 0) + return NULL; + + for ( i=0; !se_priv_equal(&privs[i].se_priv, &se_priv_end); i++ ) { + if ( set->low == privs[i].luid.low ) { + fstrcpy( name, privs[i].name ); + return name; + } + } + + return NULL; +} + +/******************************************************************* + return the number of elements in the privlege array +*******************************************************************/ + +int count_all_privileges( void ) +{ + static int count; + + if ( count ) + return count; + + /* loop over the array and count it */ + for ( count=0; !se_priv_equal(&privs[count].se_priv, &se_priv_end); count++ ) ; + + return count; +} + +/******************************************************************* +*******************************************************************/ + +BOOL se_priv_to_privilege_set( PRIVILEGE_SET *set, SE_PRIV *mask ) +{ + int i; + uint32 num_privs = count_all_privileges(); + LUID_ATTR luid; + + luid.attr = 0; + luid.luid.high = 0; + + for ( i=0; i<num_privs; i++ ) { + if ( !is_privilege_assigned(mask, &privs[i].se_priv) ) + continue; + + luid.luid = privs[i].luid; + + if ( !privilege_set_add( set, luid ) ) + return False; + } + + return True; +} + +/******************************************************************* +*******************************************************************/ + +static BOOL luid_to_se_priv( LUID *luid, SE_PRIV *mask ) +{ + int i; + uint32 num_privs = count_all_privileges(); + + for ( i=0; i<num_privs; i++ ) { + if ( luid->low == privs[i].luid.low ) { + se_priv_copy( mask, &privs[i].se_priv ); + return True; + } + } + + return False; +} + +/******************************************************************* +*******************************************************************/ + +BOOL privilege_set_to_se_priv( SE_PRIV *mask, PRIVILEGE_SET *privset ) +{ + int i; + + ZERO_STRUCTP( mask ); + + for ( i=0; i<privset->count; i++ ) { + SE_PRIV r; + + /* sanity check for invalid privilege. we really + only care about the low 32 bits */ + + if ( privset->set[i].luid.high != 0 ) + return False; + + if ( luid_to_se_priv( &privset->set[i].luid, &r ) ) + se_priv_add( mask, &r ); + } + + return True; +} + /******************************************************************* *******************************************************************/ @@ -421,11 +890,15 @@ BOOL is_privileged_sid( const DOM_SID *sid ) BOOL grant_all_privileges( const DOM_SID *sid ) { + int i; SE_PRIV mask; + uint32 num_privs = count_all_privileges(); - if (!se_priv_put_all_privileges(&mask)) { - return False; - } + se_priv_copy( &mask, &se_priv_none ); + for ( i=0; i<num_privs; i++ ) { + se_priv_add(&mask, &privs[i].se_priv); + } + return grant_privilege( sid, &mask ); } diff --git a/source/lib/privileges_basic.c b/source/lib/privileges_basic.c deleted file mode 100644 index 93ecee89dce..00000000000 --- a/source/lib/privileges_basic.c +++ /dev/null @@ -1,512 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Privileges handling functions - Copyright (C) Jean François Micouleau 1998-2001 - Copyright (C) Simo Sorce 2002-2003 - Copyright (C) Gerald (Jerry) Carter 2005 - Copyright (C) Michael Adam 2007 - - 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. -*/ - -/* - * Basic privileges functions (mask-operations and conversion - * functions between the different formats (se_priv, privset, luid) - * moved here * from lib/privileges.c to minimize linker deps. - * - * generally SID- and LUID-related code is left in lib/privileges.c - * - * some extra functions to hide privs array from lib/privileges.c - */ - -#include "includes.h" - -const SE_PRIV se_priv_all = SE_ALL_PRIVS; -static const SE_PRIV se_priv_end = SE_END; - -/* Define variables for all privileges so we can use the - SE_PRIV* in the various se_priv_XXX() functions */ - -const SE_PRIV se_priv_none = SE_NONE; -const SE_PRIV se_machine_account = SE_MACHINE_ACCOUNT; -const SE_PRIV se_print_operator = SE_PRINT_OPERATOR; -const SE_PRIV se_add_users = SE_ADD_USERS; -const SE_PRIV se_disk_operators = SE_DISK_OPERATOR; -const SE_PRIV se_remote_shutdown = SE_REMOTE_SHUTDOWN; -const SE_PRIV se_restore = SE_RESTORE; -const SE_PRIV se_take_ownership = SE_TAKE_OWNERSHIP; - -/******************************************************************** - This is a list of privileges reported by a WIndows 2000 SP4 AD DC - just for reference purposes (and I know the LUID is not guaranteed - across reboots): - - SeCreateTokenPrivilege Create a token object ( 0x0, 0x2 ) - SeAssignPrimaryTokenPrivilege Replace a process level token ( 0x0, 0x3 ) - SeLockMemoryPrivilege Lock pages in memory ( 0x0, 0x4 ) - SeIncreaseQuotaPrivilege Increase quotas ( 0x0, 0x5 ) - SeMachineAccountPrivilege Add workstations to domain ( 0x0, 0x6 ) - SeTcbPrivilege Act as part of the operating system ( 0x0, 0x7 ) - SeSecurityPrivilege Manage auditing and security log ( 0x0, 0x8 ) - SeTakeOwnershipPrivilege Take ownership of files or other objects ( 0x0, 0x9 ) - SeLoadDriverPrivilege Load and unload device drivers ( 0x0, 0xa ) - SeSystemProfilePrivilege Profile system performance ( 0x0, 0xb ) - SeSystemtimePrivilege Change the system time ( 0x0, 0xc ) - SeProfileSingleProcessPrivilege Profile single process ( 0x0, 0xd ) - SeIncreaseBasePriorityPrivilege Increase scheduling priority ( 0x0, 0xe ) - SeCreatePagefilePrivilege Create a pagefile ( 0x0, 0xf ) - SeCreatePermanentPrivilege Create permanent shared objects ( 0x0, 0x10 ) - SeBackupPrivilege Back up files and directories ( 0x0, 0x11 ) - SeRestorePrivilege Restore files and directories ( 0x0, 0x12 ) - SeShutdownPrivilege Shut down the system ( 0x0, 0x13 ) - SeDebugPrivilege Debug programs ( 0x0, 0x14 ) - SeAuditPrivilege Generate security audits ( 0x0, 0x15 ) - SeSystemEnvironmentPrivilege Modify firmware environment values ( 0x0, 0x16 ) - SeChangeNotifyPrivilege Bypass traverse checking ( 0x0, 0x17 ) - SeRemoteShutdownPrivilege Force shutdown from a remote system ( 0x0, 0x18 ) - SeUndockPrivilege Remove computer from docking station ( 0x0, 0x19 ) - SeSyncAgentPrivilege Synchronize directory service data ( 0x0, 0x1a ) - SeEnableDelegationPrivilege Enable computer and user accounts to be trusted for delegation ( 0x0, 0x1b ) - SeManageVolumePrivilege Perform volume maintenance tasks ( 0x0, 0x1c ) - SeImpersonatePrivilege Impersonate a client after authentication ( 0x0, 0x1d ) - SeCreateGlobalPrivilege Create global objects ( 0x0, 0x1e ) - - ********************************************************************/ - -/* we have to define the LUID here due to a horrible check by printmig.exe - that requires the SeBackupPrivilege match what is in Windows. So match - those that we implement and start Samba privileges at 0x1001 */ - -PRIVS privs[] = { -#if 0 /* usrmgr will display these twice if you include them. We don't - use them but we'll keep the bitmasks reserved in privileges.h anyways */ - - {SE_NETWORK_LOGON, "SeNetworkLogonRight", "Access this computer from network", { 0x0, 0x0 }}, - {SE_INTERACTIVE_LOGON, "SeInteractiveLogonRight", "Log on locally", { 0x0, 0x0 }}, - {SE_BATCH_LOGON, "SeBatchLogonRight", "Log on as a batch job", { 0x0, 0x0 }}, - {SE_SERVICE_LOGON, "SeServiceLogonRight", "Log on as a service", { 0x0, 0x0 }}, -#endif - {SE_MACHINE_ACCOUNT, "SeMachineAccountPrivilege", "Add machines to domain", { 0x0, 0x0006 }}, - {SE_TAKE_OWNERSHIP, "SeTakeOwnershipPrivilege", "Take ownership of files or other objects",{ 0x0, 0x0009 }}, - {SE_BACKUP, "SeBackupPrivilege", "Back up files and directories", { 0x0, 0x0011 }}, - {SE_RESTORE, "SeRestorePrivilege", "Restore files and directories", { 0x0, 0x0012 }}, - {SE_REMOTE_SHUTDOWN, "SeRemoteShutdownPrivilege", "Force shutdown from a remote system", { 0x0, 0x0018 }}, - - {SE_PRINT_OPERATOR, "SePrintOperatorPrivilege", "Manage printers", { 0x0, 0x1001 }}, - {SE_ADD_USERS, "SeAddUsersPrivilege", "Add users and groups to the domain", { 0x0, 0x1002 }}, - {SE_DISK_OPERATOR, "SeDiskOperatorPrivilege", "Manage disk shares", { 0x0, 0x1003 }}, - - {SE_END, "", "", { 0x0, 0x0 }} -}; - -/*************************************************************************** - copy an SE_PRIV structure -****************************************************************************/ - -BOOL se_priv_copy( SE_PRIV *dst, const SE_PRIV *src ) -{ - if ( !dst || !src ) - return False; - - memcpy( dst, src, sizeof(SE_PRIV) ); - - return True; -} - -/*************************************************************************** - put all privileges into a mask -****************************************************************************/ - -BOOL se_priv_put_all_privileges(SE_PRIV *mask) -{ - int i; - uint32 num_privs = count_all_privileges(); - - if (!se_priv_copy(mask, &se_priv_none)) { - return False; - } - for ( i=0; i<num_privs; i++ ) { - se_priv_add(mask, &privs[i].se_priv); - } - return True; -} - -/*************************************************************************** - combine 2 SE_PRIV structures and store the resulting set in mew_mask -****************************************************************************/ - -void se_priv_add( SE_PRIV *mask, const SE_PRIV *addpriv ) -{ - int i; - - for ( i=0; i<SE_PRIV_MASKSIZE; i++ ) { - mask->mask[i] |= addpriv->mask[i]; - } -} - -/*************************************************************************** - remove one SE_PRIV sytucture from another and store the resulting set - in mew_mask -****************************************************************************/ - -void se_priv_remove( SE_PRIV *mask, const SE_PRIV *removepriv ) -{ - int i; - - for ( i=0; i<SE_PRIV_MASKSIZE; i++ ) { - mask->mask[i] &= ~removepriv->mask[i]; - } -} - -/*************************************************************************** - invert a given SE_PRIV and store the set in new_mask -****************************************************************************/ - -static void se_priv_invert( SE_PRIV *new_mask, const SE_PRIV *mask ) -{ - SE_PRIV allprivs; - - se_priv_copy( &allprivs, &se_priv_all ); - se_priv_remove( &allprivs, mask ); - se_priv_copy( new_mask, &allprivs ); -} - -/*************************************************************************** - check if 2 SE_PRIV structure are equal -****************************************************************************/ - -BOOL se_priv_equal( const SE_PRIV *mask1, const SE_PRIV *mask2 ) -{ - return ( memcmp(mask1, mask2, sizeof(SE_PRIV)) == 0 ); -} - -/*************************************************************************** - check if a SE_PRIV has any assigned privileges -****************************************************************************/ - -static BOOL se_priv_empty( const SE_PRIV *mask ) -{ - SE_PRIV p1; - int i; - - se_priv_copy( &p1, mask ); - - for ( i=0; i<SE_PRIV_MASKSIZE; i++ ) { - p1.mask[i] &= se_priv_all.mask[i]; - } - - return se_priv_equal( &p1, &se_priv_none ); -} - -/********************************************************************* - Lookup the SE_PRIV value for a privilege name -*********************************************************************/ - -BOOL se_priv_from_name( const char *name, SE_PRIV *mask ) -{ - int i; - - for ( i=0; !se_priv_equal(&privs[i].se_priv, &se_priv_end); i++ ) { - if ( strequal( privs[i].name, name ) ) { - se_priv_copy( mask, &privs[i].se_priv ); - return True; - } - } - - return False; -} - -/*************************************************************************** - dump an SE_PRIV structure to the log files -****************************************************************************/ - -void dump_se_priv( int dbg_cl, int dbg_lvl, const SE_PRIV *mask ) -{ - int i; - - DEBUGADDC( dbg_cl, dbg_lvl,("SE_PRIV ")); - - for ( i=0; i<SE_PRIV_MASKSIZE; i++ ) { - DEBUGADDC( dbg_cl, dbg_lvl,(" 0x%x", mask->mask[i] )); - } - - DEBUGADDC( dbg_cl, dbg_lvl, ("\n")); -} - -/**************************************************************************** - check if the privilege is in the privilege list -****************************************************************************/ - -BOOL is_privilege_assigned(const SE_PRIV *privileges, - const SE_PRIV *check) -{ - SE_PRIV p1, p2; - - if ( !privileges || !check ) - return False; - - /* everyone has privileges if you aren't checking for any */ - - if ( se_priv_empty( check ) ) { - DEBUG(1,("is_privilege_assigned: no privileges in check_mask!\n")); - return True; - } - - se_priv_copy( &p1, check ); - - /* invert the SE_PRIV we want to check for and remove that from the - original set. If we are left with the SE_PRIV we are checking - for then return True */ - - se_priv_invert( &p1, check ); - se_priv_copy( &p2, privileges ); - se_priv_remove( &p2, &p1 ); - - return se_priv_equal( &p2, check ); -} - -/**************************************************************************** - check if the privilege is in the privilege list -****************************************************************************/ - -static BOOL is_any_privilege_assigned( SE_PRIV *privileges, const SE_PRIV *check ) -{ - SE_PRIV p1, p2; - - if ( !privileges || !check ) - return False; - - /* everyone has privileges if you aren't checking for any */ - - if ( se_priv_empty( check ) ) { - DEBUG(1,("is_any_privilege_assigned: no privileges in check_mask!\n")); - return True; - } - - se_priv_copy( &p1, check ); - - /* invert the SE_PRIV we want to check for and remove that from the - original set. If we are left with the SE_PRIV we are checking - for then return True */ - - se_priv_invert( &p1, check ); - se_priv_copy( &p2, privileges ); - se_priv_remove( &p2, &p1 ); - - /* see if we have any bits left */ - - return !se_priv_empty( &p2 ); -} - -/********************************************************************* - Generate the LUID_ATTR structure based on a bitmask -*********************************************************************/ - -const char* get_privilege_dispname( const char *name ) -{ - int i; - - for ( i=0; !se_priv_equal(&privs[i].se_priv, &se_priv_end); i++ ) { - - if ( strequal( privs[i].name, name ) ) { - return privs[i].description; - } - } - - return NULL; -} - -/**************************************************************************** - initialise a privilege list and set the talloc context - ****************************************************************************/ - -/**************************************************************************** - Does the user have the specified privilege ? We only deal with one privilege - at a time here. -*****************************************************************************/ - -BOOL user_has_privileges(const NT_USER_TOKEN *token, const SE_PRIV *privilege) -{ - if ( !token ) - return False; - - return is_privilege_assigned( &token->privileges, privilege ); -} - -/**************************************************************************** - Does the user have any of the specified privileges ? We only deal with one privilege - at a time here. -*****************************************************************************/ - -BOOL user_has_any_privilege(NT_USER_TOKEN *token, const SE_PRIV *privilege) -{ - if ( !token ) - return False; - - return is_any_privilege_assigned( &token->privileges, privilege ); -} - -/******************************************************************* - return the number of elements in the privlege array -*******************************************************************/ - -int count_all_privileges( void ) -{ - /* - * The -1 is due to the weird SE_END record... - */ - return (sizeof(privs) / sizeof(privs[0])) - 1; -} - - -/********************************************************************* - Generate the LUID_ATTR structure based on a bitmask - The assumption here is that the privilege has already been validated - so we are guaranteed to find it in the list. -*********************************************************************/ - -LUID_ATTR get_privilege_luid( SE_PRIV *mask ) -{ - LUID_ATTR priv_luid; - int i; - - ZERO_STRUCT( priv_luid ); - - for ( i=0; !se_priv_equal(&privs[i].se_priv, &se_priv_end); i++ ) { - - if ( se_priv_equal( &privs[i].se_priv, mask ) ) { - priv_luid.luid = privs[i].luid; - break; - } - } - - return priv_luid; -} - -/**************************************************************************** - Convert a LUID to a named string -****************************************************************************/ - -const char *luid_to_privilege_name(const LUID *set) -{ - int i; - - if (set->high != 0) - return NULL; - - for ( i=0; !se_priv_equal(&privs[i].se_priv, &se_priv_end); i++ ) { - if ( set->low == privs[i].luid.low ) { - return privs[i].name; - } - } - - return NULL; -} - - -/**************************************************************************** - add a privilege to a privilege array - ****************************************************************************/ - -static BOOL privilege_set_add(PRIVILEGE_SET *priv_set, LUID_ATTR set) -{ - LUID_ATTR *new_set; - - /* we can allocate memory to add the new privilege */ - - new_set = TALLOC_REALLOC_ARRAY(priv_set->mem_ctx, priv_set->set, LUID_ATTR, priv_set->count + 1); - if ( !new_set ) { - DEBUG(0,("privilege_set_add: failed to allocate memory!\n")); - return False; - } - - new_set[priv_set->count].luid.high = set.luid.high; - new_set[priv_set->count].luid.low = set.luid.low; - new_set[priv_set->count].attr = set.attr; - - priv_set->count++; - priv_set->set = new_set; - - return True; -} - -/******************************************************************* -*******************************************************************/ - -BOOL se_priv_to_privilege_set( PRIVILEGE_SET *set, SE_PRIV *mask ) -{ - int i; - uint32 num_privs = count_all_privileges(); - LUID_ATTR luid; - - luid.attr = 0; - luid.luid.high = 0; - - for ( i=0; i<num_privs; i++ ) { - if ( !is_privilege_assigned(mask, &privs[i].se_priv) ) - continue; - - luid.luid = privs[i].luid; - - if ( !privilege_set_add( set, luid ) ) - return False; - } - - return True; -} - -/******************************************************************* -*******************************************************************/ - -static BOOL luid_to_se_priv( LUID *luid, SE_PRIV *mask ) -{ - int i; - uint32 num_privs = count_all_privileges(); - - for ( i=0; i<num_privs; i++ ) { - if ( luid->low == privs[i].luid.low ) { - se_priv_copy( mask, &privs[i].se_priv ); - return True; - } - } - - return False; -} - -/******************************************************************* -*******************************************************************/ - -BOOL privilege_set_to_se_priv( SE_PRIV *mask, PRIVILEGE_SET *privset ) -{ - int i; - - ZERO_STRUCTP( mask ); - - for ( i=0; i<privset->count; i++ ) { - SE_PRIV r; - - /* sanity check for invalid privilege. we really - only care about the low 32 bits */ - - if ( privset->set[i].luid.high != 0 ) - return False; - - if ( luid_to_se_priv( &privset->set[i].luid, &r ) ) - se_priv_add( mask, &r ); - } - - return True; -} - diff --git a/source/lib/replace/Makefile.in b/source/lib/replace/Makefile.in index 30f39ac6cb4..f4c79749a69 100644 --- a/source/lib/replace/Makefile.in +++ b/source/lib/replace/Makefile.in @@ -11,10 +11,9 @@ srcdir = @srcdir@ builddir = @builddir@ INSTALL = @INSTALL@ -.PHONY: test all showflags install installcheck clean distclean realdistclean +.PHONY: test -CFLAGS=-I. @CFLAGS@ -LDFLAGS=@LDFLAGS@ +CFLAGS=-I. -I@libreplacedir@ @CFLAGS@ OBJS = @LIBREPLACEOBJ@ @@ -24,7 +23,7 @@ showflags: @echo 'libreplace will be compiled with flags:' @echo ' CC = $(CC)' @echo ' CFLAGS = $(CFLAGS)' - @echo ' LDFLAGS= $(LDFLAGS)' + @echo ' LIBS = $(LIBS)' install: all mkdir -p $(libdir) @@ -41,7 +40,7 @@ installcheck: install test TEST_OBJS = test/testsuite.o test/os2_delete.o test/strptime.o testsuite: libreplace.a $(TEST_OBJS) - $(CC) -o testsuite $(TEST_OBJS) -L. -lreplace $(LDFLAGS) + $(CC) -o testsuite $(TEST_OBJS) -L. -lreplace .c.o: @echo Compiling $*.c diff --git a/source/lib/replace/README b/source/lib/replace/README index e7b89936c0f..77558b2ca96 100644 --- a/source/lib/replace/README +++ b/source/lib/replace/README @@ -92,7 +92,6 @@ ZERO_STRUCTPN ZERO_ARRAY ARRAY_SIZE PTR_DIFF -offsetof Headers: stdint.h diff --git a/source/lib/replace/configure.ac b/source/lib/replace/configure.ac index beeb77e1520..48fb7ce2594 100644 --- a/source/lib/replace/configure.ac +++ b/source/lib/replace/configure.ac @@ -19,6 +19,4 @@ if test "$ac_cv_prog_gcc" = yes; then CFLAGS="$CFLAGS -Wno-format-y2k" fi -AC_SUBST(LDFLAGS) - AC_OUTPUT(Makefile) diff --git a/source/lib/replace/dlfcn.c b/source/lib/replace/dlfcn.c index 55b38bb9eb7..22f9f8bf79b 100644 --- a/source/lib/replace/dlfcn.c +++ b/source/lib/replace/dlfcn.c @@ -26,11 +26,7 @@ #include "replace.h" #ifndef HAVE_DLOPEN -#ifdef DLOPEN_TAKES_UNSIGNED_FLAGS -void *rep_dlopen(const char *name, unsigned int flags) -#else void *rep_dlopen(const char *name, int flags) -#endif { return NULL; } diff --git a/source/lib/replace/dlfcn.m4 b/source/lib/replace/dlfcn.m4 index a1b57d10ec4..d42409ac630 100644 --- a/source/lib/replace/dlfcn.m4 +++ b/source/lib/replace/dlfcn.m4 @@ -5,17 +5,12 @@ LIBS="" libreplace_cv_dlfcn=no AC_SEARCH_LIBS(dlopen, dl) -AC_CHECK_HEADERS(dlfcn.h) -AC_CHECK_FUNCS([dlopen dlsym dlerror dlclose],[],[libreplace_cv_dlfcn=yes]) - -AC_VERIFY_C_PROTOTYPE([void *dlopen(const char* filename, unsigned int flags)], - [ - return 0; - ],[ - AC_DEFINE(DLOPEN_TAKES_UNSIGNED_FLAGS, 1, [Whether dlopen takes unsinged int flags]) - ],[],[ - #include <dlfcn.h> - ]) +if test x"${ac_cv_search_dlopen}" = x"no"; then + libreplace_cv_dlfcn=yes +else + AC_CHECK_HEADERS(dlfcn.h) + AC_CHECK_FUNCS([dlopen dlsym dlerror dlclose],[],[libreplace_cv_dlfcn=yes]) +fi if test x"${libreplace_cv_dlfcn}" = x"yes";then LIBREPLACEOBJ="${LIBREPLACEOBJ} dlfcn.o" diff --git a/source/lib/replace/libreplace.m4 b/source/lib/replace/libreplace.m4 index f06d7f83dc3..e9b19b7cf51 100644 --- a/source/lib/replace/libreplace.m4 +++ b/source/lib/replace/libreplace.m4 @@ -99,7 +99,7 @@ AC_CHECK_HEADERS(stdarg.h vararg.h) AC_CHECK_HEADERS(sys/socket.h netinet/in.h netdb.h arpa/inet.h) AC_CHECK_HEADERS(netinet/ip.h netinet/tcp.h netinet/in_systm.h netinet/in_ip.h) AC_CHECK_HEADERS(sys/sockio.h sys/un.h) -AC_CHECK_HEADERS(sys/mount.h mntent.h) + dnl we need to check that net/if.h really can be used, to cope with hpux dnl where including it always fails @@ -354,7 +354,6 @@ AC_LIBREPLACE_LOCATION_CHECKS AC_LIBREPLACE_CC_CHECKS AC_LIBREPLACE_BROKEN_CHECKS AC__LIBREPLACE_ALL_CHECKS_END -CFLAGS="$CFLAGS -I$libreplacedir" ]) m4_include(libreplace_cc.m4) diff --git a/source/lib/replace/libreplace_cc.m4 b/source/lib/replace/libreplace_cc.m4 index 780cf62dec8..74c53cad998 100644 --- a/source/lib/replace/libreplace_cc.m4 +++ b/source/lib/replace/libreplace_cc.m4 @@ -60,9 +60,9 @@ case "$host_os" in *hpux*) # mmap on HPUX is completely broken... AC_DEFINE(MMAP_BLACKLIST, 1, [Whether MMAP is broken]) - if test "`uname -r`" = "B.11.00" -o "`uname -r`" = "B.11.11"; then - AC_MSG_WARN([Enabling HPUX 11.00/11.11 header bug workaround]) - CFLAGS="$CFLAGS -D_FILE_OFFSET_BITS=64 -Dpread=pread64 -Dpwrite=pwrite64" + if test "`uname -r`" = "B.11.11"; then + AC_MSG_WARN([Enabling HPUX 11.11 header bug workaround]) + CFLAGS="$CFLAGS -D_LARGEFILE64_SUPPORT -D__LP64__ -DO_LARGEFILE=04000" fi if test "`uname -r`" = "B.11.23"; then AC_MSG_WARN([Enabling HPUX 11.23 machine/sys/getppdp.h bug workaround]) diff --git a/source/lib/replace/replace.c b/source/lib/replace/replace.c index b86da53cafd..db299130e51 100644 --- a/source/lib/replace/replace.c +++ b/source/lib/replace/replace.c @@ -438,10 +438,6 @@ char *rep_mkdtemp(char *template) } #endif -/***************************************************************** - Watch out: this is not thread safe. -*****************************************************************/ - #ifndef HAVE_PREAD ssize_t rep_pread(int __fd, void *__buf, size_t __nbytes, off_t __offset) { @@ -452,10 +448,6 @@ ssize_t rep_pread(int __fd, void *__buf, size_t __nbytes, off_t __offset) } #endif -/***************************************************************** - Watch out: this is not thread safe. -*****************************************************************/ - #ifndef HAVE_PWRITE ssize_t rep_pwrite(int __fd, const void *__buf, size_t __nbytes, off_t __offset) { @@ -576,24 +568,20 @@ int rep_unsetenv(const char *name) { extern char **environ; size_t len = strlen(name); - size_t i, count; - - if (environ == NULL || getenv(name) == NULL) { - return 0; - } + size_t i; + int found = 0; - for (i=0;environ[i];i++) /* noop */ ; + for (i=0; (environ && environ[i]); i++) { + if (found) { + environ[i-1] = environ[i]; + continue; + } - count=i; - - for (i=0;i<count;) { if (strncmp(environ[i], name, len) == 0 && environ[i][len] == '=') { - /* note: we do _not_ free the old variable here. It is unsafe to - do so, as the pointer may not have come from malloc */ - memmove(&environ[i], &environ[i+1], (count-i)*sizeof(char *)); - count--; - } else { - i++; + free(environ[i]); + environ[i] = NULL; + found = 1; + continue; } } diff --git a/source/lib/replace/replace.h b/source/lib/replace/replace.h index 411d4012fe6..b96356ac467 100644 --- a/source/lib/replace/replace.h +++ b/source/lib/replace/replace.h @@ -53,10 +53,6 @@ #define QSORT_CAST (int (*)(const void *, const void *)) #endif -#ifndef offsetof -#define offsetof(t,f) ((unsigned int)&((t *)0)->f) -#endif - #ifdef HAVE_STDINT_H #include <stdint.h> /* force off HAVE_INTTYPES_H so that roken doesn't try to include both, @@ -232,12 +228,8 @@ char *rep_dlerror(void); #ifndef HAVE_DLOPEN #define dlopen rep_dlopen -#ifdef DLOPEN_TAKES_UNSIGNED_FLAGS -void *rep_dlopen(const char *name, unsigned int flags); -#else void *rep_dlopen(const char *name, int flags); #endif -#endif #ifndef HAVE_DLSYM #define dlsym rep_dlsym @@ -266,14 +258,6 @@ int rep_socketpair(int d, int type, int protocol, int sv[2]); #endif #endif -#ifndef _DEPRECATED_ -#if (__GNUC__ >= 3) && (__GNUC_MINOR__ >= 1 ) -#define _DEPRECATED_ __attribute__ ((deprecated)) -#else -#define _DEPRECATED_ -#endif -#endif - #ifndef HAVE_VASPRINTF #define vasprintf rep_vasprintf int rep_vasprintf(char **ptr, const char *format, va_list ap) PRINTF_ATTRIBUTE(2,0); @@ -337,12 +321,6 @@ char *rep_strptime(const char *buf, const char *format, struct tm *tm); #ifndef RTLD_LAZY #define RTLD_LAZY 0 #endif -#ifndef RTLD_NOW -#define RTLD_NOW 0 -#endif -#ifndef RTLD_GLOBAL -#define RTLD_GLOBAL 0 -#endif #ifndef HAVE_SECURE_MKSTEMP #define mkstemp(path) rep_mkstemp(path) @@ -354,16 +332,6 @@ int rep_mkstemp(char *temp); char *rep_mkdtemp(char *template); #endif -#ifndef HAVE_PREAD -#define pread rep_pread -ssize_t rep_pread(int __fd, void *__buf, size_t __nbytes, off_t __offset); -#endif - -#ifndef HAVE_PWRITE -#define pwrite rep_pwrite -ssize_t rep_pwrite(int __fd, const void *__buf, size_t __nbytes, off_t __offset); -#endif - #ifdef HAVE_LIMITS_H #include <limits.h> #endif diff --git a/source/lib/replace/system/aio.h b/source/lib/replace/system/aio.h index 624575f6197..45154ccb27a 100644 --- a/source/lib/replace/system/aio.h +++ b/source/lib/replace/system/aio.h @@ -7,23 +7,19 @@ Copyright (C) Andrew Tridgell 2006 - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL + 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 library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, + 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + 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. */ #ifdef HAVE_LIBAIO_H diff --git a/source/lib/replace/system/capability.h b/source/lib/replace/system/capability.h index 23e59691456..6ed8ae8de02 100644 --- a/source/lib/replace/system/capability.h +++ b/source/lib/replace/system/capability.h @@ -7,23 +7,19 @@ Copyright (C) Andrew Tridgell 2004 - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL + 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 library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, + 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + 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. */ #ifdef HAVE_SYS_CAPABILITY_H diff --git a/source/lib/replace/system/dir.h b/source/lib/replace/system/dir.h index 01607b384f2..64e413c9079 100644 --- a/source/lib/replace/system/dir.h +++ b/source/lib/replace/system/dir.h @@ -7,23 +7,19 @@ Copyright (C) Andrew Tridgell 2004 - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL + 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 library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, + 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + 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. */ #if HAVE_DIRENT_H diff --git a/source/lib/replace/system/filesys.h b/source/lib/replace/system/filesys.h index b3c339a1448..3b68abe48ae 100644 --- a/source/lib/replace/system/filesys.h +++ b/source/lib/replace/system/filesys.h @@ -7,24 +7,19 @@ Copyright (C) Andrew Tridgell 2004 - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL + 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 library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, + 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - + 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. */ #include <unistd.h> @@ -38,10 +33,6 @@ #include <sys/mount.h> #endif -#ifdef HAVE_MNTENT_H -#include <mntent.h> -#endif - #ifdef HAVE_SYS_VFS_H #include <sys/vfs.h> #endif diff --git a/source/lib/replace/system/glob.h b/source/lib/replace/system/glob.h index ea546ff7f71..0e51f397c69 100644 --- a/source/lib/replace/system/glob.h +++ b/source/lib/replace/system/glob.h @@ -7,24 +7,19 @@ Copyright (C) Andrew Tridgell 2004 - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL + 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 library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, + 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - + 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. */ #ifdef HAVE_GLOB_H diff --git a/source/lib/replace/system/iconv.h b/source/lib/replace/system/iconv.h index 2b2832a796d..abc2d6f4e1b 100644 --- a/source/lib/replace/system/iconv.h +++ b/source/lib/replace/system/iconv.h @@ -7,24 +7,19 @@ Copyright (C) Andrew Tridgell 2004 - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL + 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 library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, + 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - + 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. */ #if !defined(HAVE_ICONV) && defined(HAVE_ICONV_H) diff --git a/source/lib/replace/system/kerberos.h b/source/lib/replace/system/kerberos.h index 8a849c4fb69..1617b96aad1 100644 --- a/source/lib/replace/system/kerberos.h +++ b/source/lib/replace/system/kerberos.h @@ -8,24 +8,19 @@ Copyright (C) Andrew Tridgell 2004 - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL + 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 library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, + 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - + 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. */ #ifdef HAVE_KRB5 diff --git a/source/lib/replace/system/locale.h b/source/lib/replace/system/locale.h index aa1e1e619e5..82b179dc5b8 100644 --- a/source/lib/replace/system/locale.h +++ b/source/lib/replace/system/locale.h @@ -8,24 +8,19 @@ Copyright (C) Andrew Tridgell 2004 - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL + 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 library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, + 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - + 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. */ #ifdef HAVE_CTYPE_H diff --git a/source/lib/replace/system/network.h b/source/lib/replace/system/network.h index 64c7cd33995..5e648dcd156 100644 --- a/source/lib/replace/system/network.h +++ b/source/lib/replace/system/network.h @@ -7,24 +7,19 @@ Copyright (C) Andrew Tridgell 2004 - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL + 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 library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, + 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - + 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. */ #ifdef HAVE_SYS_SOCKET_H diff --git a/source/lib/replace/system/passwd.h b/source/lib/replace/system/passwd.h index d51914eb508..21f31f0388c 100644 --- a/source/lib/replace/system/passwd.h +++ b/source/lib/replace/system/passwd.h @@ -8,24 +8,19 @@ Copyright (C) Andrew Tridgell 2004 - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL + 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 library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, + 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - + 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. */ #ifdef HAVE_PWD_H diff --git a/source/lib/replace/system/printing.h b/source/lib/replace/system/printing.h index 3054811453a..489ccb1da8c 100644 --- a/source/lib/replace/system/printing.h +++ b/source/lib/replace/system/printing.h @@ -8,24 +8,19 @@ Copyright (C) Andrew Tridgell 2004 - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL + 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 library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, + 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - + 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. */ #ifdef AIX diff --git a/source/lib/replace/system/readline.h b/source/lib/replace/system/readline.h index 3a253058e2c..4a64ef13766 100644 --- a/source/lib/replace/system/readline.h +++ b/source/lib/replace/system/readline.h @@ -3,26 +3,21 @@ /* Unix SMB/CIFS implementation. - Readline wrappers + readline wrappers - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL + 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 library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, + 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - + 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. */ #ifdef HAVE_LIBREADLINE diff --git a/source/lib/replace/system/select.h b/source/lib/replace/system/select.h index a196f9c4789..20346259c27 100644 --- a/source/lib/replace/system/select.h +++ b/source/lib/replace/system/select.h @@ -7,34 +7,25 @@ Copyright (C) Andrew Tridgell 2004 - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL + 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 library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, + 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - + 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. */ #ifdef HAVE_SYS_SELECT_H #include <sys/select.h> #endif -#ifdef HAVE_SYS_EPOLL_H -#include <sys/epoll.h> -#endif - #ifndef SELECT_CAST #define SELECT_CAST #endif diff --git a/source/lib/replace/system/shmem.h b/source/lib/replace/system/shmem.h index 234ec1c14a1..26fa7c8d433 100644 --- a/source/lib/replace/system/shmem.h +++ b/source/lib/replace/system/shmem.h @@ -7,24 +7,19 @@ Copyright (C) Andrew Tridgell 2004 - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL + 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 library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, + 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - + 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. */ #if defined(HAVE_SYS_IPC_H) diff --git a/source/lib/replace/system/syslog.h b/source/lib/replace/system/syslog.h index f949c7a8d97..e123830a709 100644 --- a/source/lib/replace/system/syslog.h +++ b/source/lib/replace/system/syslog.h @@ -7,24 +7,19 @@ Copyright (C) Andrew Tridgell 2004 - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL + 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 library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, + 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - + 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. */ #ifdef HAVE_SYSLOG_H diff --git a/source/lib/replace/system/terminal.h b/source/lib/replace/system/terminal.h index 292c85ab6f6..94d6b5cc98d 100644 --- a/source/lib/replace/system/terminal.h +++ b/source/lib/replace/system/terminal.h @@ -7,24 +7,19 @@ Copyright (C) Andrew Tridgell 2004 - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL + 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 library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, + 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - + 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. */ #ifdef SUNOS4 diff --git a/source/lib/replace/system/time.h b/source/lib/replace/system/time.h index a0924f4051c..e7c88f133d4 100644 --- a/source/lib/replace/system/time.h +++ b/source/lib/replace/system/time.h @@ -6,25 +6,20 @@ time system include wrappers Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, + 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - + 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. */ #ifdef TIME_WITH_SYS_TIME diff --git a/source/lib/replace/system/wait.h b/source/lib/replace/system/wait.h index 96b5c2cb807..179ef0774e0 100644 --- a/source/lib/replace/system/wait.h +++ b/source/lib/replace/system/wait.h @@ -6,25 +6,20 @@ waitpid system include wrappers Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, + 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - + 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. */ #ifdef HAVE_SYS_WAIT_H diff --git a/source/lib/secace.c b/source/lib/secace.c index 871c983533d..c9b4f839503 100644 --- a/source/lib/secace.c +++ b/source/lib/secace.c @@ -47,7 +47,9 @@ void sec_ace_copy(SEC_ACE *ace_dest, SEC_ACE *ace_src) ace_dest->flags = ace_src->flags; ace_dest->size = ace_src->size; ace_dest->access_mask = ace_src->access_mask; - ace_dest->object = ace_src->object; + ace_dest->obj_flags = ace_src->obj_flags; + memcpy(&ace_dest->obj_guid, &ace_src->obj_guid, sizeof(struct GUID)); + memcpy(&ace_dest->inh_guid, &ace_src->inh_guid, sizeof(struct GUID)); sid_copy(&ace_dest->trustee, &ace_src->trustee); } @@ -55,7 +57,7 @@ void sec_ace_copy(SEC_ACE *ace_dest, SEC_ACE *ace_src) Sets up a SEC_ACE structure. ********************************************************************/ -void init_sec_ace(SEC_ACE *t, const DOM_SID *sid, uint8 type, uint32 mask, uint8 flag) +void init_sec_ace(SEC_ACE *t, const DOM_SID *sid, uint8 type, SEC_ACCESS mask, uint8 flag) { t->type = type; t->flags = flag; diff --git a/source/lib/secdesc.c b/source/lib/secdesc.c index 510282bbfb0..160fdb949d2 100644 --- a/source/lib/secdesc.c +++ b/source/lib/secdesc.c @@ -154,13 +154,13 @@ SEC_DESC_BUF *sec_desc_merge(TALLOC_CTX *ctx, SEC_DESC_BUF *new_sdb, SEC_DESC_BU /* Copy over owner and group sids. There seems to be no flag for this so just check the pointer values. */ - owner_sid = new_sdb->sd->owner_sid ? new_sdb->sd->owner_sid : - old_sdb->sd->owner_sid; + owner_sid = new_sdb->sec->owner_sid ? new_sdb->sec->owner_sid : + old_sdb->sec->owner_sid; - group_sid = new_sdb->sd->group_sid ? new_sdb->sd->group_sid : - old_sdb->sd->group_sid; + group_sid = new_sdb->sec->group_sid ? new_sdb->sec->group_sid : + old_sdb->sec->group_sid; - secdesc_type = new_sdb->sd->type; + secdesc_type = new_sdb->sec->type; /* Ignore changes to the system ACL. This has the effect of making changes through the security tab audit button not sticking. @@ -172,14 +172,14 @@ SEC_DESC_BUF *sec_desc_merge(TALLOC_CTX *ctx, SEC_DESC_BUF *new_sdb, SEC_DESC_BU /* Copy across discretionary ACL */ if (secdesc_type & SEC_DESC_DACL_PRESENT) { - dacl = new_sdb->sd->dacl; + dacl = new_sdb->sec->dacl; } else { - dacl = old_sdb->sd->dacl; + dacl = old_sdb->sec->dacl; } /* Create new security descriptor from bits */ - psd = make_sec_desc(ctx, new_sdb->sd->revision, secdesc_type, + psd = make_sec_desc(ctx, new_sdb->sec->revision, secdesc_type, owner_sid, group_sid, sacl, dacl, &secdesc_size); return_sdb = make_sec_desc_buf(ctx, secdesc_size, psd); @@ -192,7 +192,7 @@ SEC_DESC_BUF *sec_desc_merge(TALLOC_CTX *ctx, SEC_DESC_BUF *new_sdb, SEC_DESC_BU ********************************************************************/ SEC_DESC *make_sec_desc(TALLOC_CTX *ctx, uint16 revision, uint16 type, - const DOM_SID *owner_sid, const DOM_SID *grp_sid, + const DOM_SID *owner_sid, const DOM_SID *group_sid, SEC_ACL *sacl, SEC_ACL *dacl, size_t *sd_size) { SEC_DESC *dst; @@ -211,21 +211,21 @@ SEC_DESC *make_sec_desc(TALLOC_CTX *ctx, uint16 revision, uint16 type, if (dacl) dst->type |= SEC_DESC_DACL_PRESENT; - dst->owner_sid = NULL; - dst->group_sid = NULL; - dst->sacl = NULL; - dst->dacl = NULL; + dst->off_owner_sid = 0; + dst->off_grp_sid = 0; + dst->off_sacl = 0; + dst->off_dacl = 0; - if(owner_sid && ((dst->owner_sid = sid_dup_talloc(dst,owner_sid)) == NULL)) + if(owner_sid && ((dst->owner_sid = sid_dup_talloc(ctx,owner_sid)) == NULL)) goto error_exit; - if(grp_sid && ((dst->group_sid = sid_dup_talloc(dst,grp_sid)) == NULL)) + if(group_sid && ((dst->group_sid = sid_dup_talloc(ctx,group_sid)) == NULL)) goto error_exit; - if(sacl && ((dst->sacl = dup_sec_acl(dst, sacl)) == NULL)) + if(sacl && ((dst->sacl = dup_sec_acl(ctx, sacl)) == NULL)) goto error_exit; - if(dacl && ((dst->dacl = dup_sec_acl(dst, dacl)) == NULL)) + if(dacl && ((dst->dacl = dup_sec_acl(ctx, dacl)) == NULL)) goto error_exit; offset = SEC_DESC_HEADER_SIZE; @@ -235,17 +235,21 @@ SEC_DESC *make_sec_desc(TALLOC_CTX *ctx, uint16 revision, uint16 type, */ if (dst->sacl != NULL) { + dst->off_sacl = offset; offset += dst->sacl->size; } if (dst->dacl != NULL) { + dst->off_dacl = offset; offset += dst->dacl->size; } if (dst->owner_sid != NULL) { + dst->off_owner_sid = offset; offset += sid_size(dst->owner_sid); } if (dst->group_sid != NULL) { + dst->off_grp_sid = offset; offset += sid_size(dst->group_sid); } @@ -275,71 +279,14 @@ SEC_DESC *dup_sec_desc(TALLOC_CTX *ctx, const SEC_DESC *src) } /******************************************************************* - Convert a secdesc into a byte stream -********************************************************************/ -NTSTATUS marshall_sec_desc(TALLOC_CTX *mem_ctx, - struct security_descriptor *secdesc, - uint8 **data, size_t *len) -{ - prs_struct ps; - - if (!prs_init(&ps, sec_desc_size(secdesc), mem_ctx, MARSHALL)) { - return NT_STATUS_NO_MEMORY; - } - - if (!sec_io_desc("security_descriptor", &secdesc, &ps, 1)) { - prs_mem_free(&ps); - return NT_STATUS_INVALID_PARAMETER; - } - - if (!(*data = (uint8 *)talloc_memdup(mem_ctx, ps.data_p, - prs_offset(&ps)))) { - prs_mem_free(&ps); - return NT_STATUS_NO_MEMORY; - } - - *len = prs_offset(&ps); - prs_mem_free(&ps); - return NT_STATUS_OK; -} - -/******************************************************************* - Parse a byte stream into a secdesc -********************************************************************/ -NTSTATUS unmarshall_sec_desc(TALLOC_CTX *mem_ctx, uint8 *data, size_t len, - struct security_descriptor **psecdesc) -{ - prs_struct ps; - struct security_descriptor *secdesc = NULL; - - if (!(secdesc = TALLOC_ZERO_P(mem_ctx, struct security_descriptor))) { - return NT_STATUS_NO_MEMORY; - } - - if (!prs_init(&ps, 0, secdesc, UNMARSHALL)) { - return NT_STATUS_NO_MEMORY; - } - - prs_give_memory(&ps, (char *)data, len, False); - - if (!sec_io_desc("security_descriptor", &secdesc, &ps, 1)) { - return NT_STATUS_INVALID_PARAMETER; - } - - prs_mem_free(&ps); - *psecdesc = secdesc; - return NT_STATUS_OK; -} - -/******************************************************************* Creates a SEC_DESC structure with typical defaults. ********************************************************************/ -SEC_DESC *make_standard_sec_desc(TALLOC_CTX *ctx, const DOM_SID *owner_sid, const DOM_SID *grp_sid, +SEC_DESC *make_standard_sec_desc(TALLOC_CTX *ctx, const DOM_SID *owner_sid, const DOM_SID *group_sid, SEC_ACL *dacl, size_t *sd_size) { return make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, - owner_sid, grp_sid, NULL, dacl, sd_size); + owner_sid, group_sid, NULL, dacl, sd_size); } /******************************************************************* @@ -354,12 +301,15 @@ SEC_DESC_BUF *make_sec_desc_buf(TALLOC_CTX *ctx, size_t len, SEC_DESC *sec_desc) return NULL; /* max buffer size (allocated size) */ - dst->sd_size = (uint32)len; + dst->max_len = (uint32)len; + dst->len = (uint32)len; - if(sec_desc && ((dst->sd = dup_sec_desc(ctx, sec_desc)) == NULL)) { + if(sec_desc && ((dst->sec = dup_sec_desc(ctx, sec_desc)) == NULL)) { return NULL; } + dst->ptr = 0x1; + return dst; } @@ -372,7 +322,7 @@ SEC_DESC_BUF *dup_sec_desc_buf(TALLOC_CTX *ctx, SEC_DESC_BUF *src) if(src == NULL) return NULL; - return make_sec_desc_buf( ctx, src->sd_size, src->sd); + return make_sec_desc_buf( ctx, src->len, src->sec); } /******************************************************************* @@ -582,9 +532,7 @@ SEC_DESC_BUF *se_create_child_secdesc(TALLOC_CTX *ctx, SEC_DESC *parent_ctr, Sets up a SEC_ACCESS structure. ********************************************************************/ -void init_sec_access(uint32 *t, uint32 mask) +void init_sec_access(SEC_ACCESS *t, uint32 mask) { *t = mask; } - - diff --git a/source/lib/select.c b/source/lib/select.c index e8900a383cc..f63221f7cfa 100644 --- a/source/lib/select.c +++ b/source/lib/select.c @@ -71,9 +71,9 @@ int sys_select(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorfds, s */ if(set_blocking(select_pipe[0],0)==-1) - smb_panic("select_pipe[0]: O_NONBLOCK failed"); + smb_panic("select_pipe[0]: O_NONBLOCK failed.\n"); if(set_blocking(select_pipe[1],0)==-1) - smb_panic("select_pipe[1]: O_NONBLOCK failed"); + smb_panic("select_pipe[1]: O_NONBLOCK failed.\n"); initialised = sys_getpid(); } diff --git a/source/lib/sharesec.c b/source/lib/sharesec.c index 2b9cc8c6914..e3216aa4594 100644 --- a/source/lib/sharesec.c +++ b/source/lib/sharesec.c @@ -125,7 +125,7 @@ SEC_DESC *get_share_security( TALLOC_CTX *ctx, const char *servicename, slprintf(key, sizeof(key)-1, "SECDESC/%s", servicename); - if (tdb_prs_fetch_bystring(share_tdb, key, &ps, ctx)!=0 || + if (tdb_prs_fetch(share_tdb, key, &ps, ctx)!=0 || !sec_io_desc("get_share_security", &psd, &ps, 1)) { DEBUG(4, ("get_share_security: using default secdesc for %s\n", @@ -167,7 +167,7 @@ BOOL set_share_security(const char *share_name, SEC_DESC *psd) slprintf(key, sizeof(key)-1, "SECDESC/%s", share_name); - if (tdb_prs_store_bystring(share_tdb, key, &ps)==0) { + if (tdb_prs_store(share_tdb, key, &ps)==0) { ret = True; DEBUG(5,("set_share_security: stored secdesc for %s\n", share_name )); } else { @@ -179,7 +179,8 @@ BOOL set_share_security(const char *share_name, SEC_DESC *psd) out: prs_mem_free(&ps); - TALLOC_FREE(mem_ctx); + if (mem_ctx) + talloc_destroy(mem_ctx); return ret; } @@ -194,7 +195,8 @@ BOOL delete_share_security(const struct share_params *params) slprintf(key, sizeof(key)-1, "SECDESC/%s", lp_servicename(params->service)); - kbuf = string_term_tdb_data(key); + kbuf.dptr = key; + kbuf.dsize = strlen(key)+1; if (tdb_trans_delete(share_tdb, kbuf) != 0) { DEBUG(0,("delete_share_security: Failed to delete entry for share %s\n", diff --git a/source/lib/smbldap.c b/source/lib/smbldap.c index 1cfb5f89a70..c09e0968c52 100644 --- a/source/lib/smbldap.c +++ b/source/lib/smbldap.c @@ -409,8 +409,9 @@ ATTRIB_MAP_ENTRY sidmap_attr_list[] = { if (mods == NULL) { mods = SMB_MALLOC_P(LDAPMod *); if (mods == NULL) { - smb_panic("smbldap_set_mod: out of memory!"); + smb_panic("smbldap_set_mod: out of memory!\n"); /* notreached. */ + abort(); } mods[0] = NULL; } @@ -423,13 +424,15 @@ ATTRIB_MAP_ENTRY sidmap_attr_list[] = { if (mods[i] == NULL) { mods = SMB_REALLOC_ARRAY (mods, LDAPMod *, i + 2); if (mods == NULL) { - smb_panic("smbldap_set_mod: out of memory!"); + smb_panic("smbldap_set_mod: out of memory!\n"); /* notreached. */ + abort(); } mods[i] = SMB_MALLOC_P(LDAPMod); if (mods[i] == NULL) { - smb_panic("smbldap_set_mod: out of memory!"); + smb_panic("smbldap_set_mod: out of memory!\n"); /* notreached. */ + abort(); } mods[i]->mod_op = modop; mods[i]->mod_values = NULL; @@ -447,13 +450,15 @@ ATTRIB_MAP_ENTRY sidmap_attr_list[] = { mods[i]->mod_values = SMB_REALLOC_ARRAY(mods[i]->mod_values, char *, j + 2); if (mods[i]->mod_values == NULL) { - smb_panic("smbldap_set_mod: out of memory!"); + smb_panic("smbldap_set_mod: out of memory!\n"); /* notreached. */ + abort(); } if (push_utf8_allocate(&utf8_value, value) == (size_t)-1) { - smb_panic("smbldap_set_mod: String conversion failure!"); + smb_panic("smbldap_set_mod: String conversion failure!\n"); /* notreached. */ + abort(); } mods[i]->mod_values[j] = utf8_value; @@ -995,11 +1000,6 @@ static int smbldap_connect_system(struct smbldap_state *ldap_state, LDAP * ldap_ return rc; } -static void smbldap_idle_fn(struct event_context *event_ctx, - struct timed_event *te, - const struct timeval *now, - void *private_data); - /********************************************************************** Connect to LDAP server (called before every ldap operation) *********************************************************************/ @@ -1062,16 +1062,6 @@ static int smbldap_open(struct smbldap_state *ldap_state) ldap_state->last_ping = time(NULL); ldap_state->pid = sys_getpid(); - - TALLOC_FREE(ldap_state->idle_event); - - if (ldap_state->event_context != NULL) { - ldap_state->idle_event = event_add_timed( - ldap_state->event_context, NULL, - timeval_current_ofs(SMBLDAP_IDLE_TIME, 0), - "smbldap_idle_fn", smbldap_idle_fn, ldap_state); - } - DEBUG(4,("The LDAP server is succesfully connected\n")); return LDAP_SUCCESS; @@ -1556,28 +1546,17 @@ int smbldap_search_suffix (struct smbldap_state *ldap_state, filter, search_attr, 0, result); } -static void smbldap_idle_fn(struct event_context *event_ctx, - struct timed_event *te, - const struct timeval *now, - void *private_data) +static void smbldap_idle_fn(void **data, time_t *interval, time_t now) { - struct smbldap_state *state = (struct smbldap_state *)private_data; - - TALLOC_FREE(state->idle_event); + struct smbldap_state *state = (struct smbldap_state *)(*data); if (state->ldap_struct == NULL) { DEBUG(10,("ldap connection not connected...\n")); return; } - if ((state->last_use+SMBLDAP_IDLE_TIME) > now->tv_sec) { + if ((state->last_use+SMBLDAP_IDLE_TIME) > now) { DEBUG(10,("ldap connection not idle...\n")); - - state->idle_event = event_add_timed( - event_ctx, NULL, - timeval_add(now, SMBLDAP_IDLE_TIME, 0), - "smbldap_idle_fn", smbldap_idle_fn, - private_data); return; } @@ -1600,7 +1579,7 @@ void smbldap_free_struct(struct smbldap_state **ldap_state) SAFE_FREE((*ldap_state)->bind_dn); SAFE_FREE((*ldap_state)->bind_secret); - TALLOC_FREE((*ldap_state)->idle_event); + smb_unregister_idle_event((*ldap_state)->event_id); *ldap_state = NULL; @@ -1612,9 +1591,7 @@ void smbldap_free_struct(struct smbldap_state **ldap_state) Intitalise the 'general' ldap structures, on which ldap operations may be conducted *********************************************************************/ -NTSTATUS smbldap_init(TALLOC_CTX *mem_ctx, struct event_context *event_ctx, - const char *location, - struct smbldap_state **smbldap_state) +NTSTATUS smbldap_init(TALLOC_CTX *mem_ctx, const char *location, struct smbldap_state **smbldap_state) { *smbldap_state = TALLOC_ZERO_P(mem_ctx, struct smbldap_state); if (!*smbldap_state) { @@ -1628,7 +1605,14 @@ NTSTATUS smbldap_init(TALLOC_CTX *mem_ctx, struct event_context *event_ctx, (*smbldap_state)->uri = "ldap://localhost"; } - (*smbldap_state)->event_context = event_ctx; + (*smbldap_state)->event_id = + smb_register_idle_event(smbldap_idle_fn, (void *)(*smbldap_state), + SMBLDAP_IDLE_TIME); + + if ((*smbldap_state)->event_id == SMB_EVENT_ID_INVALID) { + DEBUG(0,("Failed to register LDAP idle event!\n")); + return NT_STATUS_INVALID_HANDLE; + } return NT_STATUS_OK; } diff --git a/source/lib/substitute.c b/source/lib/substitute.c index 708c184475b..4c81bd8444e 100644 --- a/source/lib/substitute.c +++ b/source/lib/substitute.c @@ -453,7 +453,7 @@ char *alloc_sub_basic(const char *smb_name, const char *domain_name, const char *str) { char *b, *p, *s, *r, *a_string; - fstring pidstr, vnnstr; + fstring pidstr; struct passwd *pass; const char *local_machine_name = get_local_machine_name(); @@ -552,10 +552,6 @@ char *alloc_sub_basic(const char *smb_name, const char *domain_name, case '(': a_string = realloc_expand_longvar( a_string, p ); break; - case 'V' : - slprintf(vnnstr,sizeof(vnnstr)-1, "%u", get_my_vnn()); - a_string = realloc_string_sub(a_string, "%V", vnnstr); - break; default: break; } @@ -773,3 +769,21 @@ void standard_sub_advanced(const char *servicename, const char *user, SAFE_FREE( s ); } } + +/**************************************************************************** + * Do some standard substitutions in a string. + * ****************************************************************************/ + +void standard_sub_conn(connection_struct *conn, char *str, size_t len) +{ + char *s; + + s = alloc_sub_advanced(lp_servicename(SNUM(conn)), conn->user, conn->connectpath, + conn->gid, smb_user_name, "", str); + + if ( s ) { + strncpy( str, s, len ); + SAFE_FREE( s ); + } +} + diff --git a/source/lib/system.c b/source/lib/system.c index 79d37d70245..ac1add8fc19 100644 --- a/source/lib/system.c +++ b/source/lib/system.c @@ -4,6 +4,7 @@ Copyright (C) Andrew Tridgell 1992-1998 Copyright (C) Jeremy Allison 1998-2005 Copyright (C) Timur Bakeyev 2005 + Copyright (C) Bjoern Jacke 2006-2007 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 @@ -642,25 +643,6 @@ int sys_chown(const char *fname,uid_t uid,gid_t gid) } /******************************************************************* - Wrapper for lchown. -********************************************************************/ - -int sys_lchown(const char *fname,uid_t uid,gid_t gid) -{ -#ifndef HAVE_LCHOWN - static int done; - if (!done) { - DEBUG(1,("WARNING: no lchown!\n")); - done=1; - } - errno = ENOSYS; - return -1; -#else - return(lchown(fname,uid,gid)); -#endif -} - -/******************************************************************* os/2 also doesn't have chroot ********************************************************************/ int sys_chroot(const char *dname) @@ -889,13 +871,15 @@ int groups_max(void) } /************************************************************************** - Wrap setgroups and getgroups for systems that declare getgroups() as - returning an array of gid_t, but actuall return an array of int. + Wrapper for getgroups. Deals with broken (int) case. ****************************************************************************/ -#if defined(HAVE_BROKEN_GETGROUPS) -static int sys_broken_getgroups(int setlen, gid_t *gidset) +int sys_getgroups(int setlen, gid_t *gidset) { +#if !defined(HAVE_BROKEN_GETGROUPS) + return getgroups(setlen, gidset); +#else + GID_T gid; GID_T *group_list; int i, ngroups; @@ -917,7 +901,7 @@ static int sys_broken_getgroups(int setlen, gid_t *gidset) if (setlen == 0) setlen = groups_max(); - if((group_list = SMB_MALLOC_ARRAY(GID_T, setlen)) == NULL) { + if((group_list = (GID_T *)malloc(setlen * sizeof(GID_T))) == NULL) { DEBUG(0,("sys_getgroups: Malloc fail.\n")); return -1; } @@ -934,10 +918,26 @@ static int sys_broken_getgroups(int setlen, gid_t *gidset) SAFE_FREE(group_list); return ngroups; +#endif /* HAVE_BROKEN_GETGROUPS */ } -static int sys_broken_setgroups(int setlen, gid_t *gidset) + +/************************************************************************** + Wrapper for setgroups. Deals with broken (int) case. Automatically used + if we have broken getgroups. +****************************************************************************/ + +int sys_setgroups(int setlen, gid_t *gidset) { +#if !defined(HAVE_SETGROUPS) + errno = ENOSYS; + return -1; +#endif /* HAVE_SETGROUPS */ + +#if !defined(HAVE_BROKEN_GETGROUPS) + return setgroups(setlen, gidset); +#else + GID_T *group_list; int i ; @@ -954,7 +954,7 @@ static int sys_broken_setgroups(int setlen, gid_t *gidset) * GID_T array of size setlen. */ - if((group_list = SMB_MALLOC_ARRAY(GID_T, setlen)) == NULL) { + if((group_list = (GID_T *)malloc(setlen * sizeof(GID_T))) == NULL) { DEBUG(0,("sys_setgroups: Malloc fail.\n")); return -1; } @@ -971,105 +971,7 @@ static int sys_broken_setgroups(int setlen, gid_t *gidset) SAFE_FREE(group_list); return 0 ; -} - #endif /* HAVE_BROKEN_GETGROUPS */ - -/* This is a list of systems that require the first GID passed to setgroups(2) - * to be the effective GID. If your system is one of these, add it here. - */ -#if defined (FREEBSD) || defined (DARWINOS) -#define USE_BSD_SETGROUPS -#endif - -#if defined(USE_BSD_SETGROUPS) -/* Depending on the particular BSD implementation, the first GID that is - * passed to setgroups(2) will either be ignored or will set the credential's - * effective GID. In either case, the right thing to do is to guarantee that - * gidset[0] is the effective GID. - */ -static int sys_bsd_setgroups(gid_t primary_gid, int setlen, const gid_t *gidset) -{ - gid_t *new_gidset = NULL; - int max; - int ret; - - /* setgroups(2) will fail with EINVAL if we pass too many groups. */ - max = groups_max(); - - /* No group list, just make sure we are setting the efective GID. */ - if (setlen == 0) { - return setgroups(1, &primary_gid); - } - - /* If the primary gid is not the first array element, grow the array - * and insert it at the front. - */ - if (gidset[0] != primary_gid) { - new_gidset = SMB_MALLOC_ARRAY(gid_t, setlen + 1); - if (new_gidset == NULL) { - return -1; - } - - memcpy(new_gidset + 1, gidset, (setlen * sizeof(gid_t))); - new_gidset[0] = primary_gid; - setlen++; - } - - if (setlen > max) { - DEBUG(3, ("forced to truncate group list from %d to %d\n", - setlen, max)); - setlen = max; - } - -#if defined(HAVE_BROKEN_GETGROUPS) - ret = sys_broken_setgroups(setlen, new_gidset ? new_gidset : gidset); -#else - ret = setgroups(setlen, new_gidset ? new_gidset : gidset); -#endif - - if (new_gidset) { - int errsav = errno; - SAFE_FREE(new_gidset); - errno = errsav; - } - - return ret; -} - -#endif /* USE_BSD_SETGROUPS */ - -/************************************************************************** - Wrapper for getgroups. Deals with broken (int) case. -****************************************************************************/ - -int sys_getgroups(int setlen, gid_t *gidset) -{ -#if defined(HAVE_BROKEN_GETGROUPS) - return sys_broken_getgroups(setlen, gidset); -#else - return getgroups(setlen, gidset); -#endif -} - -/************************************************************************** - Wrapper for setgroups. Deals with broken (int) case and BSD case. -****************************************************************************/ - -int sys_setgroups(gid_t UNUSED(primary_gid), int setlen, gid_t *gidset) -{ -#if !defined(HAVE_SETGROUPS) - errno = ENOSYS; - return -1; -#endif /* HAVE_SETGROUPS */ - -#if defined(USE_BSD_SETGROUPS) - return sys_bsd_setgroups(primary_gid, setlen, gidset); -#elif defined(HAVE_BROKEN_GETGROUPS) - return sys_broken_setgroups(setlen, gidset); -#else - return setgroups(setlen, gidset); -#endif } /************************************************************************** @@ -1366,25 +1268,21 @@ SMB_STRUCT_WPASSWD *wsys_getpwuid(uid_t uid) #endif /* NOT CURRENTLY USED - JRA */ /************************************************************************** - Extract a command into an arg list. + Extract a command into an arg list. Uses a static pstring for storage. + Caller frees returned arg list (which contains pointers into the static pstring). ****************************************************************************/ -static char **extract_args(TALLOC_CTX *mem_ctx, const char *command) +static char **extract_args(const char *command) { - char *trunc_cmd; - char *saveptr; + static pstring trunc_cmd; char *ptr; int argcl; char **argl = NULL; int i; - if (!(trunc_cmd = talloc_strdup(mem_ctx, command))) { - DEBUG(0, ("talloc failed\n")); - goto nomem; - } + pstrcpy(trunc_cmd, command); - if(!(ptr = strtok_r(trunc_cmd, " \t", &saveptr))) { - TALLOC_FREE(trunc_cmd); + if(!(ptr = strtok(trunc_cmd, " \t"))) { errno = EINVAL; return NULL; } @@ -1393,46 +1291,27 @@ static char **extract_args(TALLOC_CTX *mem_ctx, const char *command) * Count the args. */ - for( argcl = 1; ptr; ptr = strtok_r(NULL, " \t", &saveptr)) + for( argcl = 1; ptr; ptr = strtok(NULL, " \t")) argcl++; - TALLOC_FREE(trunc_cmd); - - if (!(argl = TALLOC_ARRAY(mem_ctx, char *, argcl + 1))) { - goto nomem; - } + if((argl = (char **)SMB_MALLOC((argcl + 1) * sizeof(char *))) == NULL) + return NULL; /* * Now do the extraction. */ - if (!(trunc_cmd = talloc_strdup(mem_ctx, command))) { - goto nomem; - } + pstrcpy(trunc_cmd, command); - ptr = strtok_r(trunc_cmd, " \t", &saveptr); + ptr = strtok(trunc_cmd, " \t"); i = 0; + argl[i++] = ptr; - if (!(argl[i++] = talloc_strdup(argl, ptr))) { - goto nomem; - } - - while((ptr = strtok_r(NULL, " \t", &saveptr)) != NULL) { - - if (!(argl[i++] = talloc_strdup(argl, ptr))) { - goto nomem; - } - } + while((ptr = strtok(NULL, " \t")) != NULL) + argl[i++] = ptr; argl[i++] = NULL; return argl; - - nomem: - DEBUG(0, ("talloc failed\n")); - TALLOC_FREE(trunc_cmd); - TALLOC_FREE(argl); - errno = ENOMEM; - return NULL; } /************************************************************************** @@ -1506,7 +1385,7 @@ int sys_popen(const char *command) * Extract the command and args into a NULL terminated array. */ - if(!(argl = extract_args(NULL, command))) + if(!(argl = extract_args(command))) goto err_exit; entry->child_pid = sys_fork(); @@ -1548,7 +1427,7 @@ int sys_popen(const char *command) */ close (child_end); - TALLOC_FREE(argl); + SAFE_FREE(argl); /* Link into popen_chain. */ entry->next = popen_chain; @@ -1683,6 +1562,17 @@ int sys_dup2(int oldfd, int newfd) SAFE_FREE(msgbuf); } +/******** Solaris EA helper function prototypes ********/ +#ifdef HAVE_ATTROPEN +#define SOLARIS_ATTRMODE S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP +static int solaris_write_xattr(int attrfd, const char *value, size_t size); +static ssize_t solaris_read_xattr(int attrfd, void *value, size_t size); +static ssize_t solaris_list_xattr(int attrdirfd, char *list, size_t size); +static int solaris_unlinkat(int attrdirfd, const char *name); +static int solaris_attropen(const char *path, const char *attrpath, int oflag, mode_t mode); +static int solaris_openat(int fildes, const char *path, int oflag, mode_t mode); +#endif + /************************************************************************** Wrappers for extented attribute calls. Based on the Linux package with support for IRIX and (Net|Free)BSD also. Expand as other systems have them. @@ -1731,6 +1621,14 @@ ssize_t sys_getxattr (const char *path, const char *name, void *value, size_t si retval = attr_get(path, attrname, (char *)value, &valuelength, flags); return retval ? retval : valuelength; +#elif defined(HAVE_ATTROPEN) + ssize_t ret = -1; + int attrfd = solaris_attropen(path, name, O_RDONLY, 0); + if (attrfd >= 0) { + ret = solaris_read_xattr(attrfd, value, size); + close(attrfd); + } + return ret; #else errno = ENOSYS; return -1; @@ -1774,6 +1672,14 @@ ssize_t sys_lgetxattr (const char *path, const char *name, void *value, size_t s retval = attr_get(path, attrname, (char *)value, &valuelength, flags); return retval ? retval : valuelength; +#elif defined(HAVE_ATTROPEN) + ssize_t ret = -1; + int attrfd = solaris_attropen(path, name, O_RDONLY|AT_SYMLINK_NOFOLLOW, 0); + if (attrfd >= 0) { + ret = solaris_read_xattr(attrfd, value, size); + close(attrfd); + } + return ret; #else errno = ENOSYS; return -1; @@ -1819,6 +1725,14 @@ ssize_t sys_fgetxattr (int filedes, const char *name, void *value, size_t size) retval = attr_getf(filedes, attrname, (char *)value, &valuelength, flags); return retval ? retval : valuelength; +#elif defined(HAVE_ATTROPEN) + ssize_t ret = -1; + int attrfd = solaris_openat(filedes, name, O_RDONLY|O_XATTR, 0); + if (attrfd >= 0) { + ret = solaris_read_xattr(attrfd, value, size); + close(attrfd); + } + return ret; #else errno = ENOSYS; return -1; @@ -2003,6 +1917,14 @@ ssize_t sys_listxattr (const char *path, char *list, size_t size) return bsd_attr_list(0, arg, list, size); #elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H) return irix_attr_list(path, 0, list, size, 0); +#elif defined(HAVE_ATTROPEN) + ssize_t ret = -1; + int attrdirfd = solaris_attropen(path, ".", O_RDONLY, 0); + if (attrdirfd >= 0) { + ret = solaris_list_xattr(attrdirfd, list, size); + close(attrdirfd); + } + return ret; #else errno = ENOSYS; return -1; @@ -2024,6 +1946,14 @@ ssize_t sys_llistxattr (const char *path, char *list, size_t size) return bsd_attr_list(1, arg, list, size); #elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H) return irix_attr_list(path, 0, list, size, ATTR_DONTFOLLOW); +#elif defined(HAVE_ATTROPEN) + ssize_t ret = -1; + int attrdirfd = solaris_attropen(path, ".", O_RDONLY|AT_SYMLINK_NOFOLLOW, 0); + if (attrdirfd >= 0) { + ret = solaris_list_xattr(attrdirfd, list, size); + close(attrdirfd); + } + return ret; #else errno = ENOSYS; return -1; @@ -2047,6 +1977,14 @@ ssize_t sys_flistxattr (int filedes, char *list, size_t size) return bsd_attr_list(2, arg, list, size); #elif defined(HAVE_ATTR_LISTF) return irix_attr_list(NULL, filedes, list, size, 0); +#elif defined(HAVE_ATTROPEN) + ssize_t ret = -1; + int attrdirfd = solaris_openat(filedes, ".", O_RDONLY|O_XATTR, 0); + if (attrdirfd >= 0) { + ret = solaris_list_xattr(attrdirfd, list, size); + close(attrdirfd); + } + return ret; #else errno = ENOSYS; return -1; @@ -2078,6 +2016,14 @@ int sys_removexattr (const char *path, const char *name) if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT; return attr_remove(path, attrname, flags); +#elif defined(HAVE_ATTROPEN) + int ret = -1; + int attrdirfd = solaris_attropen(path, ".", O_RDONLY, 0); + if (attrdirfd >= 0) { + ret = solaris_unlinkat(attrdirfd, name); + close(attrdirfd); + } + return ret; #else errno = ENOSYS; return -1; @@ -2107,6 +2053,14 @@ int sys_lremovexattr (const char *path, const char *name) if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT; return attr_remove(path, attrname, flags); +#elif defined(HAVE_ATTROPEN) + int ret = -1; + int attrdirfd = solaris_attropen(path, ".", O_RDONLY|AT_SYMLINK_NOFOLLOW, 0); + if (attrdirfd >= 0) { + ret = solaris_unlinkat(attrdirfd, name); + close(attrdirfd); + } + return ret; #else errno = ENOSYS; return -1; @@ -2138,6 +2092,14 @@ int sys_fremovexattr (int filedes, const char *name) if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT; return attr_removef(filedes, attrname, flags); +#elif defined(HAVE_ATTROPEN) + int ret = -1; + int attrdirfd = solaris_openat(filedes, ".", O_RDONLY|O_XATTR, 0); + if (attrdirfd >= 0) { + ret = solaris_unlinkat(attrdirfd, name); + close(attrdirfd); + } + return ret; #else errno = ENOSYS; return -1; @@ -2196,6 +2158,17 @@ int sys_setxattr (const char *path, const char *name, const void *value, size_t if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE; return attr_set(path, attrname, (const char *)value, size, myflags); +#elif defined(HAVE_ATTROPEN) + int ret = -1; + int myflags = O_RDWR; + if (flags & XATTR_CREATE) myflags |= O_EXCL; + if (!(flags & XATTR_REPLACE)) myflags |= O_CREAT; + int attrfd = solaris_attropen(path, name, myflags, (mode_t) SOLARIS_ATTRMODE); + if (attrfd >= 0) { + ret = solaris_write_xattr(attrfd, value, size); + close(attrfd); + } + return ret; #else errno = ENOSYS; return -1; @@ -2248,6 +2221,17 @@ int sys_lsetxattr (const char *path, const char *name, const void *value, size_t if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE; return attr_set(path, attrname, (const char *)value, size, myflags); +#elif defined(HAVE_ATTROPEN) + int ret = -1; + int myflags = O_RDWR | AT_SYMLINK_NOFOLLOW; + if (flags & XATTR_CREATE) myflags |= O_EXCL; + if (!(flags & XATTR_REPLACE)) myflags |= O_CREAT; + int attrfd = solaris_attropen(path, name, myflags, (mode_t) SOLARIS_ATTRMODE); + if (attrfd >= 0) { + ret = solaris_write_xattr(attrfd, value, size); + close(attrfd); + } + return ret; #else errno = ENOSYS; return -1; @@ -2301,12 +2285,147 @@ int sys_fsetxattr (int filedes, const char *name, const void *value, size_t size if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE; return attr_setf(filedes, attrname, (const char *)value, size, myflags); +#elif defined(HAVE_ATTROPEN) + int ret = -1; + int myflags = O_RDWR | O_XATTR; + if (flags & XATTR_CREATE) myflags |= O_EXCL; + if (!(flags & XATTR_REPLACE)) myflags |= O_CREAT; + int attrfd = solaris_openat(filedes, name, myflags, (mode_t) SOLARIS_ATTRMODE); + if (attrfd >= 0) { + ret = solaris_write_xattr(attrfd, value, size); + close(attrfd); + } + return ret; #else errno = ENOSYS; return -1; #endif } +/************************************************************************** + helper functions for Solaris' EA support +****************************************************************************/ +#ifdef HAVE_ATTROPEN +static ssize_t solaris_read_xattr(int attrfd, void *value, size_t size) +{ + struct stat sbuf; + + if (fstat(attrfd, &sbuf) == -1) { + errno = ENOATTR; + return -1; + } + + /* This is to return the current size of the named extended attribute */ + if (size == 0) { + return sbuf.st_size; + } + + /* check size and read xattr */ + if (sbuf.st_size > size) { + errno = ERANGE; + return -1; + } + + return read(attrfd, value, sbuf.st_size); +} + +static ssize_t solaris_list_xattr(int attrdirfd, char *list, size_t size) +{ + ssize_t len = 0; + int stop = 0; + DIR *dirp; + struct dirent *de; + int newfd = dup(attrdirfd); + /* CAUTION: The originating file descriptor should not be + used again following the call to fdopendir(). + For that reason we dup() the file descriptor + here to make things more clear. */ + dirp = fdopendir(newfd); + + while ((de = readdir(dirp))) { + size_t listlen = strlen(de->d_name); + if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) { + /* we don't want "." and ".." here: */ + DEBUG(10,("skipped EA %s\n",de->d_name)); + continue; + } + + if (size == 0) { + /* return the current size of the list of extended attribute names*/ + len += listlen + 1; + } else { + /* check size and copy entrieѕ + nul into list. */ + if ((len + listlen + 1) > size) { + errno = ERANGE; + len = -1; + break; + } else { + safe_strcpy(list + len, de->d_name, listlen); + pstrcpy(list + len, de->d_name); + len += listlen; + list[len] = '\0'; + ++len; + } + } + } + + if (closedir(dirp) == -1) { + DEBUG(0,("closedir dirp failed: %s\n",strerror(errno))); + return -1; + } + return len; +} + +static int solaris_unlinkat(int attrdirfd, const char *name) +{ + if (unlinkat(attrdirfd, name, 0) == -1) { + if (errno == ENOENT) { + errno = ENOATTR; + } + return -1; + } + return 0; +} + +static int solaris_attropen(const char *path, const char *attrpath, int oflag, mode_t mode) +{ + int filedes = attropen(path, attrpath, oflag, mode); + if (filedes == -1) { + DEBUG(10,("attropen FAILED: path: %s, name: %s, errno: %s\n",path,attrpath,strerror(errno))); + if (errno == EINVAL) { + errno = ENOTSUP; + } else { + errno = ENOATTR; + } + } + return filedes; +} + +static int solaris_openat(int fildes, const char *path, int oflag, mode_t mode) +{ + int filedes = openat(fildes, path, oflag, mode); + if (filedes == -1) { + DEBUG(10,("openat FAILED: fd: %s, path: %s, errno: %s\n",filedes,path,strerror(errno))); + if (errno == EINVAL) { + errno = ENOTSUP; + } else { + errno = ENOATTR; + } + } + return filedes; +} + +static int solaris_write_xattr(int attrfd, const char *value, size_t size) +{ + if ((ftruncate(attrfd, 0) == 0) && (write(attrfd, value, size) == size)) { + return 0; + } else { + DEBUG(10,("solaris_write_xattr FAILED!\n")); + return -1; + } +} +#endif /*HAVE_ATTROPEN*/ + /**************************************************************************** Return the major devicenumber for UNIX extensions. ****************************************************************************/ diff --git a/source/lib/system_smbd.c b/source/lib/system_smbd.c index ffdd8eeed00..509b2bbcb1e 100644 --- a/source/lib/system_smbd.c +++ b/source/lib/system_smbd.c @@ -104,10 +104,12 @@ static int getgrouplist_internals(const char *user, gid_t gid, gid_t *groups, restore_re_gid(); - if (sys_setgroups(gid, ngrp_saved, gids_saved) != 0) { + if (sys_setgroups(ngrp_saved, gids_saved) != 0) { /* yikes! */ DEBUG(0,("ERROR: getgrouplist: failed to reset group list!\n")); - smb_panic("getgrouplist: failed to reset group list!"); + smb_panic("getgrouplist: failed to reset group list!\n"); + free(gids_saved); + return -1; } free(gids_saved); @@ -154,7 +156,7 @@ BOOL getgroups_unix_user(TALLOC_CTX *mem_ctx, const char *user, gid_t *groups; int i; - max_grp = MIN(32, groups_max()); + max_grp = groups_max(); temp_groups = SMB_MALLOC_ARRAY(gid_t, max_grp); if (! temp_groups) { return False; diff --git a/source/lib/talloc/Makefile.in b/source/lib/talloc/Makefile.in index 18b48c34598..14e81156921 100644 --- a/source/lib/talloc/Makefile.in +++ b/source/lib/talloc/Makefile.in @@ -12,12 +12,12 @@ builddir = @builddir@ XSLTPROC = @XSLTPROC@ INSTALLCMD = @INSTALL@ CC = @CC@ -CFLAGS = @CFLAGS@ -DHAVE_CONFIG_H= -I. -I@srcdir@ +CFLAGS = @CFLAGS@ -DHAVE_CONFIG_H= -I. -I@srcdir@ -I@libreplacedir@ EXTRA_TARGETS = @DOC_TARGET@ .SUFFIXES: .c .o .3 .3.xml .xml .html -LIBOBJ = @TALLOC_OBJ@ @LIBREPLACEOBJ@ +LIBOBJ = @TALLOCOBJ@ @LIBREPLACEOBJ@ all: showflags libtalloc.a testsuite $(EXTRA_TARGETS) @@ -34,14 +34,13 @@ libtalloc.a: $(LIBOBJ) @-ranlib $@ install: all - ${INSTALLCMD} -d $(DESTDIR)$(libdir) - ${INSTALLCMD} -d $(DESTDIR)$(libdir)/pkgconfig - ${INSTALLCMD} -m 755 libtalloc.a $(DESTDIR)$(libdir) - ${INSTALLCMD} -d $(DESTDIR)${includedir} - ${INSTALLCMD} -m 644 $(srcdir)/talloc.h $(DESTDIR)$(includedir) - ${INSTALLCMD} -m 644 talloc.pc $(DESTDIR)$(libdir)/pkgconfig - if [ -f talloc.3 ];then ${INSTALLCMD} -d $(DESTDIR)$(mandir)/man3; fi - if [ -f talloc.3 ];then ${INSTALLCMD} -m 644 talloc.3 $(DESTDIR)$(mandir)/man3; fi + ${INSTALLCMD} -d ${libdir} + ${INSTALLCMD} -m 755 libtalloc.a $(libdir) + ${INSTALLCMD} -d ${includedir} + ${INSTALLCMD} -m 644 $(srcdir)/talloc.h $(includedir) + ${INSTALLCMD} -m 644 talloc.pc $(libdir)/pkgconfig + if [ -f talloc.3 ];then ${INSTALLCMD} -d ${mandir}/man3; fi + if [ -f talloc.3 ];then ${INSTALLCMD} -m 644 talloc.3 $(mandir)/man3; fi doc: talloc.3 talloc.3.html diff --git a/source/lib/talloc/config.mk b/source/lib/talloc/config.mk index 714ad72d1cd..0b06687dabd 100644 --- a/source/lib/talloc/config.mk +++ b/source/lib/talloc/config.mk @@ -11,3 +11,8 @@ DESCRIPTION = A hierarchical pool based memory system with destructors # # End LIBRARY LIBTALLOC ################################################ + +[BINARY::TALLOC] +OBJ_FILES = testsuite.o +PRIVATE_DEPENDENCIES = LIBTALLOC +INSTALLDIR = TORTUREDIR/LOCAL diff --git a/source/lib/talloc/configure.ac b/source/lib/talloc/configure.ac index 5f465fe93ab..51e7256bf88 100644 --- a/source/lib/talloc/configure.ac +++ b/source/lib/talloc/configure.ac @@ -1,5 +1,5 @@ AC_PREREQ(2.50) -AC_INIT(talloc, 1.0) +AC_INIT(talloc.h) AC_CONFIG_SRCDIR([talloc.c]) AC_SUBST(datarootdir) AC_CONFIG_HEADER(config.h) diff --git a/source/lib/talloc/libtalloc.m4 b/source/lib/talloc/libtalloc.m4 index d2e8eba81a4..4a0ee3c8fc5 100644 --- a/source/lib/talloc/libtalloc.m4 +++ b/source/lib/talloc/libtalloc.m4 @@ -12,14 +12,8 @@ done if test x"$tallocdir" = "x"; then AC_MSG_ERROR([cannot find talloc source in $tallocpaths]) fi -TALLOC_OBJ="talloc.o" -AC_SUBST(TALLOC_OBJ) - -TALLOC_CFLAGS="-I$tallocdir" -AC_SUBST(TALLOC_CFLAGS) - -TALLOC_LIBS="" -AC_SUBST(TALLOC_LIBS) +TALLOCOBJ="talloc.o" +AC_SUBST(TALLOCOBJ) AC_CHECK_SIZEOF(size_t,cross) AC_CHECK_SIZEOF(void *,cross) diff --git a/source/lib/talloc/talloc.3.xml b/source/lib/talloc/talloc.3.xml index 83ca67a4951..2400fef2dc5 100644 --- a/source/lib/talloc/talloc.3.xml +++ b/source/lib/talloc/talloc.3.xml @@ -583,27 +583,11 @@ if (ptr) memcpy(ptr, p, strlen(p)+1);</programlisting> </para> <programlisting>talloc_set_name_const(ptr, ptr)</programlisting> </refsect2> - <refsect2><title>char *talloc_append_string(const void *<emphasis role="italic">t</emphasis>, char *<emphasis role="italic">orig</emphasis>, const char *<emphasis role="italic">append</emphasis>);</title> - <para> - The talloc_append_string() function appends the given formatted - string to the given string. - </para> - <para> - This function sets the name of the new pointer to the new - string. This is equivalent to: - </para> - <programlisting>talloc_set_name_const(ptr, ptr)</programlisting> - </refsect2> <refsect2><title>char *talloc_vasprintf(const void *<emphasis role="italic">t</emphasis>, const char *<emphasis role="italic">fmt</emphasis>, va_list <emphasis role="italic">ap</emphasis>);</title> <para> The talloc_vasprintf() function is the talloc equivalent of the C library function vasprintf(3). </para> - <para> - This function sets the name of the new pointer to the new - string. This is equivalent to: - </para> - <programlisting>talloc_set_name_const(ptr, ptr)</programlisting> </refsect2> <refsect2><title>char *talloc_asprintf(const void *<emphasis role="italic">t</emphasis>, const char *<emphasis role="italic">fmt</emphasis>, ...);</title> <para> @@ -621,11 +605,6 @@ if (ptr) memcpy(ptr, p, strlen(p)+1);</programlisting> The talloc_asprintf_append() function appends the given formatted string to the given string. </para> - <para> - This function sets the name of the new pointer to the new - string. This is equivalent to: - </para> - <programlisting>talloc_set_name_const(ptr, ptr)</programlisting> </refsect2> <refsect2><title>(type *)talloc_array(const void *ctx, type, uint_t count);</title> <para> diff --git a/source/lib/talloc/talloc.c b/source/lib/talloc/talloc.c index abc1e9438e6..b2b00d8c65a 100644 --- a/source/lib/talloc/talloc.c +++ b/source/lib/talloc/talloc.c @@ -1137,8 +1137,6 @@ char *talloc_append_string(const void *t, char *orig, const char *append) /* append the string with the trailing \0 */ memcpy(&ret[olen], append, alenz); - _talloc_set_name_const(ret, ret); - return ret; } diff --git a/source/lib/talloc/talloc.h b/source/lib/talloc/talloc.h index d9e7d943387..9ef8724dc32 100644 --- a/source/lib/talloc/talloc.h +++ b/source/lib/talloc/talloc.h @@ -26,10 +26,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <stdlib.h> -#include <stdio.h> -#include <stdarg.h> - /* this is only needed for compatibility with the old talloc */ typedef void TALLOC_CTX; diff --git a/source/lib/talloc/talloc.pc.in b/source/lib/talloc/talloc.pc.in index 459cce70b1d..7f9ef754cbd 100644 --- a/source/lib/talloc/talloc.pc.in +++ b/source/lib/talloc/talloc.pc.in @@ -5,7 +5,6 @@ includedir=@includedir@ Name: talloc Description: A hierarchical pool based memory system with destructors -Version: @PACKAGE_VERSION@ -Libs: -L${libdir} -ltalloc -Cflags: -I${includedir} -URL: http://talloc.samba.org/ +Version: 4.0 +Libs: @LIBS@ -L${libdir} -ltalloc +Cflags: -I${includedir} @CFLAGS@ diff --git a/source/lib/talloc/talloc_guide.txt b/source/lib/talloc/talloc_guide.txt index c4634ae19a9..8b252e4ab9b 100644 --- a/source/lib/talloc/talloc_guide.txt +++ b/source/lib/talloc/talloc_guide.txt @@ -12,7 +12,7 @@ this carefully, as talloc has changed a lot. With 3.0.20 (or 3.0.14?) the Samba4 talloc has been ported back to Samba3, so this guide applies to both. The new talloc is a hierarchical, reference counted memory pool system -with destructors. Quite a mouthful really, but not too bad once you +with destructors. Quite a mounthful really, but not too bad once you get used to it. Perhaps the biggest change from Samba3 is that there is no distinction @@ -533,15 +533,6 @@ This functions sets the name of the new pointer to the passed string. This is equivalent to: talloc_set_name_const(ptr, ptr) -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -char *talloc_append_string(const void *t, char *orig, const char *append); - -The talloc_append_string() function appends the given formatted -string to the given string. - -This function sets the name of the new pointer to the new -string. This is equivalent to: - talloc_set_name_const(ptr, ptr) =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- char *talloc_vasprintf(const void *t, const char *fmt, va_list ap); @@ -549,10 +540,6 @@ char *talloc_vasprintf(const void *t, const char *fmt, va_list ap); The talloc_vasprintf() function is the talloc equivalent of the C library function vasprintf() -This functions sets the name of the new pointer to the new -string. This is equivalent to: - talloc_set_name_const(ptr, ptr) - =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- char *talloc_asprintf(const void *t, const char *fmt, ...); @@ -560,7 +547,7 @@ char *talloc_asprintf(const void *t, const char *fmt, ...); The talloc_asprintf() function is the talloc equivalent of the C library function asprintf() -This functions sets the name of the new pointer to the new +This functions sets the name of the new pointer to the passed string. This is equivalent to: talloc_set_name_const(ptr, ptr) @@ -571,10 +558,6 @@ char *talloc_asprintf_append(char *s, const char *fmt, ...); The talloc_asprintf_append() function appends the given formatted string to the given string. -This functions sets the name of the new pointer to the new -string. This is equivalent to: - talloc_set_name_const(ptr, ptr) - =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- (type *)talloc_array(const void *ctx, type, uint_t count); diff --git a/source/lib/talloc/testsuite.c b/source/lib/talloc/testsuite.c index 587f270553d..f51252e57bc 100644 --- a/source/lib/talloc/testsuite.c +++ b/source/lib/talloc/testsuite.c @@ -993,7 +993,7 @@ static bool test_talloc_ptrtype(void) s4 = talloc_array_ptrtype(top, s4, 10);location4 = __location__; if (talloc_get_size(s4) != (sizeof(struct struct1 **) * 10)) { - printf("failure: ptrtype [\n" + printf("failure: TALLOC PTRTYPE [\n" "talloc_array_ptrtype() allocated the wrong size " "%lu (should be %lu)\n]\n", (unsigned long)talloc_get_size(s4), @@ -1010,49 +1010,8 @@ static bool test_talloc_ptrtype(void) return true; } -static int _test_talloc_free_in_destructor(void **ptr) -{ - talloc_free(*ptr); - return 0; -} - -static bool test_talloc_free_in_destructor(void) -{ - void *level0; - void *level1; - void *level2; - void *level3; - void *level4; - void **level5; - - printf("test: free_in_destructor [\nTALLOC FREE IN DESTRUCTOR\n]\n"); - - level0 = talloc_new(NULL); - level1 = talloc_new(level0); - level2 = talloc_new(level1); - level3 = talloc_new(level2); - level4 = talloc_new(level3); - level5 = talloc(level4, void *); - - *level5 = level3; - (void)talloc_reference(level0, level3); - (void)talloc_reference(level3, level3); - (void)talloc_reference(level5, level3); - - talloc_set_destructor(level5, _test_talloc_free_in_destructor); - - talloc_free(level1); - - talloc_free(level0); - - printf("success: free_in_destructor\n"); - return true; -} - static bool test_autofree(void) { -#if _SAMBA_BUILD_ < 4 - /* autofree test would kill smbtorture */ void *p; printf("test: autofree [\nTALLOC AUTOFREE CONTEXT\n]\n"); @@ -1063,17 +1022,13 @@ static bool test_autofree(void) talloc_free(p); printf("success: autofree\n"); -#endif return true; } -struct torture_context; -bool torture_local_talloc(struct torture_context *tctx) +int main(void) { bool ret = true; - setlinebuf(stdout); - talloc_disable_null_tracking(); talloc_enable_null_tracking(); @@ -1094,22 +1049,13 @@ bool torture_local_talloc(struct torture_context *tctx) ret &= test_loop(); ret &= test_free_parent_deny_child(); ret &= test_talloc_ptrtype(); - ret &= test_talloc_free_in_destructor(); if (ret) { ret &= test_speed(); } ret &= test_autofree(); - return ret; -} - -#if _SAMBA_BUILD_ < 4 -int main(void) -{ - bool ret = torture_local_talloc(NULL); if (!ret) return -1; return 0; } -#endif diff --git a/source/lib/tallocmsg.c b/source/lib/tallocmsg.c index f5160125aaa..0f493538f3c 100644 --- a/source/lib/tallocmsg.c +++ b/source/lib/tallocmsg.c @@ -65,11 +65,9 @@ static void msg_pool_usage_helper(const void *ptr, int depth, int max_depth, int * Respond to a POOL_USAGE message by sending back string form of memory * usage stats. **/ -static void msg_pool_usage(struct messaging_context *msg_ctx, - void *private_data, - uint32_t msg_type, - struct server_id src, - DATA_BLOB *data) +void msg_pool_usage(int msg_type, struct process_id src_pid, + void *UNUSED(buf), size_t UNUSED(len), + void *private_data) { struct msg_pool_usage_state state; @@ -92,8 +90,8 @@ static void msg_pool_usage(struct messaging_context *msg_ctx, return; } - messaging_send_buf(msg_ctx, src, MSG_POOL_USAGE, - (uint8 *)state.s, strlen(state.s)+1); + message_send_pid(src_pid, MSG_POOL_USAGE, + state.s, strlen(state.s)+1, True); talloc_destroy(state.mem_ctx); } @@ -101,8 +99,8 @@ static void msg_pool_usage(struct messaging_context *msg_ctx, /** * Register handler for MSG_REQ_POOL_USAGE **/ -void register_msg_pool_usage(struct messaging_context *msg_ctx) +void register_msg_pool_usage(void) { - messaging_register(msg_ctx, NULL, MSG_REQ_POOL_USAGE, msg_pool_usage); + message_register(MSG_REQ_POOL_USAGE, msg_pool_usage, NULL); DEBUG(2, ("Registered MSG_REQ_POOL_USAGE\n")); } diff --git a/source/lib/tdb/Makefile.in b/source/lib/tdb/Makefile.in deleted file mode 100644 index b2f42ea70fb..00000000000 --- a/source/lib/tdb/Makefile.in +++ /dev/null @@ -1,89 +0,0 @@ -#!gmake -# -# Makefile for tdb directory -# - -CC = @CC@ -prefix = @prefix@ -exec_prefix = @exec_prefix@ -bindir = @bindir@ -includedir = @includedir@ -libdir = @libdir@ -VPATH = @srcdir@:@libreplacedir@ -srcdir = @srcdir@ -builddir = @builddir@ -CPPFLAGS = @CPPFLAGS@ -I$(srcdir)/include -Iinclude -I@libreplacedir@ -CFLAGS = $(CPPFLAGS) @CFLAGS@ -LDFLAGS = @LDFLAGS@ -EXEEXT = @EXEEXT@ - -.PHONY: test - -PROGS = bin/tdbtool$(EXEEXT) bin/tdbdump$(EXEEXT) bin/tdbbackup$(EXEEXT) -PROGS_NOINSTALL = bin/tdbtest$(EXEEXT) bin/tdbtorture$(EXEEXT) -ALL_PROGS = $(PROGS) $(PROGS_NOINSTALL) - -TDB_OBJ = @TDBOBJ@ @LIBREPLACEOBJ@ - -DIRS = bin common tools - -all: showflags dirs $(PROGS) - -showflags: - @echo 'tdb will be compiled with flags:' - @echo ' CFLAGS = $(CFLAGS)' - @echo ' CPPFLAGS = $(CPPFLAGS)' - @echo ' LDFLAGS = $(LDFLAGS)' - @echo ' LIBS = $(LIBS)' - -.c.o: - @echo Compiling $*.c - @mkdir -p `dirname $@` - @$(CC) $(CFLAGS) -c $< -o $@ - -dirs: - @mkdir -p $(DIRS) - -install: all - mkdir -p $(bindir) - mkdir -p $(includedir) - mkdir -p $(libdir) - mkdir -p $(libdir)/pkgconfig - cp $(PROGS) $(bindir) - cp $(srcdir)/include/tdb.h $(includedir) - cp tdb.pc $(libdir)/pkgconfig - -libtdb.a: $(TDB_OBJ) - ar -rv libtdb.a $(TDB_OBJ) - -bin/tdbtest$(EXEEXT): tools/tdbtest.o libtdb.a - $(CC) $(CFLAGS) $(LDFLAGS) -o bin/tdbtest tools/tdbtest.o -L. -ltdb -lgdbm - -bin/tdbtool$(EXEEXT): tools/tdbtool.o libtdb.a - $(CC) $(CFLAGS) $(LDFLAGS) -o bin/tdbtool tools/tdbtool.o -L. -ltdb - -bin/tdbtorture$(EXEEXT): tools/tdbtorture.o libtdb.a - $(CC) $(CFLAGS) $(LDFLAGS) -o bin/tdbtorture tools/tdbtorture.o -L. -ltdb - -bin/tdbdump$(EXEEXT): tools/tdbdump.o libtdb.a - $(CC) $(CFLAGS) $(LDFLAGS) -o bin/tdbdump tools/tdbdump.o -L. -ltdb - -bin/tdbbackup$(EXEEXT): tools/tdbbackup.o libtdb.a - $(CC) $(CFLAGS) $(LDFLAGS) -o bin/tdbbackup tools/tdbbackup.o -L. -ltdb - -test: bin/tdbtorture$(EXEEXT) - bin/tdbtorture$(EXEEXT) - -installcheck: test install - -clean: - rm -f $(ALL_PROGS) *.o *.a common/*.o tools/*.o tdb.pc - rm -f test.db test.tdb torture.tdb test.gdbm - -distclean: clean - rm -f *~ */*~ - rm -f config.log config.status include/config.h config.cache - rm -f Makefile - -realdistclean: distclean - rm -f configure include/config.h.in diff --git a/source/lib/tdb/aclocal.m4 b/source/lib/tdb/aclocal.m4 deleted file mode 100644 index 5605e476bab..00000000000 --- a/source/lib/tdb/aclocal.m4 +++ /dev/null @@ -1 +0,0 @@ -m4_include(libreplace.m4) diff --git a/source/lib/tdb/autogen.sh b/source/lib/tdb/autogen.sh deleted file mode 100755 index bf84eeee19a..00000000000 --- a/source/lib/tdb/autogen.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -rm -rf autom4te.cache -rm -f configure config.h.in - -IPATHS="-I libreplace -I lib/replace -I ../libreplace -I ../replace" -autoconf $IPATHS || exit 1 -autoheader $IPATHS || exit 1 - -rm -rf autom4te.cache - -echo "Now run ./configure and then make." -exit 0 - diff --git a/source/lib/tdb/common/dump.c b/source/lib/tdb/common/dump.c deleted file mode 100644 index 3f5c2c87f5b..00000000000 --- a/source/lib/tdb/common/dump.c +++ /dev/null @@ -1,138 +0,0 @@ - /* - Unix SMB/CIFS implementation. - - trivial database library - - Copyright (C) Andrew Tridgell 1999-2005 - Copyright (C) Paul `Rusty' Russell 2000 - Copyright (C) Jeremy Allison 2000-2003 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include "tdb_private.h" - -static tdb_off_t tdb_dump_record(struct tdb_context *tdb, int hash, - tdb_off_t offset) -{ - struct list_struct rec; - tdb_off_t tailer_ofs, tailer; - - if (tdb->methods->tdb_read(tdb, offset, (char *)&rec, - sizeof(rec), DOCONV()) == -1) { - printf("ERROR: failed to read record at %u\n", offset); - return 0; - } - - printf(" rec: hash=%d offset=0x%08x next=0x%08x rec_len=%d " - "key_len=%d data_len=%d full_hash=0x%x magic=0x%x\n", - hash, offset, rec.next, rec.rec_len, rec.key_len, rec.data_len, - rec.full_hash, rec.magic); - - tailer_ofs = offset + sizeof(rec) + rec.rec_len - sizeof(tdb_off_t); - - if (tdb_ofs_read(tdb, tailer_ofs, &tailer) == -1) { - printf("ERROR: failed to read tailer at %u\n", tailer_ofs); - return rec.next; - } - - if (tailer != rec.rec_len + sizeof(rec)) { - printf("ERROR: tailer does not match record! tailer=%u totalsize=%u\n", - (unsigned int)tailer, (unsigned int)(rec.rec_len + sizeof(rec))); - } - return rec.next; -} - -static int tdb_dump_chain(struct tdb_context *tdb, int i) -{ - tdb_off_t rec_ptr, top; - - top = TDB_HASH_TOP(i); - - if (tdb_lock(tdb, i, F_WRLCK) != 0) - return -1; - - if (tdb_ofs_read(tdb, top, &rec_ptr) == -1) - return tdb_unlock(tdb, i, F_WRLCK); - - if (rec_ptr) - printf("hash=%d\n", i); - - while (rec_ptr) { - rec_ptr = tdb_dump_record(tdb, i, rec_ptr); - } - - return tdb_unlock(tdb, i, F_WRLCK); -} - -void tdb_dump_all(struct tdb_context *tdb) -{ - int i; - for (i=0;i<tdb->header.hash_size;i++) { - tdb_dump_chain(tdb, i); - } - printf("freelist:\n"); - tdb_dump_chain(tdb, -1); -} - -int tdb_printfreelist(struct tdb_context *tdb) -{ - int ret; - long total_free = 0; - tdb_off_t offset, rec_ptr; - struct list_struct rec; - - if ((ret = tdb_lock(tdb, -1, F_WRLCK)) != 0) - return ret; - - offset = FREELIST_TOP; - - /* read in the freelist top */ - if (tdb_ofs_read(tdb, offset, &rec_ptr) == -1) { - tdb_unlock(tdb, -1, F_WRLCK); - return 0; - } - - printf("freelist top=[0x%08x]\n", rec_ptr ); - while (rec_ptr) { - if (tdb->methods->tdb_read(tdb, rec_ptr, (char *)&rec, - sizeof(rec), DOCONV()) == -1) { - tdb_unlock(tdb, -1, F_WRLCK); - return -1; - } - - if (rec.magic != TDB_FREE_MAGIC) { - printf("bad magic 0x%08x in free list\n", rec.magic); - tdb_unlock(tdb, -1, F_WRLCK); - return -1; - } - - printf("entry offset=[0x%08x], rec.rec_len = [0x%08x (%d)] (end = 0x%08x)\n", - rec_ptr, rec.rec_len, rec.rec_len, rec_ptr + rec.rec_len); - total_free += rec.rec_len; - - /* move to the next record */ - rec_ptr = rec.next; - } - printf("total rec_len = [0x%08x (%d)]\n", (int)total_free, - (int)total_free); - - return tdb_unlock(tdb, -1, F_WRLCK); -} - diff --git a/source/lib/tdb/common/error.c b/source/lib/tdb/common/error.c deleted file mode 100644 index ddc810e93d2..00000000000 --- a/source/lib/tdb/common/error.c +++ /dev/null @@ -1,58 +0,0 @@ - /* - Unix SMB/CIFS implementation. - - trivial database library - - Copyright (C) Andrew Tridgell 1999-2005 - Copyright (C) Paul `Rusty' Russell 2000 - Copyright (C) Jeremy Allison 2000-2003 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include "tdb_private.h" - -enum TDB_ERROR tdb_error(struct tdb_context *tdb) -{ - return tdb->ecode; -} - -static struct tdb_errname { - enum TDB_ERROR ecode; const char *estring; -} emap[] = { {TDB_SUCCESS, "Success"}, - {TDB_ERR_CORRUPT, "Corrupt database"}, - {TDB_ERR_IO, "IO Error"}, - {TDB_ERR_LOCK, "Locking error"}, - {TDB_ERR_OOM, "Out of memory"}, - {TDB_ERR_EXISTS, "Record exists"}, - {TDB_ERR_NOLOCK, "Lock exists on other keys"}, - {TDB_ERR_EINVAL, "Invalid parameter"}, - {TDB_ERR_NOEXIST, "Record does not exist"}, - {TDB_ERR_RDONLY, "write not permitted"} }; - -/* Error string for the last tdb error */ -const char *tdb_errorstr(struct tdb_context *tdb) -{ - uint32_t i; - for (i = 0; i < sizeof(emap) / sizeof(struct tdb_errname); i++) - if (tdb->ecode == emap[i].ecode) - return emap[i].estring; - return "Invalid error code"; -} - diff --git a/source/lib/tdb/common/freelist.c b/source/lib/tdb/common/freelist.c deleted file mode 100644 index 01b61aff865..00000000000 --- a/source/lib/tdb/common/freelist.c +++ /dev/null @@ -1,331 +0,0 @@ - /* - Unix SMB/CIFS implementation. - - trivial database library - - Copyright (C) Andrew Tridgell 1999-2005 - Copyright (C) Paul `Rusty' Russell 2000 - Copyright (C) Jeremy Allison 2000-2003 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include "tdb_private.h" - -/* read a freelist record and check for simple errors */ -int tdb_rec_free_read(struct tdb_context *tdb, tdb_off_t off, struct list_struct *rec) -{ - if (tdb->methods->tdb_read(tdb, off, rec, sizeof(*rec),DOCONV()) == -1) - return -1; - - if (rec->magic == TDB_MAGIC) { - /* this happens when a app is showdown while deleting a record - we should - not completely fail when this happens */ - TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_rec_free_read non-free magic 0x%x at offset=%d - fixing\n", - rec->magic, off)); - rec->magic = TDB_FREE_MAGIC; - if (tdb->methods->tdb_write(tdb, off, rec, sizeof(*rec)) == -1) - return -1; - } - - if (rec->magic != TDB_FREE_MAGIC) { - /* Ensure ecode is set for log fn. */ - tdb->ecode = TDB_ERR_CORRUPT; - TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_rec_free_read bad magic 0x%x at offset=%d\n", - rec->magic, off)); - return TDB_ERRCODE(TDB_ERR_CORRUPT, -1); - } - if (tdb->methods->tdb_oob(tdb, rec->next+sizeof(*rec), 0) != 0) - return -1; - return 0; -} - - - -/* Remove an element from the freelist. Must have alloc lock. */ -static int remove_from_freelist(struct tdb_context *tdb, tdb_off_t off, tdb_off_t next) -{ - tdb_off_t last_ptr, i; - - /* read in the freelist top */ - last_ptr = FREELIST_TOP; - while (tdb_ofs_read(tdb, last_ptr, &i) != -1 && i != 0) { - if (i == off) { - /* We've found it! */ - return tdb_ofs_write(tdb, last_ptr, &next); - } - /* Follow chain (next offset is at start of record) */ - last_ptr = i; - } - TDB_LOG((tdb, TDB_DEBUG_FATAL,"remove_from_freelist: not on list at off=%d\n", off)); - return TDB_ERRCODE(TDB_ERR_CORRUPT, -1); -} - - -/* update a record tailer (must hold allocation lock) */ -static int update_tailer(struct tdb_context *tdb, tdb_off_t offset, - const struct list_struct *rec) -{ - tdb_off_t totalsize; - - /* Offset of tailer from record header */ - totalsize = sizeof(*rec) + rec->rec_len; - return tdb_ofs_write(tdb, offset + totalsize - sizeof(tdb_off_t), - &totalsize); -} - -/* Add an element into the freelist. Merge adjacent records if - neccessary. */ -int tdb_free(struct tdb_context *tdb, tdb_off_t offset, struct list_struct *rec) -{ - tdb_off_t right, left; - - /* Allocation and tailer lock */ - if (tdb_lock(tdb, -1, F_WRLCK) != 0) - return -1; - - /* set an initial tailer, so if we fail we don't leave a bogus record */ - if (update_tailer(tdb, offset, rec) != 0) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: update_tailer failed!\n")); - goto fail; - } - - /* Look right first (I'm an Australian, dammit) */ - right = offset + sizeof(*rec) + rec->rec_len; - if (right + sizeof(*rec) <= tdb->map_size) { - struct list_struct r; - - if (tdb->methods->tdb_read(tdb, right, &r, sizeof(r), DOCONV()) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: right read failed at %u\n", right)); - goto left; - } - - /* If it's free, expand to include it. */ - if (r.magic == TDB_FREE_MAGIC) { - if (remove_from_freelist(tdb, right, r.next) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: right free failed at %u\n", right)); - goto left; - } - rec->rec_len += sizeof(r) + r.rec_len; - } - } - -left: - /* Look left */ - left = offset - sizeof(tdb_off_t); - if (left > TDB_DATA_START(tdb->header.hash_size)) { - struct list_struct l; - tdb_off_t leftsize; - - /* Read in tailer and jump back to header */ - if (tdb_ofs_read(tdb, left, &leftsize) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: left offset read failed at %u\n", left)); - goto update; - } - - /* it could be uninitialised data */ - if (leftsize == 0 || leftsize == TDB_PAD_U32) { - goto update; - } - - left = offset - leftsize; - - /* Now read in record */ - if (tdb->methods->tdb_read(tdb, left, &l, sizeof(l), DOCONV()) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: left read failed at %u (%u)\n", left, leftsize)); - goto update; - } - - /* If it's free, expand to include it. */ - if (l.magic == TDB_FREE_MAGIC) { - if (remove_from_freelist(tdb, left, l.next) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: left free failed at %u\n", left)); - goto update; - } else { - offset = left; - rec->rec_len += leftsize; - } - } - } - -update: - if (update_tailer(tdb, offset, rec) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: update_tailer failed at %u\n", offset)); - goto fail; - } - - /* Now, prepend to free list */ - rec->magic = TDB_FREE_MAGIC; - - if (tdb_ofs_read(tdb, FREELIST_TOP, &rec->next) == -1 || - tdb_rec_write(tdb, offset, rec) == -1 || - tdb_ofs_write(tdb, FREELIST_TOP, &offset) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free record write failed at offset=%d\n", offset)); - goto fail; - } - - /* And we're done. */ - tdb_unlock(tdb, -1, F_WRLCK); - return 0; - - fail: - tdb_unlock(tdb, -1, F_WRLCK); - return -1; -} - - -/* - the core of tdb_allocate - called when we have decided which - free list entry to use - */ -static tdb_off_t tdb_allocate_ofs(struct tdb_context *tdb, tdb_len_t length, tdb_off_t rec_ptr, - struct list_struct *rec, tdb_off_t last_ptr) -{ - struct list_struct newrec; - tdb_off_t newrec_ptr; - - memset(&newrec, '\0', sizeof(newrec)); - - /* found it - now possibly split it up */ - if (rec->rec_len > length + MIN_REC_SIZE) { - /* Length of left piece */ - length = TDB_ALIGN(length, TDB_ALIGNMENT); - - /* Right piece to go on free list */ - newrec.rec_len = rec->rec_len - (sizeof(*rec) + length); - newrec_ptr = rec_ptr + sizeof(*rec) + length; - - /* And left record is shortened */ - rec->rec_len = length; - } else { - newrec_ptr = 0; - } - - /* Remove allocated record from the free list */ - if (tdb_ofs_write(tdb, last_ptr, &rec->next) == -1) { - return 0; - } - - /* Update header: do this before we drop alloc - lock, otherwise tdb_free() might try to - merge with us, thinking we're free. - (Thanks Jeremy Allison). */ - rec->magic = TDB_MAGIC; - if (tdb_rec_write(tdb, rec_ptr, rec) == -1) { - return 0; - } - - /* Did we create new block? */ - if (newrec_ptr) { - /* Update allocated record tailer (we - shortened it). */ - if (update_tailer(tdb, rec_ptr, rec) == -1) { - return 0; - } - - /* Free new record */ - if (tdb_free(tdb, newrec_ptr, &newrec) == -1) { - return 0; - } - } - - /* all done - return the new record offset */ - return rec_ptr; -} - -/* allocate some space from the free list. The offset returned points - to a unconnected list_struct within the database with room for at - least length bytes of total data - - 0 is returned if the space could not be allocated - */ -tdb_off_t tdb_allocate(struct tdb_context *tdb, tdb_len_t length, struct list_struct *rec) -{ - tdb_off_t rec_ptr, last_ptr, newrec_ptr; - struct { - tdb_off_t rec_ptr, last_ptr; - tdb_len_t rec_len; - } bestfit; - - if (tdb_lock(tdb, -1, F_WRLCK) == -1) - return 0; - - /* Extra bytes required for tailer */ - length += sizeof(tdb_off_t); - - again: - last_ptr = FREELIST_TOP; - - /* read in the freelist top */ - if (tdb_ofs_read(tdb, FREELIST_TOP, &rec_ptr) == -1) - goto fail; - - bestfit.rec_ptr = 0; - bestfit.last_ptr = 0; - bestfit.rec_len = 0; - - /* - this is a best fit allocation strategy. Originally we used - a first fit strategy, but it suffered from massive fragmentation - issues when faced with a slowly increasing record size. - */ - while (rec_ptr) { - if (tdb_rec_free_read(tdb, rec_ptr, rec) == -1) { - goto fail; - } - - if (rec->rec_len >= length) { - if (bestfit.rec_ptr == 0 || - rec->rec_len < bestfit.rec_len) { - bestfit.rec_len = rec->rec_len; - bestfit.rec_ptr = rec_ptr; - bestfit.last_ptr = last_ptr; - /* consider a fit to be good enough if - we aren't wasting more than half - the space */ - if (bestfit.rec_len < 2*length) { - break; - } - } - } - - /* move to the next record */ - last_ptr = rec_ptr; - rec_ptr = rec->next; - } - - if (bestfit.rec_ptr != 0) { - if (tdb_rec_free_read(tdb, bestfit.rec_ptr, rec) == -1) { - goto fail; - } - - newrec_ptr = tdb_allocate_ofs(tdb, length, bestfit.rec_ptr, rec, bestfit.last_ptr); - tdb_unlock(tdb, -1, F_WRLCK); - return newrec_ptr; - } - - /* we didn't find enough space. See if we can expand the - database and if we can then try again */ - if (tdb_expand(tdb, length + sizeof(*rec)) == 0) - goto again; - fail: - tdb_unlock(tdb, -1, F_WRLCK); - return 0; -} - diff --git a/source/lib/tdb/common/freelistcheck.c b/source/lib/tdb/common/freelistcheck.c deleted file mode 100644 index 19368f6ad6e..00000000000 --- a/source/lib/tdb/common/freelistcheck.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - trivial database library - - Copyright (C) Jeremy Allison 2006 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include "tdb_private.h" - -/* Check the freelist is good and contains no loops. - Very memory intensive - only do this as a consistency - checker. Heh heh - uses an in memory tdb as the storage - for the "seen" record list. For some reason this strikes - me as extremely clever as I don't have to write another tree - data structure implementation :-). - */ - -static int seen_insert(struct tdb_context *mem_tdb, tdb_off_t rec_ptr) -{ - TDB_DATA key, data; - - memset(&data, '\0', sizeof(data)); - key.dptr = (unsigned char *)&rec_ptr; - key.dsize = sizeof(rec_ptr); - return tdb_store(mem_tdb, key, data, TDB_INSERT); -} - -int tdb_validate_freelist(struct tdb_context *tdb, int *pnum_entries) -{ - struct tdb_context *mem_tdb = NULL; - struct list_struct rec; - tdb_off_t rec_ptr, last_ptr; - int ret = -1; - - *pnum_entries = 0; - - mem_tdb = tdb_open("flval", tdb->header.hash_size, - TDB_INTERNAL, O_RDWR, 0600); - if (!mem_tdb) { - return -1; - } - - if (tdb_lock(tdb, -1, F_WRLCK) == -1) { - tdb_close(mem_tdb); - return 0; - } - - last_ptr = FREELIST_TOP; - - /* Store the FREELIST_TOP record. */ - if (seen_insert(mem_tdb, last_ptr) == -1) { - ret = TDB_ERRCODE(TDB_ERR_CORRUPT, -1); - goto fail; - } - - /* read in the freelist top */ - if (tdb_ofs_read(tdb, FREELIST_TOP, &rec_ptr) == -1) { - goto fail; - } - - while (rec_ptr) { - - /* If we can't store this record (we've seen it - before) then the free list has a loop and must - be corrupt. */ - - if (seen_insert(mem_tdb, rec_ptr)) { - ret = TDB_ERRCODE(TDB_ERR_CORRUPT, -1); - goto fail; - } - - if (tdb_rec_free_read(tdb, rec_ptr, &rec) == -1) { - goto fail; - } - - /* move to the next record */ - last_ptr = rec_ptr; - rec_ptr = rec.next; - *pnum_entries += 1; - } - - ret = 0; - - fail: - - tdb_close(mem_tdb); - tdb_unlock(tdb, -1, F_WRLCK); - return ret; -} diff --git a/source/lib/tdb/common/io.c b/source/lib/tdb/common/io.c deleted file mode 100644 index 2a01a103d1a..00000000000 --- a/source/lib/tdb/common/io.c +++ /dev/null @@ -1,427 +0,0 @@ - /* - Unix SMB/CIFS implementation. - - trivial database library - - Copyright (C) Andrew Tridgell 1999-2005 - Copyright (C) Paul `Rusty' Russell 2000 - Copyright (C) Jeremy Allison 2000-2003 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - - -#include "tdb_private.h" - -/* check for an out of bounds access - if it is out of bounds then - see if the database has been expanded by someone else and expand - if necessary - note that "len" is the minimum length needed for the db -*/ -static int tdb_oob(struct tdb_context *tdb, tdb_off_t len, int probe) -{ - struct stat st; - if (len <= tdb->map_size) - return 0; - if (tdb->flags & TDB_INTERNAL) { - if (!probe) { - /* Ensure ecode is set for log fn. */ - tdb->ecode = TDB_ERR_IO; - TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_oob len %d beyond internal malloc size %d\n", - (int)len, (int)tdb->map_size)); - } - return TDB_ERRCODE(TDB_ERR_IO, -1); - } - - if (fstat(tdb->fd, &st) == -1) { - return TDB_ERRCODE(TDB_ERR_IO, -1); - } - - if (st.st_size < (size_t)len) { - if (!probe) { - /* Ensure ecode is set for log fn. */ - tdb->ecode = TDB_ERR_IO; - TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_oob len %d beyond eof at %d\n", - (int)len, (int)st.st_size)); - } - return TDB_ERRCODE(TDB_ERR_IO, -1); - } - - /* Unmap, update size, remap */ - if (tdb_munmap(tdb) == -1) - return TDB_ERRCODE(TDB_ERR_IO, -1); - tdb->map_size = st.st_size; - tdb_mmap(tdb); - return 0; -} - -/* write a lump of data at a specified offset */ -static int tdb_write(struct tdb_context *tdb, tdb_off_t off, - const void *buf, tdb_len_t len) -{ - if (len == 0) { - return 0; - } - - if (tdb->read_only || tdb->traverse_read) { - tdb->ecode = TDB_ERR_RDONLY; - return -1; - } - - if (tdb->methods->tdb_oob(tdb, off + len, 0) != 0) - return -1; - - if (tdb->map_ptr) { - memcpy(off + (char *)tdb->map_ptr, buf, len); - } else if (pwrite(tdb->fd, buf, len, off) != (ssize_t)len) { - /* Ensure ecode is set for log fn. */ - tdb->ecode = TDB_ERR_IO; - TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_write failed at %d len=%d (%s)\n", - off, len, strerror(errno))); - return TDB_ERRCODE(TDB_ERR_IO, -1); - } - return 0; -} - -/* Endian conversion: we only ever deal with 4 byte quantities */ -void *tdb_convert(void *buf, uint32_t size) -{ - uint32_t i, *p = (uint32_t *)buf; - for (i = 0; i < size / 4; i++) - p[i] = TDB_BYTEREV(p[i]); - return buf; -} - - -/* read a lump of data at a specified offset, maybe convert */ -static int tdb_read(struct tdb_context *tdb, tdb_off_t off, void *buf, - tdb_len_t len, int cv) -{ - if (tdb->methods->tdb_oob(tdb, off + len, 0) != 0) { - return -1; - } - - if (tdb->map_ptr) { - memcpy(buf, off + (char *)tdb->map_ptr, len); - } else { - ssize_t ret = pread(tdb->fd, buf, len, off); - if (ret != (ssize_t)len) { - /* Ensure ecode is set for log fn. */ - tdb->ecode = TDB_ERR_IO; - TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_read failed at %d " - "len=%d ret=%d (%s) map_size=%d\n", - (int)off, (int)len, (int)ret, strerror(errno), - (int)tdb->map_size)); - return TDB_ERRCODE(TDB_ERR_IO, -1); - } - } - if (cv) { - tdb_convert(buf, len); - } - return 0; -} - - - -/* - do an unlocked scan of the hash table heads to find the next non-zero head. The value - will then be confirmed with the lock held -*/ -static void tdb_next_hash_chain(struct tdb_context *tdb, uint32_t *chain) -{ - uint32_t h = *chain; - if (tdb->map_ptr) { - for (;h < tdb->header.hash_size;h++) { - if (0 != *(uint32_t *)(TDB_HASH_TOP(h) + (unsigned char *)tdb->map_ptr)) { - break; - } - } - } else { - uint32_t off=0; - for (;h < tdb->header.hash_size;h++) { - if (tdb_ofs_read(tdb, TDB_HASH_TOP(h), &off) != 0 || off != 0) { - break; - } - } - } - (*chain) = h; -} - - -int tdb_munmap(struct tdb_context *tdb) -{ - if (tdb->flags & TDB_INTERNAL) - return 0; - -#ifdef HAVE_MMAP - if (tdb->map_ptr) { - int ret = munmap(tdb->map_ptr, tdb->map_size); - if (ret != 0) - return ret; - } -#endif - tdb->map_ptr = NULL; - return 0; -} - -void tdb_mmap(struct tdb_context *tdb) -{ - if (tdb->flags & TDB_INTERNAL) - return; - -#ifdef HAVE_MMAP - if (!(tdb->flags & TDB_NOMMAP)) { - tdb->map_ptr = mmap(NULL, tdb->map_size, - PROT_READ|(tdb->read_only? 0:PROT_WRITE), - MAP_SHARED|MAP_FILE, tdb->fd, 0); - - /* - * NB. When mmap fails it returns MAP_FAILED *NOT* NULL !!!! - */ - - if (tdb->map_ptr == MAP_FAILED) { - tdb->map_ptr = NULL; - TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_mmap failed for size %d (%s)\n", - tdb->map_size, strerror(errno))); - } - } else { - tdb->map_ptr = NULL; - } -#else - tdb->map_ptr = NULL; -#endif -} - -/* expand a file. we prefer to use ftruncate, as that is what posix - says to use for mmap expansion */ -static int tdb_expand_file(struct tdb_context *tdb, tdb_off_t size, tdb_off_t addition) -{ - char buf[1024]; - - if (tdb->read_only || tdb->traverse_read) { - tdb->ecode = TDB_ERR_RDONLY; - return -1; - } - - if (ftruncate(tdb->fd, size+addition) == -1) { - char b = 0; - if (pwrite(tdb->fd, &b, 1, (size+addition) - 1) != 1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "expand_file to %d failed (%s)\n", - size+addition, strerror(errno))); - return -1; - } - } - - /* now fill the file with something. This ensures that the - file isn't sparse, which would be very bad if we ran out of - disk. This must be done with write, not via mmap */ - memset(buf, TDB_PAD_BYTE, sizeof(buf)); - while (addition) { - int n = addition>sizeof(buf)?sizeof(buf):addition; - int ret = pwrite(tdb->fd, buf, n, size); - if (ret != n) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "expand_file write of %d failed (%s)\n", - n, strerror(errno))); - return -1; - } - addition -= n; - size += n; - } - return 0; -} - - -/* expand the database at least size bytes by expanding the underlying - file and doing the mmap again if necessary */ -int tdb_expand(struct tdb_context *tdb, tdb_off_t size) -{ - struct list_struct rec; - tdb_off_t offset; - - if (tdb_lock(tdb, -1, F_WRLCK) == -1) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "lock failed in tdb_expand\n")); - return -1; - } - - /* must know about any previous expansions by another process */ - tdb->methods->tdb_oob(tdb, tdb->map_size + 1, 1); - - /* always make room for at least 10 more records, and round - the database up to a multiple of the page size */ - size = TDB_ALIGN(tdb->map_size + size*10, tdb->page_size) - tdb->map_size; - - if (!(tdb->flags & TDB_INTERNAL)) - tdb_munmap(tdb); - - /* - * We must ensure the file is unmapped before doing this - * to ensure consistency with systems like OpenBSD where - * writes and mmaps are not consistent. - */ - - /* expand the file itself */ - if (!(tdb->flags & TDB_INTERNAL)) { - if (tdb->methods->tdb_expand_file(tdb, tdb->map_size, size) != 0) - goto fail; - } - - tdb->map_size += size; - - if (tdb->flags & TDB_INTERNAL) { - char *new_map_ptr = (char *)realloc(tdb->map_ptr, - tdb->map_size); - if (!new_map_ptr) { - tdb->map_size -= size; - goto fail; - } - tdb->map_ptr = new_map_ptr; - } else { - /* - * We must ensure the file is remapped before adding the space - * to ensure consistency with systems like OpenBSD where - * writes and mmaps are not consistent. - */ - - /* We're ok if the mmap fails as we'll fallback to read/write */ - tdb_mmap(tdb); - } - - /* form a new freelist record */ - memset(&rec,'\0',sizeof(rec)); - rec.rec_len = size - sizeof(rec); - - /* link it into the free list */ - offset = tdb->map_size - size; - if (tdb_free(tdb, offset, &rec) == -1) - goto fail; - - tdb_unlock(tdb, -1, F_WRLCK); - return 0; - fail: - tdb_unlock(tdb, -1, F_WRLCK); - return -1; -} - -/* read/write a tdb_off_t */ -int tdb_ofs_read(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d) -{ - return tdb->methods->tdb_read(tdb, offset, (char*)d, sizeof(*d), DOCONV()); -} - -int tdb_ofs_write(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d) -{ - tdb_off_t off = *d; - return tdb->methods->tdb_write(tdb, offset, CONVERT(off), sizeof(*d)); -} - - -/* read a lump of data, allocating the space for it */ -unsigned char *tdb_alloc_read(struct tdb_context *tdb, tdb_off_t offset, tdb_len_t len) -{ - unsigned char *buf; - - /* some systems don't like zero length malloc */ - if (len == 0) { - len = 1; - } - - if (!(buf = (unsigned char *)malloc(len))) { - /* Ensure ecode is set for log fn. */ - tdb->ecode = TDB_ERR_OOM; - TDB_LOG((tdb, TDB_DEBUG_ERROR,"tdb_alloc_read malloc failed len=%d (%s)\n", - len, strerror(errno))); - return TDB_ERRCODE(TDB_ERR_OOM, buf); - } - if (tdb->methods->tdb_read(tdb, offset, buf, len, 0) == -1) { - SAFE_FREE(buf); - return NULL; - } - return buf; -} - -/* Give a piece of tdb data to a parser */ - -int tdb_parse_data(struct tdb_context *tdb, TDB_DATA key, - tdb_off_t offset, tdb_len_t len, - int (*parser)(TDB_DATA key, TDB_DATA data, - void *private_data), - void *private_data) -{ - TDB_DATA data; - int result; - - data.dsize = len; - - if ((tdb->transaction == NULL) && (tdb->map_ptr != NULL)) { - /* - * Optimize by avoiding the malloc/memcpy/free, point the - * parser directly at the mmap area. - */ - if (tdb->methods->tdb_oob(tdb, offset+len, 0) != 0) { - return -1; - } - data.dptr = offset + (unsigned char *)tdb->map_ptr; - return parser(key, data, private_data); - } - - if (!(data.dptr = tdb_alloc_read(tdb, offset, len))) { - return -1; - } - - result = parser(key, data, private_data); - free(data.dptr); - return result; -} - -/* read/write a record */ -int tdb_rec_read(struct tdb_context *tdb, tdb_off_t offset, struct list_struct *rec) -{ - if (tdb->methods->tdb_read(tdb, offset, rec, sizeof(*rec),DOCONV()) == -1) - return -1; - if (TDB_BAD_MAGIC(rec)) { - /* Ensure ecode is set for log fn. */ - tdb->ecode = TDB_ERR_CORRUPT; - TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_rec_read bad magic 0x%x at offset=%d\n", rec->magic, offset)); - return TDB_ERRCODE(TDB_ERR_CORRUPT, -1); - } - return tdb->methods->tdb_oob(tdb, rec->next+sizeof(*rec), 0); -} - -int tdb_rec_write(struct tdb_context *tdb, tdb_off_t offset, struct list_struct *rec) -{ - struct list_struct r = *rec; - return tdb->methods->tdb_write(tdb, offset, CONVERT(r), sizeof(r)); -} - -static const struct tdb_methods io_methods = { - tdb_read, - tdb_write, - tdb_next_hash_chain, - tdb_oob, - tdb_expand_file, - tdb_brlock -}; - -/* - initialise the default methods table -*/ -void tdb_io_init(struct tdb_context *tdb) -{ - tdb->methods = &io_methods; -} diff --git a/source/lib/tdb/common/lock.c b/source/lib/tdb/common/lock.c deleted file mode 100644 index 8500438a4e7..00000000000 --- a/source/lib/tdb/common/lock.c +++ /dev/null @@ -1,412 +0,0 @@ - /* - Unix SMB/CIFS implementation. - - trivial database library - - Copyright (C) Andrew Tridgell 1999-2005 - Copyright (C) Paul `Rusty' Russell 2000 - Copyright (C) Jeremy Allison 2000-2003 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include "tdb_private.h" - -/* a byte range locking function - return 0 on success - this functions locks/unlocks 1 byte at the specified offset. - - On error, errno is also set so that errors are passed back properly - through tdb_open(). - - note that a len of zero means lock to end of file -*/ -int tdb_brlock(struct tdb_context *tdb, tdb_off_t offset, - int rw_type, int lck_type, int probe, size_t len) -{ - struct flock fl; - int ret; - - if (tdb->flags & TDB_NOLOCK) { - return 0; - } - - if ((rw_type == F_WRLCK) && (tdb->read_only || tdb->traverse_read)) { - tdb->ecode = TDB_ERR_RDONLY; - return -1; - } - - fl.l_type = rw_type; - fl.l_whence = SEEK_SET; - fl.l_start = offset; - fl.l_len = len; - fl.l_pid = 0; - - do { - ret = fcntl(tdb->fd,lck_type,&fl); - } while (ret == -1 && errno == EINTR); - - if (ret == -1) { - /* Generic lock error. errno set by fcntl. - * EAGAIN is an expected return from non-blocking - * locks. */ - if (!probe && lck_type != F_SETLK) { - /* Ensure error code is set for log fun to examine. */ - tdb->ecode = TDB_ERR_LOCK; - TDB_LOG((tdb, TDB_DEBUG_TRACE,"tdb_brlock failed (fd=%d) at offset %d rw_type=%d lck_type=%d len=%d\n", - tdb->fd, offset, rw_type, lck_type, (int)len)); - } - return TDB_ERRCODE(TDB_ERR_LOCK, -1); - } - return 0; -} - - -/* - upgrade a read lock to a write lock. This needs to be handled in a - special way as some OSes (such as solaris) have too conservative - deadlock detection and claim a deadlock when progress can be - made. For those OSes we may loop for a while. -*/ -int tdb_brlock_upgrade(struct tdb_context *tdb, tdb_off_t offset, size_t len) -{ - int count = 1000; - while (count--) { - struct timeval tv; - if (tdb_brlock(tdb, offset, F_WRLCK, F_SETLKW, 1, len) == 0) { - return 0; - } - if (errno != EDEADLK) { - break; - } - /* sleep for as short a time as we can - more portable than usleep() */ - tv.tv_sec = 0; - tv.tv_usec = 1; - select(0, NULL, NULL, NULL, &tv); - } - TDB_LOG((tdb, TDB_DEBUG_TRACE,"tdb_brlock_upgrade failed at offset %d\n", offset)); - return -1; -} - - -/* lock a list in the database. list -1 is the alloc list */ -int tdb_lock(struct tdb_context *tdb, int list, int ltype) -{ - struct tdb_lock_type *new_lck; - int i; - - /* a global lock allows us to avoid per chain locks */ - if (tdb->global_lock.count && - (ltype == tdb->global_lock.ltype || ltype == F_RDLCK)) { - return 0; - } - - if (tdb->global_lock.count) { - return TDB_ERRCODE(TDB_ERR_LOCK, -1); - } - - if (list < -1 || list >= (int)tdb->header.hash_size) { - TDB_LOG((tdb, TDB_DEBUG_ERROR,"tdb_lock: invalid list %d for ltype=%d\n", - list, ltype)); - return -1; - } - if (tdb->flags & TDB_NOLOCK) - return 0; - - for (i=0; i<tdb->num_lockrecs; i++) { - if (tdb->lockrecs[i].list == list) { - if (tdb->lockrecs[i].count == 0) { - /* - * Can't happen, see tdb_unlock(). It should - * be an assert. - */ - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_lock: " - "lck->count == 0 for list %d", list)); - } - /* - * Just increment the in-memory struct, posix locks - * don't stack. - */ - tdb->lockrecs[i].count++; - return 0; - } - } - - new_lck = (struct tdb_lock_type *)realloc( - tdb->lockrecs, - sizeof(*tdb->lockrecs) * (tdb->num_lockrecs+1)); - if (new_lck == NULL) { - errno = ENOMEM; - return -1; - } - tdb->lockrecs = new_lck; - - /* Since fcntl locks don't nest, we do a lock for the first one, - and simply bump the count for future ones */ - if (tdb->methods->tdb_brlock(tdb,FREELIST_TOP+4*list,ltype,F_SETLKW, - 0, 1)) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_lock failed on list %d " - "ltype=%d (%s)\n", list, ltype, strerror(errno))); - return -1; - } - - tdb->num_locks++; - - tdb->lockrecs[tdb->num_lockrecs].list = list; - tdb->lockrecs[tdb->num_lockrecs].count = 1; - tdb->lockrecs[tdb->num_lockrecs].ltype = ltype; - tdb->num_lockrecs += 1; - - return 0; -} - -/* unlock the database: returns void because it's too late for errors. */ - /* changed to return int it may be interesting to know there - has been an error --simo */ -int tdb_unlock(struct tdb_context *tdb, int list, int ltype) -{ - int ret = -1; - int i; - struct tdb_lock_type *lck = NULL; - - /* a global lock allows us to avoid per chain locks */ - if (tdb->global_lock.count && - (ltype == tdb->global_lock.ltype || ltype == F_RDLCK)) { - return 0; - } - - if (tdb->global_lock.count) { - return TDB_ERRCODE(TDB_ERR_LOCK, -1); - } - - if (tdb->flags & TDB_NOLOCK) - return 0; - - /* Sanity checks */ - if (list < -1 || list >= (int)tdb->header.hash_size) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_unlock: list %d invalid (%d)\n", list, tdb->header.hash_size)); - return ret; - } - - for (i=0; i<tdb->num_lockrecs; i++) { - if (tdb->lockrecs[i].list == list) { - lck = &tdb->lockrecs[i]; - break; - } - } - - if ((lck == NULL) || (lck->count == 0)) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_unlock: count is 0\n")); - return -1; - } - - if (lck->count > 1) { - lck->count--; - return 0; - } - - /* - * This lock has count==1 left, so we need to unlock it in the - * kernel. We don't bother with decrementing the in-memory array - * element, we're about to overwrite it with the last array element - * anyway. - */ - - ret = tdb->methods->tdb_brlock(tdb, FREELIST_TOP+4*list, F_UNLCK, - F_SETLKW, 0, 1); - tdb->num_locks--; - - /* - * Shrink the array by overwriting the element just unlocked with the - * last array element. - */ - - if (tdb->num_lockrecs > 1) { - *lck = tdb->lockrecs[tdb->num_lockrecs-1]; - } - tdb->num_lockrecs -= 1; - - /* - * We don't bother with realloc when the array shrinks, but if we have - * a completely idle tdb we should get rid of the locked array. - */ - - if (tdb->num_lockrecs == 0) { - SAFE_FREE(tdb->lockrecs); - } - - if (ret) - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_unlock: An error occurred unlocking!\n")); - return ret; -} - - - -/* lock/unlock entire database */ -static int _tdb_lockall(struct tdb_context *tdb, int ltype) -{ - /* There are no locks on read-only dbs */ - if (tdb->read_only || tdb->traverse_read) - return TDB_ERRCODE(TDB_ERR_LOCK, -1); - - if (tdb->global_lock.count && tdb->global_lock.ltype == ltype) { - tdb->global_lock.count++; - return 0; - } - - if (tdb->global_lock.count) { - /* a global lock of a different type exists */ - return TDB_ERRCODE(TDB_ERR_LOCK, -1); - } - - if (tdb->num_locks != 0) { - /* can't combine global and chain locks */ - return TDB_ERRCODE(TDB_ERR_LOCK, -1); - } - - if (tdb->methods->tdb_brlock(tdb, FREELIST_TOP, ltype, F_SETLKW, - 0, 4*tdb->header.hash_size)) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_lockall failed (%s)\n", strerror(errno))); - return -1; - } - - tdb->global_lock.count = 1; - tdb->global_lock.ltype = ltype; - - return 0; -} - -/* unlock entire db */ -static int _tdb_unlockall(struct tdb_context *tdb, int ltype) -{ - /* There are no locks on read-only dbs */ - if (tdb->read_only || tdb->traverse_read) { - return TDB_ERRCODE(TDB_ERR_LOCK, -1); - } - - if (tdb->global_lock.ltype != ltype || tdb->global_lock.count == 0) { - return TDB_ERRCODE(TDB_ERR_LOCK, -1); - } - - if (tdb->global_lock.count > 1) { - tdb->global_lock.count--; - return 0; - } - - if (tdb->methods->tdb_brlock(tdb, FREELIST_TOP, F_UNLCK, F_SETLKW, - 0, 4*tdb->header.hash_size)) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_unlockall failed (%s)\n", strerror(errno))); - return -1; - } - - tdb->global_lock.count = 0; - tdb->global_lock.ltype = 0; - - return 0; -} - -/* lock entire database with write lock */ -int tdb_lockall(struct tdb_context *tdb) -{ - return _tdb_lockall(tdb, F_WRLCK); -} - -/* unlock entire database with write lock */ -int tdb_unlockall(struct tdb_context *tdb) -{ - return _tdb_unlockall(tdb, F_WRLCK); -} - -/* lock entire database with read lock */ -int tdb_lockall_read(struct tdb_context *tdb) -{ - return _tdb_lockall(tdb, F_RDLCK); -} - -/* unlock entire database with read lock */ -int tdb_unlockall_read(struct tdb_context *tdb) -{ - return _tdb_unlockall(tdb, F_RDLCK); -} - -/* lock/unlock one hash chain. This is meant to be used to reduce - contention - it cannot guarantee how many records will be locked */ -int tdb_chainlock(struct tdb_context *tdb, TDB_DATA key) -{ - return tdb_lock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK); -} - -int tdb_chainunlock(struct tdb_context *tdb, TDB_DATA key) -{ - return tdb_unlock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK); -} - -int tdb_chainlock_read(struct tdb_context *tdb, TDB_DATA key) -{ - return tdb_lock(tdb, BUCKET(tdb->hash_fn(&key)), F_RDLCK); -} - -int tdb_chainunlock_read(struct tdb_context *tdb, TDB_DATA key) -{ - return tdb_unlock(tdb, BUCKET(tdb->hash_fn(&key)), F_RDLCK); -} - - - -/* record lock stops delete underneath */ -int tdb_lock_record(struct tdb_context *tdb, tdb_off_t off) -{ - return off ? tdb->methods->tdb_brlock(tdb, off, F_RDLCK, F_SETLKW, 0, 1) : 0; -} - -/* - Write locks override our own fcntl readlocks, so check it here. - Note this is meant to be F_SETLK, *not* F_SETLKW, as it's not - an error to fail to get the lock here. -*/ -int tdb_write_lock_record(struct tdb_context *tdb, tdb_off_t off) -{ - struct tdb_traverse_lock *i; - for (i = &tdb->travlocks; i; i = i->next) - if (i->off == off) - return -1; - return tdb->methods->tdb_brlock(tdb, off, F_WRLCK, F_SETLK, 1, 1); -} - -/* - Note this is meant to be F_SETLK, *not* F_SETLKW, as it's not - an error to fail to get the lock here. -*/ -int tdb_write_unlock_record(struct tdb_context *tdb, tdb_off_t off) -{ - return tdb->methods->tdb_brlock(tdb, off, F_UNLCK, F_SETLK, 0, 1); -} - -/* fcntl locks don't stack: avoid unlocking someone else's */ -int tdb_unlock_record(struct tdb_context *tdb, tdb_off_t off) -{ - struct tdb_traverse_lock *i; - uint32_t count = 0; - - if (off == 0) - return 0; - for (i = &tdb->travlocks; i; i = i->next) - if (i->off == off) - count++; - return (count == 1 ? tdb->methods->tdb_brlock(tdb, off, F_UNLCK, F_SETLKW, 0, 1) : 0); -} diff --git a/source/lib/tdb/common/open.c b/source/lib/tdb/common/open.c deleted file mode 100644 index 84e67f1993c..00000000000 --- a/source/lib/tdb/common/open.c +++ /dev/null @@ -1,469 +0,0 @@ - /* - Unix SMB/CIFS implementation. - - trivial database library - - Copyright (C) Andrew Tridgell 1999-2005 - Copyright (C) Paul `Rusty' Russell 2000 - Copyright (C) Jeremy Allison 2000-2003 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include "tdb_private.h" - -/* all contexts, to ensure no double-opens (fcntl locks don't nest!) */ -static struct tdb_context *tdbs = NULL; - - -/* This is based on the hash algorithm from gdbm */ -static unsigned int default_tdb_hash(TDB_DATA *key) -{ - uint32_t value; /* Used to compute the hash value. */ - uint32_t i; /* Used to cycle through random values. */ - - /* Set the initial value from the key size. */ - for (value = 0x238F13AF * key->dsize, i=0; i < key->dsize; i++) - value = (value + (key->dptr[i] << (i*5 % 24))); - - return (1103515243 * value + 12345); -} - - -/* initialise a new database with a specified hash size */ -static int tdb_new_database(struct tdb_context *tdb, int hash_size) -{ - struct tdb_header *newdb; - int size, ret = -1; - - /* We make it up in memory, then write it out if not internal */ - size = sizeof(struct tdb_header) + (hash_size+1)*sizeof(tdb_off_t); - if (!(newdb = (struct tdb_header *)calloc(size, 1))) - return TDB_ERRCODE(TDB_ERR_OOM, -1); - - /* Fill in the header */ - newdb->version = TDB_VERSION; - newdb->hash_size = hash_size; - if (tdb->flags & TDB_INTERNAL) { - tdb->map_size = size; - tdb->map_ptr = (char *)newdb; - memcpy(&tdb->header, newdb, sizeof(tdb->header)); - /* Convert the `ondisk' version if asked. */ - CONVERT(*newdb); - return 0; - } - if (lseek(tdb->fd, 0, SEEK_SET) == -1) - goto fail; - - if (ftruncate(tdb->fd, 0) == -1) - goto fail; - - /* This creates an endian-converted header, as if read from disk */ - CONVERT(*newdb); - memcpy(&tdb->header, newdb, sizeof(tdb->header)); - /* Don't endian-convert the magic food! */ - memcpy(newdb->magic_food, TDB_MAGIC_FOOD, strlen(TDB_MAGIC_FOOD)+1); - if (write(tdb->fd, newdb, size) != size) { - ret = -1; - } else { - ret = 0; - } - - fail: - SAFE_FREE(newdb); - return ret; -} - - - -static int tdb_already_open(dev_t device, - ino_t ino) -{ - struct tdb_context *i; - - for (i = tdbs; i; i = i->next) { - if (i->device == device && i->inode == ino) { - return 1; - } - } - - return 0; -} - -/* open the database, creating it if necessary - - The open_flags and mode are passed straight to the open call on the - database file. A flags value of O_WRONLY is invalid. The hash size - is advisory, use zero for a default value. - - Return is NULL on error, in which case errno is also set. Don't - try to call tdb_error or tdb_errname, just do strerror(errno). - - @param name may be NULL for internal databases. */ -struct tdb_context *tdb_open(const char *name, int hash_size, int tdb_flags, - int open_flags, mode_t mode) -{ - return tdb_open_ex(name, hash_size, tdb_flags, open_flags, mode, NULL, NULL); -} - -/* a default logging function */ -static void null_log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) PRINTF_ATTRIBUTE(3, 4); -static void null_log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) -{ -} - - -struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags, - int open_flags, mode_t mode, - const struct tdb_logging_context *log_ctx, - tdb_hash_func hash_fn) -{ - struct tdb_context *tdb; - struct stat st; - int rev = 0, locked = 0; - unsigned char *vp; - uint32_t vertest; - - if (!(tdb = (struct tdb_context *)calloc(1, sizeof *tdb))) { - /* Can't log this */ - errno = ENOMEM; - goto fail; - } - tdb_io_init(tdb); - tdb->fd = -1; - tdb->name = NULL; - tdb->map_ptr = NULL; - tdb->flags = tdb_flags; - tdb->open_flags = open_flags; - if (log_ctx) { - tdb->log = *log_ctx; - } else { - tdb->log.log_fn = null_log_fn; - tdb->log.log_private = NULL; - } - tdb->hash_fn = hash_fn ? hash_fn : default_tdb_hash; - - /* cache the page size */ - tdb->page_size = getpagesize(); - if (tdb->page_size <= 0) { - tdb->page_size = 0x2000; - } - - if (open_flags & TDB_VOLATILE) { - tdb->max_dead_records = 5; - } - - if ((open_flags & O_ACCMODE) == O_WRONLY) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: can't open tdb %s write-only\n", - name)); - errno = EINVAL; - goto fail; - } - - if (hash_size == 0) - hash_size = DEFAULT_HASH_SIZE; - if ((open_flags & O_ACCMODE) == O_RDONLY) { - tdb->read_only = 1; - /* read only databases don't do locking or clear if first */ - tdb->flags |= TDB_NOLOCK; - tdb->flags &= ~TDB_CLEAR_IF_FIRST; - } - - /* internal databases don't mmap or lock, and start off cleared */ - if (tdb->flags & TDB_INTERNAL) { - tdb->flags |= (TDB_NOLOCK | TDB_NOMMAP); - tdb->flags &= ~TDB_CLEAR_IF_FIRST; - if (tdb_new_database(tdb, hash_size) != 0) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: tdb_new_database failed!")); - goto fail; - } - goto internal; - } - - if ((tdb->fd = open(name, open_flags, mode)) == -1) { - TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_open_ex: could not open file %s: %s\n", - name, strerror(errno))); - goto fail; /* errno set by open(2) */ - } - - /* ensure there is only one process initialising at once */ - if (tdb->methods->tdb_brlock(tdb, GLOBAL_LOCK, F_WRLCK, F_SETLKW, 0, 1) == -1) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: failed to get global lock on %s: %s\n", - name, strerror(errno))); - goto fail; /* errno set by tdb_brlock */ - } - - /* we need to zero database if we are the only one with it open */ - if ((tdb_flags & TDB_CLEAR_IF_FIRST) && - (locked = (tdb->methods->tdb_brlock(tdb, ACTIVE_LOCK, F_WRLCK, F_SETLK, 0, 1) == 0))) { - open_flags |= O_CREAT; - if (ftruncate(tdb->fd, 0) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: " - "failed to truncate %s: %s\n", - name, strerror(errno))); - goto fail; /* errno set by ftruncate */ - } - } - - if (read(tdb->fd, &tdb->header, sizeof(tdb->header)) != sizeof(tdb->header) - || strcmp(tdb->header.magic_food, TDB_MAGIC_FOOD) != 0 - || (tdb->header.version != TDB_VERSION - && !(rev = (tdb->header.version==TDB_BYTEREV(TDB_VERSION))))) { - /* its not a valid database - possibly initialise it */ - if (!(open_flags & O_CREAT) || tdb_new_database(tdb, hash_size) == -1) { - errno = EIO; /* ie bad format or something */ - goto fail; - } - rev = (tdb->flags & TDB_CONVERT); - } - vp = (unsigned char *)&tdb->header.version; - vertest = (((uint32_t)vp[0]) << 24) | (((uint32_t)vp[1]) << 16) | - (((uint32_t)vp[2]) << 8) | (uint32_t)vp[3]; - tdb->flags |= (vertest==TDB_VERSION) ? TDB_BIGENDIAN : 0; - if (!rev) - tdb->flags &= ~TDB_CONVERT; - else { - tdb->flags |= TDB_CONVERT; - tdb_convert(&tdb->header, sizeof(tdb->header)); - } - if (fstat(tdb->fd, &st) == -1) - goto fail; - - if (tdb->header.rwlocks != 0) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: spinlocks no longer supported\n")); - goto fail; - } - - /* Is it already in the open list? If so, fail. */ - if (tdb_already_open(st.st_dev, st.st_ino)) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: " - "%s (%d,%d) is already open in this process\n", - name, (int)st.st_dev, (int)st.st_ino)); - errno = EBUSY; - goto fail; - } - - if (!(tdb->name = (char *)strdup(name))) { - errno = ENOMEM; - goto fail; - } - - tdb->map_size = st.st_size; - tdb->device = st.st_dev; - tdb->inode = st.st_ino; - tdb->max_dead_records = 0; - tdb_mmap(tdb); - if (locked) { - if (tdb->methods->tdb_brlock(tdb, ACTIVE_LOCK, F_UNLCK, F_SETLK, 0, 1) == -1) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: " - "failed to take ACTIVE_LOCK on %s: %s\n", - name, strerror(errno))); - goto fail; - } - - } - - /* We always need to do this if the CLEAR_IF_FIRST flag is set, even if - we didn't get the initial exclusive lock as we need to let all other - users know we're using it. */ - - if (tdb_flags & TDB_CLEAR_IF_FIRST) { - /* leave this lock in place to indicate it's in use */ - if (tdb->methods->tdb_brlock(tdb, ACTIVE_LOCK, F_RDLCK, F_SETLKW, 0, 1) == -1) - goto fail; - } - - /* if needed, run recovery */ - if (tdb_transaction_recover(tdb) == -1) { - goto fail; - } - - internal: - /* Internal (memory-only) databases skip all the code above to - * do with disk files, and resume here by releasing their - * global lock and hooking into the active list. */ - if (tdb->methods->tdb_brlock(tdb, GLOBAL_LOCK, F_UNLCK, F_SETLKW, 0, 1) == -1) - goto fail; - tdb->next = tdbs; - tdbs = tdb; - return tdb; - - fail: - { int save_errno = errno; - - if (!tdb) - return NULL; - - if (tdb->map_ptr) { - if (tdb->flags & TDB_INTERNAL) - SAFE_FREE(tdb->map_ptr); - else - tdb_munmap(tdb); - } - SAFE_FREE(tdb->name); - if (tdb->fd != -1) - if (close(tdb->fd) != 0) - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: failed to close tdb->fd on error!\n")); - SAFE_FREE(tdb); - errno = save_errno; - return NULL; - } -} - -/* - * Set the maximum number of dead records per hash chain - */ - -void tdb_set_max_dead(struct tdb_context *tdb, int max_dead) -{ - tdb->max_dead_records = max_dead; -} - -/** - * Close a database. - * - * @returns -1 for error; 0 for success. - **/ -int tdb_close(struct tdb_context *tdb) -{ - struct tdb_context **i; - int ret = 0; - - if (tdb->transaction) { - tdb_transaction_cancel(tdb); - } - - if (tdb->map_ptr) { - if (tdb->flags & TDB_INTERNAL) - SAFE_FREE(tdb->map_ptr); - else - tdb_munmap(tdb); - } - SAFE_FREE(tdb->name); - if (tdb->fd != -1) - ret = close(tdb->fd); - SAFE_FREE(tdb->lockrecs); - - /* Remove from contexts list */ - for (i = &tdbs; *i; i = &(*i)->next) { - if (*i == tdb) { - *i = tdb->next; - break; - } - } - - memset(tdb, 0, sizeof(*tdb)); - SAFE_FREE(tdb); - - return ret; -} - -/* register a loging function */ -void tdb_set_logging_function(struct tdb_context *tdb, - const struct tdb_logging_context *log_ctx) -{ - tdb->log = *log_ctx; -} - -void *tdb_get_logging_private(struct tdb_context *tdb) -{ - return tdb->log.log_private; -} - -/* reopen a tdb - this can be used after a fork to ensure that we have an independent - seek pointer from our parent and to re-establish locks */ -int tdb_reopen(struct tdb_context *tdb) -{ - struct stat st; - - if (tdb->flags & TDB_INTERNAL) { - return 0; /* Nothing to do. */ - } - - if (tdb->num_locks != 0 || tdb->global_lock.count) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_reopen: reopen not allowed with locks held\n")); - goto fail; - } - - if (tdb->transaction != 0) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_reopen: reopen not allowed inside a transaction\n")); - goto fail; - } - - if (tdb_munmap(tdb) != 0) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: munmap failed (%s)\n", strerror(errno))); - goto fail; - } - if (close(tdb->fd) != 0) - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: WARNING closing tdb->fd failed!\n")); - tdb->fd = open(tdb->name, tdb->open_flags & ~(O_CREAT|O_TRUNC), 0); - if (tdb->fd == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: open failed (%s)\n", strerror(errno))); - goto fail; - } - if ((tdb->flags & TDB_CLEAR_IF_FIRST) && - (tdb->methods->tdb_brlock(tdb, ACTIVE_LOCK, F_RDLCK, F_SETLKW, 0, 1) == -1)) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: failed to obtain active lock\n")); - goto fail; - } - if (fstat(tdb->fd, &st) != 0) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: fstat failed (%s)\n", strerror(errno))); - goto fail; - } - if (st.st_ino != tdb->inode || st.st_dev != tdb->device) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: file dev/inode has changed!\n")); - goto fail; - } - tdb_mmap(tdb); - - return 0; - -fail: - tdb_close(tdb); - return -1; -} - -/* reopen all tdb's */ -int tdb_reopen_all(int parent_longlived) -{ - struct tdb_context *tdb; - - for (tdb=tdbs; tdb; tdb = tdb->next) { - /* - * If the parent is longlived (ie. a - * parent daemon architecture), we know - * it will keep it's active lock on a - * tdb opened with CLEAR_IF_FIRST. Thus - * for child processes we don't have to - * add an active lock. This is essential - * to improve performance on systems that - * keep POSIX locks as a non-scalable data - * structure in the kernel. - */ - if (parent_longlived) { - /* Ensure no clear-if-first. */ - tdb->flags &= ~TDB_CLEAR_IF_FIRST; - } - - if (tdb_reopen(tdb) != 0) - return -1; - } - - return 0; -} diff --git a/source/lib/tdb/common/tdb.c b/source/lib/tdb/common/tdb.c deleted file mode 100644 index 92811bea49f..00000000000 --- a/source/lib/tdb/common/tdb.c +++ /dev/null @@ -1,656 +0,0 @@ - /* - Unix SMB/CIFS implementation. - - trivial database library - - Copyright (C) Andrew Tridgell 1999-2005 - Copyright (C) Paul `Rusty' Russell 2000 - Copyright (C) Jeremy Allison 2000-2003 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include "tdb_private.h" - -TDB_DATA tdb_null; - -/* - increment the tdb sequence number if the tdb has been opened using - the TDB_SEQNUM flag -*/ -static void tdb_increment_seqnum(struct tdb_context *tdb) -{ - tdb_off_t seqnum=0; - - if (!(tdb->flags & TDB_SEQNUM)) { - return; - } - - if (tdb_brlock(tdb, TDB_SEQNUM_OFS, F_WRLCK, F_SETLKW, 1, 1) != 0) { - return; - } - - /* we ignore errors from this, as we have no sane way of - dealing with them. - */ - tdb_ofs_read(tdb, TDB_SEQNUM_OFS, &seqnum); - seqnum++; - tdb_ofs_write(tdb, TDB_SEQNUM_OFS, &seqnum); - - tdb_brlock(tdb, TDB_SEQNUM_OFS, F_UNLCK, F_SETLKW, 1, 1); -} - -static int tdb_key_compare(TDB_DATA key, TDB_DATA data, void *private_data) -{ - return memcmp(data.dptr, key.dptr, data.dsize); -} - -/* Returns 0 on fail. On success, return offset of record, and fills - in rec */ -static tdb_off_t tdb_find(struct tdb_context *tdb, TDB_DATA key, uint32_t hash, - struct list_struct *r) -{ - tdb_off_t rec_ptr; - - /* read in the hash top */ - if (tdb_ofs_read(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1) - return 0; - - /* keep looking until we find the right record */ - while (rec_ptr) { - if (tdb_rec_read(tdb, rec_ptr, r) == -1) - return 0; - - if (!TDB_DEAD(r) && hash==r->full_hash - && key.dsize==r->key_len - && tdb_parse_data(tdb, key, rec_ptr + sizeof(*r), - r->key_len, tdb_key_compare, - NULL) == 0) { - return rec_ptr; - } - rec_ptr = r->next; - } - return TDB_ERRCODE(TDB_ERR_NOEXIST, 0); -} - -/* As tdb_find, but if you succeed, keep the lock */ -tdb_off_t tdb_find_lock_hash(struct tdb_context *tdb, TDB_DATA key, - uint32_t hash, int locktype, - struct list_struct *rec) -{ - uint32_t rec_ptr; - - if (tdb_lock(tdb, BUCKET(hash), locktype) == -1) - return 0; - if (!(rec_ptr = tdb_find(tdb, key, hash, rec))) - tdb_unlock(tdb, BUCKET(hash), locktype); - return rec_ptr; -} - - -/* update an entry in place - this only works if the new data size - is <= the old data size and the key exists. - on failure return -1. -*/ -static int tdb_update_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash, TDB_DATA dbuf) -{ - struct list_struct rec; - tdb_off_t rec_ptr; - - /* find entry */ - if (!(rec_ptr = tdb_find(tdb, key, hash, &rec))) - return -1; - - /* must be long enough key, data and tailer */ - if (rec.rec_len < key.dsize + dbuf.dsize + sizeof(tdb_off_t)) { - tdb->ecode = TDB_SUCCESS; /* Not really an error */ - return -1; - } - - if (tdb->methods->tdb_write(tdb, rec_ptr + sizeof(rec) + rec.key_len, - dbuf.dptr, dbuf.dsize) == -1) - return -1; - - if (dbuf.dsize != rec.data_len) { - /* update size */ - rec.data_len = dbuf.dsize; - return tdb_rec_write(tdb, rec_ptr, &rec); - } - - return 0; -} - -/* find an entry in the database given a key */ -/* If an entry doesn't exist tdb_err will be set to - * TDB_ERR_NOEXIST. If a key has no data attached - * then the TDB_DATA will have zero length but - * a non-zero pointer - */ -TDB_DATA tdb_fetch(struct tdb_context *tdb, TDB_DATA key) -{ - tdb_off_t rec_ptr; - struct list_struct rec; - TDB_DATA ret; - uint32_t hash; - - /* find which hash bucket it is in */ - hash = tdb->hash_fn(&key); - if (!(rec_ptr = tdb_find_lock_hash(tdb,key,hash,F_RDLCK,&rec))) - return tdb_null; - - ret.dptr = tdb_alloc_read(tdb, rec_ptr + sizeof(rec) + rec.key_len, - rec.data_len); - ret.dsize = rec.data_len; - tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK); - return ret; -} - -/* - * Find an entry in the database and hand the record's data to a parsing - * function. The parsing function is executed under the chain read lock, so it - * should be fast and should not block on other syscalls. - * - * DONT CALL OTHER TDB CALLS FROM THE PARSER, THIS MIGHT LEAD TO SEGFAULTS. - * - * For mmapped tdb's that do not have a transaction open it points the parsing - * function directly at the mmap area, it avoids the malloc/memcpy in this - * case. If a transaction is open or no mmap is available, it has to do - * malloc/read/parse/free. - * - * This is interesting for all readers of potentially large data structures in - * the tdb records, ldb indexes being one example. - */ - -int tdb_parse_record(struct tdb_context *tdb, TDB_DATA key, - int (*parser)(TDB_DATA key, TDB_DATA data, - void *private_data), - void *private_data) -{ - tdb_off_t rec_ptr; - struct list_struct rec; - int ret; - uint32_t hash; - - /* find which hash bucket it is in */ - hash = tdb->hash_fn(&key); - - if (!(rec_ptr = tdb_find_lock_hash(tdb,key,hash,F_RDLCK,&rec))) { - return TDB_ERRCODE(TDB_ERR_NOEXIST, 0); - } - - ret = tdb_parse_data(tdb, key, rec_ptr + sizeof(rec) + rec.key_len, - rec.data_len, parser, private_data); - - tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK); - - return ret; -} - -/* check if an entry in the database exists - - note that 1 is returned if the key is found and 0 is returned if not found - this doesn't match the conventions in the rest of this module, but is - compatible with gdbm -*/ -static int tdb_exists_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash) -{ - struct list_struct rec; - - if (tdb_find_lock_hash(tdb, key, hash, F_RDLCK, &rec) == 0) - return 0; - tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK); - return 1; -} - -int tdb_exists(struct tdb_context *tdb, TDB_DATA key) -{ - uint32_t hash = tdb->hash_fn(&key); - return tdb_exists_hash(tdb, key, hash); -} - -/* actually delete an entry in the database given the offset */ -int tdb_do_delete(struct tdb_context *tdb, tdb_off_t rec_ptr, struct list_struct*rec) -{ - tdb_off_t last_ptr, i; - struct list_struct lastrec; - - if (tdb->read_only || tdb->traverse_read) return -1; - - if (tdb_write_lock_record(tdb, rec_ptr) == -1) { - /* Someone traversing here: mark it as dead */ - rec->magic = TDB_DEAD_MAGIC; - return tdb_rec_write(tdb, rec_ptr, rec); - } - if (tdb_write_unlock_record(tdb, rec_ptr) != 0) - return -1; - - /* find previous record in hash chain */ - if (tdb_ofs_read(tdb, TDB_HASH_TOP(rec->full_hash), &i) == -1) - return -1; - for (last_ptr = 0; i != rec_ptr; last_ptr = i, i = lastrec.next) - if (tdb_rec_read(tdb, i, &lastrec) == -1) - return -1; - - /* unlink it: next ptr is at start of record. */ - if (last_ptr == 0) - last_ptr = TDB_HASH_TOP(rec->full_hash); - if (tdb_ofs_write(tdb, last_ptr, &rec->next) == -1) - return -1; - - /* recover the space */ - if (tdb_free(tdb, rec_ptr, rec) == -1) - return -1; - return 0; -} - -static int tdb_count_dead(struct tdb_context *tdb, uint32_t hash) -{ - int res = 0; - tdb_off_t rec_ptr; - struct list_struct rec; - - /* read in the hash top */ - if (tdb_ofs_read(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1) - return 0; - - while (rec_ptr) { - if (tdb_rec_read(tdb, rec_ptr, &rec) == -1) - return 0; - - if (rec.magic == TDB_DEAD_MAGIC) { - res += 1; - } - rec_ptr = rec.next; - } - return res; -} - -/* - * Purge all DEAD records from a hash chain - */ -static int tdb_purge_dead(struct tdb_context *tdb, uint32_t hash) -{ - int res = -1; - struct list_struct rec; - tdb_off_t rec_ptr; - - if (tdb_lock(tdb, -1, F_WRLCK) == -1) { - return -1; - } - - /* read in the hash top */ - if (tdb_ofs_read(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1) - goto fail; - - while (rec_ptr) { - tdb_off_t next; - - if (tdb_rec_read(tdb, rec_ptr, &rec) == -1) { - goto fail; - } - - next = rec.next; - - if (rec.magic == TDB_DEAD_MAGIC - && tdb_do_delete(tdb, rec_ptr, &rec) == -1) { - goto fail; - } - rec_ptr = next; - } - res = 0; - fail: - tdb_unlock(tdb, -1, F_WRLCK); - return res; -} - -/* delete an entry in the database given a key */ -static int tdb_delete_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash) -{ - tdb_off_t rec_ptr; - struct list_struct rec; - int ret; - - if (tdb->max_dead_records != 0) { - - /* - * Allow for some dead records per hash chain, mainly for - * tdb's with a very high create/delete rate like locking.tdb. - */ - - if (tdb_lock(tdb, BUCKET(hash), F_WRLCK) == -1) - return -1; - - if (tdb_count_dead(tdb, hash) >= tdb->max_dead_records) { - /* - * Don't let the per-chain freelist grow too large, - * delete all existing dead records - */ - tdb_purge_dead(tdb, hash); - } - - if (!(rec_ptr = tdb_find(tdb, key, hash, &rec))) { - tdb_unlock(tdb, BUCKET(hash), F_WRLCK); - return -1; - } - - /* - * Just mark the record as dead. - */ - rec.magic = TDB_DEAD_MAGIC; - ret = tdb_rec_write(tdb, rec_ptr, &rec); - } - else { - if (!(rec_ptr = tdb_find_lock_hash(tdb, key, hash, F_WRLCK, - &rec))) - return -1; - - ret = tdb_do_delete(tdb, rec_ptr, &rec); - } - - if (ret == 0) { - tdb_increment_seqnum(tdb); - } - - if (tdb_unlock(tdb, BUCKET(rec.full_hash), F_WRLCK) != 0) - TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_delete: WARNING tdb_unlock failed!\n")); - return ret; -} - -int tdb_delete(struct tdb_context *tdb, TDB_DATA key) -{ - uint32_t hash = tdb->hash_fn(&key); - return tdb_delete_hash(tdb, key, hash); -} - -/* - * See if we have a dead record around with enough space - */ -static tdb_off_t tdb_find_dead(struct tdb_context *tdb, uint32_t hash, - struct list_struct *r, tdb_len_t length) -{ - tdb_off_t rec_ptr; - - /* read in the hash top */ - if (tdb_ofs_read(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1) - return 0; - - /* keep looking until we find the right record */ - while (rec_ptr) { - if (tdb_rec_read(tdb, rec_ptr, r) == -1) - return 0; - - if (TDB_DEAD(r) && r->rec_len >= length) { - /* - * First fit for simple coding, TODO: change to best - * fit - */ - return rec_ptr; - } - rec_ptr = r->next; - } - return 0; -} - -/* store an element in the database, replacing any existing element - with the same key - - return 0 on success, -1 on failure -*/ -int tdb_store(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf, int flag) -{ - struct list_struct rec; - uint32_t hash; - tdb_off_t rec_ptr; - char *p = NULL; - int ret = -1; - - if (tdb->read_only || tdb->traverse_read) { - tdb->ecode = TDB_ERR_RDONLY; - return -1; - } - - /* find which hash bucket it is in */ - hash = tdb->hash_fn(&key); - if (tdb_lock(tdb, BUCKET(hash), F_WRLCK) == -1) - return -1; - - /* check for it existing, on insert. */ - if (flag == TDB_INSERT) { - if (tdb_exists_hash(tdb, key, hash)) { - tdb->ecode = TDB_ERR_EXISTS; - goto fail; - } - } else { - /* first try in-place update, on modify or replace. */ - if (tdb_update_hash(tdb, key, hash, dbuf) == 0) { - goto done; - } - if (tdb->ecode == TDB_ERR_NOEXIST && - flag == TDB_MODIFY) { - /* if the record doesn't exist and we are in TDB_MODIFY mode then - we should fail the store */ - goto fail; - } - } - /* reset the error code potentially set by the tdb_update() */ - tdb->ecode = TDB_SUCCESS; - - /* delete any existing record - if it doesn't exist we don't - care. Doing this first reduces fragmentation, and avoids - coalescing with `allocated' block before it's updated. */ - if (flag != TDB_INSERT) - tdb_delete_hash(tdb, key, hash); - - /* Copy key+value *before* allocating free space in case malloc - fails and we are left with a dead spot in the tdb. */ - - if (!(p = (char *)malloc(key.dsize + dbuf.dsize))) { - tdb->ecode = TDB_ERR_OOM; - goto fail; - } - - memcpy(p, key.dptr, key.dsize); - if (dbuf.dsize) - memcpy(p+key.dsize, dbuf.dptr, dbuf.dsize); - - if (tdb->max_dead_records != 0) { - /* - * Allow for some dead records per hash chain, look if we can - * find one that can hold the new record. We need enough space - * for key, data and tailer. If we find one, we don't have to - * consult the central freelist. - */ - rec_ptr = tdb_find_dead( - tdb, hash, &rec, - key.dsize + dbuf.dsize + sizeof(tdb_off_t)); - - if (rec_ptr != 0) { - rec.key_len = key.dsize; - rec.data_len = dbuf.dsize; - rec.full_hash = hash; - rec.magic = TDB_MAGIC; - if (tdb_rec_write(tdb, rec_ptr, &rec) == -1 - || tdb->methods->tdb_write( - tdb, rec_ptr + sizeof(rec), - p, key.dsize + dbuf.dsize) == -1) { - goto fail; - } - goto done; - } - } - - /* - * We have to allocate some space from the freelist, so this means we - * have to lock it. Use the chance to purge all the DEAD records from - * the hash chain under the freelist lock. - */ - - if (tdb_lock(tdb, -1, F_WRLCK) == -1) { - goto fail; - } - - if ((tdb->max_dead_records != 0) - && (tdb_purge_dead(tdb, hash) == -1)) { - tdb_unlock(tdb, -1, F_WRLCK); - goto fail; - } - - /* we have to allocate some space */ - rec_ptr = tdb_allocate(tdb, key.dsize + dbuf.dsize, &rec); - - tdb_unlock(tdb, -1, F_WRLCK); - - if (rec_ptr == 0) { - goto fail; - } - - /* Read hash top into next ptr */ - if (tdb_ofs_read(tdb, TDB_HASH_TOP(hash), &rec.next) == -1) - goto fail; - - rec.key_len = key.dsize; - rec.data_len = dbuf.dsize; - rec.full_hash = hash; - rec.magic = TDB_MAGIC; - - /* write out and point the top of the hash chain at it */ - if (tdb_rec_write(tdb, rec_ptr, &rec) == -1 - || tdb->methods->tdb_write(tdb, rec_ptr+sizeof(rec), p, key.dsize+dbuf.dsize)==-1 - || tdb_ofs_write(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1) { - /* Need to tdb_unallocate() here */ - goto fail; - } - - done: - ret = 0; - fail: - if (ret == 0) { - tdb_increment_seqnum(tdb); - } - - SAFE_FREE(p); - tdb_unlock(tdb, BUCKET(hash), F_WRLCK); - return ret; -} - - -/* Append to an entry. Create if not exist. */ -int tdb_append(struct tdb_context *tdb, TDB_DATA key, TDB_DATA new_dbuf) -{ - uint32_t hash; - TDB_DATA dbuf; - int ret = -1; - - /* find which hash bucket it is in */ - hash = tdb->hash_fn(&key); - if (tdb_lock(tdb, BUCKET(hash), F_WRLCK) == -1) - return -1; - - dbuf = tdb_fetch(tdb, key); - - if (dbuf.dptr == NULL) { - dbuf.dptr = (unsigned char *)malloc(new_dbuf.dsize); - } else { - unsigned char *new_dptr = (unsigned char *)realloc(dbuf.dptr, - dbuf.dsize + new_dbuf.dsize); - if (new_dptr == NULL) { - free(dbuf.dptr); - } - dbuf.dptr = new_dptr; - } - - if (dbuf.dptr == NULL) { - tdb->ecode = TDB_ERR_OOM; - goto failed; - } - - memcpy(dbuf.dptr + dbuf.dsize, new_dbuf.dptr, new_dbuf.dsize); - dbuf.dsize += new_dbuf.dsize; - - ret = tdb_store(tdb, key, dbuf, 0); - -failed: - tdb_unlock(tdb, BUCKET(hash), F_WRLCK); - SAFE_FREE(dbuf.dptr); - return ret; -} - - -/* - return the name of the current tdb file - useful for external logging functions -*/ -const char *tdb_name(struct tdb_context *tdb) -{ - return tdb->name; -} - -/* - return the underlying file descriptor being used by tdb, or -1 - useful for external routines that want to check the device/inode - of the fd -*/ -int tdb_fd(struct tdb_context *tdb) -{ - return tdb->fd; -} - -/* - return the current logging function - useful for external tdb routines that wish to log tdb errors -*/ -tdb_log_func tdb_log_fn(struct tdb_context *tdb) -{ - return tdb->log.log_fn; -} - - -/* - get the tdb sequence number. Only makes sense if the writers opened - with TDB_SEQNUM set. Note that this sequence number will wrap quite - quickly, so it should only be used for a 'has something changed' - test, not for code that relies on the count of the number of changes - made. If you want a counter then use a tdb record. - - The aim of this sequence number is to allow for a very lightweight - test of a possible tdb change. -*/ -int tdb_get_seqnum(struct tdb_context *tdb) -{ - tdb_off_t seqnum=0; - - tdb_ofs_read(tdb, TDB_SEQNUM_OFS, &seqnum); - return seqnum; -} - -int tdb_hash_size(struct tdb_context *tdb) -{ - return tdb->header.hash_size; -} - -size_t tdb_map_size(struct tdb_context *tdb) -{ - return tdb->map_size; -} - -int tdb_get_flags(struct tdb_context *tdb) -{ - return tdb->flags; -} - diff --git a/source/lib/tdb/common/tdb_private.h b/source/lib/tdb/common/tdb_private.h deleted file mode 100644 index 2b91ebd0bac..00000000000 --- a/source/lib/tdb/common/tdb_private.h +++ /dev/null @@ -1,204 +0,0 @@ - /* - Unix SMB/CIFS implementation. - - trivial database library - private includes - - Copyright (C) Andrew Tridgell 2005 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include "replace.h" -#include "system/filesys.h" -#include "system/time.h" -#include "system/shmem.h" -#include "system/select.h" -#include "tdb.h" - -#ifndef HAVE_GETPAGESIZE -#define getpagesize() 0x2000 -#endif - -typedef uint32_t tdb_len_t; -typedef uint32_t tdb_off_t; - -#define TDB_MAGIC_FOOD "TDB file\n" -#define TDB_VERSION (0x26011967 + 6) -#define TDB_MAGIC (0x26011999U) -#define TDB_FREE_MAGIC (~TDB_MAGIC) -#define TDB_DEAD_MAGIC (0xFEE1DEAD) -#define TDB_RECOVERY_MAGIC (0xf53bc0e7U) -#define TDB_ALIGNMENT 4 -#define MIN_REC_SIZE (2*sizeof(struct list_struct) + TDB_ALIGNMENT) -#define DEFAULT_HASH_SIZE 131 -#define FREELIST_TOP (sizeof(struct tdb_header)) -#define TDB_ALIGN(x,a) (((x) + (a)-1) & ~((a)-1)) -#define TDB_BYTEREV(x) (((((x)&0xff)<<24)|((x)&0xFF00)<<8)|(((x)>>8)&0xFF00)|((x)>>24)) -#define TDB_DEAD(r) ((r)->magic == TDB_DEAD_MAGIC) -#define TDB_BAD_MAGIC(r) ((r)->magic != TDB_MAGIC && !TDB_DEAD(r)) -#define TDB_HASH_TOP(hash) (FREELIST_TOP + (BUCKET(hash)+1)*sizeof(tdb_off_t)) -#define TDB_HASHTABLE_SIZE(tdb) ((tdb->header.hash_size+1)*sizeof(tdb_off_t)) -#define TDB_DATA_START(hash_size) TDB_HASH_TOP(hash_size-1) -#define TDB_RECOVERY_HEAD offsetof(struct tdb_header, recovery_start) -#define TDB_SEQNUM_OFS offsetof(struct tdb_header, sequence_number) -#define TDB_PAD_BYTE 0x42 -#define TDB_PAD_U32 0x42424242 - -/* NB assumes there is a local variable called "tdb" that is the - * current context, also takes doubly-parenthesized print-style - * argument. */ -#define TDB_LOG(x) tdb->log.log_fn x - -/* lock offsets */ -#define GLOBAL_LOCK 0 -#define ACTIVE_LOCK 4 -#define TRANSACTION_LOCK 8 - -/* free memory if the pointer is valid and zero the pointer */ -#ifndef SAFE_FREE -#define SAFE_FREE(x) do { if ((x) != NULL) {free(x); (x)=NULL;} } while(0) -#endif - -#define BUCKET(hash) ((hash) % tdb->header.hash_size) - -#define DOCONV() (tdb->flags & TDB_CONVERT) -#define CONVERT(x) (DOCONV() ? tdb_convert(&x, sizeof(x)) : &x) - - -/* the body of the database is made of one list_struct for the free space - plus a separate data list for each hash value */ -struct list_struct { - tdb_off_t next; /* offset of the next record in the list */ - tdb_len_t rec_len; /* total byte length of record */ - tdb_len_t key_len; /* byte length of key */ - tdb_len_t data_len; /* byte length of data */ - uint32_t full_hash; /* the full 32 bit hash of the key */ - uint32_t magic; /* try to catch errors */ - /* the following union is implied: - union { - char record[rec_len]; - struct { - char key[key_len]; - char data[data_len]; - } - uint32_t totalsize; (tailer) - } - */ -}; - - -/* this is stored at the front of every database */ -struct tdb_header { - char magic_food[32]; /* for /etc/magic */ - uint32_t version; /* version of the code */ - uint32_t hash_size; /* number of hash entries */ - tdb_off_t rwlocks; /* obsolete - kept to detect old formats */ - tdb_off_t recovery_start; /* offset of transaction recovery region */ - tdb_off_t sequence_number; /* used when TDB_SEQNUM is set */ - tdb_off_t reserved[29]; -}; - -struct tdb_lock_type { - int list; - uint32_t count; - uint32_t ltype; -}; - -struct tdb_traverse_lock { - struct tdb_traverse_lock *next; - uint32_t off; - uint32_t hash; - int lock_rw; -}; - - -struct tdb_methods { - int (*tdb_read)(struct tdb_context *, tdb_off_t , void *, tdb_len_t , int ); - int (*tdb_write)(struct tdb_context *, tdb_off_t, const void *, tdb_len_t); - void (*next_hash_chain)(struct tdb_context *, uint32_t *); - int (*tdb_oob)(struct tdb_context *, tdb_off_t , int ); - int (*tdb_expand_file)(struct tdb_context *, tdb_off_t , tdb_off_t ); - int (*tdb_brlock)(struct tdb_context *, tdb_off_t , int, int, int, size_t); -}; - -struct tdb_context { - char *name; /* the name of the database */ - void *map_ptr; /* where it is currently mapped */ - int fd; /* open file descriptor for the database */ - tdb_len_t map_size; /* how much space has been mapped */ - int read_only; /* opened read-only */ - int traverse_read; /* read-only traversal */ - struct tdb_lock_type global_lock; - int num_lockrecs; - struct tdb_lock_type *lockrecs; /* only real locks, all with count>0 */ - enum TDB_ERROR ecode; /* error code for last tdb error */ - struct tdb_header header; /* a cached copy of the header */ - uint32_t flags; /* the flags passed to tdb_open */ - struct tdb_traverse_lock travlocks; /* current traversal locks */ - struct tdb_context *next; /* all tdbs to avoid multiple opens */ - dev_t device; /* uniquely identifies this tdb */ - ino_t inode; /* uniquely identifies this tdb */ - struct tdb_logging_context log; - unsigned int (*hash_fn)(TDB_DATA *key); - int open_flags; /* flags used in the open - needed by reopen */ - unsigned int num_locks; /* number of chain locks held */ - const struct tdb_methods *methods; - struct tdb_transaction *transaction; - int page_size; - int max_dead_records; -}; - - -/* - internal prototypes -*/ -int tdb_munmap(struct tdb_context *tdb); -void tdb_mmap(struct tdb_context *tdb); -int tdb_lock(struct tdb_context *tdb, int list, int ltype); -int tdb_unlock(struct tdb_context *tdb, int list, int ltype); -int tdb_brlock(struct tdb_context *tdb, tdb_off_t offset, int rw_type, int lck_type, int probe, size_t len); -int tdb_brlock_upgrade(struct tdb_context *tdb, tdb_off_t offset, size_t len); -int tdb_write_lock_record(struct tdb_context *tdb, tdb_off_t off); -int tdb_write_unlock_record(struct tdb_context *tdb, tdb_off_t off); -int tdb_ofs_read(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d); -int tdb_ofs_write(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d); -void *tdb_convert(void *buf, uint32_t size); -int tdb_free(struct tdb_context *tdb, tdb_off_t offset, struct list_struct *rec); -tdb_off_t tdb_allocate(struct tdb_context *tdb, tdb_len_t length, struct list_struct *rec); -int tdb_ofs_read(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d); -int tdb_ofs_write(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d); -int tdb_lock_record(struct tdb_context *tdb, tdb_off_t off); -int tdb_unlock_record(struct tdb_context *tdb, tdb_off_t off); -int tdb_rec_read(struct tdb_context *tdb, tdb_off_t offset, struct list_struct *rec); -int tdb_rec_write(struct tdb_context *tdb, tdb_off_t offset, struct list_struct *rec); -int tdb_do_delete(struct tdb_context *tdb, tdb_off_t rec_ptr, struct list_struct *rec); -unsigned char *tdb_alloc_read(struct tdb_context *tdb, tdb_off_t offset, tdb_len_t len); -int tdb_parse_data(struct tdb_context *tdb, TDB_DATA key, - tdb_off_t offset, tdb_len_t len, - int (*parser)(TDB_DATA key, TDB_DATA data, - void *private_data), - void *private_data); -tdb_off_t tdb_find_lock_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash, int locktype, - struct list_struct *rec); -void tdb_io_init(struct tdb_context *tdb); -int tdb_expand(struct tdb_context *tdb, tdb_off_t size); -int tdb_rec_free_read(struct tdb_context *tdb, tdb_off_t off, - struct list_struct *rec); - - diff --git a/source/lib/tdb/common/transaction.c b/source/lib/tdb/common/transaction.c deleted file mode 100644 index 9530b8b2442..00000000000 --- a/source/lib/tdb/common/transaction.c +++ /dev/null @@ -1,1053 +0,0 @@ - /* - Unix SMB/CIFS implementation. - - trivial database library - - Copyright (C) Andrew Tridgell 2005 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include "tdb_private.h" - -/* - transaction design: - - - only allow a single transaction at a time per database. This makes - using the transaction API simpler, as otherwise the caller would - have to cope with temporary failures in transactions that conflict - with other current transactions - - - keep the transaction recovery information in the same file as the - database, using a special 'transaction recovery' record pointed at - by the header. This removes the need for extra journal files as - used by some other databases - - - dynamically allocated the transaction recover record, re-using it - for subsequent transactions. If a larger record is needed then - tdb_free() the old record to place it on the normal tdb freelist - before allocating the new record - - - during transactions, keep a linked list of writes all that have - been performed by intercepting all tdb_write() calls. The hooked - transaction versions of tdb_read() and tdb_write() check this - linked list and try to use the elements of the list in preference - to the real database. - - - don't allow any locks to be held when a transaction starts, - otherwise we can end up with deadlock (plus lack of lock nesting - in posix locks would mean the lock is lost) - - - if the caller gains a lock during the transaction but doesn't - release it then fail the commit - - - allow for nested calls to tdb_transaction_start(), re-using the - existing transaction record. If the inner transaction is cancelled - then a subsequent commit will fail - - - keep a mirrored copy of the tdb hash chain heads to allow for the - fast hash heads scan on traverse, updating the mirrored copy in - the transaction version of tdb_write - - - allow callers to mix transaction and non-transaction use of tdb, - although once a transaction is started then an exclusive lock is - gained until the transaction is committed or cancelled - - - the commit stategy involves first saving away all modified data - into a linearised buffer in the transaction recovery area, then - marking the transaction recovery area with a magic value to - indicate a valid recovery record. In total 4 fsync/msync calls are - needed per commit to prevent race conditions. It might be possible - to reduce this to 3 or even 2 with some more work. - - - check for a valid recovery record on open of the tdb, while the - global lock is held. Automatically recover from the transaction - recovery area if needed, then continue with the open as - usual. This allows for smooth crash recovery with no administrator - intervention. - - - if TDB_NOSYNC is passed to flags in tdb_open then transactions are - still available, but no transaction recovery area is used and no - fsync/msync calls are made. - -*/ - -struct tdb_transaction_el { - struct tdb_transaction_el *next, *prev; - tdb_off_t offset; - tdb_len_t length; - unsigned char *data; -}; - -/* - hold the context of any current transaction -*/ -struct tdb_transaction { - /* we keep a mirrored copy of the tdb hash heads here so - tdb_next_hash_chain() can operate efficiently */ - uint32_t *hash_heads; - - /* the original io methods - used to do IOs to the real db */ - const struct tdb_methods *io_methods; - - /* the list of transaction elements. We use a doubly linked - list with a last pointer to allow us to keep the list - ordered, with first element at the front of the list. It - needs to be doubly linked as the read/write traversals need - to be backwards, while the commit needs to be forwards */ - struct tdb_transaction_el *elements, *elements_last; - - /* non-zero when an internal transaction error has - occurred. All write operations will then fail until the - transaction is ended */ - int transaction_error; - - /* when inside a transaction we need to keep track of any - nested tdb_transaction_start() calls, as these are allowed, - but don't create a new transaction */ - int nesting; - - /* old file size before transaction */ - tdb_len_t old_map_size; -}; - - -/* - read while in a transaction. We need to check first if the data is in our list - of transaction elements, then if not do a real read -*/ -static int transaction_read(struct tdb_context *tdb, tdb_off_t off, void *buf, - tdb_len_t len, int cv) -{ - struct tdb_transaction_el *el; - - /* we need to walk the list backwards to get the most recent data */ - for (el=tdb->transaction->elements_last;el;el=el->prev) { - tdb_len_t partial; - - if (off+len <= el->offset) { - continue; - } - if (off >= el->offset + el->length) { - continue; - } - - /* an overlapping read - needs to be split into up to - 2 reads and a memcpy */ - if (off < el->offset) { - partial = el->offset - off; - if (transaction_read(tdb, off, buf, partial, cv) != 0) { - goto fail; - } - len -= partial; - off += partial; - buf = (void *)(partial + (char *)buf); - } - if (off + len <= el->offset + el->length) { - partial = len; - } else { - partial = el->offset + el->length - off; - } - memcpy(buf, el->data + (off - el->offset), partial); - if (cv) { - tdb_convert(buf, len); - } - len -= partial; - off += partial; - buf = (void *)(partial + (char *)buf); - - if (len != 0 && transaction_read(tdb, off, buf, len, cv) != 0) { - goto fail; - } - - return 0; - } - - /* its not in the transaction elements - do a real read */ - return tdb->transaction->io_methods->tdb_read(tdb, off, buf, len, cv); - -fail: - TDB_LOG((tdb, TDB_DEBUG_FATAL, "transaction_read: failed at off=%d len=%d\n", off, len)); - tdb->ecode = TDB_ERR_IO; - tdb->transaction->transaction_error = 1; - return -1; -} - - -/* - write while in a transaction -*/ -static int transaction_write(struct tdb_context *tdb, tdb_off_t off, - const void *buf, tdb_len_t len) -{ - struct tdb_transaction_el *el, *best_el=NULL; - - if (len == 0) { - return 0; - } - - /* if the write is to a hash head, then update the transaction - hash heads */ - if (len == sizeof(tdb_off_t) && off >= FREELIST_TOP && - off < FREELIST_TOP+TDB_HASHTABLE_SIZE(tdb)) { - uint32_t chain = (off-FREELIST_TOP) / sizeof(tdb_off_t); - memcpy(&tdb->transaction->hash_heads[chain], buf, len); - } - - /* first see if we can replace an existing entry */ - for (el=tdb->transaction->elements_last;el;el=el->prev) { - tdb_len_t partial; - - if (best_el == NULL && off == el->offset+el->length) { - best_el = el; - } - - if (off+len <= el->offset) { - continue; - } - if (off >= el->offset + el->length) { - continue; - } - - /* an overlapping write - needs to be split into up to - 2 writes and a memcpy */ - if (off < el->offset) { - partial = el->offset - off; - if (transaction_write(tdb, off, buf, partial) != 0) { - goto fail; - } - len -= partial; - off += partial; - buf = (const void *)(partial + (const char *)buf); - } - if (off + len <= el->offset + el->length) { - partial = len; - } else { - partial = el->offset + el->length - off; - } - memcpy(el->data + (off - el->offset), buf, partial); - len -= partial; - off += partial; - buf = (const void *)(partial + (const char *)buf); - - if (len != 0 && transaction_write(tdb, off, buf, len) != 0) { - goto fail; - } - - return 0; - } - - /* see if we can append the new entry to an existing entry */ - if (best_el && best_el->offset + best_el->length == off && - (off+len < tdb->transaction->old_map_size || - off > tdb->transaction->old_map_size)) { - unsigned char *data = best_el->data; - el = best_el; - el->data = (unsigned char *)realloc(el->data, - el->length + len); - if (el->data == NULL) { - tdb->ecode = TDB_ERR_OOM; - tdb->transaction->transaction_error = 1; - el->data = data; - return -1; - } - if (buf) { - memcpy(el->data + el->length, buf, len); - } else { - memset(el->data + el->length, TDB_PAD_BYTE, len); - } - el->length += len; - return 0; - } - - /* add a new entry at the end of the list */ - el = (struct tdb_transaction_el *)malloc(sizeof(*el)); - if (el == NULL) { - tdb->ecode = TDB_ERR_OOM; - tdb->transaction->transaction_error = 1; - return -1; - } - el->next = NULL; - el->prev = tdb->transaction->elements_last; - el->offset = off; - el->length = len; - el->data = (unsigned char *)malloc(len); - if (el->data == NULL) { - free(el); - tdb->ecode = TDB_ERR_OOM; - tdb->transaction->transaction_error = 1; - return -1; - } - if (buf) { - memcpy(el->data, buf, len); - } else { - memset(el->data, TDB_PAD_BYTE, len); - } - if (el->prev) { - el->prev->next = el; - } else { - tdb->transaction->elements = el; - } - tdb->transaction->elements_last = el; - return 0; - -fail: - TDB_LOG((tdb, TDB_DEBUG_FATAL, "transaction_write: failed at off=%d len=%d\n", off, len)); - tdb->ecode = TDB_ERR_IO; - tdb->transaction->transaction_error = 1; - return -1; -} - -/* - accelerated hash chain head search, using the cached hash heads -*/ -static void transaction_next_hash_chain(struct tdb_context *tdb, uint32_t *chain) -{ - uint32_t h = *chain; - for (;h < tdb->header.hash_size;h++) { - /* the +1 takes account of the freelist */ - if (0 != tdb->transaction->hash_heads[h+1]) { - break; - } - } - (*chain) = h; -} - -/* - out of bounds check during a transaction -*/ -static int transaction_oob(struct tdb_context *tdb, tdb_off_t len, int probe) -{ - if (len <= tdb->map_size) { - return 0; - } - return TDB_ERRCODE(TDB_ERR_IO, -1); -} - -/* - transaction version of tdb_expand(). -*/ -static int transaction_expand_file(struct tdb_context *tdb, tdb_off_t size, - tdb_off_t addition) -{ - /* add a write to the transaction elements, so subsequent - reads see the zero data */ - if (transaction_write(tdb, size, NULL, addition) != 0) { - return -1; - } - - return 0; -} - -/* - brlock during a transaction - ignore them -*/ -static int transaction_brlock(struct tdb_context *tdb, tdb_off_t offset, - int rw_type, int lck_type, int probe, size_t len) -{ - return 0; -} - -static const struct tdb_methods transaction_methods = { - transaction_read, - transaction_write, - transaction_next_hash_chain, - transaction_oob, - transaction_expand_file, - transaction_brlock -}; - - -/* - start a tdb transaction. No token is returned, as only a single - transaction is allowed to be pending per tdb_context -*/ -int tdb_transaction_start(struct tdb_context *tdb) -{ - /* some sanity checks */ - if (tdb->read_only || (tdb->flags & TDB_INTERNAL) || tdb->traverse_read) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: cannot start a transaction on a read-only or internal db\n")); - tdb->ecode = TDB_ERR_EINVAL; - return -1; - } - - /* cope with nested tdb_transaction_start() calls */ - if (tdb->transaction != NULL) { - tdb->transaction->nesting++; - TDB_LOG((tdb, TDB_DEBUG_TRACE, "tdb_transaction_start: nesting %d\n", - tdb->transaction->nesting)); - return 0; - } - - if (tdb->num_locks != 0 || tdb->global_lock.count) { - /* the caller must not have any locks when starting a - transaction as otherwise we'll be screwed by lack - of nested locks in posix */ - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: cannot start a transaction with locks held\n")); - tdb->ecode = TDB_ERR_LOCK; - return -1; - } - - if (tdb->travlocks.next != NULL) { - /* you cannot use transactions inside a traverse (although you can use - traverse inside a transaction) as otherwise you can end up with - deadlock */ - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: cannot start a transaction within a traverse\n")); - tdb->ecode = TDB_ERR_LOCK; - return -1; - } - - tdb->transaction = (struct tdb_transaction *) - calloc(sizeof(struct tdb_transaction), 1); - if (tdb->transaction == NULL) { - tdb->ecode = TDB_ERR_OOM; - return -1; - } - - /* get the transaction write lock. This is a blocking lock. As - discussed with Volker, there are a number of ways we could - make this async, which we will probably do in the future */ - if (tdb_brlock(tdb, TRANSACTION_LOCK, F_WRLCK, F_SETLKW, 0, 1) == -1) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: failed to get transaction lock\n")); - tdb->ecode = TDB_ERR_LOCK; - SAFE_FREE(tdb->transaction); - return -1; - } - - /* get a read lock from the freelist to the end of file. This - is upgraded to a write lock during the commit */ - if (tdb_brlock(tdb, FREELIST_TOP, F_RDLCK, F_SETLKW, 0, 0) == -1) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: failed to get hash locks\n")); - tdb->ecode = TDB_ERR_LOCK; - goto fail; - } - - /* setup a copy of the hash table heads so the hash scan in - traverse can be fast */ - tdb->transaction->hash_heads = (uint32_t *) - calloc(tdb->header.hash_size+1, sizeof(uint32_t)); - if (tdb->transaction->hash_heads == NULL) { - tdb->ecode = TDB_ERR_OOM; - goto fail; - } - if (tdb->methods->tdb_read(tdb, FREELIST_TOP, tdb->transaction->hash_heads, - TDB_HASHTABLE_SIZE(tdb), 0) != 0) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_start: failed to read hash heads\n")); - tdb->ecode = TDB_ERR_IO; - goto fail; - } - - /* make sure we know about any file expansions already done by - anyone else */ - tdb->methods->tdb_oob(tdb, tdb->map_size + 1, 1); - tdb->transaction->old_map_size = tdb->map_size; - - /* finally hook the io methods, replacing them with - transaction specific methods */ - tdb->transaction->io_methods = tdb->methods; - tdb->methods = &transaction_methods; - - /* by calling this transaction write here, we ensure that we don't grow the - transaction linked list due to hash table updates */ - if (transaction_write(tdb, FREELIST_TOP, tdb->transaction->hash_heads, - TDB_HASHTABLE_SIZE(tdb)) != 0) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_start: failed to prime hash table\n")); - tdb->ecode = TDB_ERR_IO; - goto fail; - } - - return 0; - -fail: - tdb_brlock(tdb, FREELIST_TOP, F_UNLCK, F_SETLKW, 0, 0); - tdb_brlock(tdb, TRANSACTION_LOCK, F_UNLCK, F_SETLKW, 0, 1); - SAFE_FREE(tdb->transaction->hash_heads); - SAFE_FREE(tdb->transaction); - return -1; -} - - -/* - cancel the current transaction -*/ -int tdb_transaction_cancel(struct tdb_context *tdb) -{ - if (tdb->transaction == NULL) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_cancel: no transaction\n")); - return -1; - } - - if (tdb->transaction->nesting != 0) { - tdb->transaction->transaction_error = 1; - tdb->transaction->nesting--; - return 0; - } - - tdb->map_size = tdb->transaction->old_map_size; - - /* free all the transaction elements */ - while (tdb->transaction->elements) { - struct tdb_transaction_el *el = tdb->transaction->elements; - tdb->transaction->elements = el->next; - free(el->data); - free(el); - } - - /* remove any global lock created during the transaction */ - if (tdb->global_lock.count != 0) { - tdb_brlock(tdb, FREELIST_TOP, F_UNLCK, F_SETLKW, 0, 4*tdb->header.hash_size); - tdb->global_lock.count = 0; - } - - /* remove any locks created during the transaction */ - if (tdb->num_locks != 0) { - int i; - for (i=0;i<tdb->num_lockrecs;i++) { - tdb_brlock(tdb,FREELIST_TOP+4*tdb->lockrecs[i].list, - F_UNLCK,F_SETLKW, 0, 1); - } - tdb->num_locks = 0; - tdb->num_lockrecs = 0; - SAFE_FREE(tdb->lockrecs); - } - - /* restore the normal io methods */ - tdb->methods = tdb->transaction->io_methods; - - tdb_brlock(tdb, FREELIST_TOP, F_UNLCK, F_SETLKW, 0, 0); - tdb_brlock(tdb, TRANSACTION_LOCK, F_UNLCK, F_SETLKW, 0, 1); - SAFE_FREE(tdb->transaction->hash_heads); - SAFE_FREE(tdb->transaction); - - return 0; -} - -/* - sync to disk -*/ -static int transaction_sync(struct tdb_context *tdb, tdb_off_t offset, tdb_len_t length) -{ - if (fsync(tdb->fd) != 0) { - tdb->ecode = TDB_ERR_IO; - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction: fsync failed\n")); - return -1; - } -#ifdef MS_SYNC - if (tdb->map_ptr) { - tdb_off_t moffset = offset & ~(tdb->page_size-1); - if (msync(moffset + (char *)tdb->map_ptr, - length + (offset - moffset), MS_SYNC) != 0) { - tdb->ecode = TDB_ERR_IO; - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction: msync failed - %s\n", - strerror(errno))); - return -1; - } - } -#endif - return 0; -} - - -/* - work out how much space the linearised recovery data will consume -*/ -static tdb_len_t tdb_recovery_size(struct tdb_context *tdb) -{ - struct tdb_transaction_el *el; - tdb_len_t recovery_size = 0; - - recovery_size = sizeof(uint32_t); - for (el=tdb->transaction->elements;el;el=el->next) { - if (el->offset >= tdb->transaction->old_map_size) { - continue; - } - recovery_size += 2*sizeof(tdb_off_t) + el->length; - } - - return recovery_size; -} - -/* - allocate the recovery area, or use an existing recovery area if it is - large enough -*/ -static int tdb_recovery_allocate(struct tdb_context *tdb, - tdb_len_t *recovery_size, - tdb_off_t *recovery_offset, - tdb_len_t *recovery_max_size) -{ - struct list_struct rec; - const struct tdb_methods *methods = tdb->transaction->io_methods; - tdb_off_t recovery_head; - - if (tdb_ofs_read(tdb, TDB_RECOVERY_HEAD, &recovery_head) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to read recovery head\n")); - return -1; - } - - rec.rec_len = 0; - - if (recovery_head != 0 && - methods->tdb_read(tdb, recovery_head, &rec, sizeof(rec), DOCONV()) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to read recovery record\n")); - return -1; - } - - *recovery_size = tdb_recovery_size(tdb); - - if (recovery_head != 0 && *recovery_size <= rec.rec_len) { - /* it fits in the existing area */ - *recovery_max_size = rec.rec_len; - *recovery_offset = recovery_head; - return 0; - } - - /* we need to free up the old recovery area, then allocate a - new one at the end of the file. Note that we cannot use - tdb_allocate() to allocate the new one as that might return - us an area that is being currently used (as of the start of - the transaction) */ - if (recovery_head != 0) { - if (tdb_free(tdb, recovery_head, &rec) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to free previous recovery area\n")); - return -1; - } - } - - /* the tdb_free() call might have increased the recovery size */ - *recovery_size = tdb_recovery_size(tdb); - - /* round up to a multiple of page size */ - *recovery_max_size = TDB_ALIGN(sizeof(rec) + *recovery_size, tdb->page_size) - sizeof(rec); - *recovery_offset = tdb->map_size; - recovery_head = *recovery_offset; - - if (methods->tdb_expand_file(tdb, tdb->transaction->old_map_size, - (tdb->map_size - tdb->transaction->old_map_size) + - sizeof(rec) + *recovery_max_size) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to create recovery area\n")); - return -1; - } - - /* remap the file (if using mmap) */ - methods->tdb_oob(tdb, tdb->map_size + 1, 1); - - /* we have to reset the old map size so that we don't try to expand the file - again in the transaction commit, which would destroy the recovery area */ - tdb->transaction->old_map_size = tdb->map_size; - - /* write the recovery header offset and sync - we can sync without a race here - as the magic ptr in the recovery record has not been set */ - CONVERT(recovery_head); - if (methods->tdb_write(tdb, TDB_RECOVERY_HEAD, - &recovery_head, sizeof(tdb_off_t)) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to write recovery head\n")); - return -1; - } - - return 0; -} - - -/* - setup the recovery data that will be used on a crash during commit -*/ -static int transaction_setup_recovery(struct tdb_context *tdb, - tdb_off_t *magic_offset) -{ - struct tdb_transaction_el *el; - tdb_len_t recovery_size; - unsigned char *data, *p; - const struct tdb_methods *methods = tdb->transaction->io_methods; - struct list_struct *rec; - tdb_off_t recovery_offset, recovery_max_size; - tdb_off_t old_map_size = tdb->transaction->old_map_size; - uint32_t magic, tailer; - - /* - check that the recovery area has enough space - */ - if (tdb_recovery_allocate(tdb, &recovery_size, - &recovery_offset, &recovery_max_size) == -1) { - return -1; - } - - data = (unsigned char *)malloc(recovery_size + sizeof(*rec)); - if (data == NULL) { - tdb->ecode = TDB_ERR_OOM; - return -1; - } - - rec = (struct list_struct *)data; - memset(rec, 0, sizeof(*rec)); - - rec->magic = 0; - rec->data_len = recovery_size; - rec->rec_len = recovery_max_size; - rec->key_len = old_map_size; - CONVERT(rec); - - /* build the recovery data into a single blob to allow us to do a single - large write, which should be more efficient */ - p = data + sizeof(*rec); - for (el=tdb->transaction->elements;el;el=el->next) { - if (el->offset >= old_map_size) { - continue; - } - if (el->offset + el->length > tdb->transaction->old_map_size) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_setup_recovery: transaction data over new region boundary\n")); - free(data); - tdb->ecode = TDB_ERR_CORRUPT; - return -1; - } - memcpy(p, &el->offset, 4); - memcpy(p+4, &el->length, 4); - if (DOCONV()) { - tdb_convert(p, 8); - } - /* the recovery area contains the old data, not the - new data, so we have to call the original tdb_read - method to get it */ - if (methods->tdb_read(tdb, el->offset, p + 8, el->length, 0) != 0) { - free(data); - tdb->ecode = TDB_ERR_IO; - return -1; - } - p += 8 + el->length; - } - - /* and the tailer */ - tailer = sizeof(*rec) + recovery_max_size; - memcpy(p, &tailer, 4); - CONVERT(p); - - /* write the recovery data to the recovery area */ - if (methods->tdb_write(tdb, recovery_offset, data, sizeof(*rec) + recovery_size) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_setup_recovery: failed to write recovery data\n")); - free(data); - tdb->ecode = TDB_ERR_IO; - return -1; - } - - /* as we don't have ordered writes, we have to sync the recovery - data before we update the magic to indicate that the recovery - data is present */ - if (transaction_sync(tdb, recovery_offset, sizeof(*rec) + recovery_size) == -1) { - free(data); - return -1; - } - - free(data); - - magic = TDB_RECOVERY_MAGIC; - CONVERT(magic); - - *magic_offset = recovery_offset + offsetof(struct list_struct, magic); - - if (methods->tdb_write(tdb, *magic_offset, &magic, sizeof(magic)) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_setup_recovery: failed to write recovery magic\n")); - tdb->ecode = TDB_ERR_IO; - return -1; - } - - /* ensure the recovery magic marker is on disk */ - if (transaction_sync(tdb, *magic_offset, sizeof(magic)) == -1) { - return -1; - } - - return 0; -} - -/* - commit the current transaction -*/ -int tdb_transaction_commit(struct tdb_context *tdb) -{ - const struct tdb_methods *methods; - tdb_off_t magic_offset = 0; - uint32_t zero = 0; - - if (tdb->transaction == NULL) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_commit: no transaction\n")); - return -1; - } - - if (tdb->transaction->transaction_error) { - tdb->ecode = TDB_ERR_IO; - tdb_transaction_cancel(tdb); - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_commit: transaction error pending\n")); - return -1; - } - - if (tdb->transaction->nesting != 0) { - tdb->transaction->nesting--; - return 0; - } - - /* check for a null transaction */ - if (tdb->transaction->elements == NULL) { - tdb_transaction_cancel(tdb); - return 0; - } - - methods = tdb->transaction->io_methods; - - /* if there are any locks pending then the caller has not - nested their locks properly, so fail the transaction */ - if (tdb->num_locks || tdb->global_lock.count) { - tdb->ecode = TDB_ERR_LOCK; - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_commit: locks pending on commit\n")); - tdb_transaction_cancel(tdb); - return -1; - } - - /* upgrade the main transaction lock region to a write lock */ - if (tdb_brlock_upgrade(tdb, FREELIST_TOP, 0) == -1) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: failed to upgrade hash locks\n")); - tdb->ecode = TDB_ERR_LOCK; - tdb_transaction_cancel(tdb); - return -1; - } - - /* get the global lock - this prevents new users attaching to the database - during the commit */ - if (tdb_brlock(tdb, GLOBAL_LOCK, F_WRLCK, F_SETLKW, 0, 1) == -1) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_commit: failed to get global lock\n")); - tdb->ecode = TDB_ERR_LOCK; - tdb_transaction_cancel(tdb); - return -1; - } - - if (!(tdb->flags & TDB_NOSYNC)) { - /* write the recovery data to the end of the file */ - if (transaction_setup_recovery(tdb, &magic_offset) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_commit: failed to setup recovery data\n")); - tdb_brlock(tdb, GLOBAL_LOCK, F_UNLCK, F_SETLKW, 0, 1); - tdb_transaction_cancel(tdb); - return -1; - } - } - - /* expand the file to the new size if needed */ - if (tdb->map_size != tdb->transaction->old_map_size) { - if (methods->tdb_expand_file(tdb, tdb->transaction->old_map_size, - tdb->map_size - - tdb->transaction->old_map_size) == -1) { - tdb->ecode = TDB_ERR_IO; - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_commit: expansion failed\n")); - tdb_brlock(tdb, GLOBAL_LOCK, F_UNLCK, F_SETLKW, 0, 1); - tdb_transaction_cancel(tdb); - return -1; - } - tdb->map_size = tdb->transaction->old_map_size; - methods->tdb_oob(tdb, tdb->map_size + 1, 1); - } - - /* perform all the writes */ - while (tdb->transaction->elements) { - struct tdb_transaction_el *el = tdb->transaction->elements; - - if (methods->tdb_write(tdb, el->offset, el->data, el->length) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_commit: write failed during commit\n")); - - /* we've overwritten part of the data and - possibly expanded the file, so we need to - run the crash recovery code */ - tdb->methods = methods; - tdb_transaction_recover(tdb); - - tdb_transaction_cancel(tdb); - tdb_brlock(tdb, GLOBAL_LOCK, F_UNLCK, F_SETLKW, 0, 1); - - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_commit: write failed\n")); - return -1; - } - tdb->transaction->elements = el->next; - free(el->data); - free(el); - } - - if (!(tdb->flags & TDB_NOSYNC)) { - /* ensure the new data is on disk */ - if (transaction_sync(tdb, 0, tdb->map_size) == -1) { - return -1; - } - - /* remove the recovery marker */ - if (methods->tdb_write(tdb, magic_offset, &zero, 4) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_commit: failed to remove recovery magic\n")); - return -1; - } - - /* ensure the recovery marker has been removed on disk */ - if (transaction_sync(tdb, magic_offset, 4) == -1) { - return -1; - } - } - - tdb_brlock(tdb, GLOBAL_LOCK, F_UNLCK, F_SETLKW, 0, 1); - - /* - TODO: maybe write to some dummy hdr field, or write to magic - offset without mmap, before the last sync, instead of the - utime() call - */ - - /* on some systems (like Linux 2.6.x) changes via mmap/msync - don't change the mtime of the file, this means the file may - not be backed up (as tdb rounding to block sizes means that - file size changes are quite rare too). The following forces - mtime changes when a transaction completes */ -#ifdef HAVE_UTIME - utime(tdb->name, NULL); -#endif - - /* use a transaction cancel to free memory and remove the - transaction locks */ - tdb_transaction_cancel(tdb); - return 0; -} - - -/* - recover from an aborted transaction. Must be called with exclusive - database write access already established (including the global - lock to prevent new processes attaching) -*/ -int tdb_transaction_recover(struct tdb_context *tdb) -{ - tdb_off_t recovery_head, recovery_eof; - unsigned char *data, *p; - uint32_t zero = 0; - struct list_struct rec; - - /* find the recovery area */ - if (tdb_ofs_read(tdb, TDB_RECOVERY_HEAD, &recovery_head) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to read recovery head\n")); - tdb->ecode = TDB_ERR_IO; - return -1; - } - - if (recovery_head == 0) { - /* we have never allocated a recovery record */ - return 0; - } - - /* read the recovery record */ - if (tdb->methods->tdb_read(tdb, recovery_head, &rec, - sizeof(rec), DOCONV()) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to read recovery record\n")); - tdb->ecode = TDB_ERR_IO; - return -1; - } - - if (rec.magic != TDB_RECOVERY_MAGIC) { - /* there is no valid recovery data */ - return 0; - } - - if (tdb->read_only) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: attempt to recover read only database\n")); - tdb->ecode = TDB_ERR_CORRUPT; - return -1; - } - - recovery_eof = rec.key_len; - - data = (unsigned char *)malloc(rec.data_len); - if (data == NULL) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to allocate recovery data\n")); - tdb->ecode = TDB_ERR_OOM; - return -1; - } - - /* read the full recovery data */ - if (tdb->methods->tdb_read(tdb, recovery_head + sizeof(rec), data, - rec.data_len, 0) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to read recovery data\n")); - tdb->ecode = TDB_ERR_IO; - return -1; - } - - /* recover the file data */ - p = data; - while (p+8 < data + rec.data_len) { - uint32_t ofs, len; - if (DOCONV()) { - tdb_convert(p, 8); - } - memcpy(&ofs, p, 4); - memcpy(&len, p+4, 4); - - if (tdb->methods->tdb_write(tdb, ofs, p+8, len) == -1) { - free(data); - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to recover %d bytes at offset %d\n", len, ofs)); - tdb->ecode = TDB_ERR_IO; - return -1; - } - p += 8 + len; - } - - free(data); - - if (transaction_sync(tdb, 0, tdb->map_size) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to sync recovery\n")); - tdb->ecode = TDB_ERR_IO; - return -1; - } - - /* if the recovery area is after the recovered eof then remove it */ - if (recovery_eof <= recovery_head) { - if (tdb_ofs_write(tdb, TDB_RECOVERY_HEAD, &zero) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to remove recovery head\n")); - tdb->ecode = TDB_ERR_IO; - return -1; - } - } - - /* remove the recovery magic */ - if (tdb_ofs_write(tdb, recovery_head + offsetof(struct list_struct, magic), - &zero) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to remove recovery magic\n")); - tdb->ecode = TDB_ERR_IO; - return -1; - } - - /* reduce the file size to the old size */ - tdb_munmap(tdb); - if (ftruncate(tdb->fd, recovery_eof) != 0) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to reduce to recovery size\n")); - tdb->ecode = TDB_ERR_IO; - return -1; - } - tdb->map_size = recovery_eof; - tdb_mmap(tdb); - - if (transaction_sync(tdb, 0, recovery_eof) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to sync2 recovery\n")); - tdb->ecode = TDB_ERR_IO; - return -1; - } - - TDB_LOG((tdb, TDB_DEBUG_TRACE, "tdb_transaction_recover: recovered %d byte database\n", - recovery_eof)); - - /* all done */ - return 0; -} diff --git a/source/lib/tdb/common/traverse.c b/source/lib/tdb/common/traverse.c deleted file mode 100644 index 6426162e994..00000000000 --- a/source/lib/tdb/common/traverse.c +++ /dev/null @@ -1,337 +0,0 @@ - /* - Unix SMB/CIFS implementation. - - trivial database library - - Copyright (C) Andrew Tridgell 1999-2005 - Copyright (C) Paul `Rusty' Russell 2000 - Copyright (C) Jeremy Allison 2000-2003 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include "tdb_private.h" - -/* Uses traverse lock: 0 = finish, -1 = error, other = record offset */ -static int tdb_next_lock(struct tdb_context *tdb, struct tdb_traverse_lock *tlock, - struct list_struct *rec) -{ - int want_next = (tlock->off != 0); - - /* Lock each chain from the start one. */ - for (; tlock->hash < tdb->header.hash_size; tlock->hash++) { - if (!tlock->off && tlock->hash != 0) { - /* this is an optimisation for the common case where - the hash chain is empty, which is particularly - common for the use of tdb with ldb, where large - hashes are used. In that case we spend most of our - time in tdb_brlock(), locking empty hash chains. - - To avoid this, we do an unlocked pre-check to see - if the hash chain is empty before starting to look - inside it. If it is empty then we can avoid that - hash chain. If it isn't empty then we can't believe - the value we get back, as we read it without a - lock, so instead we get the lock and re-fetch the - value below. - - Notice that not doing this optimisation on the - first hash chain is critical. We must guarantee - that we have done at least one fcntl lock at the - start of a search to guarantee that memory is - coherent on SMP systems. If records are added by - others during the search then thats OK, and we - could possibly miss those with this trick, but we - could miss them anyway without this trick, so the - semantics don't change. - - With a non-indexed ldb search this trick gains us a - factor of around 80 in speed on a linux 2.6.x - system (testing using ldbtest). - */ - tdb->methods->next_hash_chain(tdb, &tlock->hash); - if (tlock->hash == tdb->header.hash_size) { - continue; - } - } - - if (tdb_lock(tdb, tlock->hash, tlock->lock_rw) == -1) - return -1; - - /* No previous record? Start at top of chain. */ - if (!tlock->off) { - if (tdb_ofs_read(tdb, TDB_HASH_TOP(tlock->hash), - &tlock->off) == -1) - goto fail; - } else { - /* Otherwise unlock the previous record. */ - if (tdb_unlock_record(tdb, tlock->off) != 0) - goto fail; - } - - if (want_next) { - /* We have offset of old record: grab next */ - if (tdb_rec_read(tdb, tlock->off, rec) == -1) - goto fail; - tlock->off = rec->next; - } - - /* Iterate through chain */ - while( tlock->off) { - tdb_off_t current; - if (tdb_rec_read(tdb, tlock->off, rec) == -1) - goto fail; - - /* Detect infinite loops. From "Shlomi Yaakobovich" <Shlomi@exanet.com>. */ - if (tlock->off == rec->next) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_next_lock: loop detected.\n")); - goto fail; - } - - if (!TDB_DEAD(rec)) { - /* Woohoo: we found one! */ - if (tdb_lock_record(tdb, tlock->off) != 0) - goto fail; - return tlock->off; - } - - /* Try to clean dead ones from old traverses */ - current = tlock->off; - tlock->off = rec->next; - if (!(tdb->read_only || tdb->traverse_read) && - tdb_do_delete(tdb, current, rec) != 0) - goto fail; - } - tdb_unlock(tdb, tlock->hash, tlock->lock_rw); - want_next = 0; - } - /* We finished iteration without finding anything */ - return TDB_ERRCODE(TDB_SUCCESS, 0); - - fail: - tlock->off = 0; - if (tdb_unlock(tdb, tlock->hash, tlock->lock_rw) != 0) - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_next_lock: On error unlock failed!\n")); - return -1; -} - -/* traverse the entire database - calling fn(tdb, key, data) on each element. - return -1 on error or the record count traversed - if fn is NULL then it is not called - a non-zero return value from fn() indicates that the traversal should stop - */ -static int tdb_traverse_internal(struct tdb_context *tdb, - tdb_traverse_func fn, void *private_data, - struct tdb_traverse_lock *tl) -{ - TDB_DATA key, dbuf; - struct list_struct rec; - int ret, count = 0; - - /* This was in the initializaton, above, but the IRIX compiler - * did not like it. crh - */ - tl->next = tdb->travlocks.next; - - /* fcntl locks don't stack: beware traverse inside traverse */ - tdb->travlocks.next = tl; - - /* tdb_next_lock places locks on the record returned, and its chain */ - while ((ret = tdb_next_lock(tdb, tl, &rec)) > 0) { - count++; - /* now read the full record */ - key.dptr = tdb_alloc_read(tdb, tl->off + sizeof(rec), - rec.key_len + rec.data_len); - if (!key.dptr) { - ret = -1; - if (tdb_unlock(tdb, tl->hash, tl->lock_rw) != 0) - goto out; - if (tdb_unlock_record(tdb, tl->off) != 0) - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_traverse: key.dptr == NULL and unlock_record failed!\n")); - goto out; - } - key.dsize = rec.key_len; - dbuf.dptr = key.dptr + rec.key_len; - dbuf.dsize = rec.data_len; - - /* Drop chain lock, call out */ - if (tdb_unlock(tdb, tl->hash, tl->lock_rw) != 0) { - ret = -1; - SAFE_FREE(key.dptr); - goto out; - } - if (fn && fn(tdb, key, dbuf, private_data)) { - /* They want us to terminate traversal */ - ret = count; - if (tdb_unlock_record(tdb, tl->off) != 0) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_traverse: unlock_record failed!\n"));; - ret = -1; - } - SAFE_FREE(key.dptr); - goto out; - } - SAFE_FREE(key.dptr); - } -out: - tdb->travlocks.next = tl->next; - if (ret < 0) - return -1; - else - return count; -} - - -/* - a write style traverse - temporarily marks the db read only -*/ -int tdb_traverse_read(struct tdb_context *tdb, - tdb_traverse_func fn, void *private_data) -{ - struct tdb_traverse_lock tl = { NULL, 0, 0, F_RDLCK }; - int ret; - - /* we need to get a read lock on the transaction lock here to - cope with the lock ordering semantics of solaris10 */ - if (tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, F_RDLCK, F_SETLKW, 0, 1) == -1) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_traverse_read: failed to get transaction lock\n")); - tdb->ecode = TDB_ERR_LOCK; - return -1; - } - - tdb->traverse_read++; - ret = tdb_traverse_internal(tdb, fn, private_data, &tl); - tdb->traverse_read--; - - tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, F_UNLCK, F_SETLKW, 0, 1); - - return ret; -} - -/* - a write style traverse - needs to get the transaction lock to - prevent deadlocks -*/ -int tdb_traverse(struct tdb_context *tdb, - tdb_traverse_func fn, void *private_data) -{ - struct tdb_traverse_lock tl = { NULL, 0, 0, F_WRLCK }; - int ret; - - if (tdb->read_only || tdb->traverse_read) { - return tdb_traverse_read(tdb, fn, private_data); - } - - if (tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, F_WRLCK, F_SETLKW, 0, 1) == -1) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_traverse: failed to get transaction lock\n")); - tdb->ecode = TDB_ERR_LOCK; - return -1; - } - - ret = tdb_traverse_internal(tdb, fn, private_data, &tl); - - tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, F_UNLCK, F_SETLKW, 0, 1); - - return ret; -} - - -/* find the first entry in the database and return its key */ -TDB_DATA tdb_firstkey(struct tdb_context *tdb) -{ - TDB_DATA key; - struct list_struct rec; - - /* release any old lock */ - if (tdb_unlock_record(tdb, tdb->travlocks.off) != 0) - return tdb_null; - tdb->travlocks.off = tdb->travlocks.hash = 0; - tdb->travlocks.lock_rw = F_RDLCK; - - /* Grab first record: locks chain and returned record. */ - if (tdb_next_lock(tdb, &tdb->travlocks, &rec) <= 0) - return tdb_null; - /* now read the key */ - key.dsize = rec.key_len; - key.dptr =tdb_alloc_read(tdb,tdb->travlocks.off+sizeof(rec),key.dsize); - - /* Unlock the hash chain of the record we just read. */ - if (tdb_unlock(tdb, tdb->travlocks.hash, tdb->travlocks.lock_rw) != 0) - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_firstkey: error occurred while tdb_unlocking!\n")); - return key; -} - -/* find the next entry in the database, returning its key */ -TDB_DATA tdb_nextkey(struct tdb_context *tdb, TDB_DATA oldkey) -{ - uint32_t oldhash; - TDB_DATA key = tdb_null; - struct list_struct rec; - unsigned char *k = NULL; - - /* Is locked key the old key? If so, traverse will be reliable. */ - if (tdb->travlocks.off) { - if (tdb_lock(tdb,tdb->travlocks.hash,tdb->travlocks.lock_rw)) - return tdb_null; - if (tdb_rec_read(tdb, tdb->travlocks.off, &rec) == -1 - || !(k = tdb_alloc_read(tdb,tdb->travlocks.off+sizeof(rec), - rec.key_len)) - || memcmp(k, oldkey.dptr, oldkey.dsize) != 0) { - /* No, it wasn't: unlock it and start from scratch */ - if (tdb_unlock_record(tdb, tdb->travlocks.off) != 0) { - SAFE_FREE(k); - return tdb_null; - } - if (tdb_unlock(tdb, tdb->travlocks.hash, tdb->travlocks.lock_rw) != 0) { - SAFE_FREE(k); - return tdb_null; - } - tdb->travlocks.off = 0; - } - - SAFE_FREE(k); - } - - if (!tdb->travlocks.off) { - /* No previous element: do normal find, and lock record */ - tdb->travlocks.off = tdb_find_lock_hash(tdb, oldkey, tdb->hash_fn(&oldkey), tdb->travlocks.lock_rw, &rec); - if (!tdb->travlocks.off) - return tdb_null; - tdb->travlocks.hash = BUCKET(rec.full_hash); - if (tdb_lock_record(tdb, tdb->travlocks.off) != 0) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_nextkey: lock_record failed (%s)!\n", strerror(errno))); - return tdb_null; - } - } - oldhash = tdb->travlocks.hash; - - /* Grab next record: locks chain and returned record, - unlocks old record */ - if (tdb_next_lock(tdb, &tdb->travlocks, &rec) > 0) { - key.dsize = rec.key_len; - key.dptr = tdb_alloc_read(tdb, tdb->travlocks.off+sizeof(rec), - key.dsize); - /* Unlock the chain of this new record */ - if (tdb_unlock(tdb, tdb->travlocks.hash, tdb->travlocks.lock_rw) != 0) - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_nextkey: WARNING tdb_unlock failed!\n")); - } - /* Unlock the chain of old record */ - if (tdb_unlock(tdb, BUCKET(oldhash), tdb->travlocks.lock_rw) != 0) - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_nextkey: WARNING tdb_unlock failed!\n")); - return key; -} diff --git a/source/lib/tdb/config.guess b/source/lib/tdb/config.guess deleted file mode 100755 index ad5281e66e9..00000000000 --- a/source/lib/tdb/config.guess +++ /dev/null @@ -1,1466 +0,0 @@ -#! /bin/sh -# Attempt to guess a canonical system name. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. - -timestamp='2005-08-03' - -# This file 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., 51 Franklin Street - Fifth Floor, Boston, MA -# 02110-1301, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - - -# Originally written by Per Bothner <per@bothner.com>. -# Please send patches to <config-patches@gnu.org>. Submit a context -# diff and a properly formatted ChangeLog entry. -# -# This script attempts to guess a canonical system name similar to -# config.sub. If it succeeds, it prints the system name on stdout, and -# exits with 0. Otherwise, it exits with 1. -# -# The plan is that this can be called by configure scripts if you -# don't specify an explicit build system type. - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] - -Output the configuration name of the system \`$me' is run on. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to <config-patches@gnu.org>." - -version="\ -GNU config.guess ($timestamp) - -Originally written by Per Bothner. -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 -Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit ;; - --version | -v ) - echo "$version" ; exit ;; - --help | --h* | -h ) - echo "$usage"; exit ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" >&2 - exit 1 ;; - * ) - break ;; - esac -done - -if test $# != 0; then - echo "$me: too many arguments$help" >&2 - exit 1 -fi - -trap 'exit 1' 1 2 15 - -# CC_FOR_BUILD -- compiler used by this script. Note that the use of a -# compiler to aid in system detection is discouraged as it requires -# temporary files to be created and, as you can see below, it is a -# headache to deal with in a portable fashion. - -# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still -# use `HOST_CC' if defined, but it is deprecated. - -# Portable tmp directory creation inspired by the Autoconf team. - -set_cc_for_build=' -trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; -trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; -: ${TMPDIR=/tmp} ; - { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || - { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || - { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || - { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; -dummy=$tmp/dummy ; -tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; -case $CC_FOR_BUILD,$HOST_CC,$CC in - ,,) echo "int x;" > $dummy.c ; - for c in cc gcc c89 c99 ; do - if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then - CC_FOR_BUILD="$c"; break ; - fi ; - done ; - if test x"$CC_FOR_BUILD" = x ; then - CC_FOR_BUILD=no_compiler_found ; - fi - ;; - ,,*) CC_FOR_BUILD=$CC ;; - ,*,*) CC_FOR_BUILD=$HOST_CC ;; -esac ; set_cc_for_build= ;' - -# This is needed to find uname on a Pyramid OSx when run in the BSD universe. -# (ghazi@noc.rutgers.edu 1994-08-24) -if (test -f /.attbin/uname) >/dev/null 2>&1 ; then - PATH=$PATH:/.attbin ; export PATH -fi - -UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown -UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown -UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown -UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown - -# Note: order is significant - the case branches are not exclusive. - -case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in - *:NetBSD:*:*) - # NetBSD (nbsd) targets should (where applicable) match one or - # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, - # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently - # switched to ELF, *-*-netbsd* would select the old - # object file format. This provides both forward - # compatibility and a consistent mechanism for selecting the - # object file format. - # - # Note: NetBSD doesn't particularly care about the vendor - # portion of the name. We always set it to "unknown". - sysctl="sysctl -n hw.machine_arch" - UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ - /usr/sbin/$sysctl 2>/dev/null || echo unknown)` - case "${UNAME_MACHINE_ARCH}" in - armeb) machine=armeb-unknown ;; - arm*) machine=arm-unknown ;; - sh3el) machine=shl-unknown ;; - sh3eb) machine=sh-unknown ;; - *) machine=${UNAME_MACHINE_ARCH}-unknown ;; - esac - # The Operating System including object format, if it has switched - # to ELF recently, or will in the future. - case "${UNAME_MACHINE_ARCH}" in - arm*|i386|m68k|ns32k|sh3*|sparc|vax) - eval $set_cc_for_build - if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep __ELF__ >/dev/null - then - # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). - # Return netbsd for either. FIX? - os=netbsd - else - os=netbsdelf - fi - ;; - *) - os=netbsd - ;; - esac - # The OS release - # Debian GNU/NetBSD machines have a different userland, and - # thus, need a distinct triplet. However, they do not need - # kernel version information, so it can be replaced with a - # suitable tag, in the style of linux-gnu. - case "${UNAME_VERSION}" in - Debian*) - release='-gnu' - ;; - *) - release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` - ;; - esac - # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: - # contains redundant information, the shorter form: - # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}" - exit ;; - *:OpenBSD:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} - exit ;; - *:ekkoBSD:*:*) - echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} - exit ;; - macppc:MirBSD:*:*) - echo powerppc-unknown-mirbsd${UNAME_RELEASE} - exit ;; - *:MirBSD:*:*) - echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} - exit ;; - alpha:OSF1:*:*) - case $UNAME_RELEASE in - *4.0) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` - ;; - *5.*) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` - ;; - esac - # According to Compaq, /usr/sbin/psrinfo has been available on - # OSF/1 and Tru64 systems produced since 1995. I hope that - # covers most systems running today. This code pipes the CPU - # types through head -n 1, so we only detect the type of CPU 0. - ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` - case "$ALPHA_CPU_TYPE" in - "EV4 (21064)") - UNAME_MACHINE="alpha" ;; - "EV4.5 (21064)") - UNAME_MACHINE="alpha" ;; - "LCA4 (21066/21068)") - UNAME_MACHINE="alpha" ;; - "EV5 (21164)") - UNAME_MACHINE="alphaev5" ;; - "EV5.6 (21164A)") - UNAME_MACHINE="alphaev56" ;; - "EV5.6 (21164PC)") - UNAME_MACHINE="alphapca56" ;; - "EV5.7 (21164PC)") - UNAME_MACHINE="alphapca57" ;; - "EV6 (21264)") - UNAME_MACHINE="alphaev6" ;; - "EV6.7 (21264A)") - UNAME_MACHINE="alphaev67" ;; - "EV6.8CB (21264C)") - UNAME_MACHINE="alphaev68" ;; - "EV6.8AL (21264B)") - UNAME_MACHINE="alphaev68" ;; - "EV6.8CX (21264D)") - UNAME_MACHINE="alphaev68" ;; - "EV6.9A (21264/EV69A)") - UNAME_MACHINE="alphaev69" ;; - "EV7 (21364)") - UNAME_MACHINE="alphaev7" ;; - "EV7.9 (21364A)") - UNAME_MACHINE="alphaev79" ;; - esac - # A Pn.n version is a patched version. - # A Vn.n version is a released version. - # A Tn.n version is a released field test version. - # A Xn.n version is an unreleased experimental baselevel. - # 1.2 uses "1.2" for uname -r. - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - exit ;; - Alpha\ *:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # Should we change UNAME_MACHINE based on the output of uname instead - # of the specific Alpha model? - echo alpha-pc-interix - exit ;; - 21064:Windows_NT:50:3) - echo alpha-dec-winnt3.5 - exit ;; - Amiga*:UNIX_System_V:4.0:*) - echo m68k-unknown-sysv4 - exit ;; - *:[Aa]miga[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-amigaos - exit ;; - *:[Mm]orph[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-morphos - exit ;; - *:OS/390:*:*) - echo i370-ibm-openedition - exit ;; - *:z/VM:*:*) - echo s390-ibm-zvmoe - exit ;; - *:OS400:*:*) - echo powerpc-ibm-os400 - exit ;; - arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) - echo arm-acorn-riscix${UNAME_RELEASE} - exit ;; - arm:riscos:*:*|arm:RISCOS:*:*) - echo arm-unknown-riscos - exit ;; - SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) - echo hppa1.1-hitachi-hiuxmpp - exit ;; - Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) - # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. - if test "`(/bin/universe) 2>/dev/null`" = att ; then - echo pyramid-pyramid-sysv3 - else - echo pyramid-pyramid-bsd - fi - exit ;; - NILE*:*:*:dcosx) - echo pyramid-pyramid-svr4 - exit ;; - DRS?6000:unix:4.0:6*) - echo sparc-icl-nx6 - exit ;; - DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) - case `/usr/bin/uname -p` in - sparc) echo sparc-icl-nx7; exit ;; - esac ;; - sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - i86pc:SunOS:5.*:*) - echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:6*:*) - # According to config.sub, this is the proper way to canonicalize - # SunOS6. Hard to guess exactly what SunOS6 will be like, but - # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:*:*) - case "`/usr/bin/arch -k`" in - Series*|S4*) - UNAME_RELEASE=`uname -v` - ;; - esac - # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` - exit ;; - sun3*:SunOS:*:*) - echo m68k-sun-sunos${UNAME_RELEASE} - exit ;; - sun*:*:4.2BSD:*) - UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 - case "`/bin/arch`" in - sun3) - echo m68k-sun-sunos${UNAME_RELEASE} - ;; - sun4) - echo sparc-sun-sunos${UNAME_RELEASE} - ;; - esac - exit ;; - aushp:SunOS:*:*) - echo sparc-auspex-sunos${UNAME_RELEASE} - exit ;; - # The situation for MiNT is a little confusing. The machine name - # can be virtually everything (everything which is not - # "atarist" or "atariste" at least should have a processor - # > m68000). The system name ranges from "MiNT" over "FreeMiNT" - # to the lowercase version "mint" (or "freemint"). Finally - # the system name "TOS" denotes a system which is actually not - # MiNT. But MiNT is downward compatible to TOS, so this should - # be no problem. - atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} - exit ;; - hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} - exit ;; - *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} - exit ;; - m68k:machten:*:*) - echo m68k-apple-machten${UNAME_RELEASE} - exit ;; - powerpc:machten:*:*) - echo powerpc-apple-machten${UNAME_RELEASE} - exit ;; - RISC*:Mach:*:*) - echo mips-dec-mach_bsd4.3 - exit ;; - RISC*:ULTRIX:*:*) - echo mips-dec-ultrix${UNAME_RELEASE} - exit ;; - VAX*:ULTRIX*:*:*) - echo vax-dec-ultrix${UNAME_RELEASE} - exit ;; - 2020:CLIX:*:* | 2430:CLIX:*:*) - echo clipper-intergraph-clix${UNAME_RELEASE} - exit ;; - mips:*:*:UMIPS | mips:*:*:RISCos) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c -#ifdef __cplusplus -#include <stdio.h> /* for printf() prototype */ - int main (int argc, char *argv[]) { -#else - int main (argc, argv) int argc; char *argv[]; { -#endif - #if defined (host_mips) && defined (MIPSEB) - #if defined (SYSTYPE_SYSV) - printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_SVR4) - printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) - printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); - #endif - #endif - exit (-1); - } -EOF - $CC_FOR_BUILD -o $dummy $dummy.c && - dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && - SYSTEM_NAME=`$dummy $dummyarg` && - { echo "$SYSTEM_NAME"; exit; } - echo mips-mips-riscos${UNAME_RELEASE} - exit ;; - Motorola:PowerMAX_OS:*:*) - echo powerpc-motorola-powermax - exit ;; - Motorola:*:4.3:PL8-*) - echo powerpc-harris-powermax - exit ;; - Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) - echo powerpc-harris-powermax - exit ;; - Night_Hawk:Power_UNIX:*:*) - echo powerpc-harris-powerunix - exit ;; - m88k:CX/UX:7*:*) - echo m88k-harris-cxux7 - exit ;; - m88k:*:4*:R4*) - echo m88k-motorola-sysv4 - exit ;; - m88k:*:3*:R3*) - echo m88k-motorola-sysv3 - exit ;; - AViiON:dgux:*:*) - # DG/UX returns AViiON for all architectures - UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] - then - if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ - [ ${TARGET_BINARY_INTERFACE}x = x ] - then - echo m88k-dg-dgux${UNAME_RELEASE} - else - echo m88k-dg-dguxbcs${UNAME_RELEASE} - fi - else - echo i586-dg-dgux${UNAME_RELEASE} - fi - exit ;; - M88*:DolphinOS:*:*) # DolphinOS (SVR3) - echo m88k-dolphin-sysv3 - exit ;; - M88*:*:R3*:*) - # Delta 88k system running SVR3 - echo m88k-motorola-sysv3 - exit ;; - XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) - echo m88k-tektronix-sysv3 - exit ;; - Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) - echo m68k-tektronix-bsd - exit ;; - *:IRIX*:*:*) - echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` - exit ;; - ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. - echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id - exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' - i*86:AIX:*:*) - echo i386-ibm-aix - exit ;; - ia64:AIX:*:*) - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} - exit ;; - *:AIX:2:3) - if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include <sys/systemcfg.h> - - main() - { - if (!__power_pc()) - exit(1); - puts("powerpc-ibm-aix3.2.5"); - exit(0); - } -EOF - if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` - then - echo "$SYSTEM_NAME" - else - echo rs6000-ibm-aix3.2.5 - fi - elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then - echo rs6000-ibm-aix3.2.4 - else - echo rs6000-ibm-aix3.2 - fi - exit ;; - *:AIX:*:[45]) - IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` - if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then - IBM_ARCH=rs6000 - else - IBM_ARCH=powerpc - fi - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${IBM_ARCH}-ibm-aix${IBM_REV} - exit ;; - *:AIX:*:*) - echo rs6000-ibm-aix - exit ;; - ibmrt:4.4BSD:*|romp-ibm:BSD:*) - echo romp-ibm-bsd4.4 - exit ;; - ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and - echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to - exit ;; # report: romp-ibm BSD 4.3 - *:BOSX:*:*) - echo rs6000-bull-bosx - exit ;; - DPX/2?00:B.O.S.:*:*) - echo m68k-bull-sysv3 - exit ;; - 9000/[34]??:4.3bsd:1.*:*) - echo m68k-hp-bsd - exit ;; - hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) - echo m68k-hp-bsd4.4 - exit ;; - 9000/[34678]??:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - case "${UNAME_MACHINE}" in - 9000/31? ) HP_ARCH=m68000 ;; - 9000/[34]?? ) HP_ARCH=m68k ;; - 9000/[678][0-9][0-9]) - if [ -x /usr/bin/getconf ]; then - sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` - sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "${sc_cpu_version}" in - 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 - 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 - 532) # CPU_PA_RISC2_0 - case "${sc_kernel_bits}" in - 32) HP_ARCH="hppa2.0n" ;; - 64) HP_ARCH="hppa2.0w" ;; - '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 - esac ;; - esac - fi - if [ "${HP_ARCH}" = "" ]; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - - #define _HPUX_SOURCE - #include <stdlib.h> - #include <unistd.h> - - int main () - { - #if defined(_SC_KERNEL_BITS) - long bits = sysconf(_SC_KERNEL_BITS); - #endif - long cpu = sysconf (_SC_CPU_VERSION); - - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1"); break; - case CPU_PA_RISC2_0: - #if defined(_SC_KERNEL_BITS) - switch (bits) - { - case 64: puts ("hppa2.0w"); break; - case 32: puts ("hppa2.0n"); break; - default: puts ("hppa2.0"); break; - } break; - #else /* !defined(_SC_KERNEL_BITS) */ - puts ("hppa2.0"); break; - #endif - default: puts ("hppa1.0"); break; - } - exit (0); - } -EOF - (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` - test -z "$HP_ARCH" && HP_ARCH=hppa - fi ;; - esac - if [ ${HP_ARCH} = "hppa2.0w" ] - then - eval $set_cc_for_build - - # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating - # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler - # generating 64-bit code. GNU and HP use different nomenclature: - # - # $ CC_FOR_BUILD=cc ./config.guess - # => hppa2.0w-hp-hpux11.23 - # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess - # => hppa64-hp-hpux11.23 - - if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | - grep __LP64__ >/dev/null - then - HP_ARCH="hppa2.0w" - else - HP_ARCH="hppa64" - fi - fi - echo ${HP_ARCH}-hp-hpux${HPUX_REV} - exit ;; - ia64:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - echo ia64-hp-hpux${HPUX_REV} - exit ;; - 3050*:HI-UX:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include <unistd.h> - int - main () - { - long cpu = sysconf (_SC_CPU_VERSION); - /* The order matters, because CPU_IS_HP_MC68K erroneously returns - true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct - results, however. */ - if (CPU_IS_PA_RISC (cpu)) - { - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; - case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; - default: puts ("hppa-hitachi-hiuxwe2"); break; - } - } - else if (CPU_IS_HP_MC68K (cpu)) - puts ("m68k-hitachi-hiuxwe2"); - else puts ("unknown-hitachi-hiuxwe2"); - exit (0); - } -EOF - $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && - { echo "$SYSTEM_NAME"; exit; } - echo unknown-hitachi-hiuxwe2 - exit ;; - 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) - echo hppa1.1-hp-bsd - exit ;; - 9000/8??:4.3bsd:*:*) - echo hppa1.0-hp-bsd - exit ;; - *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) - echo hppa1.0-hp-mpeix - exit ;; - hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) - echo hppa1.1-hp-osf - exit ;; - hp8??:OSF1:*:*) - echo hppa1.0-hp-osf - exit ;; - i*86:OSF1:*:*) - if [ -x /usr/sbin/sysversion ] ; then - echo ${UNAME_MACHINE}-unknown-osf1mk - else - echo ${UNAME_MACHINE}-unknown-osf1 - fi - exit ;; - parisc*:Lites*:*:*) - echo hppa1.1-hp-lites - exit ;; - C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) - echo c1-convex-bsd - exit ;; - C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit ;; - C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) - echo c34-convex-bsd - exit ;; - C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) - echo c38-convex-bsd - exit ;; - C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) - echo c4-convex-bsd - exit ;; - CRAY*Y-MP:*:*:*) - echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*[A-Z]90:*:*:*) - echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ - | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ - -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ - -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*TS:*:*:*) - echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*T3E:*:*:*) - echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*SV1:*:*:*) - echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - *:UNICOS/mp:*:*) - echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) - FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` - echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; - 5000:UNIX_System_V:4.*:*) - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` - echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; - i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) - echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} - exit ;; - sparc*:BSD/OS:*:*) - echo sparc-unknown-bsdi${UNAME_RELEASE} - exit ;; - *:BSD/OS:*:*) - echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} - exit ;; - *:FreeBSD:*:*) - echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` - exit ;; - i*:CYGWIN*:*) - echo ${UNAME_MACHINE}-pc-cygwin - exit ;; - i*:MINGW*:*) - echo ${UNAME_MACHINE}-pc-mingw32 - exit ;; - i*:windows32*:*) - # uname -m includes "-pc" on this system. - echo ${UNAME_MACHINE}-mingw32 - exit ;; - i*:PW*:*) - echo ${UNAME_MACHINE}-pc-pw32 - exit ;; - x86:Interix*:[34]*) - echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//' - exit ;; - [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) - echo i${UNAME_MACHINE}-pc-mks - exit ;; - i*:Windows_NT*:* | Pentium*:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we - # UNAME_MACHINE based on the output of uname instead of i386? - echo i586-pc-interix - exit ;; - i*:UWIN*:*) - echo ${UNAME_MACHINE}-pc-uwin - exit ;; - amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) - echo x86_64-unknown-cygwin - exit ;; - p*:CYGWIN*:*) - echo powerpcle-unknown-cygwin - exit ;; - prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - *:GNU:*:*) - # the GNU system - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` - exit ;; - *:GNU/*:*:*) - # other systems with GNU libc and userland - echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu - exit ;; - i*86:Minix:*:*) - echo ${UNAME_MACHINE}-pc-minix - exit ;; - arm*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - cris:Linux:*:*) - echo cris-axis-linux-gnu - exit ;; - crisv32:Linux:*:*) - echo crisv32-axis-linux-gnu - exit ;; - frv:Linux:*:*) - echo frv-unknown-linux-gnu - exit ;; - ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - m32r*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - mips:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef mips - #undef mipsel - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=mipsel - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=mips - #else - CPU= - #endif - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } - ;; - mips64:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef mips64 - #undef mips64el - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=mips64el - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=mips64 - #else - CPU= - #endif - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } - ;; - or32:Linux:*:*) - echo or32-unknown-linux-gnu - exit ;; - ppc:Linux:*:*) - echo powerpc-unknown-linux-gnu - exit ;; - ppc64:Linux:*:*) - echo powerpc64-unknown-linux-gnu - exit ;; - alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in - EV5) UNAME_MACHINE=alphaev5 ;; - EV56) UNAME_MACHINE=alphaev56 ;; - PCA56) UNAME_MACHINE=alphapca56 ;; - PCA57) UNAME_MACHINE=alphapca56 ;; - EV6) UNAME_MACHINE=alphaev6 ;; - EV67) UNAME_MACHINE=alphaev67 ;; - EV68*) UNAME_MACHINE=alphaev68 ;; - esac - objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null - if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi - echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} - exit ;; - parisc:Linux:*:* | hppa:Linux:*:*) - # Look for CPU level - case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-gnu ;; - PA8*) echo hppa2.0-unknown-linux-gnu ;; - *) echo hppa-unknown-linux-gnu ;; - esac - exit ;; - parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-gnu - exit ;; - s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux - exit ;; - sh64*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - sh*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - sparc:Linux:*:* | sparc64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - x86_64:Linux:*:*) - echo x86_64-unknown-linux-gnu - exit ;; - i*86:Linux:*:*) - # The BFD linker knows what the default object file format is, so - # first see if it will tell us. cd to the root directory to prevent - # problems with other programs or directories called `ld' in the path. - # Set LC_ALL=C to ensure ld outputs messages in English. - ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ - | sed -ne '/supported targets:/!d - s/[ ][ ]*/ /g - s/.*supported targets: *// - s/ .*// - p'` - case "$ld_supported_targets" in - elf32-i386) - TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" - ;; - a.out-i386-linux) - echo "${UNAME_MACHINE}-pc-linux-gnuaout" - exit ;; - coff-i386) - echo "${UNAME_MACHINE}-pc-linux-gnucoff" - exit ;; - "") - # Either a pre-BFD a.out linker (linux-gnuoldld) or - # one that does not give us useful --help. - echo "${UNAME_MACHINE}-pc-linux-gnuoldld" - exit ;; - esac - # Determine whether the default compiler is a.out or elf - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include <features.h> - #ifdef __ELF__ - # ifdef __GLIBC__ - # if __GLIBC__ >= 2 - LIBC=gnu - # else - LIBC=gnulibc1 - # endif - # else - LIBC=gnulibc1 - # endif - #else - #ifdef __INTEL_COMPILER - LIBC=gnu - #else - LIBC=gnuaout - #endif - #endif - #ifdef __dietlibc__ - LIBC=dietlibc - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` - test x"${LIBC}" != x && { - echo "${UNAME_MACHINE}-pc-linux-${LIBC}" - exit - } - test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } - ;; - i*86:DYNIX/ptx:4*:*) - # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. - # earlier versions are messed up and put the nodename in both - # sysname and nodename. - echo i386-sequent-sysv4 - exit ;; - i*86:UNIX_SV:4.2MP:2.*) - # Unixware is an offshoot of SVR4, but it has its own version - # number series starting with 2... - # I am not positive that other SVR4 systems won't match this, - # I just have to hope. -- rms. - # Use sysv4.2uw... so that sysv4* matches it. - echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} - exit ;; - i*86:OS/2:*:*) - # If we were able to find `uname', then EMX Unix compatibility - # is probably installed. - echo ${UNAME_MACHINE}-pc-os2-emx - exit ;; - i*86:XTS-300:*:STOP) - echo ${UNAME_MACHINE}-unknown-stop - exit ;; - i*86:atheos:*:*) - echo ${UNAME_MACHINE}-unknown-atheos - exit ;; - i*86:syllable:*:*) - echo ${UNAME_MACHINE}-pc-syllable - exit ;; - i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) - echo i386-unknown-lynxos${UNAME_RELEASE} - exit ;; - i*86:*DOS:*:*) - echo ${UNAME_MACHINE}-pc-msdosdjgpp - exit ;; - i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) - UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` - if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} - else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} - fi - exit ;; - i*86:*:5:[678]*) - # UnixWare 7.x, OpenUNIX and OpenServer 6. - case `/bin/uname -X | grep "^Machine"` in - *486*) UNAME_MACHINE=i486 ;; - *Pentium) UNAME_MACHINE=i586 ;; - *Pent*|*Celeron) UNAME_MACHINE=i686 ;; - esac - echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} - exit ;; - i*86:*:3.2:*) - if test -f /usr/options/cb.name; then - UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name` - echo ${UNAME_MACHINE}-pc-isc$UNAME_REL - elif /bin/uname -X 2>/dev/null >/dev/null ; then - UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` - (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 - (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ - && UNAME_MACHINE=i586 - (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ - && UNAME_MACHINE=i686 - (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ - && UNAME_MACHINE=i686 - echo ${UNAME_MACHINE}-pc-sco$UNAME_REL - else - echo ${UNAME_MACHINE}-pc-sysv32 - fi - exit ;; - pc:*:*:*) - # Left here for compatibility: - # uname -m prints for DJGPP always 'pc', but it prints nothing about - # the processor, so we play safe by assuming i386. - echo i386-pc-msdosdjgpp - exit ;; - Intel:Mach:3*:*) - echo i386-pc-mach3 - exit ;; - paragon:*:*:*) - echo i860-intel-osf1 - exit ;; - i860:*:4.*:*) # i860-SVR4 - if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then - echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 - else # Add other i860-SVR4 vendors below as they are discovered. - echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 - fi - exit ;; - mini*:CTIX:SYS*5:*) - # "miniframe" - echo m68010-convergent-sysv - exit ;; - mc68k:UNIX:SYSTEM5:3.51m) - echo m68k-convergent-sysv - exit ;; - M680?0:D-NIX:5.3:*) - echo m68k-diab-dnix - exit ;; - M68*:*:R3V[5678]*:*) - test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; - 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) - OS_REL='' - test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; - 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4; exit; } ;; - m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - echo m68k-unknown-lynxos${UNAME_RELEASE} - exit ;; - mc68030:UNIX_System_V:4.*:*) - echo m68k-atari-sysv4 - exit ;; - TSUNAMI:LynxOS:2.*:*) - echo sparc-unknown-lynxos${UNAME_RELEASE} - exit ;; - rs6000:LynxOS:2.*:*) - echo rs6000-unknown-lynxos${UNAME_RELEASE} - exit ;; - PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) - echo powerpc-unknown-lynxos${UNAME_RELEASE} - exit ;; - SM[BE]S:UNIX_SV:*:*) - echo mips-dde-sysv${UNAME_RELEASE} - exit ;; - RM*:ReliantUNIX-*:*:*) - echo mips-sni-sysv4 - exit ;; - RM*:SINIX-*:*:*) - echo mips-sni-sysv4 - exit ;; - *:SINIX-*:*:*) - if uname -p 2>/dev/null >/dev/null ; then - UNAME_MACHINE=`(uname -p) 2>/dev/null` - echo ${UNAME_MACHINE}-sni-sysv4 - else - echo ns32k-sni-sysv - fi - exit ;; - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort - # says <Richard.M.Bartel@ccMail.Census.GOV> - echo i586-unisys-sysv4 - exit ;; - *:UNIX_System_V:4*:FTX*) - # From Gerald Hewes <hewes@openmarket.com>. - # How about differentiating between stratus architectures? -djm - echo hppa1.1-stratus-sysv4 - exit ;; - *:*:*:FTX*) - # From seanf@swdc.stratus.com. - echo i860-stratus-sysv4 - exit ;; - i*86:VOS:*:*) - # From Paul.Green@stratus.com. - echo ${UNAME_MACHINE}-stratus-vos - exit ;; - *:VOS:*:*) - # From Paul.Green@stratus.com. - echo hppa1.1-stratus-vos - exit ;; - mc68*:A/UX:*:*) - echo m68k-apple-aux${UNAME_RELEASE} - exit ;; - news*:NEWS-OS:6*:*) - echo mips-sony-newsos6 - exit ;; - R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) - if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} - else - echo mips-unknown-sysv${UNAME_RELEASE} - fi - exit ;; - BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. - echo powerpc-be-beos - exit ;; - BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. - echo powerpc-apple-beos - exit ;; - BePC:BeOS:*:*) # BeOS running on Intel PC compatible. - echo i586-pc-beos - exit ;; - SX-4:SUPER-UX:*:*) - echo sx4-nec-superux${UNAME_RELEASE} - exit ;; - SX-5:SUPER-UX:*:*) - echo sx5-nec-superux${UNAME_RELEASE} - exit ;; - SX-6:SUPER-UX:*:*) - echo sx6-nec-superux${UNAME_RELEASE} - exit ;; - Power*:Rhapsody:*:*) - echo powerpc-apple-rhapsody${UNAME_RELEASE} - exit ;; - *:Rhapsody:*:*) - echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} - exit ;; - *:Darwin:*:*) - UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - case $UNAME_PROCESSOR in - *86) UNAME_PROCESSOR=i686 ;; - unknown) UNAME_PROCESSOR=powerpc ;; - esac - echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} - exit ;; - *:procnto*:*:* | *:QNX:[0123456789]*:*) - UNAME_PROCESSOR=`uname -p` - if test "$UNAME_PROCESSOR" = "x86"; then - UNAME_PROCESSOR=i386 - UNAME_MACHINE=pc - fi - echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} - exit ;; - *:QNX:*:4*) - echo i386-pc-qnx - exit ;; - NSE-?:NONSTOP_KERNEL:*:*) - echo nse-tandem-nsk${UNAME_RELEASE} - exit ;; - NSR-?:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk${UNAME_RELEASE} - exit ;; - *:NonStop-UX:*:*) - echo mips-compaq-nonstopux - exit ;; - BS2000:POSIX*:*:*) - echo bs2000-siemens-sysv - exit ;; - DS/*:UNIX_System_V:*:*) - echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} - exit ;; - *:Plan9:*:*) - # "uname -m" is not consistent, so use $cputype instead. 386 - # is converted to i386 for consistency with other x86 - # operating systems. - if test "$cputype" = "386"; then - UNAME_MACHINE=i386 - else - UNAME_MACHINE="$cputype" - fi - echo ${UNAME_MACHINE}-unknown-plan9 - exit ;; - *:TOPS-10:*:*) - echo pdp10-unknown-tops10 - exit ;; - *:TENEX:*:*) - echo pdp10-unknown-tenex - exit ;; - KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) - echo pdp10-dec-tops20 - exit ;; - XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) - echo pdp10-xkl-tops20 - exit ;; - *:TOPS-20:*:*) - echo pdp10-unknown-tops20 - exit ;; - *:ITS:*:*) - echo pdp10-unknown-its - exit ;; - SEI:*:*:SEIUX) - echo mips-sei-seiux${UNAME_RELEASE} - exit ;; - *:DragonFly:*:*) - echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` - exit ;; - *:*VMS:*:*) - UNAME_MACHINE=`(uname -p) 2>/dev/null` - case "${UNAME_MACHINE}" in - A*) echo alpha-dec-vms ; exit ;; - I*) echo ia64-dec-vms ; exit ;; - V*) echo vax-dec-vms ; exit ;; - esac ;; - *:XENIX:*:SysV) - echo i386-pc-xenix - exit ;; - i*86:skyos:*:*) - echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' - exit ;; -esac - -#echo '(No uname command or uname output not recognized.)' 1>&2 -#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 - -eval $set_cc_for_build -cat >$dummy.c <<EOF -#ifdef _SEQUENT_ -# include <sys/types.h> -# include <sys/utsname.h> -#endif -main () -{ -#if defined (sony) -#if defined (MIPSEB) - /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, - I don't know.... */ - printf ("mips-sony-bsd\n"); exit (0); -#else -#include <sys/param.h> - printf ("m68k-sony-newsos%s\n", -#ifdef NEWSOS4 - "4" -#else - "" -#endif - ); exit (0); -#endif -#endif - -#if defined (__arm) && defined (__acorn) && defined (__unix) - printf ("arm-acorn-riscix\n"); exit (0); -#endif - -#if defined (hp300) && !defined (hpux) - printf ("m68k-hp-bsd\n"); exit (0); -#endif - -#if defined (NeXT) -#if !defined (__ARCHITECTURE__) -#define __ARCHITECTURE__ "m68k" -#endif - int version; - version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; - if (version < 4) - printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); - else - printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); - exit (0); -#endif - -#if defined (MULTIMAX) || defined (n16) -#if defined (UMAXV) - printf ("ns32k-encore-sysv\n"); exit (0); -#else -#if defined (CMU) - printf ("ns32k-encore-mach\n"); exit (0); -#else - printf ("ns32k-encore-bsd\n"); exit (0); -#endif -#endif -#endif - -#if defined (__386BSD__) - printf ("i386-pc-bsd\n"); exit (0); -#endif - -#if defined (sequent) -#if defined (i386) - printf ("i386-sequent-dynix\n"); exit (0); -#endif -#if defined (ns32000) - printf ("ns32k-sequent-dynix\n"); exit (0); -#endif -#endif - -#if defined (_SEQUENT_) - struct utsname un; - - uname(&un); - - if (strncmp(un.version, "V2", 2) == 0) { - printf ("i386-sequent-ptx2\n"); exit (0); - } - if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ - printf ("i386-sequent-ptx1\n"); exit (0); - } - printf ("i386-sequent-ptx\n"); exit (0); - -#endif - -#if defined (vax) -# if !defined (ultrix) -# include <sys/param.h> -# if defined (BSD) -# if BSD == 43 - printf ("vax-dec-bsd4.3\n"); exit (0); -# else -# if BSD == 199006 - printf ("vax-dec-bsd4.3reno\n"); exit (0); -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# endif -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# else - printf ("vax-dec-ultrix\n"); exit (0); -# endif -#endif - -#if defined (alliant) && defined (i860) - printf ("i860-alliant-bsd\n"); exit (0); -#endif - - exit (1); -} -EOF - -$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && - { echo "$SYSTEM_NAME"; exit; } - -# Apollos put the system type in the environment. - -test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } - -# Convex versions that predate uname can use getsysinfo(1) - -if [ -x /usr/convex/getsysinfo ] -then - case `getsysinfo -f cpu_type` in - c1*) - echo c1-convex-bsd - exit ;; - c2*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit ;; - c34*) - echo c34-convex-bsd - exit ;; - c38*) - echo c38-convex-bsd - exit ;; - c4*) - echo c4-convex-bsd - exit ;; - esac -fi - -cat >&2 <<EOF -$0: unable to guess system type - -This script, last modified $timestamp, has failed to recognize -the operating system you are using. It is advised that you -download the most up to date version of the config scripts from - - http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess -and - http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub - -If the version you run ($0) is already up to date, please -send the following data and any information you think might be -pertinent to <config-patches@gnu.org> in order to provide the needed -information to handle your system. - -config.guess timestamp = $timestamp - -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null` - -hostinfo = `(hostinfo) 2>/dev/null` -/bin/universe = `(/bin/universe) 2>/dev/null` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` -/bin/arch = `(/bin/arch) 2>/dev/null` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` - -UNAME_MACHINE = ${UNAME_MACHINE} -UNAME_RELEASE = ${UNAME_RELEASE} -UNAME_SYSTEM = ${UNAME_SYSTEM} -UNAME_VERSION = ${UNAME_VERSION} -EOF - -exit 1 - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/source/lib/tdb/config.mk b/source/lib/tdb/config.mk deleted file mode 100644 index ab90ed728d5..00000000000 --- a/source/lib/tdb/config.mk +++ /dev/null @@ -1,68 +0,0 @@ -################################################ -# Start SUBSYSTEM LIBTDB -[LIBRARY::LIBTDB] -VERSION = 0.0.1 -SO_VERSION = 0 -DESCRIPTION = Trivial Database Library -OBJ_FILES = \ - common/tdb.o common/dump.o common/io.o common/lock.o \ - common/open.o common/traverse.o common/freelist.o \ - common/error.o common/transaction.o -CFLAGS = -Ilib/tdb/include -PUBLIC_HEADERS = include/tdb.h -# -# End SUBSYSTEM ldb -################################################ - -################################################ -# Start BINARY tdbtool -[BINARY::tdbtool] -INSTALLDIR = BINDIR -OBJ_FILES= \ - tools/tdbtool.o -PRIVATE_DEPENDENCIES = \ - LIBTDB -# End BINARY tdbtool -################################################ - -################################################ -# Start BINARY tdbtorture -[BINARY::tdbtorture] -INSTALLDIR = BINDIR -OBJ_FILES= \ - tools/tdbtorture.o -PRIVATE_DEPENDENCIES = \ - LIBTDB -# End BINARY tdbtorture -################################################ - -################################################ -# Start BINARY tdbdump -[BINARY::tdbdump] -INSTALLDIR = BINDIR -OBJ_FILES= \ - tools/tdbdump.o -PRIVATE_DEPENDENCIES = \ - LIBTDB -# End BINARY tdbdump -################################################ - -################################################ -# Start BINARY tdbbackup -[BINARY::tdbbackup] -INSTALLDIR = BINDIR -OBJ_FILES= \ - tools/tdbbackup.o -PRIVATE_DEPENDENCIES = \ - LIBTDB -# End BINARY tdbbackup -################################################ - -####################### -# Start LIBRARY swig_tdb -[LIBRARY::swig_tdb] -LIBRARY_REALNAME = swig/_tdb.$(SHLIBEXT) -OBJ_FILES = swig/tdb_wrap.o -PUBLIC_DEPENDENCIES = LIBTDB DYNCONFIG -# End LIBRARY swig_tdb -####################### diff --git a/source/lib/tdb/config.sub b/source/lib/tdb/config.sub deleted file mode 100755 index 1c366dfde9a..00000000000 --- a/source/lib/tdb/config.sub +++ /dev/null @@ -1,1579 +0,0 @@ -#! /bin/sh -# Configuration validation subroutine script. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. - -timestamp='2005-07-08' - -# This file is (in principle) common to ALL GNU software. -# The presence of a machine in this file suggests that SOME GNU software -# can handle that machine. It does not imply ALL GNU software can. -# -# This file 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., 51 Franklin Street - Fifth Floor, Boston, MA -# 02110-1301, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - - -# Please send patches to <config-patches@gnu.org>. Submit a context -# diff and a properly formatted ChangeLog entry. -# -# Configuration subroutine to validate and canonicalize a configuration type. -# Supply the specified configuration type as an argument. -# If it is invalid, we print an error message on stderr and exit with code 1. -# Otherwise, we print the canonical config type on stdout and succeed. - -# This file is supposed to be the same for all GNU packages -# and recognize all the CPU types, system types and aliases -# that are meaningful with *any* GNU software. -# Each package is responsible for reporting which valid configurations -# it does not support. The user should be able to distinguish -# a failure to support a valid configuration from a meaningless -# configuration. - -# The goal of this file is to map all the various variations of a given -# machine specification into a single specification in the form: -# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM -# or in some cases, the newer four-part form: -# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM -# It is wrong to echo any other type of specification. - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] CPU-MFR-OPSYS - $0 [OPTION] ALIAS - -Canonicalize a configuration name. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to <config-patches@gnu.org>." - -version="\ -GNU config.sub ($timestamp) - -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 -Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit ;; - --version | -v ) - echo "$version" ; exit ;; - --help | --h* | -h ) - echo "$usage"; exit ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" - exit 1 ;; - - *local*) - # First pass through any local machine types. - echo $1 - exit ;; - - * ) - break ;; - esac -done - -case $# in - 0) echo "$me: missing argument$help" >&2 - exit 1;; - 1) ;; - *) echo "$me: too many arguments$help" >&2 - exit 1;; -esac - -# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). -# Here we must recognize all the valid KERNEL-OS combinations. -maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` -case $maybe_os in - nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \ - kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*) - os=-$maybe_os - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` - ;; - *) - basic_machine=`echo $1 | sed 's/-[^-]*$//'` - if [ $basic_machine != $1 ] - then os=`echo $1 | sed 's/.*-/-/'` - else os=; fi - ;; -esac - -### Let's recognize common machines as not being operating systems so -### that things like config.sub decstation-3100 work. We also -### recognize some manufacturers as not being operating systems, so we -### can provide default operating systems below. -case $os in - -sun*os*) - # Prevent following clause from handling this invalid input. - ;; - -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ - -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ - -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ - -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ - -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ - -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ - -apple | -axis | -knuth | -cray) - os= - basic_machine=$1 - ;; - -sim | -cisco | -oki | -wec | -winbond) - os= - basic_machine=$1 - ;; - -scout) - ;; - -wrs) - os=-vxworks - basic_machine=$1 - ;; - -chorusos*) - os=-chorusos - basic_machine=$1 - ;; - -chorusrdb) - os=-chorusrdb - basic_machine=$1 - ;; - -hiux*) - os=-hiuxwe2 - ;; - -sco5) - os=-sco3.2v5 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco4) - os=-sco3.2v4 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2.[4-9]*) - os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2v[4-9]*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco*) - os=-sco3.2v2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -udk*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -isc) - os=-isc2.2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -clix*) - basic_machine=clipper-intergraph - ;; - -isc*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -lynx*) - os=-lynxos - ;; - -ptx*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` - ;; - -windowsnt*) - os=`echo $os | sed -e 's/windowsnt/winnt/'` - ;; - -psos*) - os=-psos - ;; - -mint | -mint[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; -esac - -# Decode aliases for certain CPU-COMPANY combinations. -case $basic_machine in - # Recognize the basic CPU types without company name. - # Some are omitted here because they have special meanings below. - 1750a | 580 \ - | a29k \ - | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ - | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ - | am33_2.0 \ - | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ - | bfin \ - | c4x | clipper \ - | d10v | d30v | dlx | dsp16xx \ - | fr30 | frv \ - | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ - | i370 | i860 | i960 | ia64 \ - | ip2k | iq2000 \ - | m32r | m32rle | m68000 | m68k | m88k | maxq | mcore \ - | mips | mipsbe | mipseb | mipsel | mipsle \ - | mips16 \ - | mips64 | mips64el \ - | mips64vr | mips64vrel \ - | mips64orion | mips64orionel \ - | mips64vr4100 | mips64vr4100el \ - | mips64vr4300 | mips64vr4300el \ - | mips64vr5000 | mips64vr5000el \ - | mips64vr5900 | mips64vr5900el \ - | mipsisa32 | mipsisa32el \ - | mipsisa32r2 | mipsisa32r2el \ - | mipsisa64 | mipsisa64el \ - | mipsisa64r2 | mipsisa64r2el \ - | mipsisa64sb1 | mipsisa64sb1el \ - | mipsisa64sr71k | mipsisa64sr71kel \ - | mipstx39 | mipstx39el \ - | mn10200 | mn10300 \ - | ms1 \ - | msp430 \ - | ns16k | ns32k \ - | or32 \ - | pdp10 | pdp11 | pj | pjl \ - | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ - | pyramid \ - | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ - | sh64 | sh64le \ - | sparc | sparc64 | sparc64b | sparc86x | sparclet | sparclite \ - | sparcv8 | sparcv9 | sparcv9b \ - | strongarm \ - | tahoe | thumb | tic4x | tic80 | tron \ - | v850 | v850e \ - | we32k \ - | x86 | xscale | xscalee[bl] | xstormy16 | xtensa \ - | z8k) - basic_machine=$basic_machine-unknown - ;; - m32c) - basic_machine=$basic_machine-unknown - ;; - m6811 | m68hc11 | m6812 | m68hc12) - # Motorola 68HC11/12. - basic_machine=$basic_machine-unknown - os=-none - ;; - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) - ;; - - # We use `pc' rather than `unknown' - # because (1) that's what they normally are, and - # (2) the word "unknown" tends to confuse beginning users. - i*86 | x86_64) - basic_machine=$basic_machine-pc - ;; - # Object if more than one company name word. - *-*-*) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; - # Recognize the basic CPU types with company name. - 580-* \ - | a29k-* \ - | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ - | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ - | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ - | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ - | avr-* \ - | bfin-* | bs2000-* \ - | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ - | clipper-* | craynv-* | cydra-* \ - | d10v-* | d30v-* | dlx-* \ - | elxsi-* \ - | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ - | h8300-* | h8500-* \ - | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ - | i*86-* | i860-* | i960-* | ia64-* \ - | ip2k-* | iq2000-* \ - | m32r-* | m32rle-* \ - | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | maxq-* | mcore-* \ - | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ - | mips16-* \ - | mips64-* | mips64el-* \ - | mips64vr-* | mips64vrel-* \ - | mips64orion-* | mips64orionel-* \ - | mips64vr4100-* | mips64vr4100el-* \ - | mips64vr4300-* | mips64vr4300el-* \ - | mips64vr5000-* | mips64vr5000el-* \ - | mips64vr5900-* | mips64vr5900el-* \ - | mipsisa32-* | mipsisa32el-* \ - | mipsisa32r2-* | mipsisa32r2el-* \ - | mipsisa64-* | mipsisa64el-* \ - | mipsisa64r2-* | mipsisa64r2el-* \ - | mipsisa64sb1-* | mipsisa64sb1el-* \ - | mipsisa64sr71k-* | mipsisa64sr71kel-* \ - | mipstx39-* | mipstx39el-* \ - | mmix-* \ - | ms1-* \ - | msp430-* \ - | none-* | np1-* | ns16k-* | ns32k-* \ - | orion-* \ - | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ - | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ - | pyramid-* \ - | romp-* | rs6000-* \ - | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | shbe-* \ - | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ - | sparc-* | sparc64-* | sparc64b-* | sparc86x-* | sparclet-* \ - | sparclite-* \ - | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ - | tahoe-* | thumb-* \ - | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ - | tron-* \ - | v850-* | v850e-* | vax-* \ - | we32k-* \ - | x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \ - | xstormy16-* | xtensa-* \ - | ymp-* \ - | z8k-*) - ;; - m32c-*) - ;; - # Recognize the various machine names and aliases which stand - # for a CPU type and a company and sometimes even an OS. - 386bsd) - basic_machine=i386-unknown - os=-bsd - ;; - 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) - basic_machine=m68000-att - ;; - 3b*) - basic_machine=we32k-att - ;; - a29khif) - basic_machine=a29k-amd - os=-udi - ;; - abacus) - basic_machine=abacus-unknown - ;; - adobe68k) - basic_machine=m68010-adobe - os=-scout - ;; - alliant | fx80) - basic_machine=fx80-alliant - ;; - altos | altos3068) - basic_machine=m68k-altos - ;; - am29k) - basic_machine=a29k-none - os=-bsd - ;; - amd64) - basic_machine=x86_64-pc - ;; - amd64-*) - basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - amdahl) - basic_machine=580-amdahl - os=-sysv - ;; - amiga | amiga-*) - basic_machine=m68k-unknown - ;; - amigaos | amigados) - basic_machine=m68k-unknown - os=-amigaos - ;; - amigaunix | amix) - basic_machine=m68k-unknown - os=-sysv4 - ;; - apollo68) - basic_machine=m68k-apollo - os=-sysv - ;; - apollo68bsd) - basic_machine=m68k-apollo - os=-bsd - ;; - aux) - basic_machine=m68k-apple - os=-aux - ;; - balance) - basic_machine=ns32k-sequent - os=-dynix - ;; - c90) - basic_machine=c90-cray - os=-unicos - ;; - convex-c1) - basic_machine=c1-convex - os=-bsd - ;; - convex-c2) - basic_machine=c2-convex - os=-bsd - ;; - convex-c32) - basic_machine=c32-convex - os=-bsd - ;; - convex-c34) - basic_machine=c34-convex - os=-bsd - ;; - convex-c38) - basic_machine=c38-convex - os=-bsd - ;; - cray | j90) - basic_machine=j90-cray - os=-unicos - ;; - craynv) - basic_machine=craynv-cray - os=-unicosmp - ;; - cr16c) - basic_machine=cr16c-unknown - os=-elf - ;; - crds | unos) - basic_machine=m68k-crds - ;; - crisv32 | crisv32-* | etraxfs*) - basic_machine=crisv32-axis - ;; - cris | cris-* | etrax*) - basic_machine=cris-axis - ;; - crx) - basic_machine=crx-unknown - os=-elf - ;; - da30 | da30-*) - basic_machine=m68k-da30 - ;; - decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) - basic_machine=mips-dec - ;; - decsystem10* | dec10*) - basic_machine=pdp10-dec - os=-tops10 - ;; - decsystem20* | dec20*) - basic_machine=pdp10-dec - os=-tops20 - ;; - delta | 3300 | motorola-3300 | motorola-delta \ - | 3300-motorola | delta-motorola) - basic_machine=m68k-motorola - ;; - delta88) - basic_machine=m88k-motorola - os=-sysv3 - ;; - djgpp) - basic_machine=i586-pc - os=-msdosdjgpp - ;; - dpx20 | dpx20-*) - basic_machine=rs6000-bull - os=-bosx - ;; - dpx2* | dpx2*-bull) - basic_machine=m68k-bull - os=-sysv3 - ;; - ebmon29k) - basic_machine=a29k-amd - os=-ebmon - ;; - elxsi) - basic_machine=elxsi-elxsi - os=-bsd - ;; - encore | umax | mmax) - basic_machine=ns32k-encore - ;; - es1800 | OSE68k | ose68k | ose | OSE) - basic_machine=m68k-ericsson - os=-ose - ;; - fx2800) - basic_machine=i860-alliant - ;; - genix) - basic_machine=ns32k-ns - ;; - gmicro) - basic_machine=tron-gmicro - os=-sysv - ;; - go32) - basic_machine=i386-pc - os=-go32 - ;; - h3050r* | hiux*) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - h8300hms) - basic_machine=h8300-hitachi - os=-hms - ;; - h8300xray) - basic_machine=h8300-hitachi - os=-xray - ;; - h8500hms) - basic_machine=h8500-hitachi - os=-hms - ;; - harris) - basic_machine=m88k-harris - os=-sysv3 - ;; - hp300-*) - basic_machine=m68k-hp - ;; - hp300bsd) - basic_machine=m68k-hp - os=-bsd - ;; - hp300hpux) - basic_machine=m68k-hp - os=-hpux - ;; - hp3k9[0-9][0-9] | hp9[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k2[0-9][0-9] | hp9k31[0-9]) - basic_machine=m68000-hp - ;; - hp9k3[2-9][0-9]) - basic_machine=m68k-hp - ;; - hp9k6[0-9][0-9] | hp6[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k7[0-79][0-9] | hp7[0-79][0-9]) - basic_machine=hppa1.1-hp - ;; - hp9k78[0-9] | hp78[0-9]) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][13679] | hp8[0-9][13679]) - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][0-9] | hp8[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hppa-next) - os=-nextstep3 - ;; - hppaosf) - basic_machine=hppa1.1-hp - os=-osf - ;; - hppro) - basic_machine=hppa1.1-hp - os=-proelf - ;; - i370-ibm* | ibm*) - basic_machine=i370-ibm - ;; -# I'm not sure what "Sysv32" means. Should this be sysv3.2? - i*86v32) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv32 - ;; - i*86v4*) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv4 - ;; - i*86v) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv - ;; - i*86sol2) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-solaris2 - ;; - i386mach) - basic_machine=i386-mach - os=-mach - ;; - i386-vsta | vsta) - basic_machine=i386-unknown - os=-vsta - ;; - iris | iris4d) - basic_machine=mips-sgi - case $os in - -irix*) - ;; - *) - os=-irix4 - ;; - esac - ;; - isi68 | isi) - basic_machine=m68k-isi - os=-sysv - ;; - m88k-omron*) - basic_machine=m88k-omron - ;; - magnum | m3230) - basic_machine=mips-mips - os=-sysv - ;; - merlin) - basic_machine=ns32k-utek - os=-sysv - ;; - mingw32) - basic_machine=i386-pc - os=-mingw32 - ;; - miniframe) - basic_machine=m68000-convergent - ;; - *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; - mips3*-*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` - ;; - mips3*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown - ;; - monitor) - basic_machine=m68k-rom68k - os=-coff - ;; - morphos) - basic_machine=powerpc-unknown - os=-morphos - ;; - msdos) - basic_machine=i386-pc - os=-msdos - ;; - mvs) - basic_machine=i370-ibm - os=-mvs - ;; - ncr3000) - basic_machine=i486-ncr - os=-sysv4 - ;; - netbsd386) - basic_machine=i386-unknown - os=-netbsd - ;; - netwinder) - basic_machine=armv4l-rebel - os=-linux - ;; - news | news700 | news800 | news900) - basic_machine=m68k-sony - os=-newsos - ;; - news1000) - basic_machine=m68030-sony - os=-newsos - ;; - news-3600 | risc-news) - basic_machine=mips-sony - os=-newsos - ;; - necv70) - basic_machine=v70-nec - os=-sysv - ;; - next | m*-next ) - basic_machine=m68k-next - case $os in - -nextstep* ) - ;; - -ns2*) - os=-nextstep2 - ;; - *) - os=-nextstep3 - ;; - esac - ;; - nh3000) - basic_machine=m68k-harris - os=-cxux - ;; - nh[45]000) - basic_machine=m88k-harris - os=-cxux - ;; - nindy960) - basic_machine=i960-intel - os=-nindy - ;; - mon960) - basic_machine=i960-intel - os=-mon960 - ;; - nonstopux) - basic_machine=mips-compaq - os=-nonstopux - ;; - np1) - basic_machine=np1-gould - ;; - nsr-tandem) - basic_machine=nsr-tandem - ;; - op50n-* | op60c-*) - basic_machine=hppa1.1-oki - os=-proelf - ;; - openrisc | openrisc-*) - basic_machine=or32-unknown - ;; - os400) - basic_machine=powerpc-ibm - os=-os400 - ;; - OSE68000 | ose68000) - basic_machine=m68000-ericsson - os=-ose - ;; - os68k) - basic_machine=m68k-none - os=-os68k - ;; - pa-hitachi) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - paragon) - basic_machine=i860-intel - os=-osf - ;; - pbd) - basic_machine=sparc-tti - ;; - pbb) - basic_machine=m68k-tti - ;; - pc532 | pc532-*) - basic_machine=ns32k-pc532 - ;; - pentium | p5 | k5 | k6 | nexgen | viac3) - basic_machine=i586-pc - ;; - pentiumpro | p6 | 6x86 | athlon | athlon_*) - basic_machine=i686-pc - ;; - pentiumii | pentium2 | pentiumiii | pentium3) - basic_machine=i686-pc - ;; - pentium4) - basic_machine=i786-pc - ;; - pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) - basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumpro-* | p6-* | 6x86-* | athlon-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentium4-*) - basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pn) - basic_machine=pn-gould - ;; - power) basic_machine=power-ibm - ;; - ppc) basic_machine=powerpc-unknown - ;; - ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppcle | powerpclittle | ppc-le | powerpc-little) - basic_machine=powerpcle-unknown - ;; - ppcle-* | powerpclittle-*) - basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64) basic_machine=powerpc64-unknown - ;; - ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64le | powerpc64little | ppc64-le | powerpc64-little) - basic_machine=powerpc64le-unknown - ;; - ppc64le-* | powerpc64little-*) - basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ps2) - basic_machine=i386-ibm - ;; - pw32) - basic_machine=i586-unknown - os=-pw32 - ;; - rom68k) - basic_machine=m68k-rom68k - os=-coff - ;; - rm[46]00) - basic_machine=mips-siemens - ;; - rtpc | rtpc-*) - basic_machine=romp-ibm - ;; - s390 | s390-*) - basic_machine=s390-ibm - ;; - s390x | s390x-*) - basic_machine=s390x-ibm - ;; - sa29200) - basic_machine=a29k-amd - os=-udi - ;; - sb1) - basic_machine=mipsisa64sb1-unknown - ;; - sb1el) - basic_machine=mipsisa64sb1el-unknown - ;; - sei) - basic_machine=mips-sei - os=-seiux - ;; - sequent) - basic_machine=i386-sequent - ;; - sh) - basic_machine=sh-hitachi - os=-hms - ;; - sh64) - basic_machine=sh64-unknown - ;; - sparclite-wrs | simso-wrs) - basic_machine=sparclite-wrs - os=-vxworks - ;; - sps7) - basic_machine=m68k-bull - os=-sysv2 - ;; - spur) - basic_machine=spur-unknown - ;; - st2000) - basic_machine=m68k-tandem - ;; - stratus) - basic_machine=i860-stratus - os=-sysv4 - ;; - sun2) - basic_machine=m68000-sun - ;; - sun2os3) - basic_machine=m68000-sun - os=-sunos3 - ;; - sun2os4) - basic_machine=m68000-sun - os=-sunos4 - ;; - sun3os3) - basic_machine=m68k-sun - os=-sunos3 - ;; - sun3os4) - basic_machine=m68k-sun - os=-sunos4 - ;; - sun4os3) - basic_machine=sparc-sun - os=-sunos3 - ;; - sun4os4) - basic_machine=sparc-sun - os=-sunos4 - ;; - sun4sol2) - basic_machine=sparc-sun - os=-solaris2 - ;; - sun3 | sun3-*) - basic_machine=m68k-sun - ;; - sun4) - basic_machine=sparc-sun - ;; - sun386 | sun386i | roadrunner) - basic_machine=i386-sun - ;; - sv1) - basic_machine=sv1-cray - os=-unicos - ;; - symmetry) - basic_machine=i386-sequent - os=-dynix - ;; - t3e) - basic_machine=alphaev5-cray - os=-unicos - ;; - t90) - basic_machine=t90-cray - os=-unicos - ;; - tic54x | c54x*) - basic_machine=tic54x-unknown - os=-coff - ;; - tic55x | c55x*) - basic_machine=tic55x-unknown - os=-coff - ;; - tic6x | c6x*) - basic_machine=tic6x-unknown - os=-coff - ;; - tx39) - basic_machine=mipstx39-unknown - ;; - tx39el) - basic_machine=mipstx39el-unknown - ;; - toad1) - basic_machine=pdp10-xkl - os=-tops20 - ;; - tower | tower-32) - basic_machine=m68k-ncr - ;; - tpf) - basic_machine=s390x-ibm - os=-tpf - ;; - udi29k) - basic_machine=a29k-amd - os=-udi - ;; - ultra3) - basic_machine=a29k-nyu - os=-sym1 - ;; - v810 | necv810) - basic_machine=v810-nec - os=-none - ;; - vaxv) - basic_machine=vax-dec - os=-sysv - ;; - vms) - basic_machine=vax-dec - os=-vms - ;; - vpp*|vx|vx-*) - basic_machine=f301-fujitsu - ;; - vxworks960) - basic_machine=i960-wrs - os=-vxworks - ;; - vxworks68) - basic_machine=m68k-wrs - os=-vxworks - ;; - vxworks29k) - basic_machine=a29k-wrs - os=-vxworks - ;; - w65*) - basic_machine=w65-wdc - os=-none - ;; - w89k-*) - basic_machine=hppa1.1-winbond - os=-proelf - ;; - xbox) - basic_machine=i686-pc - os=-mingw32 - ;; - xps | xps100) - basic_machine=xps100-honeywell - ;; - ymp) - basic_machine=ymp-cray - os=-unicos - ;; - z8k-*-coff) - basic_machine=z8k-unknown - os=-sim - ;; - none) - basic_machine=none-none - os=-none - ;; - -# Here we handle the default manufacturer of certain CPU types. It is in -# some cases the only manufacturer, in others, it is the most popular. - w89k) - basic_machine=hppa1.1-winbond - ;; - op50n) - basic_machine=hppa1.1-oki - ;; - op60c) - basic_machine=hppa1.1-oki - ;; - romp) - basic_machine=romp-ibm - ;; - mmix) - basic_machine=mmix-knuth - ;; - rs6000) - basic_machine=rs6000-ibm - ;; - vax) - basic_machine=vax-dec - ;; - pdp10) - # there are many clones, so DEC is not a safe bet - basic_machine=pdp10-unknown - ;; - pdp11) - basic_machine=pdp11-dec - ;; - we32k) - basic_machine=we32k-att - ;; - sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele) - basic_machine=sh-unknown - ;; - sparc | sparcv8 | sparcv9 | sparcv9b) - basic_machine=sparc-sun - ;; - cydra) - basic_machine=cydra-cydrome - ;; - orion) - basic_machine=orion-highlevel - ;; - orion105) - basic_machine=clipper-highlevel - ;; - mac | mpw | mac-mpw) - basic_machine=m68k-apple - ;; - pmac | pmac-mpw) - basic_machine=powerpc-apple - ;; - *-unknown) - # Make sure to match an already-canonicalized machine name. - ;; - *) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; -esac - -# Here we canonicalize certain aliases for manufacturers. -case $basic_machine in - *-digital*) - basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` - ;; - *-commodore*) - basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` - ;; - *) - ;; -esac - -# Decode manufacturer-specific aliases for certain operating systems. - -if [ x"$os" != x"" ] -then -case $os in - # First match some system type aliases - # that might get confused with valid system types. - # -solaris* is a basic system type, with this one exception. - -solaris1 | -solaris1.*) - os=`echo $os | sed -e 's|solaris1|sunos4|'` - ;; - -solaris) - os=-solaris2 - ;; - -svr4*) - os=-sysv4 - ;; - -unixware*) - os=-sysv4.2uw - ;; - -gnu/linux*) - os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` - ;; - # First accept the basic system types. - # The portable systems comes first. - # Each alternative MUST END IN A *, to match a version number. - # -sysv* is not here because it comes later, after sysvr4. - -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ - | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ - | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ - | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ - | -aos* \ - | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ - | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ - | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \ - | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ - | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ - | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ - | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ - | -chorusos* | -chorusrdb* \ - | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \ - | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ - | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ - | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ - | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ - | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ - | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ - | -skyos* | -haiku*) - # Remember, each alternative MUST END IN *, to match a version number. - ;; - -qnx*) - case $basic_machine in - x86-* | i*86-*) - ;; - *) - os=-nto$os - ;; - esac - ;; - -nto-qnx*) - ;; - -nto*) - os=`echo $os | sed -e 's|nto|nto-qnx|'` - ;; - -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ - | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ - | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) - ;; - -mac*) - os=`echo $os | sed -e 's|mac|macos|'` - ;; - -linux-dietlibc) - os=-linux-dietlibc - ;; - -linux*) - os=`echo $os | sed -e 's|linux|linux-gnu|'` - ;; - -sunos5*) - os=`echo $os | sed -e 's|sunos5|solaris2|'` - ;; - -sunos6*) - os=`echo $os | sed -e 's|sunos6|solaris3|'` - ;; - -opened*) - os=-openedition - ;; - -os400*) - os=-os400 - ;; - -wince*) - os=-wince - ;; - -osfrose*) - os=-osfrose - ;; - -osf*) - os=-osf - ;; - -utek*) - os=-bsd - ;; - -dynix*) - os=-bsd - ;; - -acis*) - os=-aos - ;; - -atheos*) - os=-atheos - ;; - -syllable*) - os=-syllable - ;; - -386bsd) - os=-bsd - ;; - -ctix* | -uts*) - os=-sysv - ;; - -nova*) - os=-rtmk-nova - ;; - -ns2 ) - os=-nextstep2 - ;; - -nsk*) - os=-nsk - ;; - # Preserve the version number of sinix5. - -sinix5.*) - os=`echo $os | sed -e 's|sinix|sysv|'` - ;; - -sinix*) - os=-sysv4 - ;; - -tpf*) - os=-tpf - ;; - -triton*) - os=-sysv3 - ;; - -oss*) - os=-sysv3 - ;; - -svr4) - os=-sysv4 - ;; - -svr3) - os=-sysv3 - ;; - -sysvr4) - os=-sysv4 - ;; - # This must come after -sysvr4. - -sysv*) - ;; - -ose*) - os=-ose - ;; - -es1800*) - os=-ose - ;; - -xenix) - os=-xenix - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - os=-mint - ;; - -aros*) - os=-aros - ;; - -kaos*) - os=-kaos - ;; - -zvmoe) - os=-zvmoe - ;; - -none) - ;; - *) - # Get rid of the `-' at the beginning of $os. - os=`echo $os | sed 's/[^-]*-//'` - echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 - exit 1 - ;; -esac -else - -# Here we handle the default operating systems that come with various machines. -# The value should be what the vendor currently ships out the door with their -# machine or put another way, the most popular os provided with the machine. - -# Note that if you're going to try to match "-MANUFACTURER" here (say, -# "-sun"), then you have to tell the case statement up towards the top -# that MANUFACTURER isn't an operating system. Otherwise, code above -# will signal an error saying that MANUFACTURER isn't an operating -# system, and we'll never get to this point. - -case $basic_machine in - *-acorn) - os=-riscix1.2 - ;; - arm*-rebel) - os=-linux - ;; - arm*-semi) - os=-aout - ;; - c4x-* | tic4x-*) - os=-coff - ;; - # This must come before the *-dec entry. - pdp10-*) - os=-tops20 - ;; - pdp11-*) - os=-none - ;; - *-dec | vax-*) - os=-ultrix4.2 - ;; - m68*-apollo) - os=-domain - ;; - i386-sun) - os=-sunos4.0.2 - ;; - m68000-sun) - os=-sunos3 - # This also exists in the configure program, but was not the - # default. - # os=-sunos4 - ;; - m68*-cisco) - os=-aout - ;; - mips*-cisco) - os=-elf - ;; - mips*-*) - os=-elf - ;; - or32-*) - os=-coff - ;; - *-tti) # must be before sparc entry or we get the wrong os. - os=-sysv3 - ;; - sparc-* | *-sun) - os=-sunos4.1.1 - ;; - *-be) - os=-beos - ;; - *-haiku) - os=-haiku - ;; - *-ibm) - os=-aix - ;; - *-knuth) - os=-mmixware - ;; - *-wec) - os=-proelf - ;; - *-winbond) - os=-proelf - ;; - *-oki) - os=-proelf - ;; - *-hp) - os=-hpux - ;; - *-hitachi) - os=-hiux - ;; - i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) - os=-sysv - ;; - *-cbm) - os=-amigaos - ;; - *-dg) - os=-dgux - ;; - *-dolphin) - os=-sysv3 - ;; - m68k-ccur) - os=-rtu - ;; - m88k-omron*) - os=-luna - ;; - *-next ) - os=-nextstep - ;; - *-sequent) - os=-ptx - ;; - *-crds) - os=-unos - ;; - *-ns) - os=-genix - ;; - i370-*) - os=-mvs - ;; - *-next) - os=-nextstep3 - ;; - *-gould) - os=-sysv - ;; - *-highlevel) - os=-bsd - ;; - *-encore) - os=-bsd - ;; - *-sgi) - os=-irix - ;; - *-siemens) - os=-sysv4 - ;; - *-masscomp) - os=-rtu - ;; - f30[01]-fujitsu | f700-fujitsu) - os=-uxpv - ;; - *-rom68k) - os=-coff - ;; - *-*bug) - os=-coff - ;; - *-apple) - os=-macos - ;; - *-atari*) - os=-mint - ;; - *) - os=-none - ;; -esac -fi - -# Here we handle the case where we know the os, and the CPU type, but not the -# manufacturer. We pick the logical manufacturer. -vendor=unknown -case $basic_machine in - *-unknown) - case $os in - -riscix*) - vendor=acorn - ;; - -sunos*) - vendor=sun - ;; - -aix*) - vendor=ibm - ;; - -beos*) - vendor=be - ;; - -hpux*) - vendor=hp - ;; - -mpeix*) - vendor=hp - ;; - -hiux*) - vendor=hitachi - ;; - -unos*) - vendor=crds - ;; - -dgux*) - vendor=dg - ;; - -luna*) - vendor=omron - ;; - -genix*) - vendor=ns - ;; - -mvs* | -opened*) - vendor=ibm - ;; - -os400*) - vendor=ibm - ;; - -ptx*) - vendor=sequent - ;; - -tpf*) - vendor=ibm - ;; - -vxsim* | -vxworks* | -windiss*) - vendor=wrs - ;; - -aux*) - vendor=apple - ;; - -hms*) - vendor=hitachi - ;; - -mpw* | -macos*) - vendor=apple - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - vendor=atari - ;; - -vos*) - vendor=stratus - ;; - esac - basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` - ;; -esac - -echo $basic_machine$os -exit - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/source/lib/tdb/configure.ac b/source/lib/tdb/configure.ac deleted file mode 100644 index 8bfff589cc5..00000000000 --- a/source/lib/tdb/configure.ac +++ /dev/null @@ -1,10 +0,0 @@ -AC_PREREQ(2.50) -AC_DEFUN([SMB_MODULE_DEFAULT], [echo -n ""]) -AC_DEFUN([SMB_LIBRARY_ENABLE], [echo -n ""]) -AC_DEFUN([SMB_ENABLE], [echo -n ""]) -AC_INIT(tdb, 1.1.0) -AC_CONFIG_SRCDIR([common/tdb.c]) -AC_CONFIG_HEADER(include/config.h) -AC_LIBREPLACE_ALL_CHECKS -m4_include(libtdb.m4) -AC_OUTPUT(Makefile tdb.pc) diff --git a/source/lib/tdb/docs/README b/source/lib/tdb/docs/README deleted file mode 100644 index b31ce36ab14..00000000000 --- a/source/lib/tdb/docs/README +++ /dev/null @@ -1,235 +0,0 @@ -tdb - a trivial database system -tridge@linuxcare.com December 1999 -================================== - -This is a simple database API. It was inspired by the realisation that -in Samba we have several ad-hoc bits of code that essentially -implement small databases for sharing structures between parts of -Samba. As I was about to add another I realised that a generic -database module was called for to replace all the ad-hoc bits. - -I based the interface on gdbm. I couldn't use gdbm as we need to be -able to have multiple writers to the databases at one time. - -Compilation ------------ - -add HAVE_MMAP=1 to use mmap instead of read/write -add NOLOCK=1 to disable locking code - -Testing -------- - -Compile tdbtest.c and link with gdbm for testing. tdbtest will perform -identical operations via tdb and gdbm then make sure the result is the -same - -Also included is tdbtool, which allows simple database manipulation -on the commandline. - -tdbtest and tdbtool are not built as part of Samba, but are included -for completeness. - -Interface ---------- - -The interface is very similar to gdbm except for the following: - -- different open interface. The tdb_open call is more similar to a - traditional open() -- no tdbm_reorganise() function -- no tdbm_sync() function. No operations are cached in the library anyway -- added a tdb_traverse() function for traversing the whole database -- added transactions support - -A general rule for using tdb is that the caller frees any returned -TDB_DATA structures. Just call free(p.dptr) to free a TDB_DATA -return value called p. This is the same as gdbm. - -here is a full list of tdb functions with brief descriptions. - - ----------------------------------------------------------------------- -TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags, - int open_flags, mode_t mode) - - open the database, creating it if necessary - - The open_flags and mode are passed straight to the open call on the database - file. A flags value of O_WRONLY is invalid - - The hash size is advisory, use zero for a default value. - - return is NULL on error - - possible tdb_flags are: - TDB_CLEAR_IF_FIRST - clear database if we are the only one with it open - TDB_INTERNAL - don't use a file, instaed store the data in - memory. The filename is ignored in this case. - TDB_NOLOCK - don't do any locking - TDB_NOMMAP - don't use mmap - TDB_NOSYNC - don't synchronise transactions to disk - ----------------------------------------------------------------------- -TDB_CONTEXT *tdb_open_ex(char *name, int hash_size, int tdb_flags, - int open_flags, mode_t mode, - tdb_log_func log_fn, - tdb_hash_func hash_fn) - -This is like tdb_open(), but allows you to pass an initial logging and -hash function. Be careful when passing a hash function - all users of -the database must use the same hash function or you will get data -corruption. - - ----------------------------------------------------------------------- -char *tdb_error(TDB_CONTEXT *tdb); - - return a error string for the last tdb error - ----------------------------------------------------------------------- -int tdb_close(TDB_CONTEXT *tdb); - - close a database - ----------------------------------------------------------------------- -int tdb_update(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf); - - update an entry in place - this only works if the new data size - is <= the old data size and the key exists. - on failure return -1 - ----------------------------------------------------------------------- -TDB_DATA tdb_fetch(TDB_CONTEXT *tdb, TDB_DATA key); - - fetch an entry in the database given a key - if the return value has a null dptr then a error occurred - - caller must free the resulting data - ----------------------------------------------------------------------- -int tdb_exists(TDB_CONTEXT *tdb, TDB_DATA key); - - check if an entry in the database exists - - note that 1 is returned if the key is found and 0 is returned if not found - this doesn't match the conventions in the rest of this module, but is - compatible with gdbm - ----------------------------------------------------------------------- -int tdb_traverse(TDB_CONTEXT *tdb, int (*fn)(TDB_CONTEXT *tdb, - TDB_DATA key, TDB_DATA dbuf, void *state), void *state); - - traverse the entire database - calling fn(tdb, key, data, state) on each - element. - - return -1 on error or the record count traversed - - if fn is NULL then it is not called - - a non-zero return value from fn() indicates that the traversal - should stop. Traversal callbacks may not start transactions. - ----------------------------------------------------------------------- -int tdb_traverse_read(TDB_CONTEXT *tdb, int (*fn)(TDB_CONTEXT *tdb, - TDB_DATA key, TDB_DATA dbuf, void *state), void *state); - - traverse the entire database - calling fn(tdb, key, data, state) on - each element, but marking the database read only during the - traversal, so any write operations will fail. This allows tdb to - use read locks, which increases the parallelism possible during the - traversal. - - return -1 on error or the record count traversed - - if fn is NULL then it is not called - - a non-zero return value from fn() indicates that the traversal - should stop. Traversal callbacks may not start transactions. - ----------------------------------------------------------------------- -TDB_DATA tdb_firstkey(TDB_CONTEXT *tdb); - - find the first entry in the database and return its key - - the caller must free the returned data - ----------------------------------------------------------------------- -TDB_DATA tdb_nextkey(TDB_CONTEXT *tdb, TDB_DATA key); - - find the next entry in the database, returning its key - - the caller must free the returned data - ----------------------------------------------------------------------- -int tdb_delete(TDB_CONTEXT *tdb, TDB_DATA key); - - delete an entry in the database given a key - ----------------------------------------------------------------------- -int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag); - - store an element in the database, replacing any existing element - with the same key - - If flag==TDB_INSERT then don't overwrite an existing entry - If flag==TDB_MODIFY then don't create a new entry - - return 0 on success, -1 on failure - ----------------------------------------------------------------------- -int tdb_writelock(TDB_CONTEXT *tdb); - - lock the database. If we already have it locked then don't do anything - ----------------------------------------------------------------------- -int tdb_writeunlock(TDB_CONTEXT *tdb); - unlock the database - ----------------------------------------------------------------------- -int tdb_lockchain(TDB_CONTEXT *tdb, TDB_DATA key); - - lock one hash chain. This is meant to be used to reduce locking - contention - it cannot guarantee how many records will be locked - ----------------------------------------------------------------------- -int tdb_unlockchain(TDB_CONTEXT *tdb, TDB_DATA key); - - unlock one hash chain - ----------------------------------------------------------------------- -int tdb_transaction_start(TDB_CONTEXT *tdb) - - start a transaction. All operations after the transaction start can - either be committed with tdb_transaction_commit() or cancelled with - tdb_transaction_cancel(). - - If you call tdb_transaction_start() again on the same tdb context - while a transaction is in progress, then the same transaction - buffer is re-used. The number of tdb_transaction_{commit,cancel} - operations must match the number of successful - tdb_transaction_start() calls. - - Note that transactions are by default disk synchronous, and use a - recover area in the database to automatically recover the database - on the next open if the system crashes during a transaction. You - can disable the synchronous transaction recovery setup using the - TDB_NOSYNC flag, which will greatly speed up operations at the risk - of corrupting your database if the system crashes. - - Operations made within a transaction are not visible to other users - of the database until a successful commit. - ----------------------------------------------------------------------- -int tdb_transaction_cancel(TDB_CONTEXT *tdb) - - cancel a current transaction, discarding all write and lock - operations that have been made since the transaction started. - - ----------------------------------------------------------------------- -int tdb_transaction_commit(TDB_CONTEXT *tdb) - - commit a current transaction, updating the database and releasing - the transaction locks. - diff --git a/source/lib/tdb/docs/tdb.magic b/source/lib/tdb/docs/tdb.magic deleted file mode 100644 index f5619e7327e..00000000000 --- a/source/lib/tdb/docs/tdb.magic +++ /dev/null @@ -1,10 +0,0 @@ -# Magic file(1) information about tdb files. -# -# Install this into /etc/magic or the corresponding location for your -# system, or pass as a -m argument to file(1). - -# You may use and redistribute this file without restriction. - -0 string TDB\ file TDB database ->32 lelong =0x2601196D version 6, little-endian ->>36 lelong x hash size %d bytes diff --git a/source/lib/tdb/include/tdb.h b/source/lib/tdb/include/tdb.h deleted file mode 100644 index 3268a3bfa04..00000000000 --- a/source/lib/tdb/include/tdb.h +++ /dev/null @@ -1,153 +0,0 @@ -#ifndef __TDB_H__ -#define __TDB_H__ - -/* - Unix SMB/CIFS implementation. - - trivial database library - - Copyright (C) Andrew Tridgell 1999-2004 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#ifdef __cplusplus -extern "C" { -#endif - - -/* flags to tdb_store() */ -#define TDB_REPLACE 1 -#define TDB_INSERT 2 -#define TDB_MODIFY 3 - -/* flags for tdb_open() */ -#define TDB_DEFAULT 0 /* just a readability place holder */ -#define TDB_CLEAR_IF_FIRST 1 -#define TDB_INTERNAL 2 /* don't store on disk */ -#define TDB_NOLOCK 4 /* don't do any locking */ -#define TDB_NOMMAP 8 /* don't use mmap */ -#define TDB_CONVERT 16 /* convert endian (internal use) */ -#define TDB_BIGENDIAN 32 /* header is big-endian (internal use) */ -#define TDB_NOSYNC 64 /* don't use synchronous transactions */ -#define TDB_SEQNUM 128 /* maintain a sequence number */ -#define TDB_VOLATILE 256 /* Activate the per-hashchain freelist, default 5 */ - -#define TDB_ERRCODE(code, ret) ((tdb->ecode = (code)), ret) - -/* error codes */ -enum TDB_ERROR {TDB_SUCCESS=0, TDB_ERR_CORRUPT, TDB_ERR_IO, TDB_ERR_LOCK, - TDB_ERR_OOM, TDB_ERR_EXISTS, TDB_ERR_NOLOCK, TDB_ERR_LOCK_TIMEOUT, - TDB_ERR_NOEXIST, TDB_ERR_EINVAL, TDB_ERR_RDONLY}; - -/* debugging uses one of the following levels */ -enum tdb_debug_level {TDB_DEBUG_FATAL = 0, TDB_DEBUG_ERROR, - TDB_DEBUG_WARNING, TDB_DEBUG_TRACE}; - -typedef struct TDB_DATA { - unsigned char *dptr; - size_t dsize; -} TDB_DATA; - -#ifndef PRINTF_ATTRIBUTE -#if (__GNUC__ >= 3) -/** Use gcc attribute to check printf fns. a1 is the 1-based index of - * the parameter containing the format, and a2 the index of the first - * argument. Note that some gcc 2.x versions don't handle this - * properly **/ -#define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2))) -#else -#define PRINTF_ATTRIBUTE(a1, a2) -#endif -#endif - -/* this is the context structure that is returned from a db open */ -typedef struct tdb_context TDB_CONTEXT; - -typedef int (*tdb_traverse_func)(struct tdb_context *, TDB_DATA, TDB_DATA, void *); -typedef void (*tdb_log_func)(struct tdb_context *, enum tdb_debug_level, const char *, ...) PRINTF_ATTRIBUTE(3, 4); -typedef unsigned int (*tdb_hash_func)(TDB_DATA *key); - -struct tdb_logging_context { - tdb_log_func log_fn; - void *log_private; -}; - -struct tdb_context *tdb_open(const char *name, int hash_size, int tdb_flags, - int open_flags, mode_t mode); -struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags, - int open_flags, mode_t mode, - const struct tdb_logging_context *log_ctx, - tdb_hash_func hash_fn); -void tdb_set_max_dead(struct tdb_context *tdb, int max_dead); - -int tdb_reopen(struct tdb_context *tdb); -int tdb_reopen_all(int parent_longlived); -void tdb_set_logging_function(struct tdb_context *tdb, const struct tdb_logging_context *log_ctx); -enum TDB_ERROR tdb_error(struct tdb_context *tdb); -const char *tdb_errorstr(struct tdb_context *tdb); -TDB_DATA tdb_fetch(struct tdb_context *tdb, TDB_DATA key); -int tdb_parse_record(struct tdb_context *tdb, TDB_DATA key, - int (*parser)(TDB_DATA key, TDB_DATA data, - void *private_data), - void *private_data); -int tdb_delete(struct tdb_context *tdb, TDB_DATA key); -int tdb_store(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf, int flag); -int tdb_append(struct tdb_context *tdb, TDB_DATA key, TDB_DATA new_dbuf); -int tdb_close(struct tdb_context *tdb); -TDB_DATA tdb_firstkey(struct tdb_context *tdb); -TDB_DATA tdb_nextkey(struct tdb_context *tdb, TDB_DATA key); -int tdb_traverse(struct tdb_context *tdb, tdb_traverse_func fn, void *); -int tdb_traverse_read(struct tdb_context *tdb, tdb_traverse_func fn, void *); -int tdb_exists(struct tdb_context *tdb, TDB_DATA key); -int tdb_lockall(struct tdb_context *tdb); -int tdb_unlockall(struct tdb_context *tdb); -int tdb_lockall_read(struct tdb_context *tdb); -int tdb_unlockall_read(struct tdb_context *tdb); -const char *tdb_name(struct tdb_context *tdb); -int tdb_fd(struct tdb_context *tdb); -tdb_log_func tdb_log_fn(struct tdb_context *tdb); -void *tdb_get_logging_private(struct tdb_context *tdb); -int tdb_transaction_start(struct tdb_context *tdb); -int tdb_transaction_commit(struct tdb_context *tdb); -int tdb_transaction_cancel(struct tdb_context *tdb); -int tdb_transaction_recover(struct tdb_context *tdb); -int tdb_get_seqnum(struct tdb_context *tdb); -int tdb_hash_size(struct tdb_context *tdb); -size_t tdb_map_size(struct tdb_context *tdb); -int tdb_get_flags(struct tdb_context *tdb); - -/* Low level locking functions: use with care */ -int tdb_chainlock(struct tdb_context *tdb, TDB_DATA key); -int tdb_chainunlock(struct tdb_context *tdb, TDB_DATA key); -int tdb_chainlock_read(struct tdb_context *tdb, TDB_DATA key); -int tdb_chainunlock_read(struct tdb_context *tdb, TDB_DATA key); - -/* Debug functions. Not used in production. */ -void tdb_dump_all(struct tdb_context *tdb); -int tdb_printfreelist(struct tdb_context *tdb); -int tdb_validate_freelist(struct tdb_context *tdb, int *pnum_entries); - -extern TDB_DATA tdb_null; - -#ifdef __cplusplus -} -#endif - -#endif /* tdb.h */ diff --git a/source/lib/tdb/install-sh b/source/lib/tdb/install-sh deleted file mode 100755 index 58719246f04..00000000000 --- a/source/lib/tdb/install-sh +++ /dev/null @@ -1,238 +0,0 @@ -#! /bin/sh -# -# install - install a program, script, or datafile -# This comes from X11R5. -# -# Calling this script install-sh is preferred over install.sh, to prevent -# `make' implicit rules from creating a file called install from it -# when there is no Makefile. -# -# This script is compatible with the BSD install script, but was written -# from scratch. -# - - -# set DOITPROG to echo to test this script - -# Don't use :- since 4.3BSD and earlier shells don't like it. -doit="${DOITPROG-}" - - -# put in absolute paths if you don't have them in your path; or use env. vars. - -mvprog="${MVPROG-mv}" -cpprog="${CPPROG-cp}" -chmodprog="${CHMODPROG-chmod}" -chownprog="${CHOWNPROG-chown}" -chgrpprog="${CHGRPPROG-chgrp}" -stripprog="${STRIPPROG-strip}" -rmprog="${RMPROG-rm}" -mkdirprog="${MKDIRPROG-mkdir}" - -transformbasename="" -transform_arg="" -instcmd="$mvprog" -chmodcmd="$chmodprog 0755" -chowncmd="" -chgrpcmd="" -stripcmd="" -rmcmd="$rmprog -f" -mvcmd="$mvprog" -src="" -dst="" -dir_arg="" - -while [ x"$1" != x ]; do - case $1 in - -c) instcmd="$cpprog" - shift - continue;; - - -d) dir_arg=true - shift - continue;; - - -m) chmodcmd="$chmodprog $2" - shift - shift - continue;; - - -o) chowncmd="$chownprog $2" - shift - shift - continue;; - - -g) chgrpcmd="$chgrpprog $2" - shift - shift - continue;; - - -s) stripcmd="$stripprog" - shift - continue;; - - -t=*) transformarg=`echo $1 | sed 's/-t=//'` - shift - continue;; - - -b=*) transformbasename=`echo $1 | sed 's/-b=//'` - shift - continue;; - - *) if [ x"$src" = x ] - then - src=$1 - else - # this colon is to work around a 386BSD /bin/sh bug - : - dst=$1 - fi - shift - continue;; - esac -done - -if [ x"$src" = x ] -then - echo "install: no input file specified" - exit 1 -else - true -fi - -if [ x"$dir_arg" != x ]; then - dst=$src - src="" - - if [ -d $dst ]; then - instcmd=: - else - instcmd=mkdir - fi -else - -# Waiting for this to be detected by the "$instcmd $src $dsttmp" command -# might cause directories to be created, which would be especially bad -# if $src (and thus $dsttmp) contains '*'. - - if [ -f $src -o -d $src ] - then - true - else - echo "install: $src does not exist" - exit 1 - fi - - if [ x"$dst" = x ] - then - echo "install: no destination specified" - exit 1 - else - true - fi - -# If destination is a directory, append the input filename; if your system -# does not like double slashes in filenames, you may need to add some logic - - if [ -d $dst ] - then - dst="$dst"/`basename $src` - else - true - fi -fi - -## this sed command emulates the dirname command -dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` - -# Make sure that the destination directory exists. -# this part is taken from Noah Friedman's mkinstalldirs script - -# Skip lots of stat calls in the usual case. -if [ ! -d "$dstdir" ]; then -defaultIFS=' -' -IFS="${IFS-${defaultIFS}}" - -oIFS="${IFS}" -# Some sh's can't handle IFS=/ for some reason. -IFS='%' -set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` -IFS="${oIFS}" - -pathcomp='' - -while [ $# -ne 0 ] ; do - pathcomp="${pathcomp}${1}" - shift - - if [ ! -d "${pathcomp}" ] ; - then - $mkdirprog "${pathcomp}" - else - true - fi - - pathcomp="${pathcomp}/" -done -fi - -if [ x"$dir_arg" != x ] -then - $doit $instcmd $dst && - - if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi -else - -# If we're going to rename the final executable, determine the name now. - - if [ x"$transformarg" = x ] - then - dstfile=`basename $dst` - else - dstfile=`basename $dst $transformbasename | - sed $transformarg`$transformbasename - fi - -# don't allow the sed command to completely eliminate the filename - - if [ x"$dstfile" = x ] - then - dstfile=`basename $dst` - else - true - fi - -# Make a temp file name in the proper directory. - - dsttmp=$dstdir/#inst.$$# - -# Move or copy the file name to the temp name - - $doit $instcmd $src $dsttmp && - - trap "rm -f ${dsttmp}" 0 && - -# and set any options; do chmod last to preserve setuid bits - -# If any of these fail, we abort the whole thing. If we want to -# ignore errors from any of these, just make sure not to ignore -# errors from the above "$doit $instcmd $src $dsttmp" command. - - if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && - -# Now rename the file to the real destination. - - $doit $rmcmd -f $dstdir/$dstfile && - $doit $mvcmd $dsttmp $dstdir/$dstfile - -fi && - - -exit 0 diff --git a/source/lib/tdb/libtdb.m4 b/source/lib/tdb/libtdb.m4 deleted file mode 100644 index fefa5912c26..00000000000 --- a/source/lib/tdb/libtdb.m4 +++ /dev/null @@ -1,56 +0,0 @@ -dnl find the tdb sources. This is meant to work both for -dnl tdb standalone builds, and builds of packages using tdb -tdbdir="" -tdbpaths="$srcdir $srcdir/lib/tdb $srcdir/tdb $srcdir/../tdb" -for d in $tdbpaths; do - if test -f "$d/common/tdb.c"; then - tdbdir="$d" - AC_SUBST(tdbdir) - break; - fi -done -if test x"$tdbdir" = "x"; then - AC_MSG_ERROR([cannot find tdb source in $tdbpaths]) -fi -TDBOBJ="common/tdb.o common/dump.o common/transaction.o common/error.o common/traverse.o" -TDBOBJ="$TDBOBJ common/freelist.o common/freelistcheck.o common/io.o common/lock.o common/open.o" -AC_SUBST(TDBOBJ) -AC_SUBST(LIBREPLACEOBJ) - -AC_CHECK_FUNCS(mmap pread pwrite getpagesize utime) -AC_CHECK_HEADERS(getopt.h sys/select.h sys/time.h) - -AC_HAVE_DECL(pread, [#include <unistd.h>]) -AC_HAVE_DECL(pwrite, [#include <unistd.h>]) - -AC_MSG_CHECKING([for Python]) - -PYTHON= - -AC_ARG_WITH(python, -[ --with-python=PYTHONNAME build Python libraries], -[ case "${withval-python}" in - yes) - PYTHON=python - ;; - no) - PYTHON= - ;; - *) - PYTHON=${withval-python} - ;; - esac ]) - -if test x"$PYTHON" != "x"; then - incdir=`python -c 'import sys; print "%s/include/python%d.%d" % (sys.prefix, sys.version_info[[0]], sys.version_info[[1]])'` - CPPFLAGS="$CPPFLAGS -I $incdir" -fi - -if test x"$PYTHON" != "x"; then - AC_MSG_RESULT([${withval-python}]) -else - SMB_ENABLE(swig_tdb, NO) - AC_MSG_RESULT(no) -fi - -AC_SUBST(PYTHON) diff --git a/source/lib/tdb/swig/Tdb.py b/source/lib/tdb/swig/Tdb.py deleted file mode 100644 index aac7a90354d..00000000000 --- a/source/lib/tdb/swig/Tdb.py +++ /dev/null @@ -1,116 +0,0 @@ -"""Provide a more Pythonic and object-oriented interface to tdb.""" - -# -# Swig interface to Samba -# -# Copyright (C) Tim Potter 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. -# - -import os -from tdb import * - -# Open flags - -DEFAULT = TDB_DEFAULT -CLEAR_IF_FIRST = TDB_CLEAR_IF_FIRST -INTERNAL = TDB_INTERNAL -NOLOCK = TDB_NOLOCK -NOMMAP = TDB_NOMMAP - -# Class representing a TDB file - -class Tdb: - - # Create and destroy Tdb objects - - def __init__(self, name, hash_size = 0, flags = TDB_DEFAULT, - open_flags = os.O_RDWR | os.O_CREAT, mode = 0600): - self.tdb = tdb_open(name, hash_size, flags, open_flags, mode) - if self.tdb is None: - raise IOError, tdb_errorstr(self.tdb) - - def __del__(self): - self.close() - - def close(self): - if hasattr(self, 'tdb') and self.tdb is not None: - if tdb_close(self.tdb) == -1: - raise IOError, tdb_errorstr(self.tdb) - self.tdb = None - - # Random access to keys, values - - def __getitem__(self, key): - result = tdb_fetch(self.tdb, key) - if result is None: - raise KeyError, '%s: %s' % (key, tdb_errorstr(self.tdb)) - return result - - def __setitem__(self, key, item): - if tdb_store(self.tdb, key, item) == -1: - raise IOError, tdb_errorstr(self.tdb) - - def __delitem__(self, key): - if not tdb_exists(self.tdb, key): - raise KeyError, '%s: %s' % (key, tdb_errorstr(self.tdb)) - tdb_delete(self.tdb, key) - - def has_key(self, key): - return tdb_exists(self.tdb, key) - - # Tdb iterator - - class TdbIterator: - def __init__(self, tdb): - self.tdb = tdb - self.key = None - - def __iter__(self): - return self - - def next(self): - if self.key is None: - self.key = tdb_firstkey(self.tdb) - if self.key is None: - raise StopIteration - return self.key - else: - self.key = tdb_nextkey(self.tdb, self.key) - if self.key is None: - raise StopIteration - return self.key - - def __iter__(self): - return Tdb.TdbIterator(self.tdb) - - # Implement other dict functions using TdbIterator - - def keys(self): - return [k for k in iter(self)] - - def values(self): - return [self[k] for k in iter(self)] - - def items(self): - return [(k, self[k]) for k in iter(self)] - - def __len__(self): - return len(self.keys()) - - def clear(self): - for k in iter(self): - del(self[k]) diff --git a/source/lib/tdb/swig/tdb.i b/source/lib/tdb/swig/tdb.i deleted file mode 100644 index 98bf6441ce8..00000000000 --- a/source/lib/tdb/swig/tdb.i +++ /dev/null @@ -1,168 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Swig interface to tdb. - - Copyright (C) 2004,2005 Tim Potter <tpot@samba.org> - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -%module tdb - -%{ - -/* This symbol is used in both includes.h and Python.h which causes an - annoying compiler warning. */ - -#ifdef HAVE_FSTAT -#undef HAVE_FSTAT -#endif - -#if (__GNUC__ >= 3) -/** Use gcc attribute to check printf fns. a1 is the 1-based index of - * the parameter containing the format, and a2 the index of the first - * argument. Note that some gcc 2.x versions don't handle this - * properly **/ -#define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2))) -#else -#define PRINTF_ATTRIBUTE(a1, a2) -#endif - -/* Include tdb headers */ - -#include "lib/tdb/include/tdb.h" - -%} - -/* The tdb functions will crash if a NULL tdb context is passed */ - -%include exception.i - -%typemap(check) TDB_CONTEXT* { - if ($1 == NULL) - SWIG_exception(SWIG_ValueError, - "tdb context must be non-NULL"); -} - -/* In and out typemaps for the TDB_DATA structure. This is converted to - and from the Python string type which can contain arbitrary binary - data.. */ - -%typemap(in) TDB_DATA { - if (!PyString_Check($input)) { - PyErr_SetString(PyExc_TypeError, "string arg expected"); - return NULL; - } - $1.dsize = PyString_Size($input); - $1.dptr = PyString_AsString($input); -} - -%typemap(out) TDB_DATA { - if ($1.dptr == NULL && $1.dsize == 0) { - $result = Py_None; - } else { - $result = PyString_FromStringAndSize($1.dptr, $1.dsize); - free($1.dptr); - } -} - -/* Treat a mode_t as an unsigned integer */ - -typedef int mode_t; - -/* flags to tdb_store() */ - -#define TDB_REPLACE 1 -#define TDB_INSERT 2 -#define TDB_MODIFY 3 - -/* flags for tdb_open() */ - -#define TDB_DEFAULT 0 /* just a readability place holder */ -#define TDB_CLEAR_IF_FIRST 1 -#define TDB_INTERNAL 2 /* don't store on disk */ -#define TDB_NOLOCK 4 /* don't do any locking */ -#define TDB_NOMMAP 8 /* don't use mmap */ -#define TDB_CONVERT 16 /* convert endian (internal use) */ -#define TDB_BIGENDIAN 32 /* header is big-endian (internal use) */ - -/* Throw an IOError exception if tdb_open() or tdb_open_ex() returns NULL */ - -%exception { - $action - if (result == NULL) { - PyErr_SetFromErrno(PyExc_IOError); - SWIG_fail; - } -} - -TDB_CONTEXT *tdb_open(const char *name, int hash_size, int tdb_flags, - int open_flags, mode_t mode); - -TDB_CONTEXT *tdb_open_ex(const char *name, int hash_size, int tdb_flags, - int open_flags, mode_t mode, - tdb_log_func log_fn, - tdb_hash_func hash_fn); - -%exception; - -int tdb_reopen(TDB_CONTEXT *tdb); - -int tdb_reopen_all(int parent_longlived); - -void tdb_logging_function(TDB_CONTEXT *tdb, tdb_log_func); - -enum TDB_ERROR tdb_error(TDB_CONTEXT *tdb); - -const char *tdb_errorstr(TDB_CONTEXT *tdb); - -TDB_DATA tdb_fetch(TDB_CONTEXT *tdb, TDB_DATA key); - -int tdb_delete(TDB_CONTEXT *tdb, TDB_DATA key); - -int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag = TDB_REPLACE); - -int tdb_append(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA new_dbuf); - -int tdb_close(TDB_CONTEXT *tdb); - -TDB_DATA tdb_firstkey(TDB_CONTEXT *tdb); - -TDB_DATA tdb_nextkey(TDB_CONTEXT *tdb, TDB_DATA key); - -int tdb_traverse(TDB_CONTEXT *tdb, tdb_traverse_func fn, void *state); - -int tdb_exists(TDB_CONTEXT *tdb, TDB_DATA key); - -int tdb_lockall(TDB_CONTEXT *tdb); - -void tdb_unlockall(TDB_CONTEXT *tdb); - -/* Low level locking functions: use with care */ - -int tdb_chainlock(TDB_CONTEXT *tdb, TDB_DATA key); - -int tdb_chainunlock(TDB_CONTEXT *tdb, TDB_DATA key); - -/* Debug functions. Not used in production. */ - -void tdb_dump_all(TDB_CONTEXT *tdb); - -int tdb_printfreelist(TDB_CONTEXT *tdb); diff --git a/source/lib/tdb/tdb.pc.in b/source/lib/tdb/tdb.pc.in deleted file mode 100644 index 8180d471850..00000000000 --- a/source/lib/tdb/tdb.pc.in +++ /dev/null @@ -1,10 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: tdb -Description: A trivial database -Version: 4.0 -Libs: -L${libdir} -ltdb -Cflags: -I${includedir} diff --git a/source/lib/tdb/tools/tdbbackup.c b/source/lib/tdb/tools/tdbbackup.c deleted file mode 100644 index 2e728d46aa1..00000000000 --- a/source/lib/tdb/tools/tdbbackup.c +++ /dev/null @@ -1,301 +0,0 @@ -/* - Unix SMB/CIFS implementation. - low level tdb backup and restore utility - Copyright (C) Andrew Tridgell 2002 - - 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. -*/ - -/* - - This program is meant for backup/restore of tdb databases. Typical usage would be: - tdbbackup *.tdb - when Samba shuts down cleanly, which will make a backup of all the local databases - to *.bak files. Then on Samba startup you would use: - tdbbackup -v *.tdb - and this will check the databases for corruption and if corruption is detected then - the backup will be restored. - - You may also like to do a backup on a regular basis while Samba is - running, perhaps using cron. - - The reason this program is needed is to cope with power failures - while Samba is running. A power failure could lead to database - corruption and Samba will then not start correctly. - - Note that many of the databases in Samba are transient and thus - don't need to be backed up, so you can optimise the above a little - by only running the backup on the critical databases. - - */ - -#include "replace.h" -#include "system/locale.h" -#include "system/time.h" -#include "system/filesys.h" -#include "tdb.h" - -#ifdef HAVE_GETOPT_H -#include <getopt.h> -#endif - -static int failed; - -static char *add_suffix(const char *name, const char *suffix) -{ - char *ret; - int len = strlen(name) + strlen(suffix) + 1; - ret = (char *)malloc(len); - if (!ret) { - fprintf(stderr,"Out of memory!\n"); - exit(1); - } - snprintf(ret, len, "%s%s", name, suffix); - return ret; -} - -static int copy_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state) -{ - TDB_CONTEXT *tdb_new = (TDB_CONTEXT *)state; - - if (tdb_store(tdb_new, key, dbuf, TDB_INSERT) != 0) { - fprintf(stderr,"Failed to insert into %s\n", tdb_name(tdb)); - failed = 1; - return 1; - } - return 0; -} - - -static int test_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state) -{ - return 0; -} - -/* - carefully backup a tdb, validating the contents and - only doing the backup if its OK - this function is also used for restore -*/ -static int backup_tdb(const char *old_name, const char *new_name, int hash_size) -{ - TDB_CONTEXT *tdb; - TDB_CONTEXT *tdb_new; - char *tmp_name; - struct stat st; - int count1, count2; - - tmp_name = add_suffix(new_name, ".tmp"); - - /* stat the old tdb to find its permissions */ - if (stat(old_name, &st) != 0) { - perror(old_name); - free(tmp_name); - return 1; - } - - /* open the old tdb */ - tdb = tdb_open(old_name, 0, 0, O_RDWR, 0); - if (!tdb) { - printf("Failed to open %s\n", old_name); - free(tmp_name); - return 1; - } - - /* create the new tdb */ - unlink(tmp_name); - tdb_new = tdb_open(tmp_name, - hash_size ? hash_size : tdb_hash_size(tdb), - TDB_DEFAULT, O_RDWR|O_CREAT|O_EXCL, - st.st_mode & 0777); - if (!tdb_new) { - perror(tmp_name); - free(tmp_name); - return 1; - } - - /* lock the old tdb */ - if (tdb_lockall(tdb) != 0) { - fprintf(stderr,"Failed to lock %s\n", old_name); - tdb_close(tdb); - tdb_close(tdb_new); - unlink(tmp_name); - free(tmp_name); - return 1; - } - - failed = 0; - - /* traverse and copy */ - count1 = tdb_traverse(tdb, copy_fn, (void *)tdb_new); - if (count1 < 0 || failed) { - fprintf(stderr,"failed to copy %s\n", old_name); - tdb_close(tdb); - tdb_close(tdb_new); - unlink(tmp_name); - free(tmp_name); - return 1; - } - - /* close the old tdb */ - tdb_close(tdb); - - /* close the new tdb and re-open read-only */ - tdb_close(tdb_new); - tdb_new = tdb_open(tmp_name, 0, TDB_DEFAULT, O_RDONLY, 0); - if (!tdb_new) { - fprintf(stderr,"failed to reopen %s\n", tmp_name); - unlink(tmp_name); - perror(tmp_name); - free(tmp_name); - return 1; - } - - /* traverse the new tdb to confirm */ - count2 = tdb_traverse(tdb_new, test_fn, 0); - if (count2 != count1) { - fprintf(stderr,"failed to copy %s\n", old_name); - tdb_close(tdb_new); - unlink(tmp_name); - free(tmp_name); - return 1; - } - - /* make sure the new tdb has reached stable storage */ - fsync(tdb_fd(tdb_new)); - - /* close the new tdb and rename it to .bak */ - tdb_close(tdb_new); - unlink(new_name); - if (rename(tmp_name, new_name) != 0) { - perror(new_name); - free(tmp_name); - return 1; - } - - free(tmp_name); - - return 0; -} - -/* - verify a tdb and if it is corrupt then restore from *.bak -*/ -static int verify_tdb(const char *fname, const char *bak_name) -{ - TDB_CONTEXT *tdb; - int count = -1; - - /* open the tdb */ - tdb = tdb_open(fname, 0, 0, O_RDONLY, 0); - - /* traverse the tdb, then close it */ - if (tdb) { - count = tdb_traverse(tdb, test_fn, NULL); - tdb_close(tdb); - } - - /* count is < 0 means an error */ - if (count < 0) { - printf("restoring %s\n", fname); - return backup_tdb(bak_name, fname, 0); - } - - printf("%s : %d records\n", fname, count); - - return 0; -} - -/* - see if one file is newer than another -*/ -static int file_newer(const char *fname1, const char *fname2) -{ - struct stat st1, st2; - if (stat(fname1, &st1) != 0) { - return 0; - } - if (stat(fname2, &st2) != 0) { - return 1; - } - return (st1.st_mtime > st2.st_mtime); -} - -static void usage(void) -{ - printf("Usage: tdbbackup [options] <fname...>\n\n"); - printf(" -h this help message\n"); - printf(" -s suffix set the backup suffix\n"); - printf(" -v verify mode (restore if corrupt)\n"); - printf(" -n hashsize set the new hash size for the backup\n"); -} - - - int main(int argc, char *argv[]) -{ - int i; - int ret = 0; - int c; - int verify = 0; - int hashsize = 0; - const char *suffix = ".bak"; - - while ((c = getopt(argc, argv, "vhs:n:")) != -1) { - switch (c) { - case 'h': - usage(); - exit(0); - case 'v': - verify = 1; - break; - case 's': - suffix = optarg; - break; - case 'n': - hashsize = atoi(optarg); - break; - } - } - - argc -= optind; - argv += optind; - - if (argc < 1) { - usage(); - exit(1); - } - - for (i=0; i<argc; i++) { - const char *fname = argv[i]; - char *bak_name; - - bak_name = add_suffix(fname, suffix); - - if (verify) { - if (verify_tdb(fname, bak_name) != 0) { - ret = 1; - } - } else { - if (file_newer(fname, bak_name) && - backup_tdb(fname, bak_name, hashsize) != 0) { - ret = 1; - } - } - - free(bak_name); - } - - return ret; -} diff --git a/source/lib/tdb/tools/tdbdump.c b/source/lib/tdb/tools/tdbdump.c deleted file mode 100644 index 4ceef2d60c1..00000000000 --- a/source/lib/tdb/tools/tdbdump.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - Unix SMB/CIFS implementation. - simple tdb dump util - Copyright (C) Andrew Tridgell 2001 - - 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. -*/ - -#include "replace.h" -#include "system/locale.h" -#include "system/time.h" -#include "system/filesys.h" -#include "tdb.h" - -static void print_data(TDB_DATA d) -{ - unsigned char *p = (unsigned char *)d.dptr; - int len = d.dsize; - while (len--) { - if (isprint(*p) && !strchr("\"\\", *p)) { - fputc(*p, stdout); - } else { - printf("\\%02X", *p); - } - p++; - } -} - -static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state) -{ - printf("{\n"); - printf("key(%d) = \"", (int)key.dsize); - print_data(key); - printf("\"\n"); - printf("data(%d) = \"", (int)dbuf.dsize); - print_data(dbuf); - printf("\"\n"); - printf("}\n"); - return 0; -} - -static int dump_tdb(const char *fname, const char *keyname) -{ - TDB_CONTEXT *tdb; - TDB_DATA key, value; - - tdb = tdb_open(fname, 0, 0, O_RDONLY, 0); - if (!tdb) { - printf("Failed to open %s\n", fname); - return 1; - } - - if (!keyname) { - tdb_traverse(tdb, traverse_fn, NULL); - } else { - key.dptr = discard_const_p(uint8_t,keyname); - key.dsize = strlen( keyname); - value = tdb_fetch(tdb, key); - if (!value.dptr) { - return 1; - } else { - print_data(value); - free(value.dptr); - } - } - - return 0; -} - -static void usage( void) -{ - printf( "Usage: tdbdump [options] <filename>\n\n"); - printf( " -h this help message\n"); - printf( " -k keyname dumps value of keyname\n"); -} - - int main(int argc, char *argv[]) -{ - char *fname, *keyname=NULL; - int c; - - if (argc < 2) { - printf("Usage: tdbdump <fname>\n"); - exit(1); - } - - while ((c = getopt( argc, argv, "hk:")) != -1) { - switch (c) { - case 'h': - usage(); - exit( 0); - case 'k': - keyname = optarg; - break; - default: - usage(); - exit( 1); - } - } - - fname = argv[optind]; - - return dump_tdb(fname, keyname); -} diff --git a/source/lib/tdb/tools/tdbtest.c b/source/lib/tdb/tools/tdbtest.c deleted file mode 100644 index 1564a42bc41..00000000000 --- a/source/lib/tdb/tools/tdbtest.c +++ /dev/null @@ -1,265 +0,0 @@ -/* a test program for tdb - the trivial database */ - -#include "replace.h" -#include "tdb.h" -#include "system/filesys.h" -#include "system/time.h" - -#include <gdbm.h> - - -#define DELETE_PROB 7 -#define STORE_PROB 5 - -static struct tdb_context *db; -static GDBM_FILE gdbm; - -struct timeval tp1,tp2; - -static void _start_timer(void) -{ - gettimeofday(&tp1,NULL); -} - -static double _end_timer(void) -{ - gettimeofday(&tp2,NULL); - return((tp2.tv_sec - tp1.tv_sec) + - (tp2.tv_usec - tp1.tv_usec)*1.0e-6); -} - -static void fatal(const char *why) -{ - perror(why); - exit(1); -} - -#ifdef PRINTF_ATTRIBUTE -static void tdb_log(struct tdb_context *tdb, int level, const char *format, ...) PRINTF_ATTRIBUTE(3,4); -#endif -static void tdb_log(struct tdb_context *tdb, int level, const char *format, ...) -{ - va_list ap; - - va_start(ap, format); - vfprintf(stdout, format, ap); - va_end(ap); - fflush(stdout); -} - -static void compare_db(void) -{ - TDB_DATA d, key, nextkey; - datum gd, gkey, gnextkey; - - key = tdb_firstkey(db); - while (key.dptr) { - d = tdb_fetch(db, key); - gkey.dptr = key.dptr; - gkey.dsize = key.dsize; - - gd = gdbm_fetch(gdbm, gkey); - - if (!gd.dptr) fatal("key not in gdbm"); - if (gd.dsize != d.dsize) fatal("data sizes differ"); - if (memcmp(gd.dptr, d.dptr, d.dsize)) { - fatal("data differs"); - } - - nextkey = tdb_nextkey(db, key); - free(key.dptr); - free(d.dptr); - free(gd.dptr); - key = nextkey; - } - - gkey = gdbm_firstkey(gdbm); - while (gkey.dptr) { - gd = gdbm_fetch(gdbm, gkey); - key.dptr = gkey.dptr; - key.dsize = gkey.dsize; - - d = tdb_fetch(db, key); - - if (!d.dptr) fatal("key not in db"); - if (d.dsize != gd.dsize) fatal("data sizes differ"); - if (memcmp(d.dptr, gd.dptr, gd.dsize)) { - fatal("data differs"); - } - - gnextkey = gdbm_nextkey(gdbm, gkey); - free(gkey.dptr); - free(gd.dptr); - free(d.dptr); - gkey = gnextkey; - } -} - -static char *randbuf(int len) -{ - char *buf; - int i; - buf = (char *)malloc(len+1); - - for (i=0;i<len;i++) { - buf[i] = 'a' + (rand() % 26); - } - buf[i] = 0; - return buf; -} - -static void addrec_db(void) -{ - int klen, dlen; - char *k, *d; - TDB_DATA key, data; - - klen = 1 + (rand() % 4); - dlen = 1 + (rand() % 100); - - k = randbuf(klen); - d = randbuf(dlen); - - key.dptr = k; - key.dsize = klen+1; - - data.dptr = d; - data.dsize = dlen+1; - - if (rand() % DELETE_PROB == 0) { - tdb_delete(db, key); - } else if (rand() % STORE_PROB == 0) { - if (tdb_store(db, key, data, TDB_REPLACE) != 0) { - fatal("tdb_store failed"); - } - } else { - data = tdb_fetch(db, key); - if (data.dptr) free(data.dptr); - } - - free(k); - free(d); -} - -static void addrec_gdbm(void) -{ - int klen, dlen; - char *k, *d; - datum key, data; - - klen = 1 + (rand() % 4); - dlen = 1 + (rand() % 100); - - k = randbuf(klen); - d = randbuf(dlen); - - key.dptr = k; - key.dsize = klen+1; - - data.dptr = d; - data.dsize = dlen+1; - - if (rand() % DELETE_PROB == 0) { - gdbm_delete(gdbm, key); - } else if (rand() % STORE_PROB == 0) { - if (gdbm_store(gdbm, key, data, GDBM_REPLACE) != 0) { - fatal("gdbm_store failed"); - } - } else { - data = gdbm_fetch(gdbm, key); - if (data.dptr) free(data.dptr); - } - - free(k); - free(d); -} - -static int traverse_fn(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf, void *state) -{ -#if 0 - printf("[%s] [%s]\n", key.dptr, dbuf.dptr); -#endif - tdb_delete(tdb, key); - return 0; -} - -static void merge_test(void) -{ - int i; - char keys[5][2]; - char tdata[] = "test"; - TDB_DATA key, data; - - for (i = 0; i < 5; i++) { - snprintf(keys[i],2, "%d", i); - key.dptr = keys[i]; - key.dsize = 2; - - data.dptr = tdata; - data.dsize = 4; - - if (tdb_store(db, key, data, TDB_REPLACE) != 0) { - fatal("tdb_store failed"); - } - } - - key.dptr = keys[0]; - tdb_delete(db, key); - key.dptr = keys[4]; - tdb_delete(db, key); - key.dptr = keys[2]; - tdb_delete(db, key); - key.dptr = keys[1]; - tdb_delete(db, key); - key.dptr = keys[3]; - tdb_delete(db, key); -} - - int main(int argc, const char *argv[]) -{ - int i, seed=0; - int loops = 10000; - int num_entries; - char test_gdbm[] = "test.gdbm"; - - unlink("test.gdbm"); - - db = tdb_open("test.tdb", 0, TDB_CLEAR_IF_FIRST, - O_RDWR | O_CREAT | O_TRUNC, 0600); - gdbm = gdbm_open(test_gdbm, 512, GDBM_WRITER|GDBM_NEWDB|GDBM_FAST, - 0600, NULL); - - if (!db || !gdbm) { - fatal("db open failed"); - } - -#if 1 - srand(seed); - _start_timer(); - for (i=0;i<loops;i++) addrec_gdbm(); - printf("gdbm got %.2f ops/sec\n", i/_end_timer()); -#endif - - merge_test(); - - srand(seed); - _start_timer(); - for (i=0;i<loops;i++) addrec_db(); - printf("tdb got %.2f ops/sec\n", i/_end_timer()); - - if (tdb_validate_freelist(db, &num_entries) == -1) { - printf("tdb freelist is corrupt\n"); - } else { - printf("tdb freelist is good (%d entries)\n", num_entries); - } - - compare_db(); - - printf("traversed %d records\n", tdb_traverse(db, traverse_fn, NULL)); - printf("traversed %d records\n", tdb_traverse(db, traverse_fn, NULL)); - - tdb_close(db); - gdbm_close(gdbm); - - return 0; -} diff --git a/source/lib/tdb/tools/tdbtool.c b/source/lib/tdb/tools/tdbtool.c deleted file mode 100644 index e90acd18f0a..00000000000 --- a/source/lib/tdb/tools/tdbtool.c +++ /dev/null @@ -1,659 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Samba database functions - Copyright (C) Andrew Tridgell 1999-2000 - Copyright (C) Paul `Rusty' Russell 2000 - Copyright (C) Jeremy Allison 2000 - Copyright (C) Andrew Esh 2001 - - 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. -*/ - -#include "replace.h" -#include "system/locale.h" -#include "system/time.h" -#include "system/filesys.h" -#include "tdb.h" - -static int do_command(void); -const char *cmdname; -char *arg1, *arg2; -size_t arg1len, arg2len; -int bIterate = 0; -char *line; -TDB_DATA iterate_kbuf; -char cmdline[1024]; -static int disable_mmap; - -enum commands { - CMD_CREATE_TDB, - CMD_OPEN_TDB, - CMD_ERASE, - CMD_DUMP, - CMD_INSERT, - CMD_MOVE, - CMD_STORE, - CMD_SHOW, - CMD_KEYS, - CMD_HEXKEYS, - CMD_DELETE, - CMD_LIST_HASH_FREE, - CMD_LIST_FREE, - CMD_INFO, - CMD_MMAP, - CMD_SPEED, - CMD_FIRST, - CMD_NEXT, - CMD_SYSTEM, - CMD_QUIT, - CMD_HELP -}; - -typedef struct { - const char *name; - enum commands cmd; -} COMMAND_TABLE; - -COMMAND_TABLE cmd_table[] = { - {"create", CMD_CREATE_TDB}, - {"open", CMD_OPEN_TDB}, - {"erase", CMD_ERASE}, - {"dump", CMD_DUMP}, - {"insert", CMD_INSERT}, - {"move", CMD_MOVE}, - {"store", CMD_STORE}, - {"show", CMD_SHOW}, - {"keys", CMD_KEYS}, - {"hexkeys", CMD_HEXKEYS}, - {"delete", CMD_DELETE}, - {"list", CMD_LIST_HASH_FREE}, - {"free", CMD_LIST_FREE}, - {"info", CMD_INFO}, - {"speed", CMD_SPEED}, - {"mmap", CMD_MMAP}, - {"first", CMD_FIRST}, - {"1", CMD_FIRST}, - {"next", CMD_NEXT}, - {"n", CMD_NEXT}, - {"quit", CMD_QUIT}, - {"q", CMD_QUIT}, - {"!", CMD_SYSTEM}, - {NULL, CMD_HELP} -}; - -struct timeval tp1,tp2; - -static void _start_timer(void) -{ - gettimeofday(&tp1,NULL); -} - -static double _end_timer(void) -{ - gettimeofday(&tp2,NULL); - return((tp2.tv_sec - tp1.tv_sec) + - (tp2.tv_usec - tp1.tv_usec)*1.0e-6); -} - -/* a tdb tool for manipulating a tdb database */ - -static TDB_CONTEXT *tdb; - -static int print_rec(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state); -static int print_key(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state); -static int print_hexkey(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state); - -static void print_asc(const char *buf,int len) -{ - int i; - - /* We're probably printing ASCII strings so don't try to display - the trailing NULL character. */ - - if (buf[len - 1] == 0) - len--; - - for (i=0;i<len;i++) - printf("%c",isprint(buf[i])?buf[i]:'.'); -} - -static void print_data(const char *buf,int len) -{ - int i=0; - if (len<=0) return; - printf("[%03X] ",i); - for (i=0;i<len;) { - printf("%02X ",(int)buf[i]); - i++; - if (i%8 == 0) printf(" "); - if (i%16 == 0) { - print_asc(&buf[i-16],8); printf(" "); - print_asc(&buf[i-8],8); printf("\n"); - if (i<len) printf("[%03X] ",i); - } - } - if (i%16) { - int n; - - n = 16 - (i%16); - printf(" "); - if (n>8) printf(" "); - while (n--) printf(" "); - - n = i%16; - if (n > 8) n = 8; - print_asc(&buf[i-(i%16)],n); printf(" "); - n = (i%16) - n; - if (n>0) print_asc(&buf[i-n],n); - printf("\n"); - } -} - -static void help(void) -{ - printf("\n" -"tdbtool: \n" -" create dbname : create a database\n" -" open dbname : open an existing database\n" -" erase : erase the database\n" -" dump : dump the database as strings\n" -" keys : dump the database keys as strings\n" -" hexkeys : dump the database keys as hex values\n" -" info : print summary info about the database\n" -" insert key data : insert a record\n" -" move key file : move a record to a destination tdb\n" -" store key data : store a record (replace)\n" -" show key : show a record by key\n" -" delete key : delete a record by key\n" -" list : print the database hash table and freelist\n" -" free : print the database freelist\n" -" ! command : execute system command\n" -" 1 | first : print the first record\n" -" n | next : print the next record\n" -" q | quit : terminate\n" -" \\n : repeat 'next' command\n" -"\n"); -} - -static void terror(const char *why) -{ - printf("%s\n", why); -} - -static void create_tdb(const char *tdbname) -{ - if (tdb) tdb_close(tdb); - tdb = tdb_open(tdbname, 0, TDB_CLEAR_IF_FIRST | (disable_mmap?TDB_NOMMAP:0), - O_RDWR | O_CREAT | O_TRUNC, 0600); - if (!tdb) { - printf("Could not create %s: %s\n", tdbname, strerror(errno)); - } -} - -static void open_tdb(const char *tdbname) -{ - if (tdb) tdb_close(tdb); - tdb = tdb_open(tdbname, 0, disable_mmap?TDB_NOMMAP:0, O_RDWR, 0600); - if (!tdb) { - printf("Could not open %s: %s\n", tdbname, strerror(errno)); - } -} - -static void insert_tdb(char *keyname, size_t keylen, char* data, size_t datalen) -{ - TDB_DATA key, dbuf; - - if ((keyname == NULL) || (keylen == 0)) { - terror("need key"); - return; - } - - key.dptr = (unsigned char *)keyname; - key.dsize = keylen; - dbuf.dptr = (unsigned char *)data; - dbuf.dsize = datalen; - - if (tdb_store(tdb, key, dbuf, TDB_INSERT) == -1) { - terror("insert failed"); - } -} - -static void store_tdb(char *keyname, size_t keylen, char* data, size_t datalen) -{ - TDB_DATA key, dbuf; - - if ((keyname == NULL) || (keylen == 0)) { - terror("need key"); - return; - } - - if ((data == NULL) || (datalen == 0)) { - terror("need data"); - return; - } - - key.dptr = (unsigned char *)keyname; - key.dsize = keylen; - dbuf.dptr = (unsigned char *)data; - dbuf.dsize = datalen; - - printf("Storing key:\n"); - print_rec(tdb, key, dbuf, NULL); - - if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1) { - terror("store failed"); - } -} - -static void show_tdb(char *keyname, size_t keylen) -{ - TDB_DATA key, dbuf; - - if ((keyname == NULL) || (keylen == 0)) { - terror("need key"); - return; - } - - key.dptr = (unsigned char *)keyname; - key.dsize = keylen; - - dbuf = tdb_fetch(tdb, key); - if (!dbuf.dptr) { - terror("fetch failed"); - return; - } - - print_rec(tdb, key, dbuf, NULL); - - free( dbuf.dptr ); - - return; -} - -static void delete_tdb(char *keyname, size_t keylen) -{ - TDB_DATA key; - - if ((keyname == NULL) || (keylen == 0)) { - terror("need key"); - return; - } - - key.dptr = (unsigned char *)keyname; - key.dsize = keylen; - - if (tdb_delete(tdb, key) != 0) { - terror("delete failed"); - } -} - -static void move_rec(char *keyname, size_t keylen, char* tdbname) -{ - TDB_DATA key, dbuf; - TDB_CONTEXT *dst_tdb; - - if ((keyname == NULL) || (keylen == 0)) { - terror("need key"); - return; - } - - if ( !tdbname ) { - terror("need destination tdb name"); - return; - } - - key.dptr = (unsigned char *)keyname; - key.dsize = keylen; - - dbuf = tdb_fetch(tdb, key); - if (!dbuf.dptr) { - terror("fetch failed"); - return; - } - - print_rec(tdb, key, dbuf, NULL); - - dst_tdb = tdb_open(tdbname, 0, 0, O_RDWR, 0600); - if ( !dst_tdb ) { - terror("unable to open destination tdb"); - return; - } - - if ( tdb_store( dst_tdb, key, dbuf, TDB_REPLACE ) == -1 ) { - terror("failed to move record"); - } - else - printf("record moved\n"); - - tdb_close( dst_tdb ); - - return; -} - -static int print_rec(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state) -{ - printf("\nkey %d bytes\n", (int)key.dsize); - print_asc((const char *)key.dptr, key.dsize); - printf("\ndata %d bytes\n", (int)dbuf.dsize); - print_data((const char *)dbuf.dptr, dbuf.dsize); - return 0; -} - -static int print_key(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state) -{ - printf("key %d bytes: ", (int)key.dsize); - print_asc((const char *)key.dptr, key.dsize); - printf("\n"); - return 0; -} - -static int print_hexkey(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state) -{ - printf("key %d bytes\n", (int)key.dsize); - print_data((const char *)key.dptr, key.dsize); - printf("\n"); - return 0; -} - -static int total_bytes; - -static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state) -{ - total_bytes += dbuf.dsize; - return 0; -} - -static void info_tdb(void) -{ - int count; - total_bytes = 0; - if ((count = tdb_traverse(tdb, traverse_fn, NULL)) == -1) - printf("Error = %s\n", tdb_errorstr(tdb)); - else - printf("%d records totalling %d bytes\n", count, total_bytes); -} - -static void speed_tdb(const char *tlimit) -{ - unsigned timelimit = tlimit?atoi(tlimit):0; - double t; - int ops=0; - if (timelimit == 0) timelimit = 10; - printf("Testing traverse speed for %u seconds\n", timelimit); - _start_timer(); - while ((t=_end_timer()) < timelimit) { - tdb_traverse(tdb, traverse_fn, NULL); - printf("%10.3f ops/sec\r", (++ops)/t); - } - printf("\n"); -} - -static void toggle_mmap(void) -{ - disable_mmap = !disable_mmap; - if (disable_mmap) { - printf("mmap is disabled\n"); - } else { - printf("mmap is enabled\n"); - } -} - -static char *tdb_getline(const char *prompt) -{ - static char thisline[1024]; - char *p; - fputs(prompt, stdout); - thisline[0] = 0; - p = fgets(thisline, sizeof(thisline)-1, stdin); - if (p) p = strchr(p, '\n'); - if (p) *p = 0; - return p?thisline:NULL; -} - -static int do_delete_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, - void *state) -{ - return tdb_delete(the_tdb, key); -} - -static void first_record(TDB_CONTEXT *the_tdb, TDB_DATA *pkey) -{ - TDB_DATA dbuf; - *pkey = tdb_firstkey(the_tdb); - - dbuf = tdb_fetch(the_tdb, *pkey); - if (!dbuf.dptr) terror("fetch failed"); - else { - print_rec(the_tdb, *pkey, dbuf, NULL); - } -} - -static void next_record(TDB_CONTEXT *the_tdb, TDB_DATA *pkey) -{ - TDB_DATA dbuf; - *pkey = tdb_nextkey(the_tdb, *pkey); - - dbuf = tdb_fetch(the_tdb, *pkey); - if (!dbuf.dptr) - terror("fetch failed"); - else - print_rec(the_tdb, *pkey, dbuf, NULL); -} - -static int do_command(void) -{ - COMMAND_TABLE *ctp = cmd_table; - enum commands mycmd = CMD_HELP; - int cmd_len; - - if (cmdname && strlen(cmdname) == 0) { - mycmd = CMD_NEXT; - } else { - while (ctp->name) { - cmd_len = strlen(ctp->name); - if (strncmp(ctp->name,cmdname,cmd_len) == 0) { - mycmd = ctp->cmd; - break; - } - ctp++; - } - } - - switch (mycmd) { - case CMD_CREATE_TDB: - bIterate = 0; - create_tdb(arg1); - return 0; - case CMD_OPEN_TDB: - bIterate = 0; - open_tdb(arg1); - return 0; - case CMD_SYSTEM: - /* Shell command */ - system(arg1); - return 0; - case CMD_QUIT: - return 1; - default: - /* all the rest require a open database */ - if (!tdb) { - bIterate = 0; - terror("database not open"); - help(); - return 0; - } - switch (mycmd) { - case CMD_ERASE: - bIterate = 0; - tdb_traverse(tdb, do_delete_fn, NULL); - return 0; - case CMD_DUMP: - bIterate = 0; - tdb_traverse(tdb, print_rec, NULL); - return 0; - case CMD_INSERT: - bIterate = 0; - insert_tdb(arg1, arg1len,arg2,arg2len); - return 0; - case CMD_MOVE: - bIterate = 0; - move_rec(arg1,arg1len,arg2); - return 0; - case CMD_STORE: - bIterate = 0; - store_tdb(arg1,arg1len,arg2,arg2len); - return 0; - case CMD_SHOW: - bIterate = 0; - show_tdb(arg1, arg1len); - return 0; - case CMD_KEYS: - tdb_traverse(tdb, print_key, NULL); - return 0; - case CMD_HEXKEYS: - tdb_traverse(tdb, print_hexkey, NULL); - return 0; - case CMD_DELETE: - bIterate = 0; - delete_tdb(arg1,arg1len); - return 0; - case CMD_LIST_HASH_FREE: - tdb_dump_all(tdb); - return 0; - case CMD_LIST_FREE: - tdb_printfreelist(tdb); - return 0; - case CMD_INFO: - info_tdb(); - return 0; - case CMD_SPEED: - speed_tdb(arg1); - return 0; - case CMD_MMAP: - toggle_mmap(); - return 0; - case CMD_FIRST: - bIterate = 1; - first_record(tdb, &iterate_kbuf); - return 0; - case CMD_NEXT: - if (bIterate) - next_record(tdb, &iterate_kbuf); - return 0; - case CMD_HELP: - help(); - return 0; - case CMD_CREATE_TDB: - case CMD_OPEN_TDB: - case CMD_SYSTEM: - case CMD_QUIT: - /* - * unhandled commands. cases included here to avoid compiler - * warnings. - */ - return 0; - } - } - - return 0; -} - -static char *convert_string(char *instring, size_t *sizep) -{ - size_t length = 0; - char *outp, *inp; - char temp[3]; - - - outp = inp = instring; - - while (*inp) { - if (*inp == '\\') { - inp++; - if (*inp && strchr("0123456789abcdefABCDEF",(int)*inp)) { - temp[0] = *inp++; - temp[1] = '\0'; - if (*inp && strchr("0123456789abcdefABCDEF",(int)*inp)) { - temp[1] = *inp++; - temp[2] = '\0'; - } - *outp++ = (char)strtol((const char *)temp,NULL,16); - } else { - *outp++ = *inp++; - } - } else { - *outp++ = *inp++; - } - length++; - } - *sizep = length; - return instring; -} - -int main(int argc, char *argv[]) -{ - cmdname = ""; - arg1 = NULL; - arg1len = 0; - arg2 = NULL; - arg2len = 0; - - if (argv[1]) { - cmdname = "open"; - arg1 = argv[1]; - do_command(); - cmdname = ""; - arg1 = NULL; - } - - switch (argc) { - case 1: - case 2: - /* Interactive mode */ - while ((cmdname = tdb_getline("tdb> "))) { - arg2 = arg1 = NULL; - if ((arg1 = strchr((const char *)cmdname,' ')) != NULL) { - arg1++; - arg2 = arg1; - while (*arg2) { - if (*arg2 == ' ') { - *arg2++ = '\0'; - break; - } - if ((*arg2++ == '\\') && (*arg2 == ' ')) { - arg2++; - } - } - } - if (arg1) arg1 = convert_string(arg1,&arg1len); - if (arg2) arg2 = convert_string(arg2,&arg2len); - if (do_command()) break; - } - break; - case 5: - arg2 = convert_string(argv[4],&arg2len); - case 4: - arg1 = convert_string(argv[3],&arg1len); - case 3: - cmdname = argv[2]; - default: - do_command(); - break; - } - - if (tdb) tdb_close(tdb); - - return 0; -} diff --git a/source/lib/tdb/tools/tdbtorture.c b/source/lib/tdb/tools/tdbtorture.c deleted file mode 100644 index 14a2b48cdc7..00000000000 --- a/source/lib/tdb/tools/tdbtorture.c +++ /dev/null @@ -1,318 +0,0 @@ -/* this tests tdb by doing lots of ops from several simultaneous - writers - that stresses the locking code. -*/ - -#include "replace.h" -#include "tdb.h" -#include "system/time.h" -#include "system/wait.h" -#include "system/filesys.h" - -#ifdef HAVE_GETOPT_H -#include <getopt.h> -#endif - - -#define REOPEN_PROB 30 -#define DELETE_PROB 8 -#define STORE_PROB 4 -#define APPEND_PROB 6 -#define TRANSACTION_PROB 10 -#define LOCKSTORE_PROB 5 -#define TRAVERSE_PROB 20 -#define TRAVERSE_READ_PROB 20 -#define CULL_PROB 100 -#define KEYLEN 3 -#define DATALEN 100 - -static struct tdb_context *db; -static int in_transaction; -static int error_count; - -#ifdef PRINTF_ATTRIBUTE -static void tdb_log(struct tdb_context *tdb, enum tdb_debug_level level, const char *format, ...) PRINTF_ATTRIBUTE(3,4); -#endif -static void tdb_log(struct tdb_context *tdb, enum tdb_debug_level level, const char *format, ...) -{ - va_list ap; - - error_count++; - - va_start(ap, format); - vfprintf(stdout, format, ap); - va_end(ap); - fflush(stdout); -#if 0 - { - char *ptr; - asprintf(&ptr,"xterm -e gdb /proc/%d/exe %d", getpid(), getpid()); - system(ptr); - free(ptr); - } -#endif -} - -static void fatal(const char *why) -{ - perror(why); - error_count++; -} - -static char *randbuf(int len) -{ - char *buf; - int i; - buf = (char *)malloc(len+1); - - for (i=0;i<len;i++) { - buf[i] = 'a' + (rand() % 26); - } - buf[i] = 0; - return buf; -} - -static int cull_traverse(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf, - void *state) -{ -#if CULL_PROB - if (random() % CULL_PROB == 0) { - tdb_delete(tdb, key); - } -#endif - return 0; -} - -static void addrec_db(void) -{ - int klen, dlen; - char *k, *d; - TDB_DATA key, data; - - klen = 1 + (rand() % KEYLEN); - dlen = 1 + (rand() % DATALEN); - - k = randbuf(klen); - d = randbuf(dlen); - - key.dptr = (unsigned char *)k; - key.dsize = klen+1; - - data.dptr = (unsigned char *)d; - data.dsize = dlen+1; - -#if TRANSACTION_PROB - if (in_transaction == 0 && random() % TRANSACTION_PROB == 0) { - if (tdb_transaction_start(db) != 0) { - fatal("tdb_transaction_start failed"); - } - in_transaction++; - goto next; - } - if (in_transaction && random() % TRANSACTION_PROB == 0) { - if (tdb_transaction_commit(db) != 0) { - fatal("tdb_transaction_commit failed"); - } - in_transaction--; - goto next; - } - if (in_transaction && random() % TRANSACTION_PROB == 0) { - if (tdb_transaction_cancel(db) != 0) { - fatal("tdb_transaction_cancel failed"); - } - in_transaction--; - goto next; - } -#endif - -#if REOPEN_PROB - if (in_transaction == 0 && random() % REOPEN_PROB == 0) { - tdb_reopen_all(0); - goto next; - } -#endif - -#if DELETE_PROB - if (random() % DELETE_PROB == 0) { - tdb_delete(db, key); - goto next; - } -#endif - -#if STORE_PROB - if (random() % STORE_PROB == 0) { - if (tdb_store(db, key, data, TDB_REPLACE) != 0) { - fatal("tdb_store failed"); - } - goto next; - } -#endif - -#if APPEND_PROB - if (random() % APPEND_PROB == 0) { - if (tdb_append(db, key, data) != 0) { - fatal("tdb_append failed"); - } - goto next; - } -#endif - -#if LOCKSTORE_PROB - if (random() % LOCKSTORE_PROB == 0) { - tdb_chainlock(db, key); - data = tdb_fetch(db, key); - if (tdb_store(db, key, data, TDB_REPLACE) != 0) { - fatal("tdb_store failed"); - } - if (data.dptr) free(data.dptr); - tdb_chainunlock(db, key); - goto next; - } -#endif - -#if TRAVERSE_PROB - if (random() % TRAVERSE_PROB == 0) { - tdb_traverse(db, cull_traverse, NULL); - goto next; - } -#endif - -#if TRAVERSE_READ_PROB - if (random() % TRAVERSE_READ_PROB == 0) { - tdb_traverse_read(db, NULL, NULL); - goto next; - } -#endif - - data = tdb_fetch(db, key); - if (data.dptr) free(data.dptr); - -next: - free(k); - free(d); -} - -static int traverse_fn(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf, - void *state) -{ - tdb_delete(tdb, key); - return 0; -} - -static void usage(void) -{ - printf("Usage: tdbtorture [-n NUM_PROCS] [-l NUM_LOOPS] [-s SEED] [-H HASH_SIZE]\n"); - exit(0); -} - - int main(int argc, char * const *argv) -{ - int i, seed = -1; - int num_procs = 3; - int num_loops = 5000; - int hash_size = 2; - int c; - extern char *optarg; - pid_t *pids; - - struct tdb_logging_context log_ctx; - log_ctx.log_fn = tdb_log; - - while ((c = getopt(argc, argv, "n:l:s:H:h")) != -1) { - switch (c) { - case 'n': - num_procs = strtol(optarg, NULL, 0); - break; - case 'l': - num_loops = strtol(optarg, NULL, 0); - break; - case 'H': - hash_size = strtol(optarg, NULL, 0); - break; - case 's': - seed = strtol(optarg, NULL, 0); - break; - default: - usage(); - } - } - - unlink("torture.tdb"); - - pids = calloc(sizeof(pid_t), num_procs); - pids[0] = getpid(); - - for (i=0;i<num_procs-1;i++) { - if ((pids[i+1]=fork()) == 0) break; - } - - db = tdb_open_ex("torture.tdb", hash_size, TDB_CLEAR_IF_FIRST, - O_RDWR | O_CREAT, 0600, &log_ctx, NULL); - if (!db) { - fatal("db open failed"); - } - - if (seed == -1) { - seed = (getpid() + time(NULL)) & 0x7FFFFFFF; - } - - if (i == 0) { - printf("testing with %d processes, %d loops, %d hash_size, seed=%d\n", - num_procs, num_loops, hash_size, seed); - } - - srand(seed + i); - srandom(seed + i); - - for (i=0;i<num_loops && error_count == 0;i++) { - addrec_db(); - } - - if (error_count == 0) { - tdb_traverse_read(db, NULL, NULL); - tdb_traverse(db, traverse_fn, NULL); - tdb_traverse(db, traverse_fn, NULL); - } - - tdb_close(db); - - if (getpid() != pids[0]) { - return error_count; - } - - for (i=1;i<num_procs;i++) { - int status, j; - pid_t pid; - if (error_count != 0) { - /* try and stop the test on any failure */ - for (j=1;j<num_procs;j++) { - if (pids[j] != 0) { - kill(pids[j], SIGTERM); - } - } - } - pid = waitpid(-1, &status, 0); - if (pid == -1) { - perror("failed to wait for child\n"); - exit(1); - } - for (j=1;j<num_procs;j++) { - if (pids[j] == pid) break; - } - if (j == num_procs) { - printf("unknown child %d exited!?\n", (int)pid); - exit(1); - } - if (WEXITSTATUS(status) != 0) { - printf("child %d exited with status %d\n", - (int)pid, WEXITSTATUS(status)); - error_count++; - } - pids[j] = 0; - } - - if (error_count == 0) { - printf("OK\n"); - } - - return error_count; -} diff --git a/source/lib/util.c b/source/lib/util.c index c0f2c5648e9..3c9233d9b34 100644 --- a/source/lib/util.c +++ b/source/lib/util.c @@ -199,6 +199,7 @@ void gfree_all( void ) gfree_case_tables(); gfree_debugsyms(); gfree_charcnv(); + gfree_messages(); gfree_interfaces(); /* release the talloc null_context memory last */ @@ -512,54 +513,35 @@ void show_msg(char *buf) if (DEBUGLEVEL < 50) bcc = MIN(bcc, 512); - dump_data(10, (uint8 *)smb_buf(buf), bcc); -} - -/******************************************************************* - Set the length and marker of an encrypted smb packet. -********************************************************************/ - -void smb_set_enclen(char *buf,int len,uint16 enc_ctx_num) -{ - _smb_setlen(buf,len); - - SCVAL(buf,4,0xFF); - SCVAL(buf,5,'E'); - SSVAL(buf,6,enc_ctx_num); + dump_data(10, smb_buf(buf), bcc); } /******************************************************************* Set the length and marker of an smb packet. ********************************************************************/ -void smb_setlen(const char *frombuf, char *buf, int len) +void smb_setlen(char *buf,int len) { _smb_setlen(buf,len); - if (frombuf) { - if (buf != frombuf) { - memcpy(buf+4, frombuf+4, 4); - } - } else { - SCVAL(buf,4,0xFF); - SCVAL(buf,5,'S'); - SCVAL(buf,6,'M'); - SCVAL(buf,7,'B'); - } + SCVAL(buf,4,0xFF); + SCVAL(buf,5,'S'); + SCVAL(buf,6,'M'); + SCVAL(buf,7,'B'); } /******************************************************************* Setup the word count and byte count for a smb message. ********************************************************************/ -int set_message(const char *frombuf, char *buf,int num_words,int num_bytes,BOOL zero) +int set_message(char *buf,int num_words,int num_bytes,BOOL zero) { if (zero && (num_words || num_bytes)) { memset(buf + smb_size,'\0',num_words*2 + num_bytes); } SCVAL(buf,smb_wct,num_words); SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes); - smb_setlen(frombuf, buf,smb_size + num_words*2 + num_bytes - 4); + smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4); return (smb_size + num_words*2 + num_bytes); } @@ -567,11 +549,11 @@ int set_message(const char *frombuf, char *buf,int num_words,int num_bytes,BOOL Setup only the byte count for a smb message. ********************************************************************/ -int set_message_bcc(const char *frombuf, char *buf,int num_bytes) +int set_message_bcc(char *buf,int num_bytes) { int num_words = CVAL(buf,smb_wct); SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes); - smb_setlen(frombuf, buf,smb_size + num_words*2 + num_bytes - 4); + smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4); return (smb_size + num_words*2 + num_bytes); } @@ -580,11 +562,9 @@ int set_message_bcc(const char *frombuf, char *buf,int num_bytes) message as a marker. ********************************************************************/ -int set_message_end(const char *frombuf, void *outbuf,void *end_ptr) +int set_message_end(void *outbuf,void *end_ptr) { - return set_message_bcc(frombuf, - (char *)outbuf, - PTR_DIFF(end_ptr,smb_buf((char *)outbuf))); + return set_message_bcc((char *)outbuf,PTR_DIFF(end_ptr,smb_buf((char *)outbuf))); } /******************************************************************* @@ -1257,6 +1237,7 @@ BOOL get_mydnsdomname(fstring my_domname) if (p) { p++; fstrcpy(my_domname, p); + return True; } return False; @@ -1526,30 +1507,26 @@ BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask) Check if a process exists. Does this work on all unixes? ****************************************************************************/ -BOOL process_exists(const struct server_id pid) +BOOL process_exists(const struct process_id pid) { if (procid_is_me(&pid)) { return True; } - if (procid_is_local(&pid)) { - return (kill(pid.pid,0) == 0 || errno != ESRCH); + if (!procid_is_local(&pid)) { + /* This *SEVERELY* needs fixing. */ + return True; } -#ifdef CLUSTER_SUPPORT - return ctdbd_process_exists(messaging_ctdbd_connection(), pid.vnn, - pid.pid); -#else - return False; -#endif + /* Doing kill with a non-positive pid causes messages to be + * sent to places we don't want. */ + SMB_ASSERT(pid.pid > 0); + return(kill(pid.pid,0) == 0 || errno != ESRCH); } BOOL process_exists_by_pid(pid_t pid) { - /* Doing kill with a non-positive pid causes messages to be - * sent to places we don't want. */ - SMB_ASSERT(pid > 0); - return(kill(pid,0) == 0 || errno != ESRCH); + return process_exists(pid_to_procid(pid)); } /******************************************************************* @@ -1857,8 +1834,7 @@ const char *readdirname(SMB_STRUCT_DIR *p) BOOL is_in_path(const char *name, name_compare_entry *namelist, BOOL case_sensitive) { - pstring last_component; - char *p; + const char *last_component; /* if we have no list it's obviously not in the path */ if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL))) { @@ -1868,8 +1844,12 @@ BOOL is_in_path(const char *name, name_compare_entry *namelist, BOOL case_sensit DEBUG(8, ("is_in_path: %s\n", name)); /* Get the last component of the unix name. */ - p = strrchr_m(name, '/'); - pstrcpy(last_component, p ? ++p : name); + last_component = strrchr_m(name, '/'); + if (!last_component) { + last_component = name; + } else { + last_component++; /* Go past '/' */ + } for(; namelist->name != NULL; namelist++) { if(namelist->is_wild) { @@ -1886,7 +1866,6 @@ BOOL is_in_path(const char *name, name_compare_entry *namelist, BOOL case_sensit } } DEBUG(8,("is_in_path: match not found\n")); - return False; } @@ -2276,8 +2255,9 @@ void print_asc(int level, const unsigned char *buf,int len) DEBUG(level,("%c", isprint(buf[i])?buf[i]:'.')); } -void dump_data(int level, const unsigned char *buf,int len) +void dump_data(int level, const char *buf1,int len) { + const unsigned char *buf = (const unsigned char *)buf1; int i=0; if (len<=0) return; @@ -2314,7 +2294,7 @@ void dump_data_pw(const char *msg, const uchar * data, size_t len) DEBUG(11, ("%s", msg)); if (data != NULL && len > 0) { - dump_data(11, data, len); + dump_data(11, (const char *)data, len); } #endif } @@ -2469,16 +2449,15 @@ int smb_mkstemp(char *name_template) void *smb_xmalloc_array(size_t size, unsigned int count) { void *p; - if (size == 0) { - smb_panic("smb_xmalloc_array: called with zero size"); - } + if (size == 0) + smb_panic("smb_xmalloc_array: called with zero size.\n"); if (count >= MAX_ALLOC_SIZE/size) { - smb_panic("smb_xmalloc_array: alloc size too large"); + smb_panic("smb_xmalloc: alloc size too large.\n"); } if ((p = SMB_MALLOC(size*count)) == NULL) { DEBUG(0, ("smb_xmalloc_array failed to allocate %lu * %lu bytes\n", (unsigned long)size, (unsigned long)count)); - smb_panic("smb_xmalloc_array: malloc failed"); + smb_panic("smb_xmalloc_array: malloc fail.\n"); } return p; } @@ -2518,9 +2497,8 @@ char *smb_xstrdup(const char *s) #endif #define strdup(s) __ERROR_DONT_USE_STRDUP_DIRECTLY #endif - if (!s1) { - smb_panic("smb_xstrdup: malloc failed"); - } + if (!s1) + smb_panic("smb_xstrdup: malloc fail\n"); return s1; } @@ -2549,9 +2527,8 @@ char *smb_xstrndup(const char *s, size_t n) #endif #define strndup(s,n) __ERROR_DONT_USE_STRNDUP_DIRECTLY #endif - if (!s1) { - smb_panic("smb_xstrndup: malloc failed"); - } + if (!s1) + smb_panic("smb_xstrndup: malloc fail\n"); return s1; } @@ -2567,9 +2544,8 @@ char *smb_xstrndup(const char *s, size_t n) VA_COPY(ap2, ap); n = vasprintf(ptr, format, ap2); - if (n == -1 || ! *ptr) { + if (n == -1 || ! *ptr) smb_panic("smb_xvasprintf: out of memory"); - } return n; } @@ -2775,7 +2751,7 @@ BOOL ms_has_wild_w(const smb_ucs2_t *s) of the ".." name. *******************************************************************/ -BOOL mask_match(const char *string, char *pattern, BOOL is_case_sensitive) +BOOL mask_match(const char *string, const char *pattern, BOOL is_case_sensitive) { if (strcmp(string,"..") == 0) string = "."; @@ -2791,7 +2767,7 @@ BOOL mask_match(const char *string, char *pattern, BOOL is_case_sensitive) pattern translation. *******************************************************************/ -BOOL mask_match_search(const char *string, char *pattern, BOOL is_case_sensitive) +BOOL mask_match_search(const char *string, const char *pattern, BOOL is_case_sensitive) { if (strcmp(string,"..") == 0) string = "."; @@ -3002,7 +2978,7 @@ void *talloc_check_name_abort(const void *ptr, const char *name) DEBUG(0, ("Talloc type mismatch, expected %s, got %s\n", name, talloc_get_name(ptr))); - smb_panic("talloc type mismatch"); + smb_panic("aborting"); /* Keep the compiler happy */ return NULL; } @@ -3068,128 +3044,71 @@ uint32 map_share_mode_to_deny_mode(uint32 share_access, uint32 private_options) return (uint32)-1; } -pid_t procid_to_pid(const struct server_id *proc) +pid_t procid_to_pid(const struct process_id *proc) { return proc->pid; } -static uint32 my_vnn = NONCLUSTER_VNN; - -void set_my_vnn(uint32 vnn) -{ - DEBUG(10, ("vnn pid %d = %u\n", (int)sys_getpid(), (unsigned int)vnn)); - my_vnn = vnn; -} - -uint32 get_my_vnn(void) +struct process_id pid_to_procid(pid_t pid) { - return my_vnn; -} - -struct server_id pid_to_procid(pid_t pid) -{ - struct server_id result; + struct process_id result; result.pid = pid; -#ifdef CLUSTER_SUPPORT - result.vnn = my_vnn; -#endif return result; } -struct server_id procid_self(void) +struct process_id procid_self(void) { return pid_to_procid(sys_getpid()); } struct server_id server_id_self(void) { - return procid_self(); + struct server_id id; + id.id = procid_self(); + return id; } -BOOL procid_equal(const struct server_id *p1, const struct server_id *p2) +BOOL procid_equal(const struct process_id *p1, const struct process_id *p2) { - if (p1->pid != p2->pid) - return False; -#ifdef CLUSTER_SUPPORT - if (p1->vnn != p2->vnn) - return False; -#endif - return True; + return (p1->pid == p2->pid); } BOOL cluster_id_equal(const struct server_id *id1, const struct server_id *id2) { - return procid_equal(id1, id2); + return procid_equal(&id1->id, &id2->id); } -BOOL procid_is_me(const struct server_id *pid) +BOOL procid_is_me(const struct process_id *pid) { - if (pid->pid != sys_getpid()) - return False; -#ifdef CLUSTER_SUPPORT - if (pid->vnn != my_vnn) - return False; -#endif - return True; + return (pid->pid == sys_getpid()); } -struct server_id interpret_pid(const char *pid_string) +struct process_id interpret_pid(const char *pid_string) { -#ifdef CLUSTER_SUPPORT - unsigned int vnn, pid; - struct server_id result; - if (sscanf(pid_string, "%u:%u", &vnn, &pid) == 2) { - result.vnn = vnn; - result.pid = pid; - } - else if (sscanf(pid_string, "%u", &pid) == 1) { - result.vnn = NONCLUSTER_VNN; - result.pid = pid; - } - else { - result.vnn = NONCLUSTER_VNN; - result.pid = -1; - } - return result; -#else return pid_to_procid(atoi(pid_string)); -#endif } -char *procid_str_static(const struct server_id *pid) +char *procid_str_static(const struct process_id *pid) { static fstring str; -#ifdef CLUSTER_SUPPORT - if (pid->vnn == NONCLUSTER_VNN) { - fstr_sprintf(str, "%d", (int)pid->pid); - } - else { - fstr_sprintf(str, "%u:%d", (unsigned)pid->vnn, (int)pid->pid); - } -#else - fstr_sprintf(str, "%d", (int)pid->pid); -#endif + fstr_sprintf(str, "%d", pid->pid); return str; } -char *procid_str(TALLOC_CTX *mem_ctx, const struct server_id *pid) +char *procid_str(TALLOC_CTX *mem_ctx, const struct process_id *pid) { return talloc_strdup(mem_ctx, procid_str_static(pid)); } -BOOL procid_valid(const struct server_id *pid) +BOOL procid_valid(const struct process_id *pid) { return (pid->pid != -1); } -BOOL procid_is_local(const struct server_id *pid) +BOOL procid_is_local(const struct process_id *pid) { -#ifdef CLUSTER_SUPPORT - return pid->vnn == my_vnn; -#else return True; -#endif } int this_is_smp(void) diff --git a/source/lib/util_file.c b/source/lib/util_file.c index 9c54c50b397..03246cad8e7 100644 --- a/source/lib/util_file.c +++ b/source/lib/util_file.c @@ -102,7 +102,7 @@ char *fgets_slash(char *s2,int maxlen,XFILE *f) Load from a pipe into memory. ****************************************************************************/ -static char *file_pload(char *syscmd, size_t *size) +char *file_pload(char *syscmd, size_t *size) { int fd, n; char *p; diff --git a/source/lib/util_nttoken.c b/source/lib/util_nttoken.c deleted file mode 100644 index 9cb981f74f0..00000000000 --- a/source/lib/util_nttoken.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * Authentication utility functions - * Copyright (C) Andrew Tridgell 1992-1998 - * Copyright (C) Andrew Bartlett 2001 - * Copyright (C) Jeremy Allison 2000-2001 - * Copyright (C) Rafal Szczesniak 2002 - * Copyright (C) Volker Lendecke 2006 - * Copyright (C) Michael Adam 2007 - * - * 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. - */ - -/* function(s) moved from auth/auth_util.c to minimize linker deps */ - -#include "includes.h" - -/**************************************************************************** - Duplicate a SID token. -****************************************************************************/ - -NT_USER_TOKEN *dup_nt_token(TALLOC_CTX *mem_ctx, const NT_USER_TOKEN *ptoken) -{ - NT_USER_TOKEN *token; - - if (!ptoken) - return NULL; - - token = TALLOC_P(mem_ctx, NT_USER_TOKEN); - if (token == NULL) { - DEBUG(0, ("talloc failed\n")); - return NULL; - } - - ZERO_STRUCTP(token); - - if (ptoken->user_sids && ptoken->num_sids) { - token->user_sids = (DOM_SID *)talloc_memdup( - token, ptoken->user_sids, sizeof(DOM_SID) * ptoken->num_sids ); - - if (token->user_sids == NULL) { - DEBUG(0, ("talloc_memdup failed\n")); - TALLOC_FREE(token); - return NULL; - } - token->num_sids = ptoken->num_sids; - } - - /* copy the privileges; don't consider failure to be critical here */ - - if ( !se_priv_copy( &token->privileges, &ptoken->privileges ) ) { - DEBUG(0,("dup_nt_token: Failure to copy SE_PRIV!. " - "Continuing with 0 privileges assigned.\n")); - } - - return token; -} - diff --git a/source/lib/util_pw.c b/source/lib/util_pw.c index 2c8f2d4a7d9..dc184233a6d 100644 --- a/source/lib/util_pw.c +++ b/source/lib/util_pw.c @@ -49,7 +49,7 @@ static void init_pwnam_cache(void) pwnam_cache = TALLOC_ZERO_ARRAY(NULL, struct passwd *, PWNAMCACHE_SIZE); if (pwnam_cache == NULL) { - smb_panic("Could not init pwnam_cache"); + smb_panic("Could not init pwnam_cache\n"); } return; @@ -74,7 +74,7 @@ struct passwd *getpwnam_alloc(TALLOC_CTX *mem_ctx, const char *name) if ((pwnam_cache[i] != NULL) && (strcmp(name, pwnam_cache[i]->pw_name) == 0)) { DEBUG(10, ("Got %s from pwnam_cache\n", name)); - return tcopy_passwd(mem_ctx, pwnam_cache[i]); + return (struct passwd *)talloc_reference(mem_ctx, pwnam_cache[i]); } } @@ -98,15 +98,15 @@ struct passwd *getpwnam_alloc(TALLOC_CTX *mem_ctx, const char *name) i = rand() % PWNAMCACHE_SIZE; if (pwnam_cache[i] != NULL) { - /* Remove this old cache entry, from the cache. We - * use talloc_unlink here because we want to be very - * clear which referece we are removing */ - talloc_unlink(pwnam_cache, pwnam_cache[i]); + TALLOC_FREE(pwnam_cache[i]); } pwnam_cache[i] = tcopy_passwd(pwnam_cache, temp); + if (pwnam_cache[i]!= NULL && mem_ctx != NULL) { + return (struct passwd *)talloc_reference(mem_ctx, pwnam_cache[i]); + } - return tcopy_passwd(mem_ctx, temp); + return tcopy_passwd(NULL, pwnam_cache[i]); } struct passwd *getpwuid_alloc(TALLOC_CTX *mem_ctx, uid_t uid) diff --git a/source/lib/util_reg.c b/source/lib/util_reg.c deleted file mode 100644 index cf0564509b7..00000000000 --- a/source/lib/util_reg.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * Registry helper routines - * Copyright (C) Volker Lendecke 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. - */ - -#include "includes.h" - -extern REGISTRY_OPS smbconf_reg_ops; - -const char *reg_type_lookup(enum winreg_Type type) -{ - const char *result; - - switch(type) { - case REG_NONE: - result = "REG_NONE"; - break; - case REG_SZ: - result = "REG_SZ"; - break; - case REG_EXPAND_SZ: - result = "REG_EXPAND_SZ"; - break; - case REG_BINARY: - result = "REG_BINARY"; - break; - case REG_DWORD: - result = "REG_DWORD"; - break; - case REG_DWORD_BIG_ENDIAN: - result = "REG_DWORD_BIG_ENDIAN"; - break; - case REG_LINK: - result = "REG_LINK"; - break; - case REG_MULTI_SZ: - result = "REG_MULTI_SZ"; - break; - case REG_RESOURCE_LIST: - result = "REG_RESOURCE_LIST"; - break; - case REG_FULL_RESOURCE_DESCRIPTOR: - result = "REG_FULL_RESOURCE_DESCRIPTOR"; - break; - case REG_RESOURCE_REQUIREMENTS_LIST: - result = "REG_RESOURCE_REQUIREMENTS_LIST"; - break; - case REG_QWORD: - result = "REG_QWORD"; - break; - default: - result = "REG TYPE IS UNKNOWN"; - break; - } - return result; -} - -WERROR reg_pull_multi_sz(TALLOC_CTX *mem_ctx, const void *buf, size_t len, - uint32 *num_values, char ***values) -{ - const smb_ucs2_t *p = (const smb_ucs2_t *)buf; - *num_values = 0; - - /* - * Make sure that a talloc context for the strings retrieved exists - */ - - if (!(*values = TALLOC_ARRAY(mem_ctx, char *, 1))) { - return WERR_NOMEM; - } - - len /= 2; /* buf is a set of UCS2 strings */ - - while (len > 0) { - char *val; - size_t dstlen, thislen; - - thislen = strnlen_w(p, len) + 1; - dstlen = convert_string_allocate(*values, CH_UTF16LE, CH_UNIX, - p, thislen*2, (void *)&val, - True); - if (dstlen == (size_t)-1) { - TALLOC_FREE(*values); - return WERR_NOMEM; - } - - ADD_TO_ARRAY(*values, char *, val, values, num_values); - if (*values == NULL) { - return WERR_NOMEM; - } - - p += thislen; - len -= thislen; - } - - return WERR_OK; -} - -void normalize_dbkey(char *key) -{ - size_t len = strlen(key); - string_sub(key, "\\", "/", len+1); - strupper_m(key); -} - -/* - * check whether a given value name is forbidden in registry (smbconf) - */ -BOOL registry_smbconf_valname_forbidden(const char *valname) -{ - /* hard code the list of forbidden names here for now */ - const char *forbidden_valnames[] = { - "include", - "lock directory", - "lock dir", - NULL - }; - const char **forbidden = NULL; - - for (forbidden = forbidden_valnames; *forbidden != NULL; forbidden++) { - if (strwicmp(valname, *forbidden) == 0) { - return True; - } - } - return False; -} diff --git a/source/lib/util_reg_api.c b/source/lib/util_reg_api.c deleted file mode 100644 index 43ad347d4b8..00000000000 --- a/source/lib/util_reg_api.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * Registry helper routines - * Copyright (C) Volker Lendecke 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. - */ - -#include "includes.h" - -WERROR registry_pull_value(TALLOC_CTX *mem_ctx, - struct registry_value **pvalue, - enum winreg_Type type, uint8 *data, - uint32 size, uint32 length) -{ - struct registry_value *value; - WERROR err; - - if (!(value = TALLOC_ZERO_P(mem_ctx, struct registry_value))) { - return WERR_NOMEM; - } - - value->type = type; - - switch (type) { - case REG_DWORD: - if ((size != 4) || (length != 4)) { - err = WERR_INVALID_PARAM; - goto error; - } - value->v.dword = IVAL(data, 0); - break; - case REG_SZ: - case REG_EXPAND_SZ: - { - /* - * Make sure we get a NULL terminated string for - * convert_string_talloc(). - */ - - smb_ucs2_t *tmp; - - if (length == 1) { - /* win2k regedit gives us a string of 1 byte when - * creating a new value of type REG_SZ. this workaround - * replaces the input by using the same string as - * winxp delivers. */ - length = 2; - if (!(tmp = SMB_MALLOC_ARRAY(smb_ucs2_t, 2))) { - err = WERR_NOMEM; - goto error; - } - tmp[0] = 2; - tmp[1] = 0; - } - else if ((length % 2) != 0) { - err = WERR_INVALID_PARAM; - goto error; - } - else { - uint32 num_ucs2 = length / 2; - if (!(tmp = SMB_MALLOC_ARRAY(smb_ucs2_t, num_ucs2+1))) { - err = WERR_NOMEM; - goto error; - } - - memcpy((void *)tmp, (const void *)data, length); - tmp[num_ucs2] = 0; - } - - if (length + 2 < length) { - /* Integer wrap. */ - SAFE_FREE(tmp); - err = WERR_INVALID_PARAM; - goto error; - } - - value->v.sz.len = convert_string_talloc( - value, CH_UTF16LE, CH_UNIX, tmp, length+2, - &value->v.sz.str, False); - - SAFE_FREE(tmp); - - if (value->v.sz.len == (size_t)-1) { - err = WERR_INVALID_PARAM; - goto error; - } - break; - } - case REG_MULTI_SZ: - err = reg_pull_multi_sz(value, (void *)data, length, - &value->v.multi_sz.num_strings, - &value->v.multi_sz.strings); - if (!(W_ERROR_IS_OK(err))) { - goto error; - } - break; - case REG_BINARY: - value->v.binary.data = talloc_move(value, &data); - value->v.binary.length = length; - break; - default: - err = WERR_INVALID_PARAM; - goto error; - } - - *pvalue = value; - return WERR_OK; - - error: - TALLOC_FREE(value); - return err; -} - -WERROR registry_push_value(TALLOC_CTX *mem_ctx, - const struct registry_value *value, - DATA_BLOB *presult) -{ - switch (value->type) { - case REG_DWORD: { - char buf[4]; - SIVAL(buf, 0, value->v.dword); - *presult = data_blob_talloc(mem_ctx, (void *)buf, 4); - if (presult->data == NULL) { - return WERR_NOMEM; - } - break; - } - case REG_SZ: - case REG_EXPAND_SZ: { - presult->length = convert_string_talloc( - mem_ctx, CH_UNIX, CH_UTF16LE, value->v.sz.str, - MIN(value->v.sz.len, strlen(value->v.sz.str)+1), - (void *)&(presult->data), False); - if (presult->length == (size_t)-1) { - return WERR_NOMEM; - } - break; - } - default: - return WERR_INVALID_PARAM; - } - - return WERR_OK; -} diff --git a/source/lib/util_reg_smbconf.c b/source/lib/util_reg_smbconf.c deleted file mode 100644 index 8fe6b4e0b68..00000000000 --- a/source/lib/util_reg_smbconf.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * Registry helper routines - * Copyright (C) Michael Adam 2007 - * - * 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. - */ - -#include "includes.h" - -extern REGISTRY_OPS smbconf_reg_ops; - -/* - * create a fake token just with enough rights to - * locally access the registry. - */ -NT_USER_TOKEN *registry_create_admin_token(TALLOC_CTX *mem_ctx) -{ - NT_USER_TOKEN *token = NULL; - - /* fake a user token: builtin administrators sid and the - * disk operators privilege is all we need to access the - * registry... */ - if (!(token = TALLOC_ZERO_P(mem_ctx, NT_USER_TOKEN))) { - DEBUG(1, ("talloc failed\n")); - goto done; - } - token->privileges = se_disk_operators; - if (!add_sid_to_array(token, &global_sid_Builtin_Administrators, - &token->user_sids, &token->num_sids)) { - DEBUG(1, ("Error adding builtin administrators sid " - "to fake token.\n")); - goto done; - } -done: - return token; -} - -/* - * init the smbconf portion of the registry. - * for use in places where not the whole registry is needed, - * e.g. utils/net_conf.c and loadparm.c - */ -BOOL registry_init_regdb(void) -{ - BOOL ret = False; - int saved_errno = 0; - static REGISTRY_HOOK smbconf_reg_hook = {KEY_SMBCONF, &smbconf_reg_ops}; - - DEBUG(10, ("registry_init_regdb called\n")); - - if (!regdb_init()) { - saved_errno = errno; - DEBUG(1, ("Can't open the registry")); - if (saved_errno) { - DEBUGADD(1, (": %s", strerror(saved_errno))); - } - DEBUGADD(1, (".\n")); - goto done; - } - reghook_cache_init(); - if (!reghook_cache_add(&smbconf_reg_hook)) { - DEBUG(1, ("Error adding smbconf reghooks to reghook cache.\n")); - goto done; - } - - ret = True; - -done: - return ret; -} diff --git a/source/lib/util_sock.c b/source/lib/util_sock.c index d102e570ab1..94c5e82d153 100644 --- a/source/lib/util_sock.c +++ b/source/lib/util_sock.c @@ -658,12 +658,10 @@ ssize_t read_smb_length(int fd, char *inbuf, unsigned int timeout) BUFFER_SIZE+SAFETY_MARGIN. The timeout is in milliseconds. This function will return on receipt of a session keepalive packet. - maxlen is the max number of bytes to return, not including the 4 byte - length. If zero it means BUFFER_SIZE+SAFETY_MARGIN limit. Doesn't check the MAC on signed packets. ****************************************************************************/ -ssize_t receive_smb_raw(int fd, char *buffer, unsigned int timeout, size_t maxlen) +BOOL receive_smb_raw(int fd, char *buffer, unsigned int timeout) { ssize_t len,ret; @@ -681,7 +679,7 @@ ssize_t receive_smb_raw(int fd, char *buffer, unsigned int timeout, size_t maxle if (smb_read_error == 0) smb_read_error = READ_ERROR; - return -1; + return False; } /* @@ -701,15 +699,11 @@ ssize_t receive_smb_raw(int fd, char *buffer, unsigned int timeout, size_t maxle if (smb_read_error == 0) smb_read_error = READ_ERROR; - return -1; + return False; } } if(len > 0) { - if (maxlen) { - len = MIN(len,maxlen); - } - if (timeout > 0) { ret = read_socket_with_timeout(fd,buffer+4,len,len,timeout); } else { @@ -720,7 +714,7 @@ ssize_t receive_smb_raw(int fd, char *buffer, unsigned int timeout, size_t maxle if (smb_read_error == 0) { smb_read_error = READ_ERROR; } - return -1; + return False; } /* not all of samba3 properly checks for packet-termination of strings. This @@ -728,7 +722,7 @@ ssize_t receive_smb_raw(int fd, char *buffer, unsigned int timeout, size_t maxle SSVAL(buffer+4,len, 0); } - return len; + return True; } /**************************************************************************** @@ -738,32 +732,19 @@ ssize_t receive_smb_raw(int fd, char *buffer, unsigned int timeout, size_t maxle BOOL receive_smb(int fd, char *buffer, unsigned int timeout) { - if (receive_smb_raw(fd, buffer, timeout, 0) < 0) { + if (!receive_smb_raw(fd, buffer, timeout)) { return False; } - if (srv_encryption_on()) { - NTSTATUS status = srv_decrypt_buffer(buffer); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("receive_smb: SMB decryption failed on incoming packet! Error %s\n", - nt_errstr(status) )); - if (smb_read_error == 0) { - smb_read_error = READ_BAD_DECRYPT; - } - return False; - } - } - /* Check the incoming SMB signature. */ if (!srv_check_sign_mac(buffer, True)) { DEBUG(0, ("receive_smb: SMB Signature verification failed on incoming packet!\n")); - if (smb_read_error == 0) { + if (smb_read_error == 0) smb_read_error = READ_BAD_SIG; - } return False; - } + }; - return True; + return(True); } /**************************************************************************** @@ -775,34 +756,22 @@ BOOL send_smb(int fd, char *buffer) size_t len; size_t nwritten=0; ssize_t ret; - char *buf_out = buffer; /* Sign the outgoing packet if required. */ - srv_calculate_sign_mac(buf_out); - - if (srv_encryption_on()) { - NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("send_smb: SMB encryption failed on outgoing packet! Error %s\n", - nt_errstr(status) )); - return False; - } - } + srv_calculate_sign_mac(buffer); - len = smb_len(buf_out) + 4; + len = smb_len(buffer) + 4; while (nwritten < len) { - ret = write_data(fd,buf_out+nwritten,len - nwritten); + ret = write_data(fd,buffer+nwritten,len - nwritten); if (ret <= 0) { DEBUG(0,("Error writing %d bytes to client. %d. (%s)\n", (int)len,(int)ret, strerror(errno) )); - srv_free_enc_buffer(buf_out); return False; } nwritten += ret; } - srv_free_enc_buffer(buf_out); return True; } diff --git a/source/lib/util_str.c b/source/lib/util_str.c index aaba7300fcf..52cdbfceddc 100644 --- a/source/lib/util_str.c +++ b/source/lib/util_str.c @@ -126,6 +126,8 @@ BOOL next_token_nr(const char **ptr,char *buff, const char *sep, size_t bufsize) return ret; } +static uint16 tmpbuf[sizeof(pstring)]; + void set_first_token(char *ptr) { last_ptr = ptr; @@ -392,11 +394,9 @@ BOOL strisnormal(const char *s, int case_default) NOTE: oldc and newc must be 7 bit characters **/ -void string_replace( char *s, char oldc, char newc ) +void string_replace( pstring s, char oldc, char newc ) { char *p; - smb_ucs2_t *tmp; - size_t src_len, len; /* this is quite a common operation, so we want it to be fast. We optimise for the ascii case, knowing that all our @@ -418,14 +418,9 @@ void string_replace( char *s, char oldc, char newc ) /* With compose characters we must restart from the beginning. JRA. */ p = s; #endif - src_len = strlen(p); - len = push_ucs2_allocate(&tmp, p); - if (len == -1) { - return; - } - string_replace_w(tmp, UCS2_CHAR(oldc), UCS2_CHAR(newc)); - pull_ucs2(NULL, p, tmp, src_len+1, -1, STR_TERMINATE); - SAFE_FREE(tmp); + push_ucs2(NULL, tmpbuf, p, sizeof(tmpbuf), STR_TERMINATE); + string_replace_w(tmpbuf, UCS2_CHAR(oldc), UCS2_CHAR(newc)); + pull_ucs2(NULL, p, tmpbuf, -1, sizeof(tmpbuf), STR_TERMINATE); } /** @@ -589,22 +584,12 @@ BOOL trim_string(char *s,const char *front,const char *back) BOOL strhasupper(const char *s) { - smb_ucs2_t *tmp, *p; - BOOL ret; - - if (push_ucs2_allocate(&tmp, s) == -1) { - return False; - } - - for(p = tmp; *p != 0; p++) { - if(isupper_w(*p)) { - break; - } - } - - ret = (*p != 0); - SAFE_FREE(tmp); - return ret; + smb_ucs2_t *ptr; + push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE); + for(ptr=tmpbuf;*ptr;ptr++) + if(isupper_w(*ptr)) + return True; + return(False); } /** @@ -613,22 +598,12 @@ BOOL strhasupper(const char *s) BOOL strhaslower(const char *s) { - smb_ucs2_t *tmp, *p; - BOOL ret; - - if (push_ucs2_allocate(&tmp, s) == -1) { - return False; - } - - for(p = tmp; *p != 0; p++) { - if(islower_w(*p)) { - break; - } - } - - ret = (*p != 0); - SAFE_FREE(tmp); - return ret; + smb_ucs2_t *ptr; + push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE); + for(ptr=tmpbuf;*ptr;ptr++) + if(islower_w(*ptr)) + return True; + return(False); } /** @@ -2653,7 +2628,7 @@ size_t utf16_len_n(const void *src, size_t n) char *escape_shell_string(const char *src) { size_t srclen = strlen(src); - char *ret = SMB_MALLOC_ARRAY(char, (srclen * 2) + 1); + char *ret = SMB_MALLOC((srclen * 2) + 1); char *dest = ret; BOOL in_s_quote = False; BOOL in_d_quote = False; diff --git a/source/lib/util_tdb.c b/source/lib/util_tdb.c index 564edffdac9..a1b5bf5bb16 100644 --- a/source/lib/util_tdb.c +++ b/source/lib/util_tdb.c @@ -43,22 +43,17 @@ static void gotalarm_sig(void) Make a TDB_DATA and keep the const warning in one place ****************************************************************/ -TDB_DATA make_tdb_data(const uint8 *dptr, size_t dsize) +TDB_DATA make_tdb_data(const char *dptr, size_t dsize) { TDB_DATA ret; - ret.dptr = CONST_DISCARD(uint8 *, dptr); + ret.dptr = CONST_DISCARD(char *, dptr); ret.dsize = dsize; return ret; } TDB_DATA string_tdb_data(const char *string) { - return make_tdb_data((const uint8 *)string, string ? strlen(string) : 0 ); -} - -TDB_DATA string_term_tdb_data(const char *string) -{ - return make_tdb_data((const uint8 *)string, string ? strlen(string) + 1 : 0); + return make_tdb_data(string, strlen(string)); } /**************************************************************************** @@ -113,7 +108,7 @@ int tdb_chainlock_with_timeout( TDB_CONTEXT *tdb, TDB_DATA key, unsigned int tim int tdb_lock_bystring(TDB_CONTEXT *tdb, const char *keyval) { - TDB_DATA key = string_term_tdb_data(keyval); + TDB_DATA key = make_tdb_data(keyval, strlen(keyval)+1); return tdb_chainlock(tdb, key); } @@ -121,7 +116,7 @@ int tdb_lock_bystring(TDB_CONTEXT *tdb, const char *keyval) int tdb_lock_bystring_with_timeout(TDB_CONTEXT *tdb, const char *keyval, int timeout) { - TDB_DATA key = string_term_tdb_data(keyval); + TDB_DATA key = make_tdb_data(keyval, strlen(keyval)+1); return tdb_chainlock_with_timeout(tdb, key, timeout); } @@ -132,7 +127,7 @@ int tdb_lock_bystring_with_timeout(TDB_CONTEXT *tdb, const char *keyval, void tdb_unlock_bystring(TDB_CONTEXT *tdb, const char *keyval) { - TDB_DATA key = string_term_tdb_data(keyval); + TDB_DATA key = make_tdb_data(keyval, strlen(keyval)+1); tdb_chainunlock(tdb, key); } @@ -143,7 +138,7 @@ void tdb_unlock_bystring(TDB_CONTEXT *tdb, const char *keyval) int tdb_read_lock_bystring_with_timeout(TDB_CONTEXT *tdb, const char *keyval, unsigned int timeout) { - TDB_DATA key = string_term_tdb_data(keyval); + TDB_DATA key = make_tdb_data(keyval, strlen(keyval)+1); return tdb_chainlock_with_timeout_internal(tdb, key, timeout, F_RDLCK); } @@ -154,7 +149,7 @@ int tdb_read_lock_bystring_with_timeout(TDB_CONTEXT *tdb, const char *keyval, un void tdb_read_unlock_bystring(TDB_CONTEXT *tdb, const char *keyval) { - TDB_DATA key = string_term_tdb_data(keyval); + TDB_DATA key = make_tdb_data(keyval, strlen(keyval)+1); tdb_chainunlock_read(tdb, key); } @@ -165,8 +160,9 @@ void tdb_read_unlock_bystring(TDB_CONTEXT *tdb, const char *keyval) Output is int32 in native byte order. ****************************************************************************/ -int32 tdb_fetch_int32_byblob(TDB_CONTEXT *tdb, TDB_DATA key) +int32 tdb_fetch_int32_byblob(TDB_CONTEXT *tdb, const char *keyval, size_t len) { + TDB_DATA key = make_tdb_data(keyval, len); TDB_DATA data; int32 ret; @@ -188,9 +184,7 @@ int32 tdb_fetch_int32_byblob(TDB_CONTEXT *tdb, TDB_DATA key) int32 tdb_fetch_int32(TDB_CONTEXT *tdb, const char *keystr) { - TDB_DATA key = string_term_tdb_data(keystr); - - return tdb_fetch_int32_byblob(tdb, key); + return tdb_fetch_int32_byblob(tdb, keystr, strlen(keystr) + 1); } /**************************************************************************** @@ -198,13 +192,14 @@ int32 tdb_fetch_int32(TDB_CONTEXT *tdb, const char *keystr) Input is int32 in native byte order. Output in tdb is in little-endian. ****************************************************************************/ -int tdb_store_int32_byblob(TDB_CONTEXT *tdb, TDB_DATA key, int32 v) +int tdb_store_int32_byblob(TDB_CONTEXT *tdb, const char *keystr, size_t len, int32 v) { + TDB_DATA key = make_tdb_data(keystr, len); TDB_DATA data; int32 v_store; SIVAL(&v_store,0,v); - data.dptr = (uint8 *)&v_store; + data.dptr = (char *)&v_store; data.dsize = sizeof(int32); return tdb_store(tdb, key, data, TDB_REPLACE); @@ -217,9 +212,7 @@ int tdb_store_int32_byblob(TDB_CONTEXT *tdb, TDB_DATA key, int32 v) int tdb_store_int32(TDB_CONTEXT *tdb, const char *keystr, int32 v) { - TDB_DATA key = string_term_tdb_data(keystr); - - return tdb_store_int32_byblob(tdb, key, v); + return tdb_store_int32_byblob(tdb, keystr, strlen(keystr) + 1, v); } /**************************************************************************** @@ -227,8 +220,9 @@ int tdb_store_int32(TDB_CONTEXT *tdb, const char *keystr, int32 v) Output is uint32 in native byte order. ****************************************************************************/ -BOOL tdb_fetch_uint32_byblob(TDB_CONTEXT *tdb, TDB_DATA key, uint32 *value) +BOOL tdb_fetch_uint32_byblob(TDB_CONTEXT *tdb, const char *keyval, size_t len, uint32 *value) { + TDB_DATA key = make_tdb_data(keyval, len); TDB_DATA data; data = tdb_fetch(tdb, key); @@ -249,9 +243,7 @@ BOOL tdb_fetch_uint32_byblob(TDB_CONTEXT *tdb, TDB_DATA key, uint32 *value) BOOL tdb_fetch_uint32(TDB_CONTEXT *tdb, const char *keystr, uint32 *value) { - TDB_DATA key = string_term_tdb_data(keystr); - - return tdb_fetch_uint32_byblob(tdb, key, value); + return tdb_fetch_uint32_byblob(tdb, keystr, strlen(keystr) + 1, value); } /**************************************************************************** @@ -259,14 +251,15 @@ BOOL tdb_fetch_uint32(TDB_CONTEXT *tdb, const char *keystr, uint32 *value) Input is uint32 in native byte order. Output in tdb is in little-endian. ****************************************************************************/ -BOOL tdb_store_uint32_byblob(TDB_CONTEXT *tdb, TDB_DATA key, uint32 value) +BOOL tdb_store_uint32_byblob(TDB_CONTEXT *tdb, const char *keystr, size_t len, uint32 value) { + TDB_DATA key = make_tdb_data(keystr, len); TDB_DATA data; uint32 v_store; BOOL ret = True; SIVAL(&v_store, 0, value); - data.dptr = (uint8 *)&v_store; + data.dptr = (char *)&v_store; data.dsize = sizeof(uint32); if (tdb_store(tdb, key, data, TDB_REPLACE) == -1) @@ -282,9 +275,7 @@ BOOL tdb_store_uint32_byblob(TDB_CONTEXT *tdb, TDB_DATA key, uint32 value) BOOL tdb_store_uint32(TDB_CONTEXT *tdb, const char *keystr, uint32 value) { - TDB_DATA key = string_term_tdb_data(keystr); - - return tdb_store_uint32_byblob(tdb, key, value); + return tdb_store_uint32_byblob(tdb, keystr, strlen(keystr) + 1, value); } /**************************************************************************** Store a buffer by a null terminated string key. Return 0 on success, -1 @@ -293,17 +284,9 @@ BOOL tdb_store_uint32(TDB_CONTEXT *tdb, const char *keystr, uint32 value) int tdb_store_bystring(TDB_CONTEXT *tdb, const char *keystr, TDB_DATA data, int flags) { - TDB_DATA key = string_term_tdb_data(keystr); - - return tdb_store(tdb, key, data, flags); -} - -int tdb_trans_store_bystring(TDB_CONTEXT *tdb, const char *keystr, - TDB_DATA data, int flags) -{ - TDB_DATA key = string_term_tdb_data(keystr); + TDB_DATA key = make_tdb_data(keystr, strlen(keystr)+1); - return tdb_trans_store(tdb, key, data, flags); + return tdb_store(tdb, key, data, flags); } /**************************************************************************** @@ -313,7 +296,7 @@ int tdb_trans_store_bystring(TDB_CONTEXT *tdb, const char *keystr, TDB_DATA tdb_fetch_bystring(TDB_CONTEXT *tdb, const char *keystr) { - TDB_DATA key = string_term_tdb_data(keystr); + TDB_DATA key = make_tdb_data(keystr, strlen(keystr)+1); return tdb_fetch(tdb, key); } @@ -324,7 +307,7 @@ TDB_DATA tdb_fetch_bystring(TDB_CONTEXT *tdb, const char *keystr) int tdb_delete_bystring(TDB_CONTEXT *tdb, const char *keystr) { - TDB_DATA key = string_term_tdb_data(keystr); + TDB_DATA key = make_tdb_data(keystr, strlen(keystr)+1); return tdb_delete(tdb, key); } @@ -417,7 +400,7 @@ BOOL tdb_change_uint32_atomic(TDB_CONTEXT *tdb, const char *keystr, uint32 *oldv integers and strings. ****************************************************************************/ -size_t tdb_pack_va(uint8 *buf, int bufsize, const char *fmt, va_list ap) +size_t tdb_pack_va(char *buf, int bufsize, const char *fmt, va_list ap) { uint8 bt; uint16 w; @@ -427,7 +410,7 @@ size_t tdb_pack_va(uint8 *buf, int bufsize, const char *fmt, va_list ap) int len; char *s; char c; - uint8 *buf0 = buf; + char *buf0 = buf; const char *fmt0 = fmt; int bufsize0 = bufsize; @@ -501,7 +484,7 @@ size_t tdb_pack_va(uint8 *buf, int bufsize, const char *fmt, va_list ap) return PTR_DIFF(buf, buf0); } -size_t tdb_pack(uint8 *buf, int bufsize, const char *fmt, ...) +size_t tdb_pack(char *buf, int bufsize, const char *fmt, ...) { va_list ap; size_t result; @@ -534,7 +517,7 @@ BOOL tdb_pack_append(TALLOC_CTX *mem_ctx, uint8 **buf, size_t *len, } va_start(ap, fmt); - len2 = tdb_pack_va((*buf)+(*len), len1, fmt, ap); + len2 = tdb_pack_va((char *)(*buf)+(*len), len1, fmt, ap); va_end(ap); if (len1 != len2) { @@ -551,7 +534,7 @@ BOOL tdb_pack_append(TALLOC_CTX *mem_ctx, uint8 **buf, size_t *len, integers and strings. ****************************************************************************/ -int tdb_unpack(const uint8 *buf, int bufsize, const char *fmt, ...) +int tdb_unpack(char *buf, int bufsize, const char *fmt, ...) { va_list ap; uint8 *bt; @@ -562,7 +545,7 @@ int tdb_unpack(const uint8 *buf, int bufsize, const char *fmt, ...) void **p; char *s, **b; char c; - const uint8 *buf0 = buf; + char *buf0 = buf; const char *fmt0 = fmt; int bufsize0 = bufsize; @@ -605,14 +588,14 @@ int tdb_unpack(const uint8 *buf, int bufsize, const char *fmt, ...) break; case 'P': s = va_arg(ap,char *); - len = strlen((const char *)buf) + 1; + len = strlen(buf) + 1; if (bufsize < len || len > sizeof(pstring)) goto no_space; memcpy(s, buf, len); break; case 'f': s = va_arg(ap,char *); - len = strlen((const char *)buf) + 1; + len = strlen(buf) + 1; if (bufsize < len || len > sizeof(fstring)) goto no_space; memcpy(s, buf, len); @@ -734,7 +717,7 @@ TDB_LIST_NODE *tdb_search_keys(TDB_CONTEXT *tdb, const char* pattern) for (key = tdb_firstkey(tdb); key.dptr; key = next) { /* duplicate key string to ensure null-termination */ - char *key_str = SMB_STRNDUP((const char *)key.dptr, key.dsize); + char *key_str = (char*) SMB_STRNDUP(key.dptr, key.dsize); if (!key_str) { DEBUG(0, ("tdb_search_keys: strndup() failed!\n")); smb_panic("strndup failed!\n"); @@ -802,7 +785,7 @@ int tdb_trans_store(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf, if ((res = tdb_store(tdb, key, dbuf, flag)) != 0) { DEBUG(10, ("tdb_store failed\n")); if (tdb_transaction_cancel(tdb) != 0) { - smb_panic("Cancelling transaction failed"); + smb_panic("Cancelling transaction failed\n"); } return res; } @@ -831,7 +814,7 @@ int tdb_trans_delete(struct tdb_context *tdb, TDB_DATA key) if ((res = tdb_delete(tdb, key)) != 0) { DEBUG(10, ("tdb_delete failed\n")); if (tdb_transaction_cancel(tdb) != 0) { - smb_panic("Cancelling transaction failed"); + smb_panic("Cancelling transaction failed\n"); } return res; } @@ -906,9 +889,6 @@ struct tdb_wrap *tdb_wrap_open(TALLOC_CTX *mem_ctx, struct tdb_logging_context log_ctx; log_ctx.log_fn = tdb_wrap_log; - if (!lp_use_mmap()) - tdb_flags |= TDB_NOMMAP; - for (w=tdb_list;w;w=w->next) { if (strcmp(name, w->name) == 0) { /* @@ -943,222 +923,3 @@ struct tdb_wrap *tdb_wrap_open(TALLOC_CTX *mem_ctx, return w; } - -NTSTATUS map_nt_error_from_tdb(enum TDB_ERROR err) -{ - struct { enum TDB_ERROR err; NTSTATUS status; } map[] = - { { TDB_SUCCESS, NT_STATUS_OK }, - { TDB_ERR_CORRUPT, NT_STATUS_INTERNAL_DB_CORRUPTION }, - { TDB_ERR_IO, NT_STATUS_UNEXPECTED_IO_ERROR }, - { TDB_ERR_OOM, NT_STATUS_NO_MEMORY }, - { TDB_ERR_EXISTS, NT_STATUS_OBJECT_NAME_COLLISION }, - - /* - * TDB_ERR_LOCK is very broad, we could for example - * distinguish between fcntl locks and invalid lock - * sequences. So NT_STATUS_FILE_LOCK_CONFLICT is a - * compromise. - */ - { TDB_ERR_LOCK, NT_STATUS_FILE_LOCK_CONFLICT }, - /* - * The next two ones in the enum are not actually used - */ - { TDB_ERR_NOLOCK, NT_STATUS_FILE_LOCK_CONFLICT }, - { TDB_ERR_LOCK_TIMEOUT, NT_STATUS_FILE_LOCK_CONFLICT }, - { TDB_ERR_NOEXIST, NT_STATUS_NOT_FOUND }, - { TDB_ERR_EINVAL, NT_STATUS_INVALID_PARAMETER }, - { TDB_ERR_RDONLY, NT_STATUS_ACCESS_DENIED } - }; - - int i; - - for (i=0; i < sizeof(map) / sizeof(map[0]); i++) { - if (err == map[i].err) { - return map[i].status; - } - } - - return NT_STATUS_INTERNAL_ERROR; -} - - -/********************************************************************* - * the following is a generic validation mechanism for tdbs. - *********************************************************************/ - -/* - * internal validation function, executed by the child. - */ -static int tdb_validate_child(const char *tdb_path, - tdb_validate_data_func validate_fn, - int pfd) -{ - int ret = -1; - int num_entries = 0; - TDB_CONTEXT *tdb = NULL; - struct tdb_validation_status v_status; - - v_status.tdb_error = False; - v_status.bad_freelist = False; - v_status.bad_entry = False; - v_status.unknown_key = False; - v_status.success = True; - - tdb = tdb_open_log(tdb_path, 0, TDB_DEFAULT, O_RDONLY, 0); - if (!tdb) { - v_status.tdb_error = True; - v_status.success = False; - goto out; - } - - /* Check the cache freelist is good. */ - if (tdb_validate_freelist(tdb, &num_entries) == -1) { - DEBUG(0,("tdb_validate_child: bad freelist in cache %s\n", - tdb_path)); - v_status.bad_freelist = True; - v_status.success = False; - goto out; - } - - DEBUG(10,("tdb_validate_child: cache %s freelist has %d entries\n", - tdb_path, num_entries)); - - /* Now traverse the cache to validate it. */ - num_entries = tdb_traverse(tdb, validate_fn, (void *)&v_status); - if (num_entries == -1 || !(v_status.success)) { - DEBUG(0,("tdb_validate_child: cache %s traverse failed\n", - tdb_path)); - if (!(v_status.success)) { - if (v_status.bad_entry) { - DEBUGADD(0, (" -> bad entry found\n")); - } - if (v_status.unknown_key) { - DEBUGADD(0, (" -> unknown key encountered\n")); - } - } - goto out; - } - - DEBUG(10,("tdb_validate_child: cache %s is good " - "with %d entries\n", tdb_path, num_entries)); - ret = 0; /* Cache is good. */ - -out: - if (tdb) { - tdb_close(tdb); - } - - DEBUG(10, ("tdb_validate_child: writing status to pipe\n")); - write (pfd, (const char *)&v_status, sizeof(v_status)); - close(pfd); - - return ret; -} - -int tdb_validate(const char *tdb_path, tdb_validate_data_func validate_fn) -{ - pid_t child_pid = -1; - int child_status = 0; - int wait_pid = 0; - int ret = -1; - int pipe_fds[2]; - struct tdb_validation_status v_status; - int bytes_read = 0; - - /* fork and let the child do the validation. - * benefit: no need to twist signal handlers and panic functions. - * just let the child panic. we catch the signal. - * communicate the extended status struct over a pipe. */ - - if (pipe(pipe_fds) != 0) { - DEBUG(0, ("tdb_validate: unable to create pipe, " - "error %s", strerror(errno))); - smb_panic("winbind_validate_cache: unable to create pipe."); - } - - DEBUG(10, ("tdb_validate: forking to let child do validation.\n")); - child_pid = sys_fork(); - if (child_pid == 0) { - DEBUG(10, ("tdb_validate (validation child): created\n")); - close(pipe_fds[0]); /* close reading fd */ - DEBUG(10, ("tdb_validate (validation child): " - "calling tdb_validate_child\n")); - exit(tdb_validate_child(tdb_path, validate_fn, pipe_fds[1])); - } - else if (child_pid < 0) { - smb_panic("tdb_validate: fork for validation failed."); - } - - /* parent */ - - DEBUG(10, ("tdb_validate: fork succeeded, child PID = %d\n", - child_pid)); - close(pipe_fds[1]); /* close writing fd */ - - v_status.success = True; - v_status.bad_entry = False; - v_status.unknown_key = False; - - DEBUG(10, ("tdb_validate: reading from pipe.\n")); - bytes_read = read(pipe_fds[0], (void *)&v_status, sizeof(v_status)); - close(pipe_fds[0]); - - if (bytes_read != sizeof(v_status)) { - DEBUG(10, ("tdb_validate: read %d bytes from pipe " - "but expected %d", bytes_read, (int)sizeof(v_status))); - DEBUGADD(10, (" -> assuming child crashed\n")); - v_status.success = False; - } - else { - DEBUG(10, ("tdb_validate: read status from child\n")); - DEBUGADD(10, (" * tdb error: %s\n", v_status.tdb_error ? "yes" : "no")); - DEBUGADD(10, (" * bad freelist: %s\n", v_status.bad_freelist ? "yes" : "no")); - DEBUGADD(10, (" * bad entry: %s\n", v_status.bad_entry ? "yes" : "no")); - DEBUGADD(10, (" * unknown key: %s\n", v_status.unknown_key ? "yes" : "no")); - DEBUGADD(10, (" => overall success: %s\n", v_status.success ? "yes" : "no")); - } - - DEBUG(10, ("tdb_validate: waiting for child to finish...\n")); - while ((wait_pid = sys_waitpid(child_pid, &child_status, 0)) < 0) { - if (errno == EINTR) { - DEBUG(10, ("tdb_validate: got signal during " - "waitpid, retrying\n")); - errno = 0; - continue; - } - DEBUG(0, ("tdb_validate: waitpid failed with " - "errno %s\n", strerror(errno))); - smb_panic("tdb_validate: waitpid failed."); - } - if (wait_pid != child_pid) { - DEBUG(0, ("tdb_validate: waitpid returned pid %d, " - "but %d was expexted\n", wait_pid, child_pid)); - smb_panic("tdb_validate: waitpid returned " - "unexpected PID."); - } - - DEBUG(10, ("tdb_validate: validating child returned.\n")); - if (WIFEXITED(child_status)) { - DEBUG(10, ("tdb_validate: child exited, code %d.\n", - WEXITSTATUS(child_status))); - ret = WEXITSTATUS(child_status); - } - if (WIFSIGNALED(child_status)) { - DEBUG(10, ("tdb_validate: child terminated " - "by signal %d\n", WTERMSIG(child_status))); -#ifdef WCOREDUMP - if (WCOREDUMP(child_status)) { - DEBUGADD(10, ("core dumped\n")); - } -#endif - ret = WTERMSIG(child_status); - } - if (WIFSTOPPED(child_status)) { - DEBUG(10, ("tdb_validate: child was stopped " - "by signal %d\n", - WSTOPSIG(child_status))); - ret = WSTOPSIG(child_status); - } - - return ret; -} |