r10656: BIG merge from trunk. Features not copied over
[samba.git] / source / lib / util.c
index 3da4e536e02fb0fb38458129b7f0b451dd8d5003..a5cfe95b660fd931b168bdee55db0a82862aa03e 100644 (file)
 
 #include "includes.h"
 
+extern fstring local_machine;
+extern char *global_clobber_region_function;
+extern unsigned int global_clobber_region_line;
+extern fstring remote_arch;
+
+/* Max allowable allococation - 256mb - 0x10000000 */
+#define MAX_ALLOC_SIZE (1024*1024*256)
+
 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
 #ifdef WITH_NISPLUS_HOME
 #ifdef BROKEN_NISPLUS_INCLUDE_FILES
 
 #include <rpcsvc/nis.h>
 
-#else /* !WITH_NISPLUS_HOME */
-
-#include "rpcsvc/ypclnt.h"
-
 #endif /* WITH_NISPLUS_HOME */
 #endif /* HAVE_NETGROUP && WITH_AUTOMOUNT */
 
-int Protocol = PROTOCOL_COREPLUS;
+enum protocol_types Protocol = PROTOCOL_COREPLUS;
 
 /* a default finfo structure to ensure all fields are sensible */
 file_info def_finfo = {-1,0,0,0,0,0,0,"",""};
@@ -63,19 +67,6 @@ int chain_size = 0;
 
 int trans_num = 0;
 
-/*
-   case handling on filenames 
-*/
-int case_default = CASE_LOWER;
-
-/* the following control case operations - they are put here so the
-   client can link easily */
-BOOL case_sensitive;
-BOOL case_preserve;
-BOOL use_mangled_map = False;
-BOOL short_case_preserve;
-BOOL case_mangle;
-
 static enum remote_arch_types ra_type = RA_UNKNOWN;
 pstring user_socket_options=DEFAULT_SOCKET_OPTIONS;   
 
@@ -96,7 +87,7 @@ static char **smb_my_netbios_names;
 BOOL set_global_myname(const char *myname)
 {
        SAFE_FREE(smb_myname);
-       smb_myname = strdup(myname);
+       smb_myname = SMB_STRDUP(myname);
        if (!smb_myname)
                return False;
        strupper_m(smb_myname);
@@ -115,7 +106,7 @@ const char *global_myname(void)
 BOOL set_global_myworkgroup(const char *myworkgroup)
 {
        SAFE_FREE(smb_myworkgroup);
-       smb_myworkgroup = strdup(myworkgroup);
+       smb_myworkgroup = SMB_STRDUP(myworkgroup);
        if (!smb_myworkgroup)
                return False;
        strupper_m(smb_myworkgroup);
@@ -134,7 +125,7 @@ const char *lp_workgroup(void)
 BOOL set_global_scope(const char *scope)
 {
        SAFE_FREE(smb_scope);
-       smb_scope = strdup(scope);
+       smb_scope = SMB_STRDUP(scope);
        if (!smb_scope)
                return False;
        strupper_m(smb_scope);
@@ -168,7 +159,7 @@ static BOOL allocate_my_netbios_names_array(size_t number)
        free_netbios_names_array();
 
        smb_num_netbios_names = number + 1;
-       smb_my_netbios_names = (char **)malloc( sizeof(char *) * smb_num_netbios_names );
+       smb_my_netbios_names = SMB_MALLOC_ARRAY( char *, smb_num_netbios_names );
 
        if (!smb_my_netbios_names)
                return False;
@@ -181,7 +172,7 @@ static BOOL set_my_netbios_names(const char *name, int i)
 {
        SAFE_FREE(smb_my_netbios_names[i]);
 
-       smb_my_netbios_names[i] = strdup(name);
+       smb_my_netbios_names[i] = SMB_STRDUP(name);
        if (!smb_my_netbios_names[i])
                return False;
        strupper_m(smb_my_netbios_names[i]);
@@ -244,7 +235,6 @@ BOOL set_netbios_aliases(const char **str_array)
 
 BOOL init_names(void)
 {
-       extern fstring local_machine;
        char *p;
        int n;
 
@@ -288,21 +278,29 @@ const char *tmpdir(void)
 }
 
 /****************************************************************************
Determine whether we are in the specified group.
Add a gid to an array of gids if it's not already there.
 ****************************************************************************/
 
-BOOL in_group(gid_t group, gid_t current_gid, int ngroups, const gid_t *groups)
+void add_gid_to_array_unique(TALLOC_CTX *mem_ctx, gid_t gid,
+                            gid_t **gids, int *num)
 {
        int i;
 
-       if (group == current_gid)
-               return(True);
+       for (i=0; i<*num; i++) {
+               if ((*gids)[i] == gid)
+                       return;
+       }
 
-       for (i=0;i<ngroups;i++)
-               if (group == groups[i])
-                       return(True);
+       if (mem_ctx != NULL)
+               *gids = TALLOC_REALLOC_ARRAY(mem_ctx, *gids, gid_t, *num+1);
+       else
+               *gids = SMB_REALLOC_ARRAY(*gids, gid_t, *num+1);
 
-       return(False);
+       if (*gids == NULL)
+               return;
+
+       (*gids)[*num] = gid;
+       *num += 1;
 }
 
 /****************************************************************************
@@ -346,7 +344,7 @@ const char *get_numlist(const char *p, uint32 **num, int *count)
        while ((p = Atoic(p, &val, ":,")) != NULL && (*p) != ':') {
                uint32 *tn;
                
-               tn = Realloc((*num), ((*count)+1) * sizeof(uint32));
+               tn = SMB_REALLOC_ARRAY((*num), uint32, (*count)+1);
                if (tn == NULL) {
                        SAFE_FREE(*num);
                        return NULL;
@@ -551,7 +549,7 @@ void dos_clean_name(char *s)
        /* remove any double slashes */
        all_string_sub(s, "\\\\", "\\", 0);
 
-       while ((p = strstr(s,"\\..\\")) != NULL) {
+       while ((p = strstr_m(s,"\\..\\")) != NULL) {
                pstring s1;
 
                *p = 0;
@@ -589,7 +587,7 @@ void unix_clean_name(char *s)
                        pstrcpy(s,"./");
        }
 
-       while ((p = strstr(s,"/../")) != NULL) {
+       while ((p = strstr_m(s,"/../")) != NULL) {
                pstring s1;
 
                *p = 0;
@@ -605,38 +603,6 @@ void unix_clean_name(char *s)
        trim_string(s,NULL,"/..");
 }
 
-/****************************************************************************
- Make a dir struct.
-****************************************************************************/
-
-void make_dir_struct(char *buf, const char *mask, const char *fname,SMB_OFF_T size,int mode,time_t date)
-{  
-       char *p;
-       pstring mask2;
-
-       pstrcpy(mask2,mask);
-
-       if ((mode & aDIR) != 0)
-               size = 0;
-
-       memset(buf+1,' ',11);
-       if ((p = strchr_m(mask2,'.')) != NULL) {
-               *p = 0;
-               push_ascii(buf+1,mask2,8, 0);
-               push_ascii(buf+9,p+1,3, 0);
-               *p = '.';
-       } else
-               push_ascii(buf+1,mask2,11, 0);
-
-       memset(buf+21,'\0',DIR_STRUCT_SIZE-21);
-       SCVAL(buf,21,mode);
-       put_dos_date(buf,22,date);
-       SSVAL(buf,26,size & 0xFFFF);
-       SSVAL(buf,28,(size >> 16)&0xFFFF);
-       push_ascii(buf+30,fname,12, case_sensitive ? 0 : STR_UPPER);
-       DEBUG(8,("put name [%s] from [%s] into dir struct\n",buf+30, fname));
-}
-
 /*******************************************************************
  Close the low 3 fd's and open dev/null in their place.
 ********************************************************************/
@@ -674,6 +640,46 @@ void close_low_fds(BOOL stderr_too)
 #endif
 }
 
+/*******************************************************************
+ Write data into an fd at a given offset. Ignore seek errors.
+********************************************************************/
+
+ssize_t write_data_at_offset(int fd, const char *buffer, size_t N, SMB_OFF_T pos)
+{
+       size_t total=0;
+       ssize_t ret;
+
+       if (pos == (SMB_OFF_T)-1) {
+               return write_data(fd, buffer, N);
+       }
+#if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64)
+       while (total < N) {
+               ret = sys_pwrite(fd,buffer + total,N - total, pos);
+               if (ret == -1 && errno == ESPIPE) {
+                       return write_data(fd, buffer + total,N - total);
+               }
+               if (ret == -1) {
+                       DEBUG(0,("write_data_at_offset: write failure. Error = %s\n", strerror(errno) ));
+                       return -1;
+               }
+               if (ret == 0) {
+                       return total;
+               }
+               total += ret;
+               pos += ret;
+       }
+       return (ssize_t)total;
+#else
+       /* Use lseek and write_data. */
+       if (sys_lseek(fd, pos, SEEK_SET) == -1) {
+               if (errno != ESPIPE) {
+                       return -1;
+               }
+       }
+       return write_data(fd, buffer, N);
+#endif
+}
+
 /****************************************************************************
  Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
  else
@@ -722,7 +728,7 @@ ssize_t transfer_file_internal(int infd, int outfd, size_t n, ssize_t (*read_fn)
        size_t num_to_read_thistime;
        size_t num_written = 0;
 
-       if ((buf = malloc(TRANSFER_BUF_SIZE)) == NULL)
+       if ((buf = SMB_MALLOC(TRANSFER_BUF_SIZE)) == NULL)
                return -1;
 
        while (total < n) {
@@ -769,14 +775,26 @@ SMB_OFF_T transfer_file(int infd,int outfd,SMB_OFF_T n)
  Sleep for a specified number of milliseconds.
 ********************************************************************/
 
-void msleep(unsigned int t)
+void smb_msleep(unsigned int t)
 {
+#if defined(HAVE_NANOSLEEP)
+       struct timespec tval;
+       int ret;
+
+       tval.tv_sec = t/1000;
+       tval.tv_nsec = 1000000*(t%1000);
+
+       do {
+               errno = 0;
+               ret = nanosleep(&tval, &tval);
+       } while (ret < 0 && errno == EINTR && (tval.tv_sec > 0 || tval.tv_nsec > 0));
+#else
        unsigned int tdiff=0;
        struct timeval tval,t1,t2;  
        fd_set fds;
 
        GetTimeOfDay(&t1);
-       GetTimeOfDay(&t2);
+       t2 = t1;
   
        while (tdiff < t) {
                tval.tv_sec = (t-tdiff)/1000;
@@ -800,6 +818,7 @@ void msleep(unsigned int t)
 
                tdiff = TvalDiff(&t1,&t2);
        }
+#endif
 }
 
 /****************************************************************************
@@ -850,6 +869,76 @@ BOOL yesno(char *p)
        return(False);
 }
 
+#if defined(PARANOID_MALLOC_CHECKER)
+
+/****************************************************************************
+ Internal malloc wrapper. Externally visible.
+****************************************************************************/
+
+void *malloc_(size_t size)
+{
+#undef malloc
+       return malloc(size);
+#define malloc(s) __ERROR_DONT_USE_MALLOC_DIRECTLY
+}
+
+/****************************************************************************
+ Internal calloc wrapper. Not externally visible.
+****************************************************************************/
+
+static void *calloc_(size_t count, size_t size)
+{
+#undef calloc
+       return calloc(count, size);
+#define calloc(n,s) __ERROR_DONT_USE_CALLOC_DIRECTLY
+}
+
+/****************************************************************************
+ Internal realloc wrapper. Not externally visible.
+****************************************************************************/
+
+static void *realloc_(void *ptr, size_t size)
+{
+#undef realloc
+       return realloc(ptr, size);
+#define realloc(p,s) __ERROR_DONT_USE_RELLOC_DIRECTLY
+}
+
+#endif /* PARANOID_MALLOC_CHECKER */
+
+/****************************************************************************
+ Type-safe malloc.
+****************************************************************************/
+
+void *malloc_array(size_t el_size, unsigned int count)
+{
+       if (count >= MAX_ALLOC_SIZE/el_size) {
+               return NULL;
+       }
+
+#if defined(PARANOID_MALLOC_CHECKER)
+       return malloc_(el_size*count);
+#else
+       return malloc(el_size*count);
+#endif
+}
+
+/****************************************************************************
+ Type-safe calloc.
+****************************************************************************/
+
+void *calloc_array(size_t size, size_t nmemb)
+{
+       if (nmemb >= MAX_ALLOC_SIZE/size) {
+               return NULL;
+       }
+#if defined(PARANOID_MALLOC_CHECKER)
+       return calloc_(nmemb, size);
+#else
+       return calloc(nmemb, size);
+#endif
+}
+
 /****************************************************************************
  Expand a pointer to be a particular size.
 ****************************************************************************/
@@ -864,10 +953,17 @@ void *Realloc(void *p,size_t size)
                return NULL;
        }
 
+#if defined(PARANOID_MALLOC_CHECKER)
+       if (!p)
+               ret = (void *)malloc_(size);
+       else
+               ret = (void *)realloc_(p,size);
+#else
        if (!p)
                ret = (void *)malloc(size);
        else
                ret = (void *)realloc(p,size);
+#endif
 
        if (!ret)
                DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",(int)size));
@@ -875,17 +971,73 @@ void *Realloc(void *p,size_t size)
        return(ret);
 }
 
-void *Realloc_zero(void *ptr, size_t size)
+/****************************************************************************
+ Type-safe realloc.
+****************************************************************************/
+
+void *realloc_array(void *p,size_t el_size, unsigned int count)
 {
-       void *tptr = NULL;
-               
-       tptr = Realloc(ptr, size);
-       if(tptr == NULL)
+       if (count >= MAX_ALLOC_SIZE/el_size) {
                return NULL;
+       }
+       return Realloc(p,el_size*count);
+}
 
-       memset((char *)tptr,'\0',size);
+/****************************************************************************
+ (Hopefully) efficient array append
+****************************************************************************/
+void add_to_large_array(TALLOC_CTX *mem_ctx, size_t element_size,
+                       void *element, void **array, uint32 *num_elements,
+                       ssize_t *array_size)
+{
+       if (*array_size < 0)
+               return;
 
-       return tptr;
+       if (*array == NULL) {
+               if (*array_size == 0) {
+                       *array_size = 128;
+               }
+
+               if (*array_size >= MAX_ALLOC_SIZE/element_size) {
+                       goto error;
+               }
+
+               if (mem_ctx != NULL)
+                       *array = TALLOC(mem_ctx, element_size * (*array_size));
+               else
+                       *array = SMB_MALLOC(element_size * (*array_size));
+
+               if (*array == NULL)
+                       goto error;
+       }
+
+       if (*num_elements == *array_size) {
+               *array_size *= 2;
+
+               if (*array_size >= MAX_ALLOC_SIZE/element_size) {
+                       goto error;
+               }
+
+               if (mem_ctx != NULL)
+                       *array = TALLOC_REALLOC(mem_ctx, *array,
+                                               element_size * (*array_size));
+               else
+                       *array = SMB_REALLOC(*array,
+                                            element_size * (*array_size));
+
+               if (*array == NULL)
+                       goto error;
+       }
+
+       memcpy((char *)(*array) + element_size*(*num_elements),
+              element, element_size);
+       *num_elements += 1;
+
+       return;
+
+ error:
+       *num_elements = 0;
+       *array_size = -1;
 }
 
 /****************************************************************************
@@ -1136,7 +1288,7 @@ static void strip_mount_options( pstring *str)
 *******************************************************************/
 
 #ifdef WITH_NISPLUS_HOME
-char *automount_lookup(const char *user_name)
+char *automount_lookup( char *user_name)
 {
        static fstring last_key = "";
        static pstring last_value = "";
@@ -1179,7 +1331,7 @@ char *automount_lookup(const char *user_name)
 }
 #else /* WITH_NISPLUS_HOME */
 
-char *automount_lookup(const char *user_name)
+char *automount_lookup( char *user_name)
 {
        static fstring last_key = "";
        static pstring last_value = "";
@@ -1252,12 +1404,22 @@ BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
  Check if a process exists. Does this work on all unixes?
 ****************************************************************************/
 
-BOOL process_exists(pid_t pid)
+BOOL process_exists(const struct process_id pid)
 {
+       if (!procid_is_local(&pid)) {
+               /* This *SEVERELY* needs fixing. */
+               return True;
+       }
+
        /* Doing kill with a non-positive pid causes messages to be
         * sent to places we don't want. */
-       SMB_ASSERT(pid > 0);
-       return(kill(pid,0) == 0 || errno != ESRCH);
+       SMB_ASSERT(pid.pid > 0);
+       return(kill(pid.pid,0) == 0 || errno != ESRCH);
+}
+
+BOOL process_exists_by_pid(pid_t pid)
+{
+       return process_exists(pid_to_procid(pid));
 }
 
 /*******************************************************************
@@ -1340,11 +1502,23 @@ gid_t nametogid(const char *name)
        return (gid_t)-1;
 }
 
+/*******************************************************************
+ legacy wrapper for smb_panic2()
+********************************************************************/
+void smb_panic( const char *why )
+{
+       smb_panic2( why, True );
+}
+
 /*******************************************************************
  Something really nasty happened - panic !
 ********************************************************************/
 
-void smb_panic(const char *why)
+#ifdef HAVE_LIBEXC_H
+#include <libexc.h>
+#endif
+
+void smb_panic2(const char *why, BOOL decrement_pid_count )
 {
        char *cmd;
        int result;
@@ -1356,8 +1530,6 @@ void smb_panic(const char *why)
 
 #ifdef DEVELOPER
        {
-               extern char *global_clobber_region_function;
-               extern unsigned int global_clobber_region_line;
 
                if (global_clobber_region_function) {
                        DEBUG(0,("smb_panic: clobber_region() last called from [%s(%u)]\n",
@@ -1367,6 +1539,10 @@ void smb_panic(const char *why)
        }
 #endif
 
+       /* only smbd needs to decrement the smbd counter in connections.tdb */
+       if ( decrement_pid_count )
+               decrement_smbd_process_count();
+
        cmd = lp_panic_action();
        if (cmd && *cmd) {
                DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmd));
@@ -1395,12 +1571,56 @@ void smb_panic(const char *why)
                for (i = 0; i < backtrace_size; i++)
                        DEBUGADD(0, (" #%u %s\n", i, backtrace_strings[i]));
 
-               SAFE_FREE(backtrace_strings);
+               /* Leak the backtrace_strings, rather than risk what free() might do */
        }
 
+#elif HAVE_LIBEXC
+
+#define NAMESIZE 32 /* Arbitrary */
+
+       /* The IRIX libexc library provides an API for unwinding the stack. See
+        * libexc(3) for details. Apparantly trace_back_stack leaks memory, but
+        * since we are about to abort anyway, it hardly matters.
+        *
+        * Note that if we paniced due to a SIGSEGV or SIGBUS (or similar) this
+        * will fail with a nasty message upon failing to open the /proc entry.
+        */
+       {
+               __uint64_t      addrs[BACKTRACE_STACK_SIZE];
+               char *          names[BACKTRACE_STACK_SIZE];
+               char            namebuf[BACKTRACE_STACK_SIZE * NAMESIZE];
+
+               int             i;
+               int             levels;
+
+               ZERO_ARRAY(addrs);
+               ZERO_ARRAY(names);
+               ZERO_ARRAY(namebuf);
+
+               /* We need to be root so we can open our /proc entry to walk
+                * our stack. It also helps when we want to dump core.
+                */
+               become_root();
+
+               for (i = 0; i < BACKTRACE_STACK_SIZE; i++) {
+                       names[i] = namebuf + (i * NAMESIZE);
+               }
+
+               levels = trace_back_stack(0, addrs, names,
+                               BACKTRACE_STACK_SIZE, NAMESIZE - 1);
+
+               DEBUG(0, ("BACKTRACE: %d stack frames:\n", levels));
+               for (i = 0; i < levels; i++) {
+                       DEBUGADD(0, (" #%d 0x%llx %s\n", i, addrs[i], names[i]));
+               }
+     }
+#undef NAMESIZE
 #endif
 
        dbgflush();
+#ifdef SIGABRT
+       CatchSignal(SIGABRT,SIGNAL_CAST SIG_DFL);
+#endif
        abort();
 }
 
@@ -1408,7 +1628,7 @@ void smb_panic(const char *why)
   A readdir wrapper which just returns the file name.
  ********************************************************************/
 
-const char *readdirname(DIR *p)
+const char *readdirname(SMB_STRUCT_DIR *p)
 {
        SMB_STRUCT_DIRENT *ptr;
        char *dname;
@@ -1448,19 +1668,18 @@ const char *readdirname(DIR *p)
  of a path matches a (possibly wildcarded) entry in a namelist.
 ********************************************************************/
 
-BOOL is_in_path(const char *name, name_compare_entry *namelist)
+BOOL is_in_path(const char *name, name_compare_entry *namelist, BOOL case_sensitive)
 {
        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);
@@ -1536,8 +1755,7 @@ void set_namearray(name_compare_entry **ppname_array, char *namelist)
        if(num_entries == 0)
                return;
 
-       if(( (*ppname_array) = (name_compare_entry *)malloc(
-                                       (num_entries + 1) * sizeof(name_compare_entry))) == NULL) {
+       if(( (*ppname_array) = SMB_MALLOC_ARRAY(name_compare_entry, num_entries + 1)) == NULL) {
                DEBUG(0,("set_namearray: malloc fail\n"));
                return;
        }
@@ -1560,7 +1778,7 @@ void set_namearray(name_compare_entry **ppname_array, char *namelist)
                        break;
 
                (*ppname_array)[i].is_wild = ms_has_wild(nameptr);
-               if(((*ppname_array)[i].name = strdup(nameptr)) == NULL) {
+               if(((*ppname_array)[i].name = SMB_STRDUP(nameptr)) == NULL) {
                        DEBUG(0,("set_namearray: malloc fail (1)\n"));
                        return;
                }
@@ -1591,6 +1809,9 @@ void free_namearray(name_compare_entry *name_array)
        SAFE_FREE(name_array);
 }
 
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_LOCKING
+
 /****************************************************************************
  Simple routine to do POSIX file locking. Cruft in NFS and 64->32 bit mapping
  is dealt with in posix.c
@@ -1641,6 +1862,9 @@ BOOL fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
        return(True);
 }
 
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_ALL
+
 /*******************************************************************
  Is the name specified one of my netbios names.
  Returns true if it is equal, false otherwise.
@@ -1661,37 +1885,66 @@ BOOL is_myname(const char *s)
        return(ret);
 }
 
-/********************************************************************
- Return only the first IP address of our configured interfaces
- as a string
- *******************************************************************/
-
-const char* get_my_primary_ip (void)
+BOOL is_myname_or_ipaddr(const char *s)
 {
-       static fstring ip_string;
-       int n;
-       struct iface_struct nics[MAX_INTERFACES];
+       fstring name, dnsname;
+       char *servername;
 
-       if ((n=get_interfaces(nics, MAX_INTERFACES)) <= 0)
-               return NULL;
+       if ( !s )
+               return False;
 
-       fstrcpy(ip_string, inet_ntoa(nics[0].ip));
-       return ip_string;
-}
+       /* santize the string from '\\name' */
+
+       fstrcpy( name, s );
+
+       servername = strrchr_m( name, '\\' );
+       if ( !servername )
+               servername = name;
+       else
+               servername++;
 
-BOOL is_myname_or_ipaddr(const char *s)
-{
        /* optimize for the common case */
-       if (strequal(s, global_myname())) 
+
+       if (strequal(servername, global_myname())) 
                return True;
 
+       /* check for an alias */
+
+       if (is_myname(servername))
+               return True;
+
+       /* check for loopback */
+
+       if (strequal(servername, "localhost")) 
+               return True;
+
+       /* maybe it's my dns name */
+
+       if ( get_mydnsfullname( dnsname ) )
+               if ( strequal( servername, dnsname ) )
+                       return True;
+               
+       /* handle possible CNAME records */
+
+       if ( !is_ipaddress( servername ) ) {
+               /* use DNS to resolve the name, but only the first address */
+               struct hostent *hp;
+
+               if (((hp = sys_gethostbyname(name)) != NULL) && (hp->h_addr != NULL)) {
+                       struct in_addr return_ip;
+                       putip( (char*)&return_ip, (char*)hp->h_addr );
+                       fstrcpy( name, inet_ntoa( return_ip ) );
+                       servername = name;
+               }       
+       }
+               
        /* maybe its an IP address? */
-       if (is_ipaddress(s)) {
+       if (is_ipaddress(servername)) {
                struct iface_struct nics[MAX_INTERFACES];
                int i, n;
                uint32 ip;
                
-               ip = interpret_addr(s);
+               ip = interpret_addr(servername);
                if ((ip==0) || (ip==0xffffffff))
                        return False;
                        
@@ -1702,10 +1955,6 @@ BOOL is_myname_or_ipaddr(const char *s)
                }
        }       
 
-       /* check for an alias */
-       if (is_myname(s))
-               return True;
-       
        /* no match */
        return False;
 }
@@ -1751,7 +2000,6 @@ void ra_lanman_string( const char *native_lanman )
 
 void set_remote_arch(enum remote_arch_types type)
 {
-       extern fstring remote_arch;
        ra_type = type;
        switch( type ) {
        case RA_WFWG:
@@ -1778,6 +2026,9 @@ void set_remote_arch(enum remote_arch_types type)
        case RA_SAMBA:
                fstrcpy(remote_arch,"Samba");
                break;
+       case RA_CIFSFS:
+               fstrcpy(remote_arch,"CIFSFS");
+               break;
        default:
                ra_type = RA_UNKNOWN;
                fstrcpy(remote_arch, "UNKNOWN");
@@ -1972,52 +2223,18 @@ int set_maxfiles(int requested_max)
 #endif
 }
 
-/*****************************************************************
- Splits out the start of the key (HKLM or HKU) and the rest of the key.
-*****************************************************************/  
-
-BOOL reg_split_key(const char *full_keyname, uint32 *reg_type, char *key_name)
-{
-       pstring tmp;
-
-       if (!next_token(&full_keyname, tmp, "\\", sizeof(tmp)))
-               return False;
-
-       (*reg_type) = 0;
-
-       DEBUG(10, ("reg_split_key: hive %s\n", tmp));
-
-       if (strequal(tmp, "HKLM") || strequal(tmp, "HKEY_LOCAL_MACHINE"))
-               (*reg_type) = HKEY_LOCAL_MACHINE;
-       else if (strequal(tmp, "HKU") || strequal(tmp, "HKEY_USERS"))
-               (*reg_type) = HKEY_USERS;
-       else {
-               DEBUG(10,("reg_split_key: unrecognised hive key %s\n", tmp));
-               return False;
-       }
-       
-       if (next_token(&full_keyname, tmp, "\n\r", sizeof(tmp)))
-               fstrcpy(key_name, tmp);
-       else
-               key_name[0] = 0;
-
-       DEBUG(10, ("reg_split_key: name %s\n", key_name));
-
-       return True;
-}
-
 /*****************************************************************
  Possibly replace mkstemp if it is broken.
 *****************************************************************/  
 
-int smb_mkstemp(char *template)
+int smb_mkstemp(char *name_template)
 {
 #if HAVE_SECURE_MKSTEMP
-       return mkstemp(template);
+       return mkstemp(name_template);
 #else
        /* have a reasonable go at emulating it. Hope that
           the system mktemp() isn't completly hopeless */
-       char *p = mktemp(template);
+       char *p = mktemp(name_template);
        if (!p)
                return -1;
        return open(p, O_CREAT|O_EXCL|O_RDWR, 0600);
@@ -2028,14 +2245,18 @@ int smb_mkstemp(char *template)
  malloc that aborts with smb_panic on fail or zero size.
  *****************************************************************/  
 
-void *smb_xmalloc(size_t size)
+void *smb_xmalloc_array(size_t size, unsigned int count)
 {
        void *p;
        if (size == 0)
-               smb_panic("smb_xmalloc: called with zero size.\n");
-       if ((p = malloc(size)) == NULL) {
-               DEBUG(0, ("smb_xmalloc() failed to allocate %lu bytes\n", (unsigned long)size));
-               smb_panic("smb_xmalloc: malloc fail.\n");
+               smb_panic("smb_xmalloc_array: called with zero size.\n");
+        if (count >= MAX_ALLOC_SIZE/size) {
+                smb_panic("smb_xmalloc: alloc size too large.\n");
+        }
+       if ((p = SMB_MALLOC(size*count)) == NULL) {
+               DEBUG(0, ("smb_xmalloc_array failed to allocate %lu * %lu bytes\n",
+                       (unsigned long)size, (unsigned long)count));
+               smb_panic("smb_xmalloc_array: malloc fail.\n");
        }
        return p;
 }
@@ -2047,7 +2268,7 @@ void *smb_xmalloc(size_t size)
 void *smb_xmemdup(const void *p, size_t size)
 {
        void *p2;
-       p2 = smb_xmalloc(size);
+       p2 = SMB_XMALLOC_ARRAY(unsigned char,size);
        memcpy(p2, p, size);
        return p2;
 }
@@ -2058,10 +2279,19 @@ void *smb_xmemdup(const void *p, size_t size)
 
 char *smb_xstrdup(const char *s)
 {
+#if defined(PARANOID_MALLOC_CHECKER)
+#ifdef strdup
+#undef strdup
+#endif
+#endif
        char *s1 = strdup(s);
+#if defined(PARANOID_MALLOC_CHECKER)
+#define strdup(s) __ERROR_DONT_USE_STRDUP_DIRECTLY
+#endif
        if (!s1)
                smb_panic("smb_xstrdup: malloc fail\n");
        return s1;
+
 }
 
 /**
@@ -2070,7 +2300,15 @@ char *smb_xstrdup(const char *s)
 
 char *smb_xstrndup(const char *s, size_t n)
 {
+#if defined(PARANOID_MALLOC_CHECKER)
+#ifdef strndup
+#undef strndup
+#endif
+#endif
        char *s1 = strndup(s, n);
+#if defined(PARANOID_MALLOC_CHECKER)
+#define strndup(s,n) __ERROR_DONT_USE_STRNDUP_DIRECTLY
+#endif
        if (!s1)
                smb_panic("smb_xstrndup: malloc fail\n");
        return s1;
@@ -2102,7 +2340,7 @@ void *memdup(const void *p, size_t size)
        void *p2;
        if (size == 0)
                return NULL;
-       p2 = malloc(size);
+       p2 = SMB_MALLOC(size);
        if (!p2)
                return NULL;
        memcpy(p2, p, size);
@@ -2223,6 +2461,12 @@ char *parent_dirname(const char *path)
 BOOL ms_has_wild(const char *s)
 {
        char c;
+
+       if (lp_posix_pathnames()) {
+               /* With posix pathnames no characters are wild. */
+               return False;
+       }
+
        while ((c = *s++)) {
                switch (c) {
                case '*':
@@ -2265,7 +2509,37 @@ BOOL mask_match(const char *string, char *pattern, BOOL is_case_sensitive)
        if (strcmp(pattern,".") == 0)
                return False;
        
-       return ms_fnmatch(pattern, string, Protocol, is_case_sensitive) == 0;
+       return ms_fnmatch(pattern, string, Protocol <= PROTOCOL_LANMAN2, is_case_sensitive) == 0;
+}
+
+/*******************************************************************
+ A wrapper that handles case sensitivity and the special handling
+ of the ".." name. Varient that is only called by old search code which requires
+ pattern translation.
+*******************************************************************/
+
+BOOL mask_match_search(const char *string, char *pattern, BOOL is_case_sensitive)
+{
+       if (strcmp(string,"..") == 0)
+               string = ".";
+       if (strcmp(pattern,".") == 0)
+               return False;
+       
+       return ms_fnmatch(pattern, string, True, is_case_sensitive) == 0;
+}
+
+/*******************************************************************
+ A wrapper that handles a list of patters and calls mask_match()
+ on each.  Returns True if any of the patterns match.
+*******************************************************************/
+
+BOOL mask_match_list(const char *string, char **list, int listLen, BOOL is_case_sensitive)
+{
+       while (listLen-- > 0) {
+               if (mask_match(string, *list++, is_case_sensitive))
+                       return True;
+       }
+       return False;
 }
 
 /*********************************************************
@@ -2394,6 +2668,44 @@ BOOL unix_wild_match(const char *pattern, const char *string)
        return unix_do_match(p2, s2) == 0;      
 }
 
+/**********************************************************************
+ Converts a name to a fully qalified domain name.
+***********************************************************************/
+                                                                                                                                                   
+void name_to_fqdn(fstring fqdn, const char *name)
+{
+       struct hostent *hp = sys_gethostbyname(name);
+       if ( hp && hp->h_name && *hp->h_name ) {
+               DEBUG(10,("name_to_fqdn: lookup for %s -> %s.\n", name, hp->h_name));
+               fstrcpy(fqdn,hp->h_name);
+       } else {
+               DEBUG(10,("name_to_fqdn: lookup for %s failed.\n", name));
+               fstrcpy(fqdn, name);
+       }
+}
+
+/**********************************************************************
+ Extension to talloc_get_type: Abort on type mismatch
+***********************************************************************/
+
+void *talloc_check_name_abort(const void *ptr, const char *name)
+{
+       void *result;
+
+       if (ptr == NULL)
+               return NULL;
+
+       result = talloc_check_name(ptr, name);
+       if (result != NULL)
+               return result;
+
+       DEBUG(0, ("Talloc type mismatch, expected %s, got %s\n",
+                 name, talloc_get_name(ptr)));
+       smb_panic("aborting");
+       /* Keep the compiler happy */
+       return NULL;
+}
+
 
 #ifdef __INSURE__
 
@@ -2433,3 +2745,78 @@ int _Insure_trap_error(int a1, int a2, int a3, int a4, int a5, int a6)
        return ret;
 }
 #endif
+
+uint32 map_share_mode_to_deny_mode(uint32 share_access, uint32 private_options)
+{
+       switch (share_access & ~FILE_SHARE_DELETE) {
+               case FILE_SHARE_NONE:
+                       return DENY_ALL;
+               case FILE_SHARE_READ:
+                       return DENY_WRITE;
+               case FILE_SHARE_WRITE:
+                       return DENY_READ;
+               case FILE_SHARE_READ|FILE_SHARE_WRITE:
+                       return DENY_NONE;
+       }
+       if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
+               return DENY_DOS;
+       } else if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_FCB) {
+               return DENY_FCB;
+       }
+
+       return (uint32)-1;
+}
+
+pid_t procid_to_pid(const struct process_id *proc)
+{
+       return proc->pid;
+}
+
+struct process_id pid_to_procid(pid_t pid)
+{
+       struct process_id result;
+       result.pid = pid;
+       return result;
+}
+
+struct process_id procid_self(void)
+{
+       return pid_to_procid(sys_getpid());
+}
+
+BOOL procid_equal(const struct process_id *p1, const struct process_id *p2)
+{
+       return (p1->pid == p2->pid);
+}
+
+BOOL procid_is_me(const struct process_id *pid)
+{
+       return (pid->pid == sys_getpid());
+}
+
+struct process_id interpret_pid(const char *pid_string)
+{
+       return pid_to_procid(atoi(pid_string));
+}
+
+char *procid_str_static(const struct process_id *pid)
+{
+       static fstring str;
+       fstr_sprintf(str, "%d", pid->pid);
+       return str;
+}
+
+char *procid_str(TALLOC_CTX *mem_ctx, const struct process_id *pid)
+{
+       return talloc_strdup(mem_ctx, procid_str_static(pid));
+}
+
+BOOL procid_valid(const struct process_id *pid)
+{
+       return (pid->pid != -1);
+}
+
+BOOL procid_is_local(const struct process_id *pid)
+{
+       return True;
+}