summaryrefslogtreecommitdiffstats
path: root/source/lib
diff options
context:
space:
mode:
Diffstat (limited to 'source/lib')
-rw-r--r--source/lib/charcnv.c30
-rw-r--r--source/lib/hash.c316
-rw-r--r--source/lib/iconv.c347
-rw-r--r--source/lib/ms_fnmatch.c3
-rw-r--r--source/lib/smbldap.c55
-rw-r--r--source/lib/smbrun.c123
-rw-r--r--source/lib/util.c5
-rw-r--r--source/lib/util_file.c492
-rw-r--r--source/lib/util_str.c13
-rw-r--r--source/lib/util_uuid.c66
10 files changed, 741 insertions, 709 deletions
diff --git a/source/lib/charcnv.c b/source/lib/charcnv.c
index 6cbf7562b06..40004826b4a 100644
--- a/source/lib/charcnv.c
+++ b/source/lib/charcnv.c
@@ -56,7 +56,7 @@ static const char *charset_name(charset_t ch)
{
const char *ret = NULL;
- if (ch == CH_UCS2) ret = "UCS-2LE";
+ if (ch == CH_UCS2) ret = "UTF-16LE";
else if (ch == CH_UNIX) ret = lp_unix_charset();
else if (ch == CH_DOS) ret = lp_dos_charset();
else if (ch == CH_DISPLAY) ret = lp_display_charset();
@@ -116,10 +116,10 @@ void init_iconv(void)
/* so that charset_name() works we need to get the UNIX<->UCS2 going
first */
if (!conv_handles[CH_UNIX][CH_UCS2])
- conv_handles[CH_UNIX][CH_UCS2] = smb_iconv_open("UCS-2LE", "ASCII");
+ conv_handles[CH_UNIX][CH_UCS2] = smb_iconv_open(charset_name(CH_UCS2), "ASCII");
if (!conv_handles[CH_UCS2][CH_UNIX])
- conv_handles[CH_UCS2][CH_UNIX] = smb_iconv_open("ASCII", "UCS-2LE");
+ conv_handles[CH_UCS2][CH_UNIX] = smb_iconv_open("ASCII", charset_name(CH_UCS2));
for (c1=0;c1<NUM_CHARSETS;c1++) {
for (c2=0;c2<NUM_CHARSETS;c2++) {
@@ -216,7 +216,7 @@ static size_t convert_string_internal(charset_t from, charset_t to,
again:
- retval = smb_iconv(descriptor, (char **)&inbuf, &i_len, &outbuf, &o_len);
+ retval = smb_iconv(descriptor, &inbuf, &i_len, &outbuf, &o_len);
if(retval==(size_t)-1) {
const char *reason="unknown error";
switch(errno) {
@@ -229,14 +229,18 @@ static size_t convert_string_internal(charset_t from, charset_t to,
break;
case E2BIG:
reason="No more room";
- if (!conv_silent)
- DEBUG(3, ("convert_string_internal: Required %lu, available %lu\n",
- (unsigned long)srclen, (unsigned long)destlen));
- /* we are not sure we need srclen bytes,
- may be more, may be less.
- We only know we need more than destlen
- bytes ---simo */
- break;
+ if (!conv_silent) {
+ if (from == CH_UNIX) {
+ DEBUG(3,("E2BIG: convert_string(%s,%s): srclen=%u destlen=%u - '%s'\n",
+ charset_name(from), charset_name(to),
+ (unsigned int)srclen, (unsigned int)destlen, (const char *)src));
+ } else {
+ DEBUG(3,("E2BIG: convert_string(%s,%s): srclen=%u destlen=%u\n",
+ charset_name(from), charset_name(to),
+ (unsigned int)srclen, (unsigned int)destlen));
+ }
+ }
+ break;
case EILSEQ:
reason="Illegal multibyte sequence";
if (!conv_silent)
@@ -531,7 +535,7 @@ size_t convert_string_allocate(TALLOC_CTX *ctx, charset_t from, charset_t to,
again:
retval = smb_iconv(descriptor,
- (char **)&inbuf, &i_len,
+ &inbuf, &i_len,
&outbuf, &o_len);
if(retval == (size_t)-1) {
const char *reason="unknown error";
diff --git a/source/lib/hash.c b/source/lib/hash.c
deleted file mode 100644
index 18b6534dec2..00000000000
--- a/source/lib/hash.c
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Copyright (C) Ying Chen 2000.
- Copyright (C) Jeremy Allison 2000.
- - added some defensive programming.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-/*
- * NB. We may end up replacing this functionality in a future 2.x
- * release to reduce the number of hashing/lookup methods we support. JRA.
- */
-
-#include "includes.h"
-
-static BOOL enlarge_hash_table(hash_table *table);
-static unsigned primes[] =
- {17, 37, 67, 131, 257, 521, 1031, 2053, 4099, 8209, 16411};
-
-/****************************************************************************
- * This function initializes the hash table.
- * This hash function hashes on string keys.
- * This number of hash buckets is always rounded up to a power of
- * 2 first, then to a prime number that is large than the power of two.
- * Input:
- * table -- the hash table pointer.
- * num_buckets -- the number of buckets to be allocated. This
- * hash function can dynamically increase its size when the
- * the hash table size becomes small. There is a MAX hash table
- * size defined in hash.h.
- * compare_func -- the function pointer to a comparison function
- * used by the hash key comparison.
- ****************************************************************************
- */
-
-BOOL hash_table_init(hash_table *table, unsigned num_buckets, compare_function compare_func)
-{
- unsigned i;
- ubi_dlList *bucket;
-
- table->num_elements = 0;
- table->size = 2;
- table->comp_func = compare_func;
- while (table->size < num_buckets)
- table->size <<= 1;
- for (i = 0; i < ARRAY_SIZE(primes); i++) {
- if (primes[i] > table->size) {
- table->size = primes[i];
- break;
- }
- }
-
- DEBUG(5, ("Hash size = %d.\n", table->size));
-
- if(!(table->buckets = (ubi_dlList *) malloc(sizeof(ubi_dlList) * table->size))) {
- DEBUG(0,("hash_table_init: malloc fail !\n"));
- return False;
- }
- ubi_dlInitList(&(table->lru_chain));
- for (i=0, bucket = table->buckets; i < table->size; i++, bucket++)
- ubi_dlInitList(bucket);
-
- return True;
-}
-
-/*
- **************************************************************
- * Compute a hash value based on a string key value.
- * Make the string key into an array of int's if possible.
- * For the last few chars that cannot be int'ed, use char instead.
- * The function returns the bucket index number for the hashed
- * key.
- * JRA. Use a djb-algorithm hash for speed.
- **************************************************************
- */
-
-static int string_hash(int hash_size, const char *key)
-{
- u32 n = 0;
- const char *p;
- for (p = key; *p != '\0'; p++) {
- n = ((n << 5) + n) ^ (u32)(*p);
- }
- return (n % hash_size);
-}
-
-/* *************************************************************************
- * Search the hash table for the entry in the hash chain.
- * The function returns the pointer to the
- * element found in the chain or NULL if none is found.
- * If the element is found, the element is also moved to
- * the head of the LRU list.
- *
- * Input:
- * table -- The hash table where the element is stored in.
- * hash_chain -- The pointer to the bucket that stores the
- * element to be found.
- * key -- The hash key to be found.
- ***************************************************************************
- */
-
-static hash_element *hash_chain_find(hash_table *table, ubi_dlList *hash_chain, char *key)
-{
- hash_element *hash_elem;
- ubi_dlNodePtr lru_item;
- unsigned int i = 0;
-
- for (hash_elem = (hash_element *)(ubi_dlFirst(hash_chain)); i < hash_chain->count;
- i++, hash_elem = (hash_element *)(ubi_dlNext(hash_elem))) {
- if ((table->comp_func)(hash_elem->key, key) == 0) {
- /* Move to the head of the lru List. */
- lru_item = ubi_dlRemove(&(table->lru_chain), &(hash_elem->lru_link.lru_link));
- ubi_dlAddHead(&(table->lru_chain), lru_item);
- return(hash_elem);
- }
- }
- return ((hash_element *) NULL);
-}
-
-/* ***************************************************************************
- *
- * Lookup a hash table for an element with key.
- * The function returns a pointer to the hash element.
- * If no element is found, the function returns NULL.
- *
- * Input:
- * table -- The hash table to be searched on.
- * key -- The key to be found.
- *****************************************************************************
- */
-
-hash_element *hash_lookup(hash_table *table, char *key)
-{
- return (hash_chain_find(table, &table->buckets[string_hash(table->size, key)], key));
-}
-
-/* ***************************************************************
- *
- * This function first checks if an element with key "key"
- * exists in the hash table. If so, the function moves the
- * element to the front of the LRU list. Otherwise, a new
- * hash element corresponding to "value" and "key" is allocated
- * and inserted into the hash table. The new elements are
- * always inserted in the LRU order to the LRU list as well.
- *
- * Input:
- * table -- The hash table to be inserted in.
- * value -- The content of the element to be inserted.
- * key -- The key of the new element to be inserted.
- *
- ****************************************************************
- */
-
-hash_element *hash_insert(hash_table *table, char *value, char *key)
-{
- hash_element *hash_elem;
- ubi_dlNodePtr lru_item;
- ubi_dlList *bucket;
- size_t string_length;
-
- /*
- * If the hash table size has not reached the MAX_HASH_TABLE_SIZE,
- * the hash table may be enlarged if the current hash table is full.
- * If the hash table size has reached the MAX_HASH_TABLE_SIZE,
- * use LRU to remove the oldest element from the hash table.
- */
-
- if ((table->num_elements >= table->size) &&
- (table->num_elements < MAX_HASH_TABLE_SIZE)) {
- if(!enlarge_hash_table(table))
- return (hash_element *)NULL;
- table->num_elements += 1;
- } else if (table->num_elements >= MAX_HASH_TABLE_SIZE) {
- /* Do an LRU replacement. */
- lru_item = ubi_dlLast(&(table->lru_chain));
- hash_elem = (hash_element *)(((lru_node *)lru_item)->hash_elem);
- bucket = hash_elem->bucket;
- ubi_dlRemThis(&(table->lru_chain), &(hash_elem->lru_link.lru_link));
- ubi_dlRemThis(bucket, (ubi_dlNodePtr)hash_elem);
- SAFE_FREE(hash_elem->value);
- SAFE_FREE(hash_elem);
- } else {
- table->num_elements += 1;
- }
-
- bucket = &table->buckets[string_hash(table->size, key)];
-
- /* Since we only have 1-byte for the key string, we need to
- * allocate extra space in the hash_element to store the entire key
- * string.
- */
-
- string_length = strlen(key);
- if(!(hash_elem = (hash_element *) malloc(sizeof(hash_element) + string_length))) {
- DEBUG(0,("hash_insert: malloc fail !\n"));
- return (hash_element *)NULL;
- }
-
- safe_strcpy((char *) hash_elem->key, key, string_length);
-
- hash_elem->value = (char *)value;
- hash_elem->bucket = bucket;
- /* Insert in front of the lru list and the bucket list. */
- ubi_dlAddHead(bucket, hash_elem);
- hash_elem->lru_link.hash_elem = hash_elem;
- ubi_dlAddHead(&(table->lru_chain), &(hash_elem->lru_link.lru_link));
-
- return(hash_elem);
-}
-
-/* **************************************************************************
- *
- * Remove a hash element from the hash table. The hash element is
- * removed from both the LRU list and the hash bucket chain.
- *
- * Input:
- * table -- the hash table to be manipulated on.
- * hash_elem -- the element to be removed.
- **************************************************************************
- */
-
-void hash_remove(hash_table *table, hash_element *hash_elem)
-{
- if (hash_elem) {
- ubi_dlRemove(&(table->lru_chain), &(hash_elem->lru_link.lru_link));
- ubi_dlRemove(hash_elem->bucket, (ubi_dlNodePtr) hash_elem);
- SAFE_FREE(hash_elem->value);
- SAFE_FREE(hash_elem);
- table->num_elements--;
- }
-}
-
-/* ******************************************************************
- * Increase the hash table size if it is too small.
- * The hash table size is increased by the HASH_TABLE_INCREMENT
- * ratio.
- * Input:
- * table -- the hash table to be enlarged.
- ******************************************************************
- */
-
-static BOOL enlarge_hash_table(hash_table *table)
-{
- hash_element *hash_elem;
- int size, hash_value;
- ubi_dlList *buckets;
- ubi_dlList *old_bucket;
- ubi_dlList *bucket;
- ubi_dlList lru_chain;
-
- buckets = table->buckets;
- lru_chain = table->lru_chain;
- size = table->size;
-
- /* Reinitialize the hash table. */
- if(!hash_table_init(table, table->size * HASH_TABLE_INCREMENT, table->comp_func))
- return False;
-
- for (old_bucket = buckets; size > 0; size--, old_bucket++) {
- while (old_bucket->count != 0) {
- hash_elem = (hash_element *) ubi_dlRemHead(old_bucket);
- ubi_dlRemove(&lru_chain, &(hash_elem->lru_link.lru_link));
- hash_value = string_hash(table->size, (char *) hash_elem->key);
- bucket = &(table->buckets[hash_value]);
- ubi_dlAddHead(bucket, hash_elem);
- ubi_dlAddHead(&(table->lru_chain), &(hash_elem->lru_link.lru_link));
- hash_elem->bucket = bucket;
- hash_elem->lru_link.hash_elem = hash_elem;
- table->num_elements++;
- }
- }
- SAFE_FREE(buckets);
-
- return True;
-}
-
-/* **********************************************************************
- *
- * Remove everything from a hash table and free up the memory it
- * occupies.
- * Input:
- * table -- the hash table to be cleared.
- *
- *************************************************************************
- */
-
-void hash_clear(hash_table *table)
-{
- unsigned int i;
- ubi_dlList *bucket = table->buckets;
- hash_element *hash_elem;
- for (i = 0; i < table->size; bucket++, i++) {
- while (bucket->count != 0) {
- hash_elem = (hash_element *) ubi_dlRemHead(bucket);
- SAFE_FREE(hash_elem->value);
- SAFE_FREE(hash_elem);
- }
- }
- table->size = 0;
- SAFE_FREE(table->buckets);
- table->buckets = NULL;
-}
diff --git a/source/lib/iconv.c b/source/lib/iconv.c
index 4c9ecf992e6..66a6e6cd8bc 100644
--- a/source/lib/iconv.c
+++ b/source/lib/iconv.c
@@ -51,18 +51,26 @@
* @sa Samba Developers Guide
**/
-static size_t ascii_pull(void *,char **, size_t *, char **, size_t *);
-static size_t ascii_push(void *,char **, size_t *, char **, size_t *);
-static size_t latin1_push(void *,char **, size_t *, char **, size_t *);
-static size_t utf8_pull(void *,char **, size_t *, char **, size_t *);
-static size_t utf8_push(void *,char **, size_t *, char **, size_t *);
-static size_t ucs2hex_pull(void *,char **, size_t *, char **, size_t *);
-static size_t ucs2hex_push(void *,char **, size_t *, char **, size_t *);
-static size_t iconv_copy(void *,char **, size_t *, char **, size_t *);
+static size_t ascii_pull(void *,const char **, size_t *, char **, size_t *);
+static size_t ascii_push(void *,const char **, size_t *, char **, size_t *);
+static size_t latin1_push(void *,const char **, size_t *, char **, size_t *);
+static size_t utf8_pull(void *,const char **, size_t *, char **, size_t *);
+static size_t utf8_push(void *,const char **, size_t *, char **, size_t *);
+static size_t ucs2hex_pull(void *,const char **, size_t *, char **, size_t *);
+static size_t ucs2hex_push(void *,const char **, size_t *, char **, size_t *);
+static size_t iconv_copy(void *,const char **, size_t *, char **, size_t *);
+static size_t iconv_swab (void *,const char **, size_t *, char **, size_t *);
static struct charset_functions builtin_functions[] = {
+ /* windows is really neither UCS-2 not UTF-16 */
{"UCS-2LE", iconv_copy, iconv_copy},
+ {"UTF-16LE", iconv_copy, iconv_copy},
+ {"UCS-2BE", iconv_swab, iconv_swab},
+ {"UTF-16BE", iconv_swab, iconv_swab},
+
+ /* we include the UTF-8 alias to cope with differing locale settings */
{"UTF8", utf8_pull, utf8_push},
+ {"UTF-8", utf8_pull, utf8_push},
{"ASCII", ascii_pull, ascii_push},
{"646", ascii_pull, ascii_push},
{"ISO-8859-1", ascii_pull, latin1_push},
@@ -122,12 +130,12 @@ static void lazy_initialize_iconv(void)
this ensures that we don't have a shift state remaining for
character sets like SJIS */
static size_t sys_iconv(void *cd,
- char **inbuf, size_t *inbytesleft,
+ const char **inbuf, size_t *inbytesleft,
char **outbuf, size_t *outbytesleft)
{
#ifdef HAVE_NATIVE_ICONV
size_t ret = iconv((iconv_t)cd,
- inbuf, inbytesleft,
+ (char **)inbuf, inbytesleft,
outbuf, outbytesleft);
if (ret == (size_t)-1) {
int saved_errno = errno;
@@ -148,7 +156,7 @@ static size_t sys_iconv(void *cd,
* enough that Samba works on systems that don't have iconv.
**/
size_t smb_iconv(smb_iconv_t cd,
- char **inbuf, size_t *inbytesleft,
+ const char **inbuf, size_t *inbytesleft,
char **outbuf, size_t *outbytesleft)
{
char cvtbuf[2048];
@@ -158,7 +166,7 @@ size_t smb_iconv(smb_iconv_t cd,
/* in many cases we can go direct */
if (cd->direct) {
return cd->direct(cd->cd_direct,
- (char **)inbuf, inbytesleft, outbuf, outbytesleft);
+ inbuf, inbytesleft, outbuf, outbytesleft);
}
@@ -168,20 +176,27 @@ size_t smb_iconv(smb_iconv_t cd,
bufsize = sizeof(cvtbuf);
if (cd->pull(cd->cd_pull,
- (char **)inbuf, inbytesleft, &bufp, &bufsize) == -1
+ inbuf, inbytesleft, &bufp, &bufsize) == -1
&& errno != E2BIG) return -1;
bufp = cvtbuf;
bufsize = sizeof(cvtbuf) - bufsize;
if (cd->push(cd->cd_push,
- &bufp, &bufsize,
+ (const char **)&bufp, &bufsize,
outbuf, outbytesleft) == -1) return -1;
}
return 0;
}
+
+static BOOL is_utf16(const char *name)
+{
+ return strcasecmp(name, "UCS-2LE") == 0 ||
+ strcasecmp(name, "UTF-16LE") == 0;
+}
+
/*
simple iconv_open() wrapper
*/
@@ -220,13 +235,17 @@ smb_iconv_t smb_iconv_open(const char *tocode, const char *fromcode)
/* check if we can use iconv for this conversion */
#ifdef HAVE_NATIVE_ICONV
if (!ret->pull) {
- ret->cd_pull = iconv_open("UCS-2LE", fromcode);
+ ret->cd_pull = iconv_open("UTF-16LE", fromcode);
+ if (ret->cd_pull == (iconv_t)-1)
+ ret->cd_pull = iconv_open("UCS-2LE", fromcode);
if (ret->cd_pull != (iconv_t)-1)
ret->pull = sys_iconv;
}
if (!ret->push) {
- ret->cd_push = iconv_open(tocode, "UCS-2LE");
+ ret->cd_push = iconv_open(tocode, "UTF-16LE");
+ if (ret->cd_push == (iconv_t)-1)
+ ret->cd_push = iconv_open(tocode, "UCS-2LE");
if (ret->cd_push != (iconv_t)-1)
ret->push = sys_iconv;
}
@@ -256,13 +275,13 @@ smb_iconv_t smb_iconv_open(const char *tocode, const char *fromcode)
}
/* check for conversion to/from ucs2 */
- if (strcasecmp(fromcode, "UCS-2LE") == 0 && to) {
+ if (is_utf16(fromcode) && to) {
ret->direct = to->push;
ret->push = ret->pull = NULL;
return ret;
}
- if (strcasecmp(tocode, "UCS-2LE") == 0 && from) {
+ if (is_utf16(tocode) && from) {
ret->direct = from->pull;
ret->push = ret->pull = NULL;
return ret;
@@ -270,13 +289,13 @@ smb_iconv_t smb_iconv_open(const char *tocode, const char *fromcode)
/* Check if we can do the conversion direct */
#ifdef HAVE_NATIVE_ICONV
- if (strcasecmp(fromcode, "UCS-2LE") == 0) {
+ if (is_utf16(fromcode)) {
ret->direct = sys_iconv;
ret->cd_direct = ret->cd_push;
ret->cd_push = NULL;
return ret;
}
- if (strcasecmp(tocode, "UCS-2LE") == 0) {
+ if (is_utf16(tocode)) {
ret->direct = sys_iconv;
ret->cd_direct = ret->cd_pull;
ret->cd_pull = NULL;
@@ -313,7 +332,7 @@ int smb_iconv_close (smb_iconv_t cd)
multi-byte character set support for english users
***********************************************************************/
-static size_t ascii_pull(void *cd, char **inbuf, size_t *inbytesleft,
+static size_t ascii_pull(void *cd, const char **inbuf, size_t *inbytesleft,
char **outbuf, size_t *outbytesleft)
{
while (*inbytesleft >= 1 && *outbytesleft >= 2) {
@@ -333,7 +352,7 @@ static size_t ascii_pull(void *cd, char **inbuf, size_t *inbytesleft,
return 0;
}
-static size_t ascii_push(void *cd, char **inbuf, size_t *inbytesleft,
+static size_t ascii_push(void *cd, const char **inbuf, size_t *inbytesleft,
char **outbuf, size_t *outbytesleft)
{
int ir_count=0;
@@ -360,7 +379,7 @@ static size_t ascii_push(void *cd, char **inbuf, size_t *inbytesleft,
return ir_count;
}
-static size_t latin1_push(void *cd, char **inbuf, size_t *inbytesleft,
+static size_t latin1_push(void *cd, const char **inbuf, size_t *inbytesleft,
char **outbuf, size_t *outbytesleft)
{
int ir_count=0;
@@ -387,7 +406,7 @@ static size_t latin1_push(void *cd, char **inbuf, size_t *inbytesleft,
return ir_count;
}
-static size_t ucs2hex_pull(void *cd, char **inbuf, size_t *inbytesleft,
+static size_t ucs2hex_pull(void *cd, const char **inbuf, size_t *inbytesleft,
char **outbuf, size_t *outbytesleft)
{
while (*inbytesleft >= 1 && *outbytesleft >= 2) {
@@ -430,7 +449,7 @@ static size_t ucs2hex_pull(void *cd, char **inbuf, size_t *inbytesleft,
return 0;
}
-static size_t ucs2hex_push(void *cd, char **inbuf, size_t *inbytesleft,
+static size_t ucs2hex_push(void *cd, const char **inbuf, size_t *inbytesleft,
char **outbuf, size_t *outbytesleft)
{
while (*inbytesleft >= 2 && *outbytesleft >= 1) {
@@ -471,8 +490,32 @@ static size_t ucs2hex_push(void *cd, char **inbuf, size_t *inbytesleft,
return 0;
}
+static size_t iconv_swab(void *cd, const char **inbuf, size_t *inbytesleft,
+ char **outbuf, size_t *outbytesleft)
+{
+ int n;
+
+ n = MIN(*inbytesleft, *outbytesleft);
+
+ swab(*inbuf, *outbuf, (n&~1));
+ if (n&1) {
+ (*outbuf)[n-1] = 0;
+ }
+
+ (*inbytesleft) -= n;
+ (*outbytesleft) -= n;
+ (*inbuf) += n;
+ (*outbuf) += n;
+
+ if (*inbytesleft > 0) {
+ errno = E2BIG;
+ return -1;
+ }
-static size_t iconv_copy(void *cd, char **inbuf, size_t *inbytesleft,
+ return 0;
+}
+
+static size_t iconv_copy(void *cd, const char **inbuf, size_t *inbytesleft,
char **outbuf, size_t *outbytesleft)
{
int n;
@@ -494,102 +537,234 @@ static size_t iconv_copy(void *cd, char **inbuf, size_t *inbytesleft,
return 0;
}
-static size_t utf8_pull(void *cd, char **inbuf, size_t *inbytesleft,
+static size_t utf8_pull(void *cd, const char **inbuf, size_t *inbytesleft,
char **outbuf, size_t *outbytesleft)
{
- while (*inbytesleft >= 1 && *outbytesleft >= 2) {
- unsigned char *c = (unsigned char *)*inbuf;
- unsigned char *uc = (unsigned char *)*outbuf;
- int len = 1;
+ size_t in_left=*inbytesleft, out_left=*outbytesleft;
+ const uint8 *c = (const uint8 *)*inbuf;
+ uint8 *uc = (uint8 *)*outbuf;
+ while (in_left >= 1 && out_left >= 2) {
if ((c[0] & 0x80) == 0) {
uc[0] = c[0];
uc[1] = 0;
- } else if ((c[0] & 0xf0) == 0xe0) {
- if (*inbytesleft < 3) {
- DEBUG(0,("short utf8 char\n"));
- goto badseq;
+ c += 1;
+ in_left -= 1;
+ out_left -= 2;
+ uc += 2;
+ continue;
+ }
+
+ if ((c[0] & 0xe0) == 0xc0) {
+ if (in_left < 2 ||
+ (c[1] & 0xc0) != 0x80) {
+ errno = EILSEQ;
+ goto error;
+ }
+ uc[1] = (c[0]>>2) & 0x7;
+ uc[0] = (c[0]<<6) | (c[1]&0x3f);
+ c += 2;
+ in_left -= 2;
+ out_left -= 2;
+ uc += 2;
+ continue;
+ }
+
+ if ((c[0] & 0xf0) == 0xe0) {
+ if (in_left < 3 ||
+ (c[1] & 0xc0) != 0x80 ||
+ (c[2] & 0xc0) != 0x80) {
+ errno = EILSEQ;
+ goto error;
}
uc[1] = ((c[0]&0xF)<<4) | ((c[1]>>2)&0xF);
uc[0] = (c[1]<<6) | (c[2]&0x3f);
- len = 3;
- } else if ((c[0] & 0xe0) == 0xc0) {
- if (*inbytesleft < 2) {
- DEBUG(0,("short utf8 char\n"));
- goto badseq;
+ c += 3;
+ in_left -= 3;
+ out_left -= 2;
+ uc += 2;
+ continue;
+ }
+
+ if ((c[0] & 0xf8) == 0xf0) {
+ unsigned int codepoint;
+ if (in_left < 4 ||
+ (c[1] & 0xc0) != 0x80 ||
+ (c[2] & 0xc0) != 0x80 ||
+ (c[3] & 0xc0) != 0x80) {
+ errno = EILSEQ;
+ goto error;
}
- uc[1] = (c[0]>>2) & 0x7;
- uc[0] = (c[0]<<6) | (c[1]&0x3f);
- len = 2;
+ codepoint =
+ (c[3]&0x3f) |
+ ((c[2]&0x3f)<<6) |
+ ((c[1]&0x3f)<<12) |
+ ((c[0]&0x7)<<18);
+ if (codepoint < 0x10000) {
+ /* accept UTF-8 characters that are not
+ minimally packed, but pack the result */
+ uc[0] = (codepoint & 0xFF);
+ uc[1] = (codepoint >> 8);
+ c += 4;
+ in_left -= 4;
+ out_left -= 2;
+ uc += 2;
+ continue;
+ }
+
+ codepoint -= 0x10000;
+
+ if (out_left < 4) {
+ errno = E2BIG;
+ goto error;
+ }
+
+ uc[0] = (codepoint>>10) & 0xFF;
+ uc[1] = (codepoint>>18) | 0xd8;
+ uc[2] = codepoint & 0xFF;
+ uc[3] = ((codepoint>>8) & 0x3) | 0xdc;
+ c += 4;
+ in_left -= 4;
+ out_left -= 4;
+ uc += 4;
+ continue;
}
- (*inbuf) += len;
- (*inbytesleft) -= len;
- (*outbytesleft) -= 2;
- (*outbuf) += 2;
+ /* we don't handle 5 byte sequences */
+ errno = EINVAL;
+ goto error;
}
- if (*inbytesleft > 0) {
+ if (in_left > 0) {
errno = E2BIG;
- return -1;
+ goto error;
}
-
+
+ *inbytesleft = in_left;
+ *outbytesleft = out_left;
+ *inbuf = c;
+ *outbuf = uc;
return 0;
-badseq:
- errno = EINVAL;
+error:
+ *inbytesleft = in_left;
+ *outbytesleft = out_left;
+ *inbuf = c;
+ *outbuf = uc;
return -1;
}
-static size_t utf8_push(void *cd, char **inbuf, size_t *inbytesleft,
- char **outbuf, size_t *outbytesleft)
+static size_t utf8_push(void *cd, const char **inbuf, size_t *inbytesleft,
+ char **outbuf, size_t *outbytesleft)
{
- while (*inbytesleft >= 2 && *outbytesleft >= 1) {
- unsigned char *c = (unsigned char *)*outbuf;
- unsigned char *uc = (unsigned char *)*inbuf;
- int len=1;
-
- if (uc[1] & 0xf8) {
- if (*outbytesleft < 3) {
- DEBUG(0,("short utf8 write\n"));
- goto toobig;
+ size_t in_left=*inbytesleft, out_left=*outbytesleft;
+ uint8 *c = (uint8 *)*outbuf;
+ const uint8 *uc = (const uint8 *)*inbuf;
+
+ while (in_left >= 2 && out_left >= 1) {
+ unsigned int codepoint;
+
+ if (uc[1] == 0 && !(uc[0] & 0x80)) {
+ /* simplest case */
+ c[0] = uc[0];
+ in_left -= 2;
+ out_left -= 1;
+ uc += 2;
+ c += 1;
+ continue;
+ }
+
+ if ((uc[1]&0xf8) == 0) {
+ /* next simplest case */
+ if (out_left < 2) {
+ errno = E2BIG;
+ goto error;
}
- c[0] = 0xe0 | (uc[1]>>4);
- c[1] = 0x80 | ((uc[1]&0xF)<<2) | (uc[0]>>6);
- c[2] = 0x80 | (uc[0]&0x3f);
- len = 3;
- } else if (uc[1] | (uc[0] & 0x80)) {
- if (*outbytesleft < 2) {
- DEBUG(0,("short utf8 write\n"));
- goto toobig;
+ c[0] = 0xc0 | (uc[0]>>6) | (uc[1]<<2);
+ c[1] = 0x80 | (uc[0] & 0x3f);
+ in_left -= 2;
+ out_left -= 2;
+ uc += 2;
+ c += 2;
+ continue;
+ }
+
+ if ((uc[1] & 0xfc) == 0xdc) {
+ /* its the second part of a 4 byte sequence. Illegal */
+ if (in_left < 4) {
+ errno = EINVAL;
+ } else {
+ errno = EILSEQ;
}
- c[0] = 0xc0 | (uc[1]<<2) | (uc[0]>>6);
- c[1] = 0x80 | (uc[0]&0x3f);
- len = 2;
- } else {
- c[0] = uc[0];
+ goto error;
}
+ if ((uc[1] & 0xfc) != 0xd8) {
+ codepoint = uc[0] | (uc[1]<<8);
+ if (out_left < 3) {
+ errno = E2BIG;
+ goto error;
+ }
+ c[0] = 0xe0 | (codepoint >> 12);
+ c[1] = 0x80 | ((codepoint >> 6) & 0x3f);
+ c[2] = 0x80 | (codepoint & 0x3f);
+
+ in_left -= 2;
+ out_left -= 3;
+ uc += 2;
+ c += 3;
+ continue;
+ }
- (*inbytesleft) -= 2;
- (*outbytesleft) -= len;
- (*inbuf) += 2;
- (*outbuf) += len;
+ /* its the first part of a 4 byte sequence */
+ if (in_left < 4) {
+ errno = EINVAL;
+ goto error;
+ }
+ if ((uc[3] & 0xfc) != 0xdc) {
+ errno = EILSEQ;
+ goto error;
+ }
+ codepoint = 0x10000 + (uc[2] | ((uc[3] & 0x3)<<8) |
+ (uc[0]<<10) | ((uc[1] & 0x3)<<18));
+
+ if (out_left < 4) {
+ errno = E2BIG;
+ goto error;
+ }
+ c[0] = 0xf0 | (codepoint >> 18);
+ c[1] = 0x80 | ((codepoint >> 12) & 0x3f);
+ c[2] = 0x80 | ((codepoint >> 6) & 0x3f);
+ c[3] = 0x80 | (codepoint & 0x3f);
+
+ in_left -= 4;
+ out_left -= 4;
+ uc += 4;
+ c += 4;
}
- if (*inbytesleft == 1) {
+ if (in_left == 1) {
errno = EINVAL;
- return -1;
+ goto error;
}
- if (*inbytesleft > 1) {
+ if (in_left > 1) {
errno = E2BIG;
- return -1;
+ goto error;
}
+
+ *inbytesleft = in_left;
+ *outbytesleft = out_left;
+ *inbuf = uc;
+ *outbuf = c;
return 0;
-toobig:
- errno = E2BIG;
+error:
+ *inbytesleft = in_left;
+ *outbytesleft = out_left;
+ *inbuf = uc;
+ *outbuf = c;
return -1;
}
+
diff --git a/source/lib/ms_fnmatch.c b/source/lib/ms_fnmatch.c
index 24232c3b523..42c91bd18df 100644
--- a/source/lib/ms_fnmatch.c
+++ b/source/lib/ms_fnmatch.c
@@ -179,6 +179,9 @@ static int ms_fnmatch_w(const smb_ucs2_t *pattern, const smb_ucs2_t *string,
break;
case UCS2_CHAR('*'):
+ while (*p == UCS2_CHAR('*')) {
+ p++;
+ }
for (; *n; n++) {
if (ms_fnmatch_w(p, n, protocol, case_sensitive) == 0) return 0;
}
diff --git a/source/lib/smbldap.c b/source/lib/smbldap.c
index e66fb3640cf..57aab70a5ba 100644
--- a/source/lib/smbldap.c
+++ b/source/lib/smbldap.c
@@ -66,6 +66,29 @@ ATTRIB_MAP_ENTRY attrib_map_v22[] = {
{ LDAP_ATTR_DOMAIN, "domain" },
{ LDAP_ATTR_OBJCLASS, "objectClass" },
{ LDAP_ATTR_ACB_INFO, "acctFlags" },
+ { LDAP_ATTR_MOD_TIMESTAMP, "modifyTimestamp" },
+ { LDAP_ATTR_LIST_END, NULL }
+};
+
+ATTRIB_MAP_ENTRY attrib_map_to_delete_v22[] = {
+ { LDAP_ATTR_PWD_LAST_SET, "pwdLastSet" },
+ { LDAP_ATTR_PWD_CAN_CHANGE, "pwdCanChange" },
+ { LDAP_ATTR_PWD_MUST_CHANGE, "pwdMustChange" },
+ { LDAP_ATTR_LOGON_TIME, "logonTime" },
+ { LDAP_ATTR_LOGOFF_TIME, "logoffTime" },
+ { LDAP_ATTR_KICKOFF_TIME, "kickoffTime" },
+ { LDAP_ATTR_DISPLAY_NAME, "displayName" },
+ { LDAP_ATTR_HOME_PATH, "smbHome" },
+ { LDAP_ATTR_HOME_DRIVE, "homeDrives" },
+ { LDAP_ATTR_LOGON_SCRIPT, "scriptPath" },
+ { LDAP_ATTR_PROFILE_PATH, "profilePath" },
+ { LDAP_ATTR_USER_WKS, "userWorkstations"},
+ { LDAP_ATTR_USER_RID, "rid" },
+ { LDAP_ATTR_PRIMARY_GROUP_RID, "primaryGroupID"},
+ { LDAP_ATTR_LMPW, "lmPassword" },
+ { LDAP_ATTR_NTPW, "ntPassword" },
+ { LDAP_ATTR_DOMAIN, "domain" },
+ { LDAP_ATTR_ACB_INFO, "acctFlags" },
{ LDAP_ATTR_LIST_END, NULL }
};
@@ -106,6 +129,32 @@ ATTRIB_MAP_ENTRY attrib_map_v30[] = {
{ LDAP_ATTR_LIST_END, NULL }
};
+ATTRIB_MAP_ENTRY attrib_map_to_delete_v30[] = {
+ { LDAP_ATTR_PWD_LAST_SET, "sambaPwdLastSet" },
+ { LDAP_ATTR_PWD_CAN_CHANGE, "sambaPwdCanChange" },
+ { LDAP_ATTR_PWD_MUST_CHANGE, "sambaPwdMustChange" },
+ { LDAP_ATTR_LOGON_TIME, "sambaLogonTime" },
+ { LDAP_ATTR_LOGOFF_TIME, "sambaLogoffTime" },
+ { LDAP_ATTR_KICKOFF_TIME, "sambaKickoffTime" },
+ { LDAP_ATTR_HOME_DRIVE, "sambaHomeDrive" },
+ { LDAP_ATTR_HOME_PATH, "sambaHomePath" },
+ { LDAP_ATTR_LOGON_SCRIPT, "sambaLogonScript" },
+ { LDAP_ATTR_PROFILE_PATH, "sambaProfilePath" },
+ { LDAP_ATTR_USER_WKS, "sambaUserWorkstations" },
+ { LDAP_ATTR_USER_SID, LDAP_ATTRIBUTE_SID },
+ { LDAP_ATTR_PRIMARY_GROUP_SID, "sambaPrimaryGroupSID" },
+ { LDAP_ATTR_LMPW, "sambaLMPassword" },
+ { LDAP_ATTR_NTPW, "sambaNTPassword" },
+ { LDAP_ATTR_DOMAIN, "sambaDomainName" },
+ { LDAP_ATTR_ACB_INFO, "sambaAcctFlags" },
+ { LDAP_ATTR_MUNGED_DIAL, "sambaMungedDial" },
+ { LDAP_ATTR_BAD_PASSWORD_COUNT, "sambaBadPasswordCount" },
+ { LDAP_ATTR_BAD_PASSWORD_TIME, "sambaBadPasswordTime" },
+ { LDAP_ATTR_PWD_HISTORY, "sambaPasswordHistory" },
+ { LDAP_ATTR_LOGON_HOURS, "sambaLogonHours" },
+ { LDAP_ATTR_LIST_END, NULL }
+};
+
/* attributes used for allocating RIDs */
ATTRIB_MAP_ENTRY dominfo_attr_list[] = {
@@ -428,6 +477,12 @@ static BOOL fetch_ldap_pw(char **dn, char** pw)
char oldval[2048]; /* current largest allowed value is mungeddial */
BOOL existed;
+ if (attribute == NULL) {
+ /* This can actually happen for ldapsam_compat where we for
+ * example don't have a password history */
+ return;
+ }
+
if (existing != NULL) {
existed = smbldap_get_single_attribute(ldap_struct, existing, attribute, oldval, sizeof(oldval));
} else {
diff --git a/source/lib/smbrun.c b/source/lib/smbrun.c
index 592543bc43b..43cb209174e 100644
--- a/source/lib/smbrun.c
+++ b/source/lib/smbrun.c
@@ -90,7 +90,7 @@ int smbrun(char *cmd, int *outfd)
*outfd = -1;
}
return errno;
- }
+ }
if (pid) {
/*
@@ -178,3 +178,124 @@ int smbrun(char *cmd, int *outfd)
exit(82);
return 1;
}
+
+
+/****************************************************************************
+run a command being careful about uid/gid handling and putting the output in
+outfd (or discard it if outfd is NULL).
+sends the provided secret to the child stdin.
+****************************************************************************/
+
+int smbrunsecret(char *cmd, char *secret)
+{
+ pid_t pid;
+ uid_t uid = current_user.uid;
+ gid_t gid = current_user.gid;
+ int ifd[2];
+
+ /*
+ * Lose any kernel oplock capabilities we may have.
+ */
+ oplock_set_capability(False, False);
+
+ /* build up an input pipe */
+ if(pipe(ifd)) {
+ return -1;
+ }
+
+ /* in this method we will exec /bin/sh with the correct
+ arguments, after first setting stdout to point at the file */
+
+ /*
+ * We need to temporarily stop CatchChild from eating
+ * SIGCLD signals as it also eats the exit status code. JRA.
+ */
+
+ CatchChildLeaveStatus();
+
+ if ((pid=sys_fork()) < 0) {
+ DEBUG(0, ("smbrunsecret: fork failed with error %s\n", strerror(errno)));
+ CatchChild();
+ return errno;
+ }
+
+ if (pid) {
+ /*
+ * Parent.
+ */
+ int status = 0;
+ pid_t wpid;
+
+ close(ifd[0]);
+ /* send the secret */
+ write(ifd[1], secret, strlen(secret));
+ fsync(ifd[1]);
+ close(ifd[1]);
+
+ /* the parent just waits for the child to exit */
+ while((wpid = sys_waitpid(pid, &status, 0)) < 0) {
+ if(errno == EINTR) {
+ errno = 0;
+ continue;
+ }
+ break;
+ }
+
+ CatchChild();
+
+ if (wpid != pid) {
+ DEBUG(2, ("waitpid(%d) : %s\n", (int)pid, strerror(errno)));
+ return -1;
+ }
+
+#if defined(WIFEXITED) && defined(WEXITSTATUS)
+ if (WIFEXITED(status)) {
+ return WEXITSTATUS(status);
+ }
+#endif
+
+ return status;
+ }
+
+ CatchChild();
+
+ /* we are in the child. we exec /bin/sh to do the work for us. we
+ don't directly exec the command we want because it may be a
+ pipeline or anything else the config file specifies */
+
+ close(ifd[1]);
+ close(0);
+ if (sys_dup2(ifd[0], 0) != 0) {
+ DEBUG(2,("Failed to create stdin file descriptor\n"));
+ close(ifd[0]);
+ exit(80);
+ }
+
+ /* now completely lose our privileges. This is a fairly paranoid
+ way of doing it, but it does work on all systems that I know of */
+
+ become_user_permanently(uid, gid);
+
+ if (getuid() != uid || geteuid() != uid ||
+ getgid() != gid || getegid() != gid) {
+ /* we failed to lose our privileges - do not execute
+ the command */
+ exit(81); /* we can't print stuff at this stage,
+ instead use exit codes for debugging */
+ }
+
+#ifndef __INSURE__
+ /* close all other file descriptors, leaving only 0, 1 and 2. 0 and
+ 2 point to /dev/null from the startup code */
+ {
+ int fd;
+ for (fd = 3; fd < 256; fd++) close(fd);
+ }
+#endif
+
+ execl("/bin/sh", "sh", "-c", cmd, NULL);
+
+ /* not reached */
+ exit(82);
+ return 1;
+}
diff --git a/source/lib/util.c b/source/lib/util.c
index 8d01d9e7c9c..a456395cad1 100644
--- a/source/lib/util.c
+++ b/source/lib/util.c
@@ -1491,14 +1491,13 @@ BOOL is_in_path(const char *name, name_compare_entry *namelist, BOOL case_sensit
pstring last_component;
char *p;
- DEBUG(8, ("is_in_path: %s\n", name));
-
/* if we have no list it's obviously not in the path */
if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL))) {
- DEBUG(8,("is_in_path: no name list.\n"));
return False;
}
+ DEBUG(8, ("is_in_path: %s\n", name));
+
/* Get the last component of the unix name. */
p = strrchr_m(name, '/');
strncpy(last_component, p ? ++p : name, sizeof(last_component)-1);
diff --git a/source/lib/util_file.c b/source/lib/util_file.c
index bd505ac921c..303d961df57 100644
--- a/source/lib/util_file.c
+++ b/source/lib/util_file.c
@@ -24,7 +24,6 @@
#define MAP_FAILED ((void *)-1)
#endif
-
static int gotalarm;
/***************************************************************
@@ -33,7 +32,7 @@ static int gotalarm;
static void gotalarm_sig(void)
{
- gotalarm = 1;
+ gotalarm = 1;
}
/***************************************************************
@@ -43,34 +42,33 @@ static void gotalarm_sig(void)
BOOL do_file_lock(int fd, int waitsecs, int type)
{
- SMB_STRUCT_FLOCK lock;
- int ret;
- void (*oldsig_handler)(int);
-
- gotalarm = 0;
- oldsig_handler = CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig);
-
- lock.l_type = type;
- lock.l_whence = SEEK_SET;
- lock.l_start = 0;
- lock.l_len = 1;
- lock.l_pid = 0;
-
- alarm(waitsecs);
- /* Note we must *NOT* use sys_fcntl here ! JRA */
- ret = fcntl(fd, SMB_F_SETLKW, &lock);
- alarm(0);
- CatchSignal(SIGALRM, SIGNAL_CAST oldsig_handler);
-
- if (gotalarm) {
- DEBUG(0, ("do_file_lock: failed to %s file.\n",
- type == F_UNLCK ? "unlock" : "lock"));
- return False;
- }
-
- return (ret == 0);
-}
+ SMB_STRUCT_FLOCK lock;
+ int ret;
+ void (*oldsig_handler)(int);
+
+ gotalarm = 0;
+ oldsig_handler = CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig);
+
+ lock.l_type = type;
+ lock.l_whence = SEEK_SET;
+ lock.l_start = 0;
+ lock.l_len = 1;
+ lock.l_pid = 0;
+
+ alarm(waitsecs);
+ /* Note we must *NOT* use sys_fcntl here ! JRA */
+ ret = fcntl(fd, SMB_F_SETLKW, &lock);
+ alarm(0);
+ CatchSignal(SIGALRM, SIGNAL_CAST oldsig_handler);
+
+ if (gotalarm) {
+ DEBUG(0, ("do_file_lock: failed to %s file.\n",
+ type == F_UNLCK ? "unlock" : "lock"));
+ return False;
+ }
+ return (ret == 0);
+}
/***************************************************************
Lock an fd. Abandon after waitsecs seconds.
@@ -78,21 +76,19 @@ BOOL do_file_lock(int fd, int waitsecs, int type)
BOOL file_lock(int fd, int type, int secs, int *plock_depth)
{
- if (fd < 0)
- return False;
+ if (fd < 0)
+ return False;
- (*plock_depth)++;
+ (*plock_depth)++;
- if ((*plock_depth) == 0)
- {
- if (!do_file_lock(fd, secs, type)) {
- DEBUG(10,("file_lock: locking file failed, error = %s.\n",
- strerror(errno)));
- return False;
- }
- }
+ if ((*plock_depth) == 0) {
+ if (!do_file_lock(fd, secs, type)) {
+ DEBUG(10,("file_lock: locking file failed, error = %s.\n", strerror(errno)));
+ return False;
+ }
+ }
- return True;
+ return True;
}
/***************************************************************
@@ -101,105 +97,107 @@ BOOL file_lock(int fd, int type, int secs, int *plock_depth)
BOOL file_unlock(int fd, int *plock_depth)
{
- BOOL ret=True;
+ BOOL ret=True;
- if(*plock_depth == 1)
- ret = do_file_lock(fd, 5, F_UNLCK);
+ if(*plock_depth == 1) {
+ ret = do_file_lock(fd, 5, F_UNLCK);
+ }
- (*plock_depth)--;
+ (*plock_depth)--;
- if(!ret)
- DEBUG(10,("file_unlock: unlocking file failed, error = %s.\n",
- strerror(errno)));
- return ret;
+ if(!ret) {
+ DEBUG(10,("file_unlock: unlocking file failed, error = %s.\n", strerror(errno)));
+ }
+ return ret;
}
/***************************************************************
- locks a file for enumeration / modification.
+ Locks a file for enumeration / modification.
update to be set = True if modification is required.
****************************************************************/
void *startfilepwent(char *pfile, char *s_readbuf, int bufsize,
int *file_lock_depth, BOOL update)
{
- FILE *fp = NULL;
+ FILE *fp = NULL;
- if (!*pfile)
- {
- DEBUG(0, ("startfilepwent: No file set\n"));
- return (NULL);
- }
- DEBUG(10, ("startfilepwent: opening file %s\n", pfile));
+ if (!*pfile) {
+ DEBUG(0, ("startfilepwent: No file set\n"));
+ return (NULL);
+ }
+ DEBUG(10, ("startfilepwent: opening file %s\n", pfile));
- fp = sys_fopen(pfile, update ? "r+b" : "rb");
+ fp = sys_fopen(pfile, update ? "r+b" : "rb");
- if (fp == NULL) {
- DEBUG(0, ("startfilepwent: unable to open file %s\n", pfile));
- return NULL;
- }
+ if (fp == NULL) {
+ DEBUG(0, ("startfilepwent: unable to open file %s\n", pfile));
+ return NULL;
+ }
- /* Set a buffer to do more efficient reads */
- setvbuf(fp, s_readbuf, _IOFBF, bufsize);
+ /* Set a buffer to do more efficient reads */
+ setvbuf(fp, s_readbuf, _IOFBF, bufsize);
- if (!file_lock(fileno(fp), (update ? F_WRLCK : F_RDLCK), 5, file_lock_depth))
- {
- DEBUG(0, ("startfilepwent: unable to lock file %s\n", pfile));
- fclose(fp);
- return NULL;
- }
+ if (!file_lock(fileno(fp), (update ? F_WRLCK : F_RDLCK), 5, file_lock_depth)) {
+ DEBUG(0, ("startfilepwent: unable to lock file %s\n", pfile));
+ fclose(fp);
+ return NULL;
+ }
- /* Make sure it is only rw by the owner */
- chmod(pfile, 0600);
+ /* Make sure it is only rw by the owner */
+ chmod(pfile, 0600);
- /* We have a lock on the file. */
- return (void *)fp;
+ /* We have a lock on the file. */
+ return (void *)fp;
}
/***************************************************************
End enumeration of the file.
****************************************************************/
+
void endfilepwent(void *vp, int *file_lock_depth)
{
- FILE *fp = (FILE *)vp;
+ FILE *fp = (FILE *)vp;
- file_unlock(fileno(fp), file_lock_depth);
- fclose(fp);
- DEBUG(7, ("endfilepwent: closed file.\n"));
+ file_unlock(fileno(fp), file_lock_depth);
+ fclose(fp);
+ DEBUG(7, ("endfilepwent: closed file.\n"));
}
/*************************************************************************
Return the current position in the file list as an SMB_BIG_UINT.
This must be treated as an opaque token.
*************************************************************************/
+
SMB_BIG_UINT getfilepwpos(void *vp)
{
- return (SMB_BIG_UINT)sys_ftell((FILE *)vp);
+ return (SMB_BIG_UINT)sys_ftell((FILE *)vp);
}
/*************************************************************************
Set the current position in the file list from an SMB_BIG_UINT.
This must be treated as an opaque token.
*************************************************************************/
+
BOOL setfilepwpos(void *vp, SMB_BIG_UINT tok)
{
- return !sys_fseek((FILE *)vp, (SMB_OFF_T)tok, SEEK_SET);
+ return !sys_fseek((FILE *)vp, (SMB_OFF_T)tok, SEEK_SET);
}
/*************************************************************************
- gets a line out of a file.
+ Gets a line out of a file.
line is of format "xxxx:xxxxxx:xxxxx:".
lines with "#" at the front are ignored.
*************************************************************************/
+
int getfileline(void *vp, char *linebuf, int linebuf_size)
{
/* Static buffers we will return. */
FILE *fp = (FILE *)vp;
unsigned char c;
unsigned char *p;
- size_t linebuf_len;
+ size_t linebuf_len;
- if (fp == NULL)
- {
+ if (fp == NULL) {
DEBUG(0,("getfileline: Bad file pointer.\n"));
return -1;
}
@@ -207,13 +205,11 @@ int getfileline(void *vp, char *linebuf, int linebuf_size)
/*
* Scan the file, a line at a time.
*/
- while (!feof(fp))
- {
+ while (!feof(fp)) {
linebuf[0] = '\0';
fgets(linebuf, linebuf_size, fp);
- if (ferror(fp))
- {
+ if (ferror(fp)) {
return -1;
}
@@ -223,47 +219,38 @@ int getfileline(void *vp, char *linebuf, int linebuf_size)
*/
linebuf_len = strlen(linebuf);
- if (linebuf_len == 0)
- {
+ if (linebuf_len == 0) {
linebuf[0] = '\0';
return 0;
}
- if (linebuf[linebuf_len - 1] != '\n')
- {
+ if (linebuf[linebuf_len - 1] != '\n') {
c = '\0';
- while (!ferror(fp) && !feof(fp))
- {
+ while (!ferror(fp) && !feof(fp)) {
c = fgetc(fp);
- if (c == '\n')
- {
+ if (c == '\n') {
break;
}
}
- }
- else
- {
+ } else {
linebuf[linebuf_len - 1] = '\0';
}
#ifdef DEBUG_PASSWORD
DEBUG(100, ("getfileline: got line |%s|\n", linebuf));
#endif
- if ((linebuf[0] == 0) && feof(fp))
- {
+ if ((linebuf[0] == 0) && feof(fp)) {
DEBUG(4, ("getfileline: end of file reached\n"));
return 0;
}
- if (linebuf[0] == '#' || linebuf[0] == '\0')
- {
+ if (linebuf[0] == '#' || linebuf[0] == '\0') {
DEBUG(6, ("getfileline: skipping comment or blank line\n"));
continue;
}
p = (unsigned char *) strchr_m(linebuf, ':');
- if (p == NULL)
- {
+ if (p == NULL) {
DEBUG(0, ("getfileline: malformed line entry (no :)\n"));
continue;
}
@@ -272,85 +259,89 @@ int getfileline(void *vp, char *linebuf, int linebuf_size)
return -1;
}
-
/****************************************************************************
-read a line from a file with possible \ continuation chars.
-Blanks at the start or end of a line are stripped.
-The string will be allocated if s2 is NULL
+ Read a line from a file with possible \ continuation chars.
+ Blanks at the start or end of a line are stripped.
+ The string will be allocated if s2 is NULL.
****************************************************************************/
+
char *fgets_slash(char *s2,int maxlen,XFILE *f)
{
- char *s=s2;
- int len = 0;
- int c;
- BOOL start_of_line = True;
-
- if (x_feof(f))
- return(NULL);
-
- if (maxlen <2) return(NULL);
-
- if (!s2)
- {
- maxlen = MIN(maxlen,8);
- s = (char *)malloc(maxlen);
- }
-
- if (!s) return(NULL);
-
- *s = 0;
-
- while (len < maxlen-1)
- {
- c = x_getc(f);
- switch (c)
- {
- case '\r':
- break;
- case '\n':
- while (len > 0 && s[len-1] == ' ')
- {
- s[--len] = 0;
- }
- if (len > 0 && s[len-1] == '\\')
- {
- s[--len] = 0;
- start_of_line = True;
- break;
- }
- return(s);
- case EOF:
- if (len <= 0 && !s2)
- SAFE_FREE(s);
- return(len>0?s:NULL);
- case ' ':
- if (start_of_line)
- break;
- default:
- start_of_line = False;
- s[len++] = c;
- s[len] = 0;
- }
- if (!s2 && len > maxlen-3)
- {
- char *t;
+ char *s=s2;
+ int len = 0;
+ int c;
+ BOOL start_of_line = True;
+
+ if (x_feof(f)) {
+ return(NULL);
+ }
+
+ if (maxlen <2) {
+ return(NULL);
+ }
+
+ if (!s2) {
+ maxlen = MIN(maxlen,8);
+ s = (char *)malloc(maxlen);
+ }
+
+ if (!s) {
+ return(NULL);
+ }
+
+ *s = 0;
+
+ while (len < maxlen-1) {
+ c = x_getc(f);
+ switch (c) {
+ case '\r':
+ break;
+ case '\n':
+ while (len > 0 && s[len-1] == ' ') {
+ s[--len] = 0;
+ }
+ if (len > 0 && s[len-1] == '\\') {
+ s[--len] = 0;
+ start_of_line = True;
+ break;
+ }
+ return(s);
+ case EOF:
+ if (len <= 0 && !s2) {
+ SAFE_FREE(s);
+ }
+ return(len>0?s:NULL);
+ case ' ':
+ if (start_of_line) {
+ break;
+ }
+ default:
+ start_of_line = False;
+ s[len++] = c;
+ s[len] = 0;
+ }
+
+ if (!s2 && len > maxlen-3) {
+ char *t;
- maxlen *= 2;
- t = (char *)Realloc(s,maxlen);
- if (!t) {
- DEBUG(0,("fgets_slash: failed to expand buffer!\n"));
- SAFE_FREE(s);
- return(NULL);
- } else s = t;
- }
- }
- return(s);
+ maxlen *= 2;
+ t = (char *)Realloc(s,maxlen);
+ if (!t) {
+ DEBUG(0,("fgets_slash: failed to expand buffer!\n"));
+ SAFE_FREE(s);
+ return(NULL);
+ } else {
+ s = t;
+ }
+ }
+ }
+ return(s);
}
-
/****************************************************************************
-load from a pipe into memory
+ Load from a pipe into memory.
****************************************************************************/
+
char *file_pload(char *syscmd, size_t *size)
{
int fd, n;
@@ -359,7 +350,9 @@ char *file_pload(char *syscmd, size_t *size)
size_t total;
fd = sys_popen(syscmd);
- if (fd == -1) return NULL;
+ if (fd == -1) {
+ return NULL;
+ }
p = NULL;
total = 0;
@@ -371,7 +364,9 @@ char *file_pload(char *syscmd, size_t *size)
close(fd);
SAFE_FREE(p);
return NULL;
- } else p = tp;
+ } else {
+ p = tp;
+ }
memcpy(p+total, buf, n);
total += n;
}
@@ -382,13 +377,15 @@ char *file_pload(char *syscmd, size_t *size)
* truncated. */
sys_pclose(fd);
- if (size) *size = total;
+ if (size) {
+ *size = total;
+ }
return p;
}
/****************************************************************************
-load a file into memory from a fd.
+ Load a file into memory from a fd.
****************************************************************************/
char *fd_load(int fd, size_t *size)
@@ -396,10 +393,14 @@ char *fd_load(int fd, size_t *size)
SMB_STRUCT_STAT sbuf;
char *p;
- if (sys_fstat(fd, &sbuf) != 0) return NULL;
+ if (sys_fstat(fd, &sbuf) != 0) {
+ return NULL;
+ }
p = (char *)malloc(sbuf.st_size+1);
- if (!p) return NULL;
+ if (!p) {
+ return NULL;
+ }
if (read(fd, p, sbuf.st_size) != sbuf.st_size) {
SAFE_FREE(p);
@@ -407,79 +408,85 @@ char *fd_load(int fd, size_t *size)
}
p[sbuf.st_size] = 0;
- if (size) *size = sbuf.st_size;
+ if (size) {
+ *size = sbuf.st_size;
+ }
return p;
}
/****************************************************************************
-load a file into memory
+ Load a file into memory.
****************************************************************************/
+
char *file_load(const char *fname, size_t *size)
{
int fd;
char *p;
- if (!fname || !*fname) return NULL;
+ if (!fname || !*fname) {
+ return NULL;
+ }
fd = open(fname,O_RDONLY);
- if (fd == -1) return NULL;
+ if (fd == -1) {
+ return NULL;
+ }
p = fd_load(fd, size);
-
close(fd);
-
return p;
}
-
/*******************************************************************
-mmap (if possible) or read a file
+ mmap (if possible) or read a file.
********************************************************************/
+
void *map_file(char *fname, size_t size)
{
size_t s2 = 0;
void *p = NULL;
#ifdef HAVE_MMAP
- if (lp_use_mmap()) {
- int fd;
- fd = open(fname, O_RDONLY, 0);
- if (fd == -1) {
- DEBUG(2,("Failed to load %s - %s\n", fname, strerror(errno)));
- return NULL;
- }
- p = mmap(NULL, size, PROT_READ, MAP_SHARED|MAP_FILE, fd, 0);
- close(fd);
- if (p == MAP_FAILED) {
- DEBUG(1,("Failed to mmap %s - %s\n", fname, strerror(errno)));
- return NULL;
- }
+ int fd;
+ fd = open(fname, O_RDONLY, 0);
+ if (fd == -1) {
+ DEBUG(2,("map_file: Failed to load %s - %s\n", fname, strerror(errno)));
+ return NULL;
+ }
+ p = mmap(NULL, size, PROT_READ, MAP_SHARED|MAP_FILE, fd, 0);
+ close(fd);
+ if (p == MAP_FAILED) {
+ DEBUG(1,("map_file: Failed to mmap %s - %s\n", fname, strerror(errno)));
+ return NULL;
}
#endif
if (!p) {
p = file_load(fname, &s2);
- if (!p) return NULL;
+ if (!p) {
+ return NULL;
+ }
if (s2 != size) {
- DEBUG(1,("incorrect size for %s - got %lu expected %lu\n",
+ DEBUG(1,("map_file: incorrect size for %s - got %lu expected %lu\n",
fname, (unsigned long)s2, (unsigned long)size));
- if (p) free(p);
+ SAFE_FREE(p);
return NULL;
}
}
-
return p;
}
-
/****************************************************************************
-parse a buffer into lines
+ Parse a buffer into lines.
****************************************************************************/
+
static char **file_lines_parse(char *p, size_t size, int *numlines)
{
int i;
char *s, **ret;
- if (!p) return NULL;
+ if (!p) {
+ return NULL;
+ }
for (s = p, i=0; s < p+size; s++) {
if (s[0] == '\n') i++;
@@ -491,7 +498,9 @@ static char **file_lines_parse(char *p, size_t size, int *numlines)
return NULL;
}
memset(ret, 0, sizeof(ret[0])*(i+2));
- if (numlines) *numlines = i;
+ if (numlines) {
+ *numlines = i;
+ }
ret[0] = p;
for (s = p, i=0; s < p+size; s++) {
@@ -500,75 +509,87 @@ static char **file_lines_parse(char *p, size_t size, int *numlines)
i++;
ret[i] = s+1;
}
- if (s[0] == '\r') s[0] = 0;
+ if (s[0] == '\r') {
+ s[0] = 0;
+ }
}
return ret;
}
-
/****************************************************************************
-load a file into memory and return an array of pointers to lines in the file
-must be freed with file_lines_free().
+ Load a file into memory and return an array of pointers to lines in the file
+ must be freed with file_lines_free().
****************************************************************************/
+
char **file_lines_load(const char *fname, int *numlines)
{
char *p;
size_t size;
p = file_load(fname, &size);
- if (!p) return NULL;
+ if (!p) {
+ return NULL;
+ }
return file_lines_parse(p, size, numlines);
}
/****************************************************************************
-load a fd into memory and return an array of pointers to lines in the file
-must be freed with file_lines_free(). If convert is true calls unix_to_dos on
-the list.
+ Load a fd into memory and return an array of pointers to lines in the file
+ must be freed with file_lines_free(). If convert is true calls unix_to_dos on
+ the list.
****************************************************************************/
+
char **fd_lines_load(int fd, int *numlines)
{
char *p;
size_t size;
p = fd_load(fd, &size);
- if (!p) return NULL;
+ if (!p) {
+ return NULL;
+ }
return file_lines_parse(p, size, numlines);
}
-
/****************************************************************************
-load a pipe into memory and return an array of pointers to lines in the data
-must be freed with file_lines_free().
+ Load a pipe into memory and return an array of pointers to lines in the data
+ must be freed with file_lines_free().
****************************************************************************/
+
char **file_lines_pload(char *syscmd, int *numlines)
{
char *p;
size_t size;
p = file_pload(syscmd, &size);
- if (!p) return NULL;
+ if (!p) {
+ return NULL;
+ }
return file_lines_parse(p, size, numlines);
}
/****************************************************************************
-free lines loaded with file_lines_load
+ Free lines loaded with file_lines_load.
****************************************************************************/
+
void file_lines_free(char **lines)
{
- if (!lines) return;
+ if (!lines) {
+ return;
+ }
SAFE_FREE(lines[0]);
SAFE_FREE(lines);
}
-
/****************************************************************************
-take a lislist of lines and modify them to produce a list where \ continues
-a line
+ Take a list of lines and modify them to produce a list where \ continues
+ a line.
****************************************************************************/
+
void file_lines_slashcont(char **lines)
{
int i, j;
@@ -579,8 +600,12 @@ void file_lines_slashcont(char **lines)
lines[i][len-1] = ' ';
if (lines[i+1]) {
char *p = &lines[i][len];
- while (p < lines[i+1]) *p++ = ' ';
- for (j = i+1; lines[j]; j++) lines[j] = lines[j+1];
+ while (p < lines[i+1]) {
+ *p++ = ' ';
+ }
+ for (j = i+1; lines[j]; j++) {
+ lines[j] = lines[j+1];
+ }
}
} else {
i++;
@@ -588,9 +613,10 @@ void file_lines_slashcont(char **lines)
}
}
-/*
- save a lump of data into a file. Mostly used for debugging
-*/
+/****************************************************************************
+ Save a lump of data into a file. Mostly used for debugging.
+****************************************************************************/
+
BOOL file_save(const char *fname, void *packet, size_t length)
{
int fd;
diff --git a/source/lib/util_str.c b/source/lib/util_str.c
index 6eee62c14aa..65a616ad419 100644
--- a/source/lib/util_str.c
+++ b/source/lib/util_str.c
@@ -134,17 +134,20 @@ char **toktocliplist(int *ctok, const char *sep)
*ctok=ictok;
s=(char *)last_ptr;
- if (!(ret=iret=malloc(ictok*sizeof(char *))))
+ if (!(ret=iret=malloc((ictok+1)*sizeof(char *))))
return NULL;
while(ictok--) {
*iret++=s;
- while(*s++)
- ;
- while(!*s)
- s++;
+ if (ictok > 0) {
+ while(*s++)
+ ;
+ while(!*s)
+ s++;
+ }
}
+ ret[*ctok] = NULL;
return ret;
}
diff --git a/source/lib/util_uuid.c b/source/lib/util_uuid.c
index 8f86c2109ea..df70740b33c 100644
--- a/source/lib/util_uuid.c
+++ b/source/lib/util_uuid.c
@@ -29,11 +29,11 @@
void smb_uuid_pack(const struct uuid uu, UUID_FLAT *ptr)
{
- SIVAL(ptr, 0, uu.time_low);
- SSVAL(ptr, 4, uu.time_mid);
- SSVAL(ptr, 6, uu.time_hi_and_version);
- memcpy(ptr+8, uu.clock_seq, 2);
- memcpy(ptr+10, uu.node, 6);
+ SIVAL(ptr->info, 0, uu.time_low);
+ SSVAL(ptr->info, 4, uu.time_mid);
+ SSVAL(ptr->info, 6, uu.time_hi_and_version);
+ memcpy(ptr->info+8, uu.clock_seq, 2);
+ memcpy(ptr->info+10, uu.node, 6);
}
void smb_uuid_unpack(const UUID_FLAT in, struct uuid *uu)
@@ -96,6 +96,7 @@ BOOL smb_string_to_uuid(const char *in, struct uuid* uu)
const char *ptr = in;
char *end = (char *)in;
int i;
+ unsigned v1, v2;
if (!in || !uu) goto out;
@@ -111,61 +112,22 @@ BOOL smb_string_to_uuid(const char *in, struct uuid* uu)
if ((end - ptr) != 4 || *end != '-') goto out;
ptr = (end + 1);
- for (i = 0; i < 2; i++) {
- int adj = 0;
- if (*ptr >= '0' && *ptr <= '9') {
- adj = '0';
- } else if (*ptr >= 'a' && *ptr <= 'f') {
- adj = 'a';
- } else if (*ptr >= 'A' && *ptr <= 'F') {
- adj = 'A';
- } else {
- goto out;
- }
- uu->clock_seq[i] = (*ptr - adj) << 4;
- ptr++;
-
- if (*ptr >= '0' && *ptr <= '9') {
- adj = '0';
- } else if (*ptr >= 'a' && *ptr <= 'f') {
- adj = 'a';
- } else if (*ptr >= 'A' && *ptr <= 'F') {
- adj = 'A';
- } else {
- goto out;
- }
- uu->clock_seq[i] |= (*ptr - adj);
- ptr++;
+ if (sscanf(ptr, "%02x%02x", &v1, &v2) != 2) {
+ goto out;
}
+ uu->clock_seq[0] = v1;
+ uu->clock_seq[1] = v2;
+ ptr += 4;
if (*ptr != '-') goto out;
ptr++;
for (i = 0; i < 6; i++) {
- int adj = 0;
- if (*ptr >= '0' && *ptr <= '9') {
- adj = '0';
- } else if (*ptr >= 'a' && *ptr <= 'f') {
- adj = 'a';
- } else if (*ptr >= 'A' && *ptr <= 'F') {
- adj = 'A';
- } else {
- goto out;
- }
- uu->node[i] = (*ptr - adj) << 4;
- ptr++;
-
- if (*ptr >= '0' && *ptr <= '9') {
- adj = '0';
- } else if (*ptr >= 'a' && *ptr <= 'f') {
- adj = 'a';
- } else if (*ptr >= 'A' && *ptr <= 'F') {
- adj = 'A';
- } else {
+ if (sscanf(ptr, "%02x", &v1) != 1) {
goto out;
}
- uu->node[i] |= (*ptr - adj);
- ptr++;
+ uu->node[i] = v1;
+ ptr += 2;
}
ret = True;