diff options
Diffstat (limited to 'source3/lib')
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 |