diff options
Diffstat (limited to 'source/lib')
-rw-r--r-- | source/lib/charcnv.c | 30 | ||||
-rw-r--r-- | source/lib/hash.c | 316 | ||||
-rw-r--r-- | source/lib/iconv.c | 347 | ||||
-rw-r--r-- | source/lib/ms_fnmatch.c | 3 | ||||
-rw-r--r-- | source/lib/smbldap.c | 55 | ||||
-rw-r--r-- | source/lib/smbrun.c | 123 | ||||
-rw-r--r-- | source/lib/util.c | 5 | ||||
-rw-r--r-- | source/lib/util_file.c | 492 | ||||
-rw-r--r-- | source/lib/util_str.c | 13 | ||||
-rw-r--r-- | source/lib/util_uuid.c | 66 |
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; |