summaryrefslogtreecommitdiff
path: root/source3/lib
diff options
context:
space:
mode:
Diffstat (limited to 'source3/lib')
-rw-r--r--source3/lib/access.c33
-rw-r--r--source3/lib/addrchange.c1
-rw-r--r--source3/lib/adt_tree.c4
-rw-r--r--source3/lib/bitmap.c4
-rw-r--r--source3/lib/charcnv.c257
-rw-r--r--source3/lib/ctdb_packet.c (renamed from source3/lib/packet.c)53
-rw-r--r--source3/lib/ctdbd_conn.c70
-rw-r--r--source3/lib/dbwrap.c61
-rw-r--r--source3/lib/dbwrap_ctdb.c23
-rw-r--r--source3/lib/dbwrap_file.c10
-rw-r--r--source3/lib/dbwrap_rbt.c2
-rw-r--r--source3/lib/dbwrap_tdb.c13
-rw-r--r--source3/lib/dbwrap_util.c70
-rw-r--r--source3/lib/dprintf.c128
-rw-r--r--source3/lib/dummyparam.c (renamed from source3/lib/dummyroot.c)17
-rw-r--r--source3/lib/errmap_unix.c113
-rw-r--r--source3/lib/eventlog/eventlog.c13
-rw-r--r--source3/lib/eventlog/eventlog.h2
-rw-r--r--source3/lib/eventlog/proto.h27
-rw-r--r--source3/lib/events.c23
-rw-r--r--source3/lib/filename_util.c7
-rw-r--r--source3/lib/fncall.c7
-rw-r--r--source3/lib/g_lock.c13
-rw-r--r--source3/lib/gencache.c72
-rw-r--r--source3/lib/idmap_cache.h25
-rw-r--r--source3/lib/interface.c4
-rw-r--r--source3/lib/interfaces.c299
-rw-r--r--source3/lib/memcache.c2
-rw-r--r--source3/lib/messages.c8
-rw-r--r--source3/lib/messages_ctdbd.c5
-rw-r--r--source3/lib/messages_local.c15
-rw-r--r--source3/lib/module.c8
-rw-r--r--source3/lib/ms_fnmatch.c9
-rw-r--r--source3/lib/namearray.c39
-rw-r--r--source3/lib/netapi/cm.c5
-rw-r--r--source3/lib/netapi/group.c8
-rw-r--r--source3/lib/netapi/libnetapi.h19
-rw-r--r--source3/lib/netapi/localgroup.c6
-rw-r--r--source3/lib/netapi/netapi.c51
-rw-r--r--source3/lib/netapi/netapi.h9
-rw-r--r--source3/lib/netapi/netapi_private.h2
-rw-r--r--source3/lib/netapi/samr.c2
-rw-r--r--source3/lib/netapi/serverinfo.c26
-rw-r--r--source3/lib/netapi/share.c4
-rw-r--r--source3/lib/netapi/user.c14
-rw-r--r--source3/lib/popt_common.c8
-rw-r--r--source3/lib/privileges.h27
-rw-r--r--source3/lib/pthreadpool/Makefile9
-rw-r--r--source3/lib/pthreadpool/pthreadpool.c (renamed from source3/lib/pthreadpool.c)296
-rw-r--r--source3/lib/pthreadpool/pthreadpool.h97
-rw-r--r--source3/lib/pthreadpool/tests.c362
-rw-r--r--source3/lib/pthreadpool/wscript_build11
-rw-r--r--source3/lib/secdesc.c712
-rw-r--r--source3/lib/server_mutex.c4
-rw-r--r--source3/lib/serverid.c7
-rw-r--r--source3/lib/sessionid_tdb.c1
-rw-r--r--source3/lib/sharesec.c3
-rw-r--r--source3/lib/smbconf/smbconf_init.c20
-rw-r--r--source3/lib/smbconf/smbconf_init.h2
-rw-r--r--source3/lib/smbconf/smbconf_reg.c405
-rw-r--r--source3/lib/smbconf/smbconf_reg.h2
-rw-r--r--source3/lib/smbconf/testsuite.c70
-rw-r--r--source3/lib/smbd_shim.c (renamed from source3/lib/dummysmbd.c)54
-rw-r--r--source3/lib/smbd_shim.h56
-rw-r--r--source3/lib/smbldap.c18
-rw-r--r--source3/lib/string_init.c77
-rw-r--r--source3/lib/substitute.c139
-rw-r--r--source3/lib/substitute_generic.c116
-rw-r--r--source3/lib/system.c181
-rw-r--r--source3/lib/talloc_dict.c1
-rw-r--r--source3/lib/tallocmsg.c2
-rw-r--r--source3/lib/tdb_validate.c17
-rw-r--r--source3/lib/tdb_validate.h2
-rw-r--r--source3/lib/tldap.c18
-rw-r--r--source3/lib/tldap_util.c4
-rw-r--r--source3/lib/util.c652
-rw-r--r--source3/lib/util_builtin.c1
-rw-r--r--source3/lib/util_cmdline.c4
-rw-r--r--source3/lib/util_malloc.c171
-rw-r--r--source3/lib/util_names.c133
-rw-r--r--source3/lib/util_nttoken.c4
-rw-r--r--source3/lib/util_sid.c2
-rw-r--r--source3/lib/util_sock.c397
-rw-r--r--source3/lib/util_str.c764
-rw-r--r--source3/lib/util_tdb.c296
-rw-r--r--source3/lib/util_tsock.c2
-rw-r--r--source3/lib/winbind_util.c12
-rw-r--r--source3/lib/wins_srv.c42
88 files changed, 2665 insertions, 4119 deletions
diff --git a/source3/lib/access.c b/source3/lib/access.c
index a7475a5edc..044c079cc5 100644
--- a/source3/lib/access.c
+++ b/source3/lib/access.c
@@ -12,7 +12,7 @@
#include "includes.h"
#include "memcache.h"
-#include "interfaces.h"
+#include "lib/socket/interfaces.h"
#define NAME_INDEX 0
#define ADDR_INDEX 1
@@ -182,29 +182,32 @@ static bool string_match(const char *tok,const char *s)
bool client_match(const char *tok, const void *item)
{
const char **client = (const char **)item;
+ const char *tok_addr = tok;
+ const char *cli_addr = client[ADDR_INDEX];
+
+ /*
+ * tok and client[ADDR_INDEX] can be an IPv4 mapped to IPv6,
+ * we try and match the IPv4 part of address only.
+ * Bug #5311 and #7383.
+ */
+
+ if (strnequal(tok_addr, "::ffff:",7)) {
+ tok_addr += 7;
+ }
+
+ if (strnequal(cli_addr,"::ffff:",7)) {
+ cli_addr += 7;
+ }
/*
* Try to match the address first. If that fails, try to match the host
* name if available.
*/
- if (string_match(tok, client[ADDR_INDEX])) {
+ if (string_match(tok_addr, cli_addr)) {
return true;
}
- if (strnequal(client[ADDR_INDEX],"::ffff:",7) &&
- !strnequal(tok, "::ffff:",7)) {
- /* client[ADDR_INDEX] is an IPv4 mapped to IPv6, but
- * the list item is not. Try and match the IPv4 part of
- * address only. This will happen a lot on IPv6 enabled
- * systems with IPv4 allow/deny lists in smb.conf.
- * Bug #5311. JRA.
- */
- if (string_match(tok, (client[ADDR_INDEX])+7)) {
- return true;
- }
- }
-
if (client[NAME_INDEX][0] != 0) {
if (string_match(tok, client[NAME_INDEX])) {
return true;
diff --git a/source3/lib/addrchange.c b/source3/lib/addrchange.c
index bd4bfbaa46..a5d2041953 100644
--- a/source3/lib/addrchange.c
+++ b/source3/lib/addrchange.c
@@ -18,6 +18,7 @@
#include "includes.h"
#include "lib/addrchange.h"
+#include "../lib/util/tevent_ntstatus.h"
#if HAVE_LINUX_RTNETLINK_H
diff --git a/source3/lib/adt_tree.c b/source3/lib/adt_tree.c
index 6d481613c7..de7f2d2637 100644
--- a/source3/lib/adt_tree.c
+++ b/source3/lib/adt_tree.c
@@ -134,7 +134,7 @@ static struct tree_node *pathtree_birth_child(struct tree_node *node,
/* the strings should never match assuming that we
have called pathtree_find_child() first */
- if ( StrCaseCmp( infant->key, node->children[i-1]->key ) > 0 ) {
+ if ( strcasecmp_m( infant->key, node->children[i-1]->key ) > 0 ) {
DEBUG(11,("pathtree_birth_child: storing infant in i == [%d]\n",
i));
node->children[i] = infant;
@@ -183,7 +183,7 @@ static struct tree_node *pathtree_find_child(struct tree_node *node,
DEBUG(11,("pathtree_find_child: child key => [%s]\n",
node->children[i]->key));
- result = StrCaseCmp( node->children[i]->key, key );
+ result = strcasecmp_m( node->children[i]->key, key );
if ( result == 0 )
next = node->children[i];
diff --git a/source3/lib/bitmap.c b/source3/lib/bitmap.c
index bd56b4aad1..5216b05c58 100644
--- a/source3/lib/bitmap.c
+++ b/source3/lib/bitmap.c
@@ -29,12 +29,12 @@ struct bitmap *bitmap_talloc(TALLOC_CTX *mem_ctx, int n)
{
struct bitmap *bm;
- bm = TALLOC_P(mem_ctx, struct bitmap);
+ bm = talloc(mem_ctx, struct bitmap);
if (!bm) return NULL;
bm->n = n;
- bm->b = TALLOC_ZERO_ARRAY(bm, uint32, (n+31)/32);
+ bm->b = talloc_zero_array(bm, uint32, (n+31)/32);
if (!bm->b) {
TALLOC_FREE(bm);
return NULL;
diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c
index f6fed8d1ec..17e836dfe0 100644
--- a/source3/lib/charcnv.c
+++ b/source3/lib/charcnv.c
@@ -31,112 +31,6 @@ void gfree_charcnv(void)
}
/**
- * Initialize iconv conversion descriptors.
- *
- * This is called the first time it is needed, and also called again
- * every time the configuration is reloaded, because the charset or
- * codepage might have changed.
- **/
-void init_iconv(void)
-{
- global_iconv_handle = smb_iconv_handle_reinit(NULL, lp_dos_charset(),
- lp_unix_charset(), lp_display_charset(),
- true, global_iconv_handle);
-}
-
-/**
- talloc_strdup() a unix string to upper case.
-**/
-
-char *talloc_strdup_upper(TALLOC_CTX *ctx, const char *s)
-{
- char *out_buffer = talloc_strdup(ctx,s);
- const unsigned char *p = (const unsigned char *)s;
- unsigned char *q = (unsigned char *)out_buffer;
-
- if (!q) {
- return NULL;
- }
-
- /* this is quite a common operation, so we want it to be
- fast. We optimise for the ascii case, knowing that all our
- supported multi-byte character sets are ascii-compatible
- (ie. they match for the first 128 chars) */
-
- while (*p) {
- if (*p & 0x80)
- break;
- *q++ = toupper_ascii_fast(*p);
- p++;
- }
-
- if (*p) {
- /* MB case. */
- size_t converted_size, converted_size2;
- smb_ucs2_t *ubuf = NULL;
-
- /* We're not using the ascii buffer above. */
- TALLOC_FREE(out_buffer);
-
- if (!convert_string_talloc(ctx, CH_UNIX, CH_UTF16LE, s,
- strlen(s)+1, (void *)&ubuf,
- &converted_size))
- {
- return NULL;
- }
-
- strupper_w(ubuf);
-
- if (!convert_string_talloc(ctx, CH_UTF16LE, CH_UNIX, ubuf,
- converted_size, (void *)&out_buffer,
- &converted_size2))
- {
- TALLOC_FREE(ubuf);
- return NULL;
- }
-
- /* Don't need the intermediate buffer
- * anymore.
- */
- TALLOC_FREE(ubuf);
- }
-
- return out_buffer;
-}
-
-char *strupper_talloc(TALLOC_CTX *ctx, const char *s) {
- return talloc_strdup_upper(ctx, s);
-}
-
-
-char *talloc_strdup_lower(TALLOC_CTX *ctx, const char *s)
-{
- size_t converted_size;
- smb_ucs2_t *buffer = NULL;
- char *out_buffer;
-
- if (!push_ucs2_talloc(ctx, &buffer, s, &converted_size)) {
- return NULL;
- }
-
- strlower_w(buffer);
-
- if (!pull_ucs2_talloc(ctx, &out_buffer, buffer, &converted_size)) {
- TALLOC_FREE(buffer);
- return NULL;
- }
-
- TALLOC_FREE(buffer);
-
- return out_buffer;
-}
-
-char *strlower_talloc(TALLOC_CTX *ctx, const char *s) {
- return talloc_strdup_lower(ctx, s);
-}
-
-
-/**
* Copy a string from a char* unix src to a dos codepage string destination.
*
* @return the number of bytes occupied by the string in the destination.
@@ -189,15 +83,6 @@ size_t push_ascii(void *dest, const char *src, size_t dest_len, int flags)
Push and malloc an ascii string. src and dest null terminated.
********************************************************************/
-bool push_ascii_talloc(TALLOC_CTX *mem_ctx, char **dest, const char *src, size_t *converted_size)
-{
- size_t src_len = strlen(src)+1;
-
- *dest = NULL;
- return convert_string_talloc(mem_ctx, CH_UNIX, CH_DOS, src, src_len,
- (void **)dest, converted_size);
-}
-
/**
* Copy a string from a dos codepage source to a unix char* destination.
*
@@ -317,7 +202,7 @@ static size_t pull_ascii_base_talloc(TALLOC_CTX *ctx,
/* Have we got space to append the '\0' ? */
if (size <= dest_len) {
/* No, realloc. */
- dest = TALLOC_REALLOC_ARRAY(ctx, dest, char,
+ dest = talloc_realloc(ctx, dest, char,
dest_len+1);
if (!dest) {
/* talloc fail. */
@@ -354,7 +239,7 @@ static size_t pull_ascii_base_talloc(TALLOC_CTX *ctx,
* destination.
**/
-size_t push_ucs2(const void *base_ptr, void *dest, const char *src, size_t dest_len, int flags)
+static size_t push_ucs2(const void *base_ptr, void *dest, const char *src, size_t dest_len, int flags)
{
size_t len=0;
size_t src_len;
@@ -413,48 +298,6 @@ size_t push_ucs2(const void *base_ptr, void *dest, const char *src, size_t dest_
}
-/**
- * Copy a string from a unix char* src to a UCS2 destination,
- * allocating a buffer using talloc().
- *
- * @param dest always set at least to NULL
- * @parm converted_size set to the number of bytes occupied by the string in
- * the destination on success.
- *
- * @return true if new buffer was correctly allocated, and string was
- * converted.
- **/
-bool push_ucs2_talloc(TALLOC_CTX *ctx, smb_ucs2_t **dest, const char *src,
- size_t *converted_size)
-{
- size_t src_len = strlen(src)+1;
-
- *dest = NULL;
- return convert_string_talloc(ctx, CH_UNIX, CH_UTF16LE, src, src_len,
- (void **)dest, converted_size);
-}
-
-
-/**
- * Copy a string from a unix char* src to a UTF-8 destination, allocating a buffer using talloc
- *
- * @param dest always set at least to NULL
- * @parm converted_size set to the number of bytes occupied by the string in
- * the destination on success.
- *
- * @return true if new buffer was correctly allocated, and string was
- * converted.
- **/
-
-bool push_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src,
- size_t *converted_size)
-{
- size_t src_len = strlen(src)+1;
-
- *dest = NULL;
- return convert_string_talloc(ctx, CH_UNIX, CH_UTF8, src, src_len,
- (void**)dest, converted_size);
-}
/**
Copy a string from a ucs2 source to a unix char* destination.
@@ -606,7 +449,7 @@ static size_t pull_ucs2_base_talloc(TALLOC_CTX *ctx,
/* Have we got space to append the '\0' ? */
if (size <= dest_len) {
/* No, realloc. */
- dest = TALLOC_REALLOC_ARRAY(ctx, dest, char,
+ dest = talloc_realloc(ctx, dest, char,
dest_len+1);
if (!dest) {
/* talloc fail. */
@@ -627,70 +470,6 @@ static size_t pull_ucs2_base_talloc(TALLOC_CTX *ctx,
}
/**
- * Copy a string from a UCS2 src to a unix char * destination, allocating a buffer using talloc
- *
- * @param dest always set at least to NULL
- * @parm converted_size set to the number of bytes occupied by the string in
- * the destination on success.
- *
- * @return true if new buffer was correctly allocated, and string was
- * converted.
- **/
-
-bool pull_ucs2_talloc(TALLOC_CTX *ctx, char **dest, const smb_ucs2_t *src,
- size_t *converted_size)
-{
- size_t src_len = (strlen_w(src)+1) * sizeof(smb_ucs2_t);
-
- *dest = NULL;
- return convert_string_talloc(ctx, CH_UTF16LE, CH_UNIX, src, src_len,
- (void **)dest, converted_size);
-}
-
-/**
- * Copy a string from a UTF-8 src to a unix char * destination, allocating a buffer using talloc
- *
- * @param dest always set at least to NULL
- * @parm converted_size set to the number of bytes occupied by the string in
- * the destination on success.
- *
- * @return true if new buffer was correctly allocated, and string was
- * converted.
- **/
-
-bool pull_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src,
- size_t *converted_size)
-{
- size_t src_len = strlen(src)+1;
-
- *dest = NULL;
- return convert_string_talloc(ctx, CH_UTF8, CH_UNIX, src, src_len,
- (void **)dest, converted_size);
-}
-
-
-/**
- * Copy a string from a DOS src to a unix char * destination, allocating a buffer using talloc
- *
- * @param dest always set at least to NULL
- * @parm converted_size set to the number of bytes occupied by the string in
- * the destination on success.
- *
- * @return true if new buffer was correctly allocated, and string was
- * converted.
- **/
-
-bool pull_ascii_talloc(TALLOC_CTX *ctx, char **dest, const char *src,
- size_t *converted_size)
-{
- size_t src_len = strlen(src)+1;
-
- *dest = NULL;
- return convert_string_talloc(ctx, CH_DOS, CH_UNIX, src, src_len,
- (void **)dest, converted_size);
-}
-
-/**
Copy a string from a char* src to a unicode or ascii
dos codepage destination choosing unicode or ascii based on the
flags supplied
@@ -742,36 +521,6 @@ size_t push_string_base(const char *base, uint16 flags2,
}
/**
- Copy a string from a char* src to a unicode or ascii
- dos codepage destination choosing unicode or ascii based on the
- flags supplied
- Return the number of bytes occupied by the string in the destination.
- flags can have:
- STR_TERMINATE means include the null termination.
- STR_UPPER means uppercase in the destination.
- STR_ASCII use ascii even with unicode packet.
- STR_NOALIGN means don't do alignment.
- dest_len is the maximum length allowed in the destination. If dest_len
- is -1 then no maxiumum is used.
-**/
-
-ssize_t push_string(void *dest, const char *src, size_t dest_len, int flags)
-{
- size_t ret;
-
- if (!(flags & STR_ASCII) && \
- (flags & STR_UNICODE)) {
- ret = push_ucs2(NULL, dest, src, dest_len, flags);
- } else {
- ret = push_ascii(dest, src, dest_len, flags);
- }
- if (ret == (size_t)-1) {
- return -1;
- }
- return ret;
-}
-
-/**
Copy a string from a unicode or ascii source (depending on
the packet flags) to a char* destination.
Flags can have:
diff --git a/source3/lib/packet.c b/source3/lib/ctdb_packet.c
index 133983d3d4..17c70ff2d6 100644
--- a/source3/lib/packet.c
+++ b/source3/lib/ctdb_packet.c
@@ -1,6 +1,6 @@
-/*
+/*
Unix SMB/CIFS implementation.
- Packet handling
+ CTDB Packet handling
Copyright (C) Volker Lendecke 2007
This program is free software; you can redistribute it and/or modify
@@ -21,9 +21,9 @@
#include "../lib/util/select.h"
#include "system/filesys.h"
#include "system/select.h"
-#include "packet.h"
+#include "ctdb_packet.h"
-struct packet_context {
+struct ctdb_packet_context {
int fd;
DATA_BLOB in, out;
};
@@ -31,32 +31,32 @@ struct packet_context {
/*
* Close the underlying fd
*/
-static int packet_context_destructor(struct packet_context *ctx)
+static int ctdb_packet_context_destructor(struct ctdb_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.
+ * Initialize a ctdb_packet context. The fd is given to the ctdb_packet context, meaning
+ * that it is automatically closed when the ctdb_packet context is freed.
*/
-struct packet_context *packet_init(TALLOC_CTX *mem_ctx, int fd)
+struct ctdb_packet_context *ctdb_packet_init(TALLOC_CTX *mem_ctx, int fd)
{
- struct packet_context *result;
+ struct ctdb_packet_context *result;
- if (!(result = TALLOC_ZERO_P(mem_ctx, struct packet_context))) {
+ if (!(result = talloc_zero(mem_ctx, struct ctdb_packet_context))) {
return NULL;
}
result->fd = fd;
- talloc_set_destructor(result, packet_context_destructor);
+ talloc_set_destructor(result, ctdb_packet_context_destructor);
return result;
}
/*
* Pull data from the fd
*/
-NTSTATUS packet_fd_read(struct packet_context *ctx)
+NTSTATUS ctdb_packet_fd_read(struct ctdb_packet_context *ctx)
{
int res, available;
size_t new_size;
@@ -82,7 +82,7 @@ NTSTATUS packet_fd_read(struct packet_context *ctx)
return NT_STATUS_NO_MEMORY;
}
- if (!(in = TALLOC_REALLOC_ARRAY(ctx, ctx->in.data, uint8, new_size))) {
+ if (!(in = talloc_realloc(ctx, ctx->in.data, uint8, new_size))) {
DEBUG(10, ("talloc failed\n"));
return NT_STATUS_NO_MEMORY;
}
@@ -105,7 +105,7 @@ NTSTATUS packet_fd_read(struct packet_context *ctx)
return NT_STATUS_OK;
}
-NTSTATUS packet_fd_read_sync(struct packet_context *ctx, int timeout)
+NTSTATUS ctdb_packet_fd_read_sync_timeout(struct ctdb_packet_context *ctx, int timeout)
{
int res, revents;
@@ -124,10 +124,10 @@ NTSTATUS packet_fd_read_sync(struct packet_context *ctx, int timeout)
return NT_STATUS_IO_TIMEOUT;
}
- return packet_fd_read(ctx);
+ return ctdb_packet_fd_read(ctx);
}
-bool packet_handler(struct packet_context *ctx,
+bool ctdb_packet_handler(struct ctdb_packet_context *ctx,
bool (*full_req)(const uint8_t *buf,
size_t available,
size_t *length,
@@ -153,7 +153,7 @@ bool packet_handler(struct packet_context *ctx,
ctx->in.data = NULL;
ctx->in.length = 0;
} else {
- buf = (uint8_t *)TALLOC_MEMDUP(ctx, ctx->in.data, length);
+ buf = (uint8_t *)talloc_memdup(ctx, ctx->in.data, length);
if (buf == NULL) {
*status = NT_STATUS_NO_MEMORY;
return true;
@@ -171,7 +171,7 @@ bool packet_handler(struct packet_context *ctx,
/*
* How many bytes of outgoing data do we have pending?
*/
-size_t packet_outgoing_bytes(struct packet_context *ctx)
+size_t ctdb_packet_outgoing_bytes(struct ctdb_packet_context *ctx)
{
return ctx->out.length;
}
@@ -179,7 +179,7 @@ size_t packet_outgoing_bytes(struct packet_context *ctx)
/*
* Push data to the fd
*/
-NTSTATUS packet_fd_write(struct packet_context *ctx)
+NTSTATUS ctdb_packet_fd_write(struct ctdb_packet_context *ctx)
{
ssize_t sent;
@@ -200,10 +200,10 @@ NTSTATUS packet_fd_write(struct packet_context *ctx)
/*
* Sync flush all outgoing bytes
*/
-NTSTATUS packet_flush(struct packet_context *ctx)
+NTSTATUS ctdb_packet_flush(struct ctdb_packet_context *ctx)
{
while (ctx->out.length != 0) {
- NTSTATUS status = packet_fd_write(ctx);
+ NTSTATUS status = ctdb_packet_fd_write(ctx);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
@@ -214,10 +214,10 @@ NTSTATUS packet_flush(struct packet_context *ctx)
/*
* Send a list of DATA_BLOBs
*
- * Example: packet_send(ctx, 2, data_blob_const(&size, sizeof(size)),
+ * Example: ctdb_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, ...)
+NTSTATUS ctdb_packet_send(struct ctdb_packet_context *ctx, int num_blobs, ...)
{
va_list ap;
int i;
@@ -245,7 +245,7 @@ NTSTATUS packet_send(struct packet_context *ctx, int num_blobs, ...)
return NT_STATUS_OK;
}
- if (!(out = TALLOC_REALLOC_ARRAY(ctx, ctx->out.data, uint8, len))) {
+ if (!(out = talloc_realloc(ctx, ctx->out.data, uint8, len))) {
DEBUG(0, ("talloc failed\n"));
return NT_STATUS_NO_MEMORY;
}
@@ -266,10 +266,9 @@ NTSTATUS packet_send(struct packet_context *ctx, int num_blobs, ...)
}
/*
- * Get the packet context's file descriptor
+ * Get the ctdb_packet context's file descriptor
*/
-int packet_get_fd(struct packet_context *ctx)
+int ctdb_packet_get_fd(struct ctdb_packet_context *ctx)
{
return ctx->fd;
}
-
diff --git a/source3/lib/ctdbd_conn.c b/source3/lib/ctdbd_conn.c
index a81691a8c9..79dc1f246a 100644
--- a/source3/lib/ctdbd_conn.c
+++ b/source3/lib/ctdbd_conn.c
@@ -19,11 +19,12 @@
*/
#include "includes.h"
+#include "util_tdb.h"
#ifdef CLUSTER_SUPPORT
#include "ctdbd_conn.h"
-#include "packet.h"
+#include "ctdb_packet.h"
#include "messages.h"
/* paths to these include files come from --with-ctdb= in configure */
@@ -35,7 +36,7 @@ struct ctdbd_connection {
uint32 reqid;
uint32 our_vnn;
uint64 rand_srvid;
- struct packet_context *pkt;
+ struct ctdb_packet_context *pkt;
struct fd_event *fde;
void (*release_ip_handler)(const char *ip_addr, void *private_data);
@@ -168,9 +169,9 @@ uint32 ctdbd_vnn(const struct ctdbd_connection *conn)
*/
static NTSTATUS ctdbd_connect(TALLOC_CTX *mem_ctx,
- struct packet_context **presult)
+ struct ctdb_packet_context **presult)
{
- struct packet_context *result;
+ struct ctdb_packet_context *result;
const char *sockname = lp_ctdbd_socket();
struct sockaddr_un addr;
int fd;
@@ -196,7 +197,7 @@ static NTSTATUS ctdbd_connect(TALLOC_CTX *mem_ctx,
return map_nt_error_from_unix(errno);
}
- if (!(result = packet_init(mem_ctx, fd))) {
+ if (!(result = ctdb_packet_init(mem_ctx, fd))) {
close(fd);
return NT_STATUS_NO_MEMORY;
}
@@ -271,7 +272,7 @@ struct req_pull_state {
};
/*
- * Pull a ctdb request out of the incoming packet queue
+ * Pull a ctdb request out of the incoming ctdb_packet queue
*/
static NTSTATUS ctdb_req_pull(uint8_t *buf, size_t length,
@@ -303,7 +304,7 @@ static struct messaging_rec *ctdb_pull_messaging_rec(TALLOC_CTX *mem_ctx,
cluster_fatal("got invalid msg length");
}
- if (!(result = TALLOC_P(mem_ctx, struct messaging_rec))) {
+ if (!(result = talloc(mem_ctx, struct messaging_rec))) {
DEBUG(0, ("talloc failed\n"));
return NULL;
}
@@ -329,14 +330,14 @@ static struct messaging_rec *ctdb_pull_messaging_rec(TALLOC_CTX *mem_ctx,
return result;
}
-static NTSTATUS ctdb_packet_fd_read_sync(struct packet_context *ctx)
+static NTSTATUS ctdb_packet_fd_read_sync(struct ctdb_packet_context *ctx)
{
int timeout = lp_ctdb_timeout();
if (timeout == 0) {
timeout = -1;
}
- return packet_fd_read_sync(ctx, timeout);
+ return ctdb_packet_fd_read_sync_timeout(ctx, timeout);
}
/*
@@ -364,7 +365,7 @@ static NTSTATUS ctdb_read_req(struct ctdbd_connection *conn, uint32 reqid,
}
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0, ("packet_fd_read failed: %s\n", nt_errstr(status)));
+ DEBUG(0, ("ctdb_packet_fd_read failed: %s\n", nt_errstr(status)));
cluster_fatal("ctdbd died\n");
}
@@ -373,7 +374,7 @@ static NTSTATUS ctdb_read_req(struct ctdbd_connection *conn, uint32 reqid,
ZERO_STRUCT(state);
state.mem_ctx = mem_ctx;
- if (!packet_handler(conn->pkt, ctdb_req_complete, ctdb_req_pull,
+ if (!ctdb_packet_handler(conn->pkt, ctdb_req_complete, ctdb_req_pull,
&state, &status)) {
/*
* Not enough data
@@ -383,7 +384,7 @@ static NTSTATUS ctdb_read_req(struct ctdbd_connection *conn, uint32 reqid,
}
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0, ("Could not read packet: %s\n", nt_errstr(status)));
+ DEBUG(0, ("Could not read ctdb_packet: %s\n", nt_errstr(status)));
cluster_fatal("ctdbd died\n");
}
@@ -432,7 +433,7 @@ static NTSTATUS ctdb_read_req(struct ctdbd_connection *conn, uint32 reqid,
goto next_pkt;
}
- msg_state = TALLOC_P(NULL, struct deferred_msg_state);
+ msg_state = talloc(NULL, struct deferred_msg_state);
if (msg_state == NULL) {
DEBUG(0, ("talloc failed\n"));
TALLOC_FREE(hdr);
@@ -493,7 +494,7 @@ static NTSTATUS ctdbd_init_connection(TALLOC_CTX *mem_ctx,
struct ctdbd_connection *conn;
NTSTATUS status;
- if (!(conn = TALLOC_ZERO_P(mem_ctx, struct ctdbd_connection))) {
+ if (!(conn = talloc_zero(mem_ctx, struct ctdbd_connection))) {
DEBUG(0, ("talloc failed\n"));
return NT_STATUS_NO_MEMORY;
}
@@ -583,7 +584,7 @@ struct messaging_context *ctdb_conn_msg_ctx(struct ctdbd_connection *conn)
int ctdbd_conn_get_fd(struct ctdbd_connection *conn)
{
- return packet_get_fd(conn->pkt);
+ return ctdb_packet_get_fd(conn->pkt);
}
/*
@@ -674,14 +675,14 @@ static void ctdbd_socket_handler(struct event_context *event_ctx,
NTSTATUS status;
- status = packet_fd_read(conn->pkt);
+ status = ctdb_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,
+ while (ctdb_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",
@@ -701,7 +702,7 @@ NTSTATUS ctdbd_register_msg_ctx(struct ctdbd_connection *conn,
SMB_ASSERT(conn->fde == NULL);
if (!(conn->fde = event_add_fd(msg_ctx->event_ctx, conn,
- packet_get_fd(conn->pkt),
+ ctdb_packet_get_fd(conn->pkt),
EVENT_FD_READ,
ctdbd_socket_handler,
conn))) {
@@ -758,17 +759,17 @@ NTSTATUS ctdbd_messaging_send(struct ctdbd_connection *conn,
DEBUG(10, ("ctdbd_messaging_send: Sending ctdb packet\n"));
ctdb_packet_dump(&r.hdr);
- status = packet_send(
+ status = ctdb_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)));
+ DEBUG(0, ("ctdb_packet_send failed: %s\n", nt_errstr(status)));
goto fail;
}
- status = packet_flush(conn->pkt);
+ status = ctdb_packet_flush(conn->pkt);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(3, ("write to ctdbd failed: %s\n", nt_errstr(status)));
@@ -823,17 +824,17 @@ static NTSTATUS ctdbd_control(struct ctdbd_connection *conn,
DEBUG(10, ("ctdbd_control: Sending ctdb packet\n"));
ctdb_packet_dump(&req.hdr);
- status = packet_send(
+ status = ctdb_packet_send(
conn->pkt, 2,
data_blob_const(&req, offsetof(struct ctdb_req_control, data)),
data_blob_const(data.dptr, data.dsize));
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(3, ("packet_send failed: %s\n", nt_errstr(status)));
+ DEBUG(3, ("ctdb_packet_send failed: %s\n", nt_errstr(status)));
goto fail;
}
- status = packet_flush(conn->pkt);
+ status = ctdb_packet_flush(conn->pkt);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(3, ("write to ctdbd failed: %s\n", nt_errstr(status)));
@@ -1005,17 +1006,17 @@ NTSTATUS ctdbd_migrate(struct ctdbd_connection *conn, uint32 db_id,
DEBUG(10, ("ctdbd_migrate: Sending ctdb packet\n"));
ctdb_packet_dump(&req.hdr);
- status = packet_send(
+ status = ctdb_packet_send(
conn->pkt, 2,
data_blob_const(&req, offsetof(struct ctdb_req_call, data)),
data_blob_const(key.dptr, key.dsize));
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(3, ("packet_send failed: %s\n", nt_errstr(status)));
+ DEBUG(3, ("ctdb_packet_send failed: %s\n", nt_errstr(status)));
return status;
}
- status = packet_flush(conn->pkt);
+ status = ctdb_packet_flush(conn->pkt);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(3, ("write to ctdbd failed: %s\n", nt_errstr(status)));
@@ -1064,17 +1065,17 @@ NTSTATUS ctdbd_fetch(struct ctdbd_connection *conn, uint32 db_id,
req.db_id = db_id;
req.keylen = key.dsize;
- status = packet_send(
+ status = ctdb_packet_send(
conn->pkt, 2,
data_blob_const(&req, offsetof(struct ctdb_req_call, data)),
data_blob_const(key.dptr, key.dsize));
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(3, ("packet_send failed: %s\n", nt_errstr(status)));
+ DEBUG(3, ("ctdb_packet_send failed: %s\n", nt_errstr(status)));
return status;
}
- status = packet_flush(conn->pkt);
+ status = ctdb_packet_flush(conn->pkt);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(3, ("write to ctdbd failed: %s\n", nt_errstr(status)));
@@ -1235,7 +1236,7 @@ NTSTATUS ctdbd_traverse(uint32 db_id,
status = NT_STATUS_OK;
- if (packet_handler(conn->pkt, ctdb_req_complete,
+ if (ctdb_packet_handler(conn->pkt, ctdb_req_complete,
ctdb_traverse_handler, &state, &status)) {
if (NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)) {
@@ -1268,7 +1269,7 @@ NTSTATUS ctdbd_traverse(uint32 db_id,
}
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0, ("packet_fd_read_sync failed: %s\n", nt_errstr(status)));
+ DEBUG(0, ("ctdb_packet_fd_read_sync failed: %s\n", nt_errstr(status)));
cluster_fatal("ctdbd died\n");
}
}
@@ -1357,6 +1358,11 @@ NTSTATUS ctdbd_register_ips(struct ctdbd_connection *conn,
}
conn->release_ip_handler = release_ip_handler;
+ /*
+ * store the IP address of the server socket for later
+ * comparison in release_ip()
+ */
+ conn->release_ip_priv = private_data;
/*
* We want to be told about IP releases
diff --git a/source3/lib/dbwrap.c b/source3/lib/dbwrap.c
index 4e7346c2c4..83fc40efac 100644
--- a/source3/lib/dbwrap.c
+++ b/source3/lib/dbwrap.c
@@ -21,6 +21,7 @@
#include "includes.h"
#include "dbwrap.h"
+#include "util_tdb.h"
#ifdef CLUSTER_SUPPORT
#include "ctdb_private.h"
#endif
@@ -156,63 +157,3 @@ struct db_context *db_open(TALLOC_CTX *mem_ctx,
return result;
}
-
-NTSTATUS dbwrap_delete(struct db_context *db, TDB_DATA key)
-{
- struct db_record *rec;
- NTSTATUS status;
-
- rec = db->fetch_locked(db, talloc_tos(), key);
- if (rec == NULL) {
- return NT_STATUS_NO_MEMORY;
- }
- status = rec->delete_rec(rec);
- TALLOC_FREE(rec);
- return status;
-}
-
-NTSTATUS dbwrap_store(struct db_context *db, TDB_DATA key,
- TDB_DATA data, int flags)
-{
- struct db_record *rec;
- NTSTATUS status;
-
- rec = db->fetch_locked(db, talloc_tos(), key);
- if (rec == NULL) {
- return NT_STATUS_NO_MEMORY;
- }
-
- status = rec->store(rec, data, flags);
- TALLOC_FREE(rec);
- return status;
-}
-
-TDB_DATA dbwrap_fetch(struct db_context *db, TALLOC_CTX *mem_ctx,
- TDB_DATA key)
-{
- TDB_DATA result;
-
- if (db->fetch(db, mem_ctx, key, &result) == -1) {
- return make_tdb_data(NULL, 0);
- }
-
- return result;
-}
-
-NTSTATUS dbwrap_delete_bystring(struct db_context *db, const char *key)
-{
- return dbwrap_delete(db, string_term_tdb_data(key));
-}
-
-NTSTATUS dbwrap_store_bystring(struct db_context *db, const char *key,
- TDB_DATA data, int flags)
-{
- return dbwrap_store(db, string_term_tdb_data(key), data, flags);
-}
-
-TDB_DATA dbwrap_fetch_bystring(struct db_context *db, TALLOC_CTX *mem_ctx,
- const char *key)
-{
- return dbwrap_fetch(db, mem_ctx, string_term_tdb_data(key));
-}
-
diff --git a/source3/lib/dbwrap_ctdb.c b/source3/lib/dbwrap_ctdb.c
index f9a7dd6a6f..255a673020 100644
--- a/source3/lib/dbwrap_ctdb.c
+++ b/source3/lib/dbwrap_ctdb.c
@@ -20,6 +20,8 @@
#include "includes.h"
#include "system/filesys.h"
+#include "lib/util/tdb_wrap.h"
+#include "util_tdb.h"
#ifdef CLUSTER_SUPPORT
#include "ctdb.h"
#include "ctdb_private.h"
@@ -89,7 +91,7 @@ static NTSTATUS db_ctdb_ltdb_fetch(struct db_ctdb_ctx *db,
TDB_DATA rec;
NTSTATUS status;
- rec = tdb_fetch(db->wtdb->tdb, key);
+ rec = tdb_fetch_compat(db->wtdb->tdb, key);
if (rec.dsize < sizeof(struct ctdb_ltdb_header)) {
status = NT_STATUS_NOT_FOUND;
if (data) {
@@ -537,7 +539,7 @@ static struct db_record *db_ctdb_fetch_locked_transaction(struct db_ctdb_ctx *ct
return result;
}
- ctdb_data = tdb_fetch(ctx->wtdb->tdb, key);
+ ctdb_data = tdb_fetch_compat(ctx->wtdb->tdb, key);
if (ctdb_data.dptr == NULL) {
/* create the record */
result->value = tdb_null;
@@ -623,7 +625,7 @@ static NTSTATUS db_ctdb_transaction_store(struct db_ctdb_transaction_handle *h,
if (!pull_newest_from_marshall_buffer(h->m_write, key, &header,
NULL, NULL)) {
- rec = tdb_fetch(h->ctx->wtdb->tdb, key);
+ rec = tdb_fetch_compat(h->ctx->wtdb->tdb, key);
if (rec.dptr != NULL) {
memcpy(&header, rec.dptr,
@@ -992,10 +994,7 @@ static int db_ctdb_record_destr(struct db_record* data)
hex_encode_talloc(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;
- }
+ tdb_chainunlock(crec->ctdb_ctx->wtdb->tdb, data->key);
threshold = lp_ctdb_locktime_warn_threshold();
if (threshold != 0) {
@@ -1023,7 +1022,7 @@ static struct db_record *fetch_locked_internal(struct db_ctdb_ctx *ctx,
return NULL;
}
- if (!(crec = TALLOC_ZERO_P(result, struct db_ctdb_rec))) {
+ if (!(crec = talloc_zero(result, struct db_ctdb_rec))) {
DEBUG(0, ("talloc failed\n"));
TALLOC_FREE(result);
return NULL;
@@ -1064,7 +1063,7 @@ again:
result->delete_rec = db_ctdb_delete;
talloc_set_destructor(result, db_ctdb_record_destr);
- ctdb_data = tdb_fetch(ctx->wtdb->tdb, key);
+ ctdb_data = tdb_fetch_compat(ctx->wtdb->tdb, key);
/*
* See if we have a valid record and we are the dmaster. If so, we can
@@ -1164,7 +1163,7 @@ static int db_ctdb_fetch(struct db_context *db, TALLOC_CTX *mem_ctx,
}
/* try a direct fetch */
- ctdb_data = tdb_fetch(ctx->wtdb->tdb, key);
+ ctdb_data = tdb_fetch_compat(ctx->wtdb->tdb, key);
/*
* See if we have a valid record and we are the dmaster. If so, we can
@@ -1363,13 +1362,13 @@ struct db_context *db_open_ctdb(TALLOC_CTX *mem_ctx,
return NULL;
}
- if (!(result = TALLOC_ZERO_P(mem_ctx, struct db_context))) {
+ if (!(result = talloc_zero(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))) {
+ if (!(db_ctdb = talloc(result, struct db_ctdb_ctx))) {
DEBUG(0, ("talloc failed\n"));
TALLOC_FREE(result);
return NULL;
diff --git a/source3/lib/dbwrap_file.c b/source3/lib/dbwrap_file.c
index 69ad8e4b20..6ecd72810d 100644
--- a/source3/lib/dbwrap_file.c
+++ b/source3/lib/dbwrap_file.c
@@ -80,12 +80,12 @@ static struct db_record *db_file_fetch_locked(struct db_context *db,
SMB_ASSERT(ctx->locked_record == NULL);
again:
- if (!(result = TALLOC_P(mem_ctx, struct db_record))) {
+ if (!(result = talloc(mem_ctx, struct db_record))) {
DEBUG(0, ("talloc failed\n"));
return NULL;
}
- if (!(file = TALLOC_P(result, struct db_locked_file))) {
+ if (!(file = talloc(result, struct db_locked_file))) {
DEBUG(0, ("talloc failed\n"));
TALLOC_FREE(result);
return NULL;
@@ -168,7 +168,7 @@ static struct db_record *db_file_fetch_locked(struct db_context *db,
if (statbuf.st_size != 0) {
result->value.dsize = statbuf.st_size;
- result->value.dptr = TALLOC_ARRAY(result, uint8,
+ result->value.dptr = talloc_array(result, uint8,
statbuf.st_size);
if (result->value.dptr == NULL) {
DEBUG(1, ("talloc failed\n"));
@@ -348,12 +348,12 @@ struct db_context *db_open_file(TALLOC_CTX *mem_ctx,
struct db_context *result = NULL;
struct db_file_ctx *ctx;
- if (!(result = TALLOC_ZERO_P(mem_ctx, struct db_context))) {
+ if (!(result = talloc_zero(mem_ctx, struct db_context))) {
DEBUG(0, ("talloc failed\n"));
return NULL;
}
- if (!(ctx = TALLOC_P(result, struct db_file_ctx))) {
+ if (!(ctx = talloc(result, struct db_file_ctx))) {
DEBUG(0, ("talloc failed\n"));
TALLOC_FREE(result);
return NULL;
diff --git a/source3/lib/dbwrap_rbt.c b/source3/lib/dbwrap_rbt.c
index af88c79e6a..fd6e988864 100644
--- a/source3/lib/dbwrap_rbt.c
+++ b/source3/lib/dbwrap_rbt.c
@@ -400,7 +400,7 @@ struct db_context *db_open_rbt(TALLOC_CTX *mem_ctx)
return NULL;
}
- result->private_data = TALLOC_ZERO_P(result, struct db_rbt_ctx);
+ result->private_data = talloc_zero(result, struct db_rbt_ctx);
if (result->private_data == NULL) {
TALLOC_FREE(result);
diff --git a/source3/lib/dbwrap_tdb.c b/source3/lib/dbwrap_tdb.c
index 4cdc1930ee..2efb3dfe39 100644
--- a/source3/lib/dbwrap_tdb.c
+++ b/source3/lib/dbwrap_tdb.c
@@ -19,6 +19,7 @@
#include "includes.h"
#include "dbwrap.h"
+#include "lib/util/tdb_wrap.h"
struct db_tdb_ctx {
struct tdb_wrap *wtdb;
@@ -42,10 +43,7 @@ static int db_tdb_record_destr(struct db_record* data)
hex_encode_talloc(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;
- }
+ tdb_chainunlock(ctx->wtdb->tdb, data->key);
return 0;
}
@@ -329,7 +327,8 @@ static int db_tdb_transaction_cancel(struct db_context *db)
{
struct db_tdb_ctx *db_ctx =
talloc_get_type_abort(db->private_data, struct db_tdb_ctx);
- return tdb_transaction_cancel(db_ctx->wtdb->tdb);
+ tdb_transaction_cancel(db_ctx->wtdb->tdb);
+ return 0;
}
struct db_context *db_open_tdb(TALLOC_CTX *mem_ctx,
@@ -340,13 +339,13 @@ struct db_context *db_open_tdb(TALLOC_CTX *mem_ctx,
struct db_context *result = NULL;
struct db_tdb_ctx *db_tdb;
- result = TALLOC_ZERO_P(mem_ctx, struct db_context);
+ result = talloc_zero(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);
+ result->private_data = db_tdb = talloc(result, struct db_tdb_ctx);
if (db_tdb == NULL) {
DEBUG(0, ("talloc failed\n"));
goto fail;
diff --git a/source3/lib/dbwrap_util.c b/source3/lib/dbwrap_util.c
index 35f8a14d0d..effcf40c6b 100644
--- a/source3/lib/dbwrap_util.c
+++ b/source3/lib/dbwrap_util.c
@@ -3,7 +3,10 @@
Utility functions for the dbwrap API
Copyright (C) Volker Lendecke 2007
Copyright (C) Michael Adam 2009
-
+ 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
@@ -21,6 +24,7 @@
#include "includes.h"
#include "dbwrap.h"
+#include "util_tdb.h"
int32_t dbwrap_fetch_int32(struct db_context *db, const char *keystr)
{
@@ -429,7 +433,7 @@ static NTSTATUS dbwrap_trans_traverse_action(struct db_context* db, void* privat
int ret = db->traverse(db, ctx->f, ctx->private_data);
- return (ret == -1) ? NT_STATUS_INTERNAL_DB_CORRUPTION : NT_STATUS_OK;
+ return (ret < 0) ? NT_STATUS_INTERNAL_DB_CORRUPTION : NT_STATUS_OK;
}
NTSTATUS dbwrap_trans_traverse(struct db_context *db,
@@ -448,9 +452,69 @@ NTSTATUS dbwrap_traverse(struct db_context *db,
void *private_data)
{
int ret = db->traverse(db, f, private_data);
- return (ret == -1) ? NT_STATUS_INTERNAL_DB_CORRUPTION : NT_STATUS_OK;
+ return (ret < 0) ? NT_STATUS_INTERNAL_DB_CORRUPTION : NT_STATUS_OK;
+}
+
+
+
+NTSTATUS dbwrap_delete(struct db_context *db, TDB_DATA key)
+{
+ struct db_record *rec;
+ NTSTATUS status;
+
+ rec = db->fetch_locked(db, talloc_tos(), key);
+ if (rec == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ status = rec->delete_rec(rec);
+ TALLOC_FREE(rec);
+ return status;
+}
+
+NTSTATUS dbwrap_store(struct db_context *db, TDB_DATA key,
+ TDB_DATA data, int flags)
+{
+ struct db_record *rec;
+ NTSTATUS status;
+
+ rec = db->fetch_locked(db, talloc_tos(), key);
+ if (rec == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ status = rec->store(rec, data, flags);
+ TALLOC_FREE(rec);
+ return status;
}
+TDB_DATA dbwrap_fetch(struct db_context *db, TALLOC_CTX *mem_ctx,
+ TDB_DATA key)
+{
+ TDB_DATA result;
+
+ if (db->fetch(db, mem_ctx, key, &result) != 0) {
+ return make_tdb_data(NULL, 0);
+ }
+
+ return result;
+}
+
+NTSTATUS dbwrap_delete_bystring(struct db_context *db, const char *key)
+{
+ return dbwrap_delete(db, string_term_tdb_data(key));
+}
+
+NTSTATUS dbwrap_store_bystring(struct db_context *db, const char *key,
+ TDB_DATA data, int flags)
+{
+ return dbwrap_store(db, string_term_tdb_data(key), data, flags);
+}
+
+TDB_DATA dbwrap_fetch_bystring(struct db_context *db, TALLOC_CTX *mem_ctx,
+ const char *key)
+{
+ return dbwrap_fetch(db, mem_ctx, string_term_tdb_data(key));
+}
diff --git a/source3/lib/dprintf.c b/source3/lib/dprintf.c
deleted file mode 100644
index ad3c79a8d5..0000000000
--- a/source3/lib/dprintf.c
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- display print functions
- 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 3 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, see <http://www.gnu.org/licenses/>.
-*/
-
-
-/*
- this module provides functions for printing internal strings in the "display charset"
- This charset may be quite different from the chosen unix charset
-
- Eventually these functions will need to take care of column count constraints
-
- The d_ prefix on print functions in Samba refers to the display character set
- conversion
-*/
-
-#include "includes.h"
-#include "intl/lang_tdb.h"
-
- int d_vfprintf(FILE *f, const char *format, va_list ap)
-{
- char *p = NULL, *p2 = NULL;
- int ret, maxlen, clen;
- size_t size = 0;
- const char *msgstr;
- va_list ap2;
-
- va_copy(ap2, ap);
-
- /* do any message translations */
- msgstr = lang_msg(format);
- if (!msgstr) {
- ret = -1;
- goto out;
- }
-
- ret = vasprintf(&p, msgstr, ap2);
-
- lang_msg_free(msgstr);
-
- if (ret <= 0) {
- ret = -1;
- goto out;
- }
-
- /* now we have the string in unix format, convert it to the display
- charset, but beware of it growing */
- maxlen = ret*2;
-again:
- p2 = (char *)SMB_MALLOC(maxlen);
- if (!p2) {
- ret = -1;
- goto out;
- }
-
- if (!convert_string(CH_UNIX, CH_DISPLAY, p, ret, p2, maxlen, &size)) {
- ret = -1;
- goto out;
- }
- clen = size;
-
- if (clen >= maxlen) {
- /* it didn't fit - try a larger buffer */
- maxlen *= 2;
- SAFE_FREE(p2);
- goto again;
- }
-
- /* good, its converted OK */
- ret = fwrite(p2, 1, clen, f);
-out:
-
- SAFE_FREE(p);
- SAFE_FREE(p2);
- va_end(ap2);
-
- return ret;
-}
-
-
- int d_fprintf(FILE *f, const char *format, ...)
-{
- int ret;
- va_list ap;
-
- va_start(ap, format);
- ret = d_vfprintf(f, format, ap);
- va_end(ap);
-
- return ret;
-}
-
-static FILE *outfile;
-
- int d_printf(const char *format, ...)
-{
- int ret;
- va_list ap;
-
- if (!outfile) outfile = stdout;
-
- va_start(ap, format);
- ret = d_vfprintf(outfile, format, ap);
- va_end(ap);
-
- return ret;
-}
-
-/* interactive programs need a way of tell d_*() to write to stderr instead
- of stdout */
-void display_set_stderr(void)
-{
- outfile = stderr;
-}
diff --git a/source3/lib/dummyroot.c b/source3/lib/dummyparam.c
index 64ea75814a..bad5d56ffc 100644
--- a/source3/lib/dummyroot.c
+++ b/source3/lib/dummyparam.c
@@ -1,19 +1,19 @@
-/*
+/*
Unix SMB/CIFS implementation.
RPC pipe client
- Copyright (C) Tim Potter 2003
+ Copyright (C) Gerald (Jerry) Carter 2004.
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 3 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, see <http://www.gnu.org/licenses/>.
*/
@@ -23,12 +23,13 @@
#include "includes.h"
-void become_root(void)
+int find_service(TALLOC_CTX *ctx, const char *service_in, char **p_service_out)
{
- return;
+ return -1;
}
-void unbecome_root(void)
+bool conn_snum_used(struct smbd_server_connection *sconn,
+ int snum)
{
- return;
+ return False;
}
diff --git a/source3/lib/errmap_unix.c b/source3/lib/errmap_unix.c
index b4a98f9634..ea195474ef 100644
--- a/source3/lib/errmap_unix.c
+++ b/source3/lib/errmap_unix.c
@@ -24,91 +24,93 @@
/* 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_PARAMETER },
- { 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 },
- { ENOSYS, ERRDOS, ERRunsup, NT_STATUS_NOT_SUPPORTED },
+static const struct {
+ int unix_error;
+ NTSTATUS nt_error;
+} unix_nt_errmap[] = {
+ { EAGAIN, NT_STATUS_NETWORK_BUSY },
+ { EINTR, NT_STATUS_RETRY },
+#ifdef ENOBUFS
+ { ENOBUFS, NT_STATUS_INSUFFICIENT_RESOURCES },
+#endif
+#ifdef EWOULDBLOCK
+ { EWOULDBLOCK, NT_STATUS_NETWORK_BUSY },
+#endif
+ { EPERM, NT_STATUS_ACCESS_DENIED },
+ { EACCES, NT_STATUS_ACCESS_DENIED },
+ { ENOENT, NT_STATUS_OBJECT_NAME_NOT_FOUND },
+ { ENOTDIR, NT_STATUS_NOT_A_DIRECTORY },
+ { EIO, NT_STATUS_IO_DEVICE_ERROR },
+ { EBADF, NT_STATUS_INVALID_HANDLE },
+ { EINVAL, NT_STATUS_INVALID_PARAMETER },
+ { EEXIST, NT_STATUS_OBJECT_NAME_COLLISION},
+ { ENFILE, NT_STATUS_TOO_MANY_OPENED_FILES },
+ { EMFILE, NT_STATUS_TOO_MANY_OPENED_FILES },
+ { ENOSPC, NT_STATUS_DISK_FULL },
+ { ENOMEM, NT_STATUS_NO_MEMORY },
+ { EISDIR, NT_STATUS_FILE_IS_A_DIRECTORY},
+#ifdef EPIPE
+ { EPIPE, NT_STATUS_PIPE_BROKEN},
+#endif
+ { EMLINK, NT_STATUS_TOO_MANY_LINKS },
+ { ENOSYS, NT_STATUS_NOT_SUPPORTED },
#ifdef ELOOP
- { ELOOP, ERRDOS, ERRbadpath, NT_STATUS_OBJECT_PATH_NOT_FOUND },
+ { ELOOP, NT_STATUS_OBJECT_PATH_NOT_FOUND },
#endif
#ifdef EFTYPE
- { EFTYPE, ERRDOS, ERRbadpath, NT_STATUS_OBJECT_PATH_NOT_FOUND },
+ { EFTYPE, NT_STATUS_OBJECT_PATH_NOT_FOUND },
#endif
#ifdef EDQUOT
- { EDQUOT, ERRHRD, ERRdiskfull, NT_STATUS_DISK_FULL }, /* Windows apps need this, not NT_STATUS_QUOTA_EXCEEDED */
+ { EDQUOT, NT_STATUS_DISK_FULL }, /* Windows apps need this, not NT_STATUS_QUOTA_EXCEEDED */
#endif
#ifdef ENOTEMPTY
- { ENOTEMPTY, ERRDOS, ERRnoaccess, NT_STATUS_DIRECTORY_NOT_EMPTY },
+ { ENOTEMPTY, NT_STATUS_DIRECTORY_NOT_EMPTY },
#endif
#ifdef EXDEV
- { EXDEV, ERRDOS, ERRdiffdevice, NT_STATUS_NOT_SAME_DEVICE },
+ { EXDEV, NT_STATUS_NOT_SAME_DEVICE },
#endif
#ifdef EROFS
- { EROFS, ERRHRD, ERRnowrite, NT_STATUS_ACCESS_DENIED },
+ { EROFS, NT_STATUS_ACCESS_DENIED },
#endif
#ifdef ENAMETOOLONG
- { ENAMETOOLONG, ERRDOS, 206, NT_STATUS_OBJECT_NAME_INVALID },
+ { ENAMETOOLONG, 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 },
+ { EFBIG, NT_STATUS_DISK_FULL },
#endif
- { EAGAIN, ERRDOS, 111, NT_STATUS_NETWORK_BUSY },
#ifdef EADDRINUSE
- { EADDRINUSE, ERRDOS, 52, NT_STATUS_ADDRESS_ALREADY_ASSOCIATED},
+ { EADDRINUSE, NT_STATUS_ADDRESS_ALREADY_ASSOCIATED},
#endif
#ifdef ENETUNREACH
- { ENETUNREACH, ERRHRD, ERRgeneral, NT_STATUS_NETWORK_UNREACHABLE},
+ { ENETUNREACH, NT_STATUS_NETWORK_UNREACHABLE},
#endif
#ifdef EHOSTUNREACH
- { EHOSTUNREACH, ERRHRD, ERRgeneral, NT_STATUS_HOST_UNREACHABLE},
+ { EHOSTUNREACH, NT_STATUS_HOST_UNREACHABLE},
#endif
#ifdef ECONNREFUSED
- { ECONNREFUSED, ERRHRD, ERRgeneral, NT_STATUS_CONNECTION_REFUSED},
+ { ECONNREFUSED, NT_STATUS_CONNECTION_REFUSED},
#endif
#ifdef ETIMEDOUT
- { ETIMEDOUT, ERRHRD, 121, NT_STATUS_IO_TIMEOUT},
+ { ETIMEDOUT, NT_STATUS_IO_TIMEOUT},
#endif
#ifdef ECONNABORTED
- { ECONNABORTED, ERRHRD, ERRgeneral, NT_STATUS_CONNECTION_ABORTED},
+ { ECONNABORTED, NT_STATUS_CONNECTION_ABORTED},
#endif
#ifdef ECONNRESET
- { ECONNRESET, ERRHRD, ERRgeneral, NT_STATUS_CONNECTION_RESET},
+ { ECONNRESET, NT_STATUS_CONNECTION_RESET},
#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 },
+ { ENODEV, NT_STATUS_DEVICE_DOES_NOT_EXIST},
#endif
#ifdef ENOATTR
- { ENOATTR, ERRDOS, ERRbadfile, NT_STATUS_NOT_FOUND },
+ { ENOATTR, NT_STATUS_NOT_FOUND },
#endif
#ifdef ECANCELED
- { ECANCELED, ERRDOS, ERRbadfid, NT_STATUS_CANCELLED},
+ { ECANCELED, NT_STATUS_CANCELLED},
#endif
#ifdef ENOTSUP
- { ENOTSUP, ERRSRV, ERRnosupport, NT_STATUS_NOT_SUPPORTED},
+ { ENOTSUP, NT_STATUS_NOT_SUPPORTED},
#endif
- { 0, 0, 0, NT_STATUS_OK }
};
/*********************************************************************
@@ -131,22 +133,16 @@ NTSTATUS map_nt_error_from_unix(int unix_error)
}
/* 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++;
+ for (i=0;i<ARRAY_SIZE(unix_nt_errmap);i++) {
+ if (unix_nt_errmap[i].unix_error == unix_error) {
+ return unix_nt_errmap[i].nt_error;
+ }
}
/* Default return */
return NT_STATUS_ACCESS_DENIED;
}
-/* Convert a Unix error code to a WERROR. */
-WERROR unix_to_werror(int unix_error)
-{
- return ntstatus_to_werror(map_nt_error_from_unix(unix_error));
-}
-
/* Return a UNIX errno from a NT status code */
static const struct {
NTSTATUS status;
@@ -257,7 +253,6 @@ static const struct {
#ifdef EXDEV
{NT_STATUS_NOT_SAME_DEVICE, EXDEV},
#endif
- {NT_STATUS(0), 0}
};
int map_errno_from_nt_status(NTSTATUS status)
@@ -272,7 +267,7 @@ int map_errno_from_nt_status(NTSTATUS status)
return 0;
}
- for (i=0;nt_errno_map[i].error;i++) {
+ for (i=0;i<ARRAY_SIZE(nt_errno_map);i++) {
if (NT_STATUS_V(nt_errno_map[i].status) ==
NT_STATUS_V(status)) {
return nt_errno_map[i].error;
diff --git a/source3/lib/eventlog/eventlog.c b/source3/lib/eventlog/eventlog.c
index 4941199c5e..67583b8666 100644
--- a/source3/lib/eventlog/eventlog.c
+++ b/source3/lib/eventlog/eventlog.c
@@ -24,6 +24,7 @@
#include "system/filesys.h"
#include "lib/eventlog/eventlog.h"
#include "../libcli/security/security.h"
+#include "util_tdb.h"
/* maintain a list of open eventlog tdbs with reference counts */
@@ -202,7 +203,7 @@ static bool make_way_for_eventlogs( TDB_CONTEXT * the_tdb, int32_t needed,
/* read a record, add the amt to nbytes */
key.dsize = sizeof(int32_t);
key.dptr = (unsigned char *)&i;
- ret = tdb_fetch( the_tdb, key );
+ ret = tdb_fetch_compat( the_tdb, key );
if ( ret.dsize == 0 ) {
DEBUG( 8,
( "Can't find a record for the key, record [%d]\n",
@@ -415,7 +416,7 @@ ELOG_TDB *elog_open_tdb( const char *logname, bool force_clear, bool read_only )
return ptr;
}
- if ( !(tdb_node = TALLOC_ZERO_P( NULL, ELOG_TDB)) ) {
+ if ( !(tdb_node = talloc_zero( NULL, ELOG_TDB)) ) {
DEBUG(0,("elog_open_tdb: talloc() failure!\n"));
tdb_close( tdb );
return NULL;
@@ -678,7 +679,7 @@ struct eventlog_Record_tdb *evlog_pull_record_tdb(TALLOC_CTX *mem_ctx,
key.dptr = (unsigned char *)&srecno;
key.dsize = sizeof(int32_t);
- data = tdb_fetch(tdb, key);
+ data = tdb_fetch_compat(tdb, key);
if (data.dsize == 0) {
DEBUG(8,("evlog_pull_record_tdb: "
"Can't find a record for the key, record %d\n",
@@ -780,7 +781,7 @@ NTSTATUS evlog_push_record_tdb(TALLOC_CTX *mem_ctx,
/* lock */
ret = tdb_lock_bystring_with_timeout(tdb, EVT_NEXT_RECORD, 1);
- if (ret == -1) {
+ if (ret != 0) {
return NT_STATUS_LOCK_NOT_GRANTED;
}
@@ -803,13 +804,13 @@ NTSTATUS evlog_push_record_tdb(TALLOC_CTX *mem_ctx,
ebuf.dptr = blob.data;
ret = tdb_store(tdb, kbuf, ebuf, 0);
- if (ret == -1) {
+ if (ret != 0) {
tdb_unlock_bystring(tdb, EVT_NEXT_RECORD);
return NT_STATUS_EVENTLOG_FILE_CORRUPT;
}
ret = tdb_store_int32(tdb, EVT_NEXT_RECORD, r->record_number + 1);
- if (ret == -1) {
+ if (ret != 0) {
tdb_unlock_bystring(tdb, EVT_NEXT_RECORD);
return NT_STATUS_EVENTLOG_FILE_CORRUPT;
}
diff --git a/source3/lib/eventlog/eventlog.h b/source3/lib/eventlog/eventlog.h
index 29c25c3122..694732d184 100644
--- a/source3/lib/eventlog/eventlog.h
+++ b/source3/lib/eventlog/eventlog.h
@@ -17,6 +17,8 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "tdb_compat.h"
+
/* Defines for TDB keys */
#define EVT_OLDEST_ENTRY "INFO/oldest_entry"
#define EVT_NEXT_RECORD "INFO/next_record"
diff --git a/source3/lib/eventlog/proto.h b/source3/lib/eventlog/proto.h
index 21790d0795..d3341ce16d 100644
--- a/source3/lib/eventlog/proto.h
+++ b/source3/lib/eventlog/proto.h
@@ -1,3 +1,28 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Eventlog utility routines
+ *
+ * Copyright (C) Marcin Krzysztof Porwit 2005
+ * Copyright (C) Brian Moran 2005
+ * Copyright (C) Gerald (Jerry) Carter 2005
+ * Copyright (C) Guenther Deschner 2009
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _LIB_EVENTLOG_PROTO_H_
+#define _LIB_EVENTLOG_PROTO_H_
/* The following definitions come from lib/eventlog/eventlog.c */
@@ -33,3 +58,5 @@ NTSTATUS evlog_convert_tdb_to_evt(TALLOC_CTX *mem_ctx,
ELOG_TDB *etdb,
DATA_BLOB *blob_p,
uint32_t *num_records_p);
+
+#endif /* _LIB_EVENTLOG_PROTO_H_ */
diff --git a/source3/lib/events.c b/source3/lib/events.c
index e461ebe977..f077f58581 100644
--- a/source3/lib/events.c
+++ b/source3/lib/events.c
@@ -19,7 +19,7 @@
*/
#include "includes.h"
-#include <tevent_internal.h>
+#include "lib/tevent/tevent_internal.h"
#include "../lib/util/select.h"
#include "system/select.h"
@@ -42,7 +42,7 @@ static struct tevent_poll_private *tevent_get_poll_private(
state = (struct tevent_poll_private *)ev->additional_data;
if (state == NULL) {
- state = TALLOC_ZERO_P(ev, struct tevent_poll_private);
+ state = talloc_zero(ev, struct tevent_poll_private);
ev->additional_data = (void *)state;
if (state == NULL) {
DEBUG(10, ("talloc failed\n"));
@@ -90,7 +90,7 @@ bool event_add_to_poll_args(struct tevent_context *ev, TALLOC_CTX *mem_ctx,
idx_len = max_fd+1;
if (talloc_array_length(state->pollfd_idx) < idx_len) {
- state->pollfd_idx = TALLOC_REALLOC_ARRAY(
+ state->pollfd_idx = talloc_realloc(
state, state->pollfd_idx, int, idx_len);
if (state->pollfd_idx == NULL) {
DEBUG(10, ("talloc_realloc failed\n"));
@@ -107,7 +107,7 @@ bool event_add_to_poll_args(struct tevent_context *ev, TALLOC_CTX *mem_ctx,
*/
if (talloc_array_length(fds) < num_pollfds + num_fds + 1) {
- fds = TALLOC_REALLOC_ARRAY(mem_ctx, fds, struct pollfd,
+ fds = talloc_realloc(mem_ctx, fds, struct pollfd,
num_pollfds + num_fds + 1);
if (fds == NULL) {
DEBUG(10, ("talloc_realloc failed\n"));
@@ -258,7 +258,20 @@ bool run_events_poll(struct tevent_context *ev, int pollrtn,
return false;
}
- if (pfd->revents & (POLLIN|POLLHUP|POLLERR)) {
+ if (pfd->revents & (POLLHUP|POLLERR)) {
+ /* If we only wait for EVENT_FD_WRITE, we
+ should not tell the event handler about it,
+ and remove the writable flag, as we only
+ report errors when waiting for read events
+ to match the select behavior. */
+ if (!(fde->flags & EVENT_FD_READ)) {
+ EVENT_FD_NOT_WRITEABLE(fde);
+ continue;
+ }
+ flags |= EVENT_FD_READ;
+ }
+
+ if (pfd->revents & POLLIN) {
flags |= EVENT_FD_READ;
}
if (pfd->revents & POLLOUT) {
diff --git a/source3/lib/filename_util.c b/source3/lib/filename_util.c
index f12ca2d781..2405183d53 100644
--- a/source3/lib/filename_util.c
+++ b/source3/lib/filename_util.c
@@ -17,7 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
-#include "smbd/smbd.h"
/**
* XXX: This is temporary and there should be no callers of this outside of
@@ -61,8 +60,8 @@ NTSTATUS create_synthetic_smb_fname(TALLOC_CTX *ctx, const char *base_name,
ZERO_STRUCT(smb_fname_loc);
/* Setup the base_name/stream_name. */
- smb_fname_loc.base_name = CONST_DISCARD(char *, base_name);
- smb_fname_loc.stream_name = CONST_DISCARD(char *, stream_name);
+ smb_fname_loc.base_name = discard_const_p(char, base_name);
+ smb_fname_loc.stream_name = discard_const_p(char, stream_name);
/* Copy the psbuf if one was given. */
if (psbuf)
@@ -203,5 +202,5 @@ bool is_ntfs_default_stream_smb_fname(const struct smb_filename *smb_fname)
return false;
}
- return StrCaseCmp(smb_fname->stream_name, "::$DATA") == 0;
+ return strcasecmp_m(smb_fname->stream_name, "::$DATA") == 0;
}
diff --git a/source3/lib/fncall.c b/source3/lib/fncall.c
index e810b6814e..6e6b7c9250 100644
--- a/source3/lib/fncall.c
+++ b/source3/lib/fncall.c
@@ -18,10 +18,11 @@
*/
#include "includes.h"
+#include "../lib/util/tevent_unix.h"
#if WITH_PTHREADPOOL
-#include "pthreadpool.h"
+#include "lib/pthreadpool/pthreadpool.h"
struct fncall_state {
struct fncall_context *ctx;
@@ -86,7 +87,7 @@ struct fncall_context *fncall_context_init(TALLOC_CTX *mem_ctx,
}
talloc_set_destructor(ctx, fncall_context_destructor);
- ctx->sig_fd = pthreadpool_sig_fd(ctx->pool);
+ ctx->sig_fd = pthreadpool_signal_fd(ctx->pool);
if (ctx->sig_fd == -1) {
TALLOC_FREE(ctx);
return NULL;
@@ -265,7 +266,7 @@ struct tevent_req *fncall_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
return tevent_req_post(req, ev);
}
if (!fncall_set_pending(req, state->ctx, ev)) {
- tevent_req_nomem(NULL, req);
+ tevent_req_oom(req);
return tevent_req_post(req, ev);
}
return req;
diff --git a/source3/lib/g_lock.c b/source3/lib/g_lock.c
index 184da9b4fd..006ee3698c 100644
--- a/source3/lib/g_lock.c
+++ b/source3/lib/g_lock.c
@@ -20,6 +20,7 @@
#include "includes.h"
#include "system/filesys.h"
#include "g_lock.h"
+#include "util_tdb.h"
#include "ctdbd_conn.h"
#include "../lib/util/select.h"
#include "system/select.h"
@@ -107,7 +108,7 @@ static bool g_lock_parse(TALLOC_CTX *mem_ctx, TDB_DATA data,
DEBUG(10, ("locks:\n"));
for (i=0; i<num_locks; i++) {
DEBUGADD(10, ("%s: %s %s\n",
- procid_str(talloc_tos(), &locks[i].pid),
+ server_id_str(talloc_tos(), &locks[i].pid),
((locks[i].lock_type & 1) == G_LOCK_READ) ?
"read" : "write",
(locks[i].lock_type & G_LOCK_PENDING) ?
@@ -117,7 +118,7 @@ static bool g_lock_parse(TALLOC_CTX *mem_ctx, TDB_DATA data,
&& !process_exists(locks[i].pid)) {
DEBUGADD(10, ("lock owner %s died -- discarding\n",
- procid_str(talloc_tos(),
+ server_id_str(talloc_tos(),
&locks[i].pid)));
if (i < (num_locks-1)) {
@@ -145,7 +146,7 @@ static void g_lock_cleanup(int *pnum_locks, struct g_lock_rec *locks)
continue;
}
DEBUGADD(10, ("%s does not exist -- discarding\n",
- procid_str(talloc_tos(), &locks[i].pid)));
+ server_id_str(talloc_tos(), &locks[i].pid)));
if (i < (num_locks-1)) {
locks[i] = locks[num_locks-1];
@@ -392,7 +393,7 @@ NTSTATUS g_lock_lock(struct g_lock_ctx *ctx, const char *name,
* sys_poll and in the clustering case we might have to add
* the ctdb fd. This avoids the realloc then.
*/
- pollfds = TALLOC_ARRAY(talloc_tos(), struct pollfd, 2);
+ pollfds = talloc_array(talloc_tos(), struct pollfd, 2);
if (pollfds == NULL) {
status = NT_STATUS_NO_MEMORY;
break;
@@ -495,7 +496,7 @@ static void g_lock_got_retry(struct messaging_context *msg,
bool *pretry = (bool *)private_data;
DEBUG(10, ("Got retry message from pid %s\n",
- procid_str(talloc_tos(), &server_id)));
+ server_id_str(talloc_tos(), &server_id)));
*pretry = true;
}
@@ -586,7 +587,7 @@ static NTSTATUS g_lock_force_unlock(struct g_lock_ctx *ctx, const char *name,
&data_blob_null);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("sending retry to %s failed: %s\n",
- procid_str(talloc_tos(),
+ server_id_str(talloc_tos(),
&locks[i].pid),
nt_errstr(status)));
} else {
diff --git a/source3/lib/gencache.c b/source3/lib/gencache.c
index 67c37f34e7..31ead7be7e 100644
--- a/source3/lib/gencache.c
+++ b/source3/lib/gencache.c
@@ -24,6 +24,7 @@
#include "includes.h"
#include "system/filesys.h"
#include "system/glob.h"
+#include "util_tdb.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_TDB
@@ -80,14 +81,10 @@ again:
return false;
}
first_try = false;
- DEBUG(0, ("gencache_init: tdb_check(%s) failed - retry after CLEAR_IF_FIRST\n",
+ DEBUG(0, ("gencache_init: tdb_check(%s) failed - retry after truncate\n",
cache_fname));
- cache = tdb_open_log(cache_fname, 0, TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH, open_flags, 0644);
- if (cache) {
- tdb_close(cache);
- cache = NULL;
- goto again;
- }
+ truncate(cache_fname, 0);
+ goto again;
}
}
@@ -125,7 +122,7 @@ again:
static TDB_DATA last_stabilize_key(void)
{
TDB_DATA result;
- result.dptr = (uint8_t *)"@LAST_STABILIZED";
+ result.dptr = discard_const_p(uint8_t, "@LAST_STABILIZED");
result.dsize = 17;
return result;
}
@@ -209,7 +206,7 @@ bool gencache_set_data_blob(const char *keystr, const DATA_BLOB *blob,
*/
last_stabilize = 0;
- databuf = tdb_fetch(cache_notrans, last_stabilize_key());
+ databuf = tdb_fetch_compat(cache_notrans, last_stabilize_key());
if ((databuf.dptr != NULL)
&& (databuf.dptr[databuf.dsize-1] == '\0')) {
last_stabilize = atoi((char *)databuf.dptr);
@@ -347,11 +344,11 @@ bool gencache_parse(const char *keystr,
state.private_data = private_data;
ret = tdb_parse_record(cache_notrans, key, gencache_parse_fn, &state);
- if (ret != -1) {
+ if (ret == 0) {
return true;
}
ret = tdb_parse_record(cache, key, gencache_parse_fn, &state);
- return (ret != -1);
+ return (ret == 0);
}
struct gencache_get_data_blob_state {
@@ -464,9 +461,14 @@ bool gencache_stabilize(void)
}
res = tdb_transaction_start_nonblock(cache);
- if (res == -1) {
-
- if (tdb_error(cache) == TDB_ERR_NOLOCK) {
+ if (res != 0) {
+
+#if BUILD_TDB2
+ if (res == TDB_ERR_LOCK)
+#else
+ if (tdb_error(cache) == TDB_ERR_NOLOCK)
+#endif
+ {
/*
* Someone else already does the stabilize,
* this does not have to be done twice
@@ -475,15 +477,15 @@ bool gencache_stabilize(void)
}
DEBUG(10, ("Could not start transaction on gencache.tdb: "
- "%s\n", tdb_errorstr(cache)));
+ "%s\n", tdb_errorstr_compat(cache)));
return false;
}
res = tdb_transaction_start(cache_notrans);
- if (res == -1) {
+ if (res != 0) {
tdb_transaction_cancel(cache);
DEBUG(10, ("Could not start transaction on "
"gencache_notrans.tdb: %s\n",
- tdb_errorstr(cache_notrans)));
+ tdb_errorstr_compat(cache_notrans)));
return false;
}
@@ -491,36 +493,30 @@ bool gencache_stabilize(void)
state.written = false;
res = tdb_traverse(cache_notrans, stabilize_fn, &state);
- if ((res == -1) || state.error) {
- if ((tdb_transaction_cancel(cache_notrans) == -1)
- || (tdb_transaction_cancel(cache) == -1)) {
- smb_panic("tdb_transaction_cancel failed\n");
- }
+ if ((res < 0) || state.error) {
+ tdb_transaction_cancel(cache_notrans);
+ tdb_transaction_cancel(cache);
return false;
}
if (!state.written) {
- if ((tdb_transaction_cancel(cache_notrans) == -1)
- || (tdb_transaction_cancel(cache) == -1)) {
- smb_panic("tdb_transaction_cancel failed\n");
- }
+ tdb_transaction_cancel(cache_notrans);
+ tdb_transaction_cancel(cache);
return true;
}
res = tdb_transaction_commit(cache);
- if (res == -1) {
+ if (res != 0) {
DEBUG(10, ("tdb_transaction_commit on gencache.tdb failed: "
- "%s\n", tdb_errorstr(cache)));
- if (tdb_transaction_cancel(cache_notrans) == -1) {
- smb_panic("tdb_transaction_cancel failed\n");
- }
+ "%s\n", tdb_errorstr_compat(cache)));
+ tdb_transaction_cancel(cache_notrans);
return false;
}
res = tdb_transaction_commit(cache_notrans);
- if (res == -1) {
+ if (res != 0) {
DEBUG(10, ("tdb_transaction_commit on gencache.tdb failed: "
- "%s\n", tdb_errorstr(cache)));
+ "%s\n", tdb_errorstr_compat(cache)));
return false;
}
@@ -551,7 +547,7 @@ static int stabilize_fn(struct tdb_context *tdb, TDB_DATA key, TDB_DATA val,
}
if ((timeout < time(NULL)) || (val.dsize == 0)) {
res = tdb_delete(cache, key);
- if ((res == -1) && (tdb_error(cache) == TDB_ERR_NOEXIST)) {
+ if ((res != 0) && (tdb_error(cache) == TDB_ERR_NOEXIST)) {
res = 0;
} else {
state->written = true;
@@ -563,16 +559,16 @@ static int stabilize_fn(struct tdb_context *tdb, TDB_DATA key, TDB_DATA val,
}
}
- if (res == -1) {
+ if (res != 0) {
DEBUG(10, ("Transfer to gencache.tdb failed: %s\n",
- tdb_errorstr(cache)));
+ tdb_errorstr_compat(cache)));
state->error = true;
return -1;
}
- if (tdb_delete(cache_notrans, key) == -1) {
+ if (tdb_delete(cache_notrans, key) != 0) {
DEBUG(10, ("tdb_delete from gencache_notrans.tdb failed: "
- "%s\n", tdb_errorstr(cache_notrans)));
+ "%s\n", tdb_errorstr_compat(cache_notrans)));
state->error = true;
return -1;
}
diff --git a/source3/lib/idmap_cache.h b/source3/lib/idmap_cache.h
index af2ba82bf8..1a62dba64f 100644
--- a/source3/lib/idmap_cache.h
+++ b/source3/lib/idmap_cache.h
@@ -1,3 +1,26 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * ID Mapping Cache
+ *
+ * Copyright (C) Volker Lendecke 2008
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _LIB_IDMAP_CACHE_H_
+#define _LIB_IDMAP_CACHE_H_
+
/* The following definitions come from lib/idmap_cache.c */
bool idmap_cache_find_sid2uid(const struct dom_sid *sid, uid_t *puid,
@@ -12,3 +35,5 @@ void idmap_cache_set_sid2gid(const struct dom_sid *sid, gid_t gid);
bool idmap_cache_del_uid(uid_t uid);
bool idmap_cache_del_gid(gid_t gid);
bool idmap_cache_del_sid(const struct dom_sid *sid);
+
+#endif /* _LIB_IDMAP_CACHE_H_ */
diff --git a/source3/lib/interface.c b/source3/lib/interface.c
index 30e94069a5..39dc9cb04c 100644
--- a/source3/lib/interface.c
+++ b/source3/lib/interface.c
@@ -19,7 +19,7 @@
*/
#include "includes.h"
-#include "interfaces.h"
+#include "lib/socket/interfaces.h"
static struct iface_struct *probed_ifaces;
static int total_probed;
@@ -305,7 +305,7 @@ static void add_interface(const struct iface_struct *ifs)
char addr[INET6_ADDRSTRLEN];
struct interface *iface;
- if (iface_find((struct sockaddr *)&ifs->ip, False)) {
+ if (iface_find((const struct sockaddr *)&ifs->ip, False)) {
DEBUG(3,("add_interface: not adding duplicate interface %s\n",
print_sockaddr(addr, sizeof(addr), &ifs->ip) ));
return;
diff --git a/source3/lib/interfaces.c b/source3/lib/interfaces.c
deleted file mode 100644
index e40eaa9142..0000000000
--- a/source3/lib/interfaces.c
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- return a list of network interfaces
- Copyright (C) Andrew Tridgell 1998
- 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 3 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, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "includes.h"
-#include "interfaces.h"
-
-/****************************************************************************
- Create a struct sockaddr_storage with the netmask bits set to 1.
-****************************************************************************/
-
-bool make_netmask(struct sockaddr_storage *pss_out,
- const struct sockaddr_storage *pss_in,
- unsigned long masklen)
-{
- *pss_out = *pss_in;
- /* Now apply masklen bits of mask. */
-#if defined(HAVE_IPV6)
- if (pss_in->ss_family == AF_INET6) {
- char *p = (char *)&((struct sockaddr_in6 *)pss_out)->sin6_addr;
- unsigned int i;
-
- if (masklen > 128) {
- return false;
- }
- for (i = 0; masklen >= 8; masklen -= 8, i++) {
- *p++ = 0xff;
- }
- /* Deal with the partial byte. */
- *p++ &= (0xff & ~(0xff>>masklen));
- i++;
- for (;i < sizeof(struct in6_addr); i++) {
- *p++ = '\0';
- }
- return true;
- }
-#endif
- if (pss_in->ss_family == AF_INET) {
- if (masklen > 32) {
- return false;
- }
- ((struct sockaddr_in *)pss_out)->sin_addr.s_addr =
- htonl(((0xFFFFFFFFL >> masklen) ^ 0xFFFFFFFFL));
- return true;
- }
- return false;
-}
-
-/****************************************************************************
- Create a struct sockaddr_storage set to the broadcast or network adress from
- an incoming sockaddr_storage.
-****************************************************************************/
-
-static void make_bcast_or_net(struct sockaddr_storage *pss_out,
- const struct sockaddr_storage *pss_in,
- const struct sockaddr_storage *nmask,
- bool make_bcast_p)
-{
- unsigned int i = 0, len = 0;
- char *pmask = NULL;
- char *p = NULL;
- *pss_out = *pss_in;
-
- /* Set all zero netmask bits to 1. */
-#if defined(HAVE_IPV6)
- if (pss_in->ss_family == AF_INET6) {
- p = (char *)&((struct sockaddr_in6 *)pss_out)->sin6_addr;
- pmask = (char *)&((struct sockaddr_in6 *)nmask)->sin6_addr;
- len = 16;
- }
-#endif
- if (pss_in->ss_family == AF_INET) {
- p = (char *)&((struct sockaddr_in *)pss_out)->sin_addr;
- pmask = (char *)&((struct sockaddr_in *)nmask)->sin_addr;
- len = 4;
- }
-
- for (i = 0; i < len; i++, p++, pmask++) {
- if (make_bcast_p) {
- *p = (*p & *pmask) | (*pmask ^ 0xff);
- } else {
- /* make_net */
- *p = (*p & *pmask);
- }
- }
-}
-
-void make_bcast(struct sockaddr_storage *pss_out,
- const struct sockaddr_storage *pss_in,
- const struct sockaddr_storage *nmask)
-{
- make_bcast_or_net(pss_out, pss_in, nmask, true);
-}
-
-void make_net(struct sockaddr_storage *pss_out,
- const struct sockaddr_storage *pss_in,
- const struct sockaddr_storage *nmask)
-{
- make_bcast_or_net(pss_out, pss_in, nmask, false);
-}
-
-/****************************************************************************
- Try the "standard" getifaddrs/freeifaddrs interfaces.
- Also gets IPv6 interfaces.
-****************************************************************************/
-
-/****************************************************************************
- Get the netmask address for a local interface.
-****************************************************************************/
-
-static int _get_interfaces(TALLOC_CTX *mem_ctx, struct iface_struct **pifaces)
-{
- struct iface_struct *ifaces;
- struct ifaddrs *iflist = NULL;
- struct ifaddrs *ifptr = NULL;
- int count;
- int total = 0;
- size_t copy_size;
-
- if (getifaddrs(&iflist) < 0) {
- return -1;
- }
-
- count = 0;
- for (ifptr = iflist; ifptr != NULL; ifptr = ifptr->ifa_next) {
- if (!ifptr->ifa_addr || !ifptr->ifa_netmask) {
- continue;
- }
- if (!(ifptr->ifa_flags & IFF_UP)) {
- continue;
- }
- count += 1;
- }
-
- ifaces = talloc_array(mem_ctx, struct iface_struct, count);
- if (ifaces == NULL) {
- errno = ENOMEM;
- return -1;
- }
-
- /* Loop through interfaces, looking for given IP address */
- for (ifptr = iflist; ifptr != NULL; ifptr = ifptr->ifa_next) {
-
- if (!ifptr->ifa_addr || !ifptr->ifa_netmask) {
- continue;
- }
-
- /* Check the interface is up. */
- if (!(ifptr->ifa_flags & IFF_UP)) {
- continue;
- }
-
- memset(&ifaces[total], '\0', sizeof(ifaces[total]));
-
- copy_size = sizeof(struct sockaddr_in);
-
- ifaces[total].flags = ifptr->ifa_flags;
-
-#if defined(HAVE_IPV6)
- if (ifptr->ifa_addr->sa_family == AF_INET6) {
- copy_size = sizeof(struct sockaddr_in6);
- }
-#endif
-
- memcpy(&ifaces[total].ip, ifptr->ifa_addr, copy_size);
- memcpy(&ifaces[total].netmask, ifptr->ifa_netmask, copy_size);
-
- if (ifaces[total].flags & (IFF_BROADCAST|IFF_LOOPBACK)) {
- make_bcast(&ifaces[total].bcast,
- &ifaces[total].ip,
- &ifaces[total].netmask);
- } else if ((ifaces[total].flags & IFF_POINTOPOINT) &&
- ifptr->ifa_dstaddr ) {
- memcpy(&ifaces[total].bcast,
- ifptr->ifa_dstaddr,
- copy_size);
- } else {
- continue;
- }
-
- strlcpy(ifaces[total].name, ifptr->ifa_name,
- sizeof(ifaces[total].name));
- total++;
- }
-
- freeifaddrs(iflist);
-
- *pifaces = ifaces;
- return total;
-}
-
-static int iface_comp(struct iface_struct *i1, struct iface_struct *i2)
-{
- int r;
-
-#if defined(HAVE_IPV6)
- /*
- * If we have IPv6 - sort these interfaces lower
- * than any IPv4 ones.
- */
- if (i1->ip.ss_family == AF_INET6 &&
- i2->ip.ss_family == AF_INET) {
- return -1;
- } else if (i1->ip.ss_family == AF_INET &&
- i2->ip.ss_family == AF_INET6) {
- return 1;
- }
-
- if (i1->ip.ss_family == AF_INET6) {
- struct sockaddr_in6 *s1 = (struct sockaddr_in6 *)&i1->ip;
- struct sockaddr_in6 *s2 = (struct sockaddr_in6 *)&i2->ip;
-
- r = memcmp(&s1->sin6_addr,
- &s2->sin6_addr,
- sizeof(struct in6_addr));
- if (r) {
- return r;
- }
-
- s1 = (struct sockaddr_in6 *)&i1->netmask;
- s2 = (struct sockaddr_in6 *)&i2->netmask;
-
- r = memcmp(&s1->sin6_addr,
- &s2->sin6_addr,
- sizeof(struct in6_addr));
- if (r) {
- return r;
- }
- }
-#endif
-
- /* AIX uses __ss_family instead of ss_family inside of
- sockaddr_storage. Instead of trying to figure out which field to
- use, we can just cast it to a sockaddr.
- */
-
- if (((struct sockaddr *)&i1->ip)->sa_family == AF_INET) {
- struct sockaddr_in *s1 = (struct sockaddr_in *)&i1->ip;
- struct sockaddr_in *s2 = (struct sockaddr_in *)&i2->ip;
-
- r = ntohl(s1->sin_addr.s_addr) -
- ntohl(s2->sin_addr.s_addr);
- if (r) {
- return r;
- }
-
- s1 = (struct sockaddr_in *)&i1->netmask;
- s2 = (struct sockaddr_in *)&i2->netmask;
-
- return ntohl(s1->sin_addr.s_addr) -
- ntohl(s2->sin_addr.s_addr);
- }
- return 0;
-}
-
-/* this wrapper is used to remove duplicates from the interface list generated
- above */
-int get_interfaces(TALLOC_CTX *mem_ctx, struct iface_struct **pifaces)
-{
- struct iface_struct *ifaces;
- int total, i, j;
-
- total = _get_interfaces(mem_ctx, &ifaces);
- if (total <= 0) return total;
-
- /* now we need to remove duplicates */
- TYPESAFE_QSORT(ifaces, total, iface_comp);
-
- for (i=1;i<total;) {
- if (iface_comp(&ifaces[i-1], &ifaces[i]) == 0) {
- for (j=i-1;j<total-1;j++) {
- ifaces[j] = ifaces[j+1];
- }
- total--;
- } else {
- i++;
- }
- }
-
- *pifaces = ifaces;
- return total;
-}
-
diff --git a/source3/lib/memcache.c b/source3/lib/memcache.c
index 425861ed77..88453f32dd 100644
--- a/source3/lib/memcache.c
+++ b/source3/lib/memcache.c
@@ -72,7 +72,7 @@ struct memcache *memcache_init(TALLOC_CTX *mem_ctx, size_t max_size)
{
struct memcache *result;
- result = TALLOC_ZERO_P(mem_ctx, struct memcache);
+ result = talloc_zero(mem_ctx, struct memcache);
if (result == NULL) {
return NULL;
}
diff --git a/source3/lib/messages.c b/source3/lib/messages.c
index 4335554c2a..76c1090b81 100644
--- a/source3/lib/messages.c
+++ b/source3/lib/messages.c
@@ -112,7 +112,7 @@ static int traverse_fn(struct db_record *rec, const struct server_id *id,
* the msg has already been deleted from the messages.tdb.*/
status = messaging_send_buf(msg_all->msg_ctx, *id, msg_all->msg_type,
- (uint8 *)msg_all->buf, msg_all->len);
+ (const uint8 *)msg_all->buf, msg_all->len);
if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
@@ -184,7 +184,7 @@ struct messaging_context *messaging_init(TALLOC_CTX *mem_ctx,
struct messaging_context *ctx;
NTSTATUS status;
- if (!(ctx = TALLOC_ZERO_P(mem_ctx, struct messaging_context))) {
+ if (!(ctx = talloc_zero(mem_ctx, struct messaging_context))) {
return NULL;
}
@@ -205,7 +205,7 @@ struct messaging_context *messaging_init(TALLOC_CTX *mem_ctx,
status = messaging_ctdbd_init(ctx, ctx, &ctx->remote);
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(2, ("messaging_ctdb_init failed: %s\n",
+ DEBUG(2, ("messaging_ctdbd_init failed: %s\n",
nt_errstr(status)));
TALLOC_FREE(ctx);
return NULL;
@@ -257,7 +257,7 @@ NTSTATUS messaging_reinit(struct messaging_context *msg_ctx,
&msg_ctx->remote);
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(1, ("messaging_ctdb_init failed: %s\n",
+ DEBUG(1, ("messaging_ctdbd_init failed: %s\n",
nt_errstr(status)));
return status;
}
diff --git a/source3/lib/messages_ctdbd.c b/source3/lib/messages_ctdbd.c
index 3e2fde0b8f..b9ee049d01 100644
--- a/source3/lib/messages_ctdbd.c
+++ b/source3/lib/messages_ctdbd.c
@@ -19,6 +19,7 @@
#include "includes.h"
#include "messages.h"
+#include "util_tdb.h"
#ifdef CLUSTER_SUPPORT
@@ -104,12 +105,12 @@ NTSTATUS messaging_ctdbd_init(struct messaging_context *msg_ctx,
struct messaging_ctdbd_context *ctx;
NTSTATUS status;
- if (!(result = TALLOC_P(mem_ctx, struct messaging_backend))) {
+ if (!(result = talloc(mem_ctx, struct messaging_backend))) {
DEBUG(0, ("talloc failed\n"));
return NT_STATUS_NO_MEMORY;
}
- if (!(ctx = TALLOC_P(result, struct messaging_ctdbd_context))) {
+ if (!(ctx = talloc(result, struct messaging_ctdbd_context))) {
DEBUG(0, ("talloc failed\n"));
TALLOC_FREE(result);
return NT_STATUS_NO_MEMORY;
diff --git a/source3/lib/messages_local.c b/source3/lib/messages_local.c
index 18074cdd92..455f3d3476 100644
--- a/source3/lib/messages_local.c
+++ b/source3/lib/messages_local.c
@@ -45,6 +45,7 @@
#include "includes.h"
#include "system/filesys.h"
#include "messages.h"
+#include "lib/util/tdb_wrap.h"
struct messaging_tdb_context {
struct messaging_context *msg_ctx;
@@ -86,12 +87,12 @@ NTSTATUS messaging_tdb_init(struct messaging_context *msg_ctx,
struct messaging_backend *result;
struct messaging_tdb_context *ctx;
- if (!(result = TALLOC_P(mem_ctx, struct messaging_backend))) {
+ if (!(result = talloc(mem_ctx, struct messaging_backend))) {
DEBUG(0, ("talloc failed\n"));
return NT_STATUS_NO_MEMORY;
}
- ctx = TALLOC_ZERO_P(result, struct messaging_tdb_context);
+ ctx = talloc_zero(result, struct messaging_tdb_context);
if (!ctx) {
DEBUG(0, ("talloc failed\n"));
TALLOC_FREE(result);
@@ -186,11 +187,11 @@ static NTSTATUS messaging_tdb_fetch(TDB_CONTEXT *msg_tdb,
DATA_BLOB blob;
enum ndr_err_code ndr_err;
- if (!(result = TALLOC_ZERO_P(mem_ctx, struct messaging_array))) {
+ if (!(result = talloc_zero(mem_ctx, struct messaging_array))) {
return NT_STATUS_NO_MEMORY;
}
- data = tdb_fetch(msg_tdb, key);
+ data = tdb_fetch_compat(msg_tdb, key);
if (data.dptr == NULL) {
*presult = result;
@@ -351,7 +352,7 @@ static NTSTATUS messaging_tdb_send(struct messaging_context *msg_ctx,
key = message_key_pid(frame, pid);
- if (tdb_chainlock(tdb->tdb, key) == -1) {
+ if (tdb_chainlock(tdb->tdb, key) != 0) {
TALLOC_FREE(frame);
return NT_STATUS_LOCK_NOT_GRANTED;
}
@@ -370,7 +371,7 @@ static NTSTATUS messaging_tdb_send(struct messaging_context *msg_ctx,
goto done;
}
- if (!(rec = TALLOC_REALLOC_ARRAY(talloc_tos(), msg_array->messages,
+ if (!(rec = talloc_realloc(talloc_tos(), msg_array->messages,
struct messaging_rec,
msg_array->num_messages+1))) {
status = NT_STATUS_NO_MEMORY;
@@ -419,7 +420,7 @@ static NTSTATUS retrieve_all_messages(TDB_CONTEXT *msg_tdb,
TDB_DATA key = message_key_pid(mem_ctx, id);
NTSTATUS status;
- if (tdb_chainlock(msg_tdb, key) == -1) {
+ if (tdb_chainlock(msg_tdb, key) != 0) {
TALLOC_FREE(key.dptr);
return NT_STATUS_LOCK_NOT_GRANTED;
}
diff --git a/source3/lib/module.c b/source3/lib/module.c
index de13668009..bec4fddefd 100644
--- a/source3/lib/module.c
+++ b/source3/lib/module.c
@@ -117,10 +117,10 @@ NTSTATUS smb_probe_module(const char *subsystem, const char *module)
}
full_path = talloc_asprintf(ctx,
- "%s/%s.%s",
- modules_path(subsystem),
- module,
- shlib_ext());
+ "%s/%s.%s",
+ modules_path(ctx, subsystem),
+ module,
+ shlib_ext());
if (!full_path) {
TALLOC_FREE(ctx);
return NT_STATUS_NO_MEMORY;
diff --git a/source3/lib/ms_fnmatch.c b/source3/lib/ms_fnmatch.c
index 31c66953a9..f02354bfd7 100644
--- a/source3/lib/ms_fnmatch.c
+++ b/source3/lib/ms_fnmatch.c
@@ -166,7 +166,7 @@ int ms_fnmatch(const char *pattern, const char *string, bool translate_pattern,
if (is_case_sensitive) {
return strcmp(pattern, string);
} else {
- return StrCaseCmp(pattern, string);
+ return strcasecmp_m(pattern, string);
}
}
@@ -229,10 +229,3 @@ int ms_fnmatch(const char *pattern, const char *string, bool translate_pattern,
TALLOC_FREE(s);
return ret;
}
-
-
-/* a generic fnmatch function - uses for non-CIFS pattern matching */
-int gen_fnmatch(const char *pattern, const char *string)
-{
- return ms_fnmatch(pattern, string, true, False);
-}
diff --git a/source3/lib/namearray.c b/source3/lib/namearray.c
new file mode 100644
index 0000000000..e5c3bd983b
--- /dev/null
+++ b/source3/lib/namearray.c
@@ -0,0 +1,39 @@
+/*
+ Unix SMB/CIFS implementation.
+ Samba utility functions
+ Copyright (C) Andrew Tridgell 1992-1998
+ Copyright (C) Jeremy Allison 2001-2007
+ Copyright (C) Simo Sorce 2001
+ Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
+ Copyright (C) James Peach 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+/****************************************************************************
+ Routine to free a namearray.
+****************************************************************************/
+
+void free_namearray(name_compare_entry *name_array)
+{
+ int i;
+
+ if(name_array == NULL)
+ return;
+
+ for(i=0; name_array[i].name!=NULL; i++)
+ SAFE_FREE(name_array[i].name);
+ SAFE_FREE(name_array);
+}
diff --git a/source3/lib/netapi/cm.c b/source3/lib/netapi/cm.c
index 290194ba2d..47ccf8bb7a 100644
--- a/source3/lib/netapi/cm.c
+++ b/source3/lib/netapi/cm.c
@@ -22,6 +22,7 @@
#include "lib/netapi/netapi.h"
#include "lib/netapi/netapi_private.h"
+#include "libsmb/libsmb.h"
#include "rpc_client/cli_pipe.h"
/********************************************************************
@@ -121,7 +122,7 @@ static WERROR libnetapi_open_ipc_connection(struct libnetapi_ctx *ctx,
return WERR_CAN_NOT_COMPLETE;
}
- p = TALLOC_ZERO_P(ctx, struct client_ipc_connection);
+ p = talloc_zero(ctx, struct client_ipc_connection);
if (p == NULL) {
return WERR_NOMEM;
}
@@ -187,7 +188,7 @@ static NTSTATUS pipe_cm_connect(TALLOC_CTX *mem_ctx,
struct client_pipe_connection *p;
NTSTATUS status;
- p = TALLOC_ZERO_ARRAY(mem_ctx, struct client_pipe_connection, 1);
+ p = talloc_zero_array(mem_ctx, struct client_pipe_connection, 1);
if (!p) {
return NT_STATUS_NO_MEMORY;
}
diff --git a/source3/lib/netapi/group.c b/source3/lib/netapi/group.c
index 4295d9f7bb..710ec3790f 100644
--- a/source3/lib/netapi/group.c
+++ b/source3/lib/netapi/group.c
@@ -1157,7 +1157,7 @@ static WERROR convert_samr_disp_groups_to_GROUP_INFO_0_buffer(TALLOC_CTX *mem_ct
struct GROUP_INFO_0 *g0;
int i;
- g0 = TALLOC_ZERO_ARRAY(mem_ctx, struct GROUP_INFO_0, groups->count);
+ g0 = talloc_zero_array(mem_ctx, struct GROUP_INFO_0, groups->count);
W_ERROR_HAVE_NO_MEMORY(g0);
for (i=0; i<groups->count; i++) {
@@ -1183,7 +1183,7 @@ static WERROR convert_samr_disp_groups_to_GROUP_INFO_1_buffer(TALLOC_CTX *mem_ct
struct GROUP_INFO_1 *g1;
int i;
- g1 = TALLOC_ZERO_ARRAY(mem_ctx, struct GROUP_INFO_1, groups->count);
+ g1 = talloc_zero_array(mem_ctx, struct GROUP_INFO_1, groups->count);
W_ERROR_HAVE_NO_MEMORY(g1);
for (i=0; i<groups->count; i++) {
@@ -1211,7 +1211,7 @@ static WERROR convert_samr_disp_groups_to_GROUP_INFO_2_buffer(TALLOC_CTX *mem_ct
struct GROUP_INFO_2 *g2;
int i;
- g2 = TALLOC_ZERO_ARRAY(mem_ctx, struct GROUP_INFO_2, groups->count);
+ g2 = talloc_zero_array(mem_ctx, struct GROUP_INFO_2, groups->count);
W_ERROR_HAVE_NO_MEMORY(g2);
for (i=0; i<groups->count; i++) {
@@ -1242,7 +1242,7 @@ static WERROR convert_samr_disp_groups_to_GROUP_INFO_3_buffer(TALLOC_CTX *mem_ct
struct GROUP_INFO_3 *g3;
int i;
- g3 = TALLOC_ZERO_ARRAY(mem_ctx, struct GROUP_INFO_3, groups->count);
+ g3 = talloc_zero_array(mem_ctx, struct GROUP_INFO_3, groups->count);
W_ERROR_HAVE_NO_MEMORY(g3);
for (i=0; i<groups->count; i++) {
diff --git a/source3/lib/netapi/libnetapi.h b/source3/lib/netapi/libnetapi.h
index 2711558dbc..e832deaccc 100644
--- a/source3/lib/netapi/libnetapi.h
+++ b/source3/lib/netapi/libnetapi.h
@@ -1,3 +1,22 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * NetApi Support
+ * Copyright (C) Guenther Deschner 2007-2008
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
#ifndef __LIBNETAPI_LIBNETAPI__
#define __LIBNETAPI_LIBNETAPI__
NET_API_STATUS NetJoinDomain(const char * server /* [in] [unique] */,
diff --git a/source3/lib/netapi/localgroup.c b/source3/lib/netapi/localgroup.c
index 51f4e1d745..816afc230f 100644
--- a/source3/lib/netapi/localgroup.c
+++ b/source3/lib/netapi/localgroup.c
@@ -610,7 +610,7 @@ static WERROR map_buffer_to_alias_info(TALLOC_CTX *mem_ctx,
struct LOCALGROUP_INFO_1002 *info1002;
union samr_AliasInfo *info = NULL;
- info = TALLOC_ZERO_P(mem_ctx, union samr_AliasInfo);
+ info = talloc_zero(mem_ctx, union samr_AliasInfo);
W_ERROR_HAVE_NO_MEMORY(info);
switch (level) {
@@ -1115,7 +1115,7 @@ static WERROR NetLocalGroupModifyMembers_r(struct libnetapi_ctx *ctx,
ZERO_STRUCT(domain_handle);
ZERO_STRUCT(alias_handle);
- member_sids = TALLOC_ZERO_ARRAY(ctx, struct dom_sid,
+ member_sids = talloc_zero_array(ctx, struct dom_sid,
r->in.total_entries);
W_ERROR_HAVE_NO_MEMORY(member_sids);
@@ -1344,7 +1344,7 @@ static WERROR NetLocalGroupModifyMembers_r(struct libnetapi_ctx *ctx,
werr = WERR_OK;
done:
- if (is_valid_policy_hnd(&alias_handle)) {
+ if (b && is_valid_policy_hnd(&alias_handle)) {
dcerpc_samr_Close(b, talloc_tos(), &alias_handle, &result);
}
diff --git a/source3/lib/netapi/netapi.c b/source3/lib/netapi/netapi.c
index cd590273ce..14259864ae 100644
--- a/source3/lib/netapi/netapi.c
+++ b/source3/lib/netapi/netapi.c
@@ -24,7 +24,6 @@
#include "krb5_env.h"
struct libnetapi_ctx *stat_ctx = NULL;
-TALLOC_CTX *frame = NULL;
static bool libnetapi_initialized = false;
/****************************************************************
@@ -38,7 +37,7 @@ static NET_API_STATUS libnetapi_init_private_context(struct libnetapi_ctx *ctx)
return W_ERROR_V(WERR_INVALID_PARAM);
}
- priv = TALLOC_ZERO_P(ctx, struct libnetapi_private_ctx);
+ priv = talloc_zero(ctx, struct libnetapi_private_ctx);
if (!priv) {
return W_ERROR_V(WERR_NOMEM);
}
@@ -57,6 +56,8 @@ were not expecting it.
NET_API_STATUS libnetapi_init(struct libnetapi_ctx **context)
{
+ NET_API_STATUS ret;
+ TALLOC_CTX *frame;
if (stat_ctx && libnetapi_initialized) {
*context = stat_ctx;
return NET_API_STATUS_SUCCESS;
@@ -76,7 +77,7 @@ NET_API_STATUS libnetapi_init(struct libnetapi_ctx **context)
lp_set_cmdline("log level", "0");
setup_logging("libnetapi", DEBUG_STDERR);
- if (!lp_load(get_dyn_CONFIGFILE(), true, false, false, false)) {
+ if (!lp_load(get_dyn_CONFIGFILE(), true, false, false, true)) {
TALLOC_FREE(frame);
fprintf(stderr, "error loading %s\n", get_dyn_CONFIGFILE() );
return W_ERROR_V(WERR_GENERAL_FAILURE);
@@ -88,7 +89,9 @@ NET_API_STATUS libnetapi_init(struct libnetapi_ctx **context)
BlockSignals(True, SIGPIPE);
- return libnetapi_net_init(context);
+ ret = libnetapi_net_init(context);
+ TALLOC_FREE(frame);
+ return ret;
}
/****************************************************************
@@ -105,7 +108,7 @@ NET_API_STATUS libnetapi_net_init(struct libnetapi_ctx **context)
struct libnetapi_ctx *ctx = NULL;
char *krb5_cc_env = NULL;
- frame = talloc_stackframe();
+ TALLOC_CTX *frame = talloc_stackframe();
ctx = talloc_zero(frame, struct libnetapi_ctx);
if (!ctx) {
@@ -117,14 +120,14 @@ NET_API_STATUS libnetapi_net_init(struct libnetapi_ctx **context)
krb5_cc_env = getenv(KRB5_ENV_CCNAME);
if (!krb5_cc_env || (strlen(krb5_cc_env) == 0)) {
- ctx->krb5_cc_env = talloc_strdup(frame, "MEMORY:libnetapi");
+ ctx->krb5_cc_env = talloc_strdup(ctx, "MEMORY:libnetapi");
setenv(KRB5_ENV_CCNAME, ctx->krb5_cc_env, 1);
}
if (getenv("USER")) {
- ctx->username = talloc_strdup(frame, getenv("USER"));
+ ctx->username = talloc_strdup(ctx, getenv("USER"));
} else {
- ctx->username = talloc_strdup(frame, "");
+ ctx->username = talloc_strdup(ctx, "");
}
if (!ctx->username) {
TALLOC_FREE(frame);
@@ -140,8 +143,10 @@ NET_API_STATUS libnetapi_net_init(struct libnetapi_ctx **context)
libnetapi_initialized = true;
+ talloc_steal(NULL, ctx);
*context = stat_ctx = ctx;
-
+
+ TALLOC_FREE(frame);
return NET_API_STATUS_SUCCESS;
}
@@ -187,8 +192,10 @@ NET_API_STATUS libnetapi_free(struct libnetapi_ctx *ctx)
secrets_shutdown();
+ if (ctx == stat_ctx) {
+ stat_ctx = NULL;
+ }
TALLOC_FREE(ctx);
- TALLOC_FREE(frame);
gfree_debugsyms();
@@ -202,10 +209,14 @@ NET_API_STATUS libnetapi_free(struct libnetapi_ctx *ctx)
NET_API_STATUS libnetapi_set_debuglevel(struct libnetapi_ctx *ctx,
const char *debuglevel)
{
+ TALLOC_CTX *frame = talloc_stackframe();
ctx->debuglevel = talloc_strdup(ctx, debuglevel);
+
if (!lp_set_cmdline("log level", debuglevel)) {
+ TALLOC_FREE(frame);
return W_ERROR_V(WERR_GENERAL_FAILURE);
}
+ TALLOC_FREE(frame);
return NET_API_STATUS_SUCCESS;
}
@@ -272,15 +283,22 @@ NET_API_STATUS libnetapi_set_use_ccache(struct libnetapi_ctx *ctx)
}
/****************************************************************
+Return a libnetapi error as a string, caller must free with NetApiBufferFree
****************************************************************/
-const char *libnetapi_errstr(NET_API_STATUS status)
+char *libnetapi_errstr(NET_API_STATUS status)
{
+ TALLOC_CTX *frame = talloc_stackframe();
+ char *ret;
if (status & 0xc0000000) {
- return get_friendly_nt_error_msg(NT_STATUS(status));
+ ret = talloc_strdup(NULL,
+ get_friendly_nt_error_msg(NT_STATUS(status)));
+ } else {
+ ret = talloc_strdup(NULL,
+ get_friendly_werror_msg(W_ERROR(status)));
}
-
- return get_friendly_werror_msg(W_ERROR(status));
+ TALLOC_FREE(frame);
+ return ret;
}
/****************************************************************
@@ -304,9 +322,10 @@ NET_API_STATUS libnetapi_set_error_string(struct libnetapi_ctx *ctx,
}
/****************************************************************
+Return a libnetapi_errstr(), caller must free with NetApiBufferFree
****************************************************************/
-const char *libnetapi_get_error_string(struct libnetapi_ctx *ctx,
+char *libnetapi_get_error_string(struct libnetapi_ctx *ctx,
NET_API_STATUS status_in)
{
NET_API_STATUS status;
@@ -320,7 +339,7 @@ const char *libnetapi_get_error_string(struct libnetapi_ctx *ctx,
}
if (tmp_ctx->error_string) {
- return tmp_ctx->error_string;
+ return talloc_strdup(NULL, tmp_ctx->error_string);
}
return libnetapi_errstr(status_in);
diff --git a/source3/lib/netapi/netapi.h b/source3/lib/netapi/netapi.h
index 9e1549df0e..620d8cf591 100644
--- a/source3/lib/netapi/netapi.h
+++ b/source3/lib/netapi/netapi.h
@@ -1411,15 +1411,18 @@ NET_API_STATUS libnetapi_set_use_kerberos(struct libnetapi_ctx *ctx);
NET_API_STATUS libnetapi_set_use_ccache(struct libnetapi_ctx *ctx);
/****************************************************************
+Return a specific libnetapi error as a string, caller must free with NetApiBufferFree
****************************************************************/
-const char *libnetapi_errstr(NET_API_STATUS status);
+char *libnetapi_errstr(NET_API_STATUS status);
/****************************************************************
+Return the last libnetapi error as a string, caller must free with NetApiBufferFree
+ctx is optional
****************************************************************/
-const char *libnetapi_get_error_string(struct libnetapi_ctx *ctx,
- NET_API_STATUS status);
+char *libnetapi_get_error_string(struct libnetapi_ctx *ctx,
+ NET_API_STATUS status);
/****************************************************************
NetApiBufferAllocate
diff --git a/source3/lib/netapi/netapi_private.h b/source3/lib/netapi/netapi_private.h
index 7559c61564..349287b9e9 100644
--- a/source3/lib/netapi/netapi_private.h
+++ b/source3/lib/netapi/netapi_private.h
@@ -29,6 +29,8 @@
} \
return fn ## _r(ctx, r);
+struct dcerpc_binding_handle;
+
struct libnetapi_private_ctx {
struct {
const char *domain_name;
diff --git a/source3/lib/netapi/samr.c b/source3/lib/netapi/samr.c
index 544698004a..1c3a94ee9c 100644
--- a/source3/lib/netapi/samr.c
+++ b/source3/lib/netapi/samr.c
@@ -240,7 +240,7 @@ WERROR libnetapi_samr_open_builtin_domain(struct libnetapi_ctx *mem_ctx,
status = dcerpc_samr_OpenDomain(b, mem_ctx,
connect_handle,
builtin_mask,
- CONST_DISCARD(struct dom_sid *, &global_sid_Builtin),
+ discard_const_p(struct dom_sid, &global_sid_Builtin),
builtin_handle,
&result);
if (!NT_STATUS_IS_OK(status)) {
diff --git a/source3/lib/netapi/serverinfo.c b/source3/lib/netapi/serverinfo.c
index 22c7df69d1..4b11339f94 100644
--- a/source3/lib/netapi/serverinfo.c
+++ b/source3/lib/netapi/serverinfo.c
@@ -36,9 +36,9 @@ static WERROR NetServerGetInfo_l_101(struct libnetapi_ctx *ctx,
struct SERVER_INFO_101 i;
i.sv101_platform_id = PLATFORM_ID_NT;
- i.sv101_name = global_myname();
- i.sv101_version_major = lp_major_announce_version();
- i.sv101_version_minor = lp_minor_announce_version();
+ i.sv101_name = lp_netbios_name();
+ i.sv101_version_major = SAMBA_MAJOR_NBT_ANNOUNCE_VERSION;
+ i.sv101_version_minor = SAMBA_MINOR_NBT_ANNOUNCE_VERSION;
i.sv101_type = lp_default_server_announce();
i.sv101_comment = lp_serverstring();
@@ -540,7 +540,8 @@ WERROR NetServerGetInfo_r(struct libnetapi_ctx *ctx,
static WERROR NetServerSetInfo_l_1005(struct libnetapi_ctx *ctx,
struct NetServerSetInfo *r)
{
- WERROR werr;
+ WERROR werr = WERR_OK;
+ sbcErr err;
struct smbconf_ctx *conf_ctx;
struct srvsvc_NetSrvInfo1005 *info1005;
@@ -563,13 +564,24 @@ static WERROR NetServerSetInfo_l_1005(struct libnetapi_ctx *ctx,
return WERR_NOT_SUPPORTED;
}
- werr = smbconf_init_reg(ctx, &conf_ctx, NULL);
- if (!W_ERROR_IS_OK(werr)) {
+ err = smbconf_init_reg(ctx, &conf_ctx, NULL);
+ if (!SBC_ERROR_IS_OK(err)) {
+ libnetapi_set_error_string(ctx,
+ "Could not initialize backend: %s",
+ sbcErrorString(err));
+ werr = WERR_NO_SUCH_SERVICE;
goto done;
}
- werr = smbconf_set_global_parameter(conf_ctx, "server string",
+ err = smbconf_set_global_parameter(conf_ctx, "server string",
info1005->comment);
+ if (!SBC_ERROR_IS_OK(err)) {
+ libnetapi_set_error_string(ctx,
+ "Could not set global parameter: %s",
+ sbcErrorString(err));
+ werr = WERR_NO_SUCH_SERVICE;
+ goto done;
+ }
done:
smbconf_shutdown(conf_ctx);
diff --git a/source3/lib/netapi/share.c b/source3/lib/netapi/share.c
index c4ed1549ce..d12fa1cf0c 100644
--- a/source3/lib/netapi/share.c
+++ b/source3/lib/netapi/share.c
@@ -141,7 +141,7 @@ static NTSTATUS map_SHARE_INFO_buffer_to_srvsvc_share_info(TALLOC_CTX *mem_ctx,
case 2:
i2 = (struct SHARE_INFO_2 *)buffer;
- s2 = TALLOC_P(mem_ctx, struct srvsvc_NetShareInfo2);
+ s2 = talloc(mem_ctx, struct srvsvc_NetShareInfo2);
NT_STATUS_HAVE_NO_MEMORY(s2);
s2->name = i2->shi2_netname;
@@ -159,7 +159,7 @@ static NTSTATUS map_SHARE_INFO_buffer_to_srvsvc_share_info(TALLOC_CTX *mem_ctx,
case 1004:
i1004 = (struct SHARE_INFO_1004 *)buffer;
- s1004 = TALLOC_P(mem_ctx, struct srvsvc_NetShareInfo1004);
+ s1004 = talloc(mem_ctx, struct srvsvc_NetShareInfo1004);
NT_STATUS_HAVE_NO_MEMORY(s1004);
s1004->comment = i1004->shi1004_remark;
diff --git a/source3/lib/netapi/user.c b/source3/lib/netapi/user.c
index 63be7ac751..3003a39397 100644
--- a/source3/lib/netapi/user.c
+++ b/source3/lib/netapi/user.c
@@ -322,7 +322,7 @@ static NTSTATUS set_user_info_USER_INFO_X(TALLOC_CTX *ctx,
25,
&user_info,
&result);
- if (NT_STATUS_EQUAL(status, NT_STATUS(DCERPC_FAULT_INVALID_TAG))) {
+ if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE)) {
user_info.info23.info = info21;
@@ -575,7 +575,7 @@ WERROR NetUserDel_r(struct libnetapi_ctx *ctx,
status = dcerpc_samr_OpenDomain(b, talloc_tos(),
&connect_handle,
SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
- CONST_DISCARD(struct dom_sid *, &global_sid_Builtin),
+ discard_const_p(struct dom_sid, &global_sid_Builtin),
&builtin_handle,
&result);
if (!NT_STATUS_IS_OK(status)) {
@@ -1436,7 +1436,7 @@ static WERROR convert_samr_dispinfo_to_NET_DISPLAY_USER(TALLOC_CTX *mem_ctx,
struct NET_DISPLAY_USER *user = NULL;
int i;
- user = TALLOC_ZERO_ARRAY(mem_ctx,
+ user = talloc_zero_array(mem_ctx,
struct NET_DISPLAY_USER,
info->count);
W_ERROR_HAVE_NO_MEMORY(user);
@@ -1480,7 +1480,7 @@ static WERROR convert_samr_dispinfo_to_NET_DISPLAY_MACHINE(TALLOC_CTX *mem_ctx,
struct NET_DISPLAY_MACHINE *machine = NULL;
int i;
- machine = TALLOC_ZERO_ARRAY(mem_ctx,
+ machine = talloc_zero_array(mem_ctx,
struct NET_DISPLAY_MACHINE,
info->count);
W_ERROR_HAVE_NO_MEMORY(machine);
@@ -1522,7 +1522,7 @@ static WERROR convert_samr_dispinfo_to_NET_DISPLAY_GROUP(TALLOC_CTX *mem_ctx,
struct NET_DISPLAY_GROUP *group = NULL;
int i;
- group = TALLOC_ZERO_ARRAY(mem_ctx,
+ group = talloc_zero_array(mem_ctx,
struct NET_DISPLAY_GROUP,
info->count);
W_ERROR_HAVE_NO_MEMORY(group);
@@ -3137,7 +3137,6 @@ WERROR NetUserSetGroups_r(struct libnetapi_ctx *ctx,
size_t num_del_rids = 0;
uint32_t *member_rids = NULL;
- size_t num_member_rids = 0;
struct GROUP_USERS_INFO_0 *i0 = NULL;
struct GROUP_USERS_INFO_1 *i1 = NULL;
@@ -3263,7 +3262,6 @@ WERROR NetUserSetGroups_r(struct libnetapi_ctx *ctx,
}
member_rids = group_rids.ids;
- num_member_rids = group_rids.count;
status = dcerpc_samr_GetGroupsForUser(b, talloc_tos(),
&user_handle,
@@ -3574,7 +3572,7 @@ WERROR NetUserGetLocalGroups_r(struct libnetapi_ctx *ctx,
}
sid_array.num_sids = rid_array->count + 1;
- sid_array.sids = TALLOC_ARRAY(ctx, struct lsa_SidPtr, sid_array.num_sids);
+ sid_array.sids = talloc_array(ctx, struct lsa_SidPtr, sid_array.num_sids);
if (!sid_array.sids) {
werr = WERR_NOMEM;
goto done;
diff --git a/source3/lib/popt_common.c b/source3/lib/popt_common.c
index 128b9c1870..0c8f691c25 100644
--- a/source3/lib/popt_common.c
+++ b/source3/lib/popt_common.c
@@ -129,7 +129,7 @@ static void popt_common_callback(poptContext con,
case 'n':
if (arg) {
- set_global_myname(arg);
+ lp_set_cmdline("netbios name", arg);
}
break;
@@ -143,13 +143,13 @@ static void popt_common_callback(poptContext con,
case 'i':
if (arg) {
- set_global_scope(arg);
+ lp_set_cmdline("netbios scope", arg);
}
break;
case 'W':
if (arg) {
- set_global_myworkgroup(arg);
+ lp_set_cmdline("workgroup", arg);
}
break;
}
@@ -473,7 +473,7 @@ static void get_credentials_file(struct user_auth_info *auth_info,
} else if (strwicmp("username", param) == 0) {
set_cmdline_auth_info_username(auth_info, val);
} else if (strwicmp("domain", param) == 0) {
- set_global_myworkgroup(val);
+ set_cmdline_auth_info_domain(auth_info, val);
}
memset(buf, 0, sizeof(buf));
}
diff --git a/source3/lib/privileges.h b/source3/lib/privileges.h
index 13bc3eb083..ca2a7c9833 100644
--- a/source3/lib/privileges.h
+++ b/source3/lib/privileges.h
@@ -1,3 +1,28 @@
+/*
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _LIB_PRIVILEGES_H_
+#define _LIB_PRIVILEGES_H_
+
#include "../libcli/security/privileges.h"
/* The following definitions come from lib/privileges.c */
@@ -16,3 +41,5 @@ NTSTATUS privilege_create_account(const struct dom_sid *sid );
NTSTATUS privilege_delete_account(const struct dom_sid *sid);
bool is_privileged_sid( const struct dom_sid *sid );
bool grant_all_privileges( const struct dom_sid *sid );
+
+#endif /* _LIB_PRIVILEGES_H_ */
diff --git a/source3/lib/pthreadpool/Makefile b/source3/lib/pthreadpool/Makefile
new file mode 100644
index 0000000000..48626bd2c0
--- /dev/null
+++ b/source3/lib/pthreadpool/Makefile
@@ -0,0 +1,9 @@
+all: tests
+
+CFLAGS=-O3 -g -Wall
+
+pthreadpool.o: pthreadpool.c pthreadpool.h
+ gcc -c -O3 -o pthreadpool.o pthreadpool.c -I../../..
+
+tests: tests.o pthreadpool.o
+ gcc -o tests tests.o pthreadpool.o -lpthread \ No newline at end of file
diff --git a/source3/lib/pthreadpool.c b/source3/lib/pthreadpool/pthreadpool.c
index b62bab0a2e..9981ed25ae 100644
--- a/source3/lib/pthreadpool.c
+++ b/source3/lib/pthreadpool/pthreadpool.c
@@ -26,8 +26,10 @@
#include <signal.h>
#include <assert.h>
#include <fcntl.h>
+#include <sys/time.h>
#include "pthreadpool.h"
+#include "lib/util/dlinklist.h"
struct pthreadpool_job {
struct pthreadpool_job *next;
@@ -38,6 +40,11 @@ struct pthreadpool_job {
struct pthreadpool {
/*
+ * List pthreadpools for fork safety
+ */
+ struct pthreadpool *prev, *next;
+
+ /*
* Control access to this struct
*/
pthread_mutex_t mutex;
@@ -78,13 +85,18 @@ struct pthreadpool {
int num_idle;
/*
- * An array of threads that require joining, the array has
- * "max_threads" elements. It contains "num_exited" ids.
+ * An array of threads that require joining.
*/
int num_exited;
- pthread_t exited[1]; /* We alloc more */
+ pthread_t *exited; /* We alloc more */
};
+static pthread_mutex_t pthreadpools_mutex = PTHREAD_MUTEX_INITIALIZER;
+static struct pthreadpool *pthreadpools = NULL;
+static pthread_once_t pthreadpool_atfork_initialized = PTHREAD_ONCE_INIT;
+
+static void pthreadpool_prep_atfork(void);
+
/*
* Initialize a thread pool
*/
@@ -92,18 +104,24 @@ struct pthreadpool {
int pthreadpool_init(unsigned max_threads, struct pthreadpool **presult)
{
struct pthreadpool *pool;
- size_t size;
int ret;
- size = sizeof(struct pthreadpool) + max_threads * sizeof(pthread_t);
-
- pool = (struct pthreadpool *)malloc(size);
+ pool = (struct pthreadpool *)malloc(sizeof(struct pthreadpool));
if (pool == NULL) {
return ENOMEM;
}
+ ret = pipe(pool->sig_pipe);
+ if (ret == -1) {
+ int err = errno;
+ free(pool);
+ return err;
+ }
+
ret = pthread_mutex_init(&pool->mutex, NULL);
if (ret != 0) {
+ close(pool->sig_pipe[0]);
+ close(pool->sig_pipe[1]);
free(pool);
return ret;
}
@@ -111,6 +129,8 @@ int pthreadpool_init(unsigned max_threads, struct pthreadpool **presult)
ret = pthread_cond_init(&pool->condvar, NULL);
if (ret != 0) {
pthread_mutex_destroy(&pool->mutex);
+ close(pool->sig_pipe[0]);
+ close(pool->sig_pipe[1]);
free(pool);
return ret;
}
@@ -119,46 +139,126 @@ int pthreadpool_init(unsigned max_threads, struct pthreadpool **presult)
pool->jobs = pool->last_job = NULL;
pool->num_threads = 0;
pool->num_exited = 0;
+ pool->exited = NULL;
pool->max_threads = max_threads;
pool->num_idle = 0;
- pool->sig_pipe[0] = -1;
- pool->sig_pipe[1] = -1;
+
+ ret = pthread_mutex_lock(&pthreadpools_mutex);
+ if (ret != 0) {
+ pthread_cond_destroy(&pool->condvar);
+ pthread_mutex_destroy(&pool->mutex);
+ close(pool->sig_pipe[0]);
+ close(pool->sig_pipe[1]);
+ free(pool);
+ return ret;
+ }
+ DLIST_ADD(pthreadpools, pool);
+
+ ret = pthread_mutex_unlock(&pthreadpools_mutex);
+ assert(ret == 0);
+
+ pthread_once(&pthreadpool_atfork_initialized, pthreadpool_prep_atfork);
*presult = pool;
+
return 0;
}
-/*
- * Create and return a file descriptor which becomes readable when a job has
- * finished
- */
-
-int pthreadpool_sig_fd(struct pthreadpool *pool)
+static void pthreadpool_prepare(void)
{
- int result, ret;
+ int ret;
+ struct pthreadpool *pool;
- ret = pthread_mutex_lock(&pool->mutex);
- if (ret != 0) {
- errno = ret;
- return -1;
+ ret = pthread_mutex_lock(&pthreadpools_mutex);
+ assert(ret == 0);
+
+ pool = pthreadpools;
+
+ while (pool != NULL) {
+ ret = pthread_mutex_lock(&pool->mutex);
+ assert(ret == 0);
+ pool = pool->next;
}
+}
- if (pool->sig_pipe[0] != -1) {
- result = pool->sig_pipe[0];
- goto done;
+static void pthreadpool_parent(void)
+{
+ int ret;
+ struct pthreadpool *pool;
+
+ pool = DLIST_TAIL(pthreadpools);
+
+ while (1) {
+ ret = pthread_mutex_unlock(&pool->mutex);
+ assert(ret == 0);
+
+ if (pool == pthreadpools) {
+ break;
+ }
+ pool = pool->prev;
}
- ret = pipe(pool->sig_pipe);
- if (ret == -1) {
- result = -1;
- goto done;
+ ret = pthread_mutex_unlock(&pthreadpools_mutex);
+ assert(ret == 0);
+}
+
+static void pthreadpool_child(void)
+{
+ int ret;
+ struct pthreadpool *pool;
+
+ pool = DLIST_TAIL(pthreadpools);
+
+ while (1) {
+ close(pool->sig_pipe[0]);
+ close(pool->sig_pipe[1]);
+
+ ret = pipe(pool->sig_pipe);
+ assert(ret == 0);
+
+ pool->num_threads = 0;
+
+ pool->num_exited = 0;
+ free(pool->exited);
+ pool->exited = NULL;
+
+ pool->num_idle = 0;
+
+ while (pool->jobs != NULL) {
+ struct pthreadpool_job *job;
+ job = pool->jobs;
+ pool->jobs = job->next;
+ free(job);
+ }
+ pool->last_job = NULL;
+
+ ret = pthread_mutex_unlock(&pool->mutex);
+ assert(ret == 0);
+
+ if (pool == pthreadpools) {
+ break;
+ }
+ pool = pool->prev;
}
- result = pool->sig_pipe[0];
-done:
- ret = pthread_mutex_unlock(&pool->mutex);
+ ret = pthread_mutex_unlock(&pthreadpools_mutex);
assert(ret == 0);
- return result;
+}
+
+static void pthreadpool_prep_atfork(void)
+{
+ pthread_atfork(pthreadpool_prepare, pthreadpool_parent,
+ pthreadpool_child);
+}
+
+/*
+ * Return the file descriptor which becomes readable when a job has
+ * finished
+ */
+
+int pthreadpool_signal_fd(struct pthreadpool *pool)
+{
+ return pool->sig_pipe[0];
}
/*
@@ -173,6 +273,11 @@ static void pthreadpool_join_children(struct pthreadpool *pool)
pthread_join(pool->exited[i], NULL);
}
pool->num_exited = 0;
+
+ /*
+ * Deliberately not free and NULL pool->exited. That will be
+ * re-used by realloc later.
+ */
}
/*
@@ -181,59 +286,21 @@ static void pthreadpool_join_children(struct pthreadpool *pool)
int pthreadpool_finished_job(struct pthreadpool *pool)
{
- int result, ret, fd;
+ int result;
ssize_t nread;
- ret = pthread_mutex_lock(&pool->mutex);
- if (ret != 0) {
- errno = ret;
- return -1;
- }
-
- /*
- * Just some cleanup under the mutex
- */
- pthreadpool_join_children(pool);
-
- fd = pool->sig_pipe[0];
-
- ret = pthread_mutex_unlock(&pool->mutex);
- assert(ret == 0);
-
- if (fd == -1) {
- errno = EINVAL;
- return -1;
- }
-
nread = -1;
errno = EINTR;
while ((nread == -1) && (errno == EINTR)) {
- nread = read(fd, &result, sizeof(int));
+ nread = read(pool->sig_pipe[0], &result, sizeof(int));
}
-
- /*
- * TODO: handle nread > 0 && nread < sizeof(int)
- */
-
- /*
- * Lock the mutex to provide a memory barrier for data from the worker
- * thread to the main thread. The pipe access itself does not have to
- * be locked, for sizeof(int) the write to a pipe is atomic, and only
- * one thread reads from it. But we need to lock the mutex briefly
- * even if we don't do anything under the lock, to make sure we can
- * see all memory the helper thread has written.
- */
-
- ret = pthread_mutex_lock(&pool->mutex);
- if (ret == -1) {
- errno = ret;
- return -1;
+ if (nread == -1) {
+ return errno;
+ }
+ if (nread != sizeof(int)) {
+ return EINVAL;
}
-
- ret = pthread_mutex_unlock(&pool->mutex);
- assert(ret == 0);
-
return result;
}
@@ -250,6 +317,12 @@ int pthreadpool_destroy(struct pthreadpool *pool)
return ret;
}
+ if ((pool->jobs != NULL) || pool->shutdown) {
+ ret = pthread_mutex_unlock(&pool->mutex);
+ assert(ret == 0);
+ return EBUSY;
+ }
+
if (pool->num_threads > 0) {
/*
* We have active threads, tell them to finish, wait for that.
@@ -294,14 +367,31 @@ int pthreadpool_destroy(struct pthreadpool *pool)
ret = pthread_mutex_destroy(&pool->mutex);
ret1 = pthread_cond_destroy(&pool->condvar);
- if ((ret == 0) && (ret1 == 0)) {
- free(pool);
+ if (ret != 0) {
+ return ret;
+ }
+ if (ret1 != 0) {
+ return ret1;
}
+ ret = pthread_mutex_lock(&pthreadpools_mutex);
if (ret != 0) {
return ret;
}
- return ret1;
+ DLIST_REMOVE(pthreadpools, pool);
+ ret = pthread_mutex_unlock(&pthreadpools_mutex);
+ assert(ret == 0);
+
+ close(pool->sig_pipe[0]);
+ pool->sig_pipe[0] = -1;
+
+ close(pool->sig_pipe[1]);
+ pool->sig_pipe[1] = -1;
+
+ free(pool->exited);
+ free(pool);
+
+ return 0;
}
/*
@@ -309,7 +399,19 @@ int pthreadpool_destroy(struct pthreadpool *pool)
*/
static void pthreadpool_server_exit(struct pthreadpool *pool)
{
+ pthread_t *exited;
+
pool->num_threads -= 1;
+
+ exited = (pthread_t *)realloc(
+ pool->exited, sizeof(pthread_t *) * (pool->num_exited + 1));
+
+ if (exited == NULL) {
+ /* lost a thread status */
+ return;
+ }
+ pool->exited = exited;
+
pool->exited[pool->num_exited] = pthread_self();
pool->num_exited += 1;
}
@@ -325,7 +427,7 @@ static void *pthreadpool_server(void *arg)
}
while (1) {
- struct timespec timeout;
+ struct timespec ts;
struct pthreadpool_job *job;
/*
@@ -333,14 +435,14 @@ static void *pthreadpool_server(void *arg)
* time, exit this thread.
*/
- timeout.tv_sec = time(NULL) + 1;
- timeout.tv_nsec = 0;
+ clock_gettime(CLOCK_REALTIME, &ts);
+ ts.tv_sec += 1;
while ((pool->jobs == NULL) && (pool->shutdown == 0)) {
pool->num_idle += 1;
res = pthread_cond_timedwait(
- &pool->condvar, &pool->mutex, &timeout);
+ &pool->condvar, &pool->mutex, &ts);
pool->num_idle -= 1;
if (res == ETIMEDOUT) {
@@ -363,7 +465,6 @@ static void *pthreadpool_server(void *arg)
job = pool->jobs;
if (job != NULL) {
- int fd = pool->sig_pipe[1];
ssize_t written;
/*
@@ -376,7 +477,7 @@ static void *pthreadpool_server(void *arg)
}
/*
- * Do the work with the mutex unlocked :-)
+ * Do the work with the mutex unlocked
*/
res = pthread_mutex_unlock(&pool->mutex);
@@ -384,17 +485,14 @@ static void *pthreadpool_server(void *arg)
job->fn(job->private_data);
- written = sizeof(int);
+ written = write(pool->sig_pipe[1], &job->id,
+ sizeof(int));
+
+ free(job);
res = pthread_mutex_lock(&pool->mutex);
assert(res == 0);
- if (fd != -1) {
- written = write(fd, &job->id, sizeof(int));
- }
-
- free(job);
-
if (written != sizeof(int)) {
pthreadpool_server_exit(pool);
pthread_mutex_unlock(&pool->mutex);
@@ -447,6 +545,17 @@ int pthreadpool_add_job(struct pthreadpool *pool, int job_id,
return res;
}
+ if (pool->shutdown) {
+ /*
+ * Protect against the pool being shut down while
+ * trying to add a job
+ */
+ res = pthread_mutex_unlock(&pool->mutex);
+ assert(res == 0);
+ free(job);
+ return EINVAL;
+ }
+
/*
* Just some cleanup under the mutex
*/
@@ -472,7 +581,8 @@ int pthreadpool_add_job(struct pthreadpool *pool, int job_id,
return res;
}
- if (pool->num_threads >= pool->max_threads) {
+ if ((pool->max_threads != 0) &&
+ (pool->num_threads >= pool->max_threads)) {
/*
* No more new threads, we just queue the request
*/
diff --git a/source3/lib/pthreadpool/pthreadpool.h b/source3/lib/pthreadpool/pthreadpool.h
new file mode 100644
index 0000000000..79704ea385
--- /dev/null
+++ b/source3/lib/pthreadpool/pthreadpool.h
@@ -0,0 +1,97 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * threadpool implementation based on pthreads
+ * Copyright (C) Volker Lendecke 2009,2011
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __PTHREADPOOL_H__
+#define __PTHREADPOOL_H__
+
+struct pthreadpool;
+
+/**
+ * @defgroup pthreadpool The pthreadpool API
+ *
+ * This API provides a way to run threadsafe functions in a helper
+ * thread. It is initially intended to run getaddrinfo asynchronously.
+ */
+
+
+/**
+ * @brief Create a pthreadpool
+ *
+ * A struct pthreadpool is the basis for for running threads in the
+ * background.
+ *
+ * @param[in] max_threads Maximum parallelism in this pool
+ * @param[out] presult Pointer to the threadpool returned
+ * @return success: 0, failure: errno
+ *
+ * max_threads=0 means unlimited parallelism. The caller has to take
+ * care to not overload the system.
+ */
+int pthreadpool_init(unsigned max_threads, struct pthreadpool **presult);
+
+/**
+ * @brief Destroy a pthreadpool
+ *
+ * Destroy a pthreadpool. If jobs are still active, this returns
+ * EBUSY.
+ *
+ * @param[in] pool The pool to destroy
+ * @return success: 0, failure: errno
+ */
+int pthreadpool_destroy(struct pthreadpool *pool);
+
+/**
+ * @brief Add a job to a pthreadpool
+ *
+ * This adds a job to a pthreadpool. The job can be identified by
+ * job_id. This integer will be returned from
+ * pthreadpool_finished_job() then the job is completed.
+ *
+ * @param[in] pool The pool to run the job on
+ * @param[in] job_id A custom identifier
+ * @param[in] fn The function to run asynchronously
+ * @param[in] private_data Pointer passed to fn
+ * @return success: 0, failure: errno
+ */
+int pthreadpool_add_job(struct pthreadpool *pool, int job_id,
+ void (*fn)(void *private_data), void *private_data);
+
+/**
+ * @brief Get the signalling fd from a pthreadpool
+ *
+ * Completion of a job is indicated by readability of the fd retuned
+ * by pthreadpool_signal_fd().
+ *
+ * @param[in] pool The pool in question
+ * @return The fd to listen on for readability
+ */
+int pthreadpool_signal_fd(struct pthreadpool *pool);
+
+/**
+ * @brief Get the job_id of a finished job
+ *
+ * This blocks until a job has finished unless the fd returned by
+ * pthreadpool_signal_fd() is readable.
+ *
+ * @param[in] pool The pool to query for finished jobs
+ * @return The job_id of the finished job
+ */
+int pthreadpool_finished_job(struct pthreadpool *pool);
+
+#endif
diff --git a/source3/lib/pthreadpool/tests.c b/source3/lib/pthreadpool/tests.c
new file mode 100644
index 0000000000..667ee01784
--- /dev/null
+++ b/source3/lib/pthreadpool/tests.c
@@ -0,0 +1,362 @@
+#include <stdio.h>
+#include <string.h>
+#include <poll.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <unistd.h>
+#include "pthreadpool.h"
+
+static int test_init(void)
+{
+ struct pthreadpool *p;
+ int ret;
+
+ ret = pthreadpool_init(1, &p);
+ if (ret != 0) {
+ fprintf(stderr, "pthreadpool_init failed: %s\n",
+ strerror(ret));
+ return -1;
+ }
+ ret = pthreadpool_destroy(p);
+ if (ret != 0) {
+ fprintf(stderr, "pthreadpool_init failed: %s\n",
+ strerror(ret));
+ return -1;
+ }
+ return 0;
+}
+
+static void test_sleep(void *ptr)
+{
+ int *ptimeout = (int *)ptr;
+ int ret;
+ ret = poll(NULL, 0, *ptimeout);
+ if (ret != 0) {
+ fprintf(stderr, "poll returned %d (%s)\n",
+ ret, strerror(errno));
+ }
+}
+
+static int test_jobs(int num_threads, int num_jobs)
+{
+ char *finished;
+ struct pthreadpool *p;
+ int timeout = 1;
+ int i, ret;
+
+ finished = (char *)calloc(1, num_jobs);
+ if (finished == NULL) {
+ fprintf(stderr, "calloc failed\n");
+ return -1;
+ }
+
+ ret = pthreadpool_init(num_threads, &p);
+ if (ret != 0) {
+ fprintf(stderr, "pthreadpool_init failed: %s\n",
+ strerror(ret));
+ return -1;
+ }
+
+ for (i=0; i<num_jobs; i++) {
+ ret = pthreadpool_add_job(p, i, test_sleep, &timeout);
+ if (ret != 0) {
+ fprintf(stderr, "pthreadpool_add_job failed: %s\n",
+ strerror(ret));
+ return -1;
+ }
+ }
+
+ for (i=0; i<num_jobs; i++) {
+ ret = pthreadpool_finished_job(p);
+ if ((ret < 0) || (ret >= num_jobs)) {
+ fprintf(stderr, "invalid job number %d\n", ret);
+ return -1;
+ }
+ finished[ret] += 1;
+ }
+
+ for (i=0; i<num_jobs; i++) {
+ if (finished[i] != 1) {
+ fprintf(stderr, "finished[%d] = %d\n",
+ i, finished[i]);
+ return -1;
+ }
+ }
+
+ ret = pthreadpool_destroy(p);
+ if (ret != 0) {
+ fprintf(stderr, "pthreadpool_destroy failed: %s\n",
+ strerror(ret));
+ return -1;
+ }
+
+ free(finished);
+ return 0;
+}
+
+static int test_busydestroy(void)
+{
+ struct pthreadpool *p;
+ int timeout = 50;
+ struct pollfd pfd;
+ int ret;
+
+ ret = pthreadpool_init(1, &p);
+ if (ret != 0) {
+ fprintf(stderr, "pthreadpool_init failed: %s\n",
+ strerror(ret));
+ return -1;
+ }
+ ret = pthreadpool_add_job(p, 1, test_sleep, &timeout);
+ if (ret != 0) {
+ fprintf(stderr, "pthreadpool_add_job failed: %s\n",
+ strerror(ret));
+ return -1;
+ }
+ ret = pthreadpool_destroy(p);
+ if (ret != EBUSY) {
+ fprintf(stderr, "Could destroy a busy pool\n");
+ return -1;
+ }
+
+ pfd.fd = pthreadpool_signal_fd(p);
+ pfd.events = POLLIN|POLLERR;
+
+ poll(&pfd, 1, -1);
+
+ ret = pthreadpool_destroy(p);
+ if (ret != 0) {
+ fprintf(stderr, "pthreadpool_destroy failed: %s\n",
+ strerror(ret));
+ return -1;
+ }
+ return 0;
+}
+
+struct threaded_state {
+ pthread_t tid;
+ struct pthreadpool *p;
+ int start_job;
+ int num_jobs;
+ int timeout;
+};
+
+static void *test_threaded_worker(void *p)
+{
+ struct threaded_state *state = (struct threaded_state *)p;
+ int i;
+
+ for (i=0; i<state->num_jobs; i++) {
+ int ret = pthreadpool_add_job(state->p, state->start_job + i,
+ test_sleep, &state->timeout);
+ if (ret != 0) {
+ fprintf(stderr, "pthreadpool_add_job failed: %s\n",
+ strerror(ret));
+ return NULL;
+ }
+ }
+ return NULL;
+}
+
+static int test_threaded_addjob(int num_pools, int num_threads, int poolsize,
+ int num_jobs)
+{
+ struct pthreadpool **pools;
+ struct threaded_state *states;
+ struct threaded_state *state;
+ struct pollfd *pfds;
+ char *finished;
+ pid_t child;
+ int i, ret, poolnum;
+ int received;
+
+ states = calloc(num_threads, sizeof(struct threaded_state));
+ if (states == NULL) {
+ fprintf(stderr, "calloc failed\n");
+ return -1;
+ }
+
+ finished = calloc(num_threads * num_jobs, 1);
+ if (finished == NULL) {
+ fprintf(stderr, "calloc failed\n");
+ return -1;
+ }
+
+ pools = calloc(num_pools, sizeof(struct pthreadpool *));
+ if (pools == NULL) {
+ fprintf(stderr, "calloc failed\n");
+ return -1;
+ }
+
+ pfds = calloc(num_pools, sizeof(struct pollfd));
+ if (pfds == NULL) {
+ fprintf(stderr, "calloc failed\n");
+ return -1;
+ }
+
+ for (i=0; i<num_pools; i++) {
+ ret = pthreadpool_init(poolsize, &pools[i]);
+ if (ret != 0) {
+ fprintf(stderr, "pthreadpool_init failed: %s\n",
+ strerror(ret));
+ return -1;
+ }
+ pfds[i].fd = pthreadpool_signal_fd(pools[i]);
+ pfds[i].events = POLLIN|POLLHUP;
+ }
+
+ poolnum = 0;
+
+ for (i=0; i<num_threads; i++) {
+ state = &states[i];
+
+ state->p = pools[poolnum];
+ poolnum = (poolnum + 1) % num_pools;
+
+ state->num_jobs = num_jobs;
+ state->timeout = 1;
+ state->start_job = i * num_jobs;
+
+ ret = pthread_create(&state->tid, NULL, test_threaded_worker,
+ state);
+ if (ret != 0) {
+ fprintf(stderr, "pthread_create failed: %s\n",
+ strerror(ret));
+ return -1;
+ }
+ }
+
+ if (random() % 1) {
+ poll(NULL, 0, 1);
+ }
+
+ child = fork();
+ if (child < 0) {
+ fprintf(stderr, "fork failed: %s\n", strerror(errno));
+ return -1;
+ }
+ if (child == 0) {
+ for (i=0; i<num_pools; i++) {
+ ret = pthreadpool_destroy(pools[i]);
+ if (ret != 0) {
+ fprintf(stderr, "pthreadpool_destroy failed: "
+ "%s\n", strerror(ret));
+ exit(1);
+ }
+ }
+ /* child */
+ exit(0);
+ }
+
+ for (i=0; i<num_threads; i++) {
+ ret = pthread_join(states[i].tid, NULL);
+ if (ret != 0) {
+ fprintf(stderr, "pthread_join(%d) failed: %s\n",
+ i, strerror(ret));
+ return -1;
+ }
+ }
+
+ received = 0;
+
+ while (received < num_threads*num_jobs) {
+ int j;
+
+ ret = poll(pfds, num_pools, 1000);
+ if (ret == -1) {
+ fprintf(stderr, "poll failed: %s\n",
+ strerror(errno));
+ return -1;
+ }
+ if (ret == 0) {
+ fprintf(stderr, "\npoll timed out\n");
+ break;
+ }
+
+ for (j=0; j<num_pools; j++) {
+
+ if ((pfds[j].revents & (POLLIN|POLLHUP)) == 0) {
+ continue;
+ }
+
+ ret = pthreadpool_finished_job(pools[j]);
+ if ((ret < 0) || (ret >= num_jobs * num_threads)) {
+ fprintf(stderr, "invalid job number %d\n",
+ ret);
+ return -1;
+ }
+ finished[ret] += 1;
+ received += 1;
+ }
+ }
+
+ for (i=0; i<num_threads*num_jobs; i++) {
+ if (finished[i] != 1) {
+ fprintf(stderr, "finished[%d] = %d\n",
+ i, finished[i]);
+ return -1;
+ }
+ }
+
+ for (i=0; i<num_pools; i++) {
+ ret = pthreadpool_destroy(pools[i]);
+ if (ret != 0) {
+ fprintf(stderr, "pthreadpool_destroy failed: %s\n",
+ strerror(ret));
+ return -1;
+ }
+ }
+
+ free(pfds);
+ free(pools);
+ free(states);
+ free(finished);
+
+ return 0;
+}
+
+int main(void)
+{
+ int ret;
+
+ ret = test_init();
+ if (ret != 0) {
+ fprintf(stderr, "test_init failed\n");
+ return 1;
+ }
+
+ ret = test_jobs(10, 10000);
+ if (ret != 0) {
+ fprintf(stderr, "test_jobs failed\n");
+ return 1;
+ }
+
+ ret = test_busydestroy();
+ if (ret != 0) {
+ fprintf(stderr, "test_busydestroy failed\n");
+ return 1;
+ }
+
+ /*
+ * Test 10 threads adding jobs on a single pool
+ */
+ ret = test_threaded_addjob(1, 10, 5, 5000);
+ if (ret != 0) {
+ fprintf(stderr, "test_jobs failed\n");
+ return 1;
+ }
+
+ /*
+ * Test 10 threads on 3 pools to verify our fork handling
+ * works right.
+ */
+ ret = test_threaded_addjob(3, 10, 5, 5000);
+ if (ret != 0) {
+ fprintf(stderr, "test_jobs failed\n");
+ return 1;
+ }
+
+ printf("success\n");
+ return 0;
+}
diff --git a/source3/lib/pthreadpool/wscript_build b/source3/lib/pthreadpool/wscript_build
new file mode 100644
index 0000000000..611ff5a433
--- /dev/null
+++ b/source3/lib/pthreadpool/wscript_build
@@ -0,0 +1,11 @@
+#!/usr/bin/env python
+
+bld.SAMBA3_SUBSYSTEM('PTHREADPOOL',
+ source='pthreadpool.c',
+ deps='pthread rt',
+ enabled=bld.env.WITH_PTHREADPOOL)
+
+bld.SAMBA3_BINARY('pthreadpooltest',
+ source='tests.c',
+ deps='PTHREADPOOL',
+ enabled=bld.env.WITH_PTHREADPOOL)
diff --git a/source3/lib/secdesc.c b/source3/lib/secdesc.c
deleted file mode 100644
index 001eccb576..0000000000
--- a/source3/lib/secdesc.c
+++ /dev/null
@@ -1,712 +0,0 @@
-/*
- * Unix SMB/Netbios implementation.
- * SEC_DESC handling functions
- * Copyright (C) Andrew Tridgell 1992-1998,
- * Copyright (C) Jeremy R. Allison 1995-2003.
- * Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
- * Copyright (C) Paul Ashton 1997-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 3 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include "includes.h"
-#include "../librpc/gen_ndr/ndr_security.h"
-#include "../libcli/security/security.h"
-
-#define ALL_SECURITY_INFORMATION (SECINFO_OWNER|SECINFO_GROUP|\
- SECINFO_DACL|SECINFO_SACL|\
- SECINFO_UNPROTECTED_SACL|\
- SECINFO_UNPROTECTED_DACL|\
- SECINFO_PROTECTED_SACL|\
- SECINFO_PROTECTED_DACL)
-
-/* Map generic permissions to file object specific permissions */
-
-const struct generic_mapping file_generic_mapping = {
- FILE_GENERIC_READ,
- FILE_GENERIC_WRITE,
- FILE_GENERIC_EXECUTE,
- FILE_GENERIC_ALL
-};
-
-/*******************************************************************
- Given a security_descriptor return the sec_info.
-********************************************************************/
-
-uint32_t get_sec_info(const struct security_descriptor *sd)
-{
- uint32_t sec_info = ALL_SECURITY_INFORMATION;
-
- SMB_ASSERT(sd);
-
- if (sd->owner_sid == NULL) {
- sec_info &= ~SECINFO_OWNER;
- }
- if (sd->group_sid == NULL) {
- sec_info &= ~SECINFO_GROUP;
- }
- if (sd->sacl == NULL) {
- sec_info &= ~SECINFO_SACL;
- }
- if (sd->dacl == NULL) {
- sec_info &= ~SECINFO_DACL;
- }
-
- return sec_info;
-}
-
-
-/*******************************************************************
- Merge part of security descriptor old_sec in to the empty sections of
- security descriptor new_sec.
-********************************************************************/
-
-struct sec_desc_buf *sec_desc_merge_buf(TALLOC_CTX *ctx, struct sec_desc_buf *new_sdb, struct sec_desc_buf *old_sdb)
-{
- struct dom_sid *owner_sid, *group_sid;
- struct sec_desc_buf *return_sdb;
- struct security_acl *dacl, *sacl;
- struct security_descriptor *psd = NULL;
- uint16 secdesc_type;
- size_t secdesc_size;
-
- /* 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;
-
- group_sid = new_sdb->sd->group_sid ? new_sdb->sd->group_sid :
- old_sdb->sd->group_sid;
-
- secdesc_type = new_sdb->sd->type;
-
- /* Ignore changes to the system ACL. This has the effect of making
- changes through the security tab audit button not sticking.
- Perhaps in future Samba could implement these settings somehow. */
-
- sacl = NULL;
- secdesc_type &= ~SEC_DESC_SACL_PRESENT;
-
- /* Copy across discretionary ACL */
-
- if (secdesc_type & SEC_DESC_DACL_PRESENT) {
- dacl = new_sdb->sd->dacl;
- } else {
- dacl = old_sdb->sd->dacl;
- }
-
- /* Create new security descriptor from bits */
-
- psd = make_sec_desc(ctx, new_sdb->sd->revision, secdesc_type,
- owner_sid, group_sid, sacl, dacl, &secdesc_size);
-
- return_sdb = make_sec_desc_buf(ctx, secdesc_size, psd);
-
- return(return_sdb);
-}
-
-struct security_descriptor *sec_desc_merge(TALLOC_CTX *ctx, struct security_descriptor *new_sdb, struct security_descriptor *old_sdb)
-{
- struct dom_sid *owner_sid, *group_sid;
- struct security_acl *dacl, *sacl;
- struct security_descriptor *psd = NULL;
- uint16 secdesc_type;
- size_t secdesc_size;
-
- /* Copy over owner and group sids. There seems to be no flag for
- this so just check the pointer values. */
-
- owner_sid = new_sdb->owner_sid ? new_sdb->owner_sid :
- old_sdb->owner_sid;
-
- group_sid = new_sdb->group_sid ? new_sdb->group_sid :
- old_sdb->group_sid;
-
- secdesc_type = new_sdb->type;
-
- /* Ignore changes to the system ACL. This has the effect of making
- changes through the security tab audit button not sticking.
- Perhaps in future Samba could implement these settings somehow. */
-
- sacl = NULL;
- secdesc_type &= ~SEC_DESC_SACL_PRESENT;
-
- /* Copy across discretionary ACL */
-
- if (secdesc_type & SEC_DESC_DACL_PRESENT) {
- dacl = new_sdb->dacl;
- } else {
- dacl = old_sdb->dacl;
- }
-
- /* Create new security descriptor from bits */
- psd = make_sec_desc(ctx, new_sdb->revision, secdesc_type,
- owner_sid, group_sid, sacl, dacl, &secdesc_size);
-
- return psd;
-}
-
-/*******************************************************************
- Creates a struct security_descriptor structure
-********************************************************************/
-
-#define SEC_DESC_HEADER_SIZE (2 * sizeof(uint16) + 4 * sizeof(uint32))
-
-struct security_descriptor *make_sec_desc(TALLOC_CTX *ctx,
- enum security_descriptor_revision revision,
- uint16 type,
- const struct dom_sid *owner_sid, const struct dom_sid *grp_sid,
- struct security_acl *sacl, struct security_acl *dacl, size_t *sd_size)
-{
- struct security_descriptor *dst;
- uint32 offset = 0;
-
- *sd_size = 0;
-
- if(( dst = TALLOC_ZERO_P(ctx, struct security_descriptor)) == NULL)
- return NULL;
-
- dst->revision = revision;
- dst->type = type;
-
- if (sacl)
- dst->type |= SEC_DESC_SACL_PRESENT;
- if (dacl)
- dst->type |= SEC_DESC_DACL_PRESENT;
-
- dst->owner_sid = NULL;
- dst->group_sid = NULL;
- dst->sacl = NULL;
- dst->dacl = NULL;
-
- if(owner_sid && ((dst->owner_sid = dom_sid_dup(dst,owner_sid)) == NULL))
- goto error_exit;
-
- if(grp_sid && ((dst->group_sid = dom_sid_dup(dst,grp_sid)) == NULL))
- goto error_exit;
-
- if(sacl && ((dst->sacl = dup_sec_acl(dst, sacl)) == NULL))
- goto error_exit;
-
- if(dacl && ((dst->dacl = dup_sec_acl(dst, dacl)) == NULL))
- goto error_exit;
-
- offset = SEC_DESC_HEADER_SIZE;
-
- /*
- * Work out the linearization sizes.
- */
-
- if (dst->sacl != NULL) {
- offset += dst->sacl->size;
- }
- if (dst->dacl != NULL) {
- offset += dst->dacl->size;
- }
-
- if (dst->owner_sid != NULL) {
- offset += ndr_size_dom_sid(dst->owner_sid, 0);
- }
-
- if (dst->group_sid != NULL) {
- offset += ndr_size_dom_sid(dst->group_sid, 0);
- }
-
- *sd_size = (size_t)offset;
- return dst;
-
-error_exit:
-
- *sd_size = 0;
- return NULL;
-}
-
-/*******************************************************************
- Duplicate a struct security_descriptor structure.
-********************************************************************/
-
-struct security_descriptor *dup_sec_desc(TALLOC_CTX *ctx, const struct security_descriptor *src)
-{
- size_t dummy;
-
- if(src == NULL)
- return NULL;
-
- return make_sec_desc( ctx, src->revision, src->type,
- src->owner_sid, src->group_sid, src->sacl,
- src->dacl, &dummy);
-}
-
-/*******************************************************************
- Convert a secdesc into a byte stream
-********************************************************************/
-NTSTATUS marshall_sec_desc(TALLOC_CTX *mem_ctx,
- struct security_descriptor *secdesc,
- uint8 **data, size_t *len)
-{
- DATA_BLOB blob;
- enum ndr_err_code ndr_err;
-
- ndr_err = ndr_push_struct_blob(
- &blob, mem_ctx, secdesc,
- (ndr_push_flags_fn_t)ndr_push_security_descriptor);
-
- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
- DEBUG(0, ("ndr_push_security_descriptor failed: %s\n",
- ndr_errstr(ndr_err)));
- return ndr_map_error2ntstatus(ndr_err);
- }
-
- *data = blob.data;
- *len = blob.length;
- return NT_STATUS_OK;
-}
-
-/*******************************************************************
- Convert a secdesc_buf into a byte stream
-********************************************************************/
-
-NTSTATUS marshall_sec_desc_buf(TALLOC_CTX *mem_ctx,
- struct sec_desc_buf *secdesc_buf,
- uint8_t **data, size_t *len)
-{
- DATA_BLOB blob;
- enum ndr_err_code ndr_err;
-
- ndr_err = ndr_push_struct_blob(
- &blob, mem_ctx, secdesc_buf,
- (ndr_push_flags_fn_t)ndr_push_sec_desc_buf);
-
- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
- DEBUG(0, ("ndr_push_sec_desc_buf failed: %s\n",
- ndr_errstr(ndr_err)));
- return ndr_map_error2ntstatus(ndr_err);
- }
-
- *data = blob.data;
- *len = blob.length;
- 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)
-{
- DATA_BLOB blob;
- enum ndr_err_code ndr_err;
- struct security_descriptor *result;
-
- if ((data == NULL) || (len == 0)) {
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- result = TALLOC_ZERO_P(mem_ctx, struct security_descriptor);
- if (result == NULL) {
- return NT_STATUS_NO_MEMORY;
- }
-
- blob = data_blob_const(data, len);
-
- ndr_err = ndr_pull_struct_blob(&blob, result, result,
- (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
-
- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
- DEBUG(0, ("ndr_pull_security_descriptor failed: %s\n",
- ndr_errstr(ndr_err)));
- TALLOC_FREE(result);
- return ndr_map_error2ntstatus(ndr_err);
- }
-
- *psecdesc = result;
- return NT_STATUS_OK;
-}
-
-/*******************************************************************
- Parse a byte stream into a sec_desc_buf
-********************************************************************/
-
-NTSTATUS unmarshall_sec_desc_buf(TALLOC_CTX *mem_ctx, uint8_t *data, size_t len,
- struct sec_desc_buf **psecdesc_buf)
-{
- DATA_BLOB blob;
- enum ndr_err_code ndr_err;
- struct sec_desc_buf *result;
-
- if ((data == NULL) || (len == 0)) {
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- result = TALLOC_ZERO_P(mem_ctx, struct sec_desc_buf);
- if (result == NULL) {
- return NT_STATUS_NO_MEMORY;
- }
-
- blob = data_blob_const(data, len);
-
- ndr_err = ndr_pull_struct_blob(&blob, result, result,
- (ndr_pull_flags_fn_t)ndr_pull_sec_desc_buf);
-
- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
- DEBUG(0, ("ndr_pull_sec_desc_buf failed: %s\n",
- ndr_errstr(ndr_err)));
- TALLOC_FREE(result);
- return ndr_map_error2ntstatus(ndr_err);
- }
-
- *psecdesc_buf = result;
- return NT_STATUS_OK;
-}
-
-/*******************************************************************
- Creates a struct security_descriptor structure with typical defaults.
-********************************************************************/
-
-struct security_descriptor *make_standard_sec_desc(TALLOC_CTX *ctx, const struct dom_sid *owner_sid, const struct dom_sid *grp_sid,
- struct security_acl *dacl, size_t *sd_size)
-{
- return make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
- SEC_DESC_SELF_RELATIVE, owner_sid, grp_sid, NULL,
- dacl, sd_size);
-}
-
-/*******************************************************************
- Creates a struct sec_desc_buf structure.
-********************************************************************/
-
-struct sec_desc_buf *make_sec_desc_buf(TALLOC_CTX *ctx, size_t len, struct security_descriptor *sec_desc)
-{
- struct sec_desc_buf *dst;
-
- if((dst = TALLOC_ZERO_P(ctx, struct sec_desc_buf)) == NULL)
- return NULL;
-
- /* max buffer size (allocated size) */
- dst->sd_size = (uint32)len;
-
- if(sec_desc && ((dst->sd = dup_sec_desc(ctx, sec_desc)) == NULL)) {
- return NULL;
- }
-
- return dst;
-}
-
-/*******************************************************************
- Duplicates a struct sec_desc_buf structure.
-********************************************************************/
-
-struct sec_desc_buf *dup_sec_desc_buf(TALLOC_CTX *ctx, struct sec_desc_buf *src)
-{
- if(src == NULL)
- return NULL;
-
- return make_sec_desc_buf( ctx, src->sd_size, src->sd);
-}
-
-/*******************************************************************
- Add a new SID with its permissions to struct security_descriptor.
-********************************************************************/
-
-NTSTATUS sec_desc_add_sid(TALLOC_CTX *ctx, struct security_descriptor **psd, const struct dom_sid *sid, uint32 mask, size_t *sd_size)
-{
- struct security_descriptor *sd = 0;
- struct security_acl *dacl = 0;
- struct security_ace *ace = 0;
- NTSTATUS status;
-
- if (!ctx || !psd || !sid || !sd_size)
- return NT_STATUS_INVALID_PARAMETER;
-
- *sd_size = 0;
-
- status = sec_ace_add_sid(ctx, &ace, psd[0]->dacl->aces, &psd[0]->dacl->num_aces, sid, mask);
-
- if (!NT_STATUS_IS_OK(status))
- return status;
-
- if (!(dacl = make_sec_acl(ctx, psd[0]->dacl->revision, psd[0]->dacl->num_aces, ace)))
- return NT_STATUS_UNSUCCESSFUL;
-
- if (!(sd = make_sec_desc(ctx, psd[0]->revision, psd[0]->type, psd[0]->owner_sid,
- psd[0]->group_sid, psd[0]->sacl, dacl, sd_size)))
- return NT_STATUS_UNSUCCESSFUL;
-
- *psd = sd;
- sd = 0;
- return NT_STATUS_OK;
-}
-
-/*******************************************************************
- Modify a SID's permissions in a struct security_descriptor.
-********************************************************************/
-
-NTSTATUS sec_desc_mod_sid(struct security_descriptor *sd, struct dom_sid *sid, uint32 mask)
-{
- NTSTATUS status;
-
- if (!sd || !sid)
- return NT_STATUS_INVALID_PARAMETER;
-
- status = sec_ace_mod_sid(sd->dacl->aces, sd->dacl->num_aces, sid, mask);
-
- if (!NT_STATUS_IS_OK(status))
- return status;
-
- return NT_STATUS_OK;
-}
-
-/*******************************************************************
- Delete a SID from a struct security_descriptor.
-********************************************************************/
-
-NTSTATUS sec_desc_del_sid(TALLOC_CTX *ctx, struct security_descriptor **psd, struct dom_sid *sid, size_t *sd_size)
-{
- struct security_descriptor *sd = 0;
- struct security_acl *dacl = 0;
- struct security_ace *ace = 0;
- NTSTATUS status;
-
- if (!ctx || !psd[0] || !sid || !sd_size)
- return NT_STATUS_INVALID_PARAMETER;
-
- *sd_size = 0;
-
- status = sec_ace_del_sid(ctx, &ace, psd[0]->dacl->aces, &psd[0]->dacl->num_aces, sid);
-
- if (!NT_STATUS_IS_OK(status))
- return status;
-
- if (!(dacl = make_sec_acl(ctx, psd[0]->dacl->revision, psd[0]->dacl->num_aces, ace)))
- return NT_STATUS_UNSUCCESSFUL;
-
- if (!(sd = make_sec_desc(ctx, psd[0]->revision, psd[0]->type, psd[0]->owner_sid,
- psd[0]->group_sid, psd[0]->sacl, dacl, sd_size)))
- return NT_STATUS_UNSUCCESSFUL;
-
- *psd = sd;
- sd = 0;
- return NT_STATUS_OK;
-}
-
-/*
- * Determine if an struct security_ace is inheritable
- */
-
-static bool is_inheritable_ace(const struct security_ace *ace,
- bool container)
-{
- if (!container) {
- return ((ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT) != 0);
- }
-
- if (ace->flags & SEC_ACE_FLAG_CONTAINER_INHERIT) {
- return true;
- }
-
- if ((ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT) &&
- !(ace->flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
- return true;
- }
-
- return false;
-}
-
-/*
- * Does a security descriptor have any inheritable components for
- * the newly created type ?
- */
-
-bool sd_has_inheritable_components(const struct security_descriptor *parent_ctr, bool container)
-{
- unsigned int i;
- const struct security_acl *the_acl = parent_ctr->dacl;
-
- for (i = 0; i < the_acl->num_aces; i++) {
- const struct security_ace *ace = &the_acl->aces[i];
-
- if (is_inheritable_ace(ace, container)) {
- return true;
- }
- }
- return false;
-}
-
-/* Create a child security descriptor using another security descriptor as
- the parent container. This child object can either be a container or
- non-container object. */
-
-NTSTATUS se_create_child_secdesc(TALLOC_CTX *ctx,
- struct security_descriptor **ppsd,
- size_t *psize,
- const struct security_descriptor *parent_ctr,
- const struct dom_sid *owner_sid,
- const struct dom_sid *group_sid,
- bool container)
-{
- struct security_acl *new_dacl = NULL, *the_acl = NULL;
- struct security_ace *new_ace_list = NULL;
- unsigned int new_ace_list_ndx = 0, i;
-
- *ppsd = NULL;
- *psize = 0;
-
- /* Currently we only process the dacl when creating the child. The
- sacl should also be processed but this is left out as sacls are
- not implemented in Samba at the moment.*/
-
- the_acl = parent_ctr->dacl;
-
- if (the_acl->num_aces) {
- if (2*the_acl->num_aces < the_acl->num_aces) {
- return NT_STATUS_NO_MEMORY;
- }
-
- if (!(new_ace_list = TALLOC_ARRAY(ctx, struct security_ace,
- 2*the_acl->num_aces))) {
- return NT_STATUS_NO_MEMORY;
- }
- } else {
- new_ace_list = NULL;
- }
-
- for (i = 0; i < the_acl->num_aces; i++) {
- const struct security_ace *ace = &the_acl->aces[i];
- struct security_ace *new_ace = &new_ace_list[new_ace_list_ndx];
- const struct dom_sid *ptrustee = &ace->trustee;
- const struct dom_sid *creator = NULL;
- uint8 new_flags = ace->flags;
-
- if (!is_inheritable_ace(ace, container)) {
- continue;
- }
-
- /* see the RAW-ACLS inheritance test for details on these rules */
- if (!container) {
- new_flags = 0;
- } else {
- new_flags &= ~SEC_ACE_FLAG_INHERIT_ONLY;
-
- if (!(new_flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) {
- new_flags |= SEC_ACE_FLAG_INHERIT_ONLY;
- }
- if (new_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT) {
- new_flags = 0;
- }
- }
-
- /* The CREATOR sids are special when inherited */
- if (dom_sid_equal(ptrustee, &global_sid_Creator_Owner)) {
- creator = &global_sid_Creator_Owner;
- ptrustee = owner_sid;
- } else if (dom_sid_equal(ptrustee, &global_sid_Creator_Group)) {
- creator = &global_sid_Creator_Group;
- ptrustee = group_sid;
- }
-
- if (creator && container &&
- (new_flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) {
-
- /* First add the regular ACE entry. */
- init_sec_ace(new_ace, ptrustee, ace->type,
- ace->access_mask, 0);
-
- DEBUG(5,("se_create_child_secdesc(): %s:%d/0x%02x/0x%08x"
- " inherited as %s:%d/0x%02x/0x%08x\n",
- sid_string_dbg(&ace->trustee),
- ace->type, ace->flags, ace->access_mask,
- sid_string_dbg(&new_ace->trustee),
- new_ace->type, new_ace->flags,
- new_ace->access_mask));
-
- new_ace_list_ndx++;
-
- /* Now add the extra creator ACE. */
- new_ace = &new_ace_list[new_ace_list_ndx];
-
- ptrustee = creator;
- new_flags |= SEC_ACE_FLAG_INHERIT_ONLY;
- } else if (container &&
- !(ace->flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
- ptrustee = &ace->trustee;
- }
-
- init_sec_ace(new_ace, ptrustee, ace->type,
- ace->access_mask, new_flags);
-
- DEBUG(5, ("se_create_child_secdesc(): %s:%d/0x%02x/0x%08x "
- " inherited as %s:%d/0x%02x/0x%08x\n",
- sid_string_dbg(&ace->trustee),
- ace->type, ace->flags, ace->access_mask,
- sid_string_dbg(&ace->trustee),
- new_ace->type, new_ace->flags,
- new_ace->access_mask));
-
- new_ace_list_ndx++;
- }
-
- /* Create child security descriptor to return */
- if (new_ace_list_ndx) {
- new_dacl = make_sec_acl(ctx,
- NT4_ACL_REVISION,
- new_ace_list_ndx,
- new_ace_list);
-
- if (!new_dacl) {
- return NT_STATUS_NO_MEMORY;
- }
- }
-
- *ppsd = make_sec_desc(ctx,
- SECURITY_DESCRIPTOR_REVISION_1,
- SEC_DESC_SELF_RELATIVE|SEC_DESC_DACL_PRESENT,
- owner_sid,
- group_sid,
- NULL,
- new_dacl,
- psize);
- if (!*ppsd) {
- return NT_STATUS_NO_MEMORY;
- }
- return NT_STATUS_OK;
-}
-
-NTSTATUS se_create_child_secdesc_buf(TALLOC_CTX *ctx,
- struct sec_desc_buf **ppsdb,
- const struct security_descriptor *parent_ctr,
- bool container)
-{
- NTSTATUS status;
- size_t size = 0;
- struct security_descriptor *sd = NULL;
-
- *ppsdb = NULL;
- status = se_create_child_secdesc(ctx,
- &sd,
- &size,
- parent_ctr,
- parent_ctr->owner_sid,
- parent_ctr->group_sid,
- container);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
-
- *ppsdb = make_sec_desc_buf(ctx, size, sd);
- if (!*ppsdb) {
- return NT_STATUS_NO_MEMORY;
- }
- return NT_STATUS_OK;
-}
diff --git a/source3/lib/server_mutex.c b/source3/lib/server_mutex.c
index 1ba9d6a65b..dc65819197 100644
--- a/source3/lib/server_mutex.c
+++ b/source3/lib/server_mutex.c
@@ -20,6 +20,8 @@
#include "includes.h"
#include "system/filesys.h"
+#include "lib/util/tdb_wrap.h"
+#include "util_tdb.h"
/* For reasons known only to MS, many of their NT/Win2k versions
need serialised access only. Two connections at the same time
@@ -68,7 +70,7 @@ struct named_mutex *grab_named_mutex(TALLOC_CTX *mem_ctx, const char *name,
}
if (tdb_lock_bystring_with_timeout(result->tdb->tdb, name,
- timeout) == -1) {
+ timeout) != 0) {
DEBUG(1, ("Could not get the lock for %s\n", name));
TALLOC_FREE(result);
return NULL;
diff --git a/source3/lib/serverid.c b/source3/lib/serverid.c
index f13c66e2c9..1a1141265a 100644
--- a/source3/lib/serverid.c
+++ b/source3/lib/serverid.c
@@ -20,10 +20,13 @@
#include "includes.h"
#include "system/filesys.h"
#include "serverid.h"
+#include "util_tdb.h"
#include "dbwrap.h"
+#include "lib/util/tdb_wrap.h"
struct serverid_key {
pid_t pid;
+ uint32_t task_id;
uint32_t vnn;
};
@@ -70,6 +73,7 @@ static void serverid_fill_key(const struct server_id *id,
{
ZERO_STRUCTP(key);
key->pid = id->pid;
+ key->task_id = id->task_id;
key->vnn = id->vnn;
}
@@ -246,7 +250,7 @@ bool serverid_exists(const struct server_id *id)
state.id = id;
state.exists = false;
- if (db->parse_record(db, tdbkey, server_exists_parse, &state) == -1) {
+ if (db->parse_record(db, tdbkey, server_exists_parse, &state) != 0) {
return false;
}
return state.exists;
@@ -273,6 +277,7 @@ static bool serverid_rec_parse(const struct db_record *rec,
memcpy(&data, rec->value.dptr, sizeof(data));
id->pid = key.pid;
+ id->task_id = key.task_id;
id->vnn = key.vnn;
id->unique_id = data.unique_id;
*msg_flags = data.msg_flags;
diff --git a/source3/lib/sessionid_tdb.c b/source3/lib/sessionid_tdb.c
index ab54ec9ca5..de3ccab26a 100644
--- a/source3/lib/sessionid_tdb.c
+++ b/source3/lib/sessionid_tdb.c
@@ -21,6 +21,7 @@
#include "system/filesys.h"
#include "dbwrap.h"
#include "session.h"
+#include "util_tdb.h"
static struct db_context *session_db_ctx(void)
{
diff --git a/source3/lib/sharesec.c b/source3/lib/sharesec.c
index c84e8fa00b..ed971a97a6 100644
--- a/source3/lib/sharesec.c
+++ b/source3/lib/sharesec.c
@@ -22,6 +22,7 @@
#include "../libcli/security/security.h"
#include "../librpc/gen_ndr/ndr_security.h"
#include "dbwrap.h"
+#include "util_tdb.h"
/*******************************************************************
Create the share security tdb.
@@ -462,7 +463,7 @@ bool parse_usershare_acl(TALLOC_CTX *ctx, const char *acl_str, struct security_d
/* Add the number of ',' characters to get the number of aces. */
num_aces += count_chars(pacl,',');
- ace_list = TALLOC_ARRAY(ctx, struct security_ace, num_aces);
+ ace_list = talloc_array(ctx, struct security_ace, num_aces);
if (!ace_list) {
return False;
}
diff --git a/source3/lib/smbconf/smbconf_init.c b/source3/lib/smbconf/smbconf_init.c
index 36c51de5f0..2587a4fc53 100644
--- a/source3/lib/smbconf/smbconf_init.c
+++ b/source3/lib/smbconf/smbconf_init.c
@@ -34,28 +34,28 @@
* - "registry" or "reg"
* - "txt" or "file"
*/
-WERROR smbconf_init(TALLOC_CTX *mem_ctx, struct smbconf_ctx **conf_ctx,
+sbcErr smbconf_init(TALLOC_CTX *mem_ctx, struct smbconf_ctx **conf_ctx,
const char *source)
{
- WERROR werr;
+ sbcErr err;
char *backend = NULL;
char *path = NULL;
char *sep;
TALLOC_CTX *tmp_ctx = talloc_stackframe();
if (conf_ctx == NULL) {
- werr = WERR_INVALID_PARAM;
+ err = SBC_ERR_INVALID_PARAM;
goto done;
}
if ((source == NULL) || (*source == '\0')) {
- werr = WERR_INVALID_PARAM;
+ err = SBC_ERR_INVALID_PARAM;
goto done;
}
backend = talloc_strdup(tmp_ctx, source);
if (backend == NULL) {
- werr = WERR_NOMEM;
+ err = SBC_ERR_NOMEM;
goto done;
}
@@ -69,16 +69,16 @@ WERROR smbconf_init(TALLOC_CTX *mem_ctx, struct smbconf_ctx **conf_ctx,
}
if (strequal(backend, "registry") || strequal(backend, "reg")) {
- werr = smbconf_init_reg(mem_ctx, conf_ctx, path);
+ err = smbconf_init_reg(mem_ctx, conf_ctx, path);
} else if (strequal(backend, "file") || strequal(backend, "txt")) {
- werr = smbconf_init_txt(mem_ctx, conf_ctx, path);
+ err = smbconf_init_txt(mem_ctx, conf_ctx, path);
} else if (sep == NULL) {
/*
* If no separator was given in the source, and the string is
* not a known backend, assume file backend and use the source
* string as a path argument.
*/
- werr = smbconf_init_txt(mem_ctx, conf_ctx, backend);
+ err = smbconf_init_txt(mem_ctx, conf_ctx, backend);
} else {
/*
* Separator was specified but this is not a known backend.
@@ -87,10 +87,10 @@ WERROR smbconf_init(TALLOC_CTX *mem_ctx, struct smbconf_ctx **conf_ctx,
* This may occur with an include directive like this:
* 'include = /path/to/file.%T'
*/
- werr = smbconf_init_txt(mem_ctx, conf_ctx, source);
+ err = smbconf_init_txt(mem_ctx, conf_ctx, source);
}
done:
talloc_free(tmp_ctx);
- return werr;
+ return err;
}
diff --git a/source3/lib/smbconf/smbconf_init.h b/source3/lib/smbconf/smbconf_init.h
index abd62df204..45ea809624 100644
--- a/source3/lib/smbconf/smbconf_init.h
+++ b/source3/lib/smbconf/smbconf_init.h
@@ -26,7 +26,7 @@ struct smbconf_ctx;
* intialization dispatcher function.
* takes source string in the form of "backend:path"
*/
-WERROR smbconf_init(TALLOC_CTX *mem_ctx, struct smbconf_ctx **conf_ctx,
+sbcErr smbconf_init(TALLOC_CTX *mem_ctx, struct smbconf_ctx **conf_ctx,
const char *source);
#endif /* _LIBSMBCONF_INIT_H_ */
diff --git a/source3/lib/smbconf/smbconf_reg.c b/source3/lib/smbconf/smbconf_reg.c
index 67df03cbd2..92dbcbae1c 100644
--- a/source3/lib/smbconf/smbconf_reg.c
+++ b/source3/lib/smbconf/smbconf_reg.c
@@ -83,7 +83,7 @@ static bool smbconf_reg_valname_valid(const char *valname)
/**
* Open a subkey of the base key (i.e a service)
*/
-static WERROR smbconf_reg_open_service_key(TALLOC_CTX *mem_ctx,
+static sbcErr smbconf_reg_open_service_key(TALLOC_CTX *mem_ctx,
struct smbconf_ctx *ctx,
const char *servicename,
uint32 desired_access,
@@ -93,16 +93,18 @@ static WERROR smbconf_reg_open_service_key(TALLOC_CTX *mem_ctx,
if (servicename == NULL) {
*key = rpd(ctx)->base_key;
- return WERR_OK;
+ return SBC_ERR_OK;
}
werr = reg_openkey(mem_ctx, rpd(ctx)->base_key, servicename,
desired_access, key);
-
if (W_ERROR_EQUAL(werr, WERR_BADFILE)) {
- werr = WERR_NO_SUCH_SERVICE;
+ return SBC_ERR_NO_SUCH_SERVICE;
+ }
+ if (!W_ERROR_IS_OK(werr)) {
+ return SBC_ERR_NOMEM;
}
- return werr;
+ return SBC_ERR_OK;
}
/**
@@ -127,12 +129,13 @@ static bool smbconf_value_exists(struct registry_key *key, const char *param)
/**
* create a subkey of the base key (i.e. a service...)
*/
-static WERROR smbconf_reg_create_service_key(TALLOC_CTX *mem_ctx,
+static sbcErr smbconf_reg_create_service_key(TALLOC_CTX *mem_ctx,
struct smbconf_ctx *ctx,
const char * subkeyname,
struct registry_key **newkey)
{
- WERROR werr = WERR_OK;
+ WERROR werr;
+ sbcErr err = SBC_ERR_OK;
TALLOC_CTX *create_ctx;
enum winreg_CreateAction action = REG_ACTION_NONE;
@@ -145,26 +148,28 @@ static WERROR smbconf_reg_create_service_key(TALLOC_CTX *mem_ctx,
REG_KEY_WRITE, newkey, &action);
if (W_ERROR_IS_OK(werr) && (action != REG_CREATED_NEW_KEY)) {
DEBUG(10, ("Key '%s' already exists.\n", subkeyname));
- werr = WERR_FILE_EXISTS;
+ err = SBC_ERR_FILE_EXISTS;
}
if (!W_ERROR_IS_OK(werr)) {
DEBUG(5, ("Error creating key %s: %s\n",
subkeyname, win_errstr(werr)));
+ err = SBC_ERR_UNKNOWN_FAILURE;
}
talloc_free(create_ctx);
- return werr;
+ return err;
}
/**
* add a value to a key.
*/
-static WERROR smbconf_reg_set_value(struct registry_key *key,
+static sbcErr smbconf_reg_set_value(struct registry_key *key,
const char *valname,
const char *valstr)
{
struct registry_value val;
WERROR werr = WERR_OK;
+ sbcErr err;
char *subkeyname;
const char *canon_valname;
const char *canon_valstr;
@@ -180,14 +185,14 @@ static WERROR smbconf_reg_set_value(struct registry_key *key,
DEBUG(5, ("invalid value '%s' given for "
"parameter '%s'\n", valstr, valname));
}
- werr = WERR_INVALID_PARAM;
+ err = SBC_ERR_INVALID_PARAM;
goto done;
}
if (smbconf_reg_valname_forbidden(canon_valname)) {
DEBUG(5, ("Parameter '%s' not allowed in registry.\n",
canon_valname));
- werr = WERR_INVALID_PARAM;
+ err = SBC_ERR_INVALID_PARAM;
goto done;
}
@@ -195,7 +200,7 @@ static WERROR smbconf_reg_set_value(struct registry_key *key,
if ((subkeyname == NULL) || (*(subkeyname +1) == '\0')) {
DEBUG(5, ("Invalid registry key '%s' given as "
"smbconf section.\n", key->key->name));
- werr = WERR_INVALID_PARAM;
+ err = SBC_ERR_INVALID_PARAM;
goto done;
}
subkeyname++;
@@ -205,7 +210,7 @@ static WERROR smbconf_reg_set_value(struct registry_key *key,
DEBUG(5, ("Global parameter '%s' not allowed in "
"service definition ('%s').\n", canon_valname,
subkeyname));
- werr = WERR_INVALID_PARAM;
+ err = SBC_ERR_INVALID_PARAM;
goto done;
}
@@ -213,7 +218,7 @@ static WERROR smbconf_reg_set_value(struct registry_key *key,
val.type = REG_SZ;
if (!push_reg_sz(talloc_tos(), &val.data, canon_valstr)) {
- werr = WERR_NOMEM;
+ err = SBC_ERR_NOMEM;
goto done;
}
@@ -222,37 +227,41 @@ static WERROR smbconf_reg_set_value(struct registry_key *key,
DEBUG(5, ("Error adding value '%s' to "
"key '%s': %s\n",
canon_valname, key->key->name, win_errstr(werr)));
+ err = SBC_ERR_NOMEM;
+ goto done;
}
+ err = SBC_ERR_OK;
done:
- return werr;
+ return err;
}
-static WERROR smbconf_reg_set_multi_sz_value(struct registry_key *key,
+static sbcErr smbconf_reg_set_multi_sz_value(struct registry_key *key,
const char *valname,
const uint32_t num_strings,
const char **strings)
{
WERROR werr;
+ sbcErr err = SBC_ERR_OK;
struct registry_value *value;
uint32_t count;
TALLOC_CTX *tmp_ctx = talloc_stackframe();
const char **array;
if (strings == NULL) {
- werr = WERR_INVALID_PARAM;
+ err = SBC_ERR_INVALID_PARAM;
goto done;
}
array = talloc_zero_array(tmp_ctx, const char *, num_strings + 1);
if (array == NULL) {
- werr = WERR_NOMEM;
+ err = SBC_ERR_NOMEM;
goto done;
}
- value = TALLOC_ZERO_P(tmp_ctx, struct registry_value);
+ value = talloc_zero(tmp_ctx, struct registry_value);
if (value == NULL) {
- werr = WERR_NOMEM;
+ err = SBC_ERR_NOMEM;
goto done;
}
@@ -261,13 +270,13 @@ static WERROR smbconf_reg_set_multi_sz_value(struct registry_key *key,
for (count = 0; count < num_strings; count++) {
array[count] = talloc_strdup(value, strings[count]);
if (array[count] == NULL) {
- werr = WERR_NOMEM;
+ err = SBC_ERR_NOMEM;
goto done;
}
}
if (!push_reg_multi_sz(value, &value->data, array)) {
- werr = WERR_NOMEM;
+ err = SBC_ERR_NOMEM;
goto done;
}
@@ -275,11 +284,12 @@ static WERROR smbconf_reg_set_multi_sz_value(struct registry_key *key,
if (!W_ERROR_IS_OK(werr)) {
DEBUG(5, ("Error adding value '%s' to key '%s': %s\n",
valname, key->key->name, win_errstr(werr)));
+ err = SBC_ERR_ACCESS_DENIED;
}
done:
talloc_free(tmp_ctx);
- return werr;
+ return err;
}
/**
@@ -342,12 +352,13 @@ static char *smbconf_format_registry_value(TALLOC_CTX *mem_ctx,
return result;
}
-static WERROR smbconf_reg_get_includes_internal(TALLOC_CTX *mem_ctx,
+static sbcErr smbconf_reg_get_includes_internal(TALLOC_CTX *mem_ctx,
struct registry_key *key,
uint32_t *num_includes,
char ***includes)
{
WERROR werr;
+ sbcErr err;
uint32_t count;
struct registry_value *value = NULL;
char **tmp_includes = NULL;
@@ -358,31 +369,33 @@ static WERROR smbconf_reg_get_includes_internal(TALLOC_CTX *mem_ctx,
/* no includes */
*num_includes = 0;
*includes = NULL;
- werr = WERR_OK;
+ err = SBC_ERR_OK;
goto done;
}
werr = reg_queryvalue(tmp_ctx, key, INCLUDES_VALNAME, &value);
if (!W_ERROR_IS_OK(werr)) {
+ err = SBC_ERR_ACCESS_DENIED;
goto done;
}
if (value->type != REG_MULTI_SZ) {
/* wrong type -- ignore */
+ err = SBC_ERR_OK;
goto done;
}
if (!pull_reg_multi_sz(tmp_ctx, &value->data, &array)) {
- werr = WERR_NOMEM;
+ err = SBC_ERR_NOMEM;
goto done;
}
for (count = 0; array[count] != NULL; count++) {
- werr = smbconf_add_string_to_array(tmp_ctx,
+ err = smbconf_add_string_to_array(tmp_ctx,
&tmp_includes,
count,
array[count]);
- if (!W_ERROR_IS_OK(werr)) {
+ if (!SBC_ERROR_IS_OK(err)) {
goto done;
}
}
@@ -390,7 +403,7 @@ static WERROR smbconf_reg_get_includes_internal(TALLOC_CTX *mem_ctx,
if (count > 0) {
*includes = talloc_move(mem_ctx, &tmp_includes);
if (*includes == NULL) {
- werr = WERR_NOMEM;
+ err = SBC_ERR_NOMEM;
goto done;
}
*num_includes = count;
@@ -399,16 +412,17 @@ static WERROR smbconf_reg_get_includes_internal(TALLOC_CTX *mem_ctx,
*includes = NULL;
}
+ err = SBC_ERR_OK;
done:
talloc_free(tmp_ctx);
- return werr;
+ return err;
}
/**
* Get the values of a key as a list of value names
* and a list of value strings (ordered)
*/
-static WERROR smbconf_reg_get_values(TALLOC_CTX *mem_ctx,
+static sbcErr smbconf_reg_get_values(TALLOC_CTX *mem_ctx,
struct registry_key *key,
uint32_t *num_values,
char ***value_names,
@@ -416,6 +430,7 @@ static WERROR smbconf_reg_get_values(TALLOC_CTX *mem_ctx,
{
TALLOC_CTX *tmp_ctx = NULL;
WERROR werr = WERR_OK;
+ sbcErr err;
uint32_t count;
struct registry_value *valvalue = NULL;
char *valname = NULL;
@@ -428,7 +443,7 @@ static WERROR smbconf_reg_get_values(TALLOC_CTX *mem_ctx,
if ((num_values == NULL) || (value_names == NULL) ||
(value_strings == NULL))
{
- werr = WERR_INVALID_PARAM;
+ err = SBC_ERR_INVALID_PARAM;
goto done;
}
@@ -445,42 +460,44 @@ static WERROR smbconf_reg_get_values(TALLOC_CTX *mem_ctx,
continue;
}
- werr = smbconf_add_string_to_array(tmp_ctx,
- &tmp_valnames,
- tmp_num_values, valname);
- if (!W_ERROR_IS_OK(werr)) {
+ err = smbconf_add_string_to_array(tmp_ctx,
+ &tmp_valnames,
+ tmp_num_values, valname);
+ if (!SBC_ERROR_IS_OK(err)) {
goto done;
}
valstring = smbconf_format_registry_value(tmp_ctx, valvalue);
- werr = smbconf_add_string_to_array(tmp_ctx, &tmp_valstrings,
- tmp_num_values, valstring);
- if (!W_ERROR_IS_OK(werr)) {
+ err = smbconf_add_string_to_array(tmp_ctx, &tmp_valstrings,
+ tmp_num_values, valstring);
+ if (!SBC_ERROR_IS_OK(err)) {
goto done;
}
tmp_num_values++;
}
if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
+ err = SBC_ERR_NOMEM;
goto done;
}
/* now add the includes at the end */
- werr = smbconf_reg_get_includes_internal(tmp_ctx, key, &num_includes,
+ err = smbconf_reg_get_includes_internal(tmp_ctx, key, &num_includes,
&includes);
- if (!W_ERROR_IS_OK(werr)) {
+ if (!SBC_ERROR_IS_OK(err)) {
goto done;
}
+
for (count = 0; count < num_includes; count++) {
- werr = smbconf_add_string_to_array(tmp_ctx, &tmp_valnames,
- tmp_num_values, "include");
- if (!W_ERROR_IS_OK(werr)) {
+ err = smbconf_add_string_to_array(tmp_ctx, &tmp_valnames,
+ tmp_num_values, "include");
+ if (!SBC_ERROR_IS_OK(err)) {
goto done;
}
- werr = smbconf_add_string_to_array(tmp_ctx, &tmp_valstrings,
- tmp_num_values,
- includes[count]);
- if (!W_ERROR_IS_OK(werr)) {
+ err = smbconf_add_string_to_array(tmp_ctx, &tmp_valstrings,
+ tmp_num_values,
+ includes[count]);
+ if (!SBC_ERROR_IS_OK(err)) {
goto done;
}
@@ -498,7 +515,7 @@ static WERROR smbconf_reg_get_values(TALLOC_CTX *mem_ctx,
done:
talloc_free(tmp_ctx);
- return werr;
+ return err;
}
static bool smbconf_reg_key_has_values(struct registry_key *key)
@@ -527,9 +544,10 @@ static bool smbconf_reg_key_has_values(struct registry_key *key)
/**
* delete all values from a key
*/
-static WERROR smbconf_reg_delete_values(struct registry_key *key)
+static sbcErr smbconf_reg_delete_values(struct registry_key *key)
{
WERROR werr;
+ sbcErr err;
char *valname;
struct registry_value *valvalue;
uint32_t count;
@@ -542,6 +560,7 @@ static WERROR smbconf_reg_delete_values(struct registry_key *key)
{
werr = reg_deletevalue(key, valname);
if (!W_ERROR_IS_OK(werr)) {
+ err = SBC_ERR_ACCESS_DENIED;
goto done;
}
}
@@ -550,14 +569,15 @@ static WERROR smbconf_reg_delete_values(struct registry_key *key)
"Error enumerating values of %s: %s\n",
key->key->name,
win_errstr(werr)));
+ err = SBC_ERR_ACCESS_DENIED;
goto done;
}
- werr = WERR_OK;
+ err = SBC_ERR_OK;
done:
talloc_free(mem_ctx);
- return werr;
+ return err;
}
/**********************************************************************
@@ -569,9 +589,10 @@ done:
/**
* initialize the registry smbconf backend
*/
-static WERROR smbconf_reg_init(struct smbconf_ctx *ctx, const char *path)
+static sbcErr smbconf_reg_init(struct smbconf_ctx *ctx, const char *path)
{
WERROR werr = WERR_OK;
+ sbcErr err;
struct security_token *token;
if (path == NULL) {
@@ -579,26 +600,28 @@ static WERROR smbconf_reg_init(struct smbconf_ctx *ctx, const char *path)
}
ctx->path = talloc_strdup(ctx, path);
if (ctx->path == NULL) {
- werr = WERR_NOMEM;
+ err = SBC_ERR_NOMEM;
goto done;
}
- ctx->data = TALLOC_ZERO_P(ctx, struct reg_private_data);
+ ctx->data = talloc_zero(ctx, struct reg_private_data);
werr = ntstatus_to_werror(registry_create_admin_token(ctx, &token));
if (!W_ERROR_IS_OK(werr)) {
DEBUG(1, ("Error creating admin token\n"));
+ err = SBC_ERR_UNKNOWN_FAILURE;
goto done;
}
rpd(ctx)->open = false;
werr = registry_init_smbconf(path);
if (!W_ERROR_IS_OK(werr)) {
+ err = SBC_ERR_BADFILE;
goto done;
}
- werr = ctx->ops->open_conf(ctx);
- if (!W_ERROR_IS_OK(werr)) {
+ err = ctx->ops->open_conf(ctx);
+ if (!SBC_ERROR_IS_OK(err)) {
DEBUG(1, ("Error opening the registry.\n"));
goto done;
}
@@ -607,11 +630,12 @@ static WERROR smbconf_reg_init(struct smbconf_ctx *ctx, const char *path)
KEY_ENUMERATE_SUB_KEYS | REG_KEY_WRITE,
token, &rpd(ctx)->base_key);
if (!W_ERROR_IS_OK(werr)) {
+ err = SBC_ERR_UNKNOWN_FAILURE;
goto done;
}
done:
- return werr;
+ return err;
}
static int smbconf_reg_shutdown(struct smbconf_ctx *ctx)
@@ -640,19 +664,21 @@ static bool smbconf_reg_is_writeable(struct smbconf_ctx *ctx)
return true;
}
-static WERROR smbconf_reg_open(struct smbconf_ctx *ctx)
+static sbcErr smbconf_reg_open(struct smbconf_ctx *ctx)
{
WERROR werr;
if (rpd(ctx)->open) {
- return WERR_OK;
+ return SBC_ERR_OK;
}
werr = regdb_open();
- if (W_ERROR_IS_OK(werr)) {
- rpd(ctx)->open = true;
+ if (!W_ERROR_IS_OK(werr)) {
+ return SBC_ERR_BADFILE;
}
- return werr;
+
+ rpd(ctx)->open = true;
+ return SBC_ERR_OK;
}
static int smbconf_reg_close(struct smbconf_ctx *ctx)
@@ -682,7 +708,7 @@ static void smbconf_reg_get_csn(struct smbconf_ctx *ctx,
return;
}
- if (!W_ERROR_IS_OK(ctx->ops->open_conf(ctx))) {
+ if (!SBC_ERROR_IS_OK(ctx->ops->open_conf(ctx))) {
return;
}
@@ -692,10 +718,11 @@ static void smbconf_reg_get_csn(struct smbconf_ctx *ctx,
/**
* Drop the whole configuration (restarting empty) - registry version
*/
-static WERROR smbconf_reg_drop(struct smbconf_ctx *ctx)
+static sbcErr smbconf_reg_drop(struct smbconf_ctx *ctx)
{
char *path, *p;
WERROR werr = WERR_OK;
+ sbcErr err = SBC_ERR_OK;
struct registry_key *parent_key = NULL;
struct registry_key *new_key = NULL;
TALLOC_CTX* mem_ctx = talloc_stackframe();
@@ -705,46 +732,51 @@ static WERROR smbconf_reg_drop(struct smbconf_ctx *ctx)
werr = ntstatus_to_werror(registry_create_admin_token(ctx, &token));
if (!W_ERROR_IS_OK(werr)) {
DEBUG(1, ("Error creating admin token\n"));
+ err = SBC_ERR_UNKNOWN_FAILURE;
goto done;
}
path = talloc_strdup(mem_ctx, ctx->path);
if (path == NULL) {
- werr = WERR_NOMEM;
+ err = SBC_ERR_NOMEM;
goto done;
}
p = strrchr(path, '\\');
if (p == NULL) {
- werr = WERR_INVALID_PARAM;
+ err = SBC_ERR_INVALID_PARAM;
goto done;
}
*p = '\0';
werr = reg_open_path(mem_ctx, path, REG_KEY_WRITE, token,
&parent_key);
-
if (!W_ERROR_IS_OK(werr)) {
+ err = SBC_ERR_IO_FAILURE;
goto done;
}
werr = reg_deletekey_recursive(parent_key, p+1);
-
if (!W_ERROR_IS_OK(werr)) {
+ err = SBC_ERR_IO_FAILURE;
goto done;
}
werr = reg_createkey(mem_ctx, parent_key, p+1, REG_KEY_WRITE,
&new_key, &action);
+ if (!W_ERROR_IS_OK(werr)) {
+ err = SBC_ERR_IO_FAILURE;
+ goto done;
+ }
done:
talloc_free(mem_ctx);
- return werr;
+ return err;
}
/**
* get the list of share names defined in the configuration.
* registry version.
*/
-static WERROR smbconf_reg_get_share_names(struct smbconf_ctx *ctx,
+static sbcErr smbconf_reg_get_share_names(struct smbconf_ctx *ctx,
TALLOC_CTX *mem_ctx,
uint32_t *num_shares,
char ***share_names)
@@ -752,13 +784,13 @@ static WERROR smbconf_reg_get_share_names(struct smbconf_ctx *ctx,
uint32_t count;
uint32_t added_count = 0;
TALLOC_CTX *tmp_ctx = NULL;
- WERROR werr = WERR_OK;
+ WERROR werr;
+ sbcErr err = SBC_ERR_OK;
char *subkey_name = NULL;
char **tmp_share_names = NULL;
if ((num_shares == NULL) || (share_names == NULL)) {
- werr = WERR_INVALID_PARAM;
- goto done;
+ return SBC_ERR_INVALID_PARAM;
}
tmp_ctx = talloc_stackframe();
@@ -766,9 +798,9 @@ static WERROR smbconf_reg_get_share_names(struct smbconf_ctx *ctx,
/* if there are values in the base key, return NULL as share name */
if (smbconf_reg_key_has_values(rpd(ctx)->base_key)) {
- werr = smbconf_add_string_to_array(tmp_ctx, &tmp_share_names,
+ err = smbconf_add_string_to_array(tmp_ctx, &tmp_share_names,
0, NULL);
- if (!W_ERROR_IS_OK(werr)) {
+ if (!SBC_ERROR_IS_OK(err)) {
goto done;
}
added_count++;
@@ -776,9 +808,9 @@ static WERROR smbconf_reg_get_share_names(struct smbconf_ctx *ctx,
/* make sure "global" is always listed first */
if (smbconf_share_exists(ctx, GLOBAL_NAME)) {
- werr = smbconf_add_string_to_array(tmp_ctx, &tmp_share_names,
- added_count, GLOBAL_NAME);
- if (!W_ERROR_IS_OK(werr)) {
+ err = smbconf_add_string_to_array(tmp_ctx, &tmp_share_names,
+ added_count, GLOBAL_NAME);
+ if (!SBC_ERROR_IS_OK(err)) {
goto done;
}
added_count++;
@@ -794,19 +826,20 @@ static WERROR smbconf_reg_get_share_names(struct smbconf_ctx *ctx,
continue;
}
- werr = smbconf_add_string_to_array(tmp_ctx,
+ err = smbconf_add_string_to_array(tmp_ctx,
&tmp_share_names,
added_count,
subkey_name);
- if (!W_ERROR_IS_OK(werr)) {
+ if (!SBC_ERROR_IS_OK(err)) {
goto done;
}
added_count++;
}
if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
+ err = SBC_ERR_NO_MORE_ITEMS;
goto done;
}
- werr = WERR_OK;
+ err = SBC_ERR_OK;
*num_shares = added_count;
if (added_count > 0) {
@@ -817,7 +850,7 @@ static WERROR smbconf_reg_get_share_names(struct smbconf_ctx *ctx,
done:
talloc_free(tmp_ctx);
- return werr;
+ return err;
}
/**
@@ -827,13 +860,13 @@ static bool smbconf_reg_share_exists(struct smbconf_ctx *ctx,
const char *servicename)
{
bool ret = false;
- WERROR werr = WERR_OK;
+ sbcErr err;
TALLOC_CTX *mem_ctx = talloc_stackframe();
struct registry_key *key = NULL;
- werr = smbconf_reg_open_service_key(mem_ctx, ctx, servicename,
- REG_KEY_READ, &key);
- if (W_ERROR_IS_OK(werr)) {
+ err = smbconf_reg_open_service_key(mem_ctx, ctx, servicename,
+ REG_KEY_READ, &key);
+ if (SBC_ERROR_IS_OK(err)) {
ret = true;
}
@@ -844,286 +877,330 @@ static bool smbconf_reg_share_exists(struct smbconf_ctx *ctx,
/**
* Add a service if it does not already exist - registry version
*/
-static WERROR smbconf_reg_create_share(struct smbconf_ctx *ctx,
+static sbcErr smbconf_reg_create_share(struct smbconf_ctx *ctx,
const char *servicename)
{
- WERROR werr;
+ sbcErr err;
struct registry_key *key = NULL;
if (servicename == NULL) {
- return WERR_OK;
+ return SBC_ERR_OK;
}
- werr = smbconf_reg_create_service_key(talloc_tos(), ctx,
- servicename, &key);
+ err = smbconf_reg_create_service_key(talloc_tos(), ctx,
+ servicename, &key);
talloc_free(key);
- return werr;
+ return err;
}
/**
* get a definition of a share (service) from configuration.
*/
-static WERROR smbconf_reg_get_share(struct smbconf_ctx *ctx,
+static sbcErr smbconf_reg_get_share(struct smbconf_ctx *ctx,
TALLOC_CTX *mem_ctx,
const char *servicename,
struct smbconf_service **service)
{
- WERROR werr = WERR_OK;
+ sbcErr err;
struct registry_key *key = NULL;
struct smbconf_service *tmp_service = NULL;
TALLOC_CTX *tmp_ctx = talloc_stackframe();
- werr = smbconf_reg_open_service_key(tmp_ctx, ctx, servicename,
- REG_KEY_READ, &key);
- if (!W_ERROR_IS_OK(werr)) {
+ err = smbconf_reg_open_service_key(tmp_ctx, ctx, servicename,
+ REG_KEY_READ, &key);
+ if (!SBC_ERROR_IS_OK(err)) {
goto done;
}
- tmp_service = TALLOC_ZERO_P(tmp_ctx, struct smbconf_service);
+ tmp_service = talloc_zero(tmp_ctx, struct smbconf_service);
if (tmp_service == NULL) {
- werr = WERR_NOMEM;
+ err = SBC_ERR_NOMEM;
goto done;
}
if (servicename != NULL) {
tmp_service->name = talloc_strdup(tmp_service, servicename);
if (tmp_service->name == NULL) {
- werr = WERR_NOMEM;
+ err = SBC_ERR_NOMEM;
goto done;
}
}
- werr = smbconf_reg_get_values(tmp_service, key,
- &(tmp_service->num_params),
- &(tmp_service->param_names),
- &(tmp_service->param_values));
-
- if (W_ERROR_IS_OK(werr)) {
+ err = smbconf_reg_get_values(tmp_service, key,
+ &(tmp_service->num_params),
+ &(tmp_service->param_names),
+ &(tmp_service->param_values));
+ if (SBC_ERROR_IS_OK(err)) {
*service = talloc_move(mem_ctx, &tmp_service);
}
done:
talloc_free(tmp_ctx);
- return werr;
+ return err;
}
/**
* delete a service from configuration
*/
-static WERROR smbconf_reg_delete_share(struct smbconf_ctx *ctx,
+static sbcErr smbconf_reg_delete_share(struct smbconf_ctx *ctx,
const char *servicename)
{
- WERROR werr = WERR_OK;
+ WERROR werr;
+ sbcErr err = SBC_ERR_OK;
TALLOC_CTX *mem_ctx = talloc_stackframe();
if (servicename != NULL) {
werr = reg_deletekey_recursive(rpd(ctx)->base_key, servicename);
+ if (!W_ERROR_IS_OK(werr)) {
+ err = SBC_ERR_ACCESS_DENIED;
+ }
} else {
- werr = smbconf_reg_delete_values(rpd(ctx)->base_key);
+ err = smbconf_reg_delete_values(rpd(ctx)->base_key);
}
talloc_free(mem_ctx);
- return werr;
+ return err;
}
/**
* set a configuration parameter to the value provided.
*/
-static WERROR smbconf_reg_set_parameter(struct smbconf_ctx *ctx,
+static sbcErr smbconf_reg_set_parameter(struct smbconf_ctx *ctx,
const char *service,
const char *param,
const char *valstr)
{
- WERROR werr;
+ sbcErr err;
struct registry_key *key = NULL;
TALLOC_CTX *mem_ctx = talloc_stackframe();
- werr = smbconf_reg_open_service_key(mem_ctx, ctx, service,
- REG_KEY_WRITE, &key);
- if (!W_ERROR_IS_OK(werr)) {
+ err = smbconf_reg_open_service_key(mem_ctx, ctx, service,
+ REG_KEY_WRITE, &key);
+ if (!SBC_ERROR_IS_OK(err)) {
goto done;
}
- werr = smbconf_reg_set_value(key, param, valstr);
+ err = smbconf_reg_set_value(key, param, valstr);
done:
talloc_free(mem_ctx);
- return werr;
+ return err;
}
/**
* get the value of a configuration parameter as a string
*/
-static WERROR smbconf_reg_get_parameter(struct smbconf_ctx *ctx,
+static sbcErr smbconf_reg_get_parameter(struct smbconf_ctx *ctx,
TALLOC_CTX *mem_ctx,
const char *service,
const char *param,
char **valstr)
{
WERROR werr = WERR_OK;
+ sbcErr err;
struct registry_key *key = NULL;
struct registry_value *value = NULL;
- werr = smbconf_reg_open_service_key(mem_ctx, ctx, service,
- REG_KEY_READ, &key);
- if (!W_ERROR_IS_OK(werr)) {
+ err = smbconf_reg_open_service_key(mem_ctx, ctx, service,
+ REG_KEY_READ, &key);
+ if (!SBC_ERROR_IS_OK(err)) {
goto done;
}
if (!smbconf_reg_valname_valid(param)) {
- werr = WERR_INVALID_PARAM;
+ err = SBC_ERR_INVALID_PARAM;
goto done;
}
if (!smbconf_value_exists(key, param)) {
- werr = WERR_INVALID_PARAM;
+ err = SBC_ERR_INVALID_PARAM;
goto done;
}
werr = reg_queryvalue(mem_ctx, key, param, &value);
if (!W_ERROR_IS_OK(werr)) {
+ err = SBC_ERR_NOMEM;
goto done;
}
*valstr = smbconf_format_registry_value(mem_ctx, value);
-
if (*valstr == NULL) {
- werr = WERR_NOMEM;
+ err = SBC_ERR_NOMEM;
}
done:
talloc_free(key);
talloc_free(value);
- return werr;
+ return err;
}
/**
* delete a parameter from configuration
*/
-static WERROR smbconf_reg_delete_parameter(struct smbconf_ctx *ctx,
+static sbcErr smbconf_reg_delete_parameter(struct smbconf_ctx *ctx,
const char *service,
const char *param)
{
struct registry_key *key = NULL;
- WERROR werr = WERR_OK;
+ WERROR werr;
+ sbcErr err;
TALLOC_CTX *mem_ctx = talloc_stackframe();
- werr = smbconf_reg_open_service_key(mem_ctx, ctx, service,
- REG_KEY_ALL, &key);
- if (!W_ERROR_IS_OK(werr)) {
+ err = smbconf_reg_open_service_key(mem_ctx, ctx, service,
+ REG_KEY_ALL, &key);
+ if (!SBC_ERROR_IS_OK(err)) {
goto done;
}
if (!smbconf_reg_valname_valid(param)) {
- werr = WERR_INVALID_PARAM;
+ err = SBC_ERR_INVALID_PARAM;
goto done;
}
if (!smbconf_value_exists(key, param)) {
- werr = WERR_INVALID_PARAM;
+ err = SBC_ERR_OK;
goto done;
}
werr = reg_deletevalue(key, param);
+ if (!W_ERROR_IS_OK(werr)) {
+ err = SBC_ERR_ACCESS_DENIED;
+ }
done:
talloc_free(mem_ctx);
- return werr;
+ return err;
}
-static WERROR smbconf_reg_get_includes(struct smbconf_ctx *ctx,
+static sbcErr smbconf_reg_get_includes(struct smbconf_ctx *ctx,
TALLOC_CTX *mem_ctx,
const char *service,
uint32_t *num_includes,
char ***includes)
{
- WERROR werr;
+ sbcErr err;
struct registry_key *key = NULL;
TALLOC_CTX *tmp_ctx = talloc_stackframe();
- werr = smbconf_reg_open_service_key(tmp_ctx, ctx, service,
- REG_KEY_READ, &key);
- if (!W_ERROR_IS_OK(werr)) {
+ err = smbconf_reg_open_service_key(tmp_ctx, ctx, service,
+ REG_KEY_READ, &key);
+ if (!SBC_ERROR_IS_OK(err)) {
goto done;
}
- werr = smbconf_reg_get_includes_internal(mem_ctx, key, num_includes,
+ err = smbconf_reg_get_includes_internal(mem_ctx, key, num_includes,
includes);
+ if (!SBC_ERROR_IS_OK(err)) {
+ goto done;
+ }
done:
talloc_free(tmp_ctx);
- return werr;
+ return err;
}
-static WERROR smbconf_reg_set_includes(struct smbconf_ctx *ctx,
+static sbcErr smbconf_reg_set_includes(struct smbconf_ctx *ctx,
const char *service,
uint32_t num_includes,
const char **includes)
{
WERROR werr = WERR_OK;
+ sbcErr err;
struct registry_key *key = NULL;
TALLOC_CTX *tmp_ctx = talloc_stackframe();
- werr = smbconf_reg_open_service_key(tmp_ctx, ctx, service,
- REG_KEY_ALL, &key);
- if (!W_ERROR_IS_OK(werr)) {
+ err = smbconf_reg_open_service_key(tmp_ctx, ctx, service,
+ REG_KEY_ALL, &key);
+ if (!SBC_ERROR_IS_OK(err)) {
goto done;
}
if (num_includes == 0) {
if (!smbconf_value_exists(key, INCLUDES_VALNAME)) {
+ err = SBC_ERR_OK;
goto done;
}
werr = reg_deletevalue(key, INCLUDES_VALNAME);
+ if (!W_ERROR_IS_OK(werr)) {
+ err = SBC_ERR_ACCESS_DENIED;
+ goto done;
+ }
} else {
- werr = smbconf_reg_set_multi_sz_value(key, INCLUDES_VALNAME,
+ err = smbconf_reg_set_multi_sz_value(key, INCLUDES_VALNAME,
num_includes, includes);
}
done:
talloc_free(tmp_ctx);
- return werr;
+ return err;
}
-static WERROR smbconf_reg_delete_includes(struct smbconf_ctx *ctx,
+static sbcErr smbconf_reg_delete_includes(struct smbconf_ctx *ctx,
const char *service)
{
- WERROR werr = WERR_OK;
+ WERROR werr;
+ sbcErr err;
struct registry_key *key = NULL;
TALLOC_CTX *tmp_ctx = talloc_stackframe();
- werr = smbconf_reg_open_service_key(tmp_ctx, ctx, service,
- REG_KEY_ALL, &key);
- if (!W_ERROR_IS_OK(werr)) {
+ err = smbconf_reg_open_service_key(tmp_ctx, ctx, service,
+ REG_KEY_ALL, &key);
+ if (!SBC_ERROR_IS_OK(err)) {
goto done;
}
if (!smbconf_value_exists(key, INCLUDES_VALNAME)) {
+ err = SBC_ERR_OK;
goto done;
}
werr = reg_deletevalue(key, INCLUDES_VALNAME);
+ if (!W_ERROR_IS_OK(werr)) {
+ err = SBC_ERR_ACCESS_DENIED;
+ goto done;
+ }
-
+ err = SBC_ERR_OK;
done:
talloc_free(tmp_ctx);
- return werr;
+ return err;
}
-static WERROR smbconf_reg_transaction_start(struct smbconf_ctx *ctx)
+static sbcErr smbconf_reg_transaction_start(struct smbconf_ctx *ctx)
{
- return regdb_transaction_start();
+ WERROR werr;
+
+ werr = regdb_transaction_start();
+ if (!W_ERROR_IS_OK(werr)) {
+ return SBC_ERR_IO_FAILURE;
+ }
+
+ return SBC_ERR_OK;
}
-static WERROR smbconf_reg_transaction_commit(struct smbconf_ctx *ctx)
+static sbcErr smbconf_reg_transaction_commit(struct smbconf_ctx *ctx)
{
- return regdb_transaction_commit();
+ WERROR werr;
+
+ werr = regdb_transaction_commit();
+ if (!W_ERROR_IS_OK(werr)) {
+ return SBC_ERR_IO_FAILURE;
+ }
+
+ return SBC_ERR_OK;
}
-static WERROR smbconf_reg_transaction_cancel(struct smbconf_ctx *ctx)
+static sbcErr smbconf_reg_transaction_cancel(struct smbconf_ctx *ctx)
{
- return regdb_transaction_cancel();
+ WERROR werr;
+
+ werr = regdb_transaction_cancel();
+ if (!W_ERROR_IS_OK(werr)) {
+ return SBC_ERR_IO_FAILURE;
+ }
+
+ return SBC_ERR_OK;
}
struct smbconf_ops smbconf_ops_reg = {
@@ -1156,7 +1233,7 @@ struct smbconf_ops smbconf_ops_reg = {
* initialize the smbconf registry backend
* the only function that is exported from this module
*/
-WERROR smbconf_init_reg(TALLOC_CTX *mem_ctx, struct smbconf_ctx **conf_ctx,
+sbcErr smbconf_init_reg(TALLOC_CTX *mem_ctx, struct smbconf_ctx **conf_ctx,
const char *path)
{
return smbconf_init_internal(mem_ctx, conf_ctx, path, &smbconf_ops_reg);
diff --git a/source3/lib/smbconf/smbconf_reg.h b/source3/lib/smbconf/smbconf_reg.h
index 7f54b6e32d..2c49057a94 100644
--- a/source3/lib/smbconf/smbconf_reg.h
+++ b/source3/lib/smbconf/smbconf_reg.h
@@ -26,7 +26,7 @@ struct smbconf_ctx;
* initialization functions for the registry backend modules
*/
-WERROR smbconf_init_reg(TALLOC_CTX *mem_ctx, struct smbconf_ctx **conf_ctx,
+sbcErr smbconf_init_reg(TALLOC_CTX *mem_ctx, struct smbconf_ctx **conf_ctx,
const char *path);
diff --git a/source3/lib/smbconf/testsuite.c b/source3/lib/smbconf/testsuite.c
index 80754dd20c..c2a9a59cbe 100644
--- a/source3/lib/smbconf/testsuite.c
+++ b/source3/lib/smbconf/testsuite.c
@@ -40,17 +40,17 @@ static void print_strings(const char *prefix,
static bool test_get_includes(struct smbconf_ctx *ctx)
{
- WERROR werr;
+ sbcErr err;
bool ret = false;
uint32_t num_includes = 0;
char **includes = NULL;
TALLOC_CTX *mem_ctx = talloc_stackframe();
printf("TEST: get_includes\n");
- werr = smbconf_get_global_includes(ctx, mem_ctx,
- &num_includes, &includes);
- if (!W_ERROR_IS_OK(werr)) {
- printf("FAIL: get_includes - %s\n", win_errstr(werr));
+ err = smbconf_get_global_includes(ctx, mem_ctx,
+ &num_includes, &includes);
+ if (!SBC_ERROR_IS_OK(err)) {
+ printf("FAIL: get_includes - %s\n", sbcErrorString(err));
goto done;
}
@@ -68,7 +68,7 @@ done:
static bool test_set_get_includes(struct smbconf_ctx *ctx)
{
- WERROR werr;
+ sbcErr err;
uint32_t count;
bool ret = false;
const char *set_includes[] = {
@@ -82,18 +82,18 @@ static bool test_set_get_includes(struct smbconf_ctx *ctx)
printf("TEST: set_get_includes\n");
- werr = smbconf_set_global_includes(ctx, set_num_includes, set_includes);
- if (!W_ERROR_IS_OK(werr)) {
+ err = smbconf_set_global_includes(ctx, set_num_includes, set_includes);
+ if (!SBC_ERROR_IS_OK(err)) {
printf("FAIL: get_set_includes (setting includes) - %s\n",
- win_errstr(werr));
+ sbcErrorString(err));
goto done;
}
- werr = smbconf_get_global_includes(ctx, mem_ctx, &get_num_includes,
- &get_includes);
- if (!W_ERROR_IS_OK(werr)) {
+ err = smbconf_get_global_includes(ctx, mem_ctx, &get_num_includes,
+ &get_includes);
+ if (!SBC_ERROR_IS_OK(err)) {
printf("FAIL: get_set_includes (getting includes) - %s\n",
- win_errstr(werr));
+ sbcErrorString(err));
goto done;
}
@@ -125,7 +125,7 @@ done:
static bool test_delete_includes(struct smbconf_ctx *ctx)
{
- WERROR werr;
+ sbcErr err;
bool ret = false;
const char *set_includes[] = {
"/path/to/include",
@@ -137,25 +137,25 @@ static bool test_delete_includes(struct smbconf_ctx *ctx)
printf("TEST: delete_includes\n");
- werr = smbconf_set_global_includes(ctx, set_num_includes, set_includes);
- if (!W_ERROR_IS_OK(werr)) {
+ err = smbconf_set_global_includes(ctx, set_num_includes, set_includes);
+ if (!SBC_ERROR_IS_OK(err)) {
printf("FAIL: delete_includes (setting includes) - %s\n",
- win_errstr(werr));
+ sbcErrorString(err));
goto done;
}
- werr = smbconf_delete_global_includes(ctx);
- if (!W_ERROR_IS_OK(werr)) {
+ err = smbconf_delete_global_includes(ctx);
+ if (!SBC_ERROR_IS_OK(err)) {
printf("FAIL: delete_includes (deleting includes) - %s\n",
- win_errstr(werr));
+ sbcErrorString(err));
goto done;
}
- werr = smbconf_get_global_includes(ctx, mem_ctx, &get_num_includes,
- &get_includes);
- if (!W_ERROR_IS_OK(werr)) {
+ err = smbconf_get_global_includes(ctx, mem_ctx, &get_num_includes,
+ &get_includes);
+ if (!SBC_ERROR_IS_OK(err)) {
printf("FAIL: delete_includes (getting includes) - %s\n",
- win_errstr(werr));
+ sbcErrorString(err));
goto done;
}
@@ -164,10 +164,10 @@ static bool test_delete_includes(struct smbconf_ctx *ctx)
goto done;
}
- werr = smbconf_delete_global_includes(ctx);
- if (!W_ERROR_IS_OK(werr)) {
+ err = smbconf_delete_global_includes(ctx);
+ if (!SBC_ERROR_IS_OK(err)) {
printf("FAIL: delete_includes (delete empty includes) - "
- "%s\n", win_errstr(werr));
+ "%s\n", sbcErrorString(err));
goto done;
}
@@ -203,7 +203,7 @@ static bool create_conf_file(const char *filename)
static bool torture_smbconf_txt(void)
{
- WERROR werr;
+ sbcErr err;
bool ret = true;
const char *filename = "/tmp/smb.conf.smbconf_testsuite";
struct smbconf_ctx *conf_ctx = NULL;
@@ -217,9 +217,9 @@ static bool torture_smbconf_txt(void)
}
printf("TEST: init\n");
- werr = smbconf_init_txt(mem_ctx, &conf_ctx, filename);
- if (!W_ERROR_IS_OK(werr)) {
- printf("FAIL: text backend failed: %s\n", win_errstr(werr));
+ err = smbconf_init_txt(mem_ctx, &conf_ctx, filename);
+ if (!SBC_ERROR_IS_OK(err)) {
+ printf("FAIL: text backend failed: %s\n", sbcErrorString(err));
ret = false;
goto done;
}
@@ -245,7 +245,7 @@ done:
static bool torture_smbconf_reg(void)
{
- WERROR werr;
+ sbcErr err;
bool ret = true;
struct smbconf_ctx *conf_ctx = NULL;
TALLOC_CTX *mem_ctx = talloc_stackframe();
@@ -253,9 +253,9 @@ static bool torture_smbconf_reg(void)
printf("test: registry backend\n");
printf("TEST: init\n");
- werr = smbconf_init_reg(mem_ctx, &conf_ctx, NULL);
- if (!W_ERROR_IS_OK(werr)) {
- printf("FAIL: init failed: %s\n", win_errstr(werr));
+ err = smbconf_init_reg(mem_ctx, &conf_ctx, NULL);
+ if (!SBC_ERROR_IS_OK(err)) {
+ printf("FAIL: init failed: %s\n", sbcErrorString(err));
ret = false;
goto done;
}
diff --git a/source3/lib/dummysmbd.c b/source3/lib/smbd_shim.c
index 2465e6552b..72ae366ec3 100644
--- a/source3/lib/dummysmbd.c
+++ b/source3/lib/smbd_shim.c
@@ -3,6 +3,7 @@
RPC pipe client
Copyright (C) Gerald (Jerry) Carter 2004.
+ Copyright (C) Andrew Bartlett 2011.
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
@@ -18,48 +19,55 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* Stupid dummy functions required due to the horrible dependency mess
+/* Shim functions required due to the horrible dependency mess
in Samba. */
#include "includes.h"
+#include "smbd_shim.h"
+#include "smbd/proto.h"
-int find_service(TALLOC_CTX *ctx, const char *service_in, char **p_service_out)
-{
- return -1;
-}
+static struct smbd_shim shim;
-bool conn_snum_used(int snum)
+void set_smbd_shim(const struct smbd_shim *shim_functions)
{
- return False;
+ shim = *shim_functions;
}
void cancel_pending_lock_requests_by_fid(files_struct *fsp,
struct byte_range_lock *br_lck,
enum file_close_type close_type)
{
+ if (shim.cancel_pending_lock_requests_by_fid) {
+
+ shim.cancel_pending_lock_requests_by_fid(fsp, br_lck, close_type);
+ }
}
void send_stat_cache_delete_message(struct messaging_context *msg_ctx,
const char *name)
{
+ if (shim.send_stat_cache_delete_message) {
+ shim.send_stat_cache_delete_message(msg_ctx, name);
+ }
}
NTSTATUS can_delete_directory(struct connection_struct *conn,
const char *dirname)
{
+ if (shim.can_delete_directory) {
+ return shim.can_delete_directory(conn, dirname);
+ }
return NT_STATUS_OK;
}
bool change_to_root_user(void)
{
+ if (shim.change_to_root_user) {
+ return shim.change_to_root_user();
+ }
return false;
}
-struct event_context *smbd_event_context(void)
-{
- return NULL;
-}
-
/**
* The following two functions need to be called from inside the low-level BRL
* code for oplocks correctness in smbd. Since other utility binaries also
@@ -70,11 +78,33 @@ struct event_context *smbd_event_context(void)
void contend_level2_oplocks_begin(files_struct *fsp,
enum level2_contention_type type)
{
+ if (shim.contend_level2_oplocks_begin) {
+ shim.contend_level2_oplocks_begin(fsp, type);
+ }
return;
}
void contend_level2_oplocks_end(files_struct *fsp,
enum level2_contention_type type)
{
+ if (shim.contend_level2_oplocks_end) {
+ shim.contend_level2_oplocks_end(fsp, type);
+ }
+ return;
+}
+
+void become_root(void)
+{
+ if (shim.become_root) {
+ shim.become_root();
+ }
+ return;
+}
+
+void unbecome_root(void)
+{
+ if (shim.unbecome_root) {
+ shim.unbecome_root();
+ }
return;
}
diff --git a/source3/lib/smbd_shim.h b/source3/lib/smbd_shim.h
new file mode 100644
index 0000000000..89cae2b694
--- /dev/null
+++ b/source3/lib/smbd_shim.h
@@ -0,0 +1,56 @@
+/*
+ Unix SMB/CIFS implementation.
+ RPC pipe client
+
+ Copyright (C) Gerald (Jerry) Carter 2004.
+ Copyright (C) Andrew Bartlett 2011.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ shim functions are used required to allow library code to have
+ references to smbd specific code. The smbd daemon sets up the set
+ of function calls that it wants used by calling
+ set_smbd_shim(). Other executables don't make this call, and get
+ default (dummy) versions of these functions.
+*/
+
+struct smbd_shim
+{
+ void (*cancel_pending_lock_requests_by_fid)(files_struct *fsp,
+ struct byte_range_lock *br_lck,
+ enum file_close_type close_type);
+ void (*send_stat_cache_delete_message)(struct messaging_context *msg_ctx,
+ const char *name);
+
+ NTSTATUS (*can_delete_directory)(struct connection_struct *conn,
+ const char *dirname);
+
+ bool (*change_to_root_user)(void);
+
+ void (*contend_level2_oplocks_begin)(files_struct *fsp,
+ enum level2_contention_type type);
+
+ void (*contend_level2_oplocks_end)(files_struct *fsp,
+ enum level2_contention_type type);
+
+ void (*become_root)(void);
+
+ void (*unbecome_root)(void);
+};
+
+void set_smbd_shim(const struct smbd_shim *shim_functions);
+
+
diff --git a/source3/lib/smbldap.c b/source3/lib/smbldap.c
index fe43237464..38c7b207f5 100644
--- a/source3/lib/smbldap.c
+++ b/source3/lib/smbldap.c
@@ -239,7 +239,7 @@ ATTRIB_MAP_ENTRY sidmap_attr_list[] = {
i++;
i++;
- names = TALLOC_ARRAY( mem_ctx, const char*, i );
+ names = talloc_array( mem_ctx, const char*, i );
if ( !names ) {
DEBUG(0,("get_attr_list: out of memory\n"));
return NULL;
@@ -405,7 +405,7 @@ ATTRIB_MAP_ENTRY sidmap_attr_list[] = {
return NULL;
}
- if (StrCaseCmp(tmp, result) < 0) {
+ if (strcasecmp_m(tmp, result) < 0) {
TALLOC_FREE(result);
result = tmp;
} else {
@@ -474,7 +474,7 @@ ATTRIB_MAP_ENTRY sidmap_attr_list[] = {
return;
}
- handle = TALLOC_P(mem_ctx, LDAPMessage *);
+ handle = talloc(mem_ctx, LDAPMessage *);
SMB_ASSERT(handle != NULL);
*handle = result;
@@ -494,7 +494,7 @@ ATTRIB_MAP_ENTRY sidmap_attr_list[] = {
return;
}
- handle = TALLOC_P(mem_ctx, LDAPMod **);
+ handle = talloc(mem_ctx, LDAPMod **);
SMB_ASSERT(handle != NULL);
*handle = mod;
@@ -654,7 +654,7 @@ static void smbldap_make_mod_internal(LDAP *ldap_struct, LDAPMessage *existing,
equal = (newblob && (data_blob_cmp(&oldblob, newblob) == 0));
} else {
/* all of our string attributes are case insensitive */
- equal = (newval && (StrCaseCmp(oldval, newval) == 0));
+ equal = (newval && (strcasecmp_m(oldval, newval) == 0));
}
if (equal) {
@@ -1480,7 +1480,7 @@ static int smbldap_search_ext(struct smbldap_state *ldap_state,
while (another_ldap_try(ldap_state, &rc, &attempts, endtime)) {
rc = ldap_search_ext_s(ldap_state->ldap_struct, base, scope,
utf8_filter,
- CONST_DISCARD(char **, attrs),
+ discard_const_p(char *, attrs),
attrsonly, sctrls, cctrls, &timeout,
sizelimit, res);
if (rc != LDAP_SUCCESS) {
@@ -1562,7 +1562,7 @@ int smbldap_search_paged(struct smbldap_state *ldap_state,
}
ber_flatten(cookie_be, &cookie_bv);
- pr.ldctl_oid = CONST_DISCARD(char *, ADS_PAGE_CTL_OID);
+ pr.ldctl_oid = discard_const_p(char, ADS_PAGE_CTL_OID);
pr.ldctl_iscritical = (char) critical;
pr.ldctl_value.bv_len = cookie_bv->bv_len;
pr.ldctl_value.bv_val = cookie_bv->bv_val;
@@ -1862,7 +1862,7 @@ NTSTATUS smbldap_init(TALLOC_CTX *mem_ctx, struct event_context *event_ctx,
const char *location,
struct smbldap_state **smbldap_state)
{
- *smbldap_state = TALLOC_ZERO_P(mem_ctx, struct smbldap_state);
+ *smbldap_state = talloc_zero(mem_ctx, struct smbldap_state);
if (!*smbldap_state) {
DEBUG(0, ("talloc() failed for ldapsam private_data!\n"));
return NT_STATUS_NO_MEMORY;
@@ -1924,7 +1924,7 @@ static bool smbldap_check_root_dse(LDAP *ld, const char **attrs, const char *val
}
rc = ldap_search_s(ld, "", LDAP_SCOPE_BASE,
- "(objectclass=*)", CONST_DISCARD(char **, attrs), 0 , &msg);
+ "(objectclass=*)", discard_const_p(char *, attrs), 0 , &msg);
if (rc != LDAP_SUCCESS) {
DEBUG(3,("smbldap_check_root_dse: Could not search rootDSE\n"));
diff --git a/source3/lib/string_init.c b/source3/lib/string_init.c
new file mode 100644
index 0000000000..40a6ef059b
--- /dev/null
+++ b/source3/lib/string_init.c
@@ -0,0 +1,77 @@
+/*
+ Unix SMB/CIFS implementation.
+ Samba utility functions
+
+ Copyright (C) Andrew Tridgell 1992-2001
+ Copyright (C) Simo Sorce 2001-2002
+ Copyright (C) Martin Pool 2003
+ Copyright (C) James Peach 2006
+ Copyright (C) Jeremy Allison 1992-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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+
+/* this is used to prevent lots of mallocs of size 1 */
+static const char null_string[] = "";
+
+/**
+ Set a string value, allocing the space for the string
+**/
+
+static bool string_init(char **dest,const char *src)
+{
+ size_t l;
+
+ if (!src)
+ src = "";
+
+ l = strlen(src);
+
+ if (l == 0) {
+ *dest = discard_const_p(char, null_string);
+ } else {
+ (*dest) = SMB_STRDUP(src);
+ if ((*dest) == NULL) {
+ DEBUG(0,("Out of memory in string_init\n"));
+ return false;
+ }
+ }
+ return(true);
+}
+
+/**
+ Free a string value.
+**/
+
+void string_free(char **s)
+{
+ if (!s || !(*s))
+ return;
+ if (*s == null_string)
+ *s = NULL;
+ SAFE_FREE(*s);
+}
+
+/**
+ Set a string value, deallocating any existing space, and allocing the space
+ for the string
+**/
+
+bool string_set(char **dest,const char *src)
+{
+ string_free(dest);
+ return(string_init(dest,src));
+}
diff --git a/source3/lib/substitute.c b/source3/lib/substitute.c
index e72a8c3b61..df217bc03f 100644
--- a/source3/lib/substitute.c
+++ b/source3/lib/substitute.c
@@ -80,7 +80,7 @@ bool set_local_machine_name(const char *local_name, bool perm)
const char *get_local_machine_name(void)
{
if (!local_machine || !*local_machine) {
- return global_myname();
+ return lp_netbios_name();
}
return local_machine;
@@ -324,105 +324,6 @@ static char * realloc_expand_env_var(char *str, char *p)
}
/*******************************************************************
-*******************************************************************/
-
-static char *longvar_domainsid( void )
-{
- struct dom_sid sid;
- fstring tmp;
- char *sid_string;
-
- if ( !secrets_fetch_domain_sid( lp_workgroup(), &sid ) ) {
- return NULL;
- }
-
- sid_string = SMB_STRDUP( sid_to_fstring( tmp, &sid ) );
-
- if ( !sid_string ) {
- DEBUG(0,("longvar_domainsid: failed to dup SID string!\n"));
- }
-
- return sid_string;
-}
-
-/*******************************************************************
-*******************************************************************/
-
-struct api_longvar {
- const char *name;
- char* (*fn)( void );
-};
-
-static struct api_longvar longvar_table[] = {
- { "DomainSID", longvar_domainsid },
- { NULL, NULL }
-};
-
-static char *get_longvar_val( const char *varname )
-{
- int i;
-
- DEBUG(7,("get_longvar_val: expanding variable [%s]\n", varname));
-
- for ( i=0; longvar_table[i].name; i++ ) {
- if ( strequal( longvar_table[i].name, varname ) ) {
- return longvar_table[i].fn();
- }
- }
-
- return NULL;
-}
-
-/*******************************************************************
- Expand the long smb.conf variable names given a pointer to a %(NAME).
- Return the number of characters by which the pointer should be advanced.
- When this is called p points at the '%' character.
-********************************************************************/
-
-static char *realloc_expand_longvar(char *str, char *p)
-{
- fstring varname;
- char *value;
- char *q, *r;
- int copylen;
-
- if ( p[0] != '%' || p[1] != '(' ) {
- return str;
- }
-
- /* Look for the terminating ')'.*/
-
- if ((q = strchr_m(p,')')) == NULL) {
- DEBUG(0,("realloc_expand_longvar: Unterminated environment variable [%s]\n", p));
- return str;
- }
-
- /* Extract the name from within the %(NAME) string.*/
-
- r = p+2;
- copylen = MIN( (q-r), (sizeof(varname)-1) );
- strncpy(varname, r, copylen);
- varname[copylen] = '\0';
-
- if ((value = get_longvar_val(varname)) == NULL) {
- DEBUG(0,("realloc_expand_longvar: Variable [%s] not set. Skipping\n", varname));
- return str;
- }
-
- /* Copy the full %(NAME) into envname so it can be replaced.*/
-
- copylen = MIN( (q+1-p),(sizeof(varname)-1) );
- strncpy( varname, p, copylen );
- varname[copylen] = '\0';
- r = realloc_string_sub(str, varname, value);
- SAFE_FREE( value );
-
- /* skip over the %(varname) */
-
- return r;
-}
-
-/*******************************************************************
Patch from jkf@soton.ac.uk
Added this to implement %p (NIS auto-map version of %H)
*******************************************************************/
@@ -489,7 +390,7 @@ static const char *automount_server(const char *user_name)
if (local_machine_name && *local_machine_name) {
server_name = talloc_strdup(ctx, local_machine_name);
} else {
- server_name = talloc_strdup(ctx, global_myname());
+ server_name = talloc_strdup(ctx, lp_netbios_name());
}
if (!server_name) {
@@ -632,13 +533,13 @@ static char *alloc_sub_basic(const char *smb_name, const char *domain_name,
sub_sockaddr[0] ? sub_sockaddr : "0.0.0.0");
break;
case 'L' :
- if ( StrnCaseCmp(p, "%LOGONSERVER%", strlen("%LOGONSERVER%")) == 0 ) {
+ if ( strncasecmp_m(p, "%LOGONSERVER%", strlen("%LOGONSERVER%")) == 0 ) {
break;
}
if (local_machine_name && *local_machine_name) {
a_string = realloc_string_sub(a_string, "%L", local_machine_name);
} else {
- a_string = realloc_string_sub(a_string, "%L", global_myname());
+ a_string = realloc_string_sub(a_string, "%L", lp_netbios_name());
}
break;
case 'N':
@@ -680,9 +581,6 @@ static char *alloc_sub_basic(const char *smb_name, const char *domain_name,
case '$' :
a_string = realloc_expand_env_var(a_string, p); /* Expand environment variables */
break;
- 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);
@@ -926,3 +824,32 @@ char *standard_sub_conn(TALLOC_CTX *ctx, connection_struct *conn, const char *st
"",
str);
}
+
+/******************************************************************************
+ version of standard_sub_basic() for string lists; uses talloc_sub_basic()
+ for the work
+ *****************************************************************************/
+
+bool str_list_sub_basic( char **list, const char *smb_name,
+ const char *domain_name )
+{
+ TALLOC_CTX *ctx = list;
+ char *s, *tmpstr;
+
+ while ( *list ) {
+ s = *list;
+ tmpstr = talloc_sub_basic(ctx, smb_name, domain_name, s);
+ if ( !tmpstr ) {
+ DEBUG(0,("str_list_sub_basic: "
+ "alloc_sub_basic() return NULL!\n"));
+ return false;
+ }
+
+ TALLOC_FREE(*list);
+ *list = tmpstr;
+
+ list++;
+ }
+
+ return true;
+}
diff --git a/source3/lib/substitute_generic.c b/source3/lib/substitute_generic.c
new file mode 100644
index 0000000000..fa347fb815
--- /dev/null
+++ b/source3/lib/substitute_generic.c
@@ -0,0 +1,116 @@
+/*
+ Unix SMB/CIFS implementation.
+ Samba utility functions
+
+ Copyright (C) Andrew Tridgell 1992-2001
+ Copyright (C) Simo Sorce 2001-2002
+ Copyright (C) Martin Pool 2003
+ Copyright (C) James Peach 2006
+ Copyright (C) Jeremy Allison 1992-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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+
+void fstring_sub(char *s,const char *pattern,const char *insert)
+{
+ string_sub(s, pattern, insert, sizeof(fstring));
+}
+
+/**
+ Similar to string_sub2, but it will accept only allocated strings
+ and may realloc them so pay attention at what you pass on no
+ pointers inside strings, no const may be passed
+ as string.
+**/
+
+char *realloc_string_sub2(char *string,
+ const char *pattern,
+ const char *insert,
+ bool remove_unsafe_characters,
+ bool allow_trailing_dollar)
+{
+ char *p, *in;
+ char *s;
+ ssize_t ls,lp,li,ld, i;
+
+ if (!insert || !pattern || !*pattern || !string || !*string)
+ return NULL;
+
+ s = string;
+
+ in = SMB_STRDUP(insert);
+ if (!in) {
+ DEBUG(0, ("realloc_string_sub: out of memory!\n"));
+ return NULL;
+ }
+ ls = (ssize_t)strlen(s);
+ lp = (ssize_t)strlen(pattern);
+ li = (ssize_t)strlen(insert);
+ ld = li - lp;
+ for (i=0;i<li;i++) {
+ switch (in[i]) {
+ case '$':
+ /* allow a trailing $
+ * (as in machine accounts) */
+ if (allow_trailing_dollar && (i == li - 1 )) {
+ break;
+ }
+ case '`':
+ case '"':
+ case '\'':
+ case ';':
+ case '%':
+ case '\r':
+ case '\n':
+ if ( remove_unsafe_characters ) {
+ in[i] = '_';
+ break;
+ }
+ default:
+ /* ok */
+ break;
+ }
+ }
+
+ while ((p = strstr_m(s,pattern))) {
+ if (ld > 0) {
+ int offset = PTR_DIFF(s,string);
+ string = (char *)SMB_REALLOC(string, ls + ld + 1);
+ if (!string) {
+ DEBUG(0, ("realloc_string_sub: "
+ "out of memory!\n"));
+ SAFE_FREE(in);
+ return NULL;
+ }
+ p = string + offset + (p - s);
+ }
+ if (li != lp) {
+ memmove(p+li,p+lp,strlen(p+lp)+1);
+ }
+ memcpy(p, in, li);
+ s = p + li;
+ ls += ld;
+ }
+ SAFE_FREE(in);
+ return string;
+}
+
+char *realloc_string_sub(char *string,
+ const char *pattern,
+ const char *insert)
+{
+ return realloc_string_sub2(string, pattern, insert, true, false);
+}
diff --git a/source3/lib/system.c b/source3/lib/system.c
index 52b6477266..2f7a55f48c 100644
--- a/source3/lib/system.c
+++ b/source3/lib/system.c
@@ -48,42 +48,6 @@
/*******************************************************************
- A wrapper for memalign
-********************************************************************/
-
-void *sys_memalign( size_t align, size_t size )
-{
-#if defined(HAVE_POSIX_MEMALIGN)
- void *p = NULL;
- int ret = posix_memalign( &p, align, size );
- if ( ret == 0 )
- return p;
-
- return NULL;
-#elif defined(HAVE_MEMALIGN)
- return memalign( align, size );
-#else
- /* On *BSD systems memaligns doesn't exist, but memory will
- * be aligned on allocations of > pagesize. */
-#if defined(SYSCONF_SC_PAGESIZE)
- size_t pagesize = (size_t)sysconf(_SC_PAGESIZE);
-#elif defined(HAVE_GETPAGESIZE)
- size_t pagesize = (size_t)getpagesize();
-#else
- size_t pagesize = (size_t)-1;
-#endif
- if (pagesize == (size_t)-1) {
- DEBUG(0,("memalign functionalaity not available on this platform!\n"));
- return NULL;
- }
- if (size < pagesize) {
- size = pagesize;
- }
- return SMB_MALLOC(size);
-#endif
-}
-
-/*******************************************************************
A wrapper for usleep in case we don't have one.
********************************************************************/
@@ -545,13 +509,13 @@ void update_stat_ex_create_time(struct stat_ex *dst,
}
#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_STAT64)
-static void init_stat_ex_from_stat (struct stat_ex *dst,
- const struct stat64 *src,
- bool fake_dir_create_times)
+void init_stat_ex_from_stat (struct stat_ex *dst,
+ const struct stat64 *src,
+ bool fake_dir_create_times)
#else
-static void init_stat_ex_from_stat (struct stat_ex *dst,
- const struct stat *src,
- bool fake_dir_create_times)
+void init_stat_ex_from_stat (struct stat_ex *dst,
+ const struct stat *src,
+ bool fake_dir_create_times)
#endif
{
dst->st_ex_dev = src->st_dev;
@@ -833,6 +797,15 @@ FILE *sys_fopen(const char *path, const char *type)
}
+#if HAVE_KERNEL_SHARE_MODES
+#ifndef LOCK_MAND
+#define LOCK_MAND 32 /* This is a mandatory flock */
+#define LOCK_READ 64 /* ... Which allows concurrent read operations */
+#define LOCK_WRITE 128 /* ... Which allows concurrent write operations */
+#define LOCK_RW 192 /* ... Which allows concurrent read & write ops */
+#endif
+#endif
+
/*******************************************************************
A flock() wrapper that will perform the kernel flock.
********************************************************************/
@@ -986,18 +959,45 @@ int sys_waitpid(pid_t pid,int *status,int options)
}
/*******************************************************************
- System wrapper for getwd
+ System wrapper for getwd. Always returns MALLOC'ed memory, or NULL
+ on error (malloc fail usually).
********************************************************************/
-char *sys_getwd(char *s)
+char *sys_getwd(void)
{
- char *wd;
-#ifdef HAVE_GETCWD
- wd = (char *)getcwd(s, PATH_MAX);
+#ifdef GETCWD_TAKES_NULL
+ return getcwd(NULL, 0);
+#elif HAVE_GETCWD
+ char *wd = NULL, *s = NULL;
+ size_t allocated = PATH_MAX;
+
+ while (1) {
+ s = SMB_REALLOC_ARRAY(s, char, allocated);
+ if (s == NULL) {
+ return NULL;
+ }
+ wd = getcwd(s, allocated);
+ if (wd) {
+ break;
+ }
+ if (errno != ERANGE) {
+ SAFE_FREE(s);
+ break;
+ }
+ allocated *= 2;
+ if (allocated < PATH_MAX) {
+ SAFE_FREE(s);
+ break;
+ }
+ }
+ return wd;
#else
- wd = (char *)getwd(s);
+ char *s = SMB_MALLOC_ARRAY(char, PATH_MAX);
+ if (s == NULL) {
+ return NULL;
+ }
+ return getwd(s);
#endif
- return wd;
}
#if defined(HAVE_POSIX_CAPABILITIES)
@@ -1382,7 +1382,7 @@ static char **extract_args(TALLOC_CTX *mem_ctx, const char *command)
TALLOC_FREE(trunc_cmd);
- if (!(argl = TALLOC_ARRAY(mem_ctx, char *, argcl + 1))) {
+ if (!(argl = talloc_array(mem_ctx, char *, argcl + 1))) {
goto nomem;
}
@@ -2367,7 +2367,7 @@ static ssize_t solaris_list_xattr(int attrdirfd, char *list, size_t size)
dirp = fdopendir(newfd);
while ((de = readdir(dirp))) {
- size_t listlen = strlen(de->d_name);
+ size_t listlen = strlen(de->d_name) + 1;
if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) {
/* we don't want "." and ".." here: */
DEBUG(10,("skipped EA %s\n",de->d_name));
@@ -2376,18 +2376,16 @@ static ssize_t solaris_list_xattr(int attrdirfd, char *list, size_t size)
if (size == 0) {
/* return the current size of the list of extended attribute names*/
- len += listlen + 1;
+ len += listlen;
} else {
/* check size and copy entrieѕ + nul into list. */
- if ((len + listlen + 1) > size) {
+ if ((len + listlen) > size) {
errno = ERANGE;
len = -1;
break;
} else {
- safe_strcpy(list + len, de->d_name, listlen);
+ strlcpy(list + len, de->d_name, listlen);
len += listlen;
- list[len] = '\0';
- ++len;
}
}
}
@@ -2633,74 +2631,3 @@ int sys_aio_suspend(const SMB_STRUCT_AIOCB * const cblist[], int n, const struct
return -1;
}
#endif /* WITH_AIO */
-
-int sys_getpeereid( int s, uid_t *uid)
-{
-#if defined(HAVE_PEERCRED)
- struct ucred cred;
- socklen_t cred_len = sizeof(struct ucred);
- int ret;
-
- ret = getsockopt(s, SOL_SOCKET, SO_PEERCRED, (void *)&cred, &cred_len);
- if (ret != 0) {
- return -1;
- }
-
- if (cred_len != sizeof(struct ucred)) {
- errno = EINVAL;
- return -1;
- }
-
- *uid = cred.uid;
- return 0;
-#else
-#if defined(HAVE_GETPEEREID)
- gid_t gid;
- return getpeereid(s, uid, &gid);
-#endif
- errno = ENOSYS;
- return -1;
-#endif
-}
-
-int sys_getnameinfo(const struct sockaddr *psa,
- socklen_t salen,
- char *host,
- size_t hostlen,
- char *service,
- size_t servlen,
- int flags)
-{
- /*
- * For Solaris we must make sure salen is the
- * correct length for the incoming sa_family.
- */
-
- if (salen == sizeof(struct sockaddr_storage)) {
- salen = sizeof(struct sockaddr_in);
-#if defined(HAVE_IPV6)
- if (psa->sa_family == AF_INET6) {
- salen = sizeof(struct sockaddr_in6);
- }
-#endif
- }
- return getnameinfo(psa, salen, host, hostlen, service, servlen, flags);
-}
-
-int sys_connect(int fd, const struct sockaddr * addr)
-{
- socklen_t salen = (socklen_t)-1;
-
- if (addr->sa_family == AF_INET) {
- salen = sizeof(struct sockaddr_in);
- } else if (addr->sa_family == AF_UNIX) {
- salen = sizeof(struct sockaddr_un);
- }
-#if defined(HAVE_IPV6)
- else if (addr->sa_family == AF_INET6) {
- salen = sizeof(struct sockaddr_in6);
- }
-#endif
-
- return connect(fd, addr, salen);
-}
diff --git a/source3/lib/talloc_dict.c b/source3/lib/talloc_dict.c
index cbe5c7b5c2..95ae0a3260 100644
--- a/source3/lib/talloc_dict.c
+++ b/source3/lib/talloc_dict.c
@@ -20,6 +20,7 @@
#include "includes.h"
#include "dbwrap.h"
#include "talloc_dict.h"
+#include "util_tdb.h"
struct talloc_dict {
struct db_context *db;
diff --git a/source3/lib/tallocmsg.c b/source3/lib/tallocmsg.c
index da380c9335..9a0ce8ada1 100644
--- a/source3/lib/tallocmsg.c
+++ b/source3/lib/tallocmsg.c
@@ -65,7 +65,7 @@ static void msg_pool_usage_helper(const void *ptr, int depth, int max_depth, int
(unsigned long)talloc_total_blocks(ptr),
talloc_reference_count(ptr),
MIN(50, talloc_get_size(ptr)),
- (char *)ptr);
+ (const char *)ptr);
return;
}
diff --git a/source3/lib/tdb_validate.c b/source3/lib/tdb_validate.c
index b91ea7af83..385f4d0ef8 100644
--- a/source3/lib/tdb_validate.c
+++ b/source3/lib/tdb_validate.c
@@ -21,6 +21,7 @@
#include "includes.h"
#include "system/filesys.h"
+#include "util_tdb.h"
#include "tdb_validate.h"
/*
@@ -50,12 +51,13 @@ static int tdb_validate_child(struct tdb_context *tdb,
* but I don't want to change all the callers...
*/
ret = tdb_check(tdb, NULL, NULL);
- if (ret == -1) {
+ if (ret != 0) {
v_status.tdb_error = True;
v_status.success = False;
goto out;
}
+#ifndef BUILD_TDB2
/* Check if the tdb's freelist is good. */
if (tdb_validate_freelist(tdb, &num_entries) == -1) {
v_status.bad_freelist = True;
@@ -65,12 +67,13 @@ static int tdb_validate_child(struct tdb_context *tdb,
DEBUG(10,("tdb_validate_child: tdb %s freelist has %d entries\n",
tdb_name(tdb), num_entries));
+#endif
/* Now traverse the tdb to validate it. */
num_entries = tdb_traverse(tdb, validate_fn, (void *)&v_status);
if (!v_status.success) {
goto out;
- } else if (num_entries == -1) {
+ } else if (num_entries < 0) {
v_status.tdb_error = True;
v_status.success = False;
goto out;
@@ -288,8 +291,14 @@ static int tdb_backup(TALLOC_CTX *ctx, const char *src_path,
}
unlink(tmp_path);
- dst_tdb = tdb_open_log(tmp_path,
- hash_size ? hash_size : tdb_hash_size(src_tdb),
+
+#ifndef BUILD_TDB2
+ if (!hash_size) {
+ hash_size = tdb_hash_size(src_tdb);
+ }
+#endif
+
+ dst_tdb = tdb_open_log(tmp_path, hash_size,
TDB_DEFAULT, O_RDWR | O_CREAT | O_EXCL,
st.st_mode & 0777);
if (dst_tdb == NULL) {
diff --git a/source3/lib/tdb_validate.h b/source3/lib/tdb_validate.h
index 3e7c20d04c..5bb043d292 100644
--- a/source3/lib/tdb_validate.h
+++ b/source3/lib/tdb_validate.h
@@ -23,7 +23,7 @@
#define __TDB_VALIDATE_H__
#include "lib/replace/replace.h"
-#include <tdb.h>
+#include "tdb_compat.h"
/**
* Flag field for keeping track of the status of a validation.
diff --git a/source3/lib/tldap.c b/source3/lib/tldap.c
index cd1dea52ba..8b04d00636 100644
--- a/source3/lib/tldap.c
+++ b/source3/lib/tldap.c
@@ -20,6 +20,8 @@
#include "includes.h"
#include "tldap.h"
#include "../lib/util/asn1.h"
+#include "../lib/tsocket/tsocket.h"
+#include "../lib/util/tevent_unix.h"
static int tldap_simple_recv(struct tevent_req *req);
@@ -187,7 +189,7 @@ bool tldap_context_setattr(struct tldap_context *ld,
struct tldap_ctx_attribute *tmp, *attr;
char *tmpname;
int num_attrs;
- void **pptr = (void **)_pptr;
+ void **pptr = (void **)discard_const_p(void,_pptr);
attr = tldap_context_findattr(ld, name);
if (attr != NULL) {
@@ -539,7 +541,7 @@ static void tldap_msg_sent(struct tevent_req *subreq)
}
if (!tldap_msg_set_pending(req)) {
- tevent_req_nomem(NULL, req);
+ tevent_req_oom(req);
return;
}
}
@@ -933,10 +935,10 @@ struct tevent_req *tldap_simple_bind_send(TALLOC_CTX *mem_ctx,
DATA_BLOB cred;
if (passwd != NULL) {
- cred.data = (uint8_t *)passwd;
+ cred.data = discard_const_p(uint8_t, passwd);
cred.length = strlen(passwd);
} else {
- cred.data = (uint8_t *)"";
+ cred.data = discard_const_p(uint8_t, "");
cred.length = 0;
}
return tldap_sasl_bind_send(mem_ctx, ev, ld, dn, NULL, &cred, NULL, 0,
@@ -954,10 +956,10 @@ int tldap_simple_bind(struct tldap_context *ld, const char *dn,
DATA_BLOB cred;
if (passwd != NULL) {
- cred.data = (uint8_t *)passwd;
+ cred.data = discard_const_p(uint8_t, passwd);
cred.length = strlen(passwd);
} else {
- cred.data = (uint8_t *)"";
+ cred.data = discard_const_p(uint8_t, "");
cred.length = 0;
}
return tldap_sasl_bind(ld, dn, NULL, &cred, NULL, 0, NULL, 0);
@@ -1373,7 +1375,7 @@ static bool tldap_push_filter_basic(struct tldap_context *ld,
return false;
}
- if (StrnCaseCmp(dn, "dn:", 3) != 0) {
+ if (strncasecmp_m(dn, "dn:", 3) != 0) {
if (rule == e) {
rule = dn;
dn = NULL;
@@ -1701,7 +1703,7 @@ static void tldap_search_done(struct tevent_req *subreq)
case TLDAP_RES_SEARCH_ENTRY:
case TLDAP_RES_SEARCH_REFERENCE:
if (!tldap_msg_set_pending(subreq)) {
- tevent_req_nomem(NULL, req);
+ tevent_req_oom(req);
return;
}
tevent_req_notify_callback(req);
diff --git a/source3/lib/tldap_util.c b/source3/lib/tldap_util.c
index 0c22d6564e..6b9f912e27 100644
--- a/source3/lib/tldap_util.c
+++ b/source3/lib/tldap_util.c
@@ -300,7 +300,7 @@ static int compare_utf8_blobs(const DATA_BLOB *d1, const DATA_BLOB *d2)
TALLOC_FREE(s1);
return 0;
}
- ret = StrCaseCmp(s1, s2);
+ ret = strcasecmp_m(s1, s2);
TALLOC_FREE(s2);
TALLOC_FREE(s1);
return ret;
@@ -325,7 +325,7 @@ bool tldap_make_mod_fmt(struct tldap_message *existing, TALLOC_CTX *mem_ctx,
blob.length = strlen(newval);
if (blob.length != 0) {
- blob.data = CONST_DISCARD(uint8_t *, newval);
+ blob.data = discard_const_p(uint8_t, newval);
}
ret = tldap_make_mod_blob_int(existing, mem_ctx, pmods, pnum_mods,
attrib, blob, compare_utf8_blobs);
diff --git a/source3/lib/util.c b/source3/lib/util.c
index 0bb46db05f..b8fc319a6f 100644
--- a/source3/lib/util.c
+++ b/source3/lib/util.c
@@ -24,9 +24,11 @@
#include "includes.h"
#include "system/passwd.h"
#include "system/filesys.h"
+#include "util_tdb.h"
#include "ctdbd_conn.h"
#include "../lib/util/util_pw.h"
#include "messages.h"
+#include <ccan/hash/hash.h>
/* Max allowable allococation - 256mb - 0x10000000 */
#define MAX_ALLOC_SIZE (1024*1024*256)
@@ -71,87 +73,6 @@ void set_Protocol(enum protocol_types p)
static enum remote_arch_types ra_type = RA_UNKNOWN;
-/***********************************************************************
- Definitions for all names.
-***********************************************************************/
-
-static char *smb_scope;
-static int smb_num_netbios_names;
-static char **smb_my_netbios_names;
-
-/***********************************************************************
- Allocate and set scope. Ensure upper case.
-***********************************************************************/
-
-bool set_global_scope(const char *scope)
-{
- SAFE_FREE(smb_scope);
- smb_scope = SMB_STRDUP(scope);
- if (!smb_scope)
- return False;
- strupper_m(smb_scope);
- return True;
-}
-
-/*********************************************************************
- Ensure scope is never null string.
-*********************************************************************/
-
-const char *global_scope(void)
-{
- if (!smb_scope)
- set_global_scope("");
- return smb_scope;
-}
-
-static void free_netbios_names_array(void)
-{
- int i;
-
- for (i = 0; i < smb_num_netbios_names; i++)
- SAFE_FREE(smb_my_netbios_names[i]);
-
- SAFE_FREE(smb_my_netbios_names);
- smb_num_netbios_names = 0;
-}
-
-static bool allocate_my_netbios_names_array(size_t number)
-{
- free_netbios_names_array();
-
- smb_num_netbios_names = number + 1;
- smb_my_netbios_names = SMB_MALLOC_ARRAY( char *, smb_num_netbios_names );
-
- if (!smb_my_netbios_names)
- return False;
-
- memset(smb_my_netbios_names, '\0', sizeof(char *) * smb_num_netbios_names);
- return True;
-}
-
-static bool set_my_netbios_names(const char *name, int i)
-{
- SAFE_FREE(smb_my_netbios_names[i]);
-
- smb_my_netbios_names[i] = SMB_STRDUP(name);
- if (!smb_my_netbios_names[i])
- return False;
- strupper_m(smb_my_netbios_names[i]);
- return True;
-}
-
-/***********************************************************************
- Free memory allocated to global objects
-***********************************************************************/
-
-void gfree_names(void)
-{
- gfree_netbios_names();
- SAFE_FREE( smb_scope );
- free_netbios_names_array();
- free_local_machine_name();
-}
-
void gfree_all( void )
{
gfree_names();
@@ -161,87 +82,6 @@ void gfree_all( void )
gfree_debugsyms();
}
-const char *my_netbios_names(int i)
-{
- return smb_my_netbios_names[i];
-}
-
-bool set_netbios_aliases(const char **str_array)
-{
- size_t namecount;
-
- /* Work out the max number of netbios aliases that we have */
- for( namecount=0; str_array && (str_array[namecount] != NULL); namecount++ )
- ;
-
- if ( global_myname() && *global_myname())
- namecount++;
-
- /* Allocate space for the netbios aliases */
- if (!allocate_my_netbios_names_array(namecount))
- return False;
-
- /* Use the global_myname string first */
- namecount=0;
- if ( global_myname() && *global_myname()) {
- set_my_netbios_names( global_myname(), namecount );
- namecount++;
- }
-
- if (str_array) {
- size_t i;
- for ( i = 0; str_array[i] != NULL; i++) {
- size_t n;
- bool duplicate = False;
-
- /* Look for duplicates */
- for( n=0; n<namecount; n++ ) {
- if( strequal( str_array[i], my_netbios_names(n) ) ) {
- duplicate = True;
- break;
- }
- }
- if (!duplicate) {
- if (!set_my_netbios_names(str_array[i], namecount))
- return False;
- namecount++;
- }
- }
- }
- return True;
-}
-
-/****************************************************************************
- Common name initialization code.
-****************************************************************************/
-
-bool init_names(void)
-{
- int n;
-
- if (global_myname() == NULL || *global_myname() == '\0') {
- if (!set_global_myname(myhostname())) {
- DEBUG( 0, ( "init_names: malloc fail.\n" ) );
- return False;
- }
- }
-
- if (!set_netbios_aliases(lp_netbios_aliases())) {
- DEBUG( 0, ( "init_names: malloc fail.\n" ) );
- return False;
- }
-
- set_local_machine_name(global_myname(),false);
-
- DEBUG( 5, ("Netbios name list:-\n") );
- for( n=0; my_netbios_names(n); n++ ) {
- DEBUGADD( 5, ("my_netbios_names[%d]=\"%s\"\n",
- n, my_netbios_names(n) ) );
- }
-
- return( True );
-}
-
/*******************************************************************
Check if a file exists - call vfs_file_exist for samba files.
********************************************************************/
@@ -295,30 +135,10 @@ SMB_OFF_T get_file_size(char *file_name)
}
/*******************************************************************
- Return a string representing an attribute for a file.
-********************************************************************/
-
-char *attrib_string(uint16 mode)
-{
- fstring attrstr;
-
- attrstr[0] = 0;
-
- if (mode & aVOLID) fstrcat(attrstr,"V");
- if (mode & aDIR) fstrcat(attrstr,"D");
- if (mode & aARCH) fstrcat(attrstr,"A");
- if (mode & aHIDDEN) fstrcat(attrstr,"H");
- if (mode & aSYSTEM) fstrcat(attrstr,"S");
- if (mode & aRONLY) fstrcat(attrstr,"R");
-
- return talloc_strdup(talloc_tos(), attrstr);
-}
-
-/*******************************************************************
Show a smb message structure.
********************************************************************/
-void show_msg(char *buf)
+void show_msg(const char *buf)
{
int i;
int bcc=0;
@@ -355,7 +175,7 @@ void show_msg(char *buf)
if (DEBUGLEVEL < 50)
bcc = MIN(bcc, 512);
- dump_data(10, (uint8 *)smb_buf(buf), bcc);
+ dump_data(10, (const uint8 *)smb_buf_const(buf), bcc);
}
/*******************************************************************
@@ -407,7 +227,7 @@ ssize_t message_push_blob(uint8 **outbuf, DATA_BLOB blob)
size_t newlen = smb_len(*outbuf) + 4 + blob.length;
uint8 *tmp;
- if (!(tmp = TALLOC_REALLOC_ARRAY(NULL, *outbuf, uint8, newlen))) {
+ if (!(tmp = talloc_realloc(NULL, *outbuf, uint8, newlen))) {
DEBUG(0, ("talloc failed\n"));
return -1;
}
@@ -586,7 +406,7 @@ NTSTATUS reinit_after_fork(struct messaging_context *msg_ctx,
set_need_random_reseed();
/* tdb needs special fork handling */
- if (tdb_reopen_all(parent_longlived ? 1 : 0) == -1) {
+ if (tdb_reopen_all(parent_longlived ? 1 : 0) != 0) {
DEBUG(0,("tdb_reopen_all failed.\n"));
status = NT_STATUS_OPEN_FAILED;
goto done;
@@ -611,149 +431,6 @@ NTSTATUS reinit_after_fork(struct messaging_context *msg_ctx,
return status;
}
-#if defined(PARANOID_MALLOC_CHECKER)
-
-/****************************************************************************
- Internal malloc wrapper. Externally visible.
-****************************************************************************/
-
-void *malloc_(size_t size)
-{
- if (size == 0) {
- return NULL;
- }
-#undef malloc
- return malloc(size);
-#define malloc(s) __ERROR_DONT_USE_MALLOC_DIRECTLY
-}
-
-/****************************************************************************
- Internal calloc wrapper. Not externally visible.
-****************************************************************************/
-
-static void *calloc_(size_t count, size_t size)
-{
- if (size == 0 || count == 0) {
- return NULL;
- }
-#undef calloc
- return calloc(count, size);
-#define calloc(n,s) __ERROR_DONT_USE_CALLOC_DIRECTLY
-}
-
-/****************************************************************************
- Internal realloc wrapper. Not externally visible.
-****************************************************************************/
-
-static void *realloc_(void *ptr, size_t size)
-{
-#undef realloc
- return realloc(ptr, size);
-#define realloc(p,s) __ERROR_DONT_USE_RELLOC_DIRECTLY
-}
-
-#endif /* PARANOID_MALLOC_CHECKER */
-
-/****************************************************************************
- Type-safe memalign
-****************************************************************************/
-
-void *memalign_array(size_t el_size, size_t align, unsigned int count)
-{
- if (count >= MAX_ALLOC_SIZE/el_size) {
- return NULL;
- }
-
- return sys_memalign(align, el_size*count);
-}
-
-/****************************************************************************
- Type-safe calloc.
-****************************************************************************/
-
-void *calloc_array(size_t size, size_t nmemb)
-{
- if (nmemb >= MAX_ALLOC_SIZE/size) {
- return NULL;
- }
- if (size == 0 || nmemb == 0) {
- return NULL;
- }
-#if defined(PARANOID_MALLOC_CHECKER)
- return calloc_(nmemb, size);
-#else
- return calloc(nmemb, size);
-#endif
-}
-
-/****************************************************************************
- Expand a pointer to be a particular size.
- Note that this version of Realloc has an extra parameter that decides
- whether to free the passed in storage on allocation failure or if the
- new size is zero.
-
- This is designed for use in the typical idiom of :
-
- p = SMB_REALLOC(p, size)
- if (!p) {
- return error;
- }
-
- and not to have to keep track of the old 'p' contents to free later, nor
- to worry if the size parameter was zero. In the case where NULL is returned
- we guarentee that p has been freed.
-
- If free later semantics are desired, then pass 'free_old_on_error' as False which
- guarentees that the old contents are not freed on error, even if size == 0. To use
- this idiom use :
-
- tmp = SMB_REALLOC_KEEP_OLD_ON_ERROR(p, size);
- if (!tmp) {
- SAFE_FREE(p);
- return error;
- } else {
- p = tmp;
- }
-
- Changes were instigated by Coverity error checking. JRA.
-****************************************************************************/
-
-void *Realloc(void *p, size_t size, bool free_old_on_error)
-{
- void *ret=NULL;
-
- if (size == 0) {
- if (free_old_on_error) {
- SAFE_FREE(p);
- }
- DEBUG(2,("Realloc asked for 0 bytes\n"));
- return NULL;
- }
-
-#if defined(PARANOID_MALLOC_CHECKER)
- if (!p) {
- ret = (void *)malloc_(size);
- } else {
- ret = (void *)realloc_(p,size);
- }
-#else
- if (!p) {
- ret = (void *)malloc(size);
- } else {
- ret = (void *)realloc(p,size);
- }
-#endif
-
- if (!ret) {
- if (free_old_on_error && p) {
- SAFE_FREE(p);
- }
- DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",(int)size));
- }
-
- return(ret);
-}
-
/****************************************************************************
(Hopefully) efficient array append.
****************************************************************************/
@@ -1318,7 +995,7 @@ bool is_in_path(const char *name, name_compare_entry *namelist, bool case_sensit
}
} else {
if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
- (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0))) {
+ (!case_sensitive && (strcasecmp_m(last_component, namelist->name) == 0))) {
DEBUG(8,("is_in_path: match succeeded\n"));
return True;
}
@@ -1334,25 +1011,31 @@ bool is_in_path(const char *name, name_compare_entry *namelist, bool case_sensit
passing to is_in_path(). We do this for
speed so we can pre-parse all the names in the list
and don't do it for each call to is_in_path().
- namelist is modified here and is assumed to be
- a copy owned by the caller.
We also check if the entry contains a wildcard to
remove a potentially expensive call to mask_match
if possible.
********************************************************************/
-void set_namearray(name_compare_entry **ppname_array, const char *namelist)
+void set_namearray(name_compare_entry **ppname_array, const char *namelist_in)
{
char *name_end;
- char *nameptr = (char *)namelist;
+ char *namelist;
+ char *nameptr;
int num_entries = 0;
int i;
(*ppname_array) = NULL;
- if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0')))
+ if((namelist_in == NULL ) || ((namelist_in != NULL) && (*namelist_in == '\0')))
return;
+ namelist = talloc_strdup(talloc_tos(), namelist_in);
+ if (namelist == NULL) {
+ DEBUG(0,("set_namearray: talloc fail\n"));
+ return;
+ }
+ nameptr = namelist;
+
/* We need to make two passes over the string. The
first to count the number of elements, the second
to split it.
@@ -1378,16 +1061,19 @@ void set_namearray(name_compare_entry **ppname_array, const char *namelist)
num_entries++;
}
- if(num_entries == 0)
+ if(num_entries == 0) {
+ talloc_free(namelist);
return;
+ }
if(( (*ppname_array) = SMB_MALLOC_ARRAY(name_compare_entry, num_entries + 1)) == NULL) {
DEBUG(0,("set_namearray: malloc fail\n"));
+ talloc_free(namelist);
return;
}
/* Now copy out the names */
- nameptr = (char *)namelist;
+ nameptr = namelist;
i = 0;
while(*nameptr) {
if ( *nameptr == '/' ) {
@@ -1409,6 +1095,7 @@ void set_namearray(name_compare_entry **ppname_array, const char *namelist)
(*ppname_array)[i].is_wild = ms_has_wild(nameptr);
if(((*ppname_array)[i].name = SMB_STRDUP(nameptr)) == NULL) {
DEBUG(0,("set_namearray: malloc fail (1)\n"));
+ talloc_free(namelist);
return;
}
@@ -1419,25 +1106,10 @@ void set_namearray(name_compare_entry **ppname_array, const char *namelist)
(*ppname_array)[i].name = NULL;
+ talloc_free(namelist);
return;
}
-/****************************************************************************
- Routine to free a namearray.
-****************************************************************************/
-
-void free_namearray(name_compare_entry *name_array)
-{
- int i;
-
- if(name_array == NULL)
- return;
-
- for(i=0; name_array[i].name!=NULL; i++)
- SAFE_FREE(name_array[i].name);
- SAFE_FREE(name_array);
-}
-
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_LOCKING
@@ -1635,8 +1307,9 @@ const char *tab_depth(int level, int depth)
int str_checksum(const char *s)
{
- TDB_DATA key = string_tdb_data(s);
- return tdb_jenkins_hash(&key);
+ if (s == NULL)
+ return 0;
+ return hash(s, strlen(s), 0);
}
/*****************************************************************
@@ -1785,6 +1458,22 @@ char *myhostname(void)
return ret;
}
+/*****************************************************************
+ Get local hostname and cache result.
+*****************************************************************/
+
+char *myhostname_upper(void)
+{
+ char *name;
+ static char *ret;
+ if (ret == NULL) {
+ name = get_myname(talloc_tos());
+ ret = strupper_talloc(NULL, name);
+ talloc_free(name);
+ }
+ return ret;
+}
+
/**
* @brief Returns an absolute path to a file concatenating the provided
* @a rootpath and @a basename
@@ -1843,45 +1532,6 @@ char *pid_path(const char *name)
}
/**
- * @brief Returns an absolute path to a file in the Samba lib directory.
- *
- * @param name File to find, relative to LIBDIR.
- *
- * @retval Pointer to a string containing the full path.
- **/
-
-char *lib_path(const char *name)
-{
- return talloc_asprintf(talloc_tos(), "%s/%s", get_dyn_LIBDIR(), name);
-}
-
-/**
- * @brief Returns an absolute path to a file in the Samba modules directory.
- *
- * @param name File to find, relative to MODULESDIR.
- *
- * @retval Pointer to a string containing the full path.
- **/
-
-char *modules_path(const char *name)
-{
- return talloc_asprintf(talloc_tos(), "%s/%s", get_dyn_MODULESDIR(), name);
-}
-
-/**
- * @brief Returns an absolute path to a file in the Samba data directory.
- *
- * @param name File to find, relative to CODEPAGEDIR.
- *
- * @retval Pointer to a talloc'ed string containing the full path.
- **/
-
-char *data_path(const char *name)
-{
- return talloc_asprintf(talloc_tos(), "%s/%s", get_dyn_CODEPAGEDIR(), name);
-}
-
-/**
* @brief Returns an absolute path to a file in the Samba state directory.
*
* @param name File to find, relative to STATEDIR.
@@ -1907,17 +1557,6 @@ char *cache_path(const char *name)
return xx_path(name, lp_cachedir());
}
-/**
- * @brief Returns the platform specific shared library extension.
- *
- * @retval Pointer to a const char * containing the extension.
- **/
-
-const char *shlib_ext(void)
-{
- return get_dyn_SHLIBEXT();
-}
-
/*******************************************************************
Given a filename - get its directory name
********************************************************************/
@@ -1942,7 +1581,7 @@ bool parent_dirname(TALLOC_CTX *mem_ctx, const char *dir, char **parent,
len = p-dir;
- if (!(*parent = (char *)TALLOC_MEMDUP(mem_ctx, dir, len+1))) {
+ if (!(*parent = (char *)talloc_memdup(mem_ctx, dir, len+1))) {
return False;
}
(*parent)[len] = '\0';
@@ -2211,7 +1850,7 @@ bool name_to_fqdn(fstring fqdn, const char *name)
}
}
}
- if (full && (StrCaseCmp(full, "localhost.localdomain") == 0)) {
+ if (full && (strcasecmp_m(full, "localhost.localdomain") == 0)) {
DEBUG(1, ("WARNING: your /etc/hosts file may be broken!\n"));
DEBUGADD(1, (" Specifing the machine hostname for address 127.0.0.1 may lead\n"));
DEBUGADD(1, (" to Kerberos authentication problems as localhost.localdomain\n"));
@@ -2303,6 +1942,7 @@ struct server_id pid_to_procid(pid_t pid)
{
struct server_id result;
result.pid = pid;
+ result.task_id = 0;
result.unique_id = my_unique_id;
result.vnn = my_vnn;
return result;
@@ -2317,6 +1957,8 @@ bool procid_equal(const struct server_id *p1, const struct server_id *p2)
{
if (p1->pid != p2->pid)
return False;
+ if (p1->task_id != p2->task_id)
+ return False;
if (p1->vnn != p2->vnn)
return False;
return True;
@@ -2332,6 +1974,8 @@ bool procid_is_me(const struct server_id *pid)
{
if (pid->pid != sys_getpid())
return False;
+ if (pid->task_id != 0)
+ return False;
if (pid->vnn != my_vnn)
return False;
return True;
@@ -2340,52 +1984,45 @@ bool procid_is_me(const struct server_id *pid)
struct server_id interpret_pid(const char *pid_string)
{
struct server_id result;
- int pid;
- unsigned int vnn;
- if (sscanf(pid_string, "%u:%d", &vnn, &pid) == 2) {
+ unsigned long long pid;
+ unsigned int vnn, task_id = 0;
+
+ ZERO_STRUCT(result);
+
+ /* We accept various forms with 1, 2 or 3 component forms
+ * because the server_id_str() can print different forms, and
+ * we want backwards compatibility for scripts that may call
+ * smbclient. */
+ if (sscanf(pid_string, "%u:%llu.%u", &vnn, &pid, &task_id) == 3) {
result.vnn = vnn;
result.pid = pid;
- }
- else if (sscanf(pid_string, "%d", &pid) == 1) {
+ result.task_id = task_id;
+ } else if (sscanf(pid_string, "%u:%llu", &vnn, &pid) == 2) {
+ result.vnn = vnn;
+ result.pid = pid;
+ result.task_id = 0;
+ } else if (sscanf(pid_string, "%llu.%u", &pid, &task_id) == 2) {
result.vnn = get_my_vnn();
result.pid = pid;
- }
- else {
+ result.task_id = task_id;
+ } else if (sscanf(pid_string, "%llu", &pid) == 1) {
+ result.vnn = get_my_vnn();
+ result.pid = pid;
+ } else {
result.vnn = NONCLUSTER_VNN;
- result.pid = -1;
+ result.pid = (uint64_t)-1;
}
- /* Assigning to result.pid may have overflowed
- Map negative pid to -1: i.e. error */
- if (result.pid < 0) {
- result.pid = -1;
- }
- result.unique_id = 0;
return result;
}
-char *procid_str(TALLOC_CTX *mem_ctx, const struct server_id *pid)
-{
- if (pid->vnn == NONCLUSTER_VNN) {
- return talloc_asprintf(mem_ctx,
- "%d",
- (int)pid->pid);
- }
- else {
- return talloc_asprintf(mem_ctx,
- "%u:%d",
- (unsigned)pid->vnn,
- (int)pid->pid);
- }
-}
-
char *procid_str_static(const struct server_id *pid)
{
- return procid_str(talloc_tos(), pid);
+ return server_id_str(talloc_tos(), pid);
}
bool procid_valid(const struct server_id *pid)
{
- return (pid->pid != -1);
+ return (pid->pid != (uint64_t)-1);
}
bool procid_is_local(const struct server_id *pid)
@@ -2519,111 +2156,6 @@ void split_domain_user(TALLOC_CTX *mem_ctx,
}
}
-#if 0
-
-Disable these now we have checked all code paths and ensured
-NULL returns on zero request. JRA.
-
-/****************************************************************
- talloc wrapper functions that guarentee a null pointer return
- if size == 0.
-****************************************************************/
-
-#ifndef MAX_TALLOC_SIZE
-#define MAX_TALLOC_SIZE 0x10000000
-#endif
-
-/*
- * talloc and zero memory.
- * - returns NULL if size is zero.
- */
-
-void *_talloc_zero_zeronull(const void *ctx, size_t size, const char *name)
-{
- void *p;
-
- if (size == 0) {
- return NULL;
- }
-
- p = talloc_named_const(ctx, size, name);
-
- if (p) {
- memset(p, '\0', size);
- }
-
- return p;
-}
-
-/*
- * memdup with a talloc.
- * - returns NULL if size is zero.
- */
-
-void *_talloc_memdup_zeronull(const void *t, const void *p, size_t size, const char *name)
-{
- void *newp;
-
- if (size == 0) {
- return NULL;
- }
-
- newp = talloc_named_const(t, size, name);
- if (newp) {
- memcpy(newp, p, size);
- }
-
- return newp;
-}
-
-/*
- * alloc an array, checking for integer overflow in the array size.
- * - returns NULL if count or el_size are zero.
- */
-
-void *_talloc_array_zeronull(const void *ctx, size_t el_size, unsigned count, const char *name)
-{
- if (count >= MAX_TALLOC_SIZE/el_size) {
- return NULL;
- }
-
- if (el_size == 0 || count == 0) {
- return NULL;
- }
-
- return talloc_named_const(ctx, el_size * count, name);
-}
-
-/*
- * alloc an zero array, checking for integer overflow in the array size
- * - returns NULL if count or el_size are zero.
- */
-
-void *_talloc_zero_array_zeronull(const void *ctx, size_t el_size, unsigned count, const char *name)
-{
- if (count >= MAX_TALLOC_SIZE/el_size) {
- return NULL;
- }
-
- if (el_size == 0 || count == 0) {
- return NULL;
- }
-
- return _talloc_zero(ctx, el_size * count, name);
-}
-
-/*
- * Talloc wrapper that returns NULL if size == 0.
- */
-void *talloc_zeronull(const void *context, size_t size, const char *name)
-{
- if (size == 0) {
- return NULL;
- }
- return talloc_named_const(context, size, name);
-}
-#endif
-
/****************************************************************
strip off leading '\\' from a hostname
****************************************************************/
@@ -2672,3 +2204,37 @@ int timeval_to_msec(struct timeval t)
{
return t.tv_sec * 1000 + (t.tv_usec+999) / 1000;
}
+
+/*******************************************************************
+ Check a given DOS pathname is valid for a share.
+********************************************************************/
+
+char *valid_share_pathname(TALLOC_CTX *ctx, const char *dos_pathname)
+{
+ char *ptr = NULL;
+
+ if (!dos_pathname) {
+ return NULL;
+ }
+
+ ptr = talloc_strdup(ctx, dos_pathname);
+ if (!ptr) {
+ return NULL;
+ }
+ /* Convert any '\' paths to '/' */
+ unix_format(ptr);
+ ptr = unix_clean_name(ctx, ptr);
+ if (!ptr) {
+ return NULL;
+ }
+
+ /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
+ if (strlen(ptr) > 2 && ptr[1] == ':' && ptr[0] != '/')
+ ptr += 2;
+
+ /* Only absolute paths allowed. */
+ if (*ptr != '/')
+ return NULL;
+
+ return ptr;
+}
diff --git a/source3/lib/util_builtin.c b/source3/lib/util_builtin.c
index e1b990619b..b370a76c69 100644
--- a/source3/lib/util_builtin.c
+++ b/source3/lib/util_builtin.c
@@ -18,7 +18,6 @@
*/
#include "includes.h"
-#include "passdb.h"
#include "../libcli/security/security.h"
struct rid_name_map {
diff --git a/source3/lib/util_cmdline.c b/source3/lib/util_cmdline.c
index cb0b79a5d3..39f136821c 100644
--- a/source3/lib/util_cmdline.c
+++ b/source3/lib/util_cmdline.c
@@ -34,7 +34,7 @@ struct user_auth_info *user_auth_info_init(TALLOC_CTX *mem_ctx)
{
struct user_auth_info *result;
- result = TALLOC_ZERO_P(mem_ctx, struct user_auth_info);
+ result = talloc_zero(mem_ctx, struct user_auth_info);
if (result == NULL) {
return NULL;
}
@@ -228,7 +228,7 @@ bool set_cmdline_auth_info_machine_account_creds(struct user_auth_info *auth_inf
return false;
}
- if (asprintf(&account, "%s$@%s", global_myname(), lp_realm()) < 0) {
+ if (asprintf(&account, "%s$@%s", lp_netbios_name(), lp_realm()) < 0) {
return false;
}
diff --git a/source3/lib/util_malloc.c b/source3/lib/util_malloc.c
new file mode 100644
index 0000000000..c052adc41b
--- /dev/null
+++ b/source3/lib/util_malloc.c
@@ -0,0 +1,171 @@
+/*
+ Unix SMB/CIFS implementation.
+ Samba utility functions
+ Copyright (C) Andrew Tridgell 1992-1998
+ Copyright (C) Jeremy Allison 2001-2007
+ Copyright (C) Simo Sorce 2001
+ Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
+ Copyright (C) James Peach 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+
+/* Max allowable allococation - 256mb - 0x10000000 */
+#define MAX_ALLOC_SIZE (1024*1024*256)
+
+#if defined(PARANOID_MALLOC_CHECKER)
+
+/****************************************************************************
+ Internal malloc wrapper. Externally visible.
+****************************************************************************/
+
+void *malloc_(size_t size)
+{
+ if (size == 0) {
+ return NULL;
+ }
+#undef malloc
+ return malloc(size);
+#define malloc(s) __ERROR_DONT_USE_MALLOC_DIRECTLY
+}
+
+/****************************************************************************
+ Internal calloc wrapper. Not externally visible.
+****************************************************************************/
+
+static void *calloc_(size_t count, size_t size)
+{
+ if (size == 0 || count == 0) {
+ return NULL;
+ }
+#undef calloc
+ return calloc(count, size);
+#define calloc(n,s) __ERROR_DONT_USE_CALLOC_DIRECTLY
+}
+
+/****************************************************************************
+ Internal realloc wrapper. Not externally visible.
+****************************************************************************/
+
+static void *realloc_(void *ptr, size_t size)
+{
+#undef realloc
+ return realloc(ptr, size);
+#define realloc(p,s) __ERROR_DONT_USE_RELLOC_DIRECTLY
+}
+
+#endif /* PARANOID_MALLOC_CHECKER */
+
+/****************************************************************************
+ Type-safe memalign
+****************************************************************************/
+
+void *memalign_array(size_t el_size, size_t align, unsigned int count)
+{
+ if (count >= MAX_ALLOC_SIZE/el_size) {
+ return NULL;
+ }
+
+ return sys_memalign(align, el_size*count);
+}
+
+/****************************************************************************
+ Type-safe calloc.
+****************************************************************************/
+
+void *calloc_array(size_t size, size_t nmemb)
+{
+ if (nmemb >= MAX_ALLOC_SIZE/size) {
+ return NULL;
+ }
+ if (size == 0 || nmemb == 0) {
+ return NULL;
+ }
+#if defined(PARANOID_MALLOC_CHECKER)
+ return calloc_(nmemb, size);
+#else
+ return calloc(nmemb, size);
+#endif
+}
+
+/****************************************************************************
+ Expand a pointer to be a particular size.
+ Note that this version of Realloc has an extra parameter that decides
+ whether to free the passed in storage on allocation failure or if the
+ new size is zero.
+
+ This is designed for use in the typical idiom of :
+
+ p = SMB_REALLOC(p, size)
+ if (!p) {
+ return error;
+ }
+
+ and not to have to keep track of the old 'p' contents to free later, nor
+ to worry if the size parameter was zero. In the case where NULL is returned
+ we guarentee that p has been freed.
+
+ If free later semantics are desired, then pass 'free_old_on_error' as False which
+ guarentees that the old contents are not freed on error, even if size == 0. To use
+ this idiom use :
+
+ tmp = SMB_REALLOC_KEEP_OLD_ON_ERROR(p, size);
+ if (!tmp) {
+ SAFE_FREE(p);
+ return error;
+ } else {
+ p = tmp;
+ }
+
+ Changes were instigated by Coverity error checking. JRA.
+****************************************************************************/
+
+void *Realloc(void *p, size_t size, bool free_old_on_error)
+{
+ void *ret=NULL;
+
+ if (size == 0) {
+ if (free_old_on_error) {
+ SAFE_FREE(p);
+ }
+ DEBUG(2,("Realloc asked for 0 bytes\n"));
+ return NULL;
+ }
+
+#if defined(PARANOID_MALLOC_CHECKER)
+ if (!p) {
+ ret = (void *)malloc_(size);
+ } else {
+ ret = (void *)realloc_(p,size);
+ }
+#else
+ if (!p) {
+ ret = (void *)malloc(size);
+ } else {
+ ret = (void *)realloc(p,size);
+ }
+#endif
+
+ if (!ret) {
+ if (free_old_on_error && p) {
+ SAFE_FREE(p);
+ }
+ DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",(int)size));
+ }
+
+ return(ret);
+}
+
diff --git a/source3/lib/util_names.c b/source3/lib/util_names.c
index bd6e5c1202..0e128eab1c 100644
--- a/source3/lib/util_names.c
+++ b/source3/lib/util_names.c
@@ -6,7 +6,7 @@
Copyright (C) Simo Sorce 2001
Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
Copyright (C) James Peach 2006
- Copyright (C) Andrew Bartlett 2010
+ Copyright (C) Andrew Bartlett 2010-2011
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
@@ -24,45 +24,131 @@
#include "includes.h"
-static char *smb_myname;
-static char *smb_myworkgroup;
-
/***********************************************************************
- Allocate and set myname. Ensure upper case.
+ Definitions for all names.
***********************************************************************/
-bool set_global_myname(const char *myname)
+static int smb_num_netbios_names;
+static char **smb_my_netbios_names;
+
+static void free_netbios_names_array(void)
+{
+ int i;
+
+ for (i = 0; i < smb_num_netbios_names; i++)
+ SAFE_FREE(smb_my_netbios_names[i]);
+
+ SAFE_FREE(smb_my_netbios_names);
+ smb_num_netbios_names = 0;
+}
+
+static bool allocate_my_netbios_names_array(size_t number)
{
- SAFE_FREE(smb_myname);
- smb_myname = SMB_STRDUP(myname);
- if (!smb_myname)
+ free_netbios_names_array();
+
+ smb_num_netbios_names = number + 1;
+ smb_my_netbios_names = SMB_MALLOC_ARRAY( char *, smb_num_netbios_names );
+
+ if (!smb_my_netbios_names)
return False;
- strupper_m(smb_myname);
+
+ memset(smb_my_netbios_names, '\0', sizeof(char *) * smb_num_netbios_names);
return True;
}
-const char *global_myname(void)
+static bool set_my_netbios_names(const char *name, int i)
{
- return smb_myname;
+ SAFE_FREE(smb_my_netbios_names[i]);
+
+ smb_my_netbios_names[i] = SMB_STRDUP(name);
+ if (!smb_my_netbios_names[i])
+ return False;
+ strupper_m(smb_my_netbios_names[i]);
+ return True;
}
/***********************************************************************
- Allocate and set myworkgroup. Ensure upper case.
+ Free memory allocated to global objects
***********************************************************************/
-bool set_global_myworkgroup(const char *myworkgroup)
+void gfree_names(void)
+{
+ free_netbios_names_array();
+ free_local_machine_name();
+}
+
+const char *my_netbios_names(int i)
+{
+ return smb_my_netbios_names[i];
+}
+
+bool set_netbios_aliases(const char **str_array)
{
- SAFE_FREE(smb_myworkgroup);
- smb_myworkgroup = SMB_STRDUP(myworkgroup);
- if (!smb_myworkgroup)
+ size_t namecount;
+
+ /* Work out the max number of netbios aliases that we have */
+ for( namecount=0; str_array && (str_array[namecount] != NULL); namecount++ )
+ ;
+
+ if ( lp_netbios_name() && *lp_netbios_name())
+ namecount++;
+
+ /* Allocate space for the netbios aliases */
+ if (!allocate_my_netbios_names_array(namecount))
return False;
- strupper_m(smb_myworkgroup);
+
+ /* Use the global_myname string first */
+ namecount=0;
+ if ( lp_netbios_name() && *lp_netbios_name()) {
+ set_my_netbios_names( lp_netbios_name(), namecount );
+ namecount++;
+ }
+
+ if (str_array) {
+ size_t i;
+ for ( i = 0; str_array[i] != NULL; i++) {
+ size_t n;
+ bool duplicate = False;
+
+ /* Look for duplicates */
+ for( n=0; n<namecount; n++ ) {
+ if( strequal( str_array[i], my_netbios_names(n) ) ) {
+ duplicate = True;
+ break;
+ }
+ }
+ if (!duplicate) {
+ if (!set_my_netbios_names(str_array[i], namecount))
+ return False;
+ namecount++;
+ }
+ }
+ }
return True;
}
-const char *lp_workgroup(void)
+/****************************************************************************
+ Common name initialization code.
+****************************************************************************/
+
+bool init_names(void)
{
- return smb_myworkgroup;
+ int n;
+
+ if (!set_netbios_aliases(lp_netbios_aliases())) {
+ DEBUG( 0, ( "init_names: malloc fail.\n" ) );
+ return False;
+ }
+
+ set_local_machine_name(lp_netbios_name(),false);
+
+ DEBUG( 5, ("Netbios name list:-\n") );
+ for( n=0; my_netbios_names(n); n++ ) {
+ DEBUGADD( 5, ("my_netbios_names[%d]=\"%s\"\n",
+ n, my_netbios_names(n) ) );
+ }
+
+ return( True );
}
/******************************************************************
@@ -75,11 +161,6 @@ const char *get_global_sam_name(void)
if (IS_DC) {
return lp_workgroup();
}
- return global_myname();
+ return lp_netbios_name();
}
-void gfree_netbios_names(void)
-{
- SAFE_FREE( smb_myname );
- SAFE_FREE( smb_myworkgroup );
-}
diff --git a/source3/lib/util_nttoken.c b/source3/lib/util_nttoken.c
index 2fd0f088ab..ffa858d779 100644
--- a/source3/lib/util_nttoken.c
+++ b/source3/lib/util_nttoken.c
@@ -39,7 +39,7 @@ struct security_token *dup_nt_token(TALLOC_CTX *mem_ctx, const struct security_t
if (!ptoken)
return NULL;
- token = TALLOC_ZERO_P(mem_ctx, struct security_token);
+ token = talloc_zero(mem_ctx, struct security_token);
if (token == NULL) {
DEBUG(0, ("talloc failed\n"));
return NULL;
@@ -80,7 +80,7 @@ NTSTATUS merge_nt_token(TALLOC_CTX *mem_ctx,
return NT_STATUS_INVALID_PARAMETER;
}
- token = TALLOC_ZERO_P(mem_ctx, struct security_token);
+ token = talloc_zero(mem_ctx, struct security_token);
NT_STATUS_HAVE_NO_MEMORY(token);
for (i=0; i < token_1->num_sids; i++) {
diff --git a/source3/lib/util_sid.c b/source3/lib/util_sid.c
index ef46a38f8a..f080d3dfb0 100644
--- a/source3/lib/util_sid.c
+++ b/source3/lib/util_sid.c
@@ -121,7 +121,7 @@ char *sid_binstring_hex(const struct dom_sid *sid)
if (!buf)
return NULL;
sid_linearize(buf, len, sid);
- hex_encode(buf, len, &s);
+ hex_encode((const unsigned char *)buf, len, &s);
free(buf);
return s;
}
diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c
index 71f6a8f29c..9b8632b181 100644
--- a/source3/lib/util_sock.c
+++ b/source3/lib/util_sock.c
@@ -24,158 +24,9 @@
#include "memcache.h"
#include "../lib/async_req/async_sock.h"
#include "../lib/util/select.h"
-#include "interfaces.h"
-
-/****************************************************************************
- Get a port number in host byte order from a sockaddr_storage.
-****************************************************************************/
-
-uint16_t get_sockaddr_port(const struct sockaddr_storage *pss)
-{
- uint16_t port = 0;
-
- if (pss->ss_family != AF_INET) {
-#if defined(HAVE_IPV6)
- /* IPv6 */
- const struct sockaddr_in6 *sa6 =
- (const struct sockaddr_in6 *)pss;
- port = ntohs(sa6->sin6_port);
-#endif
- } else {
- const struct sockaddr_in *sa =
- (const struct sockaddr_in *)pss;
- port = ntohs(sa->sin_port);
- }
- return port;
-}
-
-/****************************************************************************
- Print out an IPv4 or IPv6 address from a struct sockaddr_storage.
-****************************************************************************/
-
-static char *print_sockaddr_len(char *dest,
- size_t destlen,
- const struct sockaddr *psa,
- socklen_t psalen)
-{
- if (destlen > 0) {
- dest[0] = '\0';
- }
- (void)sys_getnameinfo(psa,
- psalen,
- dest, destlen,
- NULL, 0,
- NI_NUMERICHOST);
- return dest;
-}
-
-/****************************************************************************
- Print out an IPv4 or IPv6 address from a struct sockaddr_storage.
-****************************************************************************/
-
-char *print_sockaddr(char *dest,
- size_t destlen,
- const struct sockaddr_storage *psa)
-{
- return print_sockaddr_len(dest, destlen, (struct sockaddr *)psa,
- sizeof(struct sockaddr_storage));
-}
-
-/****************************************************************************
- Print out a canonical IPv4 or IPv6 address from a struct sockaddr_storage.
-****************************************************************************/
-
-char *print_canonical_sockaddr(TALLOC_CTX *ctx,
- const struct sockaddr_storage *pss)
-{
- char addr[INET6_ADDRSTRLEN];
- char *dest = NULL;
- int ret;
-
- /* Linux getnameinfo() man pages says port is unitialized if
- service name is NULL. */
-
- ret = sys_getnameinfo((const struct sockaddr *)pss,
- sizeof(struct sockaddr_storage),
- addr, sizeof(addr),
- NULL, 0,
- NI_NUMERICHOST);
- if (ret != 0) {
- return NULL;
- }
-
- if (pss->ss_family != AF_INET) {
-#if defined(HAVE_IPV6)
- dest = talloc_asprintf(ctx, "[%s]", addr);
-#else
- return NULL;
-#endif
- } else {
- dest = talloc_asprintf(ctx, "%s", addr);
- }
-
- return dest;
-}
-
-/****************************************************************************
- Return the string of an IP address (IPv4 or IPv6).
-****************************************************************************/
-
-static const char *get_socket_addr(int fd, char *addr_buf, size_t addr_len)
-{
- struct sockaddr_storage sa;
- socklen_t length = sizeof(sa);
-
- /* Ok, returning a hard coded IPv4 address
- * is bogus, but it's just as bogus as a
- * zero IPv6 address. No good choice here.
- */
-
- strlcpy(addr_buf, "0.0.0.0", addr_len);
-
- if (fd == -1) {
- return addr_buf;
- }
-
- if (getsockname(fd, (struct sockaddr *)&sa, &length) < 0) {
- DEBUG(0,("getsockname failed. Error was %s\n",
- strerror(errno) ));
- return addr_buf;
- }
-
- return print_sockaddr_len(addr_buf, addr_len, (struct sockaddr *)&sa, length);
-}
-
-/****************************************************************************
- Return the port number we've bound to on a socket.
-****************************************************************************/
-
-int get_socket_port(int fd)
-{
- struct sockaddr_storage sa;
- socklen_t length = sizeof(sa);
-
- if (fd == -1) {
- return -1;
- }
-
- if (getsockname(fd, (struct sockaddr *)&sa, &length) < 0) {
- int level = (errno == ENOTCONN) ? 2 : 0;
- DEBUG(level, ("getsockname failed. Error was %s\n",
- strerror(errno)));
- return -1;
- }
-
-#if defined(HAVE_IPV6)
- if (sa.ss_family == AF_INET6) {
- return ntohs(((struct sockaddr_in6 *)&sa)->sin6_port);
- }
-#endif
- if (sa.ss_family == AF_INET) {
- return ntohs(((struct sockaddr_in *)&sa)->sin_port);
- }
- return -1;
-}
+#include "lib/socket/interfaces.h"
+#include "../lib/util/tevent_unix.h"
+#include "../lib/util/tevent_ntstatus.h"
const char *client_name(int fd)
{
@@ -187,11 +38,6 @@ const char *client_addr(int fd, char *addr, size_t addrlen)
return get_peer_addr(fd,addr,addrlen);
}
-const char *client_socket_addr(int fd, char *addr, size_t addr_len)
-{
- return get_socket_addr(fd, addr, addr_len);
-}
-
#if 0
/* Not currently used. JRA. */
int client_socket_port(int fd)
@@ -232,166 +78,6 @@ bool is_a_socket(int fd)
return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
}
-enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
-
-typedef struct smb_socket_option {
- const char *name;
- int level;
- int option;
- int value;
- int opttype;
-} smb_socket_option;
-
-static const smb_socket_option socket_options[] = {
- {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL},
- {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL},
- {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL},
-#ifdef TCP_NODELAY
- {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL},
-#endif
-#ifdef TCP_KEEPCNT
- {"TCP_KEEPCNT", IPPROTO_TCP, TCP_KEEPCNT, 0, OPT_INT},
-#endif
-#ifdef TCP_KEEPIDLE
- {"TCP_KEEPIDLE", IPPROTO_TCP, TCP_KEEPIDLE, 0, OPT_INT},
-#endif
-#ifdef TCP_KEEPINTVL
- {"TCP_KEEPINTVL", IPPROTO_TCP, TCP_KEEPINTVL, 0, OPT_INT},
-#endif
-#ifdef IPTOS_LOWDELAY
- {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON},
-#endif
-#ifdef IPTOS_THROUGHPUT
- {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON},
-#endif
-#ifdef SO_REUSEPORT
- {"SO_REUSEPORT", SOL_SOCKET, SO_REUSEPORT, 0, OPT_BOOL},
-#endif
-#ifdef SO_SNDBUF
- {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT},
-#endif
-#ifdef SO_RCVBUF
- {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT},
-#endif
-#ifdef SO_SNDLOWAT
- {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT},
-#endif
-#ifdef SO_RCVLOWAT
- {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT},
-#endif
-#ifdef SO_SNDTIMEO
- {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT},
-#endif
-#ifdef SO_RCVTIMEO
- {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT},
-#endif
-#ifdef TCP_FASTACK
- {"TCP_FASTACK", IPPROTO_TCP, TCP_FASTACK, 0, OPT_INT},
-#endif
-#ifdef TCP_QUICKACK
- {"TCP_QUICKACK", IPPROTO_TCP, TCP_QUICKACK, 0, OPT_BOOL},
-#endif
-#ifdef TCP_KEEPALIVE_THRESHOLD
- {"TCP_KEEPALIVE_THRESHOLD", IPPROTO_TCP, TCP_KEEPALIVE_THRESHOLD, 0, OPT_INT},
-#endif
-#ifdef TCP_KEEPALIVE_ABORT_THRESHOLD
- {"TCP_KEEPALIVE_ABORT_THRESHOLD", IPPROTO_TCP, TCP_KEEPALIVE_ABORT_THRESHOLD, 0, OPT_INT},
-#endif
- {NULL,0,0,0,0}};
-
-/****************************************************************************
- Print socket options.
-****************************************************************************/
-
-static void print_socket_options(int s)
-{
- int value;
- socklen_t vlen = 4;
- const smb_socket_option *p = &socket_options[0];
-
- /* wrapped in if statement to prevent streams
- * leak in SCO Openserver 5.0 */
- /* reported on samba-technical --jerry */
- if ( DEBUGLEVEL >= 5 ) {
- DEBUG(5,("Socket options:\n"));
- for (; p->name != NULL; p++) {
- if (getsockopt(s, p->level, p->option,
- (void *)&value, &vlen) == -1) {
- DEBUGADD(5,("\tCould not test socket option %s.\n",
- p->name));
- } else {
- DEBUGADD(5,("\t%s = %d\n",
- p->name,value));
- }
- }
- }
- }
-
-/****************************************************************************
- Set user socket options.
-****************************************************************************/
-
-void set_socket_options(int fd, const char *options)
-{
- TALLOC_CTX *ctx = talloc_stackframe();
- char *tok;
-
- while (next_token_talloc(ctx, &options, &tok," \t,")) {
- int ret=0,i;
- int value = 1;
- char *p;
- bool got_value = false;
-
- if ((p = strchr_m(tok,'='))) {
- *p = 0;
- value = atoi(p+1);
- got_value = true;
- }
-
- for (i=0;socket_options[i].name;i++)
- if (strequal(socket_options[i].name,tok))
- break;
-
- if (!socket_options[i].name) {
- DEBUG(0,("Unknown socket option %s\n",tok));
- continue;
- }
-
- switch (socket_options[i].opttype) {
- case OPT_BOOL:
- case OPT_INT:
- ret = setsockopt(fd,socket_options[i].level,
- socket_options[i].option,
- (char *)&value,sizeof(int));
- break;
-
- case OPT_ON:
- if (got_value)
- DEBUG(0,("syntax error - %s "
- "does not take a value\n",tok));
-
- {
- int on = socket_options[i].value;
- ret = setsockopt(fd,socket_options[i].level,
- socket_options[i].option,
- (char *)&on,sizeof(int));
- }
- break;
- }
-
- if (ret != 0) {
- /* be aware that some systems like Solaris return
- * EINVAL to a setsockopt() call when the client
- * sent a RST previously - no need to worry */
- DEBUG(2,("Failed to set socket option %s (Error %s)\n",
- tok, strerror(errno) ));
- }
- }
-
- TALLOC_FREE(ctx);
- print_socket_options(fd);
-}
-
/****************************************************************************
Read from a socket.
****************************************************************************/
@@ -571,7 +257,7 @@ ssize_t write_data_iov(int fd, const struct iovec *orig_iov, int iovcnt)
* discarding elements.
*/
- iov_copy = (struct iovec *)TALLOC_MEMDUP(
+ iov_copy = (struct iovec *)talloc_memdup(
talloc_tos(), orig_iov, sizeof(struct iovec) * iovcnt);
if (iov_copy == NULL) {
@@ -620,7 +306,7 @@ ssize_t write_data(int fd, const char *buffer, size_t N)
{
struct iovec iov;
- iov.iov_base = CONST_DISCARD(void *, buffer);
+ iov.iov_base = discard_const_p(void, buffer);
iov.iov_len = N;
return write_data_iov(fd, &iov, 1);
}
@@ -787,6 +473,32 @@ int open_socket_in(int type,
#endif /* SO_REUSEPORT */
}
+#ifdef HAVE_IPV6
+ /*
+ * As IPV6_V6ONLY is the default on some systems,
+ * we better try to be consistent and always use it.
+ *
+ * This also avoids using IPv4 via AF_INET6 sockets
+ * and makes sure %I never resolves to a '::ffff:192.168.0.1'
+ * string.
+ */
+ if (sock.ss_family == AF_INET6) {
+ int val = 1;
+ int ret;
+
+ ret = setsockopt(res, IPPROTO_IPV6, IPV6_V6ONLY,
+ (const void *)&val, sizeof(val));
+ if (ret == -1) {
+ if(DEBUGLVL(0)) {
+ dbgtext("open_socket_in(): IPV6_ONLY failed: ");
+ dbgtext("%s\n", strerror(errno));
+ }
+ close(res);
+ return -1;
+ }
+ }
+#endif
+
/* now we've got a socket - we need to bind it */
if (bind(res, (struct sockaddr *)&sock, slen) == -1 ) {
if( DEBUGLVL(dlevel) && (port == SMB_PORT1 ||
@@ -812,7 +524,7 @@ struct open_socket_out_state {
struct sockaddr_storage ss;
socklen_t salen;
uint16_t port;
- int wait_nsec;
+ int wait_usec;
};
static void open_socket_out_connected(struct tevent_req *subreq);
@@ -848,7 +560,7 @@ struct tevent_req *open_socket_out_send(TALLOC_CTX *mem_ctx,
state->ev = ev;
state->ss = *pss;
state->port = port;
- state->wait_nsec = 10000;
+ state->wait_usec = 10000;
state->salen = -1;
state->fd = socket(state->ss.ss_family, SOCK_STREAM, 0);
@@ -859,7 +571,7 @@ struct tevent_req *open_socket_out_send(TALLOC_CTX *mem_ctx,
talloc_set_destructor(state, open_socket_out_state_destructor);
if (!tevent_req_set_endtime(
- result, ev, timeval_current_ofs(0, timeout*1000))) {
+ result, ev, timeval_current_ofs_msec(timeout))) {
goto fail;
}
@@ -896,7 +608,7 @@ struct tevent_req *open_socket_out_send(TALLOC_CTX *mem_ctx,
if ((subreq == NULL)
|| !tevent_req_set_endtime(
subreq, state->ev,
- timeval_current_ofs(0, state->wait_nsec))) {
+ timeval_current_ofs(0, state->wait_usec))) {
goto fail;
}
tevent_req_set_callback(subreq, open_socket_out_connected, result);
@@ -938,8 +650,8 @@ static void open_socket_out_connected(struct tevent_req *subreq)
* retry
*/
- if (state->wait_nsec < 250000) {
- state->wait_nsec *= 1.5;
+ if (state->wait_usec < 250000) {
+ state->wait_usec *= 1.5;
}
subreq = async_connect_send(state, state->ev, state->fd,
@@ -950,7 +662,7 @@ static void open_socket_out_connected(struct tevent_req *subreq)
}
if (!tevent_req_set_endtime(
subreq, state->ev,
- timeval_current_ofs(0, state->wait_nsec))) {
+ timeval_current_ofs_usec(state->wait_usec))) {
tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
return;
}
@@ -1248,7 +960,7 @@ static bool matchname(const char *remotehost,
continue;
}
if (sockaddr_equal((const struct sockaddr *)res->ai_addr,
- (struct sockaddr *)pss)) {
+ (const struct sockaddr *)pss)) {
freeaddrinfo(ailist);
return true;
}
@@ -1454,14 +1166,21 @@ int create_pipe_sock(const char *socket_dir,
} else {
/* Check ownership and permission on existing directory */
if (!S_ISDIR(st.st_mode)) {
- DEBUG(0, ("socket directory %s isn't a directory\n",
+ DEBUG(0, ("socket directory '%s' isn't a directory\n",
socket_dir));
goto out_umask;
}
- if ((st.st_uid != sec_initial_uid()) ||
- ((st.st_mode & 0777) != dir_perms)) {
- DEBUG(0, ("invalid permissions on socket directory "
- "%s\n", socket_dir));
+ if (st.st_uid != sec_initial_uid()) {
+ DEBUG(0, ("invalid ownership on directory "
+ "'%s'\n", socket_dir));
+ umask(old_umask);
+ goto out_umask;
+ }
+ if ((st.st_mode & 0777) != dir_perms) {
+ DEBUG(0, ("invalid permissions on directory "
+ "'%s': has 0%o should be 0%o\n", socket_dir,
+ (st.st_mode & 0777), dir_perms));
+ umask(old_umask);
goto out_umask;
}
}
@@ -1602,13 +1321,13 @@ static bool is_my_ipaddr(const char *ipaddr_str)
return false;
}
- if (ismyaddr((struct sockaddr *)&ss)) {
- return true;
+ if (is_zero_addr(&ss)) {
+ return false;
}
- if (is_zero_addr(&ss) ||
- is_loopback_addr((struct sockaddr *)&ss)) {
- return false;
+ if (ismyaddr((struct sockaddr *)&ss) ||
+ is_loopback_addr((struct sockaddr *)&ss)) {
+ return true;
}
n = get_interfaces(talloc_tos(), &nics);
@@ -1651,7 +1370,7 @@ bool is_myname_or_ipaddr(const char *s)
}
/* Optimize for the common case */
- if (strequal(servername, global_myname())) {
+ if (strequal(servername, lp_netbios_name())) {
return true;
}
@@ -1802,7 +1521,7 @@ int poll_one_fd(int fd, int events, int timeout, int *revents)
int ret;
int saved_errno;
- fds = TALLOC_ZERO_ARRAY(talloc_tos(), struct pollfd, 2);
+ fds = talloc_zero_array(talloc_tos(), struct pollfd, 2);
if (fds == NULL) {
errno = ENOMEM;
return -1;
diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c
index 88a3d703f4..a348b389e8 100644
--- a/source3/lib/util_str.c
+++ b/source3/lib/util_str.c
@@ -36,164 +36,6 @@ const char toupper_ascii_fast_table[128] = {
};
/**
- * Case insensitive string compararison.
- *
- * iconv does not directly give us a way to compare strings in
- * arbitrary unix character sets -- all we can is convert and then
- * compare. This is expensive.
- *
- * As an optimization, we do a first pass that considers only the
- * prefix of the strings that is entirely 7-bit. Within this, we
- * check whether they have the same value.
- *
- * Hopefully this will often give the answer without needing to copy.
- * In particular it should speed comparisons to literal ascii strings
- * or comparisons of strings that are "obviously" different.
- *
- * If we find a non-ascii character we fall back to converting via
- * iconv.
- *
- * This should never be slower than convering the whole thing, and
- * often faster.
- *
- * A different optimization would be to compare for bitwise equality
- * in the binary encoding. (It would be possible thought hairy to do
- * both simultaneously.) But in that case if they turn out to be
- * different, we'd need to restart the whole thing.
- *
- * Even better is to implement strcasecmp for each encoding and use a
- * function pointer.
- **/
-int StrCaseCmp(const char *s, const char *t)
-{
-
- const char *ps, *pt;
- size_t size;
- smb_ucs2_t *buffer_s, *buffer_t;
- int ret;
-
- for (ps = s, pt = t; ; ps++, pt++) {
- char us, ut;
-
- if (!*ps && !*pt)
- return 0; /* both ended */
- else if (!*ps)
- return -1; /* s is a prefix */
- else if (!*pt)
- return +1; /* t is a prefix */
- else if ((*ps & 0x80) || (*pt & 0x80))
- /* not ascii anymore, do it the hard way
- * from here on in */
- break;
-
- us = toupper_ascii_fast(*ps);
- ut = toupper_ascii_fast(*pt);
- if (us == ut)
- continue;
- else if (us < ut)
- return -1;
- else if (us > ut)
- return +1;
- }
-
- if (!push_ucs2_talloc(talloc_tos(), &buffer_s, ps, &size)) {
- return strcmp(ps, pt);
- /* Not quite the right answer, but finding the right one
- under this failure case is expensive, and it's pretty
- close */
- }
-
- if (!push_ucs2_talloc(talloc_tos(), &buffer_t, pt, &size)) {
- TALLOC_FREE(buffer_s);
- return strcmp(ps, pt);
- /* Not quite the right answer, but finding the right one
- under this failure case is expensive, and it's pretty
- close */
- }
-
- ret = strcasecmp_w(buffer_s, buffer_t);
- TALLOC_FREE(buffer_s);
- TALLOC_FREE(buffer_t);
- return ret;
-}
-
-
-/**
- Case insensitive string compararison, length limited.
-**/
-int StrnCaseCmp(const char *s, const char *t, size_t len)
-{
- size_t n = 0;
- const char *ps, *pt;
- size_t size;
- smb_ucs2_t *buffer_s, *buffer_t;
- int ret;
-
- for (ps = s, pt = t; n < len ; ps++, pt++, n++) {
- char us, ut;
-
- if (!*ps && !*pt)
- return 0; /* both ended */
- else if (!*ps)
- return -1; /* s is a prefix */
- else if (!*pt)
- return +1; /* t is a prefix */
- else if ((*ps & 0x80) || (*pt & 0x80))
- /* not ascii anymore, do it the
- * hard way from here on in */
- break;
-
- us = toupper_ascii_fast(*ps);
- ut = toupper_ascii_fast(*pt);
- if (us == ut)
- continue;
- else if (us < ut)
- return -1;
- else if (us > ut)
- return +1;
- }
-
- if (n == len) {
- return 0;
- }
-
- if (!push_ucs2_talloc(talloc_tos(), &buffer_s, ps, &size)) {
- return strncmp(ps, pt, len-n);
- /* Not quite the right answer, but finding the right one
- under this failure case is expensive,
- and it's pretty close */
- }
-
- if (!push_ucs2_talloc(talloc_tos(), &buffer_t, pt, &size)) {
- TALLOC_FREE(buffer_s);
- return strncmp(ps, pt, len-n);
- /* Not quite the right answer, but finding the right one
- under this failure case is expensive,
- and it's pretty close */
- }
-
- ret = strncasecmp_w(buffer_s, buffer_t, len-n);
- TALLOC_FREE(buffer_s);
- TALLOC_FREE(buffer_t);
- return ret;
-}
-
-/**
- * Compare 2 strings.
- *
- * @note The comparison is case-insensitive.
- **/
-bool strequal(const char *s1, const char *s2)
-{
- if (s1 == s2)
- return(true);
- if (!s1 || !s2)
- return(false);
-
- return(StrCaseCmp(s1,s2)==0);
-}
-
-/**
* Compare 2 strings up to and including the nth char.
*
* @note The comparison is case-insensitive.
@@ -205,7 +47,7 @@ bool strnequal(const char *s1,const char *s2,size_t n)
if (!s1 || !s2 || !n)
return(false);
- return(StrnCaseCmp(s1,s2,n)==0);
+ return(strncasecmp_m(s1,s2,n)==0);
}
/**
@@ -328,77 +170,6 @@ bool trim_char(char *s,char cfront,char cback)
}
/**
- Safe string copy into a known length string. maxlength does not
- include the terminating zero.
-**/
-
-char *safe_strcpy_fn(char *dest,
- const char *src,
- size_t maxlength)
-{
- size_t len;
-
- if (!dest) {
- smb_panic("ERROR: NULL dest in safe_strcpy");
- }
-
- if (!src) {
- *dest = 0;
- return dest;
- }
-
- len = strnlen(src, maxlength+1);
-
- if (len > maxlength) {
- DEBUG(0,("ERROR: string overflow by "
- "%lu (%lu - %lu) in safe_strcpy [%.50s]\n",
- (unsigned long)(len-maxlength), (unsigned long)len,
- (unsigned long)maxlength, src));
- len = maxlength;
- }
-
- memmove(dest, src, len);
- dest[len] = 0;
- return dest;
-}
-
-/**
- Safe string cat into a string. maxlength does not
- include the terminating zero.
-**/
-char *safe_strcat_fn(char *dest,
- const char *src,
- size_t maxlength)
-{
- size_t src_len, dest_len;
-
- if (!dest) {
- smb_panic("ERROR: NULL dest in safe_strcat");
- }
-
- if (!src)
- return dest;
-
- src_len = strnlen(src, maxlength + 1);
- dest_len = strnlen(dest, maxlength + 1);
-
- if (src_len + dest_len > maxlength) {
- DEBUG(0,("ERROR: string overflow by %d "
- "in safe_strcat [%.50s]\n",
- (int)(src_len + dest_len - maxlength), src));
- if (maxlength > dest_len) {
- memcpy(&dest[dest_len], src, maxlength - dest_len);
- }
- dest[maxlength] = 0;
- return NULL;
- }
-
- memcpy(&dest[dest_len], src, src_len);
- dest[dest_len + src_len] = 0;
- return dest;
-}
-
-/**
Like strncpy but always null terminates. Make sure there is room!
The variable n should always be one less than the available size.
**/
@@ -446,7 +217,7 @@ bool in_list(const char *s, const char *list, bool casesensitive)
break;
}
} else {
- if (StrCaseCmp(tok,s) == 0) {
+ if (strcasecmp_m(tok,s) == 0) {
ret = true;
break;
}
@@ -456,235 +227,6 @@ bool in_list(const char *s, const char *list, bool casesensitive)
return ret;
}
-/* this is used to prevent lots of mallocs of size 1 */
-static const char null_string[] = "";
-
-/**
- Set a string value, allocing the space for the string
-**/
-
-static bool string_init(char **dest,const char *src)
-{
- size_t l;
-
- if (!src)
- src = "";
-
- l = strlen(src);
-
- if (l == 0) {
- *dest = CONST_DISCARD(char*, null_string);
- } else {
- (*dest) = SMB_STRDUP(src);
- if ((*dest) == NULL) {
- DEBUG(0,("Out of memory in string_init\n"));
- return false;
- }
- }
- return(true);
-}
-
-/**
- Free a string value.
-**/
-
-void string_free(char **s)
-{
- if (!s || !(*s))
- return;
- if (*s == null_string)
- *s = NULL;
- SAFE_FREE(*s);
-}
-
-/**
- Set a string value, deallocating any existing space, and allocing the space
- for the string
-**/
-
-bool string_set(char **dest,const char *src)
-{
- string_free(dest);
- return(string_init(dest,src));
-}
-
-/**
- Substitute a string for a pattern in another string. Make sure there is
- enough room!
-
- This routine looks for pattern in s and replaces it with
- insert. It may do multiple replacements or just one.
-
- Any of " ; ' $ or ` in the insert string are replaced with _
- if len==0 then the string cannot be extended. This is different from the old
- use of len==0 which was for no length checks to be done.
-**/
-
-void string_sub2(char *s,const char *pattern, const char *insert, size_t len,
- bool remove_unsafe_characters, bool replace_once,
- bool allow_trailing_dollar)
-{
- char *p;
- ssize_t ls,lp,li, i;
-
- if (!insert || !pattern || !*pattern || !s)
- return;
-
- ls = (ssize_t)strlen(s);
- lp = (ssize_t)strlen(pattern);
- li = (ssize_t)strlen(insert);
-
- if (len == 0)
- len = ls + 1; /* len is number of *bytes* */
-
- while (lp <= ls && (p = strstr_m(s,pattern))) {
- if (ls + (li-lp) >= len) {
- DEBUG(0,("ERROR: string overflow by "
- "%d in string_sub(%.50s, %d)\n",
- (int)(ls + (li-lp) - len),
- pattern, (int)len));
- break;
- }
- if (li != lp) {
- memmove(p+li,p+lp,strlen(p+lp)+1);
- }
- for (i=0;i<li;i++) {
- switch (insert[i]) {
- case '$':
- /* allow a trailing $
- * (as in machine accounts) */
- if (allow_trailing_dollar && (i == li - 1 )) {
- p[i] = insert[i];
- break;
- }
- case '`':
- case '"':
- case '\'':
- case ';':
- case '%':
- case '\r':
- case '\n':
- if ( remove_unsafe_characters ) {
- p[i] = '_';
- /* yes this break should be here
- * since we want to fall throw if
- * not replacing unsafe chars */
- break;
- }
- default:
- p[i] = insert[i];
- }
- }
- s = p + li;
- ls += (li-lp);
-
- if (replace_once)
- break;
- }
-}
-
-void string_sub_once(char *s, const char *pattern,
- const char *insert, size_t len)
-{
- string_sub2( s, pattern, insert, len, true, true, false );
-}
-
-void string_sub(char *s,const char *pattern, const char *insert, size_t len)
-{
- string_sub2( s, pattern, insert, len, true, false, false );
-}
-
-void fstring_sub(char *s,const char *pattern,const char *insert)
-{
- string_sub(s, pattern, insert, sizeof(fstring));
-}
-
-/**
- Similar to string_sub2, but it will accept only allocated strings
- and may realloc them so pay attention at what you pass on no
- pointers inside strings, no const may be passed
- as string.
-**/
-
-char *realloc_string_sub2(char *string,
- const char *pattern,
- const char *insert,
- bool remove_unsafe_characters,
- bool allow_trailing_dollar)
-{
- char *p, *in;
- char *s;
- ssize_t ls,lp,li,ld, i;
-
- if (!insert || !pattern || !*pattern || !string || !*string)
- return NULL;
-
- s = string;
-
- in = SMB_STRDUP(insert);
- if (!in) {
- DEBUG(0, ("realloc_string_sub: out of memory!\n"));
- return NULL;
- }
- ls = (ssize_t)strlen(s);
- lp = (ssize_t)strlen(pattern);
- li = (ssize_t)strlen(insert);
- ld = li - lp;
- for (i=0;i<li;i++) {
- switch (in[i]) {
- case '$':
- /* allow a trailing $
- * (as in machine accounts) */
- if (allow_trailing_dollar && (i == li - 1 )) {
- break;
- }
- case '`':
- case '"':
- case '\'':
- case ';':
- case '%':
- case '\r':
- case '\n':
- if ( remove_unsafe_characters ) {
- in[i] = '_';
- break;
- }
- default:
- /* ok */
- break;
- }
- }
-
- while ((p = strstr_m(s,pattern))) {
- if (ld > 0) {
- int offset = PTR_DIFF(s,string);
- string = (char *)SMB_REALLOC(string, ls + ld + 1);
- if (!string) {
- DEBUG(0, ("realloc_string_sub: "
- "out of memory!\n"));
- SAFE_FREE(in);
- return NULL;
- }
- p = string + offset + (p - s);
- }
- if (li != lp) {
- memmove(p+li,p+lp,strlen(p+lp)+1);
- }
- memcpy(p, in, li);
- s = p + li;
- ls += ld;
- }
- SAFE_FREE(in);
- return string;
-}
-
-char *realloc_string_sub(char *string,
- const char *pattern,
- const char *insert)
-{
- return realloc_string_sub2(string, pattern, insert, true, false);
-}
-
/*
* Internal guts of talloc_string_sub and talloc_all_string_sub.
* talloc version of string_sub2.
@@ -715,7 +257,7 @@ char *talloc_string_sub2(TALLOC_CTX *mem_ctx, const char *src,
s = string;
- in = SMB_STRDUP(insert);
+ in = talloc_strdup(mem_ctx, insert);
if (!in) {
DEBUG(0, ("talloc_string_sub2: ENOMEM\n"));
return NULL;
@@ -758,7 +300,7 @@ char *talloc_string_sub2(TALLOC_CTX *mem_ctx, const char *src,
if (!string) {
DEBUG(0, ("talloc_string_sub: out of "
"memory!\n"));
- SAFE_FREE(in);
+ TALLOC_FREE(in);
return NULL;
}
p = string + offset + (p - s);
@@ -774,7 +316,7 @@ char *talloc_string_sub2(TALLOC_CTX *mem_ctx, const char *src,
break;
}
}
- SAFE_FREE(in);
+ TALLOC_FREE(in);
return string;
}
@@ -789,48 +331,6 @@ char *talloc_string_sub(TALLOC_CTX *mem_ctx,
true, false, false);
}
-/**
- Similar to string_sub() but allows for any character to be substituted.
- Use with caution!
- if len==0 then the string cannot be extended. This is different from the old
- use of len==0 which was for no length checks to be done.
-**/
-
-void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
-{
- char *p;
- ssize_t ls,lp,li;
-
- if (!insert || !pattern || !s)
- return;
-
- ls = (ssize_t)strlen(s);
- lp = (ssize_t)strlen(pattern);
- li = (ssize_t)strlen(insert);
-
- if (!*pattern)
- return;
-
- if (len == 0)
- len = ls + 1; /* len is number of *bytes* */
-
- while (lp <= ls && (p = strstr_m(s,pattern))) {
- if (ls + (li-lp) >= len) {
- DEBUG(0,("ERROR: string overflow by "
- "%d in all_string_sub(%.50s, %d)\n",
- (int)(ls + (li-lp) - len),
- pattern, (int)len));
- break;
- }
- if (li != lp) {
- memmove(p+li,p+lp,strlen(p+lp)+1);
- }
- memcpy(p, insert, li);
- s = p + li;
- ls += (li-lp);
- }
-}
-
char *talloc_all_string_sub(TALLOC_CTX *ctx,
const char *src,
const char *pattern,
@@ -898,93 +398,12 @@ char *strnrchr_m(const char *s, char c, unsigned int n)
/* Too hard to try and get right. */
return NULL;
}
- ret = (char *)(s+strlen(s2));
+ ret = discard_const_p(char, (s+strlen(s2)));
TALLOC_FREE(ws);
TALLOC_FREE(s2);
return ret;
}
-/***********************************************************************
- strstr_m - We convert via ucs2 for now.
-***********************************************************************/
-
-char *strstr_m(const char *src, const char *findstr)
-{
- smb_ucs2_t *p;
- smb_ucs2_t *src_w, *find_w;
- const char *s;
- char *s2;
- char *retp;
-
- size_t converted_size, findstr_len = 0;
-
- /* for correctness */
- if (!findstr[0]) {
- return (char*)src;
- }
-
- /* Samba does single character findstr calls a *lot*. */
- if (findstr[1] == '\0')
- return strchr_m(src, *findstr);
-
- /* We optimise for the ascii case, knowing that all our
- supported multi-byte character sets are ascii-compatible
- (ie. they match for the first 128 chars) */
-
- for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
- if (*s == *findstr) {
- if (!findstr_len)
- findstr_len = strlen(findstr);
-
- if (strncmp(s, findstr, findstr_len) == 0) {
- return (char *)s;
- }
- }
- }
-
- if (!*s)
- return NULL;
-
-#if 1 /* def BROKEN_UNICODE_COMPOSE_CHARACTERS */
- /* 'make check' fails unless we do this */
-
- /* With compose characters we must restart from the beginning. JRA. */
- s = src;
-#endif
-
- if (!push_ucs2_talloc(talloc_tos(), &src_w, src, &converted_size)) {
- DEBUG(0,("strstr_m: src malloc fail\n"));
- return NULL;
- }
-
- if (!push_ucs2_talloc(talloc_tos(), &find_w, findstr, &converted_size)) {
- TALLOC_FREE(src_w);
- DEBUG(0,("strstr_m: find malloc fail\n"));
- return NULL;
- }
-
- p = strstr_w(src_w, find_w);
-
- if (!p) {
- TALLOC_FREE(src_w);
- TALLOC_FREE(find_w);
- return NULL;
- }
-
- *p = 0;
- if (!pull_ucs2_talloc(talloc_tos(), &s2, src_w, &converted_size)) {
- TALLOC_FREE(src_w);
- TALLOC_FREE(find_w);
- DEBUG(0,("strstr_m: dest malloc fail\n"));
- return NULL;
- }
- retp = (char *)(s+strlen(s2));
- TALLOC_FREE(src_w);
- TALLOC_FREE(find_w);
- TALLOC_FREE(s2);
- return retp;
-}
-
static bool unix_strlower(const char *src, size_t srclen, char *dest, size_t destlen)
{
size_t size;
@@ -1005,6 +424,36 @@ static bool unix_strlower(const char *src, size_t srclen, char *dest, size_t des
return ret;
}
+#if 0 /* Alternate function that avoid talloc calls for ASCII and non ASCII */
+
+/**
+ Convert a string to lower case.
+**/
+_PUBLIC_ void strlower_m(char *s)
+{
+ char *d;
+ struct smb_iconv_handle *iconv_handle;
+
+ iconv_handle = get_iconv_handle();
+
+ d = s;
+
+ while (*s) {
+ size_t c_size, c_size2;
+ codepoint_t c = next_codepoint_handle(iconv_handle, s, &c_size);
+ c_size2 = push_codepoint_handle(iconv_handle, d, tolower_m(c));
+ if (c_size2 > c_size) {
+ DEBUG(0,("FATAL: codepoint 0x%x (0x%x) expanded from %d to %d bytes in strlower_m\n",
+ c, tolower_m(c), (int)c_size, (int)c_size2));
+ smb_panic("codepoint expansion in strlower_m\n");
+ }
+ s += c_size;
+ d += c_size2;
+ }
+ *d = 0;
+}
+
+#endif
/**
Convert a string to lower case.
@@ -1060,6 +509,37 @@ static bool unix_strupper(const char *src, size_t srclen, char *dest, size_t des
return ret;
}
+#if 0 /* Alternate function that avoid talloc calls for ASCII and non ASCII */
+
+/**
+ Convert a string to UPPER case.
+**/
+_PUBLIC_ void strupper_m(char *s)
+{
+ char *d;
+ struct smb_iconv_handle *iconv_handle;
+
+ iconv_handle = get_iconv_handle();
+
+ d = s;
+
+ while (*s) {
+ size_t c_size, c_size2;
+ codepoint_t c = next_codepoint_handle(iconv_handle, s, &c_size);
+ c_size2 = push_codepoint_handle(iconv_handle, d, toupper_m(c));
+ if (c_size2 > c_size) {
+ DEBUG(0,("FATAL: codepoint 0x%x (0x%x) expanded from %d to %d bytes in strupper_m\n",
+ c, toupper_m(c), (int)c_size, (int)c_size2));
+ smb_panic("codepoint expansion in strupper_m\n");
+ }
+ s += c_size;
+ d += c_size2;
+ }
+ *d = 0;
+}
+
+#endif
+
/**
Convert a string to upper case.
**/
@@ -1116,35 +596,6 @@ int fstr_sprintf(fstring s, const char *fmt, ...)
#define S_LIST_ABS 16 /* List Allocation Block Size */
/******************************************************************************
- version of standard_sub_basic() for string lists; uses talloc_sub_basic()
- for the work
- *****************************************************************************/
-
-bool str_list_sub_basic( char **list, const char *smb_name,
- const char *domain_name )
-{
- TALLOC_CTX *ctx = list;
- char *s, *tmpstr;
-
- while ( *list ) {
- s = *list;
- tmpstr = talloc_sub_basic(ctx, smb_name, domain_name, s);
- if ( !tmpstr ) {
- DEBUG(0,("str_list_sub_basic: "
- "alloc_sub_basic() return NULL!\n"));
- return false;
- }
-
- TALLOC_FREE(*list);
- *list = tmpstr;
-
- list++;
- }
-
- return true;
-}
-
-/******************************************************************************
substitute a specific pattern in a string list
*****************************************************************************/
@@ -1173,7 +624,7 @@ bool str_list_substitute(char **list, const char *pattern, const char *insert)
t = *list;
d = p -t;
if (ld) {
- t = TALLOC_ARRAY(ctx, char, ls +ld +1);
+ t = talloc_array(ctx, char, ls +ld +1);
if (!t) {
DEBUG(0,("str_list_substitute: "
"Unable to allocate memory"));
@@ -1415,25 +866,16 @@ uint64_t STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
*
* Returns 0 if the string can't be converted.
*/
-SMB_OFF_T conv_str_size(const char * str)
+uint64_t conv_str_size(const char * str)
{
- SMB_OFF_T lval_orig;
- SMB_OFF_T lval;
+ uint64_t lval;
char * end;
if (str == NULL || *str == '\0') {
return 0;
}
-#ifdef HAVE_STRTOULL
- if (sizeof(SMB_OFF_T) == 8) {
- lval = strtoull(str, &end, 10 /* base */);
- } else {
- lval = strtoul(str, &end, 10 /* base */);
- }
-#else
- lval = strtoul(str, &end, 10 /* base */);
-#endif
+ lval = strtoull(str, &end, 10 /* base */);
if (end == NULL || end == str) {
return 0;
@@ -1443,35 +885,24 @@ SMB_OFF_T conv_str_size(const char * str)
return lval;
}
- lval_orig = lval;
-
if (strwicmp(end, "K") == 0) {
- lval *= (SMB_OFF_T)1024;
+ lval *= 1024ULL;
} else if (strwicmp(end, "M") == 0) {
- lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024);
+ lval *= (1024ULL * 1024ULL);
} else if (strwicmp(end, "G") == 0) {
- lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
- (SMB_OFF_T)1024);
+ lval *= (1024ULL * 1024ULL *
+ 1024ULL);
} else if (strwicmp(end, "T") == 0) {
- lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
- (SMB_OFF_T)1024 * (SMB_OFF_T)1024);
+ lval *= (1024ULL * 1024ULL *
+ 1024ULL * 1024ULL);
} else if (strwicmp(end, "P") == 0) {
- lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
- (SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
- (SMB_OFF_T)1024);
+ lval *= (1024ULL * 1024ULL *
+ 1024ULL * 1024ULL *
+ 1024ULL);
} else {
return 0;
}
- /*
- * Primitive attempt to detect wrapping on platforms with
- * 4-byte SMB_OFF_T. It's better to let the caller handle a
- * failure than some random number.
- */
- if (lval_orig <= lval) {
- return 0;
- }
-
return lval;
}
@@ -1495,7 +926,7 @@ void sprintf_append(TALLOC_CTX *mem_ctx, char **string, ssize_t *len,
if (*bufsize == 0)
*bufsize = 128;
- *string = TALLOC_ARRAY(mem_ctx, char, *bufsize);
+ *string = talloc_array(mem_ctx, char, *bufsize);
if (*string == NULL)
goto error;
}
@@ -1517,7 +948,7 @@ void sprintf_append(TALLOC_CTX *mem_ctx, char **string, ssize_t *len,
}
if (increased) {
- *string = TALLOC_REALLOC_ARRAY(mem_ctx, *string, char,
+ *string = talloc_realloc(mem_ctx, *string, char,
*bufsize);
if (*string == NULL) {
goto error;
@@ -1589,33 +1020,6 @@ char *talloc_asprintf_strlower_m(TALLOC_CTX *t, const char *fmt, ...)
}
-/*
- Returns the substring from src between the first occurrence of
- the char "front" and the first occurence of the char "back".
- Mallocs the return string which must be freed. Not for use
- with wide character strings.
-*/
-char *sstring_sub(const char *src, char front, char back)
-{
- char *temp1, *temp2, *temp3;
- ptrdiff_t len;
-
- temp1 = strchr(src, front);
- if (temp1 == NULL) return NULL;
- temp2 = strchr(src, back);
- if (temp2 == NULL) return NULL;
- len = temp2 - temp1;
- if (len <= 0) return NULL;
- temp3 = (char*)SMB_MALLOC(len);
- if (temp3 == NULL) {
- DEBUG(1,("Malloc failure in sstring_sub\n"));
- return NULL;
- }
- memcpy(temp3, temp1+1, len-1);
- temp3[len-1] = '\0';
- return temp3;
-}
-
/********************************************************************
Check a string for any occurrences of a specified list of invalid
characters.
@@ -1825,7 +1229,7 @@ char **str_list_make_v3(TALLOC_CTX *mem_ctx, const char *string,
if (!string || !*string)
return NULL;
- list = TALLOC_ARRAY(mem_ctx, char *, S_LIST_ABS+1);
+ list = talloc_array(mem_ctx, char *, S_LIST_ABS+1);
if (list == NULL) {
return NULL;
}
@@ -1849,7 +1253,7 @@ char **str_list_make_v3(TALLOC_CTX *mem_ctx, const char *string,
lsize += S_LIST_ABS;
- tmp = TALLOC_REALLOC_ARRAY(mem_ctx, list, char *,
+ tmp = talloc_realloc(mem_ctx, list, char *,
lsize + 1);
if (tmp == NULL) {
DEBUG(0,("str_list_make: "
diff --git a/source3/lib/util_tdb.c b/source3/lib/util_tdb.c
index a9290ab94a..ade46bf18e 100644
--- a/source3/lib/util_tdb.c
+++ b/source3/lib/util_tdb.c
@@ -21,11 +21,108 @@
#include "includes.h"
#include "system/filesys.h"
+#include "util_tdb.h"
+
#undef malloc
#undef realloc
#undef calloc
#undef strdup
+#ifdef BUILD_TDB2
+static struct flock flock_struct;
+
+/* Return a value which is none of v1, v2 or v3. */
+static inline short int invalid_value(short int v1, short int v2, short int v3)
+{
+ short int try = (v1+v2+v3)^((v1+v2+v3) << 16);
+ while (try == v1 || try == v2 || try == v3)
+ try++;
+ return try;
+}
+
+/* We invalidate in as many ways as we can, so the OS rejects it */
+static void invalidate_flock_struct(int signum)
+{
+ flock_struct.l_type = invalid_value(F_RDLCK, F_WRLCK, F_UNLCK);
+ flock_struct.l_whence = invalid_value(SEEK_SET, SEEK_CUR, SEEK_END);
+ flock_struct.l_start = -1;
+ /* A large negative. */
+ flock_struct.l_len = (((off_t)1 << (sizeof(off_t)*CHAR_BIT - 1)) + 1);
+}
+
+static int timeout_lock(int fd, int rw, off_t off, off_t len, bool waitflag,
+ void *_timeout)
+{
+ int ret, saved_errno;
+ unsigned int timeout = *(unsigned int *)_timeout;
+
+ flock_struct.l_type = rw;
+ flock_struct.l_whence = SEEK_SET;
+ flock_struct.l_start = off;
+ flock_struct.l_len = len;
+
+ CatchSignal(SIGALRM, invalidate_flock_struct);
+ alarm(timeout);
+
+ for (;;) {
+ if (waitflag)
+ ret = fcntl(fd, F_SETLKW, &flock_struct);
+ else
+ ret = fcntl(fd, F_SETLK, &flock_struct);
+
+ if (ret == 0)
+ break;
+
+ /* Not signalled? Something else went wrong. */
+ if (flock_struct.l_len == len) {
+ if (errno == EAGAIN || errno == EINTR)
+ continue;
+ saved_errno = errno;
+ break;
+ } else {
+ saved_errno = EINTR;
+ break;
+ }
+ }
+
+ alarm(0);
+ errno = saved_errno;
+ return ret;
+}
+
+static int tdb_chainlock_with_timeout_internal(struct tdb_context *tdb,
+ TDB_DATA key,
+ unsigned int timeout,
+ int rw_type)
+{
+ union tdb_attribute locking;
+ enum TDB_ERROR ecode;
+
+ if (timeout) {
+ locking.base.attr = TDB_ATTRIBUTE_FLOCK;
+ ecode = tdb_get_attribute(tdb, &locking);
+ if (ecode != TDB_SUCCESS)
+ return ecode;
+
+ /* Replace locking function with our own. */
+ locking.flock.data = &timeout;
+ locking.flock.lock = timeout_lock;
+
+ ecode = tdb_set_attribute(tdb, &locking);
+ if (ecode != TDB_SUCCESS)
+ return ecode;
+ }
+ if (rw_type == F_RDLCK)
+ ecode = tdb_chainlock_read(tdb, key);
+ else
+ ecode = tdb_chainlock(tdb, key);
+
+ if (timeout) {
+ tdb_unset_attribute(tdb, TDB_ATTRIBUTE_FLOCK);
+ }
+ return ecode == TDB_SUCCESS ? 0 : -1;
+}
+#else
/* these are little tdb utility functions that are meant to make
dealing with a tdb database a little less cumbersome in Samba */
@@ -65,7 +162,7 @@ static int tdb_chainlock_with_timeout_internal( TDB_CONTEXT *tdb, TDB_DATA key,
alarm(0);
tdb_setalarm_sigptr(tdb, NULL);
CatchSignal(SIGALRM, SIG_IGN);
- if (gotalarm && (ret == -1)) {
+ if (gotalarm && (ret != 0)) {
DEBUG(0,("tdb_chainlock_with_timeout_internal: alarm (%u) timed out for key %s in tdb %s\n",
timeout, key.dptr, tdb_name(tdb)));
/* TODO: If we time out waiting for a lock, it might
@@ -76,11 +173,12 @@ static int tdb_chainlock_with_timeout_internal( TDB_CONTEXT *tdb, TDB_DATA key,
}
}
- return ret;
+ return ret == 0 ? 0 : -1;
}
+#endif /* TDB1 */
/****************************************************************************
- Write lock a chain. Return -1 if timeout or lock failed.
+ Write lock a chain. Return non-zero if timeout or lock failed.
****************************************************************************/
int tdb_chainlock_with_timeout( TDB_CONTEXT *tdb, TDB_DATA key, unsigned int timeout)
@@ -97,7 +195,7 @@ int tdb_lock_bystring_with_timeout(TDB_CONTEXT *tdb, const char *keyval,
}
/****************************************************************************
- Read lock a chain by string. Return -1 if timeout or lock failed.
+ Read lock a chain by string. Return non-zero if timeout or lock failed.
****************************************************************************/
int tdb_read_lock_bystring_with_timeout(TDB_CONTEXT *tdb, const char *keyval, unsigned int timeout)
@@ -229,7 +327,7 @@ bool tdb_pack_append(TALLOC_CTX *mem_ctx, uint8 **buf, size_t *len,
va_end(ap);
if (mem_ctx != NULL) {
- *buf = TALLOC_REALLOC_ARRAY(mem_ctx, *buf, uint8,
+ *buf = talloc_realloc(mem_ctx, *buf, uint8,
(*len) + len1);
} else {
*buf = SMB_REALLOC_ARRAY(*buf, uint8, (*len) + len1);
@@ -370,6 +468,14 @@ int tdb_unpack(const uint8 *buf, int bufsize, const char *fmt, ...)
Log tdb messages via DEBUG().
****************************************************************************/
+#ifdef BUILD_TDB2
+static void tdb_log(TDB_CONTEXT *tdb, enum tdb_log_level level,
+ const char *message, void *unused)
+{
+ DEBUG((int)level, ("tdb(%s): %s",
+ tdb_name(tdb) ? tdb_name(tdb) : "unnamed", message));
+}
+#else
static void tdb_log(TDB_CONTEXT *tdb, enum tdb_debug_level level, const char *format, ...)
{
va_list ap;
@@ -386,6 +492,7 @@ static void tdb_log(TDB_CONTEXT *tdb, enum tdb_debug_level level, const char *fo
DEBUG((int)level, ("tdb(%s): %s", tdb_name(tdb) ? tdb_name(tdb) : "unnamed", ptr));
SAFE_FREE(ptr);
}
+#endif /* TDB1 */
/****************************************************************************
Like tdb_open() but also setup a logging function that redirects to
@@ -396,14 +503,10 @@ TDB_CONTEXT *tdb_open_log(const char *name, int hash_size, int tdb_flags,
int open_flags, mode_t mode)
{
TDB_CONTEXT *tdb;
- struct tdb_logging_context log_ctx;
if (!lp_use_mmap())
tdb_flags |= TDB_NOMMAP;
- log_ctx.log_fn = tdb_log;
- log_ctx.log_private = NULL;
-
if ((hash_size == 0) && (name != NULL)) {
const char *base = strrchr_m(name, '/');
if (base != NULL) {
@@ -415,8 +518,8 @@ TDB_CONTEXT *tdb_open_log(const char *name, int hash_size, int tdb_flags,
hash_size = lp_parm_int(-1, "tdb_hashsize", base, 0);
}
- tdb = tdb_open_ex(name, hash_size, tdb_flags,
- open_flags, mode, &log_ctx, NULL);
+ tdb = tdb_open_compat(name, hash_size, tdb_flags,
+ open_flags, mode, tdb_log, NULL);
if (!tdb)
return NULL;
@@ -440,9 +543,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");
- }
+ tdb_transaction_cancel(tdb);
return res;
}
@@ -469,9 +570,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");
- }
+ tdb_transaction_cancel(tdb);
return res;
}
@@ -482,165 +581,6 @@ int tdb_trans_delete(struct tdb_context *tdb, TDB_DATA key)
return res;
}
-/*
- Log tdb messages via DEBUG().
-*/
-static void tdb_wrap_log(TDB_CONTEXT *tdb, enum tdb_debug_level level,
- const char *format, ...) PRINTF_ATTRIBUTE(3,4);
-
-static void tdb_wrap_log(TDB_CONTEXT *tdb, enum tdb_debug_level level,
- const char *format, ...)
-{
- va_list ap;
- char *ptr = NULL;
- int debuglevel = 0;
- int ret;
-
- switch (level) {
- case TDB_DEBUG_FATAL:
- debuglevel = 0;
- break;
- case TDB_DEBUG_ERROR:
- debuglevel = 1;
- break;
- case TDB_DEBUG_WARNING:
- debuglevel = 2;
- break;
- case TDB_DEBUG_TRACE:
- debuglevel = 5;
- break;
- default:
- debuglevel = 0;
- }
-
- va_start(ap, format);
- ret = vasprintf(&ptr, format, ap);
- va_end(ap);
-
- if (ret != -1) {
- const char *name = tdb_name(tdb);
- DEBUG(debuglevel, ("tdb(%s): %s", name ? name : "unnamed", ptr));
- free(ptr);
- }
-}
-
-struct tdb_wrap_private {
- struct tdb_context *tdb;
- const char *name;
- struct tdb_wrap_private *next, *prev;
-};
-
-static struct tdb_wrap_private *tdb_list;
-
-/* destroy the last connection to a tdb */
-static int tdb_wrap_private_destructor(struct tdb_wrap_private *w)
-{
- tdb_close(w->tdb);
- DLIST_REMOVE(tdb_list, w);
- return 0;
-}
-
-static struct tdb_wrap_private *tdb_wrap_private_open(TALLOC_CTX *mem_ctx,
- const char *name,
- int hash_size,
- int tdb_flags,
- int open_flags,
- mode_t mode)
-{
- struct tdb_wrap_private *result;
- struct tdb_logging_context log_ctx;
-
- result = talloc(mem_ctx, struct tdb_wrap_private);
- if (result == NULL) {
- return NULL;
- }
- result->name = talloc_strdup(result, name);
- if (result->name == NULL) {
- goto fail;
- }
-
- log_ctx.log_fn = tdb_wrap_log;
-
- if (!lp_use_mmap()) {
- tdb_flags |= TDB_NOMMAP;
- }
-
- if ((hash_size == 0) && (name != NULL)) {
- const char *base;
- base = strrchr_m(name, '/');
-
- if (base != NULL) {
- base += 1;
- } else {
- base = name;
- }
- hash_size = lp_parm_int(-1, "tdb_hashsize", base, 0);
- }
-
- result->tdb = tdb_open_ex(name, hash_size, tdb_flags,
- open_flags, mode, &log_ctx, NULL);
- if (result->tdb == NULL) {
- goto fail;
- }
- talloc_set_destructor(result, tdb_wrap_private_destructor);
- DLIST_ADD(tdb_list, result);
- return result;
-
-fail:
- TALLOC_FREE(result);
- return NULL;
-}
-
-/*
- wrapped connection to a tdb database
- to close just talloc_free() the tdb_wrap pointer
- */
-struct tdb_wrap *tdb_wrap_open(TALLOC_CTX *mem_ctx,
- const char *name, int hash_size, int tdb_flags,
- int open_flags, mode_t mode)
-{
- struct tdb_wrap *result;
- struct tdb_wrap_private *w;
-
- result = talloc(mem_ctx, struct tdb_wrap);
- if (result == NULL) {
- return NULL;
- }
-
- for (w=tdb_list;w;w=w->next) {
- if (strcmp(name, w->name) == 0) {
- break;
- }
- }
-
- if (w == NULL) {
- w = tdb_wrap_private_open(result, name, hash_size, tdb_flags,
- open_flags, mode);
- } else {
- /*
- * Correctly use talloc_reference: The tdb will be
- * closed when "w" is being freed. The caller never
- * sees "w", so an incorrect use of talloc_free(w)
- * instead of calling talloc_unlink is not possible.
- * To avoid having to refcount ourselves, "w" will
- * have multiple parents that hang off all the
- * tdb_wrap's being returned from here. Those parents
- * can be freed without problem.
- */
- if (talloc_reference(result, w) == NULL) {
- goto fail;
- }
- }
- if (w == NULL) {
- goto fail;
- }
- result->tdb = w->tdb;
- return result;
-fail:
- TALLOC_FREE(result);
- return NULL;
-}
-
NTSTATUS map_nt_error_from_tdb(enum TDB_ERROR err)
{
NTSTATUS result = NT_STATUS_INTERNAL_ERROR;
@@ -672,6 +612,7 @@ NTSTATUS map_nt_error_from_tdb(enum TDB_ERROR err)
result = NT_STATUS_FILE_LOCK_CONFLICT;
break;
+#ifndef BUILD_TDB2
case TDB_ERR_NOLOCK:
case TDB_ERR_LOCK_TIMEOUT:
/*
@@ -679,6 +620,7 @@ NTSTATUS map_nt_error_from_tdb(enum TDB_ERROR err)
*/
result = NT_STATUS_FILE_LOCK_CONFLICT;
break;
+#endif
case TDB_ERR_NOEXIST:
result = NT_STATUS_NOT_FOUND;
break;
@@ -688,9 +630,11 @@ NTSTATUS map_nt_error_from_tdb(enum TDB_ERROR err)
case TDB_ERR_RDONLY:
result = NT_STATUS_ACCESS_DENIED;
break;
+#ifndef BUILD_TDB2
case TDB_ERR_NESTING:
result = NT_STATUS_INTERNAL_ERROR;
break;
+#endif
};
return result;
}
diff --git a/source3/lib/util_tsock.c b/source3/lib/util_tsock.c
index 1cb88c67bd..35a97f5e69 100644
--- a/source3/lib/util_tsock.c
+++ b/source3/lib/util_tsock.c
@@ -18,6 +18,8 @@
*/
#include "includes.h"
+#include "../lib/tsocket/tsocket.h"
+#include "../lib/util/tevent_unix.h"
struct tstream_read_packet_state {
struct tevent_context *ev;
diff --git a/source3/lib/winbind_util.c b/source3/lib/winbind_util.c
index f30bcfc612..b458ebe847 100644
--- a/source3/lib/winbind_util.c
+++ b/source3/lib/winbind_util.c
@@ -237,15 +237,15 @@ bool winbind_lookup_rids(TALLOC_CTX *mem_ctx,
}
*domain_name = talloc_strdup(mem_ctx, dom_name);
- *names = TALLOC_ARRAY(mem_ctx, const char*, num_rids);
- *types = TALLOC_ARRAY(mem_ctx, enum lsa_SidType, num_rids);
+ *names = talloc_array(mem_ctx, const char*, num_rids);
+ *types = talloc_array(mem_ctx, enum lsa_SidType, num_rids);
for(i=0; i<num_rids; i++) {
(*names)[i] = talloc_strdup(*names, namelist[i]);
(*types)[i] = (enum lsa_SidType)name_types[i];
}
- wbcFreeMemory(CONST_DISCARD(char*, dom_name));
+ wbcFreeMemory(discard_const_p(char, dom_name));
wbcFreeMemory(namelist);
wbcFreeMemory(name_types);
@@ -284,7 +284,7 @@ bool winbind_get_groups(TALLOC_CTX * mem_ctx, const char *account, uint32_t *num
if (ret != WBC_ERR_SUCCESS)
return false;
- *_groups = TALLOC_ARRAY(mem_ctx, gid_t, ngroups);
+ *_groups = talloc_array(mem_ctx, gid_t, ngroups);
if (*_groups == NULL) {
wbcFreeMemory(group_list);
return false;
@@ -313,7 +313,7 @@ bool winbind_get_sid_aliases(TALLOC_CTX *mem_ctx,
memcpy(&domain_sid, dom_sid, sizeof(*dom_sid));
- sid_list = TALLOC_ARRAY(mem_ctx, struct wbcDomainSid, num_members);
+ sid_list = talloc_array(mem_ctx, struct wbcDomainSid, num_members);
for (i=0; i < num_members; i++) {
memcpy(&sid_list[i], &members[i], sizeof(sid_list[i]));
@@ -328,7 +328,7 @@ bool winbind_get_sid_aliases(TALLOC_CTX *mem_ctx,
return false;
}
- *pp_alias_rids = TALLOC_ARRAY(mem_ctx, uint32_t, num_rids);
+ *pp_alias_rids = talloc_array(mem_ctx, uint32_t, num_rids);
if (*pp_alias_rids == NULL) {
wbcFreeMemory(rids);
return false;
diff --git a/source3/lib/wins_srv.c b/source3/lib/wins_srv.c
index 6676f02e94..f9e8f3b0e1 100644
--- a/source3/lib/wins_srv.c
+++ b/source3/lib/wins_srv.c
@@ -328,6 +328,48 @@ struct in_addr wins_srv_ip_tag(const char *tag, struct in_addr src_ip)
return t_ip.ip;
}
+bool wins_server_tag_ips(const char *tag, TALLOC_CTX *mem_ctx,
+ struct in_addr **pservers, int *pnum_servers)
+{
+ const char **list;
+ int i, num_servers;
+ struct in_addr *servers;
+
+ list = lp_wins_server_list();
+ if ((list == NULL) || (list[0] == NULL)) {
+ return false;
+ }
+
+ num_servers = 0;
+
+ for (i=0; list[i] != NULL; i++) {
+ struct tagged_ip t_ip;
+ parse_ip(&t_ip, list[i]);
+ if (strcmp(tag, t_ip.tag) == 0) {
+ num_servers += 1;
+ }
+ }
+
+ servers = talloc_array(mem_ctx, struct in_addr, num_servers);
+ if (servers == NULL) {
+ return false;
+ }
+
+ num_servers = 0;
+
+ for (i=0; list[i] != NULL; i++) {
+ struct tagged_ip t_ip;
+ parse_ip(&t_ip, list[i]);
+ if (strcmp(tag, t_ip.tag) == 0) {
+ servers[num_servers] = t_ip.ip;
+ num_servers += 1;
+ }
+ }
+ *pnum_servers = num_servers;
+ *pservers = servers;
+ return true;
+}
+
/*
return a count of the number of IPs for a particular tag, including